Saturday, January 05, 2019

Ristex 0.1.0 Released

At about 11:46 pm, I got version 0.1.0 of Ristex released to Maven central. This marks the first Scala library I would be releasing! Yay!! 🎉

It should now be available for inclusion with the following sbt configuration:

// ${version} = 0.1.0
libraryDependencies += "io.geekabyte.ristex" %% "ristex" % "${version}"


And by the way, the release process was not as painful as I envisaged. Read further, for my thought on this.

What is Ristex

Ristex is a parser combinator library for parsing the RIR Statistics Exchange files. In theory it should work with the files published by all regional internet registry, in practice, it has only been used with files published by RIPE NCC.

Ristex uses Atto, which is a compact, pure-functional, incremental text parsing library for Scala. Infact, Ristex essentially extends Atto to cater for parsing the RIR Statistics Exchange files, and it makes no attempt to abstract it away, hence all of Atto's API are directly available for use with Ristex.

The idea for Ristex came up when I started working on a fun project to create a JSON format for the CSV like format of the RIR Statistics Exchange files. While working on this, it became apparent that it would be good to have a nicer way to parse the exchange files instead of relying on regex. And since I have always wanted to explore the idea of Parser Combinators in general and the Atto library in particular, it took little persuasion to temporarily shelf the project to create a JSON format, and create a parser combinator library to parse them instead.

Releasing to Maven Central Via SBT

Releasing the library to maven with sbt was relatively painless. I was expecting it to be much of a frustrating experience but I was pleasantly surprised. I guess having previously documented How To Publish Software Artifacts To Central Repository, also helped.

I found this post: An in depth guide to deploying to Maven Central with sbt by Leonard Ehrenfried to be particularly helpful.

The only snag I encountered was related to getting the PGP key published to a public key server. For reasons I still do not know, running the command:

`pgp-cmd send-key ${keyname} hkp://pool.sks-keyservers.net` 

as specified in the post above was not working. This caused the release process to fail a couple of times since maven could not verify the integrity of what was being published.

I had to result to manually uploading the PGP key using the web interface provided by https://pgp.surfnet.nl/. Apart from this, everything went smoothly.

Anyways, the source of Ristex is available on Github, so do feel free to poke around!

Saturday, December 08, 2018

Understanding JavaScript Modules As A TypeScript User

This post, is the first in a series of post that I will be writing about Modules in TypeScript. It is a continuation of the process of jotting down the various things I learnt while building ip-num. The previous post like this one, was Declaration Files in TypeScript: An Introduction. In which I shared how I came to wrap my head around declaration files in TypeScript.

Since the topic of Modules is quite an expansive one, instead of jamming everything I need to write into one blogpost, I will be spreading it out, across various posts, that would be published in the coming weeks/months.

This post is to get the ball rolling on that, and It would focus mainly on introducing the concepts of modules as we have them within the JavaScript ecosystem.

Since TypeScript is but a superset of JavaScript and JavaScript is still its only transpiler target, one really cannot get away from having to understand how things work in the JavaScript land in other to be able to deeply understand how various aspects of TypeScript fits together.

Modules are just one example of this.

Saturday, September 22, 2018

Easing Into Cats, And The Case For Category Theory Inspired Abstractions

Cats is a lightweight, modular, and extensible library for functional programming in Scala. On its website, it is stated that the name “cats” is a playful shortening of the word, category - so it has nothing to do with the animal: cat (if you ever wondering), but with category theory :)

It is a library that I have personally found to be helpful in making functional programming in Scala less confusing. It does this by being more concrete and more obvious with regards the various patterns and abstractions that arises from a valid logical conclusion of programming with functions in a statically typed language that has higher-kinded types.

Unfortunately, due to the relative unfamiliarity with functional programming and the various abstraction that comes with it, the Cats library is usually approached with hesitation amongst a sizable amount of software developers.

The sentiments I have seen expressed directly or indirectly is that introducing Cats would inadvertently fling developers into the deep ends of various unknown, academic and good for nothing, category theory inspired abstractions, that only confuses and add complexity. Since nobody wants this, the decision usually gets made not to bother with a library like Cats.

Nothing can be farther from the truth.

Saturday, July 21, 2018

How to Make Aggregates Directly Handle Commands In Axon

In 2015, I created the exploringCQRSwithAxon example project while learning about CQRS and the Axon Framework.

When I did, I set up the example project in such a way that it uses command handler classes. The setup was as follows:
  1. A controller receives a request via an endpoint
  2. Controller turns the request into a command and put it on the command gateway
  3. The command handler classes listens to specific commands. When a particular command it listens to is published via the command gateway, it loads the aggregate from the repository.
  4. The command handler class calls method on the loaded aggregate with the command that was published.
The 3rd step, most of the time, is unnecessary and can be eliminated. This is because the command handler class usually just serves as a dummy proxy that proxies commands to the aggregates.


Saturday, July 14, 2018

ip-num 1.1.1 is Released

ip-num, version 1.1.1 is now available.


I will quickly highlight some of the new features, improvement and some bug fixes contained in this release.

Support for IPv4-Mapped IPv6 Address

It is possible to embed an IPv4 address within an IPv6 address. Doing this involves using the least significant 32 bits to encode the IPv4 address, the next least 16 significant bits is turned On, and the remaining 80 bits turned Off. The format of the "IPv4-mapped IPv6 address" Looks like this:

   |                80 bits               | 16 |      32 bits        |
   +--------------------------------------+--------------------------+
   |0000..............................0000|FFFF|    IPv4 address     |
   +--------------------------------------+----+---------------------+

ip-num now supports creating these kinds of IPv6 addresses. This can be achieved in various ways:

Converting from an existing IPv4
import { IPv4 } from "ip-num/IPv4";

let ipv4 = new IPv4("74.125.43.99")
ipv4.toIPv4MappedIPv6().toString() // produces ::ffff:4a7d:2b63

From an existing IPv4 using convenience method on IPv6
import { IPv6 } from "ip-num/IPv6";

let ipv6 = IPv6.fromIPv4(new IPv4("74.125.43.99"))
ipv6.toString() // produces ::ffff:4a7d:2b63

From dot-decimal notation using convenience method on IPv6
import { IPv6 } from "ip-num/IPv6";

let ipv6 = IPv6.fromIPv4DotDecimalString("74.125.43.99")
ipv6.toString() // produces ::ffff:4a7d:2b63

Convenience methods for creating IPv4, IPv6 and ASN from Binary string

ip-num now has method that allows the creation of IPv4, IPv6, and ASN instances from binary string.

import { Asn } from "ip-num/Asn";
import { IPv4 } from "ip-num/IPv4";
import { IPv6 } from "ip-num/IPv6";

let anAsn = Asn.fromBinaryString('1111');
let anIPv4 = IPv4.fromBinaryString("01001010011111010010101101100011");
let anIPv6 = IPv6.fromBinaryString("01001010011111010010101101100011");

Improvement to various Validators

Big fixes, increased test coverage and improvements were made to Validators. This mainly touches the Validator.isValidIPv4String() and Validator.isValidIPv6String() validators.

For a complete view of the changes included in the v1.1.1 release, please check the change log.

As usual, you can download the source here. Or just run:

npm install ip-num //or npm install ip-num@1.1.1

to add ip-num as a dependency to your next project.

Feel free to open an issue to discuss a feature or to report a bug.

ps: v1.1.0 was unpublished due to inadvertently publishing some dev dependencies as normal dependencies