Skip to content

Commit 2bcc03d

Browse files
authored
[GCE Discovery] Correcly handle large zones with 500 or more instances (#83785)
Discovery gce plugin has some issues while running in large pools of vms instances. This pr attempts to solve it. Closes #83783
1 parent e3deacf commit 2bcc03d

File tree

6 files changed

+105
-8
lines changed

6 files changed

+105
-8
lines changed

docs/changelog/83785.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pr: 83785
2+
summary: '[GCE Discovery] Correcly handle large zones with 500 or more instances'
3+
area: Distributed
4+
type: bug
5+
issues:
6+
- 83783

plugins/discovery-gce/src/main/java/org/elasticsearch/cloud/gce/GceInstancesServiceImpl.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,19 @@ public Collection<Instance> instances() {
6969
try {
7070
// hack around code messiness in GCE code
7171
// TODO: get this fixed
72-
InstanceList instanceList = Access.doPrivilegedIOException(() -> {
73-
Compute.Instances.List list = client().instances().list(project, zoneId);
74-
return list.execute();
72+
return Access.doPrivilegedIOException(() -> {
73+
String nextPageToken = null;
74+
List<Instance> zoneInstances = new ArrayList<>();
75+
do {
76+
Compute.Instances.List list = client().instances().list(project, zoneId).setPageToken(nextPageToken);
77+
InstanceList instanceList = list.execute();
78+
nextPageToken = instanceList.getNextPageToken();
79+
if (instanceList.isEmpty() == false && instanceList.getItems() != null) {
80+
zoneInstances.addAll(instanceList.getItems());
81+
}
82+
} while (nextPageToken != null);
83+
return zoneInstances;
7584
});
76-
// assist type inference
77-
return instanceList.isEmpty() || instanceList.getItems() == null
78-
? Collections.<Instance>emptyList()
79-
: instanceList.getItems();
8085
} catch (IOException e) {
8186
logger.warn((Supplier<?>) () -> new ParameterizedMessage("Problem fetching instance list for zone {}", zoneId), e);
8287
logger.debug("Full exception:", e);

plugins/discovery-gce/src/test/java/org/elasticsearch/discovery/gce/GceDiscoveryTests.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,4 +272,17 @@ public void testMetadataServerValues() {
272272
List<TransportAddress> dynamicHosts = buildDynamicNodes(mock, nodeSettings);
273273
assertThat(dynamicHosts, hasSize(1));
274274
}
275+
276+
public void testNodesWithPagination() {
277+
Settings nodeSettings = Settings.builder()
278+
.put(GceInstancesServiceImpl.PROJECT_SETTING.getKey(), projectName)
279+
.put(GceInstancesServiceImpl.ZONE_SETTING.getKey(), "europe-west1-b")
280+
.putList(GceSeedHostsProvider.TAGS_SETTING.getKey(), "elasticsearch", "dev")
281+
.build();
282+
mock = new GceInstancesServiceMock(nodeSettings);
283+
List<TransportAddress> dynamicHosts = buildDynamicNodes(mock, nodeSettings);
284+
assertThat(dynamicHosts, hasSize(2));
285+
assertEquals("10.240.79.59", dynamicHosts.get(0).getAddress());
286+
assertEquals("10.240.79.60", dynamicHosts.get(1).getAddress());
287+
}
275288
}

plugins/discovery-gce/src/test/java/org/elasticsearch/discovery/gce/GceMockUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public static String readGoogleApiJsonResponse(String url) throws IOException {
6767

6868
private static String readJsonResponse(String url, String urlRoot) throws IOException {
6969
// We extract from the url the mock file path we want to use
70-
String mockFileName = Strings.replace(url, urlRoot, "");
70+
String mockFileName = Strings.replace(url, urlRoot, "").replace("?", "%3F");
7171

7272
URL resource = GceMockUtils.class.getResource(mockFileName);
7373
if (resource == null) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"id": "dummy",
3+
"items":[
4+
{
5+
"description": "ES Node 1",
6+
"id": "9309873766428965105",
7+
"kind": "compute#instance",
8+
"machineType": "n1-standard-1",
9+
"name": "test1",
10+
"networkInterfaces": [
11+
{
12+
"accessConfigs": [
13+
{
14+
"kind": "compute#accessConfig",
15+
"name": "External NAT",
16+
"natIP": "104.155.13.147",
17+
"type": "ONE_TO_ONE_NAT"
18+
}
19+
],
20+
"name": "nic0",
21+
"network": "default",
22+
"networkIP": "10.240.79.59"
23+
}
24+
],
25+
"status": "RUNNING",
26+
"tags": {
27+
"fingerprint": "xA6QJb-rGtg=",
28+
"items": [
29+
"elasticsearch",
30+
"dev"
31+
]
32+
},
33+
"zone": "europe-west1-b"
34+
}
35+
],
36+
"nextPageToken": "next-token"
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"id": "dummy",
3+
"items":[
4+
{
5+
"description": "ES Node 2",
6+
"id": "9309873766428965105",
7+
"kind": "compute#instance",
8+
"machineType": "n1-standard-1",
9+
"name": "test2",
10+
"networkInterfaces": [
11+
{
12+
"accessConfigs": [
13+
{
14+
"kind": "compute#accessConfig",
15+
"name": "External NAT",
16+
"natIP": "104.155.13.147",
17+
"type": "ONE_TO_ONE_NAT"
18+
}
19+
],
20+
"name": "nic0",
21+
"network": "default",
22+
"networkIP": "10.240.79.60"
23+
}
24+
],
25+
"status": "RUNNING",
26+
"tags": {
27+
"fingerprint": "xA6QJb-rGtg=",
28+
"items": [
29+
"elasticsearch",
30+
"dev"
31+
]
32+
},
33+
"zone": "europe-west1-b"
34+
}
35+
]
36+
}

0 commit comments

Comments
 (0)