Strategy pattern example with Kotlin scripts

I thought it would be nice to use advantages of kotlin language to showcase strategy pattern implementation. In order to get the example running – we need to install kotlin binaries (installation). I’m running simple kotlin script in this example.

Having scripting support it makes it very easy to fire up some process with full kotlin language capabilities. You could use it to do some kind of administrative tasks in your business environment.  Continue reading

Advertisements

Microservices with Spring Boot, Netflix Zuul, Kotlin, Docker and MongoDB

Recently I’ve started playing with Kotlin programming language, and wanted to give it a try.

Kotlin gives us possibility to write quite concise code, such as:

@RestController
class UsersController(val userRepo: UserRepository) {

    @ResponseStatus(HttpStatus.OK)
    @GetMapping("/users/{userId}")
    fun getUser(@PathVariable userId: String): UserDTO {
        return userRepo.findOne(userId).toUserDTO()
    }
}

You can find and download source code from GitHub. Readme file there explains how to start & use services. docker-compose comes quite handy to start / shutdown all the services with simple commands and orchestrate them via docker-compose yaml configuration file.

I’ve built sample, small microservice, composed of some kind of simple api-gateway or proxy server, implemented using Spring Boot and Netflix Zuul library for proxying requests to downstream servers.

Continue reading

Listing system / spring environment properties

Ladies & Gents, I prototyped just a small app that could help you print out some basic environment related information by exposing a few Rest controller endpoints.

Running the app

The easiest way is to run the app using Spring boot maven plugin

$ mvn spring-boot:run \
  -Drun.jvmArguments="\
    -Dfoo=foo \
    -Dbar=bar \
    -Dbaz=baz \
    -Dserver.port=8080 \
    -agentlib:jdwp=transport=dt_socket,server=y,address=1044,suspend=n"

Here, we specify some Java properties that will be used by the application:

  • foo, bar, baz custom properties
  • server.port – which is the way to instruct Spring Boot which port to use
  • we also specify to start with remote debug capabilities (if we’d like to do some remote debugging with our IDE)

Rest controller exposing various system / spring properties

package rs.dodalovic.envprops;

import com.google.common.collect.ImmutableMap;
import lombok.AllArgsConstructor;
import lombok.val;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

@RestController
@AllArgsConstructor
public class EnvPropertiesController {
    private final Environment environment;

    @GetMapping("/sys/props")
    public Map<String, Object> getSysProperties() {
        val builder = ImmutableMap.builder();
        System.getProperties().stringPropertyNames().forEach(name -> {
            builder.put(name, environment.getProperty(name));
        });
        val systemProperties = builder.build();
        return ImmutableMap.of(
                "size", systemProperties.size(),
                "values", systemProperties
        );
    }

    @GetMapping("/sys/props/custom")
    public Map<String, Object> getCustomEnvProperties() {
        val builder = ImmutableMap.builder();
        builder.put("properties.key1", environment.getProperty("properties.key1"));
        builder.put("properties.key2", environment.getProperty("properties.key2"));

        builder.put("foo", environment.getProperty("foo"));
        builder.put("bar", environment.getProperty("bar"));
        builder.put("baz", environment.getProperty("baz"));

        val customProperties = builder.build();

        return ImmutableMap.of(
                "size", customProperties.size(),
                "values", customProperties
        );
    }

    @GetMapping("/sys/env")
    public Map<String, Object> get() {
        val env = System.getenv();
        return ImmutableMap.of(
                "size", env.size(),
                "values", env
        );
    }
}

Highlighted are lines used to get insights from running application environment. We are injecting Environment implementation which gives us access to environment properties, and application profiles.

application.properties

properties.key1=properties.val1
properties.key2=properties.val2

In the application.properties (main Spring Boot configuration file) we define two custom Spring environment properties: properties.key1 and properties.key2.

Listing system properties

$ curl -s 'http://localhost:8080/sys/props' | jq .

Response:

 {
   "size": 63,
   "values": {
     "java.runtime.name": "Java(TM) SE Runtime Environment",
     "sun.boot.library.path": "/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib",
     "java.vm.version": "25.121-b13"
     // ...
 }
}

Listing system environment

$ curl -s 'http://localhost:8080/sys/env' | jq .

Response:

