|
36 | 36 | import org.opensearch.transport.grpc.proto.request.search.aggregation.AggregationBuilderProtoConverterRegistryImpl; |
37 | 37 | import org.opensearch.transport.grpc.proto.request.search.query.AbstractQueryBuilderProtoUtils; |
38 | 38 | import org.opensearch.transport.grpc.proto.request.search.query.QueryBuilderProtoConverterRegistryImpl; |
| 39 | +import org.opensearch.transport.grpc.proto.response.search.aggregation.AggregateProtoConverterRegistryImpl; |
| 40 | +import org.opensearch.transport.grpc.proto.response.search.aggregation.AggregateProtoUtils; |
39 | 41 | import org.opensearch.transport.grpc.services.DocumentServiceImpl; |
40 | 42 | import org.opensearch.transport.grpc.services.SearchServiceImpl; |
| 43 | +import org.opensearch.transport.grpc.spi.AggregateProtoConverter; |
41 | 44 | import org.opensearch.transport.grpc.spi.AggregationBuilderProtoConverter; |
42 | 45 | import org.opensearch.transport.grpc.spi.GrpcInterceptorProvider; |
43 | 46 | import org.opensearch.transport.grpc.spi.GrpcInterceptorProvider.OrderedGrpcInterceptor; |
@@ -85,9 +88,11 @@ public final class GrpcPlugin extends Plugin implements NetworkPlugin, Extensibl |
85 | 88 |
|
86 | 89 | private final List<QueryBuilderProtoConverter> queryConverters = new ArrayList<>(); |
87 | 90 | private final List<AggregationBuilderProtoConverter> aggregationConverters = new ArrayList<>(); |
| 91 | + private final List<AggregateProtoConverter> aggregateConverters = new ArrayList<>(); |
88 | 92 | private final List<GrpcServiceFactory> servicesFactory = new ArrayList<>(); |
89 | 93 | private QueryBuilderProtoConverterRegistryImpl queryRegistry; |
90 | 94 | private AggregationBuilderProtoConverterRegistryImpl aggregationRegistry; |
| 95 | + private AggregateProtoConverterRegistryImpl aggregateRegistry; |
91 | 96 | private AbstractQueryBuilderProtoUtils queryUtils; |
92 | 97 | private GrpcInterceptorChain serverInterceptor; // Initialized in createComponents |
93 | 98 | private List<GrpcInterceptorProvider> interceptorProviders = new ArrayList<>(); |
@@ -140,6 +145,23 @@ public void loadExtensions(ExtensiblePlugin.ExtensionLoader loader) { |
140 | 145 | logger.info("No AggregationBuilderProtoConverter extensions found from other plugins"); |
141 | 146 | } |
142 | 147 |
|
| 148 | + // Load aggregate converters (response-side) from other plugins |
| 149 | + List<AggregateProtoConverter> aggResponseExtensions = loader.loadExtensions(AggregateProtoConverter.class); |
| 150 | + if (aggResponseExtensions != null && !aggResponseExtensions.isEmpty()) { |
| 151 | + logger.info("Loading {} AggregateProtoConverter extensions from other plugins", aggResponseExtensions.size()); |
| 152 | + for (AggregateProtoConverter converter : aggResponseExtensions) { |
| 153 | + logger.info( |
| 154 | + "Discovered AggregateProtoConverter extension: {} (handles: {})", |
| 155 | + converter.getClass().getName(), |
| 156 | + converter.getHandledAggregationType().getName() |
| 157 | + ); |
| 158 | + aggregateConverters.add(converter); |
| 159 | + } |
| 160 | + logger.info("Successfully loaded {} AggregateProtoConverter extensions", aggResponseExtensions.size()); |
| 161 | + } else { |
| 162 | + logger.info("No AggregateProtoConverter extensions found from other plugins"); |
| 163 | + } |
| 164 | + |
143 | 165 | List<GrpcInterceptorProvider> providers = loader.loadExtensions(GrpcInterceptorProvider.class); |
144 | 166 | if (providers != null) { |
145 | 167 | // Note: ThreadContext will be provided during component creation |
@@ -417,6 +439,12 @@ public Collection<Object> createComponents( |
417 | 439 | // Create the aggregation registry |
418 | 440 | this.aggregationRegistry = new AggregationBuilderProtoConverterRegistryImpl(); |
419 | 441 |
|
| 442 | + // Create the aggregate registry (response-side) |
| 443 | + this.aggregateRegistry = new AggregateProtoConverterRegistryImpl(); |
| 444 | + |
| 445 | + // Set the global aggregate registry for response serialization |
| 446 | + AggregateProtoUtils.setRegistry(aggregateRegistry); |
| 447 | + |
420 | 448 | // Create the query utils instance |
421 | 449 | this.queryUtils = new AbstractQueryBuilderProtoUtils(queryRegistry); |
422 | 450 |
|
@@ -475,6 +503,28 @@ public Collection<Object> createComponents( |
475 | 503 | logger.info("No external AggregationBuilderProtoConverter(s) to register"); |
476 | 504 | } |
477 | 505 |
|
| 506 | + // Register external aggregate converters (response-side) |
| 507 | + if (!aggregateConverters.isEmpty()) { |
| 508 | + logger.info( |
| 509 | + "Registering {} external AggregateProtoConverter(s)", |
| 510 | + aggregateConverters.size() |
| 511 | + ); |
| 512 | + for (AggregateProtoConverter converter : aggregateConverters) { |
| 513 | + logger.info( |
| 514 | + "Processing external aggregate converter: {} (handles: {})", |
| 515 | + converter.getClass().getName(), |
| 516 | + converter.getHandledAggregationType().getName() |
| 517 | + ); |
| 518 | + |
| 519 | + // Register the converter in the SPI registry |
| 520 | + aggregateRegistry.getSpiRegistry().registerConverter(converter); |
| 521 | + logger.info("Registered aggregate converter: {}", converter.getClass().getName()); |
| 522 | + } |
| 523 | + logger.info("Successfully registered all {} external aggregate converters", aggregateConverters.size()); |
| 524 | + } else { |
| 525 | + logger.info("No external AggregateProtoConverter(s) to register"); |
| 526 | + } |
| 527 | + |
478 | 528 | return super.createComponents( |
479 | 529 | client, |
480 | 530 | clusterService, |
|
0 commit comments