micronaut-projects / micronaut-discovery-client

Micronaut's Discovery Client
Apache License 2.0
22 stars 20 forks source link

Microanut service registration for consul client will resutle in a failure even if the service is registered #525

Closed krickert closed 1 year ago

krickert commented 1 year ago

Expected Behavior

I followed the directions on how to get a consul client, but I'm getting an exception:

Caused by: io.micronaut.http.client.exceptions.HttpClientResponseException: Client 'consul': Error decoding HTTP response body: No bean introspection available for type [class java.net.InetAddress]. Ensure the class is annotated with io.micronaut.core.annotation.Introspected
    at io.micronaut.http.client.netty.DefaultHttpClient$FullHttpResponseHandler.makeNormalBodyParseError(DefaultHttpClient.java:2254)
    at io.micronaut.http.client.netty.DefaultHttpClient$FullHttpResponseHandler.forwardResponseToPromise(DefaultHttpClient.java:2184)

I'm almost positive this is related to #524 and #517 -

Actual Behaviour

InetAddress bean injection failure with exception above

Steps To Reproduce

  1. setup consul client for grpc
  2. inject the stub
  3. make a call
  4. client fiails but service discovery does return a non-null client object

Environment Information

No response

Example Application

No response

Version

mn -V: Micronaut Version: 4.1.3

sdelamo commented 1 year ago

do you have a sample application?

krickert commented 1 year ago

I do, but I'm trying to make it a separate project so it's not dependent on a lot of cruft.

The main idea is that the registration part works per the #517 instructions but if I try a consul client, it does not work. Give me about an hour, I think I can give you an example. But everything I've tried so far to make a consul client work has resulted in a different exception.

Right now I'm just following the grpc demo tutorial to re-create the example. Since it'll need to have a running consul application and a test dependent on a running consul, it'll take me a second.

krickert commented 1 year ago

consul client failure

This one isn't giving the same error. I'm trying to recreate from scratch. I think I followed the direcitons right on here.

The test goes as follows: 1) Creates grpc server on a random port, registers successfully with consul 2) test attempts doesn't communicate with consul for client discovery (see Clients.java) -

The client returns, but when executing it's not using the client consul discovery.

krickert commented 1 year ago

So I'm testing with the latest SNAPSHOT version - and still not able to get a consul client. Maybe I have a missing dependency. Is there any sample project that exists that successfully grabs a consul client? No matter what I try, it doesn't work. So I'm not sure if I just set it up wrong or what to do.

krickert commented 1 year ago

I tested with the latest SNAPSHOT version and the service registration works with the original dependencies. Now when I try to send a payload, it looks like it expects SSL to be turned on:

Caused by: io.netty.handler.ssl.NotSslRecordException: not an SSL/TLS record: 00001204000000000000037fffffff000400100000000600002000000004080000000000000f0001
    at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1313)
    at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1383)
    at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:529)
    at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:468)
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:290)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562)
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    ... 1 common frames omitted

I'm assuming this is now a confugiration issue. Are there instructions to setup SSL or disable it?

krickert commented 1 year ago

OK - validated and got it to work on the latest snapshot. Works as it is designed! Thanks!

sdelamo commented 1 year ago

can you try with Micronaut Framework 4.1.4? Does it work for you without pinning any snapshots?

krickert commented 1 year ago

Tried it. Still works. Is there a way I can programatically get the client? I see that we put the channel name in the annotation - is there a way to create the same bean without the annotation?

So instead of this:

    @Singleton
    @Bean
    @Named("vectorizer")
    PipeServiceGrpc.PipeServiceStub vectorizorPipeServiceStub(
            @GrpcChannel("vectorizer") ManagedChannel channel) {
        return PipeServiceGrpc.newStub(channel);
    }

Is there something like:

@Inject
GreeterGrpcStub buildStub(ConsulManagedGrpcClientFactory cf, String serviceaName) {
      ManagedChannel grpc = cf.getServiceChannel(serviceName);
      return GreeterGrpc.newStub(
                grpc);
}

Of course, I know there's no ConsulManagedGrpcClientFactory, but I could really find one handy to use.

I have multiple versions of the same service that I would run in the same JVM. I would like to have the service names in the configuration and dynamically create the clients at anytime. I figured since the annotation does inject the channel, there might be a way to accomplish the getting a managed channel from Consul but by only passing in the service name? Can you nudge me in the right direction to accomplish this?