Skip to content

Commit 01fce8e

Browse files
authored
Merge pull request #7 from fireflyframework/feature/hexagonal-architecture-remediation
refactor: hexagonal architecture remediation — data @componentscan removal
2 parents 5ca5295 + 490565f commit 01fce8e

10 files changed

Lines changed: 160 additions & 45 deletions

src/main/java/org/fireflyframework/data/config/DataEnrichmentAutoConfiguration.java

Lines changed: 154 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,37 @@
1717
package org.fireflyframework.data.config;
1818

1919
import com.fasterxml.jackson.databind.ObjectMapper;
20+
import io.micrometer.core.instrument.MeterRegistry;
21+
import io.micrometer.observation.ObservationRegistry;
2022
import org.fireflyframework.cache.core.CacheAdapter;
2123
import org.fireflyframework.data.cache.EnrichmentCacheKeyGenerator;
2224
import org.fireflyframework.data.cache.EnrichmentCacheService;
2325
import org.fireflyframework.data.cache.OperationCacheService;
26+
import org.fireflyframework.data.event.EnrichmentEventPublisher;
27+
import org.fireflyframework.data.event.JobEventPublisher;
28+
import org.fireflyframework.data.event.OperationEventPublisher;
29+
import org.fireflyframework.data.health.JobOrchestratorHealthIndicator;
30+
import org.fireflyframework.data.mapper.JobResultMapper;
31+
import org.fireflyframework.data.mapper.JobResultMapperRegistry;
32+
import org.fireflyframework.data.observability.JobMetricsService;
33+
import org.fireflyframework.data.observability.JobTracingService;
34+
import org.fireflyframework.data.operation.schema.JsonSchemaGenerator;
35+
import org.fireflyframework.data.orchestration.port.JobOrchestrator;
2436
import org.fireflyframework.data.service.DataEnricher;
2537
import org.fireflyframework.data.service.DataEnricherRegistry;
38+
import org.fireflyframework.data.service.DataJobDiscoveryService;
2639
import lombok.extern.slf4j.Slf4j;
2740
import org.springframework.boot.autoconfigure.AutoConfiguration;
2841
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
42+
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
2943
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
3044
import org.springframework.boot.context.properties.EnableConfigurationProperties;
45+
import org.springframework.context.ApplicationContext;
46+
import org.springframework.context.ApplicationEventPublisher;
3147
import org.springframework.context.annotation.Bean;
32-
import org.springframework.context.annotation.ComponentScan;
3348

3449
import java.util.List;
50+
import java.util.Optional;
3551

