Skip to content

Commit b8ee44c

Browse files
committed
spring integration for KubernetesEndpointsLoadBalanced annotation
1 parent a812284 commit b8ee44c

File tree

19 files changed

+618
-105
lines changed

19 files changed

+618
-105
lines changed

examples/src/main/java/io/kubernetes/client/examples/SpringControllerExample.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import io.kubernetes.client.informer.SharedInformerFactory;
2121
import io.kubernetes.client.informer.cache.Lister;
2222
import io.kubernetes.client.openapi.ApiClient;
23+
import io.kubernetes.client.openapi.models.V1Endpoints;
24+
import io.kubernetes.client.openapi.models.V1EndpointsList;
2325
import io.kubernetes.client.openapi.models.V1Node;
2426
import io.kubernetes.client.openapi.models.V1NodeList;
2527
import io.kubernetes.client.openapi.models.V1Pod;
@@ -107,6 +109,11 @@ public PrometheusScrapeEndpoint prometheusScrapeEndpoint() {
107109
}
108110

109111
@KubernetesInformers({ // Defining what resources is the informer-factory actually watching.
112+
@KubernetesInformer(
113+
apiTypeClass = V1Endpoints.class,
114+
apiListTypeClass = V1EndpointsList.class,
115+
groupVersionResource =
116+
@GroupVersionResource(apiGroup = "", apiVersion = "v1", resourcePlural = "endpoints")),
110117
@KubernetesInformer(
111118
apiTypeClass = V1Node.class,
112119
apiListTypeClass = V1NodeList.class,
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
Copyright 2020 The Kubernetes Authors.
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
http://www.apache.org/licenses/LICENSE-2.0
7+
Unless required by applicable law or agreed to in writing, software
8+
distributed under the License is distributed on an "AS IS" BASIS,
9+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
package io.kubernetes.client.examples;
14+
15+
import io.kubernetes.client.extended.network.LoadBalancer;
16+
import io.kubernetes.client.informer.SharedInformerFactory;
17+
import io.kubernetes.client.spring.extended.network.annotation.KubernetesEndpointsLoadBalanced;
18+
import org.springframework.boot.CommandLineRunner;
19+
import org.springframework.boot.SpringApplication;
20+
import org.springframework.boot.autoconfigure.SpringBootApplication;
21+
import org.springframework.context.annotation.Bean;
22+
import org.springframework.context.annotation.Configuration;
23+
24+
@SpringBootApplication
25+
public class SpringLoadBalancerExample {
26+
27+
public static void main(String[] args) {
28+
SpringApplication.run(SpringLoadBalancerExample.class, args);
29+
}
30+
31+
@Configuration
32+
public static class AppConfig {
33+
34+
@Bean
35+
public CommandLineRunner loadBalancerCommandLineRunner(
36+
SharedInformerFactory sharedInformerFactory, MyService myService) {
37+
return args -> {
38+
System.out.println("starting informers..");
39+
sharedInformerFactory.startAllRegisteredInformers();
40+
41+
System.out.println("routing default/kubernetes:");
42+
System.out.println(myService.defaultKubernetesLoadBalancer.getTargetIP());
43+
};
44+
}
45+
46+
@Bean
47+
public MyService myService() {
48+
return new MyService();
49+
}
50+
}
51+
52+
public static class MyService {
53+
54+
@KubernetesEndpointsLoadBalanced(namespace = "default", name = "kubernetes")
55+
private LoadBalancer defaultKubernetesLoadBalancer;
56+
}
57+
}

extended/src/main/java/io/kubernetes/client/extended/network/EndpointsLoadBalancer.java

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
*/
1313
package io.kubernetes.client.extended.network;
1414

15+
import io.kubernetes.client.extended.network.exception.NoAvailableAddressException;
1516
import io.kubernetes.client.openapi.models.V1Endpoints;
1617
import java.util.List;
1718
import java.util.function.Supplier;
@@ -37,26 +38,50 @@ public EndpointsLoadBalancer(
3738
}
3839

3940
@Override
40-
public String getTargetIP() {
41+
public List<String> getAllAvailableIPs() throws NoAvailableAddressException {
4142
V1Endpoints ep = endpointsSupplier.get();
42-
List<String> availableIPs =
43-
ep.getSubsets().stream()
44-
.flatMap(subset -> subset.getAddresses().stream().map(addr -> addr.getIp()))
45-
.collect(Collectors.toList());
43+
if (ep == null || ep.getSubsets() == null) {
44+
throw new NoAvailableAddressException();
45+
}
46+
return ep.getSubsets().stream()
47+
.flatMap(subset -> subset.getAddresses().stream().map(addr -> addr.getIp()))
48+
.collect(Collectors.toList());
49+
}
50+
51+
@Override
52+
public List<String> getAllAvailableIPs(int port) throws NoAvailableAddressException {
53+
V1Endpoints ep = endpointsSupplier.get();
54+
if (ep == null || ep.getSubsets() == null) {
55+
throw new NoAvailableAddressException();
56+
}
57+
return ep.getSubsets().stream()
58+
.filter(
59+
subset ->
60+
subset.getPorts().stream()
61+
.anyMatch(epPort -> Integer.valueOf(port).equals(epPort.getPort())))
62+
.flatMap(subset -> subset.getAddresses().stream().map(addr -> addr.getIp()))
63+
.collect(Collectors.toList());
64+
}
65+
66+
@Override
67+
public String getTargetIP() throws NoAvailableAddressException {
68+
List<String> availableIPs = getAllAvailableIPs();
69+
if (availableIPs.size() == 0) {
70+
throw new NoAvailableAddressException();
71+
}
4672
return this.strategy.chooseIP(availableIPs);
4773
}
4874

4975
@Override
50-
public String getTargetIP(int port) {
76+
public String getTargetIP(int port) throws NoAvailableAddressException {
5177
V1Endpoints ep = endpointsSupplier.get();
52-
List<String> availableIPs =
53-
ep.getSubsets().stream()
54-
.filter(
55-
subset ->
56-
subset.getPorts().stream()
57-
.anyMatch(epPort -> Integer.valueOf(port).equals(epPort.getPort())))
58-
.flatMap(subset -> subset.getAddresses().stream().map(addr -> addr.getIp()))
59-
.collect(Collectors.toList());
78+
if (ep == null || ep.getSubsets() == null) {
79+
throw new NoAvailableAddressException();
80+
}
81+
List<String> availableIPs = getAllAvailableIPs(port);
82+
if (availableIPs.size() == 0) {
83+
throw new NoAvailableAddressException();
84+
}
6085
return this.strategy.chooseIP(availableIPs);
6186
}
6287
}

extended/src/main/java/io/kubernetes/client/extended/network/EndpointsUtils.java

Lines changed: 0 additions & 83 deletions
This file was deleted.

extended/src/main/java/io/kubernetes/client/extended/network/LoadBalancer.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,17 @@
1212
*/
1313
package io.kubernetes.client.extended.network;
1414

15+
import io.kubernetes.client.extended.network.exception.NoAvailableAddressException;
16+
import java.util.List;
17+
1518
/** LoadBalancer provides IP address for L4 client-side load-balancing. */
1619
public interface LoadBalancer {
1720

18-
String getTargetIP();
21+
List<String> getAllAvailableIPs() throws NoAvailableAddressException;
22+
23+
List<String> getAllAvailableIPs(int port) throws NoAvailableAddressException;
24+
25+
String getTargetIP() throws NoAvailableAddressException;
1926

20-
String getTargetIP(int port);
27+
String getTargetIP(int port) throws NoAvailableAddressException;
2128
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*
2+
Copyright 2020 The Kubernetes Authors.
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
http://www.apache.org/licenses/LICENSE-2.0
7+
Unless required by applicable law or agreed to in writing, software
8+
distributed under the License is distributed on an "AS IS" BASIS,
9+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
package io.kubernetes.client.extended.network.exception;
14+
15+
public class NoAvailableAddressException extends Exception {}

extended/src/test/java/io/kubernetes/client/extended/network/EndpointsLoadBalancerTests.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import static org.junit.Assert.*;
1616

17+
import io.kubernetes.client.extended.network.exception.NoAvailableAddressException;
1718
import io.kubernetes.client.openapi.models.V1EndpointAddress;
1819
import io.kubernetes.client.openapi.models.V1EndpointPort;
1920
import io.kubernetes.client.openapi.models.V1EndpointSubset;
@@ -56,7 +57,7 @@ public class EndpointsLoadBalancerTests {
5657
.addPortsItem(new V1EndpointPort().port(8082)));
5758

5859
@Test
59-
public void testGetTargetIP1() {
60+
public void testGetTargetIP1() throws NoAvailableAddressException {
6061
AtomicReference<List<String>> receivingAvailableIPs = new AtomicReference<>();
6162
EndpointsLoadBalancer endpointsLoadBalancer =
6263
new EndpointsLoadBalancer(
@@ -70,7 +71,7 @@ public void testGetTargetIP1() {
7071
}
7172

7273
@Test
73-
public void testGetTargetIP2() {
74+
public void testGetTargetIP2() throws NoAvailableAddressException {
7475
AtomicReference<List<String>> receivingAvailableIPs = new AtomicReference<>();
7576
EndpointsLoadBalancer endpointsLoadBalancer =
7677
new EndpointsLoadBalancer(
@@ -84,7 +85,7 @@ public void testGetTargetIP2() {
8485
}
8586

8687
@Test
87-
public void testGetTargetIP3() {
88+
public void testGetTargetIP3() throws NoAvailableAddressException {
8889
AtomicReference<List<String>> receivingAvailableIPs = new AtomicReference<>();
8990
EndpointsLoadBalancer endpointsLoadBalancer =
9091
new EndpointsLoadBalancer(

extended/src/test/java/io/kubernetes/client/extended/network/RoundRobinEndpointsLoadBalancerTests.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import static org.junit.Assert.*;
1616

17+
import io.kubernetes.client.extended.network.exception.NoAvailableAddressException;
1718
import io.kubernetes.client.openapi.models.V1EndpointAddress;
1819
import io.kubernetes.client.openapi.models.V1EndpointPort;
1920
import io.kubernetes.client.openapi.models.V1EndpointSubset;
@@ -81,14 +82,14 @@ public void testChooseChangingMultipleIPShouldWork() {
8182
}
8283

8384
@Test
84-
public void testEndpointLoadBalancing() {
85+
public void testEndpointLoadBalancing() throws NoAvailableAddressException {
8586
EndpointsLoadBalancer loadBalancer =
8687
new EndpointsLoadBalancer(() -> twoPortTwoHostEp, new RoundRobinLoadBalanceStrategy());
8788
assertEquals("127.0.0.1", loadBalancer.getTargetIP());
8889
assertEquals("127.0.0.2", loadBalancer.getTargetIP());
8990
assertEquals("127.0.0.1", loadBalancer.getTargetIP(8081));
9091
assertThrows(
91-
IllegalArgumentException.class,
92+
NoAvailableAddressException.class,
9293
() -> {
9394
loadBalancer.getTargetIP(9999);
9495
});

0 commit comments

Comments
 (0)