{
  "size": 46,
  "values": {
    "M2": "/usr/local/Cellar/maven/3.5.0/libexec/bin",
    "GREP_COLOR": "1;33",
    "JENV_FORCEJDKHOME": "true"
    // ...
  }
}

 Listing custom spring properties

$ curl -s 'http://localhost:8080/sys/props/custom' | jq .

Response:

{
  "size": 5,
  "values": {
    "properties.key1": "properties.val1",
    "properties.key2": "properties.val2",
    "foo": "foo",
    "bar": "bar",
    "baz": "baz"
  }
}

Here we see merged collection of environment properties we either passed via command line or defined in application.properties.

You can checkout source code from GitHub

Hope you’ll find this useful. If so – don’t forget to subscribe to get notified of upcoming posts.

Asynchronous event publishing with Spring Boot

Ladies & gents, I’ve created sample Spring Boot app that demonstrates useful scenario of asynchronous publish / subscribe model. It could be useful in many ways. Idea is that, for example, you have some API handling some web requests, and apart from functionality it provides, it also publishes some event, so that some other thread can react upon it, with main functionality still being processed with request handling thread. Or even shorter – request handling thread will do it’s job, and publishes some event (using Java annotation), and some other background thread will subscribe to event and process it. You can use it for scenario you register user with your API, and publish user registered event, and in background you can subscribe to it by sending out e-mail to end user.

You can checkout source code from GitHub

Easiest way to start your application could be running it via spring-boot:run Maven goal:

mvn spring-boot:run

That will start our demo app on standard 8080 port.

Demo app contains two APIs, get user and update user. Those are just dummy implementations. It also has User domain model class.

You can then, using command line and curl tool, issue the get user request (I’m just doing pipe to jq tool  for nicer response rendering – you can omit that part):

curl -s 'http://localhost:8080/users/1' | jq .
{
 "id": 1,
 "age": 33,
 "name": "Some name"
}
2017-04-23 11:46:59.940 INFO 7421 --- [nio-8080-exec-1] de.odalinho.async.PublishingController : PublishingController::Thread.currentThread().getName() = http-nio-8080-exec-1
2017-04-23 11:46:59.941 INFO 7421 --- [pool-1-thread-3] d.o.a.m.UserNotificationPublisher : UserNotificationPublisher::Thread.currentThread().getName() = pool-1-thread-3
2017-04-23 11:46:59.941 INFO 7421 --- [pool-1-thread-3] d.o.a.m.UserNotificationPublisher : UserNotificationPublisher::event.getMessage() = User(id=1, age=33, name=Some name)

Continue reading

Using regular expressions for querying MongoDB documents

Ladies and gents, here’s one fairly short hint for anyone wondering how to query documents in mongodb using regular expressions. Let’s get straight to the point:

Let’s start by inserting couple of documents (using mongodb shell) which we’ll use for querying afterwards:

db.developers.insertMany([
    { "name" : "John", "languages" : ["java", "php", "javascript"] },
    { "name" : "Johnny", "languages" : ["java", "c", "c++"] },
    { "name" : "Jim", "languages" : ["node", "java"] }
]);

Continue reading

Querying Mongo documents for array properties

Ladies and gents, I’m just posting one short reminder to myself and anyone keen to find out how do we query array type fields in mongodb.

Let’s start by inserting couple of documents (using mongodb shell) which we’ll use for querying afterwards:

db.developers.insertMany([
    { "name" : "John", "languages" : ["java", "php", "javascript"] },
    { "name" : "Jack", "languages" : ["java", "c", "c++"] },
    { "name" : "Jim", "languages" : ["node", "java"] }
]);

Continue reading

Asserting your method get valid arguments can’t be easier than using …

Just wanted to help myself and anyone interested in topic simplify asserting my methods receive valid arguments before ever executing main logic.
One easy way to do so is using Java’s assert keyword.

So, say you have method:

     private static int populateMatrixSortedAscending() {
        int counter = 0;
        final int totalRows = matrix.length;
        for (int i = 0; i < totalRows; i++) {
            for (int j = 0; j < matrix[i].length; j++) {
                int newEntry = newEntry();
                while (!isValidNewEntry(newEntry, i, j)) {
                    newEntry = newEntry();
                }
                matrix[i][j] = newEntry;
            }
        }
        return counter;
    }

Continue reading