Friday, August 11, 2017

Clean up Docker artifacts in dev environments

Remote dev environments that get continuous Docker deployments should have their images and volumes cleaned up regularly.

Pass the following commands over SSH to the remote server, perhaps in a Jenkins job for example:

 sudo -- bash -c 'docker volume rm $(docker volume ls -f dangling=true -q)' > /dev/null 2>&1  
 sudo -- bash -c 'docker images --quiet --filter=dangling=true | xargs --no-run-if-empty docker rmi' > /dev/null 2>&1  
 echo $?  

echo $?  .. is used at the end because if the images are already cleaned up there may be an exit status code indicating and error .. which can actually safely be ignored so echo $? will evaluate it so that Jenkins will not report the job as failed.

Thursday, August 10, 2017

Connect JasperServer to a Postgres Data Source with SSL

In response to question such this:


In the JDBC connection string, just add this:


i.e. just setting ssl=true is not enough.

And just to state the obvious, your Postgres server must support SSL connections.

Thursday, March 2, 2017

The bait and switch of open source

Great presentation by Katrina Owen. You need to sign up for a Safari Books account but (at this time) its free and does not require a credit card. If you don't want to give them your email, just use mailinator or something.

Some good points from this talk:

  • Understand the the difference of "issues" vs "symptoms" in your product
  • When explaining your product, talk about it's benefits, not its features
  • "Manage your energy rather than your time"

Wednesday, March 1, 2017

Boilerplate Java for AWS Lambda invoked from AWS API Gateway

import java.util.HashMap;
import java.util.Map;

public class LambdaAPIGateway {

    public Map<String, Object> handleRequest(Map<String, Object> request, Context context) {
        LambdaLogger logger = context.getLogger();
        logger.log("Function version: " + context.getFunctionVersion() + "; ");
        logger.log("Event: " + request.toString());
        String bodyAsJson = "{\"data\":\"ok\"}";
        Map<String, Object> result = Respond(200, bodyAsJson, context);
        return result;

    public static Map<String, Object> Respond(int httpStatus, String bodyAsJson, Context context)  {
        Map<String, Object> retval = new HashMap<>();
         Response MUST be in a specific format with "headers"; "statusCode" and "body" ONLY
         Example: { "headers": {"Content-Type":"application/json"}, "body":"...", "statusCode":200 }
         (under the heading Output Format of a Lambda Function for Proxy Integration)
        Map<String, Object> headers = new HashMap<>();
        headers.put("Content-Type", "application/json");
        headers.put("x-request-id", context.getAwsRequestId());
        retval.put("headers", headers);
        retval.put("statusCode", httpStatus);
        retval.put("body", bodyAsJson);
        return retval;

The AWS documentation provides a Java example which uses inputStream and outputStream and takes a lot more code:

I like this version better because is simpler and shorter.

More comprehensive example here: