akhq icon indicating copy to clipboard operation
akhq copied to clipboard

Error when trying to use GitHub Oauth2 in dev branch

Open pavilalopes opened this issue 9 months ago • 4 comments

In the latest dev version, when trying to use Github SSO, the following error happens:

Internal Server Error: Could not resolve placeholder ${github.api.url}

Stack trace:

io.micronaut.context.exceptions.ConfigurationException: Could not resolve placeholder ${github.api.url}
  at io.micronaut.context.env.DefaultPropertyPlaceholderResolver$PlaceholderSegment.getValue(DefaultPropertyPlaceholderResolver.java:391)
  at io.micronaut.context.env.DefaultPropertyPlaceholderResolver.resolveRequiredPlaceholdersString(DefaultPropertyPlaceholderResolver.java:124)
  at io.micronaut.context.env.DefaultPropertyPlaceholderResolver.resolveRequiredPlaceholders(DefaultPropertyPlaceholderResolver.java:109)
  at io.micronaut.inject.annotation.AbstractEnvironmentAnnotationMetadata.lambda$getEnvironmentValueMapper$15(AbstractEnvironmentAnnotationMetadata.java:522)
  at io.micronaut.inject.annotation.DefaultAnnotationMetadata.getRawSingleValue(DefaultAnnotationMetadata.java:1539)
  at io.micronaut.inject.annotation.DefaultAnnotationMetadata.stringValue(DefaultAnnotationMetadata.java:732)
  at io.micronaut.inject.annotation.DefaultAnnotationMetadata.stringValue(DefaultAnnotationMetadata.java:654)
  at io.micronaut.inject.annotation.AnnotationMetadataHierarchy.stringValue(AnnotationMetadataHierarchy.java:881)
  at io.micronaut.inject.annotation.AbstractEnvironmentAnnotationMetadata.stringValue(AbstractEnvironmentAnnotationMetadata.java:216)
  at io.micronaut.inject.annotation.AnnotationMetadataHierarchy.stringValue(AnnotationMetadataHierarchy.java:883)
  at io.micronaut.inject.annotation.AbstractEnvironmentAnnotationMetadata.stringValue(AbstractEnvironmentAnnotationMetadata.java:216)
  at io.micronaut.core.annotation.AnnotationMetadata.stringValue(AnnotationMetadata.java:1140)
  at io.micronaut.http.client.netty.DefaultNettyHttpClientRegistry.getClientKey(DefaultNettyHttpClientRegistry.java:523)
  at io.micronaut.http.client.netty.DefaultNettyHttpClientRegistry.getClient(DefaultNettyHttpClientRegistry.java:192)
  at io.micronaut.http.client.netty.DefaultNettyHttpClientRegistry.getClient(DefaultNettyHttpClientRegistry.java:105)
  at io.micronaut.http.client.interceptor.HttpClientIntroductionAdvice.intercept(HttpClientIntroductionAdvice.java:162)
  at io.micronaut.aop.chain.MethodInterceptorChain.proceed(MethodInterceptorChain.java:138)
  at org.akhq.security.authentication.GithubApiClient$Intercepted.getUser(Unknown Source)
  at org.akhq.security.mapper.GithubAuthenticationMapper.createAuthenticationResponse(GithubAuthenticationMapper.java:40)
  at io.micronaut.security.oauth2.endpoint.authorization.response.DefaultOauthAuthorizationResponseHandler.lambda$handle$0(DefaultOauthAuthorizationResponseHandler.java:108)
  at reactor.core.publisher.FluxSwitchMapNoPrefetch$SwitchMapMain.subscribeInner(FluxSwitchMapNoPrefetch.java:210)
  at reactor.core.publisher.FluxSwitchMapNoPrefetch$SwitchMapMain.onNext(FluxSwitchMapNoPrefetch.java:164)
  at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:122)
  at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79)
  at reactor.core.publisher.SerializedSubscriber.onNext(SerializedSubscriber.java:99)
  at reactor.core.publisher.FluxTimeout$TimeoutMainSubscriber.onNext(FluxTimeout.java:181)
  at reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber.onNext(FluxContextWrite.java:107)
  at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:158)
  at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79)
  at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:122)
  at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:82)
  at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:82)
  at io.micronaut.core.async.propagation.ReactivePropagation$2.onNext(ReactivePropagation.java:106)
  at io.micronaut.configuration.metrics.binder.web.WebMetricsPublisher$1.onNext(WebMetricsPublisher.java:166)
  at io.micronaut.configuration.metrics.binder.web.WebMetricsPublisher$1.onNext(WebMetricsPublisher.java:151)
  at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:122)
  at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79)
  at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:122)
  at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:82)
  at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:82)
  at io.micronaut.core.async.propagation.ReactivePropagation$2.onNext(ReactivePropagation.java:106)
  at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:122)
  at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79)
  at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:122)
  at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:82)
  at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:82)
  at io.micronaut.core.async.propagation.ReactivePropagation$2.onNext(ReactivePropagation.java:106)
  at io.micronaut.http.client.filters.ClientServerRequestTracingPublisher$1.lambda$onNext$1(ClientServerRequestTracingPublisher.java:60)
  at io.micronaut.http.context.ServerRequestContext.with(ServerRequestContext.java:49)
  at io.micronaut.http.client.filters.ClientServerRequestTracingPublisher$1.onNext(ClientServerRequestTracingPublisher.java:60)
  at io.micronaut.http.client.filters.ClientServerRequestTracingPublisher$1.onNext(ClientServerRequestTracingPublisher.java:52)
  at reactor.core.publisher.StrictSubscriber.onNext(StrictSubscriber.java:89)
  at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:122)
  at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79)
  at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:122)
  at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:82)
  at reactor.core.publisher.MonoFlatMapMany$FlatMapManyInner.onNext(MonoFlatMapMany.java:251)
  at reactor.core.publisher.FluxCreate$BufferAsyncSink.drain(FluxCreate.java:880)
  at reactor.core.publisher.FluxCreate$BufferAsyncSink.next(FluxCreate.java:805)
  at reactor.core.publisher.FluxCreate$SerializedFluxSink.next(FluxCreate.java:163)
  at io.micronaut.http.client.netty.ForwardingSubscriber.onNext(ForwardingSubscriber.java:45)
  at io.micronaut.http.client.netty.NettyFuturePublisher$1.lambda$request$0(NettyFuturePublisher.java:54)
  at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:590)
  at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:557)
  at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:492)
  at io.netty.util.concurrent.DefaultPromise.setValue0(DefaultPromise.java:636)
  at io.netty.util.concurrent.DefaultPromise.setSuccess0(DefaultPromise.java:625)
  at io.netty.util.concurrent.DefaultPromise.trySuccess(DefaultPromise.java:105)
  at io.micronaut.http.client.netty.DefaultHttpClient$FullHttpResponseHandler.forwardResponseToPromise(DefaultHttpClient.java:2206)
  at io.micronaut.http.client.netty.DefaultHttpClient$FullHttpResponseHandler.channelReadInstrumented(DefaultHttpClient.java:2179)
  at io.micronaut.http.client.netty.DefaultHttpClient$FullHttpResponseHandler.channelReadInstrumented(DefaultHttpClient.java:2147)
  at io.micronaut.http.client.netty.SimpleChannelInboundHandlerInstrumented.channelRead0(SimpleChannelInboundHandlerInstrumented.java:46)
  at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99)
  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.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
  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.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
  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.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
  at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111)
  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
  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.handler.codec.http2.AbstractHttp2StreamChannel$Http2ChannelUnsafe.doRead0(AbstractHttp2StreamChannel.java:971)
  at io.netty.handler.codec.http2.AbstractHttp2StreamChannel.fireChildRead(AbstractHttp2StreamChannel.java:600)
  at io.netty.handler.codec.http2.Http2MultiplexHandler.channelRead(Http2MultiplexHandler.java:195)
  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
  at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
  at io.netty.handler.codec.http2.Http2FrameCodec.onHttp2Frame(Http2FrameCodec.java:712)
  at io.netty.handler.codec.http2.Http2FrameCodec$FrameListener.onDataRead(Http2FrameCodec.java:651)
  at io.netty.handler.codec.http2.Http2FrameListenerDecorator.onDataRead(Http2FrameListenerDecorator.java:36)
  at io.netty.handler.codec.http2.Http2EmptyDataFrameListener.onDataRead(Http2EmptyDataFrameListener.java:49)
  at io.netty.handler.codec.http2.DefaultHttp2ConnectionDecoder$FrameReadListener.onDataRead(DefaultHttp2ConnectionDecoder.java:322)
  at io.netty.handler.codec.http2.DefaultHttp2FrameReader.readDataFrame(DefaultHttp2FrameReader.java:411)
  at io.netty.handler.codec.http2.DefaultHttp2FrameReader.processPayloadState(DefaultHttp2FrameReader.java:246)
  at io.netty.handler.codec.http2.DefaultHttp2FrameReader.readFrame(DefaultHttp2FrameReader.java:166)
  at io.netty.handler.codec.http2.DefaultHttp2ConnectionDecoder.decodeFrame(DefaultHttp2ConnectionDecoder.java:188)
  at io.netty.handler.codec.http2.DecoratingHttp2ConnectionDecoder.decodeFrame(DecoratingHttp2ConnectionDecoder.java:63)
  at io.netty.handler.codec.http2.Http2ConnectionHandler$FrameDecoder.decode(Http2ConnectionHandler.java:393)
  at io.netty.handler.codec.http2.Http2ConnectionHandler.decode(Http2ConnectionHandler.java:453)
  at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:530)
  at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:469)
  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.handler.ssl.SslHandler.unwrap(SslHandler.java:1475)
  at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1338)
  at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1387)
  at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:530)
  at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:469)
  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.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:93)
  at io.micronaut.http.client.netty.ResettableReadTimeoutHandler$NextInterceptor.channelRead(ResettableReadTimeoutHandler.java:92)
  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.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:289)
  at io.micronaut.http.client.netty.ResettableReadTimeoutHandler.channelRead(ResettableReadTimeoutHandler.java:64)
  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
  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)
  at java.base/java.lang.Thread.run(Unknown Source)

pavilalopes avatar May 10 '24 15:05 pavilalopes

@pavilalopes there is a missing information in the doc. Since #1613 the Github API URL is customizable. Try by adding the github.api.url properties in your application.yml

https://github.com/tchiotludo/akhq/blob/a9197f9f2adcaaea737a4c6ee97e66ae5289ca10/src/main/resources/application.yml#L71-L74

AlexisSouquiere avatar May 14 '24 06:05 AlexisSouquiere

Thanks for the reply.

Adding this to application.yml did not fix the error:

micronaut:
  # ... omitted ...
  http: 
    client: 
      github.api.url: https://api.github.com 

Setting the environment variable github.api.url (suggested in the linked PR) also does not fix the error. The linked PR also implies that github.api.url should have a default value anyway.

pavilalopes avatar May 14 '24 09:05 pavilalopes

I just tried on my side. The snippet I gave you to setup the github.api.url doesn't work. The client is expecting an environment variable github.api.url so you need to put it like this in the application.yml

micronaut:
# All your config...

github.api.url: https://api.github.com

Moreover I confirm that adding the following environment variable github.api.url=https://api.github.com also works.

Please try again to set the environment variable and try also the right application.yaml settings. Then, I will update sample config as well as the documentation

AlexisSouquiere avatar May 16 '24 06:05 AlexisSouquiere

Setting github.api.url: https://api.github.com at the root level of application.yml does indeed fix the error.

I went back to try the environment variable, and realized why it didn't work for me: it turns out "github.api.url" is not a valid variable name in the eyes of most tools. docker-compose just drops it silently (sigh...) and sh and bash both treat it as a syntax error. So while it may indeed work I was not able to test it.

Thanks for the help.

I'll leave the bug open in case you want to fix any of the issues that were found.

pavilalopes avatar May 16 '24 12:05 pavilalopes