Single-Page Session

../../_images/example-hello-server.png

Session Service

A session service is used by a single-page application for user login state. Each user session creates a new session service instance.

Preparation: Maven Archetype for Baratine

You can use the Baratine maven archetype to create a template for the example. The archetype will create an echo service, which you can update into the session service.

The Baratine Maven archetype creates a skeleton directory with a stub echo service, which can be useful when starting an application.

$ mvn archetype:generate \
      -DarchetypeGroupId=io.baratine \
      -DarchetypeArtifactId=baratine-maven-archetype \
      -DarchetypeVersion=0.10.3 \
      -DgroupId=session \
      -Dpackage=session \
      -DartifactId=pod \
      -DinteractiveMode=false

The created directory inclues an echo application which you can build and test with mvn package baratine:run. and start Baratine with baratine:run. Baratine will listen to port 8085 and use /tmp/baratine as its work directory.

$ mvn package baratine:run
baratine>

Browse http://localhost:8085 to run the echo service.

Session Application Source

  • index.html (HTML main page)
  • SessionService.java (Service API)
  • SessionServiceImpl.java (Service Implementation)
  • pom.xml

Client HTML and JavaScript (index.html)

main/web/index.html:

<html>
<script src="baratine-js.js"></script>

<script>
var host = window.location.host;
var url = "ws://" + host + "/s/pod";
jamp = new Jamp.BaratineClient("http://" + host + "/s/pod");

function login()
{
  jamp.query("/session", "login", ["my-user","my-password"], function(data)
  {
    var out = document.getElementById("login");

    out.innerText = data;
  });
}

function execute()
{
  jamp.query("/session", "echo", ["Hello World"], function (data)
  {
    var out = document.getElementById("output");

    out.innerText = data;
  });
}
</script>

<body style="padding: 1em;">

<input id="btn" name="btn" type="button" onclick="login()"
       value="Login"> <br>

<input id="btn" name="btn" type="button" onclick="execute()"
       value="Echo 'Hello World!'"> <br>

Value: <span id="output"></span> <br>

<span id="login">---</span> <br>
</body>
</html>

Application API (SessionService.java)

The application API defines the protocol between the client and the service. Baratine’s protocol is method-based and asynchronous, while allowing for synchronous proxies for older Java clients and testing.

This example has a two methods: login and echo. Both methods have an asynchronous Result.

Baratine allows plain Java return calls, which would simplify the example, but we wanted to emphasize that Baratine is based around asynchronous calls for scalability.

main/java/example/SessionService.java:

package session;

import io.baratine.core.Result;

public class SessionService
{
  void login(String user, String password, Result<String> result);

  void echo(String arg, Result<String> result);
}

Service Implementation (SessionImpl.java)

main/java/example/SessionImpl.java:

package example;

import io.baratine.core.Service;
import io.baratine.core.Session;

@Service("session:///session")
public class SessionServiceImpl implements SessionService
{
  @SessionId
  private String _sid;

  private String _user = "anonymous";

  public void login(String user, String password,
                    Result<String> result)
  {
    if (user == null) {
      user = "anonymous";
    }

    _user = user;

    result.complete(_sid);
  }

  public void echo(String message, Result<String> result)
  {
    result.complete(_user + "[" + message + "]");
  }
}

jUnit Tests (SessionTest.java)

Because the archetype creates tests for the echo service, you will need to change or remove the tests in src/test/java/session for the session to work.

The tests need the following changes:

# The session address is now “session:///session/test-id” # The echo result is “anonymous[Hello World!]” # New tests should be added to test the login itself

The new “session:///session/test-id” address is the most important change. Because SessionTest is in a test environment, the @SessionId must be provided by the @Lookup, instead of the generated sessionid for a remote call. We can choose “test-id” as the id.

SessionTest.java:

package session;

import com.caucho.junit.*;
import org.junit.*;
import javax.inject.*;
import io.baratine.core.*;

@RunWith(RunnerBaratine.class)
@ConfigurationBaratine(services={SessionServiceImpl.class})
public class SessionTest
{
  @Inject @Lookup("session:///session/test-id")
  private SessionServiceSync _session;

  @Test
  public void test()
  {
    String user = "anonymous";
    String message = "Hello World!";

    Assert.assertEquals(user + "[" + message + "]", _session.echo(message));
  }
}

main/web/baratine-js.js

If you’re not using the baratine-js dependency in maven, you can copy the Baratine JavaScript from github.

Download the JavaScript library from github and copy it into main/web:

Downloading Baratine

Download Baratine from <http://baratine.io/download> and extract it to any directory.

Deploying on a Baratine Server

Although the maven baratine:run is useful for development, Baratine is normally started with its start command.

$ baratine start
Baratine/0.10-SNAPSHOT start with watchdog at 127.0.0.1:6700
Baratine/0.10-SNAPSHOT launching watchdog at 127.0.0.1:6700
  starting *:8085 (cluster-8085)

Deploying a service is also from the command line with the deploy command.

$ baratine deploy hello-1.0-SNAPSHOT.bar
  deployed hello-1.0-SNAPSHOT.bar to bfs:///config/pods/50-pod.cf

As with the maven baratine:run, the application can be browsed at:

http://localhost:8085/pod

Baratine Archive (.bar file)

The Baratine archive is a jar file with the following structure:

* lib/my-lib.jar - any jar files, including libraries
* classes/*      - direct classes
* web/index.html - static pages

After Session

Download:

Examples:

Examples on GitHub:

The auction example includes a session service in a more complete form. You can download the example from github.

Client libraries on GitHub: