logo

ShrimpWorks

// why am I so n00b?

Frequently while implementing HTTP API or other HTTP clients, you want to be able to test your client implementation against an actual HTTP service, which helps validate that your headers are set correctly, body is serialised appropriately, and responses are parsed as expected.

This can be done through the use of various additional libraries and mocking frameworks, however I’d argue that for most use cases, something that can simply validate and respond to an HTTP request is more than enough.

For such cases, the example below achieves just that. I find this much quicker and easier to set up, requiring no additional dependencies or learning of a new DSL, and test setup, execution and teardown are at least a factor of 3-4 times faster for the same test suite.

import com.sun.net.httpserver.HttpServer;

public class MyAPIClientTest {
	private static final int PORT = 56897;

	private HttpServer server;

	@BeforeEach
	public void before() throws IOException {
		this.server = HttpServer.create(new InetSocketAddress("127.0.0.1", PORT), 0);
		this.server.setExecutor(Executors.newSingleThreadExecutor());
		this.server.start();
	}

	@AfterEach
	public void after() {
		this.server.stop(0);
	}

	@Test
	public void shouldGetBalance() {
		// test setup - define expectations, set up expected response
		this.server.createContext("/za/pb/v1/accounts/172878438321553632224/balance", e -> {
			try {
				assertEquals(e.getRequestMethod(), "GET");
				assertEquals(e.getRequestHeaders().getFirst("Authorization"), "Bearer Ms9OsZkyrhBZd5yQJgfEtiDy4t2c");

				// JSON.toBytes() is a simple wrapper around a Jackson writeValueAsBytes() call
				byte[] result = JSON.toBytes(Map.of(
						"data", Map.of(
								"accountId", "172878438321553632224",
								"currentBalance", BigDecimal.valueOf(28857.76),
								"availableBalance", BigDecimal.valueOf(98857.76),
								"currency", "ZAR"
						),
						"links", Map.of("self", "/za/pb/v1/accounts/172878438321553632224/balance"),
						"meta", Map.of("totalPages", 1)
				));
				e.sendResponseHeaders(200, result.length);
				e.getResponseBody().write(result);
			} finally {
				e.close();
			}
		});
    
		// run test using my client against the API
		MyClient client = new MyClient("127.0.0.1", PORT);
		Balance = client.getBalance("172878438321553632224");
		// validate response client gathered, etc...
    }
}

As you can see, we’ve simply set up an expectation based on URL and method, validated that the Authorization was provided as expected, and then constructed a suitable response in the format the upstream API should be providing.

In place of the constructed API response I’ve used here, one could also easily place the contents of real or documented example API responses directly into the response, for your client to consume.

There’s a strong tendency to want to run everything in Docker these days, especially if you’re trying to run something as an always-on service, since passing --restart=always to your run invocation or Docker Compose configuration ensures that running containers start back up after reboots or failures, and seems to involve a little less “black magic” than actually configuring software to run as services directly on a host.

The downside to this is the approach is that running a service in a container leads to significantly longer startup times, more memory and CPU overhead, lost logs, and in my opinion offer a false sense of security and isolation since most images are still configured to run as root, and more often than not large swathes of the host filesystem are mounted as volumes to achieve simple tasks.

There’s also a belief that your software will magically run anywhere - but if you’re writing Java (or any JVM language) code - that’s one of Java’s biggest selling points - it already has its own VM your code is running in, no most platforms!

Therefore, let’s see how easy it actually is to configure our software to run as a standard system service, providing us with the ability to run it as a separate restricted user, complete with standard logging configuration, and give us control over via standard service myservice start|status|restart|stop commands.

arrow Continue Reading ...

It’s a really simple thing, but I’ve been using this simple “pattern” for defining simple value objects for years, and it has served me well.

While there’s nothing particularly special about this style, I still see a significant amount of Java code needlessly following the JavaBeans style, when using these objects as Beans in the strict sense is not actually desired, intended, or required, and simply makes code needlessly verbose and leaves objects implemented as Beans open to abuse due to leaving their internal state open for mutation.

This pattern works well over traditional JavaBeans because:

  • it’s immutable - invaluable for concurrent or multi-threaded applications where you don’t want to give applications the ability to change values as they please
  • it’s neat - due to being immutable, there’s no need for superfluous “setters”, and if there are no setters, there’s no need for “getters”, so the code is dead simple and easy to work with
  • it’s portable - these objects are trivial to serialise using either Java Serialisation (or any of the preferable drop-in replacements), almost any serialisation library will be able to serialise them, and Jackson can deserialise them without any additional code
  • due to all the above, they’re also ideal for use as messages in event-driven systems

Here’s an example of a simple object implemented in this style:

import java.beans.ConstructorProperties;

public class User implements Serializable {
  private static final long serialVersionUID = 1L;

  public final String email;
  public final String name;
  public final Address address;

  @ConstructorProperties({ "email", "name", "address" })
  public User(String email, String name, Address address) {
    this.name = name;
    this.email = email;
    this.address = address;  
  }
}

This object is now serialisable and deserialisable via Java serialisation or better alternatives such as FST (just leave off Serializable if you don’t need that), as well as JSON serialisation libraries such as Jackson or GSON.

More a curiosity than an actual useful project, I just had an Idea I wanted to try out, and this is the result.

This Java application (or library, if you want to include it in your own project) simply takes a source image, a couple of optional parameters, and outputs a new image with a halftone- like effect.

