Deployment

Services can be deployed in several ways:

  • In a standalone Baratine server
  • In a servlet web-app
  • In an embedded Baratine manager

Baratine Server deployment

Deploying Services

Services are deployed on the command-line with:

$ bin/baratine deploy hello.jar

By default, services are deployed to the default pod named “pod”. You may choose a different pod on the command-line with:

$ bin/baratine deploy --pod mypod hello.jar

If the pod does not exist, Baratine will automatically create it. If you’re accessing or debugging the service with a REST call, you’ll address the pod as part of the URL:

$ curl http://localhost:8085/s/mypod/hello-service?m=hello

If you’re building the jar with a manifest, you can specify the pod to deploy to with a Service-Pod attribute in the manifest:

Service-Pod: mypod

Deployment Mechanism

In the background, the deploy command creates a configuration file and uploads both that file and the jar to BFS. An internal pods service watches the bfs:///config/pods directory for changes and starts/restarts the affected pods. Redeploying a jar will restart the pod with the new program.

You can examine the generated configuration file with:

$ bin/baratine cat bfs:///config/pods/mypod.cf
# created by deploy

pod mypod {
  archive "bfs:///usr/lib/hello.bar";
}

And the uploaded .bar file is also in BFS:

$ bin/baratine ls -l bfs:///usr/lib
-rwxrwxrwx  -  -  -          2360 2015 Jan 12 11:32 hello.bar

$ bin/baratine get bfs:///usr/lib/hello.bar hello.bar

The undeploy command undeploys the application by removing the configuration file from bfs:///config/pods.

Developers may control the lifecycle of pods by uploading and deleting files from bfs:///config/pods.

.bar file

The bar file is an archive containing Baratine services, jars and static pages.

lib/my-file.jar
web/index.html

It has an optional configuration section in META-INF/baratine/config. All files in that directory are copied to BFS when the bar is deployed.

Pod Configuration File

The configuration file for a pod configures the:

  • pod type,
  • code archive for the application,
  • servers in the pod, and
  • directory to serve static resources from (jpg, html, etc.)

Example mypod.cf:

# pod <name> <pod-type>, valid pod types are:
#     - off: the pod is off
#     - solo: one instance
#     - pair: two instances
#     - triad: three instances
#     - cluster: n x M instances
#
pod "mypod" "cluster" {
  # may be a jar or a bar (a bar is just a jar with config and static content)
  archive "/usr/lib/pods/myapp.bar";

  # number of servers to allocate for this pod, default is to use all available servers
  server 127.0.0.1:8085
  server 127.0.0.1:8086
  server 127.0.0.1:8087
  server 127.0.0.1:8088
  server 127.0.0.1:8089

  # enables serving of pages from http://localhost:8086/my-static-dir
  # for the archive's /my-static-dir
  web "/my-static-content" "my-static-dir";
}

You can create your pod and deploy it by simply copying the .cf file into bfs:///config/pods:

$ bin/baratine put myapp.bar /usr/lib/pods/
$ bin/baratine put mypod.cf /config/pods/

Note

A single configuration file may define multiple pods. Two configuration files can define the same pod; Baratine will concatenate the files together in file name lexical order.

Backup Servers

For each service, there is at most 2 backup servers for it. The active service streams its inbox and journal to its backup servers. One of the backup servers will take over if the active server ever fails to heartbeat its status to the cluster.

For solo pods, the backup servers are the 2nd and 3rd servers in the pod, if defined.

For pair, the backup servers are each other and the 3rd server in the pod, if defined.

For triad and cluster, the backup servers are each others.

Querying Pod and Service State

bfs:///proc/pods

bfs:///proc/pods describes the pod configuration, including the current servers:

$ bin/baratine cat /proc/pods/my-pod
{ "pod" : "my-pod.cluster",
  "type" : "solo",
  "sequence" : 1433044254057,
  "servers" : [
    {"server" : "192.168.1.149:8085"},
    {"server" : ""},
    {"server" : ""}
  ],
  "nodes" : [
    [0, 1, 2]
  ]
}

The output shows that pod “my-pod” has one physical server with three virtual nodes.

bfs:///proc/services

bfs:///proc/services describes the publicly-available services in a pod:

$ bin/baratine cat /proc/services
[
{ "pod" : "pods/pod.0",
  "services" : [
  { "service" : "public:///map",
    "api" : "example.cache.map.MapManagerServiceImpl",
    "queue-size" : "2"
  },
  { "service" : "public:///string",
    "api" : "example.cache.string.StringManagerServiceImpl",
    "queue-size" : "2"
  },
  { "service" : "public:///counter",
    "api" : "example.cache.counter.CounterManagerServiceImpl",
    "queue-size" : "2"
  },
  { "service" : "public:///tree",
    "api" : "example.cache.tree.TreeManagerServiceImpl",
    "queue-size" : "2"
  },
  { "service" : "public:///list",
    "api" : "example.cache.list.ListManagerServiceImpl",
    "queue-size" : "2"
  }]
}]

Web-App deployment

A Baratine service deployed in a web-app is discovered by the baratine.jar scanning for @Service classes. Services will be available through the ServiceManager obtained using ServiceManager.current().

To deploy in a servlet web-app, add baratine.jar to WEB-INF/lib.

Web-App Client lookup

public class MyServlet extends GenericServlet
{
  private Hello _hello;

  public void init(ServletContext)
  {
    ServiceManager manager = ServiceManager.current();

    Hello hello = manager.lookup("/hello")
                         .as(Hello.class);
  }
  ...

Web-App dynamic service

A service can be deployed dynamically, even without a name. A dynamic service can be used for resources like TCP/REST or WebSocket connections.

For example, a TCP protocol connection can use Baratine to queue and batch outgoing messages.

ServiceManager manager = ServiceManager.current();

MyTcpProtocolImpl myTcpImpl = ...; // dynamic resource

MyTcpProtocol myTcp = manager.newService()
                             .service(myTcp);
                             .as(MyTcpProtocol.class);

Embedded Baratine Manager

A Baratine ServiceManager can be created in any JVM. The manager can create and optionally bind services; and lookup and create client proxies.

ServiceManager manager = ServiceManager.newManager().build();

manager.newService()
       .service(new HelloImpl())
       .address("public:///hello")
       .build();

Hello hello = manager.lookup("/hello")
                     .as(Hello.class);