Wednesday, November 25, 2015

Setting up Dropwizard

Generate self signed certificate.
  • $ keytool -genkey -alias selfsigned -keyalg RSA -keystore keystore.jks -keysize 2048
Export the keystore as certificate (.crt):
  • $ keytool -export -alias selfsigned -file selfsigned.crt -keystore keystore.jks

Import that certificate into your cacerts, the default Java keystore. You may need to do this as root, or with sudo. Go to the $JAVA_HOME/jre/lib/security directory, and run:
$ keytool -import -trustcacerts -alias selfsigned -file $SSL_FOLDER/selfsigned.crt -keystore cacerts

Put the following config in config.yml of dropwizard:

config.yml:
server:  adminMinThreads: 1
  adminMaxThreads: 64
  adminContextPath: /admin
  applicationContextPath: /
  applicationConnectors:    - type: http
      port: 8080
    - type: https
      port: 8443
      keyStorePath: ./keystore.jks
      keyStorePassword: password
      trustStorePath: $JAVA_HOME/jre/lib/security/cacerts
      trustStorePassword: changeit
      certAlias: selfsigned
  adminConnectors:    - type: http
      port: 8081
    - type: https
      port: 8444
      keyStorePath: ./keystore.jks
      keyStorePassword: password
      keyStoreType: JKS
      validateCerts: false


To have caching control headers being returned on every response:
Add the following filter:

public class CacheControlFilter implements Filter{

    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain) throws IOException, ServletException {

        HttpServletResponse resp = (HttpServletResponse) response;

        // Add whatever headers you want here        resp.setHeader("Cache-Control", "public, max-age=500000");
        resp.setHeader("Expires", new Date().getTime()+500000 + "");

        chain.doFilter(request, response);
    }

    public void destroy() {}

    public void init(FilterConfig arg0) throws ServletException {}
}

And then in your Application#run():

environment.servlets().addFilter("CacheControlFilter", new CacheControlFilter())
        .addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");

Similarly, for CORS headers add a filter:

public class CORSFilter implements ContainerResponseFilter {

    @Override    public void filter(ContainerRequestContext request,
                       ContainerResponseContext response) throws IOException {
        response.getHeaders().add("Access-Control-Allow-Origin", "*");
        response.getHeaders().add("Access-Control-Allow-Headers",
                "origin, content-type, accept, authorization");
        response.getHeaders().add("Access-Control-Allow-Credentials", "true");
        response.getHeaders().add("Access-Control-Allow-Methods",
                "GET, POST, PUT, DELETE, OPTIONS, HEAD");
    }
}

and initialize it as:
environment.jersey().register(new CORSFilter());

Book notes: Designing Data-Intensive Applications: The Big Ideas Behind Reliable, Scalable, and Maintainable Systems, by Martin Kleppmann

My notes from the excellent book on how software has evolved to handle data from hierarchical databases to the NoSQL -  https://www.goodrea...