55import java .util .Map ;
66import java .util .function .Function ;
77
8+ import javax .net .ssl .TrustManagerFactory ;
9+
810import io .weaviate .client6 .v1 .internal .ObjectBuilder ;
911import io .weaviate .client6 .v1 .internal .TokenProvider ;
1012import io .weaviate .client6 .v1 .internal .grpc .GrpcChannelOptions ;
@@ -17,7 +19,8 @@ public record Config(
1719 String grpcHost ,
1820 int grpcPort ,
1921 Map <String , String > headers ,
20- TokenProvider tokenProvider ) {
22+ TokenProvider tokenProvider ,
23+ TrustManagerFactory trustManagerFactory ) {
2124
2225 public static Config of (Function <Custom , ObjectBuilder <Config >> fn ) {
2326 return fn .apply (new Custom ()).build ();
@@ -31,15 +34,16 @@ private Config(Builder<?> builder) {
3134 builder .grpcHost ,
3235 builder .grpcPort ,
3336 builder .headers ,
34- builder .tokenProvider );
37+ builder .tokenProvider ,
38+ builder .trustManagerFactory );
3539 }
3640
37- public RestTransportOptions restTransportOptions () {
38- return new RestTransportOptions (scheme , httpHost , httpPort , headers , tokenProvider );
41+ RestTransportOptions restTransportOptions () {
42+ return new RestTransportOptions (scheme , httpHost , httpPort , headers , tokenProvider , trustManagerFactory );
3943 }
4044
41- public GrpcChannelOptions grpcTransportOptions () {
42- return new GrpcChannelOptions (scheme , grpcHost , grpcPort , headers , tokenProvider );
45+ GrpcChannelOptions grpcTransportOptions () {
46+ return new GrpcChannelOptions (scheme , grpcHost , grpcPort , headers , tokenProvider , trustManagerFactory );
4347 }
4448
4549 private abstract static class Builder <SELF extends Builder <SELF >> implements ObjectBuilder <Config > {
@@ -50,20 +54,33 @@ private abstract static class Builder<SELF extends Builder<SELF>> implements Obj
5054 protected String grpcHost ;
5155 protected int grpcPort ;
5256 protected TokenProvider tokenProvider ;
57+ protected TrustManagerFactory trustManagerFactory ;
5358 protected Map <String , String > headers = new HashMap <>();
5459
60+ /**
61+ * Set URL scheme. Subclasses may increase the visibility of this method to
62+ * {@code public} if using a different scheme is allowed.
63+ */
5564 @ SuppressWarnings ("unchecked" )
5665 protected SELF scheme (String scheme ) {
5766 this .scheme = scheme ;
5867 return (SELF ) this ;
5968 }
6069
70+ /**
71+ * Set port for REST requests. Subclasses may increase the visibility of this
72+ * method to {@code public} if using a different port is allowed.
73+ */
6174 @ SuppressWarnings ("unchecked" )
6275 protected SELF httpHost (String httpHost ) {
6376 this .httpHost = trimScheme (httpHost );
6477 return (SELF ) this ;
6578 }
6679
80+ /**
81+ * Set port for gRPC requests. Subclasses may increase the visibility of this
82+ * method to {@code public} if using a different port is allowed.
83+ */
6784 @ SuppressWarnings ("unchecked" )
6885 protected SELF grpcHost (String grpcHost ) {
6986 this .grpcHost = trimScheme (grpcHost );
@@ -75,18 +92,41 @@ private String trimScheme(String url) {
7592 return url .replaceFirst ("^https?\\ /\\ /" , "" );
7693 }
7794
95+ /**
96+ * Provide a {@link TrustManagerFactory}. Subclasses which support
97+ * secure connection should expose this method.
98+ */
99+ @ SuppressWarnings ("unchecked" )
100+ protected SELF trustManagerFactory (TrustManagerFactory tmf ) {
101+ this .trustManagerFactory = tmf ;
102+ return (SELF ) this ;
103+ }
104+
105+ /**
106+ * Set a single request header. The client does not support header lists,
107+ * so there is no equivalent {@code addHeader} to append to existing header.
108+ * This will be applied both to REST and gRPC requests.
109+ */
78110 @ SuppressWarnings ("unchecked" )
79111 public SELF setHeader (String key , String value ) {
80112 this .headers .put (key , value );
81113 return (SELF ) this ;
82114 }
83115
116+ /**
117+ * Set multiple request headers.
118+ * This will be applied both to REST and gRPC requests.
119+ */
84120 @ SuppressWarnings ("unchecked" )
85121 public SELF setHeaders (Map <String , String > headers ) {
86- this .headers = Map .copyOf (headers );
122+ this .headers . putAll ( Map .copyOf (headers ) );
87123 return (SELF ) this ;
88124 }
89125
126+ /**
127+ * Weaviate will use the URL in this header to call Weaviate Embeddings
128+ * Service if an appropriate vectorizer is configured for collection.
129+ */
90130 private static final String HEADER_X_WEAVIATE_CLUSTER_URL = "X-Weaviate-Cluster-URL" ;
91131
92132 /**
@@ -102,13 +142,27 @@ private static boolean isWeaviateDomain(String host) {
102142
103143 @ Override
104144 public Config build () {
145+ // For clusters hosted on Weaviate Cloud, Weaviate Embedding Service
146+ // will be available under the same domain.
105147 if (isWeaviateDomain (httpHost ) && tokenProvider != null ) {
106148 setHeader (HEADER_X_WEAVIATE_CLUSTER_URL , "https://" + httpHost + ":" + httpPort );
107149 }
108150 return new Config (this );
109151 }
110152 }
111153
154+ /**
155+ * Configuration for Weaviate instances deployed locally.
156+ *
157+ * <p>
158+ * Has sane defaults that match standard Weaviate deployment configuration:
159+ * <ul>
160+ * <li>{@code scheme: http}</li>
161+ * <li>{@code host: localhost}</li>
162+ * <li>{@code httpPort: 8080}</li>
163+ * <li>{@code grpcPort: 50051}</li>
164+ * </ul>
165+ */
112166 public static class Local extends Builder <Local > {
113167 public Local () {
114168 scheme ("http" );
@@ -117,23 +171,37 @@ public Local() {
117171 grpcPort (50051 );
118172 }
119173
174+ /**
175+ * Set a different hostname.
176+ * This changes both {@code httpHost} and {@code grpcHost}.
177+ */
120178 public Local host (String host ) {
121179 httpHost (host );
122180 grpcHost (host );
123181 return this ;
124182 }
125183
184+ /** Override default HTTP port. */
126185 public Local httpPort (int port ) {
127186 this .httpPort = port ;
128187 return this ;
129188 }
130189
190+ /** Override default gRPC port. */
131191 public Local grpcPort (int port ) {
132192 this .grpcPort = port ;
133193 return this ;
134194 }
135195 }
136196
197+ /**
198+ * Configuration for instances hosted on Weaviate Cloud.
199+ * {@link WeaviateCloud} will create a secure client
200+ * with {@code schema: https} and {@code http-/grpcPort: 443}.
201+ *
202+ * Custom SSL certificates are suppored via
203+ * {@link #trustManagerFactory}.
204+ */
137205 public static class WeaviateCloud extends Builder <WeaviateCloud > {
138206 public WeaviateCloud (String httpHost , TokenProvider tokenProvider ) {
139207 this (URI .create (httpHost ), tokenProvider );
@@ -144,48 +212,108 @@ public WeaviateCloud(URI clusterUri, TokenProvider tokenProvider) {
144212 super .httpHost (clusterUri .getHost () != null
145213 ? clusterUri .getHost () // https://[example.com]/about
146214 : clusterUri .getPath ().split ("/" )[0 ]); // [example.com]/about
147- this .httpPort = 443 ;
148215 super .grpcHost ("grpc-" + this .httpHost );
216+ this .httpPort = 443 ;
149217 this .grpcPort = 443 ;
150218 this .tokenProvider = tokenProvider ;
151219 }
220+
221+ /**
222+ * Configure a custom TrustStore to validate third-party SSL certificates.
223+ *
224+ * <p>
225+ * Usage:
226+ *
227+ * <pre>{@code
228+ * // Create a TrustManagerFactory to validate custom certificates.
229+ * TrustManagerFactory tmf;
230+ * try (var keys = new FileInputStream("/path/to/custom/truststore.p12")) {
231+ * KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
232+ * trustStore.load(myKeys, "secret-password".toCharArra());
233+ *
234+ * tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
235+ * tmf.init(trustStore);
236+ * }
237+ *
238+ * // Pass it to wcd -> wcd.trustManagerFactory(tmf)
239+ * }</pre>
240+ */
241+ public WeaviateCloud trustManagerFactory (TrustManagerFactory tmf ) {
242+ return super .trustManagerFactory (tmf );
243+ }
152244 }
153245
246+ /** Configuration for custom Weaviate deployements. */
154247 public static class Custom extends Builder <Custom > {
155248 /**
156249 * Scheme controls which protocol will be used for the database connection.
157250 * REST and gRPC ports will be automatically inferred from it:
158251 * <strong>443</strong> for HTTPS connection and <strong>80</strong> for HTTP.
252+ *
253+ * These can be overriden with {@link #httpPort(int)} and
254+ * {@link #grpcPort(int)}.
159255 */
160256 public Custom scheme (String scheme ) {
161257 httpPort ("https" .equals (scheme ) ? 443 : 80 );
162258 grpcPort ("https" .equals (scheme ) ? 443 : 80 );
163259 return super .scheme (scheme );
164260 }
165261
262+ /** Set HTTP hostname. */
166263 public Custom httpHost (String httpHost ) {
167264 super .httpHost (httpHost );
168265 return this ;
169266 }
170267
268+ /** Set HTTP port. */
171269 public Custom httpPort (int port ) {
172270 this .httpPort = port ;
173271 return this ;
174272 }
175273
274+ /** Set gRPC hostname. */
176275 public Custom grpcHost (String grpcHost ) {
177276 super .grpcHost (grpcHost );
178277 return this ;
179278 }
180279
280+ /** Set gRPC port. */
181281 public Custom grpcPort (int port ) {
182282 this .grpcPort = port ;
183283 return this ;
184284 }
185285
286+ /**
287+ * Set authorization method. Setting this to {@code null} or omitting
288+ * will not use any authorization mechanism.
289+ */
186290 public Custom authorization (TokenProvider tokenProvider ) {
187291 this .tokenProvider = tokenProvider ;
188292 return this ;
189293 }
294+
295+ /**
296+ * Configure a custom TrustStore to validate third-party SSL certificates.
297+ *
298+ * <p>
299+ * Usage:
300+ *
301+ * <pre>{@code
302+ * // Create a TrustManagerFactory to validate custom certificates.
303+ * TrustManagerFactory tmf;
304+ * try (var keys = new FileInputStream("/path/to/custom/truststore.p12")) {
305+ * KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
306+ * trustStore.load(myKeys, "secret-password".toCharArra());
307+ *
308+ * tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
309+ * tmf.init(trustStore);
310+ * }
311+ *
312+ * // Pass it to custom -> custom.trustManagerFactory(tmf)
313+ * }</pre>
314+ */
315+ public Custom trustManagerFactory (TrustManagerFactory tmf ) {
316+ return super .trustManagerFactory (tmf );
317+ }
190318 }
191319}
0 commit comments