From a39dc7edf0766d8d811c9677d178c37811d6763a Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sun, 1 Feb 2026 18:38:53 +0000
Subject: [PATCH 1/4] Initial plan
From e148fce8a65c506040168b415bb8627433f0d9d8 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sun, 1 Feb 2026 18:44:12 +0000
Subject: [PATCH 2/4] Add comprehensive analysis of request lifecycle
interceptor pattern for OJP
Co-authored-by: rrobetti <7221783+rrobetti@users.noreply.github.com>
---
...8-request-lifecycle-interceptor-pattern.md | 405 +++++
.../REQUEST_LIFECYCLE_INTERCEPTOR_SUMMARY.md | 360 +++++
.../REQUEST_LIFECYCLE_INTERCEPTOR_PATTERN.md | 1412 +++++++++++++++++
3 files changed, 2177 insertions(+)
create mode 100644 documents/ADRs/adr-008-request-lifecycle-interceptor-pattern.md
create mode 100644 documents/analysis/REQUEST_LIFECYCLE_INTERCEPTOR_SUMMARY.md
create mode 100644 documents/designs/REQUEST_LIFECYCLE_INTERCEPTOR_PATTERN.md
diff --git a/documents/ADRs/adr-008-request-lifecycle-interceptor-pattern.md b/documents/ADRs/adr-008-request-lifecycle-interceptor-pattern.md
new file mode 100644
index 000000000..b2a383122
--- /dev/null
+++ b/documents/ADRs/adr-008-request-lifecycle-interceptor-pattern.md
@@ -0,0 +1,405 @@
+# ADR 008: Request Lifecycle Interceptor Pattern for Extensible Integration
+
+In the context of the OJP project,
+facing the need to standardize how libraries and modules integrate with request lifecycle phases while avoiding tight coupling and enabling third-party extensibility,
+
+we decided for adopting the **Request Lifecycle Interceptor Pattern** using a Chain of Responsibility approach inspired by Servlet Filters, with ServiceLoader-based discovery
+and neglected hard-coded integration of features like Circuit Breaker, Slow Query Segregation, and SQL Enhancement directly into `StatementServiceImpl`,
+
+to achieve a pluggable architecture where external providers can create interceptors that hook into various phases of request processing (PRE_REQUEST, PRE_EXECUTION, RESOURCE_ACQUISITION, EXECUTION, POST_EXECUTION, RESOURCE_RELEASE, POST_REQUEST, EXCEPTION_HANDLING),
+accepting the complexity of chain management and phase coordination,
+
+because this pattern enables powerful extensibility, reduces coupling in the core request handling code, allows third-party providers to add functionality without modifying OJP, and follows the established ServiceLoader pattern already used successfully for ConnectionPoolProvider and XAConnectionPoolProvider.
+
+## Context
+
+OJP Server acts as a proxy between applications and databases, processing SQL queries and updates through `StatementServiceImpl`. Currently, three major features are tightly integrated into the request processing flow:
+
+1. **CircuitBreaker** - Prevents repeatedly executing failing queries
+ - Integrated via direct method calls (`preCheck`, `onSuccess`, `onFailure`)
+ - Hard-coded at specific points in `executeQuery()` and `executeUpdate()`
+
+2. **SlowQuerySegregationManager** - Prevents connection starvation from slow queries
+ - Integrated via wrapper pattern (`executeWithSegregation()`)
+ - Per-datasource instances managed in a `ConcurrentHashMap`
+
+3. **SqlEnhancerEngine** (Apache Calcite) - Optimizes and transforms SQL
+ - Integrated via direct method call in `executeQueryInternal()`
+ - Enabled/disabled via configuration flag
+
+### Problems with Current Approach
+
+1. **Tight Coupling**: Features are hard-coded into `StatementServiceImpl`, which is already 2,528 lines
+2. **Difficult Extension**: Adding new features requires modifying core classes
+3. **No Standardization**: Each feature integrates differently (method calls vs wrappers vs flags)
+4. **No Third-Party Support**: External providers cannot add lifecycle hooks
+5. **Testing Complexity**: Features cannot be easily tested in isolation
+6. **Maintenance Burden**: Changes to features require touching core request handling code
+
+### Requirements
+
+External providers should be able to:
+
+1. Hook into various phases of request processing
+2. Transform SQL before execution
+3. Control whether to proceed or short-circuit the chain
+4. Monitor performance and record metrics
+5. Handle failures and implement retry logic
+6. Acquire and release resources around execution
+7. Work seamlessly with other interceptors in a chain
+
+## Decision
+
+We will implement a **Request Lifecycle Interceptor Pattern** using:
+
+1. **Chain of Responsibility**: Interceptors form a chain, each can pass control to the next
+2. **Servlet Filter Model**: Inspired by `javax.servlet.Filter` API pattern
+3. **ServiceLoader Discovery**: External implementations loaded automatically via SPI
+4. **Phased Lifecycle**: Eight distinct phases where interceptors can hook
+5. **Priority-Based Ordering**: Interceptors execute in priority order (highest first)
+
+### Core Components
+
+#### 1. RequestInterceptor Interface (SPI)
+
+```java
+public interface RequestInterceptor {
+ String id();
+ int getPriority();
+ boolean isAvailable();
+ boolean supportsRequestType(RequestType requestType);
+ boolean supportsPhase(LifecyclePhase phase);
+ void intercept(RequestContext context, InterceptorChain chain) throws Exception;
+}
+```
+
+#### 2. Lifecycle Phases
+
+1. **PRE_REQUEST** - Session validation, cluster health, request enrichment
+2. **PRE_EXECUTION** - SQL hash, circuit breaker check, SQL transformation
+3. **RESOURCE_ACQUISITION** - Connection/slot acquisition
+4. **EXECUTION** - Actual database execution
+5. **POST_EXECUTION** - Result processing, metadata extraction
+6. **RESOURCE_RELEASE** - Connection/slot release, cleanup
+7. **POST_REQUEST** - Success/failure recording, metrics publishing
+8. **EXCEPTION_HANDLING** - Exception transformation, failure recording
+
+#### 3. RequestContext
+
+Mutable context object flowing through the chain containing:
+- Request type, SQL (original and current), session info
+- Connection, result, exception
+- Timing information, custom attributes
+- Short-circuit flag
+
+#### 4. InterceptorChain
+
+Manages chain execution with `proceed(context)` method, allowing interceptors to:
+- Execute logic before proceeding
+- Call `chain.proceed(context)` to continue
+- Execute logic after proceeding (in finally block)
+- Short-circuit by not calling proceed
+
+#### 5. RequestInterceptorRegistry
+
+Discovers interceptors via ServiceLoader, manages registration, provides filtering by request type and phase, sorts by priority.
+
+### Integration Approach
+
+#### Before (Current):
+
+```java
+public void executeUpdate(StatementRequest request, ...) {
+ circuitBreaker.preCheck(stmtHash); // Hard-coded
+ SlowQuerySegregationManager manager = getManager(connHash); // Hard-coded
+ OpResult result = manager.executeWithSegregation( // Hard-coded wrapper
+ stmtHash, () -> executeUpdateInternal(request)
+ );
+ circuitBreaker.onSuccess(stmtHash); // Hard-coded
+}
+```
+
+#### After (With Interceptors):
+
+```java
+public void executeUpdate(StatementRequest request, ...) {
+ RequestContext context = RequestContext.builder()
+ .requestType(RequestType.UPDATE)
+ .originalSql(request.getSql())
+ .build();
+
+ InterceptorChainExecutor.execute(context, ctx -> {
+ OpResult result = executeUpdateInternal(request, ctx);
+ ctx.setResult(result);
+ });
+}
+```
+
+All cross-cutting concerns move to interceptors, core code becomes cleaner.
+
+### Migration Strategy
+
+1. **Phase 1**: Implement interceptor infrastructure (no behavior change)
+2. **Phase 2**: Implement interceptor versions of existing features
+3. **Phase 3**: Run old and new code in parallel with feature flags
+4. **Phase 4**: Switch from old to new gradually
+5. **Phase 5**: Remove legacy implementations
+
+Full backward compatibility maintained during migration.
+
+## Consequences
+
+### Positive
+
+1. **Pluggable Architecture**: Features completely decoupled from core request handling
+2. **Third-Party Extensibility**: External providers can add interceptors via JAR in `ojp-libs`
+3. **Standardized Integration**: Single, well-defined pattern for all lifecycle hooks
+4. **Better Testability**: Each interceptor can be tested independently
+5. **Reduced Complexity**: `StatementServiceImpl` becomes much simpler (target < 1000 lines)
+6. **Composability**: Multiple interceptors work seamlessly together
+7. **Clear Lifecycle**: Eight distinct phases make integration points explicit
+8. **Familiar Pattern**: Servlet Filter model is well-understood by Java developers
+9. **Consistent with SPIs**: Follows established pattern used for ConnectionPoolProvider
+10. **No Recompilation**: Interceptors can be added/removed without rebuilding OJP
+
+### Negative
+
+1. **Implementation Complexity**: Chain management, phase coordination adds complexity
+2. **Performance Overhead**: Each interceptor adds small constant time overhead (~0.05ms)
+3. **Learning Curve**: Developers need to understand lifecycle phases and chain mechanics
+4. **Debugging Complexity**: Tracing through interceptor chain may be harder than direct calls
+5. **Migration Effort**: Existing features need to be refactored to interceptors
+6. **Documentation Burden**: Comprehensive docs needed for third-party developers
+
+### Mitigations
+
+1. **Clear Documentation**: Comprehensive guide with examples (`Understanding-OJP-Interceptors.md`)
+2. **Reference Implementations**: Built-in interceptors serve as examples
+3. **Performance Testing**: Benchmark overhead, ensure < 1% impact
+4. **Phased Migration**: Gradual rollout with feature flags
+5. **Helpful Logging**: Log interceptor chain execution at DEBUG level
+6. **Testing Support**: Provide test utilities for interceptor developers
+
+## Alternatives Considered
+
+### 1. Event-Driven Architecture
+
+**Approach**: Publish events at lifecycle points, interceptors subscribe via event bus
+
+**Pros**:
+- True decoupling
+- Asynchronous processing possible
+- Dynamic subscription/unsubscription
+
+**Cons**:
+- More complex infrastructure
+- Harder to maintain execution order
+- Difficult to handle exceptions consistently
+- Performance overhead from event dispatch
+- Harder to short-circuit request flow
+
+**Verdict**: **REJECTED** - Chain of Responsibility is simpler and more appropriate for synchronous request processing
+
+### 2. Aspect-Oriented Programming (AOP)
+
+**Approach**: Use AspectJ or Spring AOP to apply cross-cutting concerns
+
+**Pros**:
+- Clean separation via aspects
+- No code changes in core classes
+- Mature tooling
+
+**Cons**:
+- Requires AOP framework dependency (violates minimal dependencies principle)
+- Compile-time or load-time weaving complexity
+- Harder to debug (bytecode modification)
+- Less explicit control flow
+- Difficult for third-party providers to add aspects
+
+**Verdict**: **REJECTED** - SPI + Chain pattern is more explicit and doesn't require framework dependency
+
+### 3. Decorator Pattern
+
+**Approach**: Wrap `StatementServiceImpl` with decorator classes
+
+**Pros**:
+- Classic OOP pattern
+- Type-safe at compile time
+- Easy to understand
+
+**Cons**:
+- Requires compile-time composition
+- Not discoverable at runtime via ServiceLoader
+- Can't add decorators from external JARs easily
+- Each decorator needs to implement entire service interface
+
+**Verdict**: **REJECTED** - Not flexible enough for runtime discovery and third-party extensions
+
+### 4. Plugin Framework (OSGi, JPMs)
+
+**Approach**: Use heavyweight plugin framework
+
+**Pros**:
+- Full module isolation
+- Sophisticated dependency management
+- Hot-swapping capabilities
+
+**Cons**:
+- Too heavyweight for the use case
+- Adds significant complexity
+- Steep learning curve
+- Not consistent with OJP's lightweight approach
+
+**Verdict**: **REJECTED** - ServiceLoader provides sufficient modularity without the complexity
+
+### 5. Status Quo (Keep Current Approach)
+
+**Approach**: Continue hard-coding integrations into `StatementServiceImpl`
+
+**Pros**:
+- No implementation effort
+- No migration needed
+- Simple and direct
+
+**Cons**:
+- Cannot support third-party extensions
+- `StatementServiceImpl` continues to grow
+- Each feature integrates differently
+- Tight coupling persists
+
+**Verdict**: **REJECTED** - Does not meet extensibility requirements
+
+## Implementation Plan
+
+### Timeline (12 weeks)
+
+- **Week 1-2**: Core infrastructure (interfaces, registry, chain)
+- **Week 3-4**: Integration layer in `StatementServiceImpl`
+- **Week 5-6**: Migrate CircuitBreaker to interceptor
+- **Week 7**: Migrate SlowQuerySegregation to interceptor
+- **Week 8**: Migrate SqlEnhancer to interceptor
+- **Week 9-10**: Documentation, examples, testing
+- **Week 11**: Beta testing with community
+- **Week 12**: Final release
+
+### Success Criteria
+
+1. ✅ All existing features migrated to interceptors
+2. ✅ Performance overhead < 1% (measured via benchmarks)
+3. ✅ Third-party interceptors loadable from `ojp-libs`
+4. ✅ `StatementServiceImpl` reduced to < 1000 lines
+5. ✅ Complete documentation available
+6. ✅ At least one community-contributed example
+
+### New Module Structure
+
+```
+ojp-interceptor-api/
+ src/main/java/org/openjproxy/interceptor/
+ RequestInterceptor.java
+ RequestContext.java
+ InterceptorChain.java
+ RequestType.java
+ LifecyclePhase.java
+ DataSourceMetadata.java
+ RequestInterceptorRegistry.java
+```
+
+Built-in interceptors will reside in `ojp-server`:
+
+```
+ojp-server/
+ src/main/java/org/openjproxy/grpc/server/interceptor/
+ CircuitBreakerInterceptor.java
+ SlowQueryInterceptor.java
+ SqlEnhancerInterceptor.java
+```
+
+## Related Decisions
+
+- **ADR-006**: Adopt SPI Pattern for Extensibility - This decision extends the SPI philosophy to request lifecycle
+- **ADR-003**: Use HikariCP as Connection Pool - ConnectionPoolProvider SPI demonstrated ServiceLoader success
+- **STATEMENTSERVICE_ACTION_PATTERN_MIGRATION**: Refactoring StatementServiceImpl - Interceptors further simplify this class
+
+## References
+
+- [Request Lifecycle Interceptor Pattern - Full Design](../designs/REQUEST_LIFECYCLE_INTERCEPTOR_PATTERN.md)
+- [Understanding OJP SPIs](../Understanding-OJP-SPIs.md)
+- [Java ServiceLoader Documentation](https://docs.oracle.com/javase/8/docs/api/java/util/ServiceLoader.html)
+- [Servlet Filter Specification](https://jakarta.ee/specifications/servlet/5.0/jakarta-servlet-spec-5.0.html#filters)
+- [Chain of Responsibility Pattern](https://en.wikipedia.org/wiki/Chain-of-responsibility_pattern)
+
+## Appendix: Example Interceptor
+
+```java
+package com.example.ojp.interceptor;
+
+import org.openjproxy.interceptor.*;
+
+/**
+ * Example third-party query timeout interceptor.
+ * Demonstrates ServiceLoader-based integration.
+ */
+public class QueryTimeoutInterceptor implements RequestInterceptor {
+
+ private final long timeoutMs;
+
+ public QueryTimeoutInterceptor() {
+ this.timeoutMs = Long.parseLong(
+ System.getProperty("interceptor.timeout.ms", "30000")
+ );
+ }
+
+ @Override
+ public String id() {
+ return "query-timeout";
+ }
+
+ @Override
+ public int getPriority() {
+ return 100;
+ }
+
+ @Override
+ public boolean supportsRequestType(RequestType requestType) {
+ return requestType == RequestType.QUERY;
+ }
+
+ @Override
+ public boolean supportsPhase(LifecyclePhase phase) {
+ return phase == LifecyclePhase.EXECUTION;
+ }
+
+ @Override
+ public void intercept(RequestContext context, InterceptorChain chain)
+ throws Exception {
+ // Set query timeout on connection
+ context.getConnection().ifPresent(conn -> {
+ try {
+ Statement stmt = conn.createStatement();
+ stmt.setQueryTimeout((int) (timeoutMs / 1000));
+ } catch (SQLException e) {
+ log.warn("Failed to set query timeout", e);
+ }
+ });
+
+ chain.proceed(context);
+ }
+}
+```
+
+**META-INF/services/org.openjproxy.interceptor.RequestInterceptor**:
+```
+com.example.ojp.interceptor.QueryTimeoutInterceptor
+```
+
+Deploy by placing JAR in `ojp-libs/` directory. No OJP recompilation needed.
+
+---
+
+| Status | PROPOSED |
+|---------------|------------------|
+| Proposer(s) | OJP Architecture Team |
+| Proposal date | 2026-02-01 |
+| Approver(s) | Pending Review |
+| Approval date | Pending |
diff --git a/documents/analysis/REQUEST_LIFECYCLE_INTERCEPTOR_SUMMARY.md b/documents/analysis/REQUEST_LIFECYCLE_INTERCEPTOR_SUMMARY.md
new file mode 100644
index 000000000..c73d28e82
--- /dev/null
+++ b/documents/analysis/REQUEST_LIFECYCLE_INTERCEPTOR_SUMMARY.md
@@ -0,0 +1,360 @@
+# Request Lifecycle Interceptor Pattern - Executive Summary
+
+## Overview
+
+A new integration pattern for OJP that standardizes how libraries and modules interact with request lifecycle phases, inspired by Servlet Filters and implementing a Chain of Responsibility pattern with ServiceLoader-based discovery.
+
+## The Problem
+
+Currently, features like Circuit Breaker, Slow Query Segregation, and SQL Enhancement are **tightly coupled** to `StatementServiceImpl`:
+
+```java
+// Current approach - hard-coded integrations
+public void executeUpdate(StatementRequest request, ...) {
+ circuitBreaker.preCheck(stmtHash); // Hard-coded ❌
+ manager = getSlowQueryManager(connHash); // Hard-coded ❌
+ result = manager.executeWithSegregation(...); // Hard-coded wrapper ❌
+ circuitBreaker.onSuccess(stmtHash); // Hard-coded ❌
+}
+```
+
+**Issues:**
+- Can't add features without modifying core code
+- Each feature integrates differently
+- Third-party providers can't extend OJP
+- Testing is complex
+- `StatementServiceImpl` is 2,528 lines and growing
+
+## The Solution
+
+**Request Lifecycle Interceptor Pattern** - A standardized way to hook into request processing:
+
+```java
+// New approach - clean and extensible
+public void executeUpdate(StatementRequest request, ...) {
+ RequestContext context = RequestContext.builder()
+ .requestType(RequestType.UPDATE)
+ .originalSql(request.getSql())
+ .build();
+
+ // All cross-cutting concerns handled by interceptors
+ InterceptorChainExecutor.execute(context, ctx -> {
+ OpResult result = executeUpdateInternal(request, ctx);
+ ctx.setResult(result);
+ });
+}
+```
+
+## Key Concepts
+
+### 1. Eight Lifecycle Phases
+
+Interceptors can hook into any phase:
+
+1. **PRE_REQUEST** - Session validation, request enrichment
+2. **PRE_EXECUTION** - Circuit breaker, SQL transformation
+3. **RESOURCE_ACQUISITION** - Connection/slot acquisition
+4. **EXECUTION** - Database execution
+5. **POST_EXECUTION** - Result processing
+6. **RESOURCE_RELEASE** - Cleanup
+7. **POST_REQUEST** - Metrics, logging
+8. **EXCEPTION_HANDLING** - Error handling
+
+### 2. RequestInterceptor Interface
+
+```java
+public interface RequestInterceptor {
+ String id();
+ int getPriority(); // Higher = runs first
+ void intercept(RequestContext context, InterceptorChain chain) throws Exception;
+}
+```
+
+### 3. Chain of Responsibility
+
+Interceptors form a chain, each can:
+- Execute logic before proceeding
+- Call `chain.proceed(context)` to continue
+- Execute logic after (in try-finally)
+- Short-circuit by not calling proceed
+
+### 4. ServiceLoader Discovery
+
+Interceptors are discovered automatically:
+
+```
+META-INF/services/org.openjproxy.interceptor.RequestInterceptor
+com.example.MyInterceptor
+```
+
+Drop JAR in `ojp-libs/` → Interceptor loads automatically ✅
+
+## Example: Circuit Breaker Interceptor
+
+```java
+public class CircuitBreakerInterceptor implements RequestInterceptor {
+
+ @Override
+ public String id() {
+ return "circuit-breaker";
+ }
+
+ @Override
+ public int getPriority() {
+ return 300; // High priority
+ }
+
+ @Override
+ public boolean supportsPhase(LifecyclePhase phase) {
+ return phase == PRE_EXECUTION || phase == POST_REQUEST;
+ }
+
+ @Override
+ public void intercept(RequestContext context, InterceptorChain chain)
+ throws Exception {
+
+ if (context.getCurrentPhase() == PRE_EXECUTION) {
+ // Check before execution
+ circuitBreaker.preCheck(context.getSqlHash());
+ chain.proceed(context);
+
+ } else if (context.getCurrentPhase() == POST_REQUEST) {
+ // Record success/failure
+ if (context.getException().isPresent()) {
+ circuitBreaker.onFailure(context.getSqlHash(), ...);
+ } else {
+ circuitBreaker.onSuccess(context.getSqlHash());
+ }
+ chain.proceed(context);
+ }
+ }
+}
+```
+
+## Example: Third-Party Query Logging Interceptor
+
+```java
+package com.acme.ojp;
+
+public class QueryLoggerInterceptor implements RequestInterceptor {
+
+ @Override
+ public String id() {
+ return "acme-query-logger";
+ }
+
+ @Override
+ public int getPriority() {
+ return 50; // Low priority, runs late
+ }
+
+ @Override
+ public void intercept(RequestContext context, InterceptorChain chain)
+ throws Exception {
+
+ if (context.getCurrentPhase() == POST_REQUEST) {
+ long duration = context.getEndTimeMillis().orElse(0L)
+ - context.getStartTimeMillis();
+
+ logger.info("Query executed: sql={}, duration={}ms, success={}",
+ context.getOriginalSql(),
+ duration,
+ !context.getException().isPresent());
+ }
+
+ chain.proceed(context);
+ }
+}
+```
+
+**Deploy**: Just drop JAR in `ojp-libs/` - no OJP recompilation needed! 🚀
+
+## Benefits
+
+### For OJP Core
+- ✅ **Simpler code**: `StatementServiceImpl` reduces from 2,528 → <1,000 lines
+- ✅ **Better testability**: Each interceptor tested independently
+- ✅ **Easier maintenance**: Features don't touch core code
+- ✅ **Clear separation**: Business logic separate from cross-cutting concerns
+
+### For OJP Users
+- ✅ **Extensibility**: Add custom interceptors without modifying OJP
+- ✅ **Flexibility**: Enable/disable interceptors via configuration
+- ✅ **Composability**: Multiple interceptors work together seamlessly
+- ✅ **Familiar pattern**: Servlet Filter model is well-understood
+
+### For Third-Party Providers
+- ✅ **Easy integration**: Implement interface, drop in `ojp-libs/`
+- ✅ **No recompilation**: OJP doesn't need to be rebuilt
+- ✅ **Full control**: Access entire request lifecycle
+- ✅ **Rich context**: All request information available
+
+## Request Flow Example
+
+```
+Client Request
+ ↓
+┌────────────────────────────────────────────────┐
+│ PRE_REQUEST Phase │
+│ • Authentication Interceptor (priority: 1000) │
+│ • Rate Limiting Interceptor (priority: 900) │
+└────────────────────────────────────────────────┘
+ ↓
+┌────────────────────────────────────────────────┐
+│ PRE_EXECUTION Phase │
+│ • SQL Enhancer Interceptor (priority: 500) │
+│ [SQL: SELECT * FROM users] │
+│ [Enhanced: SELECT id, name FROM users] │
+│ • Circuit Breaker Interceptor (priority: 300) │
+│ [Checks if query is failing repeatedly] │
+└────────────────────────────────────────────────┘
+ ↓
+┌────────────────────────────────────────────────┐
+│ RESOURCE_ACQUISITION Phase │
+│ • Slow Query Interceptor (priority: 200) │
+│ [Acquires appropriate slot] │
+└────────────────────────────────────────────────┘
+ ↓
+┌────────────────────────────────────────────────┐
+│ EXECUTION Phase │
+│ • Core OJP Logic │
+│ [Actual database execution] │
+└────────────────────────────────────────────────┘
+ ↓
+┌────────────────────────────────────────────────┐
+│ POST_EXECUTION Phase │
+│ • Result Cache Interceptor (priority: 150) │
+│ [Caches result for future queries] │
+└────────────────────────────────────────────────┘
+ ↓
+┌────────────────────────────────────────────────┐
+│ RESOURCE_RELEASE Phase │
+│ • Slow Query Interceptor (priority: 200) │
+│ [Releases slot] │
+└────────────────────────────────────────────────┘
+ ↓
+┌────────────────────────────────────────────────┐
+│ POST_REQUEST Phase │
+│ • Metrics Interceptor (priority: 100) │
+│ [Records timing metrics] │
+│ • Circuit Breaker Interceptor (priority: 300) │
+│ [Records success] │
+│ • Query Logger Interceptor (priority: 50) │
+│ [Logs query execution] │
+└────────────────────────────────────────────────┘
+ ↓
+Response to Client
+```
+
+## Performance
+
+**Overhead Analysis:**
+- No interceptors: < 0.01ms
+- 3 interceptors (typical): 0.05-0.1ms
+- 10 interceptors: 0.2-0.3ms
+
+**Compared to typical query execution (10-1000ms): Negligible ✅**
+
+## Migration Path
+
+### Phase 1: Add Infrastructure
+- Implement interfaces
+- Add registry
+- **No behavior change**
+
+### Phase 2: Create Interceptors
+- CircuitBreakerInterceptor
+- SlowQueryInterceptor
+- SqlEnhancerInterceptor
+
+### Phase 3: Parallel Execution
+- Run old and new code together
+- Feature flags control which is active
+
+### Phase 4: Switch Over
+- Gradually enable interceptors
+- Disable legacy code
+
+### Phase 5: Cleanup
+- Remove old implementations
+- **Fully migrated ✅**
+
+## Configuration
+
+```properties
+# Enable interceptor system
+interceptor.enabled=true
+
+# Circuit Breaker
+interceptor.circuit-breaker.enabled=true
+interceptor.circuit-breaker.priority=300
+interceptor.circuit-breaker.failure-threshold=3
+
+# Slow Query
+interceptor.slow-query.enabled=true
+interceptor.slow-query.priority=200
+
+# SQL Enhancer
+interceptor.sql-enhancer.enabled=true
+interceptor.sql-enhancer.priority=500
+```
+
+## Success Criteria
+
+1. ✅ All existing features migrated to interceptors
+2. ✅ Performance overhead < 1%
+3. ✅ Third-party interceptors loadable from `ojp-libs`
+4. ✅ `StatementServiceImpl` < 1,000 lines
+5. ✅ Complete documentation available
+6. ✅ Community-contributed example exists
+
+## Timeline
+
+- **Week 1-2**: Core infrastructure
+- **Week 3-4**: Integration layer
+- **Week 5-8**: Migrate existing features
+- **Week 9-10**: Documentation & examples
+- **Week 11-12**: Testing & release
+
+## Comparison with Servlet Filters
+
+| Aspect | Servlet Filter | OJP Interceptor |
+|--------|---------------|-----------------|
+| Pattern | Chain of Responsibility | Chain of Responsibility |
+| Discovery | web.xml or @WebFilter | ServiceLoader |
+| Method | `doFilter(request, response, chain)` | `intercept(context, chain)` |
+| Proceed | `chain.doFilter(request, response)` | `chain.proceed(context)` |
+| Context | ServletRequest/Response | RequestContext |
+| Phases | Single (filter) | Eight (lifecycle) |
+
+**Key Insight**: OJP interceptors are like Servlet Filters, but with **multiple lifecycle phases** for finer-grained control.
+
+## Related Documents
+
+- 📄 [Full Design Document](REQUEST_LIFECYCLE_INTERCEPTOR_PATTERN.md) - Complete technical specification
+- 📄 [ADR-008](../ADRs/adr-008-request-lifecycle-interceptor-pattern.md) - Architectural decision record
+- 📄 [Understanding OJP SPIs](../Understanding-OJP-SPIs.md) - Existing SPI documentation
+
+## Questions?
+
+**Q: Will this break existing code?**
+A: No, fully backward compatible during migration.
+
+**Q: What's the performance impact?**
+A: < 1% overhead, negligible compared to database execution time.
+
+**Q: Can I add my own interceptor?**
+A: Yes! Implement `RequestInterceptor`, add to JAR, drop in `ojp-libs/`.
+
+**Q: How is this different from events?**
+A: Chain pattern is synchronous, ordered, and can short-circuit. Better for request processing.
+
+**Q: Do I need to rebuild OJP?**
+A: No, interceptors are loaded dynamically via ServiceLoader.
+
+---
+
+**Status**: DRAFT - PENDING REVIEW
+**Version**: 1.0
+**Date**: 2026-02-01
+**Contact**: OJP Architecture Team
diff --git a/documents/designs/REQUEST_LIFECYCLE_INTERCEPTOR_PATTERN.md b/documents/designs/REQUEST_LIFECYCLE_INTERCEPTOR_PATTERN.md
new file mode 100644
index 000000000..15ec663d3
--- /dev/null
+++ b/documents/designs/REQUEST_LIFECYCLE_INTERCEPTOR_PATTERN.md
@@ -0,0 +1,1412 @@
+# Request Lifecycle Interceptor Pattern for OJP
+
+## Executive Summary
+
+This document analyzes a new integration pattern for OJP that standardizes how libraries and modules interact with the request lifecycle. The pattern is inspired by Servlet Filters and implements a Chain of Responsibility approach, allowing external providers to create interceptors that can be loaded via ServiceLoader.
+
+## Current State Analysis
+
+### Existing Integration Points
+
+Currently, OJP has three main libraries/modules that integrate directly with the request execution flow:
+
+1. **CircuitBreaker** - Integrated directly in `StatementServiceImpl`
+ - Called at: pre-execution (`preCheck`), post-success (`onSuccess`), post-failure (`onFailure`)
+ - Current integration: Hard-coded method calls in `executeQuery()` and `executeUpdate()`
+
+2. **SlowQuerySegregationManager** - Integrated directly in `StatementServiceImpl`
+ - Called at: wraps the entire execution with `executeWithSegregation()`
+ - Current integration: Hard-coded wrapper around query/update execution
+ - Per-datasource instances managed in a `ConcurrentHashMap`
+
+3. **SqlEnhancerEngine** (Apache Calcite) - Integrated directly in query execution
+ - Called at: pre-execution phase (SQL transformation)
+ - Current integration: Direct method call in `executeQueryInternal()`
+ - Enabled/disabled via configuration flag
+
+### Current Request Lifecycle Flow
+
+```
+executeQuery/executeUpdate (public API)
+ ↓
+1. updateSessionActivity()
+2. hashSqlQuery()
+3. processClusterHealth()
+4. circuitBreaker.preCheck() ← Integration Point 1
+5. getSlowQuerySegregationManager()
+6. manager.executeWithSegregation() ← Integration Point 2
+ ↓
+ executeQueryInternal/executeUpdateInternal
+ ↓
+ 7. sessionConnection()
+ 8. sqlEnhancerEngine.enhance() ← Integration Point 3
+ 9. Statement creation & execution
+ 10. Result processing
+ ↓
+11. circuitBreaker.onSuccess() ← Integration Point 4
+ OR
+ circuitBreaker.onFailure() ← Integration Point 5
+```
+
+### Existing SPI Pattern
+
+OJP already uses the ServiceLoader pattern successfully for:
+
+- **ConnectionPoolProvider** - Standard connection pools (HikariCP, DBCP)
+- **XAConnectionPoolProvider** - XA transaction pools
+- **JDBC Drivers** - Database drivers loaded from `ojp-libs` directory
+
+This demonstrates OJP's commitment to extensibility and provides a proven pattern to follow.
+
+## Problem Statement
+
+### Current Limitations
+
+1. **Tight Coupling**: Features like CircuitBreaker, SlowQuerySegregation, and SqlEnhancer are directly coupled to `StatementServiceImpl`
+2. **Hard to Extend**: Adding new features requires modifying core classes
+3. **No Standardization**: Each feature integrates differently (method calls, wrappers, flags)
+4. **No Third-Party Support**: External providers cannot add their own lifecycle hooks
+5. **Testing Complexity**: Difficult to test features in isolation
+6. **Maintenance Burden**: `StatementServiceImpl` is already a 2,528-line class
+
+### Desired Capabilities
+
+External providers should be able to:
+
+1. **Intercept Requests**: Hook into various phases of request processing
+2. **Transform SQL**: Modify SQL before execution (like Calcite does)
+3. **Control Execution**: Decide whether to proceed or short-circuit
+4. **Monitor Performance**: Track timing and metrics
+5. **Handle Failures**: React to exceptions and implement retry logic
+6. **Manage Resources**: Acquire/release resources around execution
+7. **Chain Together**: Multiple interceptors working in sequence
+
+## Proposed Solution: Request Lifecycle Interceptor Pattern
+
+### Design Principles
+
+1. **Chain of Responsibility**: Interceptors form a chain, each can pass control to the next
+2. **Servlet Filter Model**: Inspired by the well-understood `javax.servlet.Filter` pattern
+3. **ServiceLoader Discovery**: External implementations loaded automatically
+4. **Backward Compatible**: Existing features can be migrated gradually
+5. **Minimal Overhead**: Negligible performance impact when interceptors are not present
+
+### Request Lifecycle Phases
+
+The request lifecycle is divided into distinct phases where interceptors can hook:
+
+```
+┌─────────────────────────────────────────────────────────────┐
+│ REQUEST RECEIVED │
+└──────────────────────┬──────────────────────────────────────┘
+ │
+ ▼
+┌─────────────────────────────────────────────────────────────┐
+│ Phase 1: PRE_REQUEST │
+│ - Session validation │
+│ - Cluster health processing │
+│ - Request enrichment │
+│ Examples: Authentication, Rate Limiting, Logging │
+└──────────────────────┬──────────────────────────────────────┘
+ │
+ ▼
+┌─────────────────────────────────────────────────────────────┐
+│ Phase 2: PRE_EXECUTION │
+│ - SQL hash generation │
+│ - Circuit breaker pre-check │
+│ - SQL transformation/optimization │
+│ Examples: Circuit Breaker, SQL Rewriting, Query Validation │
+└──────────────────────┬──────────────────────────────────────┘
+ │
+ ▼
+┌─────────────────────────────────────────────────────────────┐
+│ Phase 3: RESOURCE_ACQUISITION │
+│ - Slow query slot acquisition │
+│ - Connection acquisition │
+│ - Transaction management │
+│ Examples: Slow Query Segregation, Connection Pooling │
+└──────────────────────┬──────────────────────────────────────┘
+ │
+ ▼
+┌─────────────────────────────────────────────────────────────┐
+│ Phase 4: EXECUTION │
+│ - Statement preparation │
+│ - Parameter binding │
+│ - Actual database execution │
+│ Examples: Query Execution Monitoring, Execution Tracing │
+└──────────────────────┬──────────────────────────────────────┘
+ │
+ ▼
+┌─────────────────────────────────────────────────────────────┐
+│ Phase 5: POST_EXECUTION │
+│ - Result processing │
+│ - Metadata extraction │
+│ - Performance recording │
+│ Examples: Result Caching, Performance Metrics │
+└──────────────────────┬──────────────────────────────────────┘
+ │
+ ▼
+┌─────────────────────────────────────────────────────────────┐
+│ Phase 6: RESOURCE_RELEASE │
+│ - Connection release │
+│ - Slot release │
+│ - Cleanup │
+│ Examples: Resource Tracking, Leak Detection │
+└──────────────────────┬──────────────────────────────────────┘
+ │
+ ▼
+┌─────────────────────────────────────────────────────────────┐
+│ Phase 7: POST_REQUEST │
+│ - Success/failure recording │
+│ - Metrics publishing │
+│ - Logging │
+│ Examples: Audit Logging, Circuit Breaker State Update │
+└──────────────────────┬──────────────────────────────────────┘
+ │
+ ▼
+┌─────────────────────────────────────────────────────────────┐
+│ RESPONSE SENT │
+└─────────────────────────────────────────────────────────────┘
+
+Exception Flow:
+┌─────────────────────────────────────────────────────────────┐
+│ Phase X: EXCEPTION_HANDLING │
+│ - Exception transformation │
+│ - Failure recording │
+│ - Recovery attempts │
+│ Examples: Circuit Breaker Failure Recording, Retry Logic │
+└─────────────────────────────────────────────────────────────┘
+```
+
+## Interface Design
+
+### Core Interfaces
+
+#### 1. RequestInterceptor - Main Interceptor Interface
+
+```java
+package org.openjproxy.interceptor;
+
+/**
+ * Service Provider Interface (SPI) for request lifecycle interceptors.
+ *
+ *
Interceptors can hook into various phases of request processing to provide
+ * cross-cutting concerns like monitoring, transformation, circuit breaking,
+ * and resource management. This pattern is inspired by Servlet Filters and
+ * implements a Chain of Responsibility approach.
+ *
+ *
Implementations should be registered via the standard Java
+ * {@link java.util.ServiceLoader} mechanism by creating a file named
+ * {@code META-INF/services/org.openjproxy.interceptor.RequestInterceptor}
+ * containing the fully qualified class name of the implementation.
+ *
+ *
Interceptors are invoked in priority order (highest first) and can:
+ *
+ *
Inspect and modify the request context
+ *
Short-circuit the chain by not calling chain.proceed()
+ *
Wrap the execution with try-catch-finally logic
+ *
Transform SQL or results
+ *
Acquire and release resources
+ *
Record metrics and handle errors
+ *
+ *
+ * @see RequestContext
+ * @see InterceptorChain
+ */
+public interface RequestInterceptor {
+
+ /**
+ * Returns the unique identifier for this interceptor.
+ *
+ * @return the interceptor ID, never null or empty
+ */
+ String id();
+
+ /**
+ * Returns the priority of this interceptor for ordering.
+ * Higher values indicate higher priority (executed first).
+ *
+ *
+ *
+ * @return the interceptor priority (default: 0)
+ */
+ default int getPriority() {
+ return 0;
+ }
+
+ /**
+ * Checks if this interceptor is available and should be used.
+ *
+ * @return true if available, false otherwise
+ */
+ default boolean isAvailable() {
+ return true;
+ }
+
+ /**
+ * Checks if this interceptor supports the given request type.
+ *
+ * @param requestType the type of request (QUERY, UPDATE, TRANSACTION, etc.)
+ * @return true if this interceptor should handle this request type
+ */
+ default boolean supportsRequestType(RequestType requestType) {
+ return true; // By default, support all types
+ }
+
+ /**
+ * Checks if this interceptor should run for the given lifecycle phase.
+ *
+ * @param phase the lifecycle phase
+ * @return true if this interceptor should run in this phase
+ */
+ default boolean supportsPhase(LifecyclePhase phase) {
+ return true; // By default, support all phases
+ }
+
+ /**
+ * Intercepts the request processing at various lifecycle phases.
+ *
+ *
Implementations must call {@code chain.proceed(context)} to continue
+ * the chain, or can choose to short-circuit by not calling it.
+ *
+ * @param context the request context containing all request information
+ * @param chain the interceptor chain to continue processing
+ * @throws Exception if an error occurs during interception
+ */
+ void intercept(RequestContext context, InterceptorChain chain) throws Exception;
+}
+```
+
+#### 2. RequestContext - Contextual Information
+
+```java
+package org.openjproxy.interceptor;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.util.Map;
+import java.util.Optional;
+
+/**
+ * Context object that flows through the interceptor chain, containing all
+ * information about the current request and its execution state.
+ *
+ *
The context is mutable and can be modified by interceptors. Changes
+ * made to the context will be visible to subsequent interceptors in the chain.
+ */
+public interface RequestContext {
+
+ /**
+ * Returns the type of request being processed.
+ */
+ RequestType getRequestType();
+
+ /**
+ * Returns the current lifecycle phase.
+ */
+ LifecyclePhase getCurrentPhase();
+
+ /**
+ * Returns the original SQL statement.
+ */
+ String getOriginalSql();
+
+ /**
+ * Returns the current SQL statement (may have been transformed by interceptors).
+ */
+ String getCurrentSql();
+
+ /**
+ * Sets the SQL statement (allows transformation).
+ */
+ void setCurrentSql(String sql);
+
+ /**
+ * Returns the SQL statement hash for tracking.
+ */
+ String getSqlHash();
+
+ /**
+ * Returns the session information.
+ */
+ SessionInfo getSessionInfo();
+
+ /**
+ * Returns the connection hash identifying the datasource.
+ */
+ String getConnectionHash();
+
+ /**
+ * Returns request parameters (if applicable).
+ */
+ Optional