Microswitch
Microswitch - Advanced Embedded Deployment Strategy Library A powerful Java Spring Boot library for implementing sophisticated deployment strategies with real-time traffic management on low level and deep result comparison.
Install / Use
/learn @n11techhub/MicroswitchREADME
🚀 Microswitch — Deployment Strategy Library
Microswitch is a lightweight library for Java/Spring Boot that lets you apply deployment strategies programmatically: Canary, Shadow, and Blue/Green. It provides a single, minimal public API and hides all internals via JPMS.
This README explains how to add Microswitch to your project, configure it, and use it safely in production.
Table of Contents
- Features
- Requirements
- Installation
- Quick Start
- Configuration
- Public API & Module Boundaries
- JPMS Module-Info Usage
- Metrics & Actuator
- Examples
- Troubleshooting
- Contributing & Governance
- Security
- License (Apache-2.0)
Features
- Canary, Shadow, and Blue/Green strategies
- Lazy evaluation (only the selected Supplier executes)
- Optional Prometheus/Micrometer metrics
- YAML-based configuration
- Spring Boot auto-configuration
- Actuator endpoint for runtime visibility
Requirements
- Java 21+
- Spring Boot 3.5.5+
Installation
Option 1: JitPack (No Authentication Required) ⭐ Recommended
Maven
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependency>
<groupId>com.github.n11tech</groupId>
<artifactId>microswitch</artifactId>
<version>v1.4.8</version> <!-- JitPack uses tag name with 'v' prefix -->
</dependency>
Gradle
repositories {
maven { url 'https://jitpack.io' }
}
dependencies {
implementation 'com.github.n11tech:microswitch:v1.4.8' // JitPack uses tag name with 'v' prefix
}
Option 2: GitHub Packages (Authentication Required)
First, configure authentication in ~/.m2/settings.xml:
<settings>
<servers>
<server>
<id>github</id>
<username>YOUR_GITHUB_USERNAME</username>
<password>YOUR_GITHUB_TOKEN</password>
</server>
</servers>
</settings>
Then add to your project:
Maven
<repositories>
<repository>
<id>github</id>
<url>https://maven.pkg.github.com/n11tech/microswitch</url>
</repository>
</repositories>
<dependency>
<groupId>io.github.n11tech</groupId>
<artifactId>microswitch</artifactId>
<version>1.4.8</version>
</dependency>
Gradle
repositories {
maven {
url = uri("https://maven.pkg.github.com/n11tech/microswitch")
credentials {
username = project.findProperty("gpr.user") ?: System.getenv("USERNAME")
password = project.findProperty("gpr.key") ?: System.getenv("TOKEN")
}
}
}
dependencies {
implementation 'io.github.n11tech:microswitch:1.4.8'
}
Quick Start
- Configure application properties (application.yml)
microswitch:
enabled: true # master switch
services:
user-service:
enabled: true
activeStrategy: canary # NEW in v1.1.0: configuration-driven strategy selection
canary:
percentage: 80/20 # stable/experimental split
algorithm: SEQUENCE # AlgorithmType enum (e.g., SEQUENCE, RANDOM)
blueGreen:
weight: 1/0 # 1/0 → primary, 0/1 → secondary
ttl: 60000 # milliseconds
shadow:
stable: primary # returns result from this path
mirror: secondary # mirrors this path when triggered
mirrorPercentage: 10 # mirror every 10% of calls
comparator: # NEW in v1.2.2: nested comparator tuning
mode: disable # enable/disable deep comparison
maxCompareTimeMillis: 200
samplingOnHuge:
enable: false # enable sampling for large collections
maxCollectionElements: 1000
stride: 10
maxFieldsPerClass: 100
- Inject and use
DeploymentManager
@Service
public class UserService {
private final DeploymentManager deploymentManager;
public UserService(DeploymentManager deploymentManager) {
this.deploymentManager = deploymentManager;
}
public User createUser(String name) {
// NEW in v1.1.0: Configuration-driven strategy selection
return deploymentManager.execute(
() -> createUserV1(name), // stable
() -> createUserV2(name), // experimental
"user-service" // uses activeStrategy from config
);
// Legacy approach (still supported but deprecated)
// return deploymentManager.canary(() -> createUserV1(name), () -> createUserV2(name), "user-service");
}
private User createUserV1(String name) { return new User(name, "v1"); }
private User createUserV2(String name) { return new User(name, "v2"); }
}
Deployment Strategies
Canary
Route a percentage of traffic to the experimental version.
// %80 stable, %20 experimental
String result = deploymentManager.canary(
this::stableMethod,
this::experimentalMethod,
"service-key"
);
Shadow
Execute the experimental path in the background, but always return the stable result to callers. Useful for validating parity and measuring performance.
// Stable döner, experimental paralel çalışır
Integer result = deploymentManager.shadow(
this::stableMethod,
this::experimentalMethod,
"service-key"
);
Blue/Green
Choose between two versions using a binary weight selector and/or a TTL cutoff for full switchover. The weight accepts only two forms:
1/0→ route to primary0/1→ route to secondary
// Primary percentage veya TTL tabanlı seçim
String result = deploymentManager.blueGreen(
this::blueMethod,
this::greenMethod,
"service-key"
);
Release Notes
See the full changelog here: CHANGELOG.md
Version 1.4.8 (Latest)
New in 1.4.8 — JitPack Build Fixes
- Fixed: JitPack build issues with Java 21 and JPMS modules
- Added:
jitpack.ymlconfiguration to ensure OpenJDK 21 is used - Updated: Maven compiler plugin configuration for better compatibility
New in 1.4.7 — GroupId Migration and JitPack Support
See CHANGELOG.md for complete details. Major changes include:
- Breaking Change: Maven GroupId changed from
io.development.n11techtoio.github.n11tech - JitPack Support: Now available via JitPack without authentication requirement
- Simplified Workflow: Removed complex version checking from GitHub Actions
Carried over from 1.4.6 — Enhanced Stability and Performance
- Comparator tuning for large data structures (Shadow strategy)
microswitch:
services:
order-service:
shadow:
comparator:
mode: enable # enable/disable deep comparison
maxCompareTimeMillis: 200 # time budget in ms; returns early when exceeded
samplingOnHuge:
enable: false # enable sampling mode for huge lists
maxCollectionElements: 1000 # switch to sampling for very large lists
stride: 10 # sampling step for lists
maxFieldsPerClass: 100
- Large lists: head/tail + stride sampling prevents O(n) deep scans
- Time budget: early return if the total comparison time exceeds the configured budget
- Operational visibility with WARN logs
- Sampling activated:
Deep comparison sampling activated for large list (size=...) - Time budget exceeded:
Deep comparison time budget exceeded (>X ms) at ... after Y ms; returning early
These logs make performance-protection behavior observable in production without extra instrumentation.
- Backward compatibility
- Legacy
shadow.comparator: enable|disablestill works and maps toshadow.comparator.mode - New nested fields are optional and come with safe defaults
Improvements carried over from 1.1.2
- Enhanced constructor injection in auto-configuration
- Improved logging and configuration validation
Bug Fixes & Improvements
1. Enhanced Constructor Injection
Improved dependency injection reliability by replacing field injection with constructor injection in MicroswitchAutoConfiguration:
// Before: Field injection with @Autowired
@Autowired
private InitializerConfiguration properties;
// After: Constructor injection (more reliable)
public MicroswitchAutoConfiguration(InitializerConfiguration properties) {
this.properties = properties;
}
Benefits:
- More reliable dependency injection
- Better testability and immutability
- Follows Spring Boot best practices
- Eliminates potential null pointer exceptions
2. Improved Logging and Error Handling
Enhanced logging throughout the library for better debugging and monitoring:
- Added detailed initialization logging based on enabled/disabled state
- Improved error messages for configuration validation
- Enhanced debug logging for strategy execution paths
- Better exception handling with more descriptive error messages
3. Configuration Validation Improvements
Strengthened configuration validation and error reporting:
- Better validation messages for invalid strategy configurations
- Improved handling of missing or malformed configuration sections
- Enhanced fallback mechanisms for edge cases
Benefits
- Better Reliability: Constructor injection eliminates potential initialization issues
- Enhanced Debugging: Improved logging helps identify configuration and execution issues
- Stronger Validation: Better error messages
