Logical Architecture
Module: Lens Platform: Stormus Version: 1.0.0-RELEASE Last Updated: October 25, 2025 Document Type: Logical Architecture (Component View)
Table of Contentsβ
- Introduction
- Architectural Layers
- Component Diagram
- Package Structure
- Layer Responsibilities
- Communication Patterns
- Design Patterns
- Module Dependencies
- Cross-Cutting Concerns
Introductionβ
This document describes the logical architecture of the AWS Lens module, focusing on the structural organization of components, layers, and design patterns. It provides a developer's view of how the system is organized internally.
Purpose of This Documentβ
- Define architectural layers and their responsibilities
- Document component structure and relationships
- Explain design patterns and principles
- Guide developers on where to add new features
- Ensure architectural consistency
Architectural Styleβ
Lens follows a Layered Architecture pattern with clear separation of concerns:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Presentation Layer (Controllers) β
β 40 REST Controllers β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Application Layer (Services) β
β 107 Service Classes β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Data Access Layer (DAOs & Repositories) β
β 47 DAO Classes + JPA Repos β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Data Transfer Layer (DTOs & Documents) β
β 165 DTOs + MongoDB Documents β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Infrastructure Layer (Config, Utils) β
β Configuration + Utilities + Cross-Cutting β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Related Documentsβ
- 02-functional-architecture - Business capabilities and use cases
- 04-technical-architecture - Technology stack and integrations
- 05-component-design - Detailed component documentation
Architectural Layersβ
Layer 1: Presentation Layer (Controllers)β
Responsibility: HTTP request handling, input validation, response formatting
Components: 40 REST Controllers
Package: com.ttn.ck.lens.controller
Key Characteristics:
- Stateless: Controllers do not maintain state
- Thin: Minimal business logic, delegate to service layer
- RESTful: Follow REST API conventions
- Secured: All endpoints annotated with
@Secured - Validated: Input validation via
@ValidandBindingResult
Controller Categories:
- Core Controllers (14): Base cost management endpoints
- Alert Controllers (5): Located in
controller/alertsapi - Cost Breakup Controllers (13): Located in
controller/costbreakup - CUDOS Controllers (3): Located in
controller/cudos - FinOps Controllers (1): Located in
controller/finops - Marketplace Controllers (1): Located in
controller/marketplace - Monthly Report Controllers (2): Located in
controller/monthlyreport
Responsibilities:
- Receive HTTP requests
- Validate input using
@Validannotations - Call appropriate service methods
- Wrap responses in
ResponseDto(success/error) - Handle HTTP status codes
- Return JSON responses
Not Responsible For:
- Business logic execution
- Database queries
- External API calls
- Complex calculations
Layer 2: Application Layer (Services)β
Responsibility: Business logic, orchestration, transaction management
Components: 107 Service Classes (interfaces + implementations)
Package: com.ttn.ck.lens.service (interfaces), com.ttn.ck.lens.service.impl (implementations)
Key Characteristics:
- Interface-based: Services defined as interfaces, implementations separate
- Transactional: Use
@Transactionalwhere needed - Orchestration: Coordinate multiple DAOs and external services
- Business Rules: Implement all business logic
- Testable: Easy to mock for unit testing
Service Categories:
- Core Services: AwsVsActualCostService, BillingConsoleService, etc.
- Cost Breakup Services: 12 categories (Analytics, Containers, Database, etc.)
- CUDOS Services: S3Dashboard, DataTransferDashboard, DatabaseDashboard
- Utility Services: DatesService, RecommendationService, etc.
Subpackage Structure:
service/
βββ (interfaces) # Service interfaces
βββ impl/ # Core implementations
β βββ billingsummary/ # Billing summary services
β βββ costbreakup/ # Cost breakup services
β βββ analytics/
β βββ containers/
β βββ database/
β βββ datatransfer/
β βββ instance/
β βββ managementandgovernance/
β βββ media/
β βββ migrationandtransfer/
β βββ networkingandcontent/
β βββ security/
β βββ serverless/
β βββ storage/
Responsibilities:
- Execute business logic
- Validate business rules
- Aggregate data from multiple DAOs
- Transform DTOs
- Call external APIs (AWS SDK, Feign clients)
- Cache results (when appropriate)
- Handle exceptions and retries
Not Responsible For:
- HTTP request/response handling
- SQL query construction
- Direct database access
- UI concerns
Layer 3: Data Access Layer (DAOs & Repositories)β
Responsibility: Database queries, data persistence, external data sources
Components: 47 DAO Classes + JPA Repositories
Packages:
com.ttn.ck.lens.dao(interfaces)com.ttn.ck.lens.dao.impl(implementations)com.ttn.ck.lens.repo(JPA repositories)com.ttn.ck.lens.queries(SQL query classes)
Key Characteristics:
- Data Source Abstraction: Hide database implementation details
- Query Optimization: Efficient SQL queries
- Multi-Database: Support Snowflake, MongoDB, MySQL
- Result Mapping: Map database rows to DTOs
DAO Categories:
- Snowflake DAOs: Cost data queries (primary data source)
- MongoDB Repositories: Document storage (saved reports, filters)
- JPA Repositories: Transactional data (MySQL)
Subpackage Structure:
dao/
βββ (interfaces) # DAO interfaces
βββ impl/ # Snowflake DAO implementations
βββ cudos/ # CUDOS-specific DAOs
βββ marketplace/ # Marketplace DAOs
repo/ # JPA & Mongo repositories
queries/ # SQL query classes
βββ costbreakup/
βββ cudos/
βββ marketplace/
Responsibilities:
- Execute Snowflake SQL queries
- Map result sets to DTOs
- Handle database connections
- Query optimization
- Pagination
- Caching query results
Not Responsible For:
- Business logic
- Data transformation (beyond mapping)
- HTTP handling
Layer 4: Data Transfer Layer (DTOs & Documents)β
Responsibility: Data structures for transferring data between layers
Components: 165 DTOs + MongoDB Documents
Packages:
com.ttn.ck.lens.dto(Data Transfer Objects for API)com.ttn.ck.lens.document(MongoDB documents)
Key Characteristics:
- Immutability: DTOs should be immutable (use
@Datafor Lombok) - Validation Annotations: Use JSR-303 annotations (
@NotNull,@Size, etc.) - Serializable: Support JSON serialization
- Flat Structure: Avoid deep nesting
DTO Categories:
dto/
βββ AwsVsActualCost/ # Cost comparison DTOs
βββ accountwisebreakup/ # Account breakup DTOs
βββ billingconsole/ # Billing console DTOs
βββ billingsummary/ # Billing summary DTOs
βββ costalert/ # Cost alert DTOs
βββ costbreakup/ # Cost breakup DTOs (12 categories)
βββ costexplorer/ # Cost explorer DTOs
βββ costtrends/ # Cost trends DTOs
βββ cudos/ # CUDOS dashboard DTOs
βββ recommendation/ # Recommendation DTOs
βββ reservation/ # Reservation DTOs
βββ ricoverage/ # RI coverage DTOs
βββ riexpiry/ # RI expiry DTOs
βββ GenericRequestDTO.java # Common request DTO
Responsibilities:
- Define data contracts between layers
- Input validation (request DTOs)
- Response formatting (response DTOs)
- JSON serialization/deserialization
- Field-level validation
Not Responsible For:
- Business logic
- Database operations
- HTTP handling
Layer 5: Infrastructure Layer (Config, Utils, Cross-Cutting)β
Responsibility: Configuration, utilities, cross-cutting concerns
Components: Configuration classes, utilities, caching, listeners
Packages:
com.ttn.ck.lens.config(Configuration classes)com.ttn.ck.lens.utils(Utility classes)com.ttn.ck.lens.cache(Caching logic)com.ttn.ck.lens.listner(Event listeners)com.ttn.ck.lens.enums(Enumerations)com.ttn.ck.lens.clients(External service clients - Feign)
Key Characteristics:
- Reusable: Used across all layers
- Stateless: Most utilities are stateless
- Configuration: Externalized via Spring Cloud Config
Subpackages:
config/ # Spring configuration
βββ SnowflakeConfig.java
βββ MongoConfig.java
βββ RedisConfig.java
βββ RabbitMQConfig.java
utils/ # Utility classes
βββ ApplicationConstants.java # 660+ constants
βββ ApplicationUtils.java # Common utilities
βββ ColumnNameConstants.java # Database column names
βββ QueueConstants.java # RabbitMQ constants
βββ SortUtils.java # Sorting utilities
βββ AccountWiseBreakUpReportGenerator.java
cache/ # Caching logic
βββ CacheConfiguration.java
listner/ # Event listeners
βββ MessageQueueListener.java # RabbitMQ consumer
clients/ # Feign clients
βββ AwsRecommendationClient.java # AWS Cost Explorer API
enums/ # Enumerations
βββ costbreakup/
βββ cudos/
Responsibilities:
- Application configuration
- Common utilities (date, string, sorting)
- Constants management
- Caching configuration
- Event processing (RabbitMQ listeners)
- External API clients (Feign)
Not Responsible For:
- Business logic
- Direct database access
Component Diagramβ
High-Level Component Viewβ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β LENS MODULE β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β PRESENTATION LAYER (Controllers) β β
β β β β
β β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β β
β β β Core β β Alerts β β CostBreakup β β β
β β β Controllers β β Controllers β β Controllers β β β
β β β (14) β β (5) β β (13) β β β
β β ββββββββ¬ββββββββ ββββββββ¬ββββββββ ββββββββ¬ββββββββ β β
β β β β β β β
β βββββββββββΌβββββββββββββββββββΌβββββββββββββββββββΌββββββββββββββ β
β β β β β
β ββββββββββββββββββββ΄βββββββββββββββββββ β
β β β
β ββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββ β
β β APPLICATION LAYER (Services) β β β
β β βΌ β β
β β βββββββββββββββ ββββββββββββββββ βββββββββββββββββββββββ β
β β β Core β β CostBreakup β β CUDOS Services ββ β
β β β Services β β Services β β ββ β
β β β (20) β β (60+) β β (3) ββ β
β β βββββββ¬ββββββββ ββββββββ¬ββββββββ ββββββββββ¬βββββββββββββ β
β β β β β β β
β ββββββββββΌβββββββββββββββββββΌβββββββββββββββββββββΌβββββββββββββ β
β β β β β
β ββββββββββββββββββββ΄βββββββββββββββββββββ β
β β β
β βββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββ β
β β DATA ACCESS LAYER (DAOs & Repositories) β β β
β β βΌ β β
β β βββββββββββββββββ ββββββββββββββββββ ββββββββββββββββββ β β
β β β Snowflake β β MongoDB β β JPA Repos β β β
β β β DAOs β β Repositories β β (MySQL) β β β
β β β (35+) β β (5) β β (7) β β β
β β βββββββββ¬ββββββββ ββββββββββ¬ββββββββ ββββββββββ¬ββββββββ β β
β β β β β β β
β ββββββββββββΌβββββββββββββββββββββΌβββββββββββββββββββββΌββββββββββ β
β β β β β
β βΌ βΌ βΌ β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β DATA SOURCES ββ
β β ββββββββββββ ββββββββββββ ββββββββββββ ββββββββββ ββ
β β βSnowflake β β MongoDB β β MySQL β β Redis β ββ
β β βAnalytics β βDocuments β βTransactionβ β Cache β ββ
β β ββββββββββββ ββββββββββββ ββββββββββββ ββββββββββ ββ
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β EXTERNAL INTEGRATIONS ββ
β β ββββββββββββ ββββββββββββ ββββββββββββ ββββββββββ ββ
β β β AWS SDK β β RabbitMQ β β Config β β AuthX β ββ
β β β(Feign) β β (AMQP) β β Server β β (JWT) β ββ
β β ββββββββββββ ββββββββββββ ββββββββββββ ββββββββββ ββ
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Package Structureβ
Complete Package Hierarchyβ
com.ttn.ck.lens/
β
βββ LensApplication.java # Main Spring Boot application
β
βββ controller/ # Presentation Layer (40 controllers)
β βββ AwsVsActualCostController.java
β βββ BillingConsoleController.java
β βββ BillingSummaryController.java
β βββ CostExplorerController.java
β βββ CostTrendsController.java
β βββ DatesController.java
β βββ RecommendationController.java
β βββ ReservationController.java
β βββ ReservationUtilizationController.java
β βββ RiCoverageController.java
β βββ SavedReportFilterMetaController.java
β βββ TagReportController.java
β βββ AccountWiseBreakupController.java
β βββ AccountWiseBreakupV2Controller.java
β β
β βββ alertsapi/ # Alert controllers (5)
β β βββ AccountsDatesController.java
β β βββ CostAlertController.java
β β βββ DailyReportController.java
β β βββ RiExpiryAlertController.java
β β βββ RiUtilizationAlertController.java
β β
β βββ costbreakup/ # Cost breakup controllers (13)
β β βββ AbstractCostBreakupController.java
β β βββ AnalyticsController.java
β β βββ ContainersController.java
β β βββ DatabaseController.java
β β βββ DataTransferController.java
β β βββ InstanceCostController.java
β β βββ ManagementAndGovernanceController.java
β β βββ MediaController.java
β β βββ MigrationAndTransferController.java
β β βββ NetworkingAndContentDeliveryController.java
β β βββ SecurityController.java
β β βββ ServerlessController.java
β β βββ StorageController.java
β β
β βββ cudos/ # CUDOS controllers (3)
β β βββ DataTransferDashboardController.java
β β βββ S3DashboardController.java
β β βββ DatabaseDashboardController.java
β β
β βββ finops/ # FinOps controller (1)
β β βββ FinOpsRecommendationController.java
β β
β βββ marketplace/ # Marketplace controller (1)
β β βββ MarketPlaceController.java
β β
β βββ monthlyreport/ # Monthly report controllers (2)
β βββ MonthlyReportAccountDates.java
β βββ ReportRecommendationController.java
β
βββ service/ # Application Layer (107 services)
β βββ (Interface files) # Service interfaces
β β βββ AwsVsActualCostService.java
β β βββ BillingConsoleService.java
β β βββ BillingSummaryService.java
β β βββ CostExplorerService.java
β β βββ CostTrendsService.java
β β βββ RecommendationService.java
β β βββ ReservationService.java
β β βββ ... (20+ core service interfaces)
β β
β βββ impl/ # Service implementations
β βββ AwsVsActualCostServiceImpl.java
β βββ BillingConsoleServiceImpl.java
β βββ BillingSummaryServiceImpl.java
β βββ CostExplorerServiceImpl.java
β βββ CostTrendsServiceImpl.java
β βββ ... (20+ core implementations)
β β
β βββ billingsummary/ # Billing summary services
β β βββ ... (billing services)
β β
β βββ costbreakup/ # Cost breakup services (60+)
β βββ analytics/
β β βββ AnalyticsService.java
β β βββ AnalyticsServiceImpl.java
β β βββ KinesisService.java
β β βββ EmrService.java
β β
β βββ containers/
β β βββ ContainersService.java
β β βββ EcsService.java
β β βββ EksService.java
β β βββ FargateService.java
β β
β βββ database/
β β βββ DatabaseService.java
β β βββ RdsService.java
β β βββ DynamoDbService.java
β β βββ ElastiCacheService.java
β β βββ RedshiftService.java
β β
β βββ datatransfer/
β βββ instance/
β βββ managementandgovernance/
β βββ media/
β βββ migrationandtransfer/
β βββ networkingandcontent/
β βββ security/
β βββ serverless/
β βββ storage/
β
βββ dao/ # Data Access Layer (47 DAOs)
β βββ (Interface files) # DAO interfaces
β β βββ AwsVsActualCostDao.java
β β βββ BillingConsoleDao.java
β β βββ CostExplorerDao.java
β β βββ ... (35+ DAO interfaces)
β β
β βββ impl/ # DAO implementations
β β βββ AwsVsActualCostDaoImpl.java
β β βββ BillingConsoleDaoImpl.java
β β βββ ... (35+ implementations)
β β
β βββ cudos/ # CUDOS DAOs
β β βββ S3DashboardDao.java
β β βββ DataTransferDashboardDao.java
β β βββ DatabaseDashboardDao.java
β β
β βββ marketplace/ # Marketplace DAOs
β βββ MarketPlaceDao.java
β
βββ queries/ # SQL Query Classes
β βββ costbreakup/
β β βββ AnalyticsQueries.java
β β βββ DatabaseQueries.java
β β βββ StorageQueries.java
β β βββ ... (12 query classes)
β β
β βββ cudos/
β β βββ S3Queries.java
β β βββ DataTransferQueries.java
β β βββ DatabaseQueries.java
β β
β βββ marketplace/
β βββ MarketPlaceQueries.java
β
βββ dto/ # Data Transfer Layer (165 DTOs)
β βββ GenericRequestDTO.java # Common request DTO
β βββ AwsVsActualCost/
β βββ accountwisebreakup/
β βββ billingconsole/
β βββ billingsummary/
β βββ costalert/
β βββ costbreakup/ # 12 subcategories
β βββ costexplorer/
β βββ costtrends/
β βββ cudos/
β βββ recommendation/
β βββ reservation/
β βββ ricoverage/
β βββ riexpiry/
β
βββ document/ # MongoDB Documents
β βββ SavedReportDocument.java
β βββ FilterMetadataDocument.java
β βββ CustomQueryDocument.java
β
βββ repo/ # JPA & MongoDB Repositories
β βββ SavedReportRepository.java # MongoDB
β βββ FilterMetadataRepository.java # MongoDB
β βββ ... (7 repositories)
β
βββ config/ # Configuration Classes
β βββ SnowflakeConfig.java
β βββ MongoConfig.java
β βββ RedisConfig.java
β βββ RabbitMQConfig.java
β βββ CacheConfig.java
β βββ SwaggerConfig.java
β
βββ utils/ # Utility Classes
β βββ ApplicationConstants.java # 660+ constants
β βββ ApplicationUtils.java
β βββ ColumnNameConstants.java
β βββ QueueConstants.java
β βββ HourlyDataConverter.java
β βββ SequenceGenerationUtil.java
β βββ SortUtils.java
β βββ StrReplaceForMongoUtils.java
β βββ UtilityService.java
β βββ AccountWiseBreakUpReportGenerator.java
β
βββ cache/ # Caching Logic
β βββ CacheConfiguration.java
β
βββ listner/ # Event Listeners
β βββ MessageQueueListener.java # RabbitMQ consumer
β
βββ clients/ # External Service Clients
β βββ AwsRecommendationClient.java # Feign client
β
βββ enums/ # Enumerations
βββ costbreakup/
β βββ AnalyticsServiceEnum.java
β βββ DatabaseServiceEnum.java
β βββ ... (12 enum files)
βββ cudos/
βββ CudosServiceEnum.java
Layer Responsibilitiesβ
Request Flow Through Layersβ
Example: Get Cost Summary Request
1. HTTP Request
β
2. AwsVsActualCostController.getAwsAndActualCostSummary()
- Validates input (@Valid GenericRequestDTO)
- Security check (@Secured annotation)
β
3. AwsVsActualCostService.getCostSummary()
- Business logic: Date range validation
- Calls DAO layer
- Aggregates results
- Calculates savings percentage
β
4. AwsVsActualCostDao.queryCostData()
- Builds Snowflake SQL query
- Executes query
- Maps ResultSet to DTOs
β
5. Snowflake Database
- Executes query
- Returns result set
β
6. (Return path - up the stack)
DAO β Service β Controller β HTTP Response
Separation of Concerns:
- Controller: "What data did the user request?" (routing)
- Service: "How do we process this business logic?" (orchestration)
- DAO: "How do we fetch this data?" (persistence)
- DTO: "What does the data look like?" (structure)
Communication Patternsβ
1. Synchronous Request-Responseβ
Pattern: Controller β Service β DAO β Database β Response
Used For: Most API endpoints (cost queries, dashboards, reports)
Example:
// Controller
@GetMapping("/cost/summary")
public ResponseDto<`List<CostSummaryDTO>`> getCostSummary(@Valid GenericRequestDTO request) {
return new SuccessResponseDto<>(awsVsActualCostService.getCostSummary(request));
}
// Service
public `List<CostSummaryDTO>` getCostSummary(GenericRequestDTO request) {
// Business logic
return awsVsActualCostDao.queryCostSummary(request);
}
// DAO
public `List<CostSummaryDTO>` queryCostSummary(GenericRequestDTO request) {
// SQL query execution
return jdbcTemplate.query(sql, rowMapper);
}
Characteristics:
- Blocking (request waits for response)
- Simple to debug
- Works for fast queries (<2 seconds)
2. Asynchronous Processingβ
Pattern: Controller β Service β @Async Method β Background Thread β Database
Used For: Heavy reports, large exports, batch processing
Implementation:
// LensApplication.java:12
@EnableAsync
// Service
@Async
public `CompletableFuture<File>` generateLargeReport(ReportDTO request) {
// Heavy processing in background
File report = reportGenerator.generate(request);
return CompletableFuture.completedFuture(report);
}
// Controller
@GetMapping("/export")
public `ResponseEntity<String>` exportReport(@Valid ReportDTO request) {
`CompletableFuture<File>` future = service.generateLargeReport(request);
return ResponseEntity.accepted().body("Report generation started. ID: " + jobId);
}
Characteristics:
- Non-blocking (controller returns immediately)
- Used for long-running operations (>5 seconds)
- Improves user experience (no timeout)
3. Caching Patternβ
Pattern: Request β Check Cache β Cache Hit? β Return Cached Data : Fetch from DB β Store in Cache β Return
Used For: Frequently accessed, slowly-changing data (filter metadata, static queries)
Implementation:
// LensApplication.java:14
@EnableCaching
// Service
@Cacheable(value = "filterMetadata", key = "#customerId")
public FilterMetadataDTO getFilterMetadata(String customerId) {
// Expensive database query
return dao.queryFilterMetadata(customerId);
}
@CacheEvict(value = "filterMetadata", key = "#customerId")
public void updateFilterMetadata(String customerId, FilterMetadataDTO metadata) {
dao.updateMetadata(customerId, metadata);
}
Cache Configuration:
- Backend: Redis
- TTL: 15 minutes (dashboard queries), 1 hour (filter metadata)
- Eviction: LRU (Least Recently Used)
- Size: 1000 entries max
Characteristics:
- Reduces database load
- Faster response times (cache hit: <10ms vs DB query: 500ms)
- Cache invalidation on updates
4. Event-Driven (Message Queue)β
Pattern: Service β Publish Message β RabbitMQ β Consumer β Process Event
Used For: Cost data updates, alert generation, async notifications
Implementation:
// Publisher (Service)
public void publishCostUpdateEvent(CostUpdateDTO update) {
rabbitTemplate.convertAndSend(QueueConstants.COST_UPDATE_EXCHANGE,
QueueConstants.COST_UPDATE_ROUTING_KEY,
update);
}
// Consumer (Listener)
@RabbitListener(queues = QueueConstants.COST_UPDATE_QUEUE)
public void handleCostUpdate(CostUpdateDTO update) {
// Process cost update
// Invalidate caches
// Trigger alerts if needed
}
Queues Used:
cost.update- Cost data updatedalert.cost- Cost alert triggeredreport.generated- Report generation complete
Characteristics:
- Decoupled (publisher doesn't wait for consumer)
- Reliable (messages persisted in RabbitMQ)
- Scalable (multiple consumers)
5. Retry Patternβ
Pattern: Service β Call External API β Failure? β Retry (exponential backoff)
Used For: External API calls (AWS SDK, Snowflake connections)
Implementation:
// LensApplication.java:13
@EnableRetry
// Service
@Retryable(
value = {SnowflakeConnectionException.class},
maxAttempts = 3,
backoff = @Backoff(delay = 1000, multiplier = 2)
)
public `List<CostDTO>` queryCostData(RequestDTO request) {
return dao.queryCostData(request);
}
@Recover
public `List<CostDTO>` recover(SnowflakeConnectionException ex, RequestDTO request) {
log.error("Failed to query cost data after 3 retries", ex);
throw new GenericException("Unable to fetch cost data. Please try again later.");
}
Retry Configuration:
- Max Attempts: 3
- Initial Delay: 1 second
- Backoff Multiplier: 2x (1s, 2s, 4s)
- Recoverable Exceptions: SnowflakeConnectionException, AwsApiThrottlingException
Characteristics:
- Resilient to transient failures
- Exponential backoff prevents overwhelming failed service
- Recovery method provides graceful degradation
Design Patternsβ
1. Layered Architectureβ
Description: Clear separation of concerns into horizontal layers
Implementation: Controller β Service β DAO β Database
Benefits:
- Easy to understand
- Easy to test (mock each layer)
- Easy to maintain
- Enforces separation of concerns
2. Interface-Based Design (Dependency Inversion)β
Description: Services and DAOs defined as interfaces, implementations injected
Implementation:
// Interface
public interface AwsVsActualCostService {
`List<CostSummaryDTO>` getCostSummary(GenericRequestDTO request);
}
// Implementation
@Service
public class AwsVsActualCostServiceImpl implements AwsVsActualCostService {
@Override
public `List<CostSummaryDTO>` getCostSummary(GenericRequestDTO request) {
// Implementation
}
}
// Controller (dependency injection)
@AllArgsConstructor
public class AwsVsActualCostController {
private final AwsVsActualCostService service; // Interface, not implementation
}
Benefits:
- Easy to mock for testing
- Easy to swap implementations
- Loose coupling
3. DTO Pattern (Data Transfer Object)β
Description: Dedicated objects for transferring data between layers
Implementation: Separate DTO classes for request, response, database entities
Benefits:
- Decouples layers
- Allows different representations (API vs DB)
- Input validation
4. Template Method Pattern (Abstract Controllers)β
Description: Abstract base class with common controller logic
Implementation:
// AbstractCostBreakupController.java
public abstract class AbstractCostBreakupController {
protected ResponseDto<CostBreakupDTO> getCostBreakup(RequestDTO request) {
// Common validation
// Common error handling
// Call abstract method
CostBreakupDTO data = fetchCostData(request);
return new SuccessResponseDto<>(data);
}
protected abstract CostBreakupDTO fetchCostData(RequestDTO request);
}
// AnalyticsController extends AbstractCostBreakupController
@Override
protected CostBreakupDTO fetchCostData(RequestDTO request) {
return analyticsService.getAnalyticsCostBreakup(request);
}
Benefits:
- Code reuse
- Consistent behavior across cost breakup controllers
- Easy to add new cost breakup categories
5. Repository Pattern (JPA & MongoDB)β
Description: Abstract data access logic behind repository interfaces
Implementation:
public interface SavedReportRepository extends MongoRepository<SavedReportDocument, String> {
`List<SavedReportDocument>` findByCustomerId(String customerId);
`Optional<SavedReportDocument>` findByReportId(String reportId);
}
Benefits:
- Standardized data access
- Spring Data JPA generates implementations
- Easy to switch databases
6. Strategy Pattern (Cost Breakup Services)β
Description: Different algorithms for different cost breakup categories
Implementation: Each cost breakup service (Analytics, Database, Storage) implements same interface but with different logic
Benefits:
- Extensible (easy to add new AWS services)
- Clean separation
7. Builder Pattern (Query Construction)β
Description: Fluent API for building complex SQL queries
Implementation:
String sql = QueryBuilder.select()
.from("COST_DAILY")
.where("ACCOUNT_ID", accountId)
.where("DATE BETWEEN", startDate, endDate)
.groupBy("SERVICE")
.orderBy("COST DESC")
.build();
Benefits:
- Readable query construction
- Type-safe
Module Dependenciesβ
Internal Module Dependenciesβ
Lens depends on 4 internal Stormus modules:
1. snowplugβ
Purpose: Snowflake multi-tenant datasource configuration
Usage: Provides Snowflake connection pooling and multi-tenant schema routing
Dependency:
api project(":snowplug")
Integration:
@Autowired
private SnowflakeJdbcTemplate snowflakeTemplate;
public `List<CostDTO>` queryCosts(String customerId) {
// snowplug automatically routes to customer's schema
return snowflakeTemplate.query(sql, rowMapper, customerId);
}
2. monitoringβ
Purpose: Prometheus metrics, application monitoring
Usage: Exposes metrics for cost query latency, cache hit rates, API calls
Dependency:
api project(":monitoring")
Integration:
@Autowired
private MeterRegistry meterRegistry;
public `List<CostDTO>` queryCosts(RequestDTO request) {
Timer.Sample sample = Timer.start(meterRegistry);
`List<CostDTO>` result = dao.queryCosts(request);
sample.stop(meterRegistry.timer("lens.query.cost.duration"));
return result;
}
Metrics Exposed:
lens.query.cost.duration- Cost query latencylens.cache.hit.rate- Cache hit percentagelens.api.requests- API request count by endpoint
3. errorhandlerβ
Purpose: Centralized exception handling
Usage: Consistent error responses across all Lens endpoints
Dependency:
api project(":errorhandler")
Integration:
// errorhandler provides @ControllerAdvice for global exception handling
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(GenericException.class)
public `ResponseEntity<ErrorResponseDto>` handleGenericException(GenericException ex) {
return ResponseEntity.status(500).body(new ErrorResponseDto(ex.getMessage()));
}
}
Error Response Format:
{
"status": "error",
"code": 500,
"message": "Unable to fetch cost data",
"timestamp": "2025-10-25T18:30:00Z"
}
4. loggerutilβ
Purpose: Structured logging utilities
Usage: Consistent log formatting, correlation IDs, log levels
Dependency:
api project(":loggerutil")
Integration:
import com.ttn.ck.loggerutil.Logger;
private static final Logger log = Logger.getLogger(AwsVsActualCostService.class);
public `List<CostDTO>` getCostSummary(RequestDTO request) {
log.info("Fetching cost summary for customer: {}, date range: {} - {}",
request.getCustomerId(), request.getStartDate(), request.getEndDate());
// ...
}
Log Format:
2025-10-25 18:30:00.123 INFO [lens-api] [request-id-123] [customer-456] AwsVsActualCostService - Fetching cost summary for customer: 456, date range: 2024-01-01 - 2024-01-31
External Module Dependenciesβ
See 04-technical-architecture for detailed external dependency information.
Key External Dependencies:
- Snowflake JDBC (3.13.27)
- AWS Java SDK (1.12.324)
- Spring Boot (2.7.4)
- Spring Cloud (2021.0.8)
- MongoDB
- Redis
- RabbitMQ
Cross-Cutting Concernsβ
1. Securityβ
Implementation: All controllers secured with @Secured annotation
Location: com.ttn.ck.authX (external module)
Mechanism: JWT token validation
Example:
@Secured(key = "LENS_AWSVSACTUALCOSTCONTROLLER")
public class AwsVsActualCostController {
// All endpoints in this controller require valid JWT with appropriate permissions
}
Security Flow:
- Client sends JWT token in
Authorizationheader authXmodule validates token- Extracts user context (customer ID, roles)
- Checks if user has permission for controller
- Allows/denies request
2. Loggingβ
Implementation: Structured logging via loggerutil module
Log Levels:
- ERROR: Exceptions, failures
- WARN: Anomalies, deprecated usage
- INFO: Business events (queries, reports)
- DEBUG: Detailed debug information
Correlation ID: Every request has unique ID for tracing across services
3. Monitoringβ
Implementation: Prometheus metrics via monitoring module
Metrics Categories:
- Request Metrics: Count, latency, errors
- Cache Metrics: Hit rate, miss rate, evictions
- Database Metrics: Query duration, connection pool usage
- Business Metrics: Cost queries per customer, report generations
Dashboards: Grafana dashboards for real-time monitoring
4. Cachingβ
Implementation: Redis via Spring Cache
Cache Strategies:
- Filter Metadata: 1 hour TTL (rarely changes)
- Dashboard Queries: 15 minutes TTL (changes daily)
- RI Data: 1 hour TTL (changes hourly)
Cache Eviction: Automatic on updates + scheduled cleanup
5. Error Handlingβ
Implementation: Global exception handler via errorhandler module
Exception Types:
- GenericException: Business logic errors
- SnowflakeConnectionException: Database connectivity
- AwsApiException: AWS API failures
- ValidationException: Input validation errors
Error Response: Consistent JSON format with status, code, message
6. Validationβ
Implementation: JSR-303 Bean Validation
Location: DTO classes
Example:
public class GenericRequestDTO {
@NotNull(message = "Customer ID is required")
private String customerId;
@NotNull(message = "Start date is required")
@PastOrPresent(message = "Start date cannot be in future")
private LocalDate startDate;
@NotNull(message = "End date is required")
private LocalDate endDate;
@AssertTrue(message = "End date must be after start date")
public boolean isDateRangeValid() {
return endDate.isAfter(startDate);
}
}
7. Configuration Managementβ
Implementation: Spring Cloud Config
Externalized Properties:
- Database credentials
- API endpoints
- Feature flags
- Cache TTLs
Configuration Profiles: dev, uat, prod
Summaryβ
The AWS Lens module follows a Layered Architecture with clear separation of concerns:
- 40 Controllers (Presentation Layer): Handle HTTP, validate input, return responses
- 107 Services (Application Layer): Execute business logic, orchestrate DAOs
- 47 DAOs (Data Access Layer): Query databases, map results to DTOs
- 165 DTOs (Data Transfer Layer): Define data contracts
- Infrastructure Layer: Configuration, utilities, cross-cutting concerns
Communication Patterns: Synchronous request-response, asynchronous processing, caching, event-driven (RabbitMQ), retry
Design Patterns: Layered Architecture, Interface-Based Design, DTO Pattern, Template Method, Repository, Strategy, Builder
Module Dependencies: 4 internal modules (snowplug, monitoring, errorhandler, loggerutil)
Cross-Cutting Concerns: Security, logging, monitoring, caching, error handling, validation, configuration
Next Steps:
- 04-technical-architecture - Technology stack deep dive
- 05-component-design - Detailed component documentation
- 06-api-reference - Complete API documentation
Document Version: 1.0 Last Updated: October 25, 2025