How to use Arrow Flight to connect to Dremio

In the Release Note, Dremio 4.9.1 support Arrow Flight already. But I did not find the official approach to connect in Java. Do you have any guide or sample code? We hope to use this with better performance instread of JDBC.

Dremio 4.9.1 offers a new Arrow Flight endpoint for Arrow Flight connections. The feature is enabled by default on port 32010. Arrow Flight enables high speed data transfer compared to ODBC/JDBC connections by utilizing the Apache Arrow format to avoid serializing and deserializing data.

Dremio provides sample Flight client applications at Dremio Hub. See the Arrow Flight documentation for more information about Arrow Flight.

I am trying to use https://github.com/keeratsingh/arrow-flight-client-examples/tree/add-java-sample-app to connect. But report the error below. Do you have any idea how to fix?

I am using the keystore, which is imported with HTTPS cert. I am wonderring if it cause this error. Or any config need to change on Dremio side

org.apache.arrow.flight.FlightRuntimeException: UNAVAILABLE: io exception
Channel Pipeline: [SslHandler#0, ProtocolNegotiators$ClientTlsHandler#0, WriteBufferingAndExceptionHandler#0, DefaultChannelPipeline$TailContext#0]

	at org.apache.arrow.flight.CallStatus.toRuntimeException(CallStatus.java:131)
	at org.apache.arrow.flight.grpc.StatusUtils.fromGrpcRuntimeException(StatusUtils.java:152)
	at org.apache.arrow.flight.grpc.StatusUtils.fromThrowable(StatusUtils.java:176)
	at org.apache.arrow.flight.auth2.ClientHandshakeWrapper.doClientHandshake(ClientHandshakeWrapper.java:59)
	at org.apache.arrow.flight.FlightClient.handshake(FlightClient.java:210)
	at com.adhoc.flight.client.AdhocFlightClient.authenticate(AdhocFlightClient.java:141)
	at com.adhoc.flight.client.AdhocFlightClient.getEncryptedClient(AdhocFlightClient.java:86)
	at com.adhoc.flight.TestSitFlightClient.createSSLFlightClient(TestSitFlightClient.java:107)
	at com.adhoc.flight.TestSitFlightClient.testSitQuery(TestSitFlightClient.java:114)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
	at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
	at org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:258)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
Caused by: io.netty.handler.ssl.NotSslRecordException: not an SSL/TLS record: 00001204000000000000037fffffff000400100000000600002000000004080000000000000f0001
	at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1214)
	at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1282)
	at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:498)
	at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:437)
	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.lang.Thread.run(Thread.java:745)

@popejune,

You might try the client examples on Dremio Hub: https://github.com/dremio-hub/arrow-flight-client-examples

Also, it sounds like you would have to enable SSL for the flight service. You can do this via dremio.conf. You can find a reference configuration here: https://github.com/dremio/dremio-oss/blob/ed4d6b6c0e492c9e8fdb42d0d846f66c6b469535/common/src/main/resources/dremio-reference.conf#L201

Hi @ben,

I disabled the SSL in flight part. The dremio service.log report the error below. I am using the correct user/password (could login dremio portal). Do you have any idea?

2020-12-18 05:41:04,958 [flight-server-default-executor-2] ERROR c.d.s.f.a.DremioFlightServerAuthValidator - Unable to authenticate user
com.dremio.service.users.UserLoginException: User doesn't exist, user
        at com.dremio.service.usergroup.PATService.authenticate(PATService.java:81)
        at com.dremio.service.flight.auth.DremioFlightServerAuthValidator.getToken(DremioFlightServerAuthValidator.java:59)
        at org.apache.arrow.flight.auth.BasicServerAuthHandler.authenticate(BasicServerAuthHandler.java:58)
        at org.apache.arrow.flight.auth.ServerAuthWrapper.lambda$wrapHandshake$0(ServerAuthWrapper.java:58)
        at io.grpc.Context$1.run(Context.java:605)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)