8000 Add more data fetchers for ECS by donghwikim2 · Pull Request #80 · Blazebit/blaze-query · GitHub
[go: up one dir, main page]

Skip to content

Add more data fetchers for ECS - #80

Closed
donghwikim2 wants to merge 22 commits into
Blazebit:mainfrom
donghwikim2:add-more-ecs-data-fetchers
Closed

donghwikim2 wants to merge 22 commits into
Blazebit:mainfrom
donghwikim2:add-more-ecs-data-fetchers

Conversation

@donghwikim2
Copy link
Copy Markdown
Contributor

No description provided.

@donghwikim2
donghwikim2 force-pushed the add-more-ecs-data-fetchers branch 2 times, most recently from 5110b09 to 8cdb56b Compare November 12, 2025 14:23
@donghwikim2
donghwikim2 force-pushed the add-more-ecs-data-fetchers branch from 8cdb56b to 4cfdbec Compare November 12, 2025 15:26
Copilot AI and others added 15 commits November 13, 2025 08:27
…tion query

Co-authored-by: donghwikim2 <126684759+donghwikim2@users.noreply.github.com>
Address feedback: revert ClusterDataFetcher imports, add missing AwsContainerDefinition query
Co-authored-by: donghwikim2 <126684759+donghwikim2@users.noreply.github.com>
Add AwsTaskSet query to example application
Co-authored-by: donghwikim2 <126684759+donghwikim2@users.noreply.github.com>
Register AwsContainerDefinition and AwsTaskSet as schema object aliases
Co-authored-by: donghwikim2 <126684759+donghwikim2@users.noreply.github.com>
Address formatting and ordering feedback on ECS data fetchers
@donghwikim2
donghwikim2 marked this pull request as ready for review November 14, 2025 10:36
@donghwikim2 donghwikim2 changed the title [WiP] Add more data fetchers for ECS Add more data fetchers for ECS Nov 14, 2025
* @author Donghwi Kim
* @since 1.0.0
*/
public class AwsService extends AwsWrapper<Service> {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name is rather generic, can you maybe use a more concrete name on what it is?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe you can prefix all of the resources with the service type, e.g. AwsEcsService, AwsEcsTaskSet etc. That way we know to which service it belongs. Some are rather generic.

8000

Copilot AI review requested due to automatic review settings November 18, 2025 09:28
Copilot AI left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR expands AWS ECS connector functionality by introducing new data fetchers and model classes for ECS resources. The changes rename AwsCluster to AwsEcsCluster for consistency and add support for querying ECS services, task definitions, container definitions, and task sets.

