Java Based Akka application Part 2: Adding tests

On the previous blog we focused on spinning up our first Akka project.
Now it’s time to add a test for our codebase.

First thing to get started is adding the right dependencies to the existing project.

	<dependencies>
		<dependency>
			<groupId>com.typesafe.akka</groupId>
			<artifactId>akka-actor-typed_2.13</artifactId>
			<version>${akka.version}</version>
		</dependency>
		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-classic</artifactId>
			<version>1.2.3</version>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<version>1.18.16</version>
			<scope>provided</scope>
		</dependency>

		<!-- Test -->
		<dependency>
			<groupId>com.typesafe.akka</groupId>
			<artifactId>akka-actor-testkit-typed_2.13</artifactId>
			<version>${akka.version}</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.13.1</version>
			<scope>test</scope>
		</dependency>
	</dependencies>

What you shall notice is the usage of Junit 4, instead of Junit 5. Some of the testing utils like TestKitJunitResource need annotations like @ClassRule and are bound to Junit4. Obviously this is not a blocker on using JUnit 5, with some tweaks it is feasible to use the tools your project needs. However in this example Junit 4 shall be used.

Before we write the test we need to think of our code.
It is obvious that we sent a message to our actor in a fire and forget fashion.

	private Behavior<GuardianMessage> receiveMessage(MessageToGuardian messageToGuardian) {
		getContext().getLog().info("Message received: {}",messageToGuardian.getMessage());
		return this;
	}

If you don’t have a way to intercept what happens inside the method your options are limited. In those cases you can utilise the log messages and actually expect log events to happen.

Before we add the unit test we need to make some logback adjustments. This will take effect only on our test logback.xml. More specific we need to have an appender on logback that captured the data. This is the CapturingAppender.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
        <encoder>
            <pattern>[%date{ISO8601}] [%level] [%logger] [%marker] [%thread] - %msg MDC: {%mdc}%n</pattern>
        </encoder>
    </appender>

    <!-- Logging from tests are silenced by this appender. When there is a test failure the captured logging events are flushed to the appenders defined for the akka.actor.testkit.typed.internal.CapturingAppenderDelegate logger. -->
    <appender name="CapturingAppender" class="akka.actor.testkit.typed.internal.CapturingAppender" />

    <!-- The appenders defined for this CapturingAppenderDelegate logger are used when there is a test failure and all logging events from the test are flushed to these appenders. -->
    <logger name="akka.actor.testkit.typed.internal.CapturingAppenderDelegate" >
      <appender-ref ref="STDOUT"/>
    </logger>

    <root level="DEBUG">
        <appender-ref ref="CapturingAppender"/>
    </root>
</configuration>

Now it’s time to add the unit test.

package com.gkatzioura;

import akka.actor.testkit.typed.javadsl.LogCapturing;
import akka.actor.testkit.typed.javadsl.LoggingTestKit;
import akka.actor.testkit.typed.javadsl.TestKitJunitResource;
import akka.actor.testkit.typed.javadsl.TestProbe;
import akka.actor.typed.ActorRef;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;

public class AppGuardianTests {

	@ClassRule
	public static final TestKitJunitResource testKit = new TestKitJunitResource();

	@Rule
	public final LogCapturing logCapturing = new LogCapturing();

	@Test
	public void testReceiveMessage() {
		ActorRef<AppGuardian.GuardianMessage> underTest = testKit.spawn(AppGuardian.create(), "app-guardian");

		LoggingTestKit.info("Message received: hello")
				.expect(
						testKit.system(),
						() -> {
							underTest.tell(new AppGuardian.MessageToGuardian("hello"));
							return null;
						});
	}

}

Once we run the test the expected outcome is to pass. The actor did receive the message, did execute a logging action and this was captured by the CapturingAppender. Then the logging event was validated if it was the expected one. In case of exception probably you need to check if the logback.xml took effect.

As always you can find the source code on github.

Java Based Akka application Part 1: Your base Project

