Skip to content

Commit 49b7eef

Browse files
committed
Discovery NPE when a zone has 0 nodes in it
Closes #43. (cherry picked from commit b028910) (cherry picked from commit fa3e157)
1 parent 3fd35d2 commit 49b7eef

File tree

3 files changed

+97
-8
lines changed

3 files changed

+97
-8
lines changed

src/main/java/org/elasticsearch/cloud/gce/GceComputeServiceImpl.java

+3
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ public List<Instance> apply(String zoneId) {
6767
try {
6868
Compute.Instances.List list = client().instances().list(project, zoneId);
6969
InstanceList instanceList = list.execute();
70+
if (instanceList.isEmpty()) {
71+
return Lists.newArrayList();
72+
}
7073

7174
return instanceList.getItems();
7275
} catch (IOException e) {

src/test/java/org/elasticsearch/discovery/gce/GceComputeEngineTest.java

+16-8
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,7 @@
2424
import org.elasticsearch.common.collect.Lists;
2525
import org.elasticsearch.common.settings.ImmutableSettings;
2626
import org.elasticsearch.common.settings.Settings;
27-
import org.elasticsearch.discovery.gce.mock.GceComputeServiceTwoNodesDifferentTagsMock;
28-
import org.elasticsearch.discovery.gce.mock.GceComputeServiceTwoNodesOneZoneMock;
29-
import org.elasticsearch.discovery.gce.mock.GceComputeServiceTwoNodesSameTagsMock;
30-
import org.elasticsearch.discovery.gce.mock.GceComputeServiceTwoNodesTwoZonesMock;
27+
import org.elasticsearch.discovery.gce.mock.*;
3128
import org.elasticsearch.plugins.PluginsService;
3229
import org.elasticsearch.test.ElasticsearchIntegrationTest;
3330
import org.junit.Ignore;
@@ -186,11 +183,11 @@ public void nodes_with_same_tags_and_two_tags_set() {
186183
public void multiple_zones_and_two_nodes_in_same_zone() {
187184
startNode(1,
188185
GceComputeServiceTwoNodesOneZoneMock.class,
189-
ImmutableSettings.settingsBuilder().put("cloud.gce.zones", Lists.newArrayList("us-central1-a", "us-central1-b",
186+
ImmutableSettings.settingsBuilder().put("cloud.gce.zone", Lists.newArrayList("us-central1-a", "us-central1-b",
190187
"us-central1-f", "europe-west1-a", "europe-west1-b")).build());
191188
startNode(2,
192189
GceComputeServiceTwoNodesOneZoneMock.class,
193-
ImmutableSettings.settingsBuilder().put("cloud.gce.zones", Lists.newArrayList("us-central1-a", "us-central1-b",
190+
ImmutableSettings.settingsBuilder().put("cloud.gce.zone", Lists.newArrayList("us-central1-a", "us-central1-b",
194191
"us-central1-f", "europe-west1-a", "europe-west1-b")).build());
195192

196193
// We expect having 2 nodes as part of the cluster, let's test that
@@ -201,15 +198,26 @@ public void multiple_zones_and_two_nodes_in_same_zone() {
201198
public void multiple_zones_and_two_nodes_in_different_zones() {
202199
startNode(1,
203200
GceComputeServiceTwoNodesTwoZonesMock.class,
204-
ImmutableSettings.settingsBuilder().put("cloud.gce.zones", Lists.newArrayList("us-central1-a", "us-central1-b",
201+
ImmutableSettings.settingsBuilder().put("cloud.gce.zone", Lists.newArrayList("us-central1-a", "us-central1-b",
205202
"us-central1-f", "europe-west1-a", "europe-west1-b")).build());
206203
startNode(2,
207204
GceComputeServiceTwoNodesTwoZonesMock.class,
208-
ImmutableSettings.settingsBuilder().put("cloud.gce.zones", Lists.newArrayList("us-central1-a", "us-central1-b",
205+
ImmutableSettings.settingsBuilder().put("cloud.gce.zone", Lists.newArrayList("us-central1-a", "us-central1-b",
209206
"us-central1-f", "europe-west1-a", "europe-west1-b")).build());
210207

211208
// We expect having 2 nodes as part of the cluster, let's test that
212209
checkNumberOfNodes(2);
213210
}
214211

212+
/**
213+
* For issue https://github.com/elastic/elasticsearch-cloud-gce/issues/43
214+
*/
215+
@Test @Ignore
216+
public void zero_node_43() {
217+
startNode(1,
218+
GceComputeServiceZeroNodeMock.class,
219+
ImmutableSettings.settingsBuilder().put("cloud.gce.zone", Lists.newArrayList("us-central1-a", "us-central1-b",
220+
"us-central1-f", "europe-west1-a", "europe-west1-b")).build());
221+
}
222+
215223
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.discovery.gce.mock;
21+
22+
import com.google.api.services.compute.model.Instance;
23+
import org.elasticsearch.common.base.Function;
24+
import org.elasticsearch.common.collect.Iterables;
25+
import org.elasticsearch.common.collect.Lists;
26+
import org.elasticsearch.common.inject.Inject;
27+
import org.elasticsearch.common.settings.Settings;
28+
29+
import java.util.ArrayList;
30+
import java.util.Collection;
31+
import java.util.List;
32+
33+
/**
34+
*
35+
*/
36+
public class GceComputeServiceZeroNodeMock extends GceComputeServiceAbstractMock {
37+
38+
@Override
39+
protected List<ArrayList<String>> getTags() {
40+
return Lists.newArrayList();
41+
}
42+
43+
@Override
44+
protected List<String> getZones() {
45+
return Lists.newArrayList();
46+
}
47+
48+
private final List<String> zoneList;
49+
50+
@Override
51+
public Collection<Instance> instances() {
52+
logger.debug("get instances for zoneList [{}]", zoneList);
53+
54+
List<List<Instance>> instanceListByZone = Lists.transform(zoneList, new Function<String, List<Instance>>() {
55+
@Override
56+
public List<Instance> apply(String zoneId) {
57+
// If we return null here we will get a trace as explained in issue 43
58+
return Lists.newArrayList();
59+
}
60+
});
61+
62+
//Collapse instances from all zones into one neat list
63+
List<Instance> instanceList = Lists.newArrayList(Iterables.concat(instanceListByZone));
64+
65+
if (instanceList.size() == 0) {
66+
logger.warn("disabling GCE discovery. Can not get list of nodes");
67+
}
68+
69+
return instanceList;
70+
}
71+
72+
@Inject
73+
protected GceComputeServiceZeroNodeMock(Settings settings) {
74+
super(settings);
75+
String[] zoneList = componentSettings.getAsArray(Fields.ZONE, settings.getAsArray("cloud.gce." + Fields.ZONE));
76+
this.zoneList = Lists.newArrayList(zoneList);
77+
}
78+
}

0 commit comments

Comments
 (0)