Milesoft Commons Library (commons)

1. Overview & Purpose

The commons library is a unified, high-performance foundation library that encapsulates core utilities, multi-tenant context propagation, timezone-aware date/time holders, lightweight self-validation helpers, and fault-tolerant retry/validation workflows used across the Milesoft ecosystem.

1.1 Strategic Architecture: Lightweight & Safe Dependency Facades

To minimize transitive dependency footprints for client-facing SDKs and downstream microservices, commons features highly optimized, null-tolerant utility facades. These facades encapsulate the most frequently used patterns from popular external libraries like Google Guava and Apache Commons Lang:

  • Preconditions: A lightweight facade for standard sanity checks (checkNotNull, checkArgument, checkState), shielding downstream projects from Guava's complex dependency graph.
  • StringUtils: A null-safe facade for fundamental character sequence checks (isBlank, isEmpty, equals), matching Apache Commons Lang behavior.
  • BooleanUtils: Null-safe Boolean assertions (isTrue, isFalse, etc.).
  • ObjectUtils: Null-safe object operations (defaultIfNull).

This strategic approach allows both lightweight client-facing SDKs and heavy internal microservices to share the exact same runtime contracts without incurring classpath pollution.


2. Installation & Status

To resolve this package from our secure Google Cloud Artifact Registry repository, configure your build.gradle as follows:

repositories {
    mavenCentral()
    maven { url "artifactregistry://us-west2-maven.pkg.dev/milesoft-repo/repo-maven" }
}

dependencies {
    // Standard platform dependency
    implementation "io.milesoft:commons:2.0.1"
}

2.1 Status

The commons library is Production-Ready and fully integrated across the Milesoft ecosystem.


3. Core Modules & Multi-Tenant Context Holders

3.1 Multi-Tenant Context Propagation (io.milesoft.actors.holders)

To guarantee secure, multi-tenant isolation, Milesoft relies on the thread-local propagation of execution contexts.

  • ActorHolder: Manages a ThreadLocal-bound Actor context representing the current request's calling entity (appId, accountId, and userId).
  • Standard Fallback: If no thread-bound context is present, ActorHolder defaults to ActorConstants.ACTOR_UNKNOWN.
import io.milesoft.primitives.actor.Actor;
import io.milesoft.actors.holders.ActorHolder;

// Binding a multi-tenant actor context to the active ThreadLocal
ActorHolder.setActor(Actor.of("app-123", "account-456").withUser("user-789"));

// Retrieving the current context safely deep in the call stack
Actor currentActor = ActorHolder.getActor();
System.out.println(currentActor.appId());     // "app-123"
System.out.println(currentActor.accountId()); // "account-456"

// Best practice: Always clear thread-local state in a try-finally block!
try {
    ActorHolder.setActor(myActor);
    // Execute tenant-isolated business logic...
} finally {
    ActorHolder.setActor(null);
}

3.2 Thread-Local Timezone Propagation (io.milesoft.temporal.holders)

Just like execution context, timezones are propagated through ThreadLocal bindings to support multi-tenant, localized date/time formatting and processing.

  • TimeZoneHolder: Manages a thread-bound ZoneId for context-specific datetime formatting, defaulting dynamically to Arizona standard time (US/Arizona).
import io.milesoft.temporal.holders.TimeZoneHolder;
import java.time.ZoneId;

// Establish active user/tenant timezone
TimeZoneHolder.setTimeZone(ZoneId.of("America/New_York"));

// Retrieve thread-bound timezone
ZoneId activeZone = TimeZoneHolder.getTimeZone();
System.out.println(activeZone.getId()); // "America/New_York"

// Reset default fallback timezone globally (e.g., at application bootstrap)
TimeZoneHolder.setDefault(ZoneId.of("America/Phoenix"));

4. High-Performance Utility Suites

4.1 Null-Tolerant JSON Processing (io.milesoft.commons.json)

