Ice Client SDK Integration Guide

Learn how to integrate Ice Client SDK into your business applications

Overview

Ice Client is the rule execution engine that needs to be integrated into your business applications. Java SDK is currently available with two integration methods:

MethodPackageUse Case
SpringBoot Starterice-spring-boot-starter-3x / ice-spring-boot-starter-2xSpringBoot projects (Recommended)
Core Packageice-coreNon-SpringBoot projects

SpringBoot Project Integration

1. Add Dependency

Choose the appropriate Starter based on your SpringBoot version:

<dependency>
  <groupId>com.waitmoon.ice</groupId>
  <artifactId>ice-spring-boot-starter-3x</artifactId>
  <version>2.0.0</version>
</dependency>
<dependency>
  <groupId>com.waitmoon.ice</groupId>
  <artifactId>ice-spring-boot-starter-2x</artifactId>
  <version>2.0.0</version>
</dependency>

2. Configure application.yml

ice:
  # Application ID (required) - corresponds to App in Server
  app: 1
  
  # Shared storage path (required) - must share same directory with Server
  storage:
    path: ./ice-data
  
  # Leaf node scan packages
  # Multiple packages separated by comma, scans all if not configured (slower)
  scan: com.your.package
  
  # Version polling interval (seconds), default 5
  poll-interval: 5
  
  # Heartbeat update interval (seconds), default 10
  heartbeat-interval: 10
  
  # Thread pool configuration (for concurrent relation nodes)
  pool:
    parallelism: -1  # Default -1, ≤0 uses ForkJoinPool default

3. Develop Leaf Nodes

Create leaf node classes under the configured scan package path:

package com.your.package;

import com.ice.core.leaf.roam.BaseLeafRoamResult;
import lombok.Data;
import lombok.EqualsAndHashCode;

@Data
@EqualsAndHashCode(callSuper = true)
public class AmountResult extends BaseLeafRoamResult {

    // Fields configurable in Server
    private String uidKey;
    private double amount;

    @Override
    protected boolean doRoamResult(IceRoam roam) {
        Integer uid = roam.getMulti(uidKey);
        if (uid == null || amount <= 0) {
            return false;
        }
        // Business logic
        return sendService.sendAmount(uid, amount);
    }
}

4. Execute Rules

@Service
public class YourService {

    public void processRule(Long userId) {
        IcePack pack = new IcePack();
        pack.setIceId(1L);  // Rule ID
        
        IceRoam roam = new IceRoam();
        roam.put("uid", userId);
        pack.setRoam(roam);
        
        // Synchronous execution
        Ice.syncProcess(pack);
        
        // Get execution result
        Object result = roam.get("RESULT_KEY");
    }
}

Non-SpringBoot Project Integration

1. Add Dependency

<dependency>
  <groupId>com.waitmoon.ice</groupId>
  <artifactId>ice-core</artifactId>
  <version>2.0.0</version>
</dependency>

2. Initialize Client

import com.ice.core.client.IceFileClient;
import java.util.Set;

public class IceClientInit {

    private static IceFileClient iceFileClient;

    public static void init() {
        // Method 1: Simple constructor
        iceFileClient = new IceFileClient(
            1,                    // app ID
            "./ice-data",         // shared storage path
            "com.your.package"    // leaf node scan package
        );

        // Method 2: Full constructor
        iceFileClient = new IceFileClient(
            1,                              // app ID
            "./ice-data",                   // shared storage path
            -1,                             // parallelism (≤0 uses default)
            Set.of("com.your.package"),     // scan packages set
            5,                              // poll interval (seconds)
            10                              // heartbeat interval (seconds)
        );

        // Start client
        iceFileClient.start();
        
        // Wait for startup completion
        iceFileClient.waitStarted();
    }

    public static void destroy() {
        if (iceFileClient != null) {
            iceFileClient.destroy();
        }
    }
}

3. Configure Bean Factory (Optional)

If leaf nodes require dependency injection:

import com.ice.core.utils.IceBeanUtils;

public class IceBeanFactoryInit {

    public static void init() {
        IceBeanUtils.setIceBeanFactory(new IceBeanFactory() {
            @Override
            public <T> T getBean(Class<T> clazz) {
                // Get bean from your IoC container
                return YourContainer.getBean(clazz);
            }
        });
    }
}

4. Execute Rules

public void processRule(Long userId) {
    IcePack pack = new IcePack();
    pack.setIceId(1L);
    
    IceRoam roam = new IceRoam();
    roam.put("uid", userId);
    pack.setRoam(roam);
    
    Ice.syncProcess(pack);
}

Shared Storage Configuration

Critical Configuration

ice.storage.path (or storagePath in constructor) must share the same directory with Server!

Local Development

# Server and Client configure the same local path
ice:
  storage:
    path: ./ice-data

Docker Environment

# docker-compose.yml
services:
  ice-server:
    volumes:
      - ./ice-data:/app/ice-data

  your-app:
    volumes:
      - ./ice-data:/app/ice-data  # Same mount

Distributed Environment

Use shared storage (NFS, cloud drives, etc.):

services:
  ice-server:
    volumes:
      - /nfs/ice-data:/app/ice-data

  client-1:
    volumes:
      - /nfs/ice-data:/app/ice-data

  client-2:
    volumes:
      - /nfs/ice-data:/app/ice-data

Configuration Parameters

ParameterTypeDefaultDescription
appint-Application ID, required
storage.pathstring-Shared storage path, required
scanstringallLeaf node scan packages, comma-separated
poll-intervalint5Version polling interval (seconds)
heartbeat-intervalint10Heartbeat report interval (seconds)
pool.parallelismint-1Thread pool parallelism, ≤0 uses default

Next Steps