Thursday, September 24, 2015

JPact, trundling towards an MVP

Simply put, consumer driven contracts are awesome. The ability to specify, control and version their interactions between a client and server is nothing less than godly. My only real problem is with the current implementations.

I'm not a big fan of them being client driven, mostly because I'm happiest in a collaborative setting. Lets agree a contract and work from there. If both client and server stick to the contract then happy days.

Which is why I started writing jPact. jPact is pretty close to a client driven contract framework without the client driven part. Everything starts with the contract, a JSON file specifying an interaction between client and server. If everyone does their job, both client and server behave exactly as laid out in the pact file.

The code isn't in a massively working state. but its slowly trundling towards a minimal viable testing product. I suppose i'd better do some more work.

Anywho : heres the source so far if anyone's interested

Thursday, May 7, 2015

How to setup docker as a development tool OSX

  • Install Virtualbox
  • Assuming you have Brew installed, install boot2docker
  • If you use a proxy to connect to the internet, Implement transparent proxying (this'll be a bit of work, and worthy of a blog post of its own)
  • Setup your internal networking to allow direct access to containers
    • In the Global settings of Virtual box, add a second 'host-only-network', and give it these settings:
      • ipv4 address : 172.16.0.1
      • ipv4 network mask : 255.255.255.0
      • ipv6 address : blank
      • ipv6 network mask length  : 0
      • Uncheck DHCP server
    • In the settings of the boot2docker vm, add the host only adapter we created in the last step as 'Adapter 3'
    • Start the boot2docker vm, adding the environment variables as instructed
    • Remote onto the boot2docker vm and run the following
      • sudo ifconfig eth2 172.16.0.11
      • sudo ifconfig eth1 netmask 255.255.0.0
    • On your mac, run the following
      • sudo route -n add 172.17.0.0/16 $(boot2docker ip)
    • Bring up a test container :
      • docker run -t -i ubuntu /bin/bash
    • The containers should now be network accessible, to test this, in another terminal run
      • docker inspect
      • There'll be an IP address in the output, it should be ping-able
  • We'll use skydock / skydns to provide accessible host names for the containers
    • docker run -d -p 53:53/udp --name skydns crosbymichael/skydns -domain docker
    • docker run -d -v /var/run/docker.sock:/docker.sock --name skydock crosbymichael/skydock -ttl 30 -environment dev -s /docker.sock -domain docker -name skydns
  • To route all dns requests for the docker domain to a skydock/skydns server, run the following
    • sudo echo "nameserver 192.168.59.103" > /etc/resolver/docker
  • Docker containers should now be available at addresses in the form of, . .dev.docker i.e. rabbitmq01.rabbitmq.dev.docker
  • If multiple containers are running with the same image, they can be loadbalanced with .dev.docker i.e.  rabbitmq.dev.docker

Friday, February 27, 2015

Groovy closures and Awaitility are a match made in heaven

The awaitility pattern for waiting for a condition to be true has always irked me, it's always seemed like something that should be shorter and simpler. If you want to implement a wait in awaitility, you implement a callable interface and hand that off to awaitility to call repeatedly until its satisfied or times out. Giving you code that looks something like this …
Steps.java
@Then("a payload is sent to the destination")
public void aPayloadIsSentToTheDestination() throws Exception {
   PayloadIsSentChecker aPayloadIsSent = new PayloadIsSentChecker(acceptanceTestAmqpClient, Destination.EXAMPLE);
   await().atMost(FIVE_SECONDS).until(aPayloadIsSent);
}
PayloadIsSentChecker.java
public PayloadIsSentChecker(AcceptanceTestAmqpClient acceptanceTestAmqpClient, Destination destination) {
   this.acceptanceTestAmqpClient = acceptanceTestAmqpClient;
   this.destination = destination;
}

@Override
public Boolean call() throws Exception {
   Message message = acceptanceTestAmqpClient.lastMessageFromAcceptanceOutbound(destination);
   if (message == null) {
      return false;
   }
   return true;
}
However, if we bypass the callable interface entirely and use a groovy closure, with a mixin [AwaitilitySupport] from awaitility instead, we get
def thePayloadArrivesAt(Destination destination) {
   await().atMost(FIVE_SECONDS).until {
      assertThat(acceptanceTestAmqpClient.lastEventFromAcceptanceOutbound(destination), notNullValue())
   }
}
And voila, a significant reduction in boiler plate code.