The platform standardizes JSON operations on Jackson, pre-configured with time/date modules and serializers tailored for UTC compliance.

  • ObjectMapperFactory: Instantiates clean Jackson ObjectMapper instances preconfigured with JavaTimeModule and specific serializers for Duration, ZonedDateTime, OffsetDateTime, and OffsetTime.
    • lenientObjectMapper(): Returns an mapper configured with DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES and SerializationFeature.FAIL_ON_EMPTY_BEANS disabled.
  • ObjectMapperUtils: Provides rapid, null-safe conversions between Java POJOs and map containers (Map<String, Object>).
import io.milesoft.commons.json.ObjectMapperUtils;
import io.milesoft.commons.json.ObjectMapperFactory;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;

// Convert DTOs to standard JSON maps
Map<String, Object> map = ObjectMapperUtils.toMap(myDto);

// Instantiate maps back to structured POJOs
MyDto restoredDto = ObjectMapperUtils.fromMap(map, MyDto.class);

// Create custom, thread-safe lenient object mappers
ObjectMapper customMapper = ObjectMapperFactory.lenientObjectMapper();

4.2 Sophisticated Collections Operations (io.milesoft.commons.utils.CollectionUtils)

Simplifies java.util collection manipulation with clean null-safe builders and utilities.

  • Null-Safe Immutability: immutableList(List), immutableSet(Set), and immutableMap(Map) guarantee non-null, unmodifiable containers, avoiding NullPointerException and boilerplate checks.
  • Null-Safe Mutability: mutableList(List), mutableSet(Set), and mutableMap(Map) safely instantiate new collections, copying source elements if present.
  • listEqualsIgnoreOrder(list1, list2): Compares lists for equivalent elements regardless of order.
  • randomItem(List): Retrieves a random element from a list, backed by cryptographically secure random numbers.
import io.milesoft.commons.utils.CollectionUtils;
import java.util.List;
import java.util.Set;

// Safely convert a potentially null list into an unmodifiable list
List<String> safeList = CollectionUtils.immutableList(externalInputList);

// Instantiates a new LinkedHashSet from an input set (handling null cleanly)
Set<Integer> newSet = CollectionUtils.mutableSet(sourceSet);

// Compare collections for contents equality ignoring element ordering
boolean match = CollectionUtils.listEqualsIgnoreOrder(listA, listB);

4.3 Secure Random Generation (io.milesoft.commons.utils.RandomUtils)

  • RandomUtils: High-security random utility utilizing a thread-local, cryptographically secure SecureRandom instance.
  • Random strings: Easily generates high-entropy strings for credentials, passwords, or salts.
import io.milesoft.commons.utils.RandomUtils;

boolean flag = RandomUtils.nextBoolean();
int randomNum = RandomUtils.nextInt(1, 100); // 1 inclusive to 100 exclusive

// Generate random strings for secure tokens
String numericToken = RandomUtils.nextNumeric(6);       // e.g. "508314"
String alphabeticSalt = RandomUtils.nextAlphabetic(16);   // e.g. "gKdJSbQpxLmsAtPw"
String securePassword = RandomUtils.nextAlphanumeric(32); // e.g. "z9Kq8P2xW1mSb7vYt9R0nK3xJ2mL4v7P"

4.4 Date & Chronological Calculations (io.milesoft.temporal.utils)

  • DateUtils: Features comprehensive calculation, boundary evaluation, and formatting support.
    • isWithin: Evaluates whether a timestamp falls within chronological boundaries (or whether one DateTimeRange fits inside another).
    • daysApart / hoursApart: Computes the exact absolute elapsed duration between two ZonedDateTime instances, localized to a specified timezone.
    • getBeginningOfWeek / getDayOfWeek: Returns the LocalDate matching the specified day (e.g., Sunday) for a timezone, taking into account timezone-specific date boundaries.
  • ClockUtils: Provides standard mechanisms for capturing current times or fixing clock configurations for unit test predictability.
import io.milesoft.temporal.utils.DateUtils;
import io.milesoft.temporal.utils.ClockUtils;
import java.time.ZonedDateTime;
import java.time.ZoneId;
import java.time.Clock;

ZonedDateTime start = ZonedDateTime.parse("2026-07-20T00:00:00Z");
ZonedDateTime stop = ZonedDateTime.parse("2026-07-25T00:00:00Z");
ZonedDateTime target = ZonedDateTime.parse("2026-07-22T12:00:00Z");

