Skip to content

Getting Started

This page is the minimum working path for an integration developer. It shows the smallest runtime that can start, register a collection, and serve local reads and writes.

If you are integrating DSM into a service today, start here first, even if you plan to use Spring Boot later.

What You Will Build

In this guide you will:

  1. add the core DSM dependency
  2. model one register entity
  3. create a runtime with stable cluster and service identity
  4. register one collection
  5. start the runtime and use the collection handle

Prerequisites

  • Java 25+
  • Maven 3.6+
  • one long-lived service process that will host the DSM runtime

Step 1: Add The Dependency

xml
<dependency>
  <groupId>com.leanowtech.dsm</groupId>
  <artifactId>dsm-core</artifactId>
  <version>${dsm.version}</version>
</dependency>

Use dsm-core when your service owns runtime creation directly. If you want Spring Boot auto-configuration, finish this page first and then move to the Spring Boot guide.

Step 2: Model One Register Entity

Register and CRDT collections work with entities that implement DsmEntity<E>. Lease collections use LeaseEntity<E>.

The important modeling rules are:

  • entities should be immutable
  • entryKey() identifies the logical record inside the collection
  • DSM metadata is copied in through withMetadata(...)
  • codecs must be deterministic across nodes
java
public record RouteHint(
        String entryKey,
        EntityMetadata metadata,
        String address)
        implements DsmEntity<RouteHint> {

    @Override
    public RouteHint withMetadata(EntityMetadata metadata) {
        return new RouteHint(entryKey, metadata, address);
    }
}

Use a register first unless you specifically need lease ownership or CRDT local-write convergence.

Step 3: Create The Runtime

The runtime needs three things before it can build:

  • clusterId: the DSM cluster boundary
  • serviceId: the service-family boundary
  • ClusterMembership: how peers find and track each other

For the smallest local setup, use standalone membership.

java
NodeInfo self = new NodeInfo("node-a", "127.0.0.1", 9090);

DsmRuntime runtime = DsmRuntimeBuilder.builder()
    .clusterId("runtime-example")
    .serviceId("gateway-service")
    .membership(new StandaloneClusterMembership(self))
    .build();

Keep clusterId stable for the deployed DSM cluster. Keep serviceId stable for the service family sharing the runtime view. Do not treat them as display labels.

Step 4: Register A Collection

Collections are identified by a three-part locator:

  • tenantId
  • applicationId
  • collectionId

For a register collection, use CollectionSpecBuilder.register(...).

java
DsmRegister<RouteHint> routeHints = runtime.register(
    CollectionSpecBuilder.<RouteHint>register(
            "shared",
            "gateway",
            "route-hints")
        .schemaId("route-hints/v1")
        .codec(new RouteHintCodec())
        .build());

The defaults used by this builder are appropriate for simple replicated metadata:

  • consistency tier: REGISTER
  • replication profile: embedded register
  • QoS profile: best-effort metadata
  • persistence profile: ephemeral

Step 5: Start The Runtime

Registration does not start lifecycle services by itself. Start the runtime explicitly.

java
runtime.start();

At this point the runtime is ready to accept local collection operations.

Step 6: Use The Collection Handle

DsmRegister<E> is the public register API. The core methods you will usually use first are put, get, all, remove, and size.

java
routeHints.put(new RouteHint("orders", null, "10.0.0.12:8443"));

routeHints.get("orders")
    .ifPresent(route -> System.out.println(route.address()));

System.out.println(routeHints.size());

If you want to inspect runtime state during local development:

java
System.out.println(runtime.state());
System.out.println(runtime.isReady());
System.out.println(runtime.clusterView());
System.out.println(runtime.diagnostics().totalEntries());

Common Mistakes

Reusing Unstable Identifiers

Do not generate clusterId or serviceId dynamically per process. They are isolation boundaries, not ephemeral node labels.

Treating Collection IDs As Optional Naming

The locator is the logical identity of the collection. All nodes that should converge on the same collection must use the same tenant, application, and collection identifiers.

Starting With Lease Or CRDT Without Needing Them

If you only need replicated metadata, start with a register collection. Lease collections add ownership semantics. CRDT collections add mergeable local-write behavior and extra supporting types.

Repository Example

The repository includes a runnable example that creates register, lease, and CRDT collections:

bash
mvn -pl dsm-examples exec:java

Next Reading