Integration Points
Module: Lens Version: 1.0.0-RELEASE Last Updated: October 25, 2025
Overview​
Lens integrates with 8 external systems:
- Snowflake (primary analytics database)
- MongoDB (document storage)
- MySQL (transactional data)
- Redis (caching layer)
- RabbitMQ (message queue)
- AWS SDK (Cost Explorer, Pricing APIs)
- Spring Cloud Config Server (configuration)
- authX Module (JWT authentication)
1. Snowflake Integration​
Purpose: Query massive cost and usage data
Connection:
snowflake.url=jdbc:snowflake://account.snowflakecomputing.com
snowflake.warehouse=LENS_WH
snowflake.database=COST_DB
snowflake.schema=CUSTOMER_{customerId} # Multi-tenant
Usage Pattern:
// Query cost data
String sql = "SELECT SERVICE, SUM(COST) FROM COST_DAILY WHERE ACCOUNT_ID = ? GROUP BY SERVICE";
`List<CostDTO>` costs = snowflakeJdbcTemplate.query(sql, rowMapper, accountId);
Performance Optimizations:
- Clustering: Tables clustered by DATE
- Result Cache: 24-hour cache for identical queries
- Auto-suspend: Warehouse auto-suspends after 60 seconds idle
- Connection Pool: HikariCP with max 20 connections
2. MongoDB Integration​
Purpose: Store flexible documents (saved reports, filters)
Connection:
spring:
data:
mongodb:
uri: mongodb://${MONGODB_HOST}:27017/lens
database: lens
Usage Pattern:
// Save report
SavedReportDocument report = new SavedReportDocument();
report.setCustomerId(customerId);
report.setReportName("Monthly EC2 Costs");
savedReportRepository.save(report);
// Query reports
`List<SavedReportDocument>` reports =
savedReportRepository.findByCustomerId(customerId);
Collections:
saved_reports- User-saved report configurationsfilter_metadata- Filter dropdown values (cached)custom_queries- User-defined custom SQL queries
3. MySQL Integration​
Purpose: Transactional data (users, accounts, billing metadata)
Connection:
spring.datasource.url=jdbc:mysql://${MYSQL_HOST}:3306/lens
spring.datasource.hikari.maximum-pool-size=20
Usage Pattern:
// JPA repository
@Repository
public interface AccountRepository extends JpaRepository<Account, String> {
`List<Account>` findByCustomerId(String customerId);
}
// Usage
`List<Account>` accounts = accountRepository.findByCustomerId(customerId);
4. Redis Integration​
Purpose: High-speed caching for frequently accessed data
Connection:
spring:
redis:
host: ${REDIS_HOST}
port: 6379
lettuce:
pool:
max-active: 8
Usage Pattern:
@Cacheable(value = "dashboardQueries", key = "#customerId + ':' + #dateRange", ttl = 900)
public DashboardDTO getDashboardData(String customerId, String dateRange) {
return dao.queryDashboard(customerId, dateRange);
}
Cache Configurations:
dashboardQueries: 15-minute TTLfilterMetadata: 1-hour TTLriUtilization: 1-hour TTL
5. RabbitMQ Integration​
Purpose: Asynchronous event processing
Connection:
spring:
rabbitmq:
host: ${RABBITMQ_HOST}
port: 5672
virtual-host: /lens
Exchanges & Queues:
// Exchange declaration
@Bean
public TopicExchange lensEventsExchange() {
return new TopicExchange("lens.events");
}
// Queue declaration
@Bean
public Queue costUpdateQueue() {
return new Queue("lens.cost.update");
}
// Binding
@Bean
public Binding costUpdateBinding() {
return BindingBuilder.bind(costUpdateQueue())
.to(lensEventsExchange())
.with("cost.update.*");
}
Message Publishing:
rabbitTemplate.convertAndSend("lens.events", "cost.update.CUST-123", costUpdateEvent);
Message Consumption:
@RabbitListener(queues = "lens.cost.update")
public void handleCostUpdate(CostUpdateEvent event) {
// Invalidate cache
cacheManager.getCache("dashboardQueries").clear();
}
6. AWS SDK Integration​
Purpose: Fetch recommendations, pricing data
Services Used:
- AWS Cost Explorer API
- AWS Pricing API
- AWS Organizations API
Configuration:
@Bean
public AmazonCostExplorer costExplorerClient() {
return AmazonCostExplorerClientBuilder.standard()
.withRegion(Regions.US_EAST_1)
.withCredentials(new DefaultAWSCredentialsProviderChain())
.build();
}
Usage - Get RI Recommendations:
GetReservationPurchaseRecommendationRequest request =
new GetReservationPurchaseRecommendationRequest()
.withService("Amazon Elastic Compute Cloud - Compute")
.withLookbackPeriodInDays("THIRTY_DAYS");
GetReservationPurchaseRecommendationResult result =
costExplorerClient.getReservationPurchaseRecommendation(request);
Rate Limiting: 5 req/sec (AWS limit), exponential backoff on throttling
7. Spring Cloud Config Server​
Purpose: Externalized configuration
Bootstrap Configuration:
spring:
cloud:
config:
uri: http://cloudonomic-spring-config.uat.cloudonomic.net
name: lens
label: prod
fail-fast: true
Fetched Properties:
- Database credentials
- AWS credentials (if not using IAM roles)
- Feature flags
- Cache TTLs
- External service URLs
Refresh:
# Trigger config refresh without restart
curl -X POST http://localhost:8080/actuator/refresh
8. authX Module (JWT Authentication)​
Purpose: Authenticate and authorize API requests
Integration:
@Secured(key = "LENS_AWSVSACTUALCOSTCONTROLLER")
public class AwsVsActualCostController {
// All endpoints require valid JWT with specific permission
}
JWT Validation Flow:
- Client sends JWT in
Authorization: Bearer <token>header - authX interceptor validates JWT signature
- authX extracts customer ID and permissions from JWT
- authX checks user has required permission key
- Request proceeds or 403 Forbidden returned
Integration Dependencies​
Gradle dependencies:
// Internal modules
api project(":snowplug") // Snowflake integration
api project(":monitoring") // Prometheus metrics
api project(":errorhandler") // Exception handling
api project(":loggerutil") // Structured logging
// External integrations
implementation 'net.snowflake:snowflake-jdbc:3.13.27'
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation 'org.springframework.boot:spring-boot-starter-amqp'
implementation 'com.amazonaws:aws-java-sdk:1.12.324'
Error Handling & Resilience​
Retry Strategy​
@Retryable(
value = {SnowflakeConnectionException.class},
maxAttempts = 3,
backoff = @Backoff(delay = 1000, multiplier = 2)
)
public `List<CostDTO>` queryCosts(RequestDTO request) {
return snowflakeDao.query(request);
}
Circuit Breaker (Optional)​
@CircuitBreaker(name = "snowflake", fallbackMethod = "fallbackGetCosts")
public `List<CostDTO>` getCosts(RequestDTO request) {
return dao.queryCosts(request);
}
public `List<CostDTO>` fallbackGetCosts(RequestDTO request, Throwable ex) {
return cacheService.getCachedCosts(request); // Return stale data
}
Summary​
8 External Integrations: Snowflake, MongoDB, MySQL, Redis, RabbitMQ, AWS SDK, Config Server, authX
Connection Pooling: HikariCP for databases (max 20 connections)
Resilience: Retry logic (3 attempts, exponential backoff)
Caching: Redis with configurable TTLs (15min - 1hour)
Messaging: RabbitMQ topic exchange with event-driven architecture
Authentication: JWT via authX module
Document Version: 1.0 Last Updated: October 25, 2025