// Boundary checking
boolean inside = DateUtils.isWithin(start, stop, target); // true

// Calculate absolute timezone-specific days apart
long days = DateUtils.daysApart(start, stop, ZoneId.of("America/New_York")); // 5

// Unit Testing utility: generate mock clock fixed on specific instants
Clock fixedClock = ClockUtils.getFixed(target);
ZonedDateTime now = ClockUtils.getNow(fixedClock); // Always returns target timestamp!

5. Advanced Flow & Logic Orchestrators

5.1 Fault-Tolerant Retry Loop Runner (io.milesoft.commons.utils.RetryUtils)

Encapsulates retry logic cleanly inside functional closures, avoiding noisy exception-handling loops.

  • RetryUtils.retryIfNecessary(maxAttempts, Supplier<RetryResult<P>>): Continually executes a functional supplier block up to maxAttempts, checking isFailure() and isRetriable() conditions.
import io.milesoft.commons.utils.RetryUtils;
import io.milesoft.commons.domain.RetryResult;

RetryResult<String> result = RetryUtils.retryIfNecessary(3, () -> {
    try {
        String response = httpClient.callExternalApi();
        return RetryResult.success(response);
    } catch (TransientException e) {
        // Mark as failure but flag as retriable
        return RetryResult.failure(true);
    } catch (FatalException e) {
        // Mark as failure and abort future retries immediately
        return RetryResult.failure(false);
    }
});

if (result.isSuccess()) {
    String data = result.getPayload();
    System.out.println("Succeeded: " + data);
}

5.2 Programmatic Multi-Validator Suite (io.milesoft.validation.utils)

Allows building compound pipelines of isolated, single-responsibility business validators.

  • Validator<I>: Functional interface exposing ValidationResult validate(I item).
  • ValidationResult: Tracks validation errors, exposing isSuccess(), isFailure(), and getErrors().
  • ValidationUtils.validate(item, List<Validator<I>>): Coordinates sequential execution of multiple validation policies on an object, aggregating all validation violations into a unified result.
import io.milesoft.validation.utils.ValidationUtils;
import io.milesoft.validation.domain.Validator;
import io.milesoft.validation.domain.ValidationResult;
import java.util.List;

// 1. Define custom, single-responsibility validators
Validator<UserDto> emailValidator = user -> {
    ValidationResult.Builder builder = ValidationResult.builder();
    if (!user.getEmail().contains("@")) {
        builder.error("Email is malformed");
    }
    return builder.build();
};

Validator<UserDto> passwordValidator = user -> {
    ValidationResult.Builder builder = ValidationResult.builder();
    if (user.getPassword().length() < 8) {
        builder.error("Password must be at least 8 characters");
    }
    return builder.build();
};

// 2. Validate DTOs sequentially and gather aggregated reports
ValidationResult result = ValidationUtils.validate(
    myUser, 
    List.of(emailValidator, passwordValidator)
);

if (result.isFailure()) {
    List<String> allErrors = result.getErrors();
    System.out.println("Validation failed with: " + allErrors);
}

6. Additional Essential Utilities

The utility packages also include helper operations designed to simplify common microservice and controller tasks:

Class Primary Purpose Key Methods
CryptoUtils Fast SHA-256 generation & OAuth/JWK signing support. hashSha256(String), isSha256(String), encodeForJwk(byte[])
WordUtils Grammar formatting & human-readable joiners. plural(String, int), count(String, int), commaSeparated(List<String>)
UrlUtils Null-safe HTTP/HTTPS path manipulation. appendParam(String, String, Object), isAbsolute(String), getDomain(String)
Base64Utils Safe, UTF-8 based Base64 translation. encodeBase64(String), decodeBase64(String)
HtmlUtils HTML text preparation. newToBr(String) (transforms \n to <br>)
PropertyUtils Clean, resource-based properties retrieval. read(String) (loads classpath properties files into Properties)
ResourceUtils Resource file retrieval. read(String) (reads classpath files directly into Strings)
StreamUtils Null-safe Java Stream initialization. stream(Collection), stream(Array), parallelStream(Collection)