-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add kubernetes service discovery (#32)
* Add service discovery * Fixed bug * Add order * Make ktlint happy * Remove invalid code * Modify ApplicationContextAware to SPI * Optimize code * Optimize code * Make ktlint happy * Optimize code * Optimize code Co-authored-by: wz <[email protected]>
- Loading branch information
Showing
14 changed files
with
214 additions
and
88 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 12 additions & 0 deletions
12
middleware/sisyphus-grpc-client-kubernetes/build.gradle.kts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
middleware | ||
|
||
plugins { | ||
`java-library` | ||
} | ||
|
||
description = "Middleware for grpc service discovery of kubernetes in Sisyphus Project" | ||
|
||
dependencies { | ||
api(project(":middleware:sisyphus-grpc-client")) | ||
implementation(Dependencies.kubeJavaClient) | ||
} |
49 changes: 49 additions & 0 deletions
49
...lin/com/bybutter/sisyphus/middleware/grpc/client/kubernetes/KubernetesClientRepository.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package com.bybutter.sisyphus.middleware.grpc.client.kubernetes | ||
|
||
import com.bybutter.sisyphus.middleware.grpc.ClientRepository | ||
import com.bybutter.sisyphus.protobuf.ProtoTypes | ||
import io.kubernetes.client.openapi.apis.CoreV1Api | ||
import io.kubernetes.client.util.Config | ||
import java.nio.charset.Charset | ||
import java.nio.file.Files | ||
import java.nio.file.Paths | ||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory | ||
import org.springframework.beans.factory.support.AbstractBeanDefinition | ||
import org.springframework.beans.factory.support.BeanDefinitionBuilder | ||
import org.springframework.core.env.Environment | ||
|
||
class KubernetesClientRepository : ClientRepository { | ||
|
||
override var order: Int = Int.MIN_VALUE + 2000 | ||
|
||
override fun listClientBeanDefinition(beanFactory: ConfigurableListableBeanFactory, environment: Environment): List<AbstractBeanDefinition> { | ||
val api = try { | ||
CoreV1Api(Config.fromCluster()) | ||
} catch (e: IllegalStateException) { | ||
throw IllegalStateException("Get config fail: $e, maybe not in k8s.") | ||
} catch (e: NullPointerException) { | ||
throw e | ||
} | ||
val path = Paths.get(Config.SERVICEACCOUNT_ROOT, "namespace") | ||
if (!Files.exists(path)) { | ||
throw IllegalStateException("can not find ${path.fileName}.") | ||
} | ||
val namespace = String(Files.readAllBytes(path), Charset.defaultCharset()) | ||
val beanDefinitionList = arrayListOf<AbstractBeanDefinition>() | ||
val registerServiceNames = ProtoTypes.getRegisteredServiceNames() | ||
for (serviceName in registerServiceNames) { | ||
val list = api.listNamespacedService(namespace, null, null, null, null, serviceName, null, null, null, null) | ||
val channel = list.items[0].spec?.ports?.get(0)?.port?.let { | ||
createGrpcChannel(serviceName, it) | ||
} ?: continue | ||
val service = ProtoTypes.getRegisterService(serviceName) ?: throw IllegalStateException("Grpc service not be found.") | ||
val client = getClientFromService(service) | ||
val stub = getStubFromService(service) | ||
val clientBeanDefinition = BeanDefinitionBuilder.genericBeanDefinition(client as Class<Any>) { | ||
processStub(createGrpcClient(stub, channel), beanFactory) | ||
} | ||
beanDefinitionList.add(clientBeanDefinition.beanDefinition) | ||
} | ||
return beanDefinitionList | ||
} | ||
} |
1 change: 1 addition & 0 deletions
1
...c/main/resources/META-INF/services/com.bybutter.sisyphus.middleware.grpc.ClientRepository
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
com.bybutter.sisyphus.middleware.grpc.client.kubernetes.KubernetesClientRepository |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
59 changes: 59 additions & 0 deletions
59
...hus-grpc-client/src/main/kotlin/com/bybutter/sisyphus/middleware/grpc/ClientRepository.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package com.bybutter.sisyphus.middleware.grpc | ||
|
||
import io.grpc.CallOptions | ||
import io.grpc.Channel | ||
import io.grpc.ClientInterceptor | ||
import io.grpc.ManagedChannelBuilder | ||
import io.grpc.stub.AbstractStub | ||
import kotlin.reflect.full.companionObject | ||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory | ||
import org.springframework.beans.factory.support.AbstractBeanDefinition | ||
import org.springframework.core.env.Environment | ||
|
||
interface ClientRepository { | ||
|
||
var order: Int | ||
|
||
fun listClientBeanDefinition(beanFactory: ConfigurableListableBeanFactory, environment: Environment): List<AbstractBeanDefinition> | ||
|
||
fun getStubFromService(service: Class<*>): Class<*> { | ||
return service.kotlin.companionObject?.java?.classes?.firstOrNull { | ||
it.simpleName == "Stub" | ||
} ?: throw IllegalStateException("Grpc service must have stub class in companion.") | ||
} | ||
|
||
fun getClientFromService(service: Class<*>): Class<*> { | ||
return service.declaredClasses.firstOrNull { it.simpleName == "Client" } | ||
?: throw IllegalStateException("Grpc service must have nested class named 'Client'.") | ||
} | ||
|
||
fun processStub(stub: AbstractStub<*>, beanFactory: ConfigurableListableBeanFactory): AbstractStub<*> { | ||
var result = stub | ||
|
||
val builderInterceptors = beanFactory.getBeansOfType(ClientBuilderInterceptor::class.java) | ||
for ((_, builderInterceptor) in builderInterceptors) { | ||
result = builderInterceptor.intercept(result) | ||
} | ||
|
||
val interceptors = beanFactory.getBeansOfType(ClientInterceptor::class.java) | ||
return result.withInterceptors(*interceptors.values.toTypedArray()) | ||
} | ||
|
||
fun createGrpcChannel(property: GrpcChannelProperty): Channel { | ||
return ManagedChannelBuilder.forTarget(property.target).usePlaintext().userAgent("Generated by Sisyphus").build() | ||
} | ||
|
||
fun createGrpcChannel(name: String, port: Int): Channel { | ||
return ManagedChannelBuilder.forAddress(name, port).usePlaintext().userAgent("Generated by Sisyphus").build() | ||
} | ||
|
||
fun createGrpcClient(target: Class<*>, channel: Channel, property: GrpcChannelProperty): AbstractStub<*> { | ||
return target.getDeclaredConstructor(Channel::class.java, CallOptions::class.java) | ||
.newInstance(channel, property.options) as AbstractStub<*> | ||
} | ||
|
||
fun createGrpcClient(target: Class<*>, channel: Channel): AbstractStub<*> { | ||
return target.getDeclaredConstructor(Channel::class.java, CallOptions::class.java) | ||
.newInstance(channel, CallOptions.DEFAULT) as AbstractStub<*> | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
...rpc-client/src/main/kotlin/com/bybutter/sisyphus/middleware/grpc/LocalClientRepository.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package com.bybutter.sisyphus.middleware.grpc | ||
|
||
import com.bybutter.sisyphus.rpc.GrpcServerConstants | ||
import com.bybutter.sisyphus.rpc.RpcService | ||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory | ||
import org.springframework.beans.factory.support.AbstractBeanDefinition | ||
import org.springframework.beans.factory.support.BeanDefinitionBuilder | ||
import org.springframework.core.annotation.AnnotationUtils | ||
import org.springframework.core.env.Environment | ||
|
||
class LocalClientRepository : ClientRepository { | ||
|
||
override var order: Int = Int.MIN_VALUE + 1000 | ||
|
||
override fun listClientBeanDefinition(beanFactory: ConfigurableListableBeanFactory, environment: Environment): List<AbstractBeanDefinition> { | ||
val localPort = environment.getProperty(GrpcServerConstants.GRPC_PORT_PROPERTY, Int::class.java, GrpcServerConstants.DEFAULT_GRPC_PORT) | ||
val localChannel = createGrpcChannel("localhost", localPort) | ||
val beanDefinitionList = arrayListOf<AbstractBeanDefinition>() | ||
for (serviceName in beanFactory.getBeanNamesForAnnotation(RpcServiceImpl::class.java)) { | ||
val serviceBeanDefinition = beanFactory.getBeanDefinition(serviceName) | ||
val serviceClass = Class.forName(serviceBeanDefinition.beanClassName) | ||
val rpcService = AnnotationUtils.findAnnotation(serviceClass, RpcService::class.java) ?: continue | ||
val service = rpcService.client.java.declaringClass | ||
val stub = getStubFromService(service) | ||
val clientBeanDefinition = BeanDefinitionBuilder.genericBeanDefinition(rpcService.client.java as Class<Any>) { | ||
processStub(createGrpcClient(stub, localChannel), beanFactory) | ||
} | ||
beanDefinitionList.add(clientBeanDefinition.beanDefinition) | ||
} | ||
return beanDefinitionList | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
...pc-client/src/main/kotlin/com/bybutter/sisyphus/middleware/grpc/RemoteClientRepository.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package com.bybutter.sisyphus.middleware.grpc | ||
|
||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory | ||
import org.springframework.beans.factory.getBeansOfType | ||
import org.springframework.beans.factory.support.AbstractBeanDefinition | ||
import org.springframework.beans.factory.support.BeanDefinitionBuilder | ||
import org.springframework.core.env.Environment | ||
|
||
class RemoteClientRepository : ClientRepository { | ||
|
||
override var order: Int = Int.MAX_VALUE - 1000 | ||
|
||
override fun listClientBeanDefinition(beanFactory: ConfigurableListableBeanFactory, environment: Environment): List<AbstractBeanDefinition> { | ||
val properties = beanFactory.getBeansOfType<GrpcChannelProperty>() | ||
if (properties.isEmpty()) return arrayListOf() | ||
val beanDefinitionList = arrayListOf<AbstractBeanDefinition>() | ||
for (property in properties.values) { | ||
val channel = createGrpcChannel(property) | ||
beanFactory.registerSingleton(property.name, channel) | ||
for (service in property.services) { | ||
val client = getClientFromService(service) | ||
val stub = getStubFromService(service) | ||
val clientBeanDefinition = BeanDefinitionBuilder.genericBeanDefinition(client as Class<Any>) { | ||
processStub(createGrpcClient(stub, channel, property), beanFactory) | ||
} | ||
beanDefinitionList.add(clientBeanDefinition.beanDefinition) | ||
} | ||
} | ||
return beanDefinitionList | ||
} | ||
} |
2 changes: 2 additions & 0 deletions
2
...c/main/resources/META-INF/services/com.bybutter.sisyphus.middleware.grpc.ClientRepository
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
com.bybutter.sisyphus.middleware.grpc.LocalClientRepository | ||
com.bybutter.sisyphus.middleware.grpc.RemoteClientRepository |
Oops, something went wrong.