Architecture Overview
Architecture Overview
Understanding Morphium's internal architecture and component relationships.
High-Level Architecture
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Application │ │ Messaging │ │ Cache │
│ │ │ System │ │ Management │
└─────────┬───────┘ └─────────┬───────┘ └─────────┬───────┘
│ │ │
└──────────────────────┼──────────────────────┘
│
┌─────────────────────────────────────┐
│ Morphium Core │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ Query │ │ Object │ │
│ │ System │ │ Mapper │ │
│ └─────────────┘ └─────────────┘ │
└─────────────────┬───────────────────┘
│
┌─────────────────────────────────────┐
│ Driver Layer │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ Pooled │ │ Single │ │
│ │ Driver │ │ Driver │ │
│ └─────────────┘ └─────────────┘ │
└─────────────────┬───────────────────┘
│
┌─────────────────────────────────────┐
│ Wire Protocol │
│ MongoDB Communication Layer │
└─────────────────┬───────────────────┘
│
┌─────────────────────────────────────┐
│ MongoDB │
│ (Replica Set / Cluster) │
└─────────────────────────────────────┘
Core Components
1. Morphium Core (Morphium.java)
Central facade providing all database operations and configuration.
Key Responsibilities:
- Configuration management
- Driver lifecycle
- Transaction coordination
- Entity lifecycle management
Main APIs:
// CRUD operations
morphium.store(entity);
morphium.delete(entity);
Query<T> query = morphium.createQueryFor(Class.class);
// Transaction support
morphium.beginTransaction();
morphium.commitTransaction();
morphium.abortTransaction();
// Configuration access
MorphiumConfig config = morphium.getConfig();
2. Driver Architecture
Three driver implementations for different use cases:
PooledDriver (Default - Production)
- Connection pooling with configurable min/max connections per host
- Replica set support with automatic failover
- Health monitoring with heartbeat checks
- Load balancing across replica set members
// Internal architecture
PooledDriver {
Map<String, BlockingQueue<Connection>> connectionPool;
Map<Integer, Connection> borrowedConnections;
Map<String, AtomicInteger> waitCounter;
ScheduledExecutorService heartbeat;
}
SingleMongoConnectDriver
- Single connection per operation
- Simpler implementation for low-concurrency scenarios
- No connection pooling overhead
InMemoryDriver (Testing)
- Full in-memory MongoDB emulation
- No network communication
- Supports most MongoDB operations including aggregation
- Perfect for unit testing
3. Object Mapping System
ObjectMapperImpl
Bidirectional mapping between Java objects and BSON documents.
Features:
- Annotation-driven mapping (
@Entity,@Embedded,@Property) - Type conversion for Java → BSON → Java
- Reference resolution (lazy and eager)
- Polymorphism support with class name storage
Mapping Flow:
Java Object → ObjectMapper → BSON Document → MongoDB
MongoDB → BSON Document → ObjectMapper → Java Object
Type Mappers
Specialized mappers for different Java types:
BigDecimalTypeMapperBigIntegerTypeMapperDateTypeMapperEnumTypeMapper- Collections and arrays
4. Query System
Query Interface
Fluent API for building MongoDB queries:
Query<User> q = morphium.createQueryFor(User.class)
.f("status").eq("active")
.f("age").gte(18)
.sort("-created")
.limit(100);
MorphiumIterator
Paged iteration for large result sets:
- Configurable window size
- Prefetching support
- Thread-safe access
- Memory-efficient processing
Aggregation Framework
MongoDB aggregation pipeline support:
Aggregator<Order, OrderStats> agg = morphium.createAggregator(Order.class, OrderStats.class)
.match(morphium.createQueryFor(Order.class).f("status").eq("completed"))
.group("customerId").sum("total", "$amount").avg("avgAmount", "$amount").end()
.sort("total");
5. Caching System
Multi-Level Caching
- Query Result Cache - Caches query results
- ID Cache - Caches individual entities by ID
- Write Cache - Buffers writes for performance
Cache Synchronization
Cluster-aware caching with synchronization:
- WatchingCacheSynchronizer - Uses MongoDB Change Streams
- MessagingCacheSynchronizer - Uses Morphium messaging
- Manual cache control for custom strategies
Cache Strategies
@Cache(
timeout = 60000, // 60-second TTL
maxEntries = 10000, // LRU eviction limit
strategy = Cache.ClearStrategy.LRU,
syncCache = Cache.SyncCacheStrategy.CLEAR_TYPE_CACHE
)
6. Messaging System
MongoDB-Based Message Queue
Unique approach: Uses MongoDB collections as message queues.
Key Features:
- Topic-based routing
- Exclusive vs broadcast delivery
- Request/response patterns
- Message persistence and durability
- Change Stream integration for real-time processing
Message Processing Flow
Sender → MongoDB Collection → Change Stream/Polling → Listener
↓
Message Persistence
Implementation Variants
- StdMessaging - Standard implementation
- AdvancedSplitCollectionMessaging - Scalable variant with collection splitting
7. Writer System
Three Writer Types
-
Synchronous Writer (
MorphiumWriter)- Immediate writes
- Strong consistency
- Simple error handling
-
Asynchronous Writer (
AsyncWriterImpl)- Non-blocking writes
- Callback-based completion
- Higher throughput
-
Buffered Writer (
BufferedMorphiumWriterImpl)- Write batching for performance
- Configurable buffer size and timeout
- Risk of data loss on system failure
@Entity
@WriteBuffer(size = 1000, timeout = 5000,
strategy = WriteBuffer.STRATEGY.WRITE_OLD)
public class LogEntry {
// High-frequency writes use buffering
}
Threading Model
Virtual Threads (JDK 21+)
Morphium leverages virtual threads for better concurrency:
// Connection pool uses virtual thread factory
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(5,
Thread.ofVirtual().name("MCon-", 0).factory());
// Individual operations use virtual threads
Thread.ofVirtual().name("HeartbeatCheck-" + host).start(() -> {
// Heartbeat logic
});
Concurrency Patterns
-
Connection Pool Management
- Lock-free connection borrowing/returning
- Atomic counters for statistics
- ConcurrentHashMap for connection storage
-
Cache Management
- Lock-free cache access
- Atomic cache statistics
- Background cache cleanup
-
Message Processing
- Configurable single/multi-threaded processing
- Thread-safe message listeners
- Concurrent message polling
Configuration Architecture
Modular Configuration System
MorphiumConfig {
ConnectionSettings connectionSettings;
ClusterSettings clusterSettings;
DriverSettings driverSettings;
MessagingSettings messagingSettings;
CacheSettings cacheSettings;
ThreadPoolSettings threadPoolSettings;
WriterSettings writerSettings;
// ... other settings
}
Configuration Sources
- Programmatic - Direct Java configuration
- Properties Files - Standard Java properties
- JSON - Structured JSON configuration
- Environment Variables - System environment
Extension Points
Plugin Architecture
Morphium provides multiple extension points:
- Custom Drivers - Implement
MorphiumDriverinterface - Name Providers - Custom collection naming strategies
- Object Mappers - Custom serialization logic
- Cache Implementations - JCache integration support
- Encryption Providers - Field-level encryption
- Lifecycle Listeners - Storage event hooks
Example Extension
// Custom name provider for time-based collections
public class TimeBasedNameProvider implements NameProvider {
@Override
public String getCollectionName(Class<?> type, ObjectMapper om,
boolean translateCamelCase, boolean useFQN,
String specifiedName, Morphium morphium) {
SimpleDateFormat df = new SimpleDateFormat("yyyyMM");
String date = df.format(new Date());
return specifiedName + "_" + date;
}
}
@Entity(nameProvider = TimeBasedNameProvider.class)
public class LogEntry {
// Will be stored in collections like "log_entry_202412"
}
Performance Architecture
Key Performance Features
-
Connection Pooling
- Reduces connection overhead
- Configurable pool sizes per host
- Connection health monitoring
-
Query Optimization
- Index-aware query building
- Result caching at multiple levels
- Projection support to limit data transfer
-
Batching Support
- Bulk write operations
- Message batching
- Aggregation pipeline optimization
-
Async Operations
- Non-blocking I/O where possible
- Callback-based async API
- Virtual thread utilization
Memory Management
- Bounded caches with LRU eviction
- Connection lifecycle management
- Large result set streaming via iterators
- Reference counting for shared resources
Design Principles
1. Annotation-Driven Configuration
Minimal XML/configuration files, maximum annotation-based setup.
2. Fail-Fast Philosophy
Early detection of configuration and runtime errors.
3. Extensibility
Plugin architecture for customization without core changes.
4. Performance First
Design decisions prioritize performance and scalability.
5. MongoDB-Native
Deep integration with MongoDB features and concepts.
6. Type Safety
Compile-time checking where possible, runtime validation where necessary.
This architecture provides high performance, scalability, and flexibility while maintaining simplicity for common use cases and extensibility for advanced scenarios.