### Start Dropwizard Example Application Source: https://www.dropwizard.io/en/stable/manual/example.html Start the Dropwizard Example Application using the command line or by running it directly in an IDE. ```bash java -jar target/dropwizard-example-5.0.0-SNAPSHOT.jar server example.yml ``` ```java com.example.helloworld.HelloWorldApplication server example.yml ``` -------------------------------- ### Build and Migrate Dropwizard Example Application Source: https://www.dropwizard.io/en/stable/manual/example.html Build the Dropwizard example application using Maven and then migrate the database schema using Liquibase. ```bash mvn clean install ``` ```bash java -jar target/dropwizard-example-5.0.0-SNAPSHOT.jar db migrate example.yml ``` -------------------------------- ### Database Configuration Example Source: https://www.dropwizard.io/en/stable/manual/hibernate.html Example of how to configure database connection details, including driver, user, password, URL, and Hibernate properties, in the application's configuration file. ```yaml database: # the name of your JDBC driver driverClass: org.postgresql.Driver # the username user: pg-user # the password password: iAMs00perSecrEET # the JDBC URL url: jdbc:postgresql://db.example.com/db-prod # any properties specific to your JDBC driver: properties: charSet: UTF-8 hibernate.dialect: org.hibernate.dialect.PostgreSQLDialect # the maximum amount of time to wait on an empty pool before throwing an exception maxWaitForConnection: 1s # the SQL query to run when validating a connection's liveness validationQuery: "/* MyApplication Health Check */ SELECT 1" # the minimum number of connections to keep open minSize: 8 # the maximum number of connections to keep open maxSize: 32 # whether or not idle connections should be validated checkConnectionWhileIdle: false ``` -------------------------------- ### Interact with Dropwizard Example Application API Source: https://www.dropwizard.io/en/stable/manual/example.html Examples of inserting a new person and retrieving person data using curl commands. ```bash curl -H "Content-Type: application/json" -d '{"fullName":"John Doe", "jobTitle" : "Chief Wizard" }' http://localhost:8080/people ``` ```bash curl http://localhost:8080/people/1 ``` ```bash curl http://localhost:8080/people/1/view_freemarker ``` ```bash curl http://localhost:8080/people/1/view_mustache ``` -------------------------------- ### Server Startup Logs Source: https://www.dropwizard.io/en/stable/getting-started.html Example log output showing the server initialization and port binding. ```text INFO [2011-12-03 00:38:32,927] io.dropwizard.core.cli.ServerCommand: Starting hello-world INFO [2011-12-03 00:38:32,931] org.eclipse.jetty.server.Server: jetty-7.x.y-SNAPSHOT INFO [2011-12-03 00:38:32,936] org.eclipse.jetty.server.handler.ContextHandler: started o.e.j.s.ServletContextHandler{/,null} INFO [2011-12-03 00:38:32,999] com.sun.jersey.server.impl.application.WebApplicationImpl: Initiating Jersey application, version 'Jersey: 1.10 11/02/2011 03:53 PM' INFO [2011-12-03 00:38:33,041] io.dropwizard.core.setup.Environment: GET /hello-world (com.example.helloworld.resources.HelloWorldResource) INFO [2011-12-03 00:38:33,215] org.eclipse.jetty.server.handler.ContextHandler: started o.e.j.s.ServletContextHandler{/,null} INFO [2011-12-03 00:38:33,235] org.eclipse.jetty.server.AbstractConnector: Started BlockingChannelConnector@0.0.0.0:8080 STARTING INFO [2011-12-03 00:38:33,238] org.eclipse.jetty.server.AbstractConnector: Started SocketConnector@0.0.0.0:8081 STARTING ``` -------------------------------- ### Example YAML Configuration Source: https://www.dropwizard.io/en/stable/manual/testing.html A sample YAML configuration file containing environment variable placeholders. ```yaml widgets: - type: hammer weight: ${HAMMER_WEIGHT:-20} - type: chisel radius: 0.4 ``` -------------------------------- ### Configure BasicAuth ResourceExtension Source: https://www.dropwizard.io/en/stable/manual/auth.html Setup the ResourceExtension with BasicCredentialAuthFilter and GrizzlyWebTestContainerFactory. ```java @ExtendWith(DropwizardExtensionsSupport.class) public class OAuthResourceTest { public ResourceExtension resourceExtension = ResourceExtension .builder() .setTestContainerFactory(new GrizzlyWebTestContainerFactory()) .addProvider(new AuthDynamicFeature(new BasicCredentialAuthFilter.Builder() .setAuthenticator(new MyBasicAuthenticator()) .setAuthorizer(new MyBasicAuthorizer()) .buildAuthFilter())) .addProvider(RolesAllowedDynamicFeature.class) .addProvider(new AuthValueFactoryProvider.Binder<>(User.class)) .addResource(new ProtectedResource()) .build() } ``` -------------------------------- ### Example Liquibase migrations.xml Source: https://www.dropwizard.io/en/stable/manual/migrations.html Define your database migrations in src/main/resources/migrations.xml using Liquibase XML format. This example creates a 'people' table with id, fullName, and jobTitle columns. ```xml ``` -------------------------------- ### Run Dropwizard Application Source: https://www.dropwizard.io/en/stable/manual/internals.html Example command to execute a packaged Dropwizard JAR with a server configuration file. ```bash java -jar target/hello-world-0.0.1-SNAPSHOT.jar server hello-world.yml ``` -------------------------------- ### JSON Log Output Examples Source: https://www.dropwizard.io/en/stable/manual/core.html Sample output formats for general and access JSON logging. ```json {"timestamp":1515002688000, "level":"INFO","logger":"org.eclipse.jetty.server.Server","thread":"main","message":"Started @6505ms"} ``` ```json {"timestamp":1515002688000, "method":"GET","uri":"/hello-world", "status":200, "protocol":"HTTP/1.1","contentLength":37,"remoteAddress":"127.0.0.1","requestTime":5, "userAgent":"Mozilla/5.0"} ``` -------------------------------- ### Application Startup Banner Output Source: https://www.dropwizard.io/en/stable/manual/core.html Example of an ASCII art banner displayed in the logs upon application startup. ```text INFO [2011-12-09 21:56:37,209] io.dropwizard.core.cli.ServerCommand: Starting hello-world dP 88 .d8888b. dP. .dP .d8888b. 88d8b.d8b. 88d888b. 88 .d8888b. 88ooood8 `8bd8' 88' `88 88'`88'`88 88' `88 88 88ooood8 88. ... .d88b. 88. .88 88 88 88 88. .88 88 88. ... `88888P' dP' `dP `88888P8 dP dP dP 88Y888P' dP `88888P' 88 dP INFO [2011-12-09 21:56:37,214] org.eclipse.jetty.server.Server: jetty-7.6.0 ... ``` -------------------------------- ### Configure OAuth ResourceExtension Source: https://www.dropwizard.io/en/stable/manual/auth.html Setup the ResourceExtension with OAuthCredentialAuthFilter and GrizzlyWebTestContainerFactory. ```java @ExtendWith(DropwizardExtensionsSupport.class) public class OAuthResourceTest { public ResourceExtension resourceExtension = ResourceExtension .builder() .setTestContainerFactory(new GrizzlyWebTestContainerFactory()) .addProvider(new AuthDynamicFeature(new OAuthCredentialAuthFilter.Builder() .setAuthenticator(new MyOAuthAuthenticator()) .setAuthorizer(new MyAuthorizer()) .setRealm("SUPER SECRET STUFF") .setPrefix("Bearer") .buildAuthFilter())) .addProvider(RolesAllowedDynamicFeature.class) .addProvider(new AuthValueFactoryProvider.Binder<>(User.class)) .addResource(new ProtectedResource()) .build(); } ``` -------------------------------- ### Example YAML Configuration Source: https://www.dropwizard.io/en/stable/manual/configuration.html Define the polymorphic list in your YAML configuration file using the type property. ```yaml widgets: - type: hammer weight: 20 - type: chisel radius: 0.4 ``` -------------------------------- ### Example Log Output Source: https://www.dropwizard.io/en/stable/manual/core.html The standard format for Dropwizard logs, including timestamps in UTC and ISO 8601 format. ```text TRACE [2010-04-06 06:42:35,271] com.example.dw.Thing: Contemplating doing a thing. DEBUG [2010-04-06 06:42:35,274] com.example.dw.Thing: About to do a thing. INFO [2010-04-06 06:42:35,274] com.example.dw.Thing: Doing a thing WARN [2010-04-06 06:42:35,275] com.example.dw.Thing: Doing a thing ERROR [2010-04-06 06:42:35,275] com.example.dw.Thing: This may get ugly. ! java.lang.RuntimeException: oh noes! ! at com.example.dw.Thing.run(Thing.java:16) ! ``` -------------------------------- ### Maven Package Build Output Example Source: https://www.dropwizard.io/en/stable/getting-started.html This output is shown after running `mvn package` with the versioning configuration. It indicates the successful build and replacement of the artifact with a shaded version, including the project version in the filename. ```text [INFO] Including org.eclipse.jetty:jetty-util:jar:7.6.0.RC0 in the shaded jar. [INFO] Including com.google.guava:guava:jar:10.0.1 in the shaded jar. [INFO] Including com.google.code.findbugs:jsr305:jar:1.3.9 in the shaded jar. [INFO] Including org.hibernate:hibernate-validator:jar:4.2.0.Final in the shaded jar. [INFO] Including javax.validation:validation-api:jar:1.0.0.GA in the shaded jar. [INFO] Including org.yaml:snakeyaml:jar:1.9 in the shaded jar. [INFO] Replacing original artifact with shaded artifact. [INFO] Replacing /Users/yourname/Projects/hello-world/target/hello-world-0.0.1-SNAPSHOT.jar with /Users/yourname/Projects/hello-world/target/hello-world-0.0.1-SNAPSHOT-shaded.jar [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 8.415s [INFO] Finished at: Fri Dec 02 16:26:42 PST 2011 [INFO] Final Memory: 11M/81M [INFO] ------------------------------------------------------------------------ ``` -------------------------------- ### Combine Multiple Appenders Source: https://www.dropwizard.io/en/stable/manual/core.html Example of using multiple appenders with different thresholds and configurations. ```yaml logging: # Permit DEBUG, INFO, WARN and ERROR messages to be logged by appenders. level: DEBUG appenders: # Log warnings and errors to stderr - type: console threshold: WARN target: stderr # Log info, warnings and errors to our apps' main log. # Rolled over daily and retained for 5 days. - type: file threshold: INFO currentLogFilename: ./logs/example.log archivedLogFilenamePattern: ./logs/example-%d.log.gz archivedFileCount: 5 # Log debug messages, info, warnings and errors to our apps' debug log. # Rolled over hourly and retained for 6 hours - type: file threshold: DEBUG currentLogFilename: ./logs/debug.log archivedLogFilenamePattern: ./logs/debug-%d{yyyy-MM-dd-hh}.log.gz archivedFileCount: 6 ``` -------------------------------- ### Logging Configuration in YAML Source: https://www.dropwizard.io/en/stable/manual/core.html Example of configuring logger levels and appenders within the Dropwizard YAML configuration file. ```yaml # Logging settings. logging: # The default level of all loggers. Can be OFF, ERROR, WARN, INFO, DEBUG, TRACE, or ALL. level: INFO # Logger-specific levels. loggers: # Overrides the level of com.example.dw.Thing and sets it to DEBUG. "com.example.dw.Thing": DEBUG # Enables the SQL query log and redirect it to a separate file "org.hibernate.SQL": level: DEBUG # This line stops org.hibernate.SQL (or anything under it) from using the root logger additive: false appenders: - type: file currentLogFilename: ./logs/example-sql.log archivedLogFilenamePattern: ./logs/example-sql-%d.log.gz archivedFileCount: 5 ``` -------------------------------- ### Implement Basic Authenticator Source: https://www.dropwizard.io/en/stable/manual/auth.html Implement the Authenticator interface for Basic Authentication. This example checks for a 'secret' password and returns a User principal. ```java public class ExampleAuthenticator implements Authenticator { @Override public Optional authenticate(BasicCredentials credentials) throws AuthenticationException { if ("secret".equals(credentials.getPassword())) { return Optional.of(new User(credentials.getUsername())); } return Optional.empty(); } } ``` -------------------------------- ### JSON Representation Example Source: https://www.dropwizard.io/en/stable/manual/core.html The resulting JSON output for the Notification POJO. ```json { "text": "hey it's the value of the text field" } ``` -------------------------------- ### Test Protected Resource Source: https://www.dropwizard.io/en/stable/manual/upgrade-notes/upgrade-notes-0_9_x.html Example curl command to test an authenticated endpoint. ```bash $ curl 'testUser:secret@localhost:8080/protected' Hey there, testUser. You know the secret! ``` -------------------------------- ### Resource with Context Injection (Dropwizard 1.3) Source: https://www.dropwizard.io/en/stable/manual/upgrade-notes/upgrade-notes-2_0_x.html Example of a resource class with context injection on fields, which behaved differently in Dropwizard 1.3 compared to 2.0. ```java @Path("/") @Produces(MediaType.APPLICATION_JSON) public class InfoResource { @Context UriInfo requestUri; @GET public String getInfo() { return requestUri.getRequestUri().toString() } } ``` -------------------------------- ### Migrate Schema for Custom Named Bundles Source: https://www.dropwizard.io/en/stable/manual/migrations.html Execute schema migrations using custom bundle names defined during initialization. The command format is ` migrate `. This example shows migrating for 'db1' and 'db2'. ```java java -jar hello-world.jar db1 migrate helloworld.yml ``` ```java java -jar hello-world.jar db2 migrate helloworld.yml ``` -------------------------------- ### Perform Integration Testing with DropwizardAppExtension Source: https://www.dropwizard.io/en/stable/manual/testing.html Starts the full application using JUnit 5 extensions to manage the lifecycle and provide access to the application environment. ```java @ExtendWith(DropwizardExtensionsSupport.class) class LoginAcceptanceTest { private static DropwizardAppExtension EXT = new DropwizardAppExtension<>( MyApp.class, ResourceHelpers.resourceFilePath("my-app-config.yaml") ); @Test void loginHandlerRedirectsAfterPost() { Client client = EXT.client(); Response response = client.target( String.format("http://localhost:%d/login", EXT.getLocalPort())) .request() .post(Entity.json(loginForm())); assertThat(response.getStatus()).isEqualTo(302); } } ``` -------------------------------- ### Test HTTP Client Implementations with DropwizardClientExtension Source: https://www.dropwizard.io/en/stable/manual/testing.html Uses DropwizardClientExtension to start a temporary application with JAX-RS test doubles, avoiding circular dependencies. ```java @ExtendWith(DropwizardExtensionsSupport.class) class CustomClientTest { @Path("/ping") public static class PingResource { @GET public String ping() { return "pong"; } } private static final DropwizardClientExtension EXT = new DropwizardClientExtension(new PingResource()); @Test void shouldPing() throws IOException { final URL url = new URL(EXT.baseUri() + "/ping"); final String response = new BufferedReader(new InputStreamReader(url.openStream())).readLine(); assertEquals("pong", response); } } ``` -------------------------------- ### GET Endpoint with @NotEmpty for String Return Source: https://www.dropwizard.io/en/stable/manual/validation.html When a GET endpoint returns a String and is annotated with @NotEmpty, Dropwizard ensures the returned string is not empty. This example demonstrates a potential issue where such endpoints might be invoked twice. ```java @Path("/") public class ValidatedResource { private AtomicLong counter = new AtomicLong(); @GET @Path("/foo") @NotEmpty public String getFoo() { counter.getAndIncrement(); return ""; } @GET @Path("/bar") public String getBar() { return ""; } } ``` -------------------------------- ### Execute a GET Request in Dropwizard Integration Test Source: https://www.dropwizard.io/en/stable/manual/upgrade-notes/upgrade-notes-0_8_x.html This snippet demonstrates how to execute a GET request to a specific endpoint and assert the response status and content. ```java final WebTarget target = ClientBuilder.newClient().target( String.format("http://localhost:%d/api/user/1", RULE.getLocalPort())); final Response response = target .request(MediaType.APPLICATION_JSON_TYPE) .accept(MediaType.APPLICATION_JSON_TYPE) .get(); assertThat(response.getStatus()).isEqualTo(Response.Status.OK.getStatusCode()); final User user = response.readEntity(User.class); assertThat(user.getId()).isEqualTo(1L); assertThat(user.getFirstName()).isEqualTo("John"); assertThat(user.getLastName()).isEqualTo("Doe"); ``` -------------------------------- ### Configure Default Server with Multiple Connectors Source: https://www.dropwizard.io/en/stable/manual/configuration.html Sets up a default server configuration with detailed settings for application and admin threads, context paths, and multiple HTTP/HTTPS connectors for both application and admin interfaces. Includes keystore configuration for HTTPS. ```yaml server: adminMinThreads: 1 adminMaxThreads: 64 enableAdminVirtualThreads: false adminContextPath: / applicationContextPath: / applicationConnectors: - type: http port: 8080 - type: https port: 8443 keyStorePath: example.keystore keyStorePassword: example validateCerts: false adminConnectors: - type: http port: 8081 - type: https port: 8444 keyStorePath: example.keystore keyStorePassword: example validateCerts: false ``` -------------------------------- ### Implement Managed Interface for Riak Client Source: https://www.dropwizard.io/en/stable/manual/core.html Implement the `Managed` interface to control the start and stop lifecycle of a Riak client. This ensures the client is properly initialized before the application starts and shut down gracefully afterward. ```java public class RiakClientManager implements Managed { private final RiakClient client; public RiakClientManager(RiakClient client) { this.client = client; } @Override public void start() throws Exception { client.start(); } @Override public void stop() throws Exception { client.stop(); } } ``` -------------------------------- ### Register Managed Object with Dropwizard Environment Source: https://www.dropwizard.io/en/stable/manual/core.html Register an instance of a class implementing the `Managed` interface with the Dropwizard `Environment`. This ties the object's lifecycle to the application's HTTP server, ensuring its `start()` method is called before the server starts and `stop()` after it has stopped. ```java public class ManagedApp extends Application { @Override public void run(Configuration configuration, Environment environment) { RiakClient client = new RiakClient(); RiakClientManager riakClientManager = new RiakClientManager(client); environment.lifecycle().manage(riakClientManager); } } ``` -------------------------------- ### Implement Application run method Source: https://www.dropwizard.io/en/stable/manual/internals.html The run method initializes the bootstrap environment, registers commands, and executes the CLI. ```java public void run(String... arguments) throws Exception { final Bootstrap bootstrap = new Bootstrap<>(this); bootstrap.addCommand(new ServerCommand<>(this)); bootstrap.addCommand(new CheckCommand<>(this)); initialize(bootstrap); // -- implemented by you; it should call: // 1. add bundles (typically being used) // 2. add commands (if any) // Should be called after `initialize` to give an opportunity to set a custom metric registry bootstrap.registerMetrics(); // start tracking some default jvm params… // for each cmd, configure parser w/ cmd final Cli cli = new Cli(new JarLocation(getClass()), bootstrap, our, err) cli.run(arguments); } ``` -------------------------------- ### View CLI Help Output Source: https://www.dropwizard.io/en/stable/getting-started.html Displays the expected output when running the JAR without arguments. ```text usage: java -jar hello-world-0.0.1-SNAPSHOT.jar [-h] [-v] {server} ... positional arguments: {server} available commands optional arguments: -h, --help show this help message and exit -v, --version show the service version and exit ``` -------------------------------- ### Test Configuration with Environment Variables Source: https://www.dropwizard.io/en/stable/manual/testing.html Shows how to test configurations that use EnvironmentVariableSubstitutor by wrapping the source provider. ```java public class WidgetFactoryTest { private final ObjectMapper objectMapper = Jackson.newObjectMapper(); private final Validator validator = Validators.newValidator(); private final YamlConfigurationFactory factory = new YamlConfigurationFactory<>(WidgetFactory.class, validator, objectMapper, "dw"); // test for discoverability @Test public void testBuildAHammer() throws Exception { final WidgetFactory wid = factory.build(new SubstitutingSourceProvider( new ResourceConfigurationSourceProvider(), new EnvironmentVariableSubstitutor(false) ), "yaml/hammer.yaml"); assertThat(wid).isInstanceOf(HammerFactory.class); assertThat(((HammerFactory) wid).createWidget().getWeight()).isEqualTo(20); } // test for the chisel factory } ``` -------------------------------- ### Health Check Output Source: https://www.dropwizard.io/en/stable/getting-started.html Example output from the health check resource endpoint. ```text * deadlocks: OK * template: OK ``` -------------------------------- ### Define JSON Representation Source: https://www.dropwizard.io/en/stable/getting-started.html Example of the expected JSON structure for the API response. ```json { "id": 1, "content": "Hi!" } ``` -------------------------------- ### Add Multiple Migration Bundles with Custom Names Source: https://www.dropwizard.io/en/stable/manual/migrations.html Initialize multiple `MigrationsBundle` instances, each associated with a specific data source factory and given a unique name. This allows for distinct command-line migration commands. ```java @Override public void initialize(Bootstrap bootstrap) { bootstrap.addBundle(new MigrationsBundle() { @Override public DataSourceFactory getDataSourceFactory(ExampleConfiguration configuration) { return configuration.getDb1DataSourceFactory(); } @Override public String name() { return "db1"; } }); bootstrap.addBundle(new MigrationsBundle() { @Override public DataSourceFactory getDataSourceFactory(ExampleConfiguration configuration) { return configuration.getDb2DataSourceFactory(); } @Override public String name() { return "db2"; } }); } ``` -------------------------------- ### Register Jetty Lifecycle Listener Source: https://www.dropwizard.io/en/stable/manual/internals.html Registers a listener to be notified after the Jetty server has successfully started. ```java env.lifecycle().addServerLifecycleListener(new ServerLifecycleListener() { @Override public void serverStarted(Server server) { /// ... do things here .... } }); ``` -------------------------------- ### Define YAML Configuration File Source: https://www.dropwizard.io/en/stable/getting-started.html Provide the YAML configuration file that maps to the fields defined in the HelloWorldConfiguration class. ```yaml --- template: Hello, %s! defaultName: Stranger ``` -------------------------------- ### Create a JSON fixture file Source: https://www.dropwizard.io/en/stable/manual/testing.html A sample JSON file representing the expected structure of the Person object. ```json { "name": "Luther Blissett", "email": "lb@example.com" } ``` -------------------------------- ### Example JSON error response Source: https://www.dropwizard.io/en/stable/manual/core.html The expected JSON output when a 404 error is triggered by the resource. ```json {"code":404,"message":"Collection foobar does not exist"} ``` -------------------------------- ### Implement Dependency Injection Bundle Source: https://www.dropwizard.io/en/stable/manual/di.html Create a ConfiguredBundle to register the defined singletons and properties into the Jersey environment. ```java public class DependencyInjectionBundle implements ConfiguredBundle { @Override public void run(DependencyInjectionConfiguration configuration, Environment environment) throws Exception { environment .jersey() .register( new AbstractBinder() { @Override protected void configure() { for (Class singletonClass : configuration.getSingletons()) { bindAsContract(singletonClass).in(Singleton.class); } for (NamedProperty namedProperty : configuration.getNamedProperties()) { bind((Object) namedProperty.getValue()).to((Class) namedProperty.getClazz()).named(namedProperty.getId()); } } } ); } } ``` -------------------------------- ### Configure Simple Server with HTTP Connector Source: https://www.dropwizard.io/en/stable/manual/configuration.html Defines a simple server configuration with specified application and admin context paths, and an HTTP connector on port 8080. ```yaml server: type: simple applicationContextPath: /application adminContextPath: /admin connector: type: http port: 8080 ``` -------------------------------- ### Configure HTTPS Connector Source: https://www.dropwizard.io/en/stable/manual/core.html Set up an HTTPS connector in the server configuration using a Java keystore. ```yaml --- server: applicationConnectors: - type: https port: 8443 keyStorePath: example.keystore keyStorePassword: example validateCerts: false ``` -------------------------------- ### Handle UnwrapValidatedValue Changes Source: https://www.dropwizard.io/en/stable/manual/upgrade-notes/upgrade-notes-0_9_x.html Examples showing the transition from implicit to explicit @UnwrapValidatedValue usage for Hibernate Validator. ```java @GET public String heads(@QueryParam("cheese") @NotNull IntParam secretSauce) { ``` ```java @GET public String heads(@QueryParam("cheese") @NotNull @UnwrapValidatedValue(false) IntParam secretSauce) { ``` -------------------------------- ### Grep Log Messages Source: https://www.dropwizard.io/en/stable/manual/core.html Command-line examples for filtering log files using standard UNIX tools. ```bash tail -f dw.log | grep '^WARN' ``` ```bash tail -f dw.log | grep 'com.example.dw.Thing' ``` ```bash tail -f dw.log | grep -B 1 '^!' ``` -------------------------------- ### Implement a ConfiguredCommand Source: https://www.dropwizard.io/en/stable/manual/core.html Create a command that requires access to the application's configuration file. ```java public class MyConfiguredCommand extends ConfiguredCommand { public MyConfiguredCommand() { // The name of our command is "hello" and the description printed is // "Prints a greeting" super("hello", "Prints a greeting"); } @Override public void configure(Subparser subparser) { // Add a command line option subparser.addArgument("-u", "--user") .dest("user") .type(String.class) .required(true) .help("The user of the program"); } @Override protected void run(Bootstrap bootstrap, Namespace namespace, Configuration configuration) throws Exception { System.out.println("Hello " + namespace.getString("user")); } } ``` -------------------------------- ### Generate a Dropwizard project using Maven archetype Source: https://www.dropwizard.io/en/stable/getting-started.html Use this command to bootstrap a new Dropwizard project structure. Replace the version placeholder with the desired release version. ```bash mvn archetype:generate -DarchetypeGroupId=io.dropwizard.archetypes -DarchetypeArtifactId=java-simple -DarchetypeVersion=[REPLACE WITH A VALID DROPWIZARD VERSION] ``` -------------------------------- ### Generate Database Documentation Source: https://www.dropwizard.io/en/stable/manual/migrations.html Create HTML documentation of the current database schema status. Specify the output directory for the generated documentation. ```java java -jar hello-world.jar db generate-docs helloworld.yml ~/db-docs/ ``` -------------------------------- ### Structure of Bootstrap environment Source: https://www.dropwizard.io/en/stable/manual/internals.html The Bootstrap object holds the pre-start environment configuration, including registries and factories. ```java Bootstrap(application: Application) { this.application = application; this.objectMapper = Jackson.newObjectMapper(); this.bundles = new ArrayList<>(); this.configuredBundles = new ArrayList<>(); this.commands = new ArrayList<>(); this.validatorFactory = Validators.newValidatorFactory(); this.metricRegistry = new MetricRegistry(); this.classLoader = Thread.currentThread().getContextClassLoader(); this.configurationFactory = new DefaultConfigurationFactoryFactory<>(); this.healthCheckRegistry = new HealthCheckRegistry(); } ``` -------------------------------- ### Improved @MaxDuration Validation Message (Exclusive) Source: https://www.dropwizard.io/en/stable/manual/upgrade-notes/upgrade-notes-2_0_x.html Example of an improved validation message for @MaxDuration when the 'inclusive' mode is set to false. ```text messageRate must be less than 1 MINUTES ``` -------------------------------- ### Improved @MinDuration Validation Message (Inclusive) Source: https://www.dropwizard.io/en/stable/manual/upgrade-notes/upgrade-notes-2_0_x.html Example of an improved validation message for @MinDuration when the 'inclusive' mode is set to true. ```text messageRate must be less than or equal to 1 MINUTES ``` -------------------------------- ### Configure Request Log with logback-access Source: https://www.dropwizard.io/en/stable/manual/configuration.html Sets up the request log to use the logback-access library for extended logging patterns. Ensure logback-access is available as a dependency. ```yaml server: requestLog: appenders: - type: console ``` -------------------------------- ### Run the Dropwizard JAR Source: https://www.dropwizard.io/en/stable/getting-started.html Executes the application JAR file to view available commands. ```bash java -jar target/hello-world-0.0.1-SNAPSHOT.jar ``` -------------------------------- ### Test OAuth Protected Resource Source: https://www.dropwizard.io/en/stable/manual/auth.html Perform a GET request to a protected endpoint by manually setting the Authorization header with a Bearer token. ```java @Test public void testProtected() throws Exception { final Response response = resourceExtension.target("/protected") .request(MediaType.APPLICATION_JSON_TYPE) .header("Authorization", "Bearer TOKEN") .get(); assertThat(response.getStatus()).isEqualTo(200); } ``` -------------------------------- ### Configure HttpClient Settings Source: https://www.dropwizard.io/en/stable/manual/configuration.html Standard YAML configuration for HttpClient timeouts, connection limits, and protocol settings. ```yaml httpClient: timeout: 500ms connectionTimeout: 500ms timeToLive: 1h cookiesEnabled: false maxConnections: 1024 maxConnectionsPerRoute: 1024 keepAlive: 0ms retries: 0 userAgent: () protocolUpgradeEnabled: true ``` -------------------------------- ### Configure File Logging Source: https://www.dropwizard.io/en/stable/manual/core.html Recommended configuration for production environments using rotated log files. ```yaml logging: appenders: - type: file # The file to which current statements will be logged. currentLogFilename: ./logs/example.log # When the log file rotates, the archived log will be renamed to this and gzipped. The # %d is replaced with the previous day (yyyy-MM-dd). Custom rolling windows can be created # by passing a SimpleDateFormat-compatible format as an argument: "%d{yyyy-MM-dd-hh}". archivedLogFilenamePattern: ./logs/example-%d.log.gz # The number of archived files to keep. archivedFileCount: 5 # The timezone used to format dates. HINT: USE THE DEFAULT, UTC. timeZone: UTC ``` -------------------------------- ### Dropwizard Class Rule for Integration Testing Source: https://www.dropwizard.io/en/stable/manual/upgrade-notes/upgrade-notes-0_8_x.html The Dropwizard Class Rule remains unchanged and is used in subsequent examples for setting up integration tests. ```java @ClassRule public static final DropwizardAppRule RULE = new DropwizardAppRule<>(App.class, "config.yaml"); ``` -------------------------------- ### Define a Jersey Resource Class Source: https://www.dropwizard.io/en/stable/getting-started.html A resource class annotated with @Path and @Produces to handle HTTP GET requests and return JSON representations. ```java package com.example.helloworld.resources; import com.codahale.metrics.annotation.Timed; import com.example.helloworld.api.Saying; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.Produces; import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.core.MediaType; import java.util.Optional; import java.util.concurrent.atomic.AtomicLong; @Path("/hello-world") @Produces(MediaType.APPLICATION_JSON) public class HelloWorldResource { private final String template; private final String defaultName; private final AtomicLong counter; public HelloWorldResource(String template, String defaultName) { this.template = template; this.defaultName = defaultName; this.counter = new AtomicLong(); } @GET @Timed public Saying sayHello(@QueryParam("name") Optional name) { final String value = String.format(template, name.orElse(defaultName)); return new Saying(counter.incrementAndGet(), value); } } ``` -------------------------------- ### Test BasicAuth Protected Resource Source: https://www.dropwizard.io/en/stable/manual/auth.html Perform a GET request to a protected endpoint by manually setting the Authorization header with Base64 encoded credentials. ```java @Test public void testProtectedResource(){ String credential = "Basic " + Base64.getEncoder().encodeToString("test@gmail.com:secret".getBytes()) Response response = resourceExtension .target("/protected") .request() .header(HttpHeaders.AUTHORIZATION, credential) .get(); Assert.assertEquals(200, response.getStatus()); } ``` -------------------------------- ### Add AssetsBundle to Serve Static Assets from Root Source: https://www.dropwizard.io/en/stable/manual/core.html Add an `AssetsBundle` to the application's bootstrap to serve static resources from a specified directory (e.g., `/assets/`) at the root path (`/`). This allows `index.htm` to be served as the default page. ```java bootstrap.addBundle(new AssetsBundle("/assets/", "/")); ``` -------------------------------- ### Implement Authorizer Source: https://www.dropwizard.io/en/stable/manual/auth.html Implement the Authorizer interface to define access control logic. This example grants ADMIN role access only to a user named 'good-guy'. ```java public class ExampleAuthorizer implements Authorizer { @Override public boolean authorize(User user, String role) { return user.getName().equals("good-guy") && role.equals("ADMIN"); } } ``` -------------------------------- ### Define CLI Commands Source: https://www.dropwizard.io/en/stable/manual/internals.html Class definitions for standard Dropwizard commands, showing the inheritance hierarchy for configuration and environment commands. ```java class CheckCommand extends ConfiguredCommand class ServerCommand extends EnvironmentCommand ``` -------------------------------- ### Override Logging Level via System Property Source: https://www.dropwizard.io/en/stable/manual/core.html Start your application with a Java system property prefixed with 'dw.' to override configuration settings like logging level. ```bash java -Ddw.logging.level=DEBUG server my-config.json ``` -------------------------------- ### Define a Discoverable Configuration Interface Source: https://www.dropwizard.io/en/stable/manual/configuration.html Create a base interface extending Discoverable and register it in META-INF/services/io.dropwizard.jackson.Discoverable. ```java @JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = "type") interface WidgetFactory extends Discoverable { Widget createWidget(); } ``` -------------------------------- ### Configure Authentication Cache Policy Source: https://www.dropwizard.io/en/stable/manual/auth.html Define the authentication cache policy in the configuration file using CaffeineSpec syntax. This example sets a maximum size and an expiration time. ```yaml authenticationCachePolicy: maximumSize=10000, expireAfterAccess=10m ``` -------------------------------- ### Initialize Environment Variable Substitution Source: https://www.dropwizard.io/en/stable/manual/core.html Configure the Bootstrap object to enable environment variable substitution in the application configuration. ```java public void initialize(Bootstrap bootstrap) { // Enable variable substitution with environment variables EnvironmentVariableSubstitutor substitutor = new EnvironmentVariableSubstitutor(false); SubstitutingSourceProvider provider = new SubstitutingSourceProvider(bootstrap.getConfigurationSourceProvider(), substitutor); bootstrap.setConfigurationSourceProvider(provider); } ``` -------------------------------- ### Register Request Filter with DynamicFeature in Jersey Source: https://www.dropwizard.io/en/stable/manual/core.html Implement a Jersey `DynamicFeature` to conditionally register request filters. This example registers the `DateNotSpecifiedFilter` only for resource methods annotated with `@DateRequired`. ```java @Provider public class DateRequiredFeature implements DynamicFeature { @Override public void configure(ResourceInfo resourceInfo, FeatureContext context) { if (resourceInfo.getResourceMethod().getAnnotation(DateRequired.class) != null) { context.register(DateNotSpecifiedFilter.class); } } } ``` -------------------------------- ### Example Hibernate Query Comment Source: https://www.dropwizard.io/en/stable/manual/hibernate.html Dropwizard automatically prepends comments to Hibernate queries, indicating the origin of the query within your application. This aids in identifying slow or problematic queries. ```sql /* load com.example.helloworld.core.Person */ select person0_.id as id0_0_, person0_.fullName as fullName0_0_, person0_.jobTitle as jobTitle0_0_ from people person0_ where person0_.id=? ``` -------------------------------- ### Define Configuration Variables Source: https://www.dropwizard.io/en/stable/manual/core.html Use Apache Commons Text syntax to reference environment variables within the configuration file. ```yaml mySetting: ${DW_MY_SETTING} defaultSetting: ${DW_DEFAULT_SETTING:-default value} ``` -------------------------------- ### Configure Console Appender with Filter Factory Source: https://www.dropwizard.io/en/stable/manual/configuration.html This example shows how to configure a console appender with a URI filter factory. Filter factories are used to process log events before they are outputted. ```yaml logging: level: INFO appenders: - type: console filterFactories: - type: URI ``` -------------------------------- ### Execute a POST Request in Dropwizard Integration Test Source: https://www.dropwizard.io/en/stable/manual/upgrade-notes/upgrade-notes-0_8_x.html This snippet shows how to perform a POST request to create a new user and verify the response, including the location header. ```java final WebTarget target = ClientBuilder.newClient().target( String.format("http://localhost:%d/api/user", RULE.getLocalPort())); final User user = new User(0L, "John", "Doe"); final Response response = target .request(MediaType.APPLICATION_JSON_TYPE) .accept(MediaType.APPLICATION_JSON_TYPE) .post(Entity.json(user)); assertThat(response.getStatus()).isEqualTo(Response.Status.CREATED.getStatusCode()); final URI location = response.getLocation(); assertThat(location).isNotNull(); final String path = location.getPath(); final long newId = Long.parseLong(path.substring(path.lastIndexOf("/") + 1)); assertThat(newId).isGreaterThan(0); ``` -------------------------------- ### Implement Custom Request Filter in Jersey Source: https://www.dropwizard.io/en/stable/manual/core.html Create a Jersey `ContainerRequestFilter` to intercept and process incoming requests. This example checks for the presence of the 'Date' header and throws a `WebApplicationException` if it's missing. ```java @Provider public class DateNotSpecifiedFilter implements ContainerRequestFilter { @Override public void filter(ContainerRequestContext requestContext) throws IOException { String dateHeader = requestContext.getHeaderString(HttpHeaders.DATE); if (dateHeader == null) { Exception cause = new IllegalArgumentException("Date Header was not specified"); throw new WebApplicationException(cause, Response.Status.BAD_REQUEST); } } } ``` -------------------------------- ### Implement a Custom Command Source: https://www.dropwizard.io/en/stable/manual/core.html Create a subclass of Command to define custom CLI actions with specific arguments. ```java public class MyCommand extends Command { public MyCommand() { // The name of our command is "hello" and the description printed is // "Prints a greeting" super("hello", "Prints a greeting"); } @Override public void configure(Subparser subparser) { // Add a command line option subparser.addArgument("-u", "--user") .dest("user") .type(String.class) .required(true) .help("The user of the program"); } @Override public void run(Bootstrap bootstrap, Namespace namespace) throws Exception { System.out.println("Hello " + namespace.getString("user")); } } ``` -------------------------------- ### Register Bundle in Application Source: https://www.dropwizard.io/en/stable/manual/di.html Initialize and run the DependencyInjectionBundle within the application's run method. ```java @Override public void run(ExampleConfiguration config, Environment environment) { final DependencyInjectionBundle dependencyInjectionBundle = new DependencyInjectionBundle(); dependencyInjectionBundle.run(configuration, environment); } ``` -------------------------------- ### Initialize Dropwizard CLI Source: https://www.dropwizard.io/en/stable/manual/internals.html Constructor for the Cli class, which initializes the parser and registers commands from the bootstrap. ```java public Cli(location : JarLocation, bootstrap : Bootstrap, stdOut: OutputStream, stdErr: OutputStream) { this.stdout = stdOut; this.stdErr = stdErr; this.commands = new TreeMap<>(); this.parser = buildParser(location); this.bootstrap = bootstrap; for (command in bootstrap.commands) { addCommand(command) } } ``` -------------------------------- ### BeanParam Validation with @Valid and @BeanParam Source: https://www.dropwizard.io/en/stable/manual/validation.html This example shows how to use @Valid and @BeanParam for validating parameters passed via query strings. It highlights a limitation where validation messages might not be as instructive if field names don't match query parameter names. ```java @Path("/root") @Produces(MediaType.APPLICATION_JSON) public class Resource { @GET @Path("params") public String getBean(@Valid @BeanParam MyBeanParams params) { return params.getField(); } public static class MyBeanParams { @NotEmpty private String field; public String getField() { return field; } @QueryParam("foo") public void setField(String field) { this.field = Strings.nullToEmpty(field).trim(); } } } ``` -------------------------------- ### Registering Custom ExceptionMapper in Dropwizard Java Source: https://www.dropwizard.io/en/stable/manual/validation Overrides the run method to register the custom MyJerseyViolationExceptionMapper in the Jersey environment, overriding defaults. Also registers resources. Called during application startup; no specific inputs/outputs beyond environment setup; limited to Jersey-based applications. ```Java @Override public void run(final MyConfiguration conf, final Environment env) { env.jersey().register(new MyJerseyViolationExceptionMapper()); env.jersey().register(new Resource()); } ``` -------------------------------- ### Configure Maven Dependencies Source: https://www.dropwizard.io/en/stable/getting-started.html Add the Dropwizard BOM and core library to your project's pom.xml file. ```xml io.dropwizard dropwizard-bom 5.0.1 pom import ``` ```xml io.dropwizard dropwizard-core ``` -------------------------------- ### Configure Basic Proxy Authentication Source: https://www.dropwizard.io/en/stable/manual/client.html Set up basic authentication for a forward proxy by specifying the host, port, scheme, username, password, and non-proxy hosts in the YAML configuration. ```yaml proxy: host: '192.168.52.11' port: 8080 scheme : 'https' auth: username: 'secret' password: 'stuff' nonProxyHosts: - 'localhost' - '192.168.52.*' - '*.example.com' ``` -------------------------------- ### Configure Server Root Path Source: https://www.dropwizard.io/en/stable/manual/core.html Configure the `rootPath` in the server configuration to serve static assets from the root URL. This is useful when Dropwizard backs a Javascript application and the main application is moved to a sub-URL. ```yaml server: rootPath: /api/ ``` -------------------------------- ### Configure GZip Settings Source: https://www.dropwizard.io/en/stable/manual/configuration.html Configuration for GZip compression, specifically setting the buffer size for compressed responses. ```yaml server: gzip: bufferSize: 8KiB ``` -------------------------------- ### Configure HTTP/2 Connector Source: https://www.dropwizard.io/en/stable/manual/upgrade-notes/upgrade-notes-1_0_x.html Replace the deprecated SPDY connector configuration with the HTTP/2 integration in your YAML configuration file. ```yaml # - type: spdy3 - type: h2 port: 8445 keyStorePath: example.keystore keyStorePassword: example ``` -------------------------------- ### Configure View Engines in YAML Source: https://www.dropwizard.io/en/stable/manual/views.html Define view engine settings in the Dropwizard configuration file. ```yaml views: mustache: cache: false # views: config->mustache freemarker: strict_syntax: true ```