Week Notes 22#32
14 August 2022 | 9:06 pm

A warm week, and giving Cookie some more time on her own

  • It's been another hot week
    • Not quite as hot the other week, but still early 30s
    • Lots of fans, ice in drinks and mango sorbet
  • Down to London for the weekend to celebrate Mum's birthday
    • I headed up earlier on Friday to avoid train strikes, and got to Miller and Carter for dinner 😋 was our first meal out as a family since March 2020, and was very nice
    • Had some good food - mint chocolate cheesecake, Dishoom's chicken biryani, some home-made nachos, and a great steak to name a few
    • Got to see all the cool changes at the bungalow
    • Surprisingly got a nice hello from Luna
  • Haven't actually written any code for HTTP caching, but I've been doing some research into it and that I'll need to write a library for the new RFC 9111 standard
  • Was nice to have some train journeys to just sit down and blog/tinker away at things
  • Cookie was home alone on Thursday while we went to Sherwood to pick up a few things
    • Picked up some nommy stuff from Nibbles in Sherwood while we were there
    • Saw Dylan and had a bit of a catchup
  • Came around time for my next therapy, and a lot to catch up on
  • Went into town to measure up for a tailored suit 😱
    • lots and lots of choices to make, but managed to get there in the end, and excited to see what the result will be
    • Also led to a good three hours of Cookie being on her own, which was mostly OK
  • May be able to get Linux at work 👀
  • Installed the Linux jigsaw game palapeli for a bit of something over the weekend, which was quite useful, as well as on the train home
  • Had a lovely welcome from Cookie when I got home 🥰

Watched:

  • Ted Lasso
  • Star Trek: Deep Space 9
  • Selling Sunset
  • Glow


Converting HTTP requests to Wiremock stubs, with Go
12 August 2022 | 4:17 pm

If you're using Wiremock, sometimes you want to be able to quickly generate stub mappings from an existing server, rather than hand-crafting it yourself, to give you a like-for-like stub.

I've written the following - somewhat hacky - script to produce a Wiremock stub mapping from a given HTTP response.

This can either be plugged into a command-line tool like so, or could be used with an existing HTTP call, for instance when plugged into your existing HTTP clients that integrate with the upstream server.

package main

import (
 "encoding/json"
 "fmt"
 "io"
 "log"
 "net/http"
 "net/url"
 "os"
)

type request struct {
 Method string `json:"method"`
 URL string `json:"url"`
}

type response struct {
 Status int `json:"status"`
 Body string `json:"body"`
 Headers map[string]string `json:"headers"`
}

type wiremockStub struct {
 Request request `json:"request"`
 Response response `json:"response"`
}

func toHeaders(headers http.Header) map[string]string {
 h := make(map[string]string)
 for k, v := range headers {
 h[k] = v[0]
 }
 return h
}

func toRequestURL(requestURL *url.URL) string {
 u := requestURL.Path
 if requestURL.RawQuery != "" {
 u += "?" + requestURL.RawQuery
 }
 if requestURL.RawFragment != "" {
 u += "#" + requestURL.RawFragment
 }

 return u
}

func toWiremock(resp *http.Response) *wiremockStub {
 // NOTE: we don't have too much required in the request, just method and the URL path on the incoming request, but we could do more like basing on headers, HTTP Basic Auth, and body
 wmReq := request{
 Method: resp.Request.Method,
 URL: toRequestURL(resp.Request.URL),
 }

 wmResp := response{
 Status: resp.StatusCode,
 Headers: toHeaders(resp.Header),
 }

 defer resp.Body.Close()
 body, err := io.ReadAll(resp.Body)
 if err == nil {
 wmResp.Body = string(body)
 }

 return &wiremockStub{
 Request: wmReq,
 Response: wmResp,
 }
}

func main() {
 url := os.Args[1]
 resp, err := http.Get(url)

 if err != nil {
 log.Fatal(err)
 return
 }

 s, err := json.Marshal(toWiremock(resp))
 if err != nil {
 log.Fatal(err)
 os.Exit(1)
 }

 fmt.Println(string(s))
}

This can be run like so:

go run main.go "https://www-api.jvt.me/micropub?q=source&url=https://www.jvt.me/mf2/2022/04/odxjc/"

And produces the following pretty-printed JSON:

{
 "request": {
 "method": "GET",
 "url": "/micropub?q=source&url=https://www.jvt.me/mf2/2022/04/odxjc/"
 },
 "response": {
 "body": "{\"type\":[\"h-entry\"],\"properties\":{\"syndication\":[\"https://brid.gy/publish/github\"],\"name\":[\"lestrrat-go/jwx at develop/v1\"],\"published\":[\"2022-04-12T12:53:47.383098795Z\"],\"category\":[\"go\",\"jose\",\"jwt\"],\"like-of\":[\"https://github.com/lestrrat-go/jwx\"],\"post-status\":[\"published\"]}}",
 "headers": {
 "Cache-Control": "no-cache, no-store, max-age=0, must-revalidate",
 "Content-Type": "application/json",
 "Date": "Fri, 12 Aug 2022 16:14:15 GMT",
 "Expires": "0",
 "Pragma": "no-cache",
 "Strict-Transport-Security": "max-age=15724800; includeSubDomains",
 "X-Content-Type-Options": "nosniff",
 "X-Frame-Options": "DENY",
 "X-Xss-Protection": "1; mode=block"
 },
 "status": 200
 }
}

The first script I write in a new job: `gg`
12 August 2022 | 3:25 pm

A few years back (in fact, 7(!) years ago) I started moving all my working directories for development out from my home directory and into the $HOME/workspaces directory.

This cleanup has been hugely beneficial for two reasons - firstly, I have a bit more structure to it all, and it makes it easier to manage than everything littering my home directory, but secondly, I've written a helper method which allows me to wksp jvt.me to cd $HOME/workspaces/jvt.me, but gives me handy autocomplete on just directories in $HOME/workspaces, so I can jump into child directories more quickly.

Now, on my personal machines, this is a little unstructured, but on my professional machines has a more rigid structure to follow how we use our Git hosting.

(Note that the below examples have been anonymised where appropriate)

At Capital One, we had GitHub enterprise, so I'd be regularly working in a mix of organisations and repositories, leading to a project structure like so:

workspaces/
PSD2/
identity-service/
jamietanna/
dotfiles-c1/

While working in the Central Digital and Data Office (CDDO), I was working on my personal machine and mainly out of a single GitHub organisation, so I'd have the following structure:

workspaces/
cddo/
federated-api-model/

And finally at Deliveroo, working mainly out of a single GitHub organisation, I've got the following structure:

workspaces/
deliveroo.engineering/
jamietanna-dotfiles/
_external/
deepmap/
oapi-codegen/

You can see here that they're all completely different structures, and depend entirely on the company I'm in and how it's structured.

To simplify the creation and management of these repositories, I've ended up writing a script called gg, which stands for Git Get, and is a tool to easily git clone into the directory structure as expected, with autocomplete based on already downloaded repos.

I won't share it - as the implementation doesn't really matter too much - but the key takeaway is that being able to automate these things is pretty handy, and cuts down on a lot of typing.

For instance, I can type gg deliveroo.engineering instead of cd $HOME/workspaces && git clone https://github.com/deliveroo/deliveroo.engineering, and hope that the directory doesn't already exist.

Interestingly, I found after writing it that one of our internal CLIs, roo, does have similar support for this, which is cool because more engineers will get to work within a consistent, somewhat opinionated setup.



More News from this Feed See Full Web Site