A comprehensive Java library for building and managing KMIP (Key Management Interoperability Protocol) data types with support for TTLV serialization, JSON/XML mapping, and extensible type systems.
- If you are using AI, be frank and upfront about it in the PRs and discusions
- Contribute by understanding the project goals, if you use AI to blindly create PRs they will be rejected
- Documentation docs will be heavily scrutinized for brevity and concise explanation
- All PRs must be to develop or feature branch
- Testing & Coverage: Testing Guide
- Boilerplates:
- Performance:
- Installation - How to add the library to your project
- Build System - Using Makefile, Taskfile, and justfile
- Configuration - Basic setup and configuration
- Core Concepts - Key architectural concepts and design decisions
- Type System - Understanding KMIP's type system
- Serialization - Serialization formats and protocols
-
Development Guide - Overview and checklists; see linked FooDemo boilerplates
- Testing Guide - Testing patterns and best practices
- Quick Start - Fast path to add new types
-
Implementation Reference - Comprehensive implementation details
- Core Concepts - Base interfaces and patterns
- Enumerations - Type-safe enumerations
- Attributes - Attribute implementation
- Structures - Complex data structures
- Serialization - Advanced serialization
- Testing - Advanced testing patterns
- Validation - Advanced validation
- Enumerations - Available enumeration types and their usage
- Attributes - KMIP attribute types and validation rules
- Structures - Complex KMIP data structures and composition
- Code Style - Coding standards and conventions
- Pull Requests - How to contribute code
- Release Process - Versioning and releases
- Java 21 or higher
- Maven 3.6 or higher
Add the dependency to your pom.xml:
<dependency>
<groupId>org.purpleBean</groupId>
<artifactId>kmip-adapter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>// Minimal JSON round-trip with a built-in type
import com.fasterxml.jackson.databind.ObjectMapper;
import org.purpleBean.kmip.KmipContext;
import org.purpleBean.kmip.KmipSpec;
import org.purpleBean.kmip.ProtocolVersion;
import org.purpleBean.kmip.codec.json.KmipJsonModule;
KmipContext.setSpec(KmipSpec.V1_2);
try {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new KmipJsonModule());
ProtocolVersion original = ProtocolVersion.of(1, 2);
String json = mapper.writeValueAsString(original);
ProtocolVersion restored = mapper.readValue(json, ProtocolVersion.class);
} finally {
KmipContext.clear();
}- Type-safe KMIP data structures with compile-time validation
- Extensible enumeration system supporting custom values and version compatibility
- Multi-format serialization (TTLV, JSON, XML) with Jackson integration
- Thread-safe codec contexts for version-specific processing
- Custom type registration for extending the type system
- Validation framework for input verification
- Comprehensive test suite with 500+ tests
- Performance optimized for high-throughput scenarios
- Java 21 or higher
- Maven 3.6 or higher
Add to your pom.xml:
<dependency>
<groupId>org.purpleBean</groupId>
<artifactId>kmip-adapter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>import org.purpleBean.kmip.common.ActivationDate;
import org.purpleBean.kmip.common.ActivationDateAttribute;
import org.purpleBean.kmip.common.enumeration.State;
import org.purpleBean.kmip.common.structure.SampleStructure;
import org.purpleBean.kmip.KmipSpec;
// Set KMIP specification context
KmipContext.setSpec(KmipSpec.V1_2);
// Create basic types
State activeState = new State(State.Standard.ACTIVE);
ActivationDate activationDate = ActivationDate.builder()
.value(OffsetDateTime.now())
.build();
// Create complex structures
SampleStructure structure = SampleStructure.builder()
.activationDate(activationDate)
.state(activeState)
.build();import org.purpleBean.kmip.common.enumeration.State;
import org.purpleBean.kmip.KmipSpec;
// Register custom state values
State.Value customState = State.register(
-1000001,
"CustomPendingState",
Set.of(KmipSpec.UnknownVersion, KmipSpec.V1_2)
);
// Use custom state
State myState = new State(customState);import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
// Serialize to JSON
String json = mapper.writeValueAsString(structure);
// Deserialize from JSON
SampleStructure restored = mapper.readValue(json, SampleStructure.class);import com.fasterxml.jackson.dataformat.xml.XmlMapper;
XmlMapper xmlMapper = new XmlMapper();
xmlMapper.registerModule(new JavaTimeModule());
// Serialize to XML
String xml = xmlMapper.writeValueAsString(structure);
// Deserialize from XML
SampleStructure restored = xmlMapper.readValue(xml, SampleStructure.class);- Standard Tags: All KMIP 1.2 specification tags pre-registered
- Extension Support: Custom tag registration with validation
- Byte Operations: Efficient tag-to-byte conversion for TTLV encoding
- Registry Management: Thread-safe tag lookup and management
- TTLV Types: Complete KMIP encoding type enumeration
- Type Safety: Compile-time validation of encoding compatibility
- Extensibility: Support for custom encoding types
- KmipSpec Enum: Version-specific feature support
- Compatibility Checking: Automatic validation of type/version combinations
- Context Management: Thread-local specification contexts
public interface KmipDataType {
KmipTag getKmipTag();
EncodingType getEncodingType();
boolean isSupportedFor(KmipSpec spec);
}
public interface KmipStructure extends KmipDataType {
// Marker interface for complex structures
}- ActivationDateAttribute: Date/time attributes with timezone support
- State: Extensible enumeration for object states
- ProtocolVersion: KMIP protocol version management
- SampleStructure: Example composite structure implementation
The KmipContext is a critical component that manages KMIP specification versions in a thread-safe manner. It uses ThreadLocal storage to ensure each thread has its own isolated context.
Why Use KmipContext:
- Version Validation: Ensures KMIP objects are created with compatible specification versions
- Thread Safety: Prevents version conflicts in multi-threaded applications
- Automatic Validation: KMIP types automatically validate against the current context
- Error Prevention: Catches unsupported value/version combinations at creation time
When to Use KmipContext:
-
Before Creating KMIP Objects - Always set the context before instantiating KMIP types:
// Set context first KmipContext.setSpec(KmipSpec.V1_2); // Then create objects - they will validate against V1_2 State activeState = new State(State.Standard.ACTIVE);
-
In Multi-threaded Applications - Each thread should set its own context:
// Thread 1 CompletableFuture.runAsync(() -> { KmipContext.setSpec(KmipSpec.V1_2); // Process V1_2 objects safely }); // Thread 2 - independent context CompletableFuture.runAsync(() -> { KmipContext.setSpec(KmipSpec.V1_2); // Process with isolated context });
-
When Processing Different KMIP Versions - Switch contexts for different specification versions:
// Process legacy data KmipContext.setSpec(KmipSpec.UnknownVersion); // ... process older format // Switch to current version KmipContext.setSpec(KmipSpec.V1_2); // ... process current format
-
In Web Applications - Set context per request:
@RestController public class KmipController { @PostMapping("/kmip/v1.2/objects") public ResponseEntity<?> createObject(@RequestBody ObjectRequest request) { // Set context for this request KmipContext.setSpec(KmipSpec.V1_2); try { // Create and process KMIP objects return ResponseEntity.ok(processRequest(request)); } finally { // Clean up context KmipContext.clear(); } } }
Context Management Best Practices:
// Always clear context when done (optional but recommended)
try {
KmipContext.setSpec(KmipSpec.V1_2);
// ... your KMIP operations
} finally {
KmipContext.clear(); // Resets to UnknownVersion
}
// Check current context
KmipSpec current = KmipContext.getSpec();What Happens Without Context:
- Objects default to
UnknownVersionwhich may not support all features - Version validation may fail for newer KMIP types
- Serialization behavior may be inconsistent
- Validation: Type/version compatibility checking
- Transformation: Object to intermediate representation
- Encoding: Format-specific serialization (TTLV/JSON/XML)
- Output: Serialized byte array or string
The library includes a comprehensive test suite with 540+ tests covering:
- Unit Tests: Individual component validation
- Integration Tests: End-to-end workflow testing
- Serialization Tests: Multi-format round-trip validation
- Parallel Tests: Thread safety and concurrent access
- Edge Cases: Boundary conditions and error scenarios
# Run unit tests (default)
mvn test
# Include integration tests (tagged with @Tag("integration"))
mvn -Pwith-integration test
# Run with coverage report (HTML report under target/site/jacoco/index.html)
mvn clean test
# Run specific test class
mvn test -Dtest=ProtocolVersionTest
# Run performance benchmarks (JMH) without affecting unit tests
mvn -Pperf verify
# Optional: pass JMH args
mvn -Pperf -Dbench.args="-wi 3 -i 5 -f 1 -rf json -rff target/jmh.json" verify- Generate coverage and open HTML report:
mvn clean test
open target/site/jacoco/index.html # macOS; use xdg-open on LinuxCoverage reports are generated at:
- target/site/jacoco/index.html
Optional strict coverage gate (fail build below thresholds):
mvn -Pcoverage-strict verifyCurrent test coverage includes:
- Core Types: 100% coverage of all KMIP data types
- Serialization: Complete JSON/XML round-trip testing
- Registry Operations: Full enumeration extension testing
- Thread Safety: Concurrent codec context validation
- Error Handling: Comprehensive exception scenario testing
Note: Per-class codec tests are organized to mirror runtime packages for easier discoverability, for example:
- JSON:
src/test/java/org/purpleBean/kmip/codec/json/common/... - XML:
src/test/java/org/purpleBean/kmip/codec/xml/common/... - TTLV:
src/test/java/org/purpleBean/kmip/codec/ttlv/common/...
Core dependencies automatically included:
- Jackson Databind (2.20.0): JSON/XML processing
- Jackson JSR310 (2.20.0): Java Time API support
- Lombok (1.18.40): Code generation and null safety
- Spring Boot (3.5.5): Optional dependency injection support
@Configuration
public class KmipConfig {
@Bean
public ObjectMapper kmipObjectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
return mapper;
}
}// Custom Jackson module for KMIP types
public class KmipModule extends SimpleModule {
public KmipModule() {
addSerializer(State.class, new StateSerializer());
addDeserializer(State.class, new StateDeserializer());
}
}- Immutable Objects: All KMIP types are immutable for thread safety
- Registry Caching: Enumeration values cached for fast lookup
- Lazy Loading: Complex structures built on-demand
- Context Isolation: Thread-local codec contexts prevent interference
- Concurrent Registry: Thread-safe enumeration registration
- Immutable State: No shared mutable state between threads
- Reuse
ObjectMapperinstances for better performance - Set codec context once per thread rather than per operation
- Use builder patterns for complex object construction
-
Clone Repository
git clone https://github.com/purplebean/kmip-adapter.git cd kmip-adapter -
Build Project
mvn clean compile
-
Run Tests
mvn test
The project enforces code quality through:
- Checkstyle: Google Java Style compliance
- JaCoCo: Code coverage reporting
- JUnit 5: Modern testing framework
- AssertJ: Fluent assertion library
- Follow Google Java Style Guide
- Maintain test coverage above 90%
- Include comprehensive JavaDoc documentation
- Add integration tests for new features
- Update README for API changes
This project is licensed under the GNU Lesser General Public License v3.0 - see the LICENSE file for details.
- Documentation: API Documentation
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Initial release with KMIP 1.2 support
- Complete TTLV, JSON, and XML serialization
- Extensible enumeration system
- Thread-safe codec contexts
- Comprehensive test suite (540+ tests)
Built with ❤️ by the PurpleBean Development Team