Chapter 4. Architecture

Table of Contents

4.1. Deployment Options
4.1.1. Web Archive
4.1.2. Standalone
4.1.3. Embedded

The SymmetricDS software allows for outgoing and incoming changes to be synchronized to/from other databases. The Node that initiates the connection is the client, and the Node receiving a connection is the host. Because synchronization is configurable to push or pull in either direction, the same Node can act as either a client or a host in different circumstances.

The software consists of a series of jobs, managers, servlets, and services wired together through dependency injection using the Spring Framework.

Software Stack

Figure 4.1. Software Stack


As a client, the Node runs the Push Job and Pull Job on a timer thread in order to synchronize with a host Node. The Push Job uses services to batch, extract, and stream data to another Node (i.e. it pushes data). The response from a push is a list of batch acknowlegements to indicate that data was loaded. The Pull Job uses services to load data that is streamed from another Node (i.e. it pulls data). After loading data, a second connection is made to send a list of batch acknowlegements.

As a host, the Node waits for incoming connections that pull, push, or acknowledge data changes. The Push Servlet uses services to load data that is pushed from a client Node. After loading data, it responds with a list of batch acknowledgements. The Pull Servlet uses services to batch, extract, and stream data back to the client Node. The Ack Servlet uses services to update the status of data that was loaded at a client Node.

The Transport Manager handles the incoming and outgoing streams of data between Nodes. The default transport is based on a simple implementation over HTTP. An internal transport is also provided. It is possible to add other implementations, such as a socket-based transport manager.

Node communication over HTTP is represented in the following figure.

Node Communication

Figure 4.2. Node Communication


The SymmetricEngine is wrapper API that can be used to directly start the client services only. The SymmetricWebServer is a wrapper API that can be used to directly start both the client and host services inside a Jetty web container.

4.1. Deployment Options

The following deployment options are possible:

  • Web application archive (WAR) deployed to an application server

    This option means packaging a WAR file and deploying to your favorite web server, like Apache Tomcat. It's a little more work, but you can configure the web server to do whatever you need.

  • Standalone service that embeds Jetty web server

    This option means running the sym command line, which launches the built-in Jetty web server. This is a simple option because it is already provided, but you lose the flexibility to configure the web server any further.

  • Embedded as a Java library in an application

    This option means you must write a wrapper Java program that runs SymmetricDS. You would probably use Jetty web server, which is also embeddable. You could bring up an embedded database like Derby. You could configure the web server, database, or SymmetricDS to do whatever you needed, but it's also the most work of the 3 options.

The deployment model you choose depends on how much flexibility you need versus how easy you want it to be. Both Jetty and Tomcat are excellent, scalable web servers that compete with each other and have great performance. Most people choose either the Standalone or Web Archive with Tomcat 5.5 or 6. Deploying to Tomcat is a good middle-of-the-road decision that requires a little more work for more flexibility.

4.1.1. Web Archive

As a web application archive, a WAR or EAR file is deployed to an application server, such as Tomcat, Jetty, or JBoss. The structure of the archive should have a web.xml file in the WEB-INF folder, the symmetric.properties file in the WEB-INF/classes folder, and the required JAR files in the WEB-INF/lib folder.

The WEB-INF/web.xml file is configured with a SymmetricEngineContextLoaderListener the required SymmetricFilter mapping, and the required SymmetricServlet mapping. Note that this was changed in version 1.4.0 to make it easier to configure Symmetric.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
        http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    version="2.5">

    <display-name>sync</display-name>
    
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <!-- You can optionally specify other Spring files to load into same context here -->
        <param-value>classpath:symmetric.xml</param-value>
    </context-param>
    
    <filter>
        <filter-name>SymmetricFilter</filter-name>
        <filter-class>
            org.jumpmind.symmetric.web.SymmetricFilter
        </filter-class>
    </filter>
    
    <filter-mapping>
        <filter-name>SymmetricFilter</filter-name>
        <servlet-name>/*</servlet-name>
    </filter-mapping>
    
    <listener>
        <listener-class>
            org.jumpmind.symmetric.SymmetricEngineContextLoaderListener
        </listener-class>
    </listener>
    
    <servlet>
        <servlet-name>SymmetricServlet</servlet-name>
        <servlet-class>
            org.jumpmind.symmetric.web.SymmetricServlet
        </servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>SymmetricServlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

</web-app>

This example starts all the SymmetricDS Servlets with Filters to compress the stream, authenticate nodes, and reject nodes when the server is too busy.

The web.base.servlet.path property in symmetric.properties can be set if the SymmetricServlet needs to coexist with other Servlets.

4.1.2. Standalone

A standalone service can use the sym command line options to start a server. An embedded instance of Jetty is used to service web requests for all the servlets.

/symmetric/bin/sym --properties root.properties --port 8080 --server

This example starts the SymmetricDS server on port 8080 with the startup properties found in the root.properties file.

4.1.3. Embedded

A Java application with the SymmetricDS Java Archive (JAR) library on its classpath can use the SymmetricEngine to start the server.

import org.jumpmind.symmetric.SymmetricEngine;

public class StartSymmetricDSEngine {

    public static void main(String[] args) throws Exception {
        String workingDirectory = System.getProperty("user.dir");

        SymmetricWebServer node = new SymmetricWebServer(new SymmetricEngine("classpath://my-application.properties", "file://"
                + workingDirectory + "/my-environment.properties"));

        // this will create the database, sync triggers, start jobs running
        node.start(8080);
        
        // this will stop the node
        node.stop();
    }   

}

This example starts the SymmetricDS server on port 8080 with startup properies found in two locations. The first file, my-application.properties, is packaged in the application to provide properties that override the SymmetricDS default values. The second file, my-environment.properties, is located in a working directory that overrides properties specific to the environment. This allows the same application to deploy to development and production environments using different my-environment.properties.