Akka is a free, open-source toolkit and runtime for building highly concurrent, distributed, and resilient message-driven applications on the JVM. Along with Akka you have akka-streams  a module that makes the ingestion and processing of streams easy  and Alpakka, a Reactive Enterprise Integration library for Java and Scala, based on Reactive Streams and Akka.

On this blog I shall focus on creating an Akka project using Java as well as packaging it.

 

You already know that Akka is built on Scala, thus why Java and no Scala? There are various reasons to go for Java.

  • Akka is a toolkit running on the JVM so you don’t have to be proficient with Scala to use it.
  • You might have a team already proficient with Java but not in Scala.
  • It’s much easier to evaluate if you already have a codebase on Java and the various build tools (maven etc)

Will shall go for the simple route and Download the Application from lightbend quickstart. The project received, will be backed with typed actors.

After some adaption the maven file would look like this, take note that we shall use lombok .

<project>
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.gkatzioura</groupId>
    <artifactId>akka-java-app</artifactId>
    <version>1.0</version>

    <properties>
      <akka.version>2.6.10</akka.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.typesafe.akka</groupId>
            <artifactId>akka-actor-typed_2.13</artifactId>
            <version>${akka.version}</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.16</version>
            <scope>provided</scope>
        </dependency>

    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <source>11</source>
                    <target>11</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.6.0</version>
                <configuration>
                    <executable>java</executable>
                    <arguments>
                        <argument>-classpath</argument>
                        <classpath />
                        <argument>com.gkatzioura.Application</argument>
                    </arguments>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Now there is one Actor that is responsible for managing your other actors. This is the top level actor called Guardian Actor. It is created along with the ActorSystem and when it stops the ActorSystem will stop too.

In order to create an actor you define the message the actor will receive and you specify why it will behave to those messages.

package com.gkatzioura;

import akka.actor.typed.Behavior;
import akka.actor.typed.javadsl.AbstractBehavior;
import akka.actor.typed.javadsl.ActorContext;
import akka.actor.typed.javadsl.Behaviors;
import akka.actor.typed.javadsl.Receive;
import lombok.AllArgsConstructor;
import lombok.Getter;

public class AppGuardian extends AbstractBehavior<AppGuardian.GuardianMessage> {

	public interface GuardianMessage {}

	static Behavior<GuardianMessage> create() {
		return Behaviors.setup(AppGuardian::new);
	}

	@Getter
	@AllArgsConstructor
	public static class MessageToGuardian implements GuardianMessage {
		private String message;
	}

	private AppGuardian(ActorContext<GuardianMessage> context) {
		super(context);
	}

	@Override
	public Receive<GuardianMessage> createReceive() {
		return newReceiveBuilder().onMessage(MessageToGuardian.class, this::receiveMessage).build();
	}

	private Behavior<GuardianMessage> receiveMessage(MessageToGuardian messageToGuardian) {
		getContext().getLog().info("Message received: {}",messageToGuardian.getMessage());
		return this;
	}

}

Akka is message driven so the guardian actor should be able to consume messages send to it. Therefore messages that implement the GuardianMessage interface are going to be processed.

By creating the actor the createReceive method is used in order to add handling of the messages that the actor should handle.

Be aware that when it comes to logging instead of spinning up a logger in the class use the
getContext().getLog()

Behind the scenes the log messages will have the path of the actor automatically added as akkaSource Mapped Diagnostic Context (MDC) value.

Last step would be to add the Main class.

package com.gkatzioura;

import java.io.IOException;

import akka.actor.typed.ActorSystem;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class Application {

	public static final String APP_NAME = "akka-java-app";

	public static void main(String[] args) {
		final ActorSystem<AppGuardian.GuardianMessage> appGuardian = ActorSystem.create(AppGuardian.create(), APP_NAME);
		appGuardian.tell(new AppGuardian.MessageToGuardian("First Akka Java App"));

		try {
			System.out.println(">>> Press ENTER to exit <<<");
			System.in.read();
		}
		catch (IOException ignored) {
		}
		finally {
			appGuardian.terminate();
		}
	}

}

The expected outcome is to have our Guardian actor to print the message submitted. By pressing enter the Akka application will terminate through the guardian actor.
On the next blog we will go one step further and add a unit test that validates the message received.
As always you can find the source code on github.