3652
/**
3753
* Auto-configuration for data enrichment components.
@@ -42,11 +58,14 @@
4258
* <li>Data enricher registry for discovering enrichers</li>
4359
* <li>Enrichment cache service (when cache is enabled and CacheAdapter is available)</li>
4460
* <li>Cache key generator for tenant-isolated caching</li>
61+
* <li>Job metrics and tracing services</li>
62+
* <li>Event publishers for enrichment, operation, and job events</li>
63+
* <li>Job result mapper registry</li>
64+
* <li>Job orchestrator health indicator</li>
65+
* <li>Data job discovery service</li>
66+
* <li>JSON schema generator</li>
4567
* </ul>
4668
*
47-
* <p>Note: EnrichmentEventPublisher is auto-discovered via @Service annotation
48-
* and is conditionally created based on firefly.data.enrichment.publish-events property.</p>
49-
*
5069
* <p>The configuration is activated when:</p>
5170
* <ul>
5271
* <li>The property {@code firefly.data.enrichment.enabled} is true (default)</li>
@@ -76,13 +95,12 @@
7695
havingValue = "true",
7796
matchIfMissing = true
7897
)
79-
@ComponentScan(basePackages = "org.fireflyframework.data")
8098
public class DataEnrichmentAutoConfiguration {
81-
99+
82100
public DataEnrichmentAutoConfiguration() {
83101
log.info("Initializing Data Enrichment Auto-Configuration");
84102
}
85-
103+
86104
/**
87105
* Creates the data enricher registry bean.
88106
*
@@ -166,4 +184,133 @@ public OperationCacheService operationCacheService(
166184
log.info("Creating OperationCacheService bean with cache type: {}", cacheManager.getCacheType());
167185
return new OperationCacheService(cacheManager, objectMapper, properties);
168186
}
187+
188+
/**
189+
* Creates the job metrics service bean.
190+
*
191+
* <p>This service records job-related metrics using Micrometer.</p>
192+
*/
193+
@Bean
194+
@ConditionalOnMissingBean
195+
public JobMetricsService jobMetricsService(MeterRegistry meterRegistry,
196+
JobOrchestrationProperties properties) {
197+
log.info("Creating JobMetricsService bean");
198+
return new JobMetricsService(meterRegistry, properties);
199+
}
200+
201+
/**
202+
* Creates the job tracing service bean.
203+
*
204+
* <p>This service adds distributed tracing to job operations.</p>
205+
*/
206+
@Bean
207+
@ConditionalOnMissingBean
208+
public JobTracingService jobTracingService(ObservationRegistry observationRegistry,
209+
JobOrchestrationProperties properties) {
210+
log.info("Creating JobTracingService bean");
211+
return new JobTracingService(observationRegistry, properties);
212+
}
213+
214+
/**
215+
* Creates the JSON schema generator bean.
216+
*
217+
* <p>This component generates JSON Schemas and example objects from Java classes.</p>
218+
*/
219+
@Bean
220+
@ConditionalOnMissingBean
221+
public JsonSchemaGenerator jsonSchemaGenerator(ObjectMapper objectMapper) {
222+
log.info("Creating JsonSchemaGenerator bean");
223+
return new JsonSchemaGenerator(objectMapper);
224+
}
225+
226+
/**
227+
* Creates the job event publisher bean.
228+
*
229+
* <p>This service publishes job lifecycle events through Spring's event mechanism.</p>
230+
*/
231+
@Bean
232+
@ConditionalOnMissingBean
233+
public JobEventPublisher jobEventPublisher(ApplicationEventPublisher eventPublisher,
234+
JobOrchestrationProperties properties) {
235+
log.info("Creating JobEventPublisher bean");
236+
return new JobEventPublisher(eventPublisher, properties);
237+
}
238+
239+
/**
240+
* Creates the enrichment event publisher bean.
241+
*
242+
* <p>This service publishes enrichment lifecycle events through Spring's event mechanism.
243+
* It is only created when {@code firefly.data.enrichment.publish-events} is true (default).</p>
244+
*/
245+
@Bean
246+
@ConditionalOnMissingBean
247+
@ConditionalOnProperty(
248+
prefix = "firefly.data.enrichment",
249+
name = "publish-events",
250+
havingValue = "true",
251+
matchIfMissing = true
252+
)
253+
public EnrichmentEventPublisher enrichmentEventPublisher(ApplicationEventPublisher eventPublisher) {
254+
log.info("Creating EnrichmentEventPublisher bean");
255+
return new EnrichmentEventPublisher(eventPublisher);
256+
}
257+
258+
/**
259+
* Creates the operation event publisher bean.
260+
*
261+
* <p>This service publishes provider operation lifecycle events through Spring's event mechanism.
262+
* It is only created when {@code firefly.data.enrichment.operations.publish-events} is true (default).</p>
263+
*/
264+
@Bean
265+
@ConditionalOnMissingBean
266+
@ConditionalOnProperty(
267+
prefix = "firefly.data.enrichment.operations",
268+
name = "publish-events",
269+
havingValue = "true",
270+
matchIfMissing = true
271+
)
272+
public OperationEventPublisher operationEventPublisher(ApplicationEventPublisher eventPublisher) {
273+
log.info("Creating OperationEventPublisher bean");
274+
return new OperationEventPublisher(eventPublisher);
275+
}
276+
277+
/**
278+
* Creates the data job discovery service bean.
279+
*
280+
* <p>This service discovers and logs all registered DataJobs at application startup.
281+
* It uses {@code @EventListener} to react to {@code ApplicationReadyEvent}.</p>
282+
*/
283+
@Bean
284+
@ConditionalOnMissingBean
285+
public DataJobDiscoveryService dataJobDiscoveryService(ApplicationContext applicationContext) {
286+
log.info("Creating DataJobDiscoveryService bean");
287+
return new DataJobDiscoveryService(applicationContext);
288+
}
289+
290+
/**
291+
* Creates the job result mapper registry bean.
292+
*
293+
* <p>This registry automatically discovers all {@link JobResultMapper} beans and makes them
294+
* available for the RESULT stage transformation.</p>
295+
*/
296+
@Bean
297+
@ConditionalOnMissingBean
298+
public JobResultMapperRegistry jobResultMapperRegistry(List<JobResultMapper<?, ?>> mappers) {
299+
log.info("Creating JobResultMapperRegistry bean with {} mapper(s)", mappers.size());
300+
return new JobResultMapperRegistry(mappers);
301+
}
302+
303+
/**
304+
* Creates the job orchestrator health indicator bean.
305+
*
306+
* <p>This health indicator reports the status of the job orchestrator.</p>
307+
*/
308+
@Bean
309+
@ConditionalOnMissingBean
310+
public JobOrchestratorHealthIndicator jobOrchestratorHealthIndicator(
311+
Optional<JobOrchestrator> orchestrator,
312+
JobOrchestrationProperties properties) {
313+
log.info("Creating JobOrchestratorHealthIndicator bean");
314+
return new JobOrchestratorHealthIndicator(orchestrator, properties);
315+
}
169316
}

