Communication

EclipseStore provides a module for simple object based network communication over TCP connections.

This module utilizes the Eclipse Serializer engine to serialize and deserialize Java objects and provides additional APIs to setup the required TCP connections.

Getting Started

Prerequisites

If using Maven, just add module communication-binary into your pom.xml dependencies.

pom.xml
<dependencies>
	<dependency>
		<groupId>org.eclipse.serializer</groupId>
		<artifactId>communication-binary</artifactId>
		<version>1.2.0</version>
	</dependency>
</dependencies>

Hello World

The Hello World example consists of two applications. The Host and the Client application. The host will open a network port and listen for incoming connections from the client. If a client connects successfully, it awaits data from the client that will be sent back to the client. The basic example won’t do any configuration, so the connection is not secured, and the client and host use the local system address at port 1099.

Host

public class EchoServer
{
	public static void main(final String[] args)
	{
		final ComHost<?> host = ComBinaryDynamic.Foundation()
			.setHostChannelAcceptor(channel ->
			{
				final Object received = channel.receive();
				System.out.println("received: " + received);
				channel.send(received);
			})
			.createHost();

		// run the host, making it constantly listen for new connections and relaying them to the logic
		host.run();
	}
}

Client

public class EchoClient
{
	public static void main(final String[] args)
	{
		//create the client
		final ComClient<?> client = ComBinaryDynamic.Foundation()
			.createClient();

		//connect to the host and communicate
		try(final ComChannel channel = client.connect())
		{
			channel.send("Hello Host");
			final Object received = channel.receive();
			System.out.println("received: " + received);
		}
	}
}

Configuration

Configuration of host and client is done using the ComFoundation.Default implementation of the ComFoundation interface. To get a preconfigured foundation instance, the classes ComBinaryDynamic and ComBinary provide the convenient method Foundation().

ComBinaryDynamic and ComBinary

The Object communication of Eclipse Serializer is available in two flavours: Dynamic and non-dynamic.

They differ in the way classes that should be serialized and transferred are handled:
The non-dynamic version requires all classes that should be transferred to be registered at initialization time. This can be done with the registerEntityType methods of the ComFoundation. If a transferred object graph references any unregistered class, an exception will occur!

The dynamic implementation automatically registers all classes that are part of the communication at runtime. It will also do a type-mapping if classes with the same name have different implementations on the client and host.

Common configuration values

host binding address
The host’s IP address is configured with ComFoundation.setHostBindingAddress(InetSocketAddress).

client target address
The address the client connects to is configured by ComFoundation.setClientTargetAddress(InetSocketAddress).

port only
If no host or client target address is configured, it is possible to use ComFoundation.setPort(int) to set a port that is used together with the default IP addresses for the host and client.

registering entity types
to register entity types at startup, use ComFoundation.registerEntityTypes(Class<?>…​) for example.

TLS

In order to use TLS encrypted communication, you need to setup a ComTLSConnectionHandler and supply it using ComFoundation.setConnectionHandler(ComConnectionHandler<C>). The default implementation of the ComTLSConnectionHandler uses the java SSLEngine. The required configuration elements have to be provided using either the provided implementations of the TLSKeyManagerProvider , TLSTrustManagerProvider , TLSParametersProvider and SecureRandomProvider interfaces or by custom implementations.

public class EchoServerTLS
{
	public static void main(final String[] args)
	{
		Path serverKeyStore = Paths.get(args[0]);
		Path serverTrustStore = Paths.get(args[1]);
		char[] serverKeyStorePassword = args[2].toCharArray();
		char[] serverTrustStorePassword = args[2].toCharArray();

		final ComHost<?> host = ComBinaryDynamic.Foundation()
			.setConnectionHandler(ComTLSConnectionHandler.New(
					new TLSKeyManagerProvider.PKCS12(
						serverKeyStore,
						serverKeyStorePassword),
					new TLSTrustManagerProvider.PKCS12(
						serverTrustStore,
						serverTrustStorePassword),
					new TLSParametersProvider.Default(),
					new SecureRandomProvider.Default()
				))
			.setHostChannelAcceptor(channel ->
			{
				final Object received = channel.receive();
				System.out.println("received: " + received);
				channel.send(received);
			})
			.createHost();

		// run the host, making it constantly listen for new connections and relaying them to the logic
		host.run();
	}
}

The provided implementations are:

org.eclipse.serializer.communication.tls.TLSKeyManagerProvider.Default
provides no javax.net.ssl.KeyManagers, so the SSLEngine uses the systems’s default KeyManager.

org.eclipse.serializer.communication.tls.TLSKeyManagerProvider.PKCS12
Creates a SunX509 javax.net.ssl.KeyManagers by loading a PKCS12 key store from the file system.

org.eclipse.serializer.communication.tls.TLSTrustManagerProvider.Default
provides no javax.net.ssl.TrustManager, so the SSLEngine uses the systems’s default TrustManager.

org.eclipse.serializer.communication.tls.TLSTrustManagerProvider.PKCS12
Creates a SunX509 javax.net.ssl.TrustManager by loading a PKCS12 key store from the file system.

org.eclipse.serializer.communication.tls.TLSParametersProvider.Default
- provides javax.net.ssl.SSLParameters with client authentication enabled
- protocol string is TLSv1.2
- timeout of 1000ms for the TLS handshake

org.eclipse.serializer.communication.tls.SecureRandomProvider.Default
provides a null java.security.SecureRandom to let the SLLengine use the system default SecureRandom