Scala Main class

Adding a main class is Scala is something that I always end up searching so next time it shall be through my blog.

You can go for the extends App option

One way is to add a main class by extending the App class. Everything else that get’s executed on that block is part of the “main” function.

package com.gkatzioura

object MainClass extends App {

  println("Hello world"!)
}

Then you can access the arguments since they are a variable on the App.

package com.gkatzioura

object MainClass extends App {

  for( arg <- args ) {
    println(arg)
  }

}

Add a main method

This is the most Java familiar option

package com.gkatzioura

object MainClass {

  def main(args: Array[String]): Unit = {
    println("Hello, world!")
  }

}

As expected you receive the program arguments through the function arguments.

package com.gkatzioura

object MainClass {

  def main(args: Array[String]): Unit = {
    for( arg <- args ) {
      println(arg)
    }
  }

}

Run you first gatling load test using scala.

Gatling is a neat tool. You can create your load tests by just coding in scala. Jmeter allows you to do so through a plugin or beanshell but it is not as direct as the way gatling does so.

I will start by adding the gatling plugin

addSbtPlugin("io.gatling" % "gatling-sbt" % "3.0.0")

The next step is to changed the build.sbt


version := "0.1"
scalaVersion := "2.12.8"

enablePlugins(GatlingPlugin)

scalacOptions := Seq(
  "-encoding", "UTF-8", "-target:jvm-1.8", "-deprecation",
  "-feature", "-unchecked", "-language:implicitConversions", "-language:postfixOps")
libraryDependencies += "io.gatling.highcharts" % "gatling-charts-highcharts" % "3.1.2" % "test,it"
libraryDependencies += "io.gatling"            % "gatling-test-framework"    % "3.1.2" % "test,it"

The above are no different than what you can find on the official site when it comes to sbt commands and gatling.

Our next step is to add a simple http test. Be aware that you should add it in the directories src/test or src/it since, as it is instructed from the sbt dependencies for the binaries to take effect on these directories.

I shall put this test on src/test/scala/com/gkatzioura/BasicSimulation.scala

package com.gkatzioura

import io.gatling.core.Predef._
import io.gatling.http.Predef._
import scala.concurrent.duration._

class BasicSimulation extends Simulation {

  val httpConf = http.baseUrl("http://yourapi.com")
      .doNotTrackHeader("1")

  val scn = scenario("BasicSimulation")
    .exec(http("request_1")
    .get("/"))
    .pause(5)

  setUp(scn.inject(atOnceUsers(1))).protocols(httpConf)
}

Afterwards testing is simple. You go to sbt mode and execute the test.

sbt
>gatling:testOnly com.gkatzioura.BasicSimulation
>gatling:test

The first command instructs to run just one test, the second one shall run everything.

That’s it! Pretty simple.

Migrate your elastic beanstalk workers to docker containers

Amazon Elastic Beanstalk is one of the most popular services that aws provides. Elastic beanstalk comes with two options, the worker and the web application.

The worker application consumes the messages from a sqs queue and process them. If the process was successful the message is removed from the queue, if not the message shall remain in the queue or after some failed attempts it will go back to a dead letter queue. If you want to get more into elb I have made a tutorial on deploying you spring application using elb and cloudformation.

Elastic beanstalk workers are really great because they are managed, they can be scaled up/down depending on your workloads and they provide a wide variety of development environments like java, node.js and also you can use docker images.

Although elastic bean can work wonders if you have an aws based infrastructure you might face some issues when you will try to move to a container based infrastructure using a container orchestration engine.

Most probably your containerized worker application will work seamlessly without any extra configuration, however you need to find an alternative for the agent which dispatches the queue messages to your application.

In order to make things simple I implemented a mechanism which retrieves the messages from the queue and sends them to the worker application.

The container-queue-worker projects aims to provide an easy way to migrate your elastic beanstalk workers to a docker orchestration system.

Since the solution is Scala based it can either be used as a standalone jvm application or it can be run in a container using the image from dockerhub.