src/main/java/org/fireflyframework/data/event/EnrichmentEventPublisher.java

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,28 +19,19 @@
1919
import org.fireflyframework.data.model.EnrichmentRequest;
2020
import org.fireflyframework.data.model.EnrichmentResponse;
2121
import lombok.extern.slf4j.Slf4j;
22-
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
2322
import org.springframework.context.ApplicationEventPublisher;
24-
import org.springframework.stereotype.Service;
2523

2624
import java.time.Instant;
2725
import java.util.HashMap;
2826
import java.util.Map;
2927

3028
/**
3129
* Service for publishing enrichment lifecycle events through Spring's event mechanism.
32-
*
30+
*
3331
* <p>These events can be consumed by EDA components or other parts of the system
3432
* for observability, auditing, and monitoring purposes.</p>
3533
*/
36-
@Service
3734
@Slf4j
38-
@ConditionalOnProperty(
39-
prefix = "firefly.data.enrichment",
40-
name = "publish-events",
41-
havingValue = "true",
42-
matchIfMissing = true
43-
)
4435
public class EnrichmentEventPublisher {
4536

4637
private final ApplicationEventPublisher eventPublisher;

src/main/java/org/fireflyframework/data/event/JobEventPublisher.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import org.fireflyframework.data.orchestration.model.JobExecutionStatus;
2424
import lombok.extern.slf4j.Slf4j;
2525
import org.springframework.context.ApplicationEventPublisher;
26-
import org.springframework.stereotype.Service;
2726

2827
import java.time.Instant;
2928
import java.util.HashMap;
@@ -32,11 +31,10 @@
3231
/**
3332
* Service for publishing job lifecycle events through Spring's event mechanism.
3433
* These events can be consumed by EDA components or other parts of the system.
35-
*
34+
*
3635
* This service is automatically configured when job orchestration is enabled
3736
* and publish-job-events is set to true.
3837
*/
39-
@Service
4038
@Slf4j
4139
public class JobEventPublisher {
4240

src/main/java/org/fireflyframework/data/event/OperationEventPublisher.java

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,18 @@
1717
package org.fireflyframework.data.event;
1818

1919
import lombok.extern.slf4j.Slf4j;
20-
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
2120
import org.springframework.context.ApplicationEventPublisher;
22-
import org.springframework.stereotype.Service;
2321

2422
import java.time.Instant;
2523
import java.util.HashMap;
2624
import java.util.Map;
2725

2826
/**
2927
* Service for publishing provider operation lifecycle events through Spring's event mechanism.
30-
*
28+
*
3129
* <p>These events can be consumed by EDA components or other parts of the system
3230
* for observability, auditing, and monitoring purposes.</p>
33-
*
31+
*
3432
* <p><b>Example Usage:</b></p>
3533
* <pre>{@code
3634
* operationEventPublisher.publishOperationStarted(
@@ -41,14 +39,7 @@
4139
* );
4240
* }</pre>
4341
*/
44-
@Service
4542
@Slf4j
46-
@ConditionalOnProperty(
47-
prefix = "firefly.data.enrichment.operations",
48-
name = "publish-events",
49-
havingValue = "true",
50-
matchIfMissing = true
51-
)
5243
public class OperationEventPublisher {
5344

5445
private final ApplicationEventPublisher eventPublisher;

src/main/java/org/fireflyframework/data/health/JobOrchestratorHealthIndicator.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import lombok.extern.slf4j.Slf4j;
2222
import org.springframework.boot.actuate.health.Health;
2323
import org.springframework.boot.actuate.health.ReactiveHealthIndicator;
24-
import org.springframework.stereotype.Component;
2524
import reactor.core.publisher.Mono;
2625

2726
import java.time.Duration;
@@ -33,7 +32,6 @@
3332
/**
3433
* Health indicator for job orchestrator.
3534
*/
36-
@Component
3735
@Slf4j
3836
public class JobOrchestratorHealthIndicator implements ReactiveHealthIndicator {
3937

src/main/java/org/fireflyframework/data/mapper/JobResultMapperRegistry.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package org.fireflyframework.data.mapper;
1818

1919
import lombok.extern.slf4j.Slf4j;
20-
import org.springframework.stereotype.Component;
2120

2221
import java.lang.reflect.ParameterizedType;
2322
import java.lang.reflect.Type;
@@ -55,7 +54,6 @@
5554
* }
5655
* </pre>
5756
*/
58-
@Component
5957
@Slf4j
6058
public class JobResultMapperRegistry {
6159

src/main/java/org/fireflyframework/data/observability/JobMetricsService.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import org.fireflyframework.observability.metrics.FireflyMetricsSupport;
2323
import io.micrometer.core.instrument.MeterRegistry;
2424
import lombok.extern.slf4j.Slf4j;
25-
import org.springframework.stereotype.Service;
2625

2726
import java.time.Duration;
2827
import java.util.concurrent.ConcurrentHashMap;
@@ -32,7 +31,6 @@
3231
/**
3332
* Service for recording job metrics.
3433
*/
35-
@Service
3634
@Slf4j
3735
public class JobMetricsService extends FireflyMetricsSupport {
3836

src/main/java/org/fireflyframework/data/observability/JobTracingService.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import io.micrometer.observation.Observation;
2222
import io.micrometer.observation.ObservationRegistry;
2323
import lombok.extern.slf4j.Slf4j;
24-
import org.springframework.stereotype.Service;
2524
import reactor.core.publisher.Mono;
2625

2726
import java.util.Map;
@@ -30,7 +29,6 @@
3029
/**
3130
* Service for adding distributed tracing to job operations.
3231
*/
33-
@Service
3432
@Slf4j
3533
public class JobTracingService {
3634

src/main/java/org/fireflyframework/data/operation/schema/JsonSchemaGenerator.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import com.fasterxml.jackson.module.jsonSchema.JsonSchema;
77
import io.swagger.v3.oas.annotations.media.Schema;
88
import lombok.extern.slf4j.Slf4j;
9-
import org.springframework.stereotype.Component;
109

1110
import java.lang.reflect.Field;
1211
import java.util.HashMap;
@@ -96,7 +95,6 @@
9695
* }
9796
* }</pre>
9897
*/
99-
@Component
10098
@Slf4j
10199
public class JsonSchemaGenerator {
102100

0 commit comments

Comments
 (0)