Random stuff about Java, OSGi, Docker, Kubernetes and more

2017-01-29
Generating a Namespace / Name Based UUID in Go and Java

Recently I needed to generate a new id during migration of some data of a Golang application. Another application, written in Java, contained links to the first application’s data. So somehow I needed to update those links to point to that new id. I decided to use a “namespace name based UUID”, which is version 3 and 5 of the UUID spec. They generate a reproducable id based on given data. Since the UUID class of Java only supports v3, that was the way to go.

So first I generated the UUID in Go, that was straight forward using the github.com/satori/go.uuid package. someOldData1 + someOldData2 is a logical unique key of the data, which is available in both applications:

1
2
3
4
5
6
7
8
9
10
11
12

import (
...
"github.com/satori/go.uuid"
...
)

...

newId := uuid.NewV3(uuid.NamespaceURL, someOldData1 + someOldData2).String()

...

Next was to do the same in Java using the UUID class… but wow, that was more work than I expected:

  • Java’s UUID class has no constants for the predefined namespaces (like uuid.NamespaceURL above)
  • The nameUUIDFromBytes(byte[] name) method does not even take 2 parameters (namespace + name), but only one byte array.

It was hard to find any documentation on how to actually use this method, but finally I found out:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

import javax.xml.bind.DatatypeConverter;
import java.nio.charset.Charset;
import java.util.UUID;
...

private String calculateId(String someOldData1, String someOldData2) {

// this is the predefined UUID of the "URL" namespace, with removed dashes
String urlnamespace = "6ba7b8119dad11d180b400c04fd430c8";

String name = someOldData1 + someOldData2;

// now get the bytes of namespace and name
byte[] nsbytes = DatatypeConverter.parseHexBinary(urlnamespace);
byte[] namebytes = name.getBytes(Charset.forName("UTF-8"));

// concat both byte arrays
byte[] allBytes = new byte[nsbytes.length + namebytes.length];
System.arraycopy(nsbytes, 0, allBytes, 0, nsbytes.length);
System.arraycopy(namebytes, 0, allBytes, nsbytes.length, namebytes.length);

// that's what we need as parameter...
UUID uuid = UUID.nameUUIDFromBytes(allBytes);

return uuid.toString();
}

...

Happy coding :)

Read More

2016-04-20
Zsh and Kubectl

Oh-my-zsh

Yesterday I finally installed oh-my-zsh. It was on my to-do list for longer time already, because I read so many good things about it… but having things on a todo list and finally taking the time for doing them is a big difference sometimes ;)

However, the installation went fine, and after that you can, or better to say have to spend some time on configuration, which basically means chosing a theme and the plugins you want to use.

A good thing about the installation is, that it took over the $PATH variable from the old shell. But unfortunately you now have one big export PATH=... line, while you probably had a more structered version before. At least I had. So I deleted that line from the config, and copied my old PATH config from the now unused bash configuration.

kubectl command completion

A few days ago I came across a small blog post about kubectl (the Kubernetes command line tool) command completion. That is really useful, so wanted to have that for zsh too, and I found this:

kubectl completion finally also for zsh https://github.com/kubernetes/kubernetes/pull/23262

I didn’t find instructions on how to add that to the zsh config, and it took me some minutes to find out, so I’d like to share it here:

  1. clone kubernetes master (the zsh completion is not in a release yet): git clone https://github.com/kubernetes/kubernetes.git
  2. add this to ~/.zshrc: source $HOME/path/to/kubernetes/contrib/completions/zsh/kubectl

I got an error at the first try, and it turned out that gnu-sed was the problem, which I had installed with brew. After uninstalling it, it worked fine: This issue will be solved soonish, see @the1stein’s tweet.

Kubectl command completion in action, it first completes the available k8s resources, and then the available deployments:

Read More

2016-03-02
Struggling With Angular2 Beta

For our CloudRTI project I’m currently busy with a custom frontend for deploying apps to our Kubernetes based environment. We decided to use Angular2 for it, even though it is in beta yet. I didn’t work with Angular1 before, so I started with a fresh mind.