Once set up what you need to add the routing configurations.

This can be done using environment variables

WORKER_TYPE=sqs
WORKER_SERVER_ENDPOINT=http://{docker-service}
WORKER_AWS_QUEUE_ENDPOINT=http://{amazon queue endpoint}

Or if you use it as a container you can add a config file on the /etc/worker/worker.conf path.

worker {
  type =  sqs
  server-endpoint = http://{docker-service}
  aws {
    queue-endpoint =  http://{amazon queue endpoint}
  }
}

In order to make thing easier for you I added a docker compose file simulating the desired outcome.

version: '3.5'
networks:
  queue-worker-network:
    name: queue-worker-network
services:
  worker-server:
    build:
      context: ./worker-server
      dockerfile: Dockerfile
    ports:
      - 8080:8080
    networks:
      - queue-worker-network
  elasticmq:
    build:
      context: ./elasticmq
      dockerfile: Dockerfile
    ports:
      - 9324:9324
    networks:
      - queue-worker-network
  container-queue-worker:
    image: gkatzioura/container-queue-worker:0.1
    depends_on:
      - elasticmq
      - worker-server
    environment:
      WORKER_TYPE: sqs
      WORKER_SERVER_ENDPOINT: http://worker-server:8080/
      WORKER_AWS_QUEUE_ENDPOINT: http://elasticmq:9324/queue/test-queue
      AWS_DEFAULT_REGION: eu-west-1
      AWS_ACCESS_KEY_ID: access-key
      AWS_SECRET_ACCESS_KEY: secret-key
    networks:
      - queue-worker-network

Dockerize your Scala application

Dockerizing a Scala application is pretty easy.

The first concern is creating a fat jar. Now we all come from different backgrounds including maven/gradle and different plugins that handle this issue.
If you use sbt the way to go is to use the sbt-assembly plugin.

To use it we should add it to our project/plugins.sbt file. If the file does not exist create it.

logLevel := Level.Warn

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.6")

So by executing

sbt clean assembly

We will end up with a fat jar located at the target/scala-**/**.jar path.

Now the easy part is putting our application inside docker, thus a Dockerfile is needed.

We will use the openjdk alpine as a base image.

FROM openjdk:8-jre-alpine

ADD target/scala-**/your-fat-jar app.jar

ENTRYPOINT ["java","-jar","/app.jar"]

The above approach works ok and gives the control needed to customize your build process.
For a more bootstraping experience you can use the sbt native packager.

All you need to do is to add the plugin to project/plugins.sbt file.

logLevel := Level.Warn

addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.3.4")

Then we specify the main class of our application and enable the Java and Docker plugins from the native packager at the build.sbt file.

mainClass in Compile := Some("your.package.MainClass")

enablePlugins(JavaAppPackaging)
enablePlugins(DockerPlugin)

The next step is to issue the sbt command.

sbt docker:publishLocal

This command will build your application, include the binaries needed to the jar, containerize your application and publish it to your local maven repo.

Run code on startup with Play and Scala

Depending on various projects, sometimes there is the need to execute some actions on initialization just before our application starts to serve requests.

It was a common practice to call the functions that we wanted to get executed through GlobalSettings, however it is not recommended.

The other way around to achieve this is to implement a class which will be injected and thus add the code that we want to get executed on the class constructor.

We might believe that it is sufficient to implement a class which shall use the @Singleton annotation.

For example

@Singleton
class StartUpService {

    //The code that needs to be executed

}

But this will not work as expected since our component instances on play are created lazily when they are needed.

Instances are created lazily when they are needed. If a component is never used by another component, then it won’t be created at all. This is usually what you want. For most components there’s no point creating them until they’re needed. However, in some cases you want components to be started up straight away or even if they’re not used by another component. For example, you might want to send a message to a remote system or warm up a cache when the application starts. You can force a component to be created eagerly by using an eager binding.

To tackle this problem, our singleton has to be initialized eagerly. To achieve an eager initialization we will define an eager binding.

To define an eager binding we have to implement a class that extends the AbstractModule and then bind our service as an eager singleton.

package com.gkatzioura.eager

