Skip to content

Commit 9979f68

Browse files
committed
use checked exception
1 parent f95f5a7 commit 9979f68

File tree

5 files changed

+167
-27
lines changed

5 files changed

+167
-27
lines changed

extended/src/main/java/io/kubernetes/client/extended/kubectl/KubectlApiResources.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,24 @@
1515
import io.kubernetes.client.Discovery;
1616
import io.kubernetes.client.extended.kubectl.exception.KubectlException;
1717
import io.kubernetes.client.openapi.ApiException;
18+
import io.kubernetes.client.util.exception.IncompleteDiscoveryException;
1819
import java.util.Set;
20+
import org.slf4j.Logger;
21+
import org.slf4j.LoggerFactory;
1922

2023
public class KubectlApiResources extends Kubectl.ApiClientBuilder<KubectlApiResources>
2124
implements Kubectl.Executable<Set<Discovery.APIResource>> {
2225

26+
private static final Logger LOGGER = LoggerFactory.getLogger(KubectlApiResources.class);
27+
2328
@Override
2429
public Set<Discovery.APIResource> execute() throws KubectlException {
2530
Discovery discovery = new Discovery(this.apiClient);
2631
try {
2732
return discovery.findAll();
33+
} catch (IncompleteDiscoveryException e) {
34+
LOGGER.warn("Error while getting all api resources, some resources will be missing", e);
35+
return e.getDiscoveredResources();
2836
} catch (ApiException e) {
2937
throw new KubectlException(e);
3038
}

util/src/main/java/io/kubernetes/client/Discovery.java

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import io.kubernetes.client.openapi.models.V1APIGroupList;
2121
import io.kubernetes.client.openapi.models.V1APIResourceList;
2222
import io.kubernetes.client.openapi.models.V1APIVersions;
23+
import io.kubernetes.client.util.exception.IncompleteDiscoveryException;
2324
import java.util.ArrayList;
2425
import java.util.Arrays;
2526
import java.util.Collections;
@@ -32,12 +33,9 @@
3233
import java.util.Set;
3334
import java.util.stream.Collectors;
3435
import okhttp3.Call;
35-
import org.slf4j.Logger;
36-
import org.slf4j.LoggerFactory;
3736

3837
public class Discovery {
3938

40-
private static final Logger LOGGER = LoggerFactory.getLogger(Discovery.class);
4139
private final ApiClient apiClient;
4240

4341
public Discovery() {
@@ -53,28 +51,42 @@ public Set<APIResource> findAll() throws ApiException {
5351
for (String version : legacyCoreApi().getVersions()) {
5452
allResources.addAll(findAll("", Arrays.asList(version), version, "/api/" + version));
5553
}
54+
IncompleteDiscoveryException incompleteDiscoveryException = null;
5655
for (V1APIGroup group : groupDiscovery("/apis").getGroups()) {
57-
allResources.addAll(
58-
findAll(
59-
group.getName(),
60-
group.getVersions().stream().map(v -> v.getVersion()).collect(Collectors.toList()),
61-
group.getPreferredVersion().getVersion()));
56+
try {
57+
allResources.addAll(
58+
findAll(
59+
group.getName(),
60+
group.getVersions().stream().map(v -> v.getVersion()).collect(Collectors.toList()),
61+
group.getPreferredVersion().getVersion()));
62+
} catch (ApiException e){
63+
IncompleteDiscoveryException resourceDiscoveryException = new IncompleteDiscoveryException(
64+
String.format("Unable to retrieve the complete list of server APIs: %s/%s : %s",
65+
group.getName(), group.getPreferredVersion().getVersion(), e.getResponseBody()),
66+
e, allResources);
67+
if (incompleteDiscoveryException == null) {
68+
incompleteDiscoveryException = resourceDiscoveryException;
69+
}else {
70+
incompleteDiscoveryException.addSuppressed(resourceDiscoveryException);
71+
}
72+
}
73+
}
74+
if (incompleteDiscoveryException != null) {
75+
throw incompleteDiscoveryException;
6276
}
6377
return allResources;
6478
}
6579

66-
public Set<APIResource> findAll(String group, List<String> versions, String preferredVersion) {
80+
public Set<APIResource> findAll(String group, List<String> versions, String preferredVersion)
81+
throws ApiException {
6782
return findAll(group, versions, preferredVersion, "/apis/" + group + "/" + preferredVersion);
6883
}
6984

70-
public Set<APIResource> findAll(String group, List<String> versions, String preferredVersion, String path) {
71-
try {
72-
V1APIResourceList resourceList = resourceDiscovery(path);
73-
return groupResourcesByName(group, versions, preferredVersion, resourceList);
74-
} catch (ApiException e) {
75-
LOGGER.warn("Unable to retrieve the complete list of server APIs: {}/{}: {}", group, preferredVersion, e.getResponseBody());
76-
return Collections.emptySet();
77-
}
85+
public Set<APIResource> findAll(
86+
String group, List<String> versions, String preferredVersion, String path)
87+
throws ApiException {
88+
V1APIResourceList resourceList = resourceDiscovery(path);
89+
return groupResourcesByName(group, versions, preferredVersion, resourceList);
7890
}
7991

8092
public Set<APIResource> groupResourcesByName(

util/src/main/java/io/kubernetes/client/util/ModelMapper.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import io.kubernetes.client.common.KubernetesListObject;
1919
import io.kubernetes.client.common.KubernetesObject;
2020
import io.kubernetes.client.openapi.ApiException;
21+
import io.kubernetes.client.util.exception.IncompleteDiscoveryException;
2122
import java.io.File;
2223

2324
import java.io.IOException;
@@ -266,7 +267,13 @@ public static Set<Discovery.APIResource> refresh(Discovery discovery, Duration r
266267
return lastAPIDiscovery;
267268
}
268269

269-
Set<Discovery.APIResource> apiResources = discovery.findAll();
270+
Set<Discovery.APIResource> apiResources = null;
271+
try {
272+
apiResources = discovery.findAll();
273+
} catch (IncompleteDiscoveryException e) {
274+
logger.warn("Error while getting all api resources, some api resources will not be refreshed", e);
275+
apiResources = e.getDiscoveredResources();
276+
}
270277

271278
for (Discovery.APIResource apiResource : apiResources) {
272279
for (String version : apiResource.getVersions()) {
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package io.kubernetes.client.util.exception;
2+
3+
import io.kubernetes.client.Discovery.APIResource;
4+
import io.kubernetes.client.openapi.ApiException;
5+
import java.util.Set;
6+
7+
public class IncompleteDiscoveryException extends ApiException {
8+
9+
private static final long serialVersionUID = 1L;
10+
11+
private final transient Set<APIResource> discoveredResources;
12+
13+
public IncompleteDiscoveryException(String message, ApiException cause, Set<APIResource> discoveredResources) {
14+
super(message, cause, cause.getCode(), cause.getResponseHeaders(), cause.getResponseBody());
15+
this.discoveredResources = discoveredResources;
16+
}
17+
18+
public Set<APIResource> getDiscoveredResources() {
19+
return discoveredResources;
20+
}
21+
22+
}

util/src/test/java/io/kubernetes/client/DiscoveryTest.java

Lines changed: 100 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,20 @@
1818
import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
1919
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
2020
import static org.junit.Assert.assertEquals;
21+
import static org.junit.Assert.fail;
2122

2223
import com.github.tomakehurst.wiremock.junit.WireMockRule;
2324
import io.kubernetes.client.Discovery.APIResource;
2425
import io.kubernetes.client.openapi.ApiClient;
2526
import io.kubernetes.client.openapi.ApiException;
27+
import io.kubernetes.client.openapi.models.V1APIGroup;
28+
import io.kubernetes.client.openapi.models.V1APIGroupList;
2629
import io.kubernetes.client.openapi.models.V1APIResource;
2730
import io.kubernetes.client.openapi.models.V1APIResourceList;
2831
import io.kubernetes.client.openapi.models.V1APIVersions;
32+
import io.kubernetes.client.openapi.models.V1GroupVersionForDiscovery;
2933
import io.kubernetes.client.util.ClientBuilder;
34+
import io.kubernetes.client.util.exception.IncompleteDiscoveryException;
3035
import java.io.IOException;
3136
import java.util.ArrayList;
3237
import java.util.Arrays;
@@ -106,13 +111,40 @@ public void testGroupResourcesByName() {
106111
}
107112

108113
@Test
109-
public void findAllShouldReturnAllApiResourceWhenApiResponseIsSuccess() {
114+
public void findAllShouldReturnAllApiResourceWhenAllResourceDiscoveryApiResponseAreSuccess() throws ApiException {
110115
Discovery discovery = new Discovery(apiClient);
111116

117+
wireMockRule.stubFor(
118+
get("/api")
119+
.willReturn(
120+
aResponse()
121+
.withStatus(200)
122+
.withHeader("Content-Type", "application/json")
123+
.withBody(
124+
apiClient
125+
.getJSON()
126+
.serialize(new V1APIVersions()))));
127+
112128
String group = "test.com";
113129
String version = "v1";
114130
String path="/apis/"+group+'/'+version;
115131

132+
wireMockRule.stubFor(
133+
get("/apis")
134+
.willReturn(
135+
aResponse()
136+
.withStatus(200)
137+
.withHeader("Content-Type", "application/json")
138+
.withBody(
139+
apiClient
140+
.getJSON()
141+
.serialize(new V1APIGroupList()
142+
.addGroupsItem(new V1APIGroup()
143+
.name(group)
144+
.preferredVersion(new V1GroupVersionForDiscovery().version(version))
145+
.versions(Arrays.asList(
146+
new V1GroupVersionForDiscovery().version(version))))))));
147+
116148
wireMockRule.stubFor(
117149
get(urlPathEqualTo(path))
118150
.willReturn(
@@ -132,29 +164,88 @@ public void findAllShouldReturnAllApiResourceWhenApiResponseIsSuccess() {
132164

133165
List<String> versions = new ArrayList<>();
134166
versions.add(version);
135-
Set<APIResource> apiResources = discovery.findAll(group, versions, version);
167+
Set<APIResource> apiResources = discovery.findAll();
136168
wireMockRule.verify(1, getRequestedFor(urlPathEqualTo(path)));
137169
assertEquals(2, apiResources.size());
138170
}
139171

140172
@Test
141-
public void findAllShouldReturnEmptyListWhenApiResponseIsNotSuccess() {
173+
public void findAllShouldThrowImcompleteDiscoveryExceptionWhenAtLeastOneResourceDiscoveryApiResponseIsNotSuccess() throws ApiException {
142174
Discovery discovery = new Discovery(apiClient);
143175

144-
String group = "test.com";
176+
wireMockRule.stubFor(
177+
get("/api")
178+
.willReturn(
179+
aResponse()
180+
.withStatus(200)
181+
.withHeader("Content-Type", "application/json")
182+
.withBody(
183+
apiClient
184+
.getJSON()
185+
.serialize(new V1APIVersions()))));
186+
187+
String groupSuccess = "test.com";
145188
String version = "v1";
146-
String path="/apis/"+group+'/'+version;
189+
String pathSuccess="/apis/"+groupSuccess+'/'+version;
190+
191+
String groupError = "testError.com";
192+
String pathError="/apis/"+groupError+'/'+version;
147193

148194
wireMockRule.stubFor(
149-
get(urlPathEqualTo(path))
195+
get("/apis")
196+
.willReturn(
197+
aResponse()
198+
.withStatus(200)
199+
.withHeader("Content-Type", "application/json")
200+
.withBody(
201+
apiClient
202+
.getJSON()
203+
.serialize(new V1APIGroupList()
204+
.addGroupsItem(new V1APIGroup()
205+
.name(groupError)
206+
.preferredVersion(new V1GroupVersionForDiscovery().version(version))
207+
.versions(Arrays.asList(
208+
new V1GroupVersionForDiscovery().version(version))))
209+
.addGroupsItem(new V1APIGroup()
210+
.name(groupSuccess)
211+
.preferredVersion(new V1GroupVersionForDiscovery().version(version))
212+
.versions(Arrays.asList(
213+
new V1GroupVersionForDiscovery().version(version))))))));
214+
215+
wireMockRule.stubFor(
216+
get(urlPathEqualTo(pathError))
150217
.willReturn(
151218
aResponse()
152219
.withStatus(503)));
153220

221+
wireMockRule.stubFor(
222+
get(urlPathEqualTo(pathSuccess))
223+
.willReturn(
224+
aResponse()
225+
.withStatus(200)
226+
.withHeader("Content-Type", "application/json")
227+
.withBody(
228+
apiClient
229+
.getJSON()
230+
.serialize(new V1APIResourceList()
231+
.resources(
232+
Arrays.asList(
233+
new V1APIResource()
234+
.name("first"),
235+
new V1APIResource()
236+
.name("second")))))));
237+
154238
List<String> versions = new ArrayList<>();
155239
versions.add(version);
156-
Set<APIResource> apiResources = discovery.findAll(group, versions, version);
157-
wireMockRule.verify(1, getRequestedFor(urlPathEqualTo(path)));
158-
assertEquals(0, apiResources.size());
240+
Set<APIResource> apiResources = null;
241+
try{
242+
discovery.findAll();
243+
fail("Should have throw ImcompleteDiscoveryException");
244+
} catch (IncompleteDiscoveryException e) {
245+
apiResources = e.getDiscoveredResources();
246+
}
247+
wireMockRule.verify(1, getRequestedFor(urlPathEqualTo(pathError)));
248+
wireMockRule.verify(1, getRequestedFor(urlPathEqualTo(pathSuccess)));
249+
assertEquals(2, apiResources.size());
159250
}
160251
}

0 commit comments

Comments
 (0)