· neo4j

neo4j Unmanaged Extension: Creating gzipped streamed responses with Jetty

I recently wrote a blog post describing how we created a streamed response and the next thing we wanted to do was gzip the response to shrink it's size a bit.

A bit of searching led to GZIPContentEncodingFilter popping up a lot of times but this is actually needed for a client processing a gripped response rather than helping us to gzip a response from the server.

I noticed that there was a question about this on the mailing list from about a year ago although Michael pointed out that the repository has now moved and the example is available here instead.

I adapted the example a bit and ended up with the following lifecycle plugin:


package com.markandjim;

public class GZipInitialiser implements SPIPluginLifecycle {
    private WebServer webServer;

    @Override
    public Collection<Injectable<?>> start(NeoServer neoServer) {
        webServer = getWebServer(neoServer);
        GzipFilter filter = new GzipFilter();

        webServer.addFilter(filter, "/*");
        return Collections.emptyList();

    }

    private WebServer getWebServer(final NeoServer neoServer) {
        if (neoServer instanceof AbstractNeoServer) {
            return ((AbstractNeoServer) neoServer).getWebServer();
        }
        throw new IllegalArgumentException("expected AbstractNeoServer");
    }

    @Override
    public Collection<Injectable<?>> start(GraphDatabaseService graphDatabaseService, Configuration configuration) {
        throw new IllegalAccessError();
    }

    @Override
    public void stop() {

    }
}

I then added the following line to 'resources/META-INF/services/org.neo4j.server.plugins.PluginLifecycle:


com.markandjim.GZipInitialiser

After compiling that and deploying the JAR to the 'plugins' I tried calling the end point using cURL:


$ curl -H "Accept-Encoding:gzip,deflate" -v  http://localhost:7474/unmanaged/subgraph/1000/1
* About to connect() to localhost port 7474 (#0)
*   Trying ::1...
* Connection refused
*   Trying 127.0.0.1...
* connected
* Connected to localhost (127.0.0.1) port 7474 (#0)
> GET /unmanaged/subgraph/1000/1 HTTP/1.1
> User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8r zlib/1.2.5
> Host: localhost:7474
> Accept: */*
> Accept-Encoding:gzip,deflate
>
< HTTP/1.1 200 OK
< Content-Type: text/plain
< Access-Control-Allow-Origin: *
< Content-Encoding: gzip
< Transfer-Encoding: chunked
< Server: Jetty(6.1.25)

---

gibberish!

The GZIPContentEncodingFilter that I mentioned earlier comes in handy if we want to call the end point from a Jersey client:


public class Neo4jJerseyClient {
    public static void main(String[] args) {
        Client client = Client.create();
        client.addFilter(new GZIPContentEncodingFilter(false));

        WebResource webResource = client.resource("http://localhost:7474/unmanaged/subgraph/1000/1");

        ClientResponse response  = webResource.header("accept-encoding", "gzip,deflate").get(ClientResponse.class);

        System.out.println("response = " + response.getEntity(String.class));
    }
}

We could also call it using HTTParty from the land of Ruby:


response = HTTParty.get("http://localhost:7474/unmanaged/subgraph/1000/1", 
  :headers => { 'Accept-Encoding' => 'gzip,deflate' } )

p response
  • LinkedIn
  • Tumblr
  • Reddit
  • Google+
  • Pinterest
  • Pocket