  • Renamed AwsCluster to AwsEcsCluster to follow the AwsEcs* naming convention
  • Added new ECS data fetchers: ServiceDataFetcher, TaskDefinitionDataFetcher, ContainerDefinitionDataFetcher, and TaskSetDataFetcher
  • Registered new ECS model classes and updated example application to demonstrate the new query capabilities

Reviewed Changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
Main.java Updated imports and registrations to use renamed AwsEcsCluster and added registrations/queries for new ECS entities
TaskSetDataFetcher.java New data fetcher to retrieve ECS task sets from services
TaskDefinitionDataFetcher.java New data fetcher to retrieve ECS task definitions
ServiceDataFetcher.java New data fetcher to retrieve ECS services from clusters
ContainerDefinitionDataFetcher.java New data fetcher to retrieve container definitions from task definitions
ClusterDataFetcher.java Updated to use AwsEcsCluster naming and added additional cluster fields
AwsEcsTaskSet.java New model class wrapping ECS TaskSet
AwsEcsTaskDefinition.java New model class wrapping ECS task definition response
AwsEcsService.java New model class wrapping ECS Service
AwsEcsContainerDefinition.java New record class for container definitions
AwsECSSchemaProvider.java Registered new data fetchers in the schema provider
AwsCluster.java Renamed class from AwsCluster to AwsEcsCluster

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +55 to +64
List<String> serviceArns = client.listServices( r -> r.cluster( clusterArn ) )
.serviceArns();
if ( !serviceArns.isEmpty() ) {
DescribeServicesRequest request = DescribeServicesRequest.builder()
.cluster( clusterArn )
.services( serviceArns )
.include( ServiceField.TAGS )
.build();
DescribeServicesResponse response = client.describeServices( request );
for ( Service service : response.services() ) {
Copilot AI Nov 18, 2025
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The nested loops with API calls create an N+1 query pattern. Each cluster triggers a separate listServices call. Consider batching or using pagination tokens to optimize the number of API requests.

Suggested change
List<String> serviceArns = client.listServices( r -> r.cluster( clusterArn ) )
.serviceArns();
if ( !serviceArns.isEmpty() ) {
DescribeServicesRequest request = DescribeServicesRequest.builder()
.cluster( clusterArn )
.services( serviceArns )
.include( ServiceField.TAGS )
.build();
DescribeServicesResponse response = client.describeServices( request );
for ( Service service : response.services() ) {
List<String> serviceArns = new ArrayList<>();
String nextToken = null;
do {
var response = client.listServices(r -> r.cluster(clusterArn).nextToken(nextToken));
serviceArns.addAll(response.serviceArns());
nextToken = response.nextToken();
} while (nextToken != null && !nextToken.isEmpty());
if ( !serviceArns.isEmpty() ) {
DescribeServicesRequest request = DescribeServicesRequest.builder()
.cluster( clusterArn )
.services( serviceArns )
.include( ServiceField.TAGS )
.build();
DescribeServicesResponse describeResponse = client.describeServices( request );
for ( Service service : describeResponse.services() ) {

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

        /**
         * <p>
         * A list of services to describe. You may specify up to 10 services to describe in a single operation.
         * </p>
         * 
         * @param services
         *        A list of services to describe. You may specify up to 10 services to describe in a single operation.
         * @return Returns a reference to this object so that method calls can be chained together.
         */
        Builder services(Collection<String> services);

I would not batch for now, but I noticed that maximum number of services that it accept is 10 so I modified like below now

for ( String clusterArn : clusterArns ) {
							List<String> serviceArns = client.listServices( r -> r.cluster( clusterArn ) )
									.serviceArns();
							if ( !serviceArns.isEmpty() ) {
								// AWS DescribeServices API accepts up to 10 services per request
								int batchSize = 10;
								for ( int i = 0; i < serviceArns.size(); i += batchSize ) {
									int end = Math.min( i + batchSize, serviceArns.size() );
									List<String> batch = serviceArns.subList( i, end );
									DescribeServicesRequest request = DescribeServicesRequest.builder()
											.cluster( clusterArn )
											.services( batch )
											.include( ServiceField.TAGS )
											.build();
									DescribeServicesResponse response = client.describeServices( request );
									for ( Service service : response.services() ) {
										list.add( new AwsEcsService( service.serviceArn(), service ) );
									}
								}
							}
						}

Copilot AI left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +42 to +65
List<? extends AwsEcsService> services = context.getSession().getOrFetch( AwsEcsService.class );
List<AwsEcsTaskSet> list = new ArrayList<>();
for ( AwsConnectorConfig.Account account : accounts ) {
for ( Region region : account.getRegions() ) {
EcsClientBuilder ecsClientBuilder = EcsClient.builder()
.region( region )
.credentialsProvider( account.getCredentialsProvider() );
if ( sdkHttpClient != null ) {
ecsClientBuilder.httpClient( sdkHttpClient );
}
try (EcsClient client = ecsClientBuilder.build()) {
for ( AwsEcsService service : services ) {
if ( service.getAccountId().equals( account.getAccountId() )
&& service.getRegionId().equals( region.id() ) ) {
DescribeTaskSetsResponse response = client.describeTaskSets( r -> r
.cluster( service.getPayload().clusterArn() )
.service( service.getPayload().serviceArn() )
.include( TaskSetField.TAGS )
);
for ( TaskSet taskSet : response.taskSets() ) {
list.add( new AwsEcsTaskSet( taskSet.taskSetArn(), taskSet ) );
}
}
}
Copilot AI Nov 18, 2025
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The TaskSetDataFetcher fetches all services via context.getSession().getOrFetch(AwsEcsService.class) but only processes task sets for services that match specific account and region criteria. This creates an N+1 query pattern where services are fetched globally first, then filtered locally. Additionally, fetching all services upfront may have performance implications when only a subset is needed. Consider 10BC8 fetching services per account/region or document this dependency relationship if it's intentional.

Copilot uses AI. Check for mistakes.
Comment on lines +52 to +66
try (EcsClient client = ecsClientBuilder.build()) {
List<String> taskDefinitionArns = client.listTaskDefinitions().taskDefinitionArns();
for ( String taskDefinitionArn : taskDefinitionArns ) {
DescribeTaskDefinitionRequest request = DescribeTaskDefinitionRequest.builder()
.taskDefinition( taskDefinitionArn )
.build();
DescribeTaskDefinitionResponse response = client.describeTaskDefinition( request );
TaskDefinition taskDefinition = response.taskDefinition();
List<ContainerDefinition> containerDefinitions = taskDefinition.containerDefinitions();
for ( ContainerDefinition containerDefinition : containerDefinitions ) {
list.add( new AwsEcsContainerDefinition( taskDefinition.taskDefinitionArn(),
containerDefinition.name(), containerDefinition ) );
}
}
}
Copilot AI Nov 18, 2025
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ContainerDefinitionDataFetcher and TaskDefinitionDataFetcher both independently fetch the complete list of task definitions and make describeTaskDefinition calls for each. This results in duplicated API calls and unnecessary work. Consider either:

  1. Having ContainerDefinitionDataFetcher depend on cached AwsEcsTaskDefinition objects via context.getSession().getOrFetch()
  2. Documenting why this duplication is necessary if there's a specific reason

Copilot uses AI. Check for mistakes.
@maxhov
maxhov commented Nov 18, 2025
Copy link
Copy Markdown
Collaborator

Merged via 91e75a3

@maxhov maxhov closed this Nov 18, 2025
@donghwikim2
donghwikim2 deleted the add-more-ecs-data-fetchers branch November 18, 2025 16:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

0