Briefly, works by stepping through the pixels of the source image at an interval defined by the dot size specified, samples the brightness of that pixel, and draws a circle onto the destination image, scaled according to the source pixel brightness.

For reference, take a look at the java.awt Graphics2D, Image and BufferenImage classes. It’s really nice to half a whole bunch of image processing and drawing capabilities available within the standard library, rather than needing to rely on external things (as I recently discovered to be the case with Ruby - pretty much all image processing is done via an ImageMagick dependency).

The source, documentation and a download are available from the image-halftone GitHub project page.

Now that we have dependency management with Ivy working along with everything else covered before, we’ve covered almost everything required to start building real projects with Ant.

Another thing any real project should have, is unit tests. Thankfully, using the scaffolding already put in place in earlier parts of this series, integrating a JUnit testing task into our existing build script is really straight-forward.

arrow Continue Reading ...

So far, we’ve covered the basics of creating a re-distributable .jar package suitable for use as a library, and building a Jar file which can be run by a user or server process.

A major part of any non-trivial application these days is the inclusion and re-use of 3rd party libraries which implement functionality your applications require. When a project starts, it’s probably easy enough to manually drop the odd jar library into a lib directory and forget about it, but maintaining a large application which depends on many libraries, which in turn depend on additional libraries for their own functionality, it can quickly turn into a nightmare to manage.

To solve this problem, many dependency management tools have been introduced, most notably, Apache Maven. Maven however, is so much more than just a dependency management tool, and is actually intended to manage your entire project structure. I believe however, the combination of Ant and Ivy provides far more flexibility, extensibility and control over your build and dependency management processes.

So, let’s integrate Apache Ivy into our Ant script as we left it in part 2.

arrow Continue Reading ...

In part 1, we went over the basics of using Ant to create a redistributable .jar file, suitable for use as a library in other projects. A lot of the time however, you’re probably going to want to be building things which can actually be run as regular Java applications.

Once again, the code for this tutorial is available in GitHub. More usefully, you may want to see the diff between the part 1 script and the new one.

Here’s a quick explanation of what we’ve done to achieve an executable jar file:

arrow Continue Reading ...

Apache Ant is a general-purpose build tool, primarily used for the building of Java applications, but it is flexible enough to be used for various tasks.

In the Java world at least, Ant seems to be largely passed over for the immediate convenience and IDE support of Maven, however long term, I believe a good set of Ant scripts offer far more flexibility and room for tweaking your build processes. The downside is that there’s a lot of stuff you need to learn and figure out and build by hand.

In this series of tutorials, I’ll try to document the process of learning I’ve gone through building and maintaining Ant build files, from the most basic of “just compile my stuff” steps to automatic generation of JavaDoc output, dependency management using Ant’s companion, Ivy, unit testing using JUnit, and integrating with some additional tools I’ve been using, such as Checkstyle and FindBugs.

For part 1 of this tutorial, I’ve created a simple Hello World library. It doesn’t have a main executable itself, the goal of this is to produce a .jar file we can include in other projects, to start our Ant script off fairly simply.

The source for this project can be found in GitHub. Here’s the breakdown of everything going on in this project:

arrow Continue Reading ...

Some thing I’ve been using for a while, and which recently became useful at work as well, is a simple HTTP service written in plain Java with existing JRE functionality, using an HttpServer.

Here’s a simple “main()” which sets up two basic “pages”, a root (/) and one which echoes your browser’s request headers (/headers/).

public class SimpleHTTPService {

    public static void main(String[] args) throws IOException {
        HttpServer server = HttpServerProvider.provider().createHttpServer(new InetSocketAddress(8080), 0);

        server.createContext("/", new HttpHandler() {
            @Override
            public void handle(HttpExchange he) throws IOException {
                byte[] output = "Hello world!".getBytes();
                he.sendResponseHeaders(200, output.length);
                he.getResponseBody().write(output);
            }
        });

        server.createContext("/headers", new HttpHandler() {
            @Override
            public void handle(HttpExchange he) throws IOException {
                StringBuilder result = new StringBuilder("Request Headers");
                for (Entry< String, List< String>> header : he.getRequestHeaders().entrySet()) {
                    result.append(String.format("%s", header.getKey()));
                    for (String val : header.getValue()) {
                        result.append(String.format("%s", val));
                    }
                    result.append("");
                }

                byte[] output = result.toString().getBytes();
                he.sendResponseHeaders(200, output.length);
                he.getResponseBody().write(output);
            }
        });

        server.setExecutor(Executors.newCachedThreadPool());

        server.start();

        System.out.println("HTTP Listening on port " + server.getAddress().getPort());
    }
}

Running this as-is will allow you to load up the URLs http://localhost:8080/ and http://localhost:8080/headers/ and see some output generated by the two registered contexts.

I’ve defined simple anonymous inner class contexts here, as it’s easy to play with, but obviously you can go wild and develop proper structures for these.

Combined with something like FreeMarker, and you’ve got a pretty neat way to deploy simple stand-alone HTTP applications written in Java with minimal external dependencies.

It’s also extremely useful for creating mock-ups services for use in unit tests for HTTP clients.

Here’s a small Java class I’ve been using in loads of applications and things for a few years (it’s evolved a little over the years).

It simply exposes a few very basic HTTP methods (for HEAD, GET and POST) which all just return strings containing the web server’s response. It’s seemed pretty useful and reliable in applications large and small, so maybe it’s of some use to someone else as well.

Download HttpUtils