import com.google.inject.AbstractModule
import com.google.inject.name.Names

// A Module is needed to register bindings
class EagerLoaderModule extends AbstractModule {
  override def configure() = {

    bind(classOf[StartUpService]).asEagerSingleton
  }
}

Then we have to enable our module by declaring so to our conf/application.conf configuration.

play.modules.enabled += "com.gkatzioura.eager.EagerLoaderModule"

The above approach creates a module by defining it explicitly. The other approach is to use the default functionality where Play will load any class called Module that is defined in the root package.

In conclusion, play gives us the option to execute certain functions once the application has started. To do so we need to implement a component as an eager singleton. Skip the GlobalSettings as it is not advised by the official documentation.

Play and SBT basics

Previously we had an introduction to sbt, its default tasks and how to add extra tasks.

Play comes with the sbt console. The SBT console is a development console based on sbt that allows you to manage a Play application’s complete development cycle.

Let us create a play application using sbt and see the commands provided.

sbt new playframework/play-scala-seed.g8

[warn] Executing in batch mode.
[warn]   For better performance, hit [ENTER] to switch to interactive mode, or
[warn]   consider launching sbt without any commands, or explicitly passing 'shell'
[info] Set current project to development (in build file:/home/gkatzioura/Development/)

This template generates a Play Scala project 

name [play-scala-seed]: PlayExample
organization [com.example]: com.gkatzioura
scala_version [2.11.11]: 
play_version [2.5.14]: 
scalatestplusplay_version [2.0.0]: 

The result is a play project named playexample. By opening with an editor the project/plugins.sbt we can see the sbt plugin added to our project.
Therefore we are going to check what are the extra tasks that the sbt plugin provides and some tasks that can be generally helpful.

cd playexample; sbt 
[PlayExample] $ <tab><tab>
Display all 511 possibilities? (y or n)
...
h2-browser  
...                                                                                                                                                                                                                              
playStop                                           
playUpdateSecret     
playGenerateSecret                              
...
stage
...
  • playStop – Stop Play, if it has been started in non blocking mode
  • playGenerateSecret – This will generate a new secret that you can use in your application. For example the application secret can be used for Signing session cookies and CSRF tokens or
    built in encryption utilities
  • playUpdateSecret – Update the application conf to generate an application secret
  • stage – Create a local directory with all the files laid out as they would be in the final distribution.
  • h2-browser – Opens an h2 database browser. Pretty useful if you are using h2 for development

Those are some of the commands that you might use often. However if you want extra information, you can always type help play.

[PlayExample] $ help play

playExternalizeResources

  Whether resources should be externalized into the conf directory when Play is packaged as a distribution.

playCommonClassloader

  The common classloader, is ...
...

I’ve compiled a cheat sheet that lists some helpful sbt commands.
Sign up in the link to receive it.

SBT basics

Sbt is the de facto build tool in the Scala community.
Being used to other build tools you will be familiar with the commands

  • clean – Deletes files produced by the build, such as generated sources, compiled classes, and task caches.
  • compile – Compiles sources
  • test – Executes all tests
  • package – Produces the main artifact, such as a binary jar. This is typically an alias for the task that actually does the packaging.
  • help – Displays this help message or prints detailed help on requested commands (run ‘help ‘).
  • console – Starts the Scala interpreter with the project classes on the classpath.

Then we have extra commands suchs as

    • run – Runs a main class, passing along arguments provided on the command line.
    • tasks – Lists the tasks defined for the current project.
    • reload – (Re)loads the current project or changes to plugins project or returns from it.
    • console – Starts the Scala interpreter with the project classes on the classpath.

A key functionality is the new command.

For example by using new, we can create a project from the template specified (for example scala-seed.g8) using giter8.

sbt new scala/scala-seed.g8

...
Minimum Scala build. 

name [My Something Project]: hello

Template applied in ./hello

The previous snippet creates a project called hello.