After going through the Angular2 tutorial, I started with our frontend and had some first nice results quickly. I really like the concepts. You have to get used to the somewhat strange syntax (e.g. *ngFor in html), but that’s always a “problem” when using new languages / frameworks.

But the more features I wanted to implement, the more I had to realize that I’m really working with a beta version. Some issues I came across:

  • The value of a html select option can only be string. While this is obvious from a pure HTML point of view, I expected that I can use objects in Angular, and I’m not the only one. I was glad to see that the Angular2 team accepted this as a feature request, but until then you have to use a workaround. See https://github.com/angular/angular/issues/4843.

  • At some places we enable a feature with a checkbox. When the feature is enabled, a text input field becomes required. So I used Angular to set the readonly and required attribute of the text input based on the checkbox value:

    1
    2
    <input type="checkbox" [(ngModel)]="checked">
    <input type="text" [required]="checked" [readonly]="!checked">

    Unfortunately Angular2 does not handle the dynamically added and removed required attribute, and marks the text input and with that the complete form always as invalid when empty. See https://github.com/angular/angular/issues/5527 and https://github.com/angular/angular/issues/5976.

    As a workaround I implemented a custom Validator, which takes both the checkbox and the text input as input:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public static checkboxInputValidator(checkboxName: string, inputName: string, errorCode: string) {
    return (controlGroup: ControlGroup): {[key: string]: any} => {
    let checkbox = controlGroup.controls[checkboxName].value;
    let input = controlGroup.controls[inputName].value;
    if (checkbox && !input) {
    this.addError(inputName, controlGroup.controls[inputName], errorCode);
    }
    else {
    this.removeError(inputName, controlGroup.controls[inputName], errorCode);
    }
    return null;
    }
    }

    Good thing about this workaround: I had to read about custom validators, which I needed later on anyway :)

  • change listeners are not called on selects in Firefox and IE… https://github.com/angular/angular/issues/6573

After a while I wanted to upgrade Angular2 beta2 to beta7… but that was becoming an adventure on itself… nothing compiled anymore after just increasing the version number. Some dependencies had to updated too, I had to add some typescript type definitions which were not needed before, and some 3rd party modules did not work anymore…:

  • For the type definitions I use the typings module now… too bad that the type definition for require.js has a bug :/ There is a simple fix available for weeks, but not merged yet: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/7049. So added a fixed version as a custom type definition to our project.

  • For authentication and authorization with JWT I use the angular2-jwt module. It had a dependency on another rxjs version than the updated Angular2 beta, and the Observable type changed between these 2 rxjs version, so I got “A is not assignable to B” errors. I could fix the issue and the PR is merged in the meanwhile: https://github.com/auth0/angular2-jwt/issues/39.

  • Another module for creating UUIDs failed on some browsers because function definitions are only allowed on top level in strict mode. Not sure if this is new after upgrading Angular, or if I just did not test on other browsers before… however, I could fix this one and the PR is merged now, too: https://github.com/wulfsolter/angular2-uuid/pull/1

All in all this slowed me really down the last weeks. On the other hand digging into such issues give you a better understanding for the tools you use. And contributing back to these tools after you found and fixed issues is always a good thing :)

Read More

2016-01-28
Hello World!

What should I write? Like every good software engineer I’ll start with:

Hello World!

every software engineer on earth ;)

During the last months I sometimes thought: mh, that was interesting, and might be useful for others too. So here we go, today I finally decided to start a personal blog.

What can you expect here?

  • Most posts will probably be related to software engineering, especially about Java and modular development with OSGi.
  • Another big topic will be Docker and Kubernetes, because I’m involved in projects where we use these technologies for deploying our and your applications.
  • Sometimes I find some nice tips and tricks, which at least I didn’t know yet, which make daily life easier on OSX. Some of them are probably worth sharing here, too.
  • And last but not least you might find some private topics here as well… not sure about that yet. But if so, that might include some cat content. You have been warned ;)

If you want to know more about me, also check out the About page.

That’s enough for a hello world post. Enjoy your day!

Read More