@@ -156,6 +156,9 @@ public class SpiceClient implements AutoCloseable {
156156 private URI flightAddress ;
157157 private URI httpAddress ;
158158 private int maxRetries ;
159+ private String tlsClientCertFile ;
160+ private String tlsClientKeyFile ;
161+ private String tlsRootCertFile ;
159162 private FlightSqlClient flightClient ;
160163 private CredentialCallOption authCallOptions = null ;
161164 private BufferAllocator allocator ;
@@ -200,11 +203,24 @@ public static SpiceClientBuilder builder() throws URISyntaxException {
200203 */
201204 public SpiceClient (String appId , String apiKey , URI flightAddress , URI httpAddress , int maxRetries ,
202205 String userAgent , long memoryLimitMB ) {
206+ this (appId , apiKey , flightAddress , httpAddress , maxRetries , userAgent , memoryLimitMB , null , null );
207+ }
208+
209+ public SpiceClient (String appId , String apiKey , URI flightAddress , URI httpAddress , int maxRetries ,
210+ String userAgent , long memoryLimitMB , String tlsClientCertFile , String tlsClientKeyFile ) {
211+ this (appId , apiKey , flightAddress , httpAddress , maxRetries , userAgent , memoryLimitMB , tlsClientCertFile , tlsClientKeyFile , null );
212+ }
213+
214+ public SpiceClient (String appId , String apiKey , URI flightAddress , URI httpAddress , int maxRetries ,
215+ String userAgent , long memoryLimitMB , String tlsClientCertFile , String tlsClientKeyFile , String tlsRootCertFile ) {
203216 this .appId = appId ;
204217 this .apiKey = apiKey ;
205218 this .maxRetries = maxRetries ;
206219 this .httpAddress = httpAddress ;
207220 this .userAgent = userAgent ;
221+ this .tlsClientCertFile = tlsClientCertFile ;
222+ this .tlsClientKeyFile = tlsClientKeyFile ;
223+ this .tlsRootCertFile = tlsRootCertFile ;
208224
209225 // Arrow Flight requires URI to be grpc protocol, convert http/https for
210226 // convinience
@@ -274,8 +290,17 @@ private synchronized void buildFlightClient() {
274290 NettyChannelBuilder channelBuilder = NettyChannelBuilder .forTarget (target );
275291 if (useTls ) {
276292 try {
293+ var sslContextBuilder = GrpcSslContexts .forClient ();
294+ if (this .tlsClientCertFile != null && this .tlsClientKeyFile != null ) {
295+ sslContextBuilder .keyManager (
296+ new java .io .File (this .tlsClientCertFile ),
297+ new java .io .File (this .tlsClientKeyFile ));
298+ }
299+ if (this .tlsRootCertFile != null ) {
300+ sslContextBuilder .trustManager (new java .io .File (this .tlsRootCertFile ));
301+ }
277302 channelBuilder .useTransportSecurity ()
278- .sslContext (GrpcSslContexts . forClient () .build ());
303+ .sslContext (sslContextBuilder .build ());
279304 } catch (Exception e ) {
280305 throw new RuntimeException ("Failed to configure TLS for Flight client" , e );
281306 }
0 commit comments