The file build.sbt holds a sequence of key-value pairs called setting expressions. The left-hand side is a key and the right hand side is the body.
There are three types of keys.

  • SettingKey[T]: a key for a value computed once (the value is computed
    when loading the subproject, and kept around).
  • TaskKey[T]: a key for a value, called a task, that has to be recomputed
    each time, potentially with side effects.
  • InputKey[T]: a key for a task that has command line arguments as input.

For example if we want to add and extra task, to our previous project,  which prints hello, then we shall add the following lines to the build.sbt file.

import Dependencies._

lazy val hello = taskKey[Unit]("An example task")

lazy val root = (project in file(".")).
settings(
hello := { println("Hello!") },
inThisBuild(List(
organization := "com.example",
scalaVersion := "2.12.2",
version := "0.1.0-SNAPSHOT"
)),
name := "Hello",
libraryDependencies += scalaTest % Test
)

We can either run the task or ask for more info about the task.

>sbt
> hello
Hello!
[success] Total time: 0 s, completed May 1, 2017 6:08:36 PM
> help hello
An example task
> 

Depending on the project and the plugin used, there would be extra tasks and settings defined.

On the next post we will check play and sbt integration, and some basic commands.

I’ve compiled a cheat sheet that lists some helpful sbt commands.
Sign up in the link to receive it.

SQL Data Access in Play using Scala

Today’s modern application frameworks come with a promise of easy sql data access. There is no wonder why we have so many frameworks that make it easier to issue queries and handle transactions. SQL is the lingua franca of most applications when it comes to databases.

Play comes with the JDBC plugin. We encountered the JDBC plugin previously in order to modify our database schema.

The first step is to include the jdbc and the evolutions module.

libraryDependencies += evolutions
libraryDependencies += jdbc

Then we shall define the connection string needed. We will use a simple h2 database. The configuration is added at the application.conf.

db.default.driver=org.h2.Driver
db.default.url="jdbc:h2:/tmp/defaultdatabase"

Then we add a script that creates the users table.

# Users schema

# --- !Ups

CREATE TABLE users (
    id bigint(20) NOT NULL AUTO_INCREMENT,
    email varchar(255) NOT NULL,
    first_name varchar(255) NOT NULL,
    last_name varchar(255) NOT NULL,
    PRIMARY KEY (id),
    UNIQUE KEY (email)
);

# --- !Downs

DROP TABLE users;

Before creating our repository class let’s check what the jdbc plugin provides us with.

We have the plain getConnection method, responsible for returning a jdbc connection. This is similar to the DataSource.getConnection from Java. Thus pay extra attention since you must close the connection.

val connection = db.getConnection()
connection.close()

Next method is withConnection. By using withConnection you get Play to manage the connection for you. All you have to do is pass a block of code with jdbc actions.

  def fetchUsers(): List[User] = {

    db.withConnection { conn =>

      val stmt = conn.createStatement
      var rs = stmt.executeQuery("SELECT*FROM users");
      val listBuffer = ListBuffer[User]()

      while(rs.next()) {

        listBuffer.append(User(Option(rs.getLong("id")),rs.getString("email"),rs.getString("first_name"),rs.getString("last_name")))
      }

      listBuffer.toList
    }
  }

As you can see above, we’ve just returned back a list of our user entries.

And last but not least withTransaction. You’ve guessed right, what you receive back is a connection with autocommit set to false.

  def addUser(user:User): User = {

    db.withTransaction { conn =>
      val stmt = conn.createStatement

      val insertQuery = "INSERT INTO users ( email, first_name, last_name) VALUES( '"+user.email+"', '"+user.firstName+"','"+user.lastName+"') "
      stmt.executeUpdate(insertQuery,Statement.RETURN_GENERATED_KEYS)
      val resultSet = stmt.getGeneratedKeys;
      if(resultSet.next()) {
        val id = resultSet.getLong(1);
        new User(Option(id),user.email,user.firstName,user.lastName)
      } else {
        throw new Exception("User not persisted properly")
      }
    }
  }

In the above example a user is persisted. In case of failure we throw an exception and the transaction is rolled back.

To sum up we have just checked how to access a sql database using play. Also we have checked the extra functions that play api provides apart from the familiar jdbc api.
That’s all for now! Feel free to check the code on github.