@@ -18,6 +18,7 @@ use rustler::{
18
18
} ;
19
19
use tokio:: sync:: { oneshot, Mutex , MutexGuard } ;
20
20
use tokio_stream:: StreamExt ;
21
+ use tonic:: transport:: { Certificate , ClientTlsConfig , Identity } ;
21
22
22
23
mod runtime;
23
24
@@ -40,6 +41,7 @@ rustler::atoms! {
40
41
eos, already_acked,
41
42
create_shard_reader_reply, read_shard_reply,
42
43
bad_hstream_record,
44
+ tls_config,
43
45
}
44
46
45
47
rustler:: init!(
@@ -56,6 +58,10 @@ rustler::init!(
56
58
async_ack,
57
59
async_create_shard_reader,
58
60
async_read_shard,
61
+ new_client_tls_config,
62
+ set_domain_name,
63
+ set_ca_certificate,
64
+ set_identity,
59
65
] ,
60
66
load = load
61
67
) ;
@@ -145,25 +151,61 @@ fn load(env: Env, _: Term) -> bool {
145
151
resource ! ( AppendResultFuture , env) ;
146
152
resource ! ( NifResponder , env) ;
147
153
resource ! ( NifShardReaderId , env) ;
154
+ resource ! ( NifClientTlsConfig , env) ;
148
155
env_logger:: init ( ) ;
149
156
true
150
157
}
151
158
152
159
#[ rustler:: nif]
153
- fn async_start_client ( pid : LocalPid , url : String , _conf : Term ) {
154
- let future = async move {
155
- let client = Client :: new ( url, ChannelProviderSettings :: builder ( ) . build ( ) ) . await ;
156
- OwnedEnv :: new ( ) . send_and_clear ( & pid, |env| match client {
157
- Ok ( client) => (
158
- start_client_reply ( ) ,
159
- ok ( ) ,
160
- ResourceArc :: new ( NifClient ( client) ) ,
161
- )
162
- . encode ( env) ,
163
- Err ( err) => ( start_client_reply ( ) , error ( ) , err. to_string ( ) ) . encode ( env) ,
164
- } )
165
- } ;
166
- runtime:: spawn ( future) ;
160
+ fn async_start_client < ' a > ( env : Env < ' a > , pid : LocalPid , url : String , options : Term ) -> Term < ' a > {
161
+ match from_start_client_options ( options) {
162
+ Err ( err) => ( error ( ) , ( badarg ( ) , err. to_string ( ) ) ) . encode ( env) ,
163
+ Ok ( channel_provider_settings) => {
164
+ let future = async move {
165
+ let client = Client :: new ( url, channel_provider_settings) . await ;
166
+ OwnedEnv :: new ( ) . send_and_clear ( & pid, |env| match client {
167
+ Ok ( client) => (
168
+ start_client_reply ( ) ,
169
+ ok ( ) ,
170
+ ResourceArc :: new ( NifClient ( client) ) ,
171
+ )
172
+ . encode ( env) ,
173
+ Err ( err) => ( start_client_reply ( ) , error ( ) , err. to_string ( ) ) . encode ( env) ,
174
+ } )
175
+ } ;
176
+ runtime:: spawn ( future) ;
177
+ ok ( ) . to_term ( env)
178
+ }
179
+ }
180
+ }
181
+
182
+ fn from_start_client_options ( proplists : Term ) -> hstreamdb:: Result < ChannelProviderSettings > {
183
+ let proplists = proplists
184
+ . into_list_iterator ( )
185
+ . map_err ( |err| hstreamdb:: Error :: BadArgument ( format ! ( "{err:?}" ) ) ) ?;
186
+
187
+ let mut channel_provider_settings = ChannelProviderSettings :: builder ( ) ;
188
+ for x in proplists {
189
+ if x. is_tuple ( ) {
190
+ let ( k, v) : ( Atom , Term ) = x
191
+ . decode ( )
192
+ . map_err ( |err| hstreamdb:: Error :: BadArgument ( format ! ( "{err:?}" ) ) ) ?;
193
+ if k == tls_config ( ) {
194
+ let v: ResourceArc < NifClientTlsConfig > = v
195
+ . decode ( )
196
+ . map_err ( |err| hstreamdb:: Error :: BadArgument ( format ! ( "{err:?}" ) ) ) ?;
197
+ let NifClientTlsConfig ( v) = ( * v) . clone ( ) ;
198
+ channel_provider_settings = channel_provider_settings. set_tls_config ( v)
199
+ } else if k == concurrency_limit ( ) {
200
+ let v: usize = v
201
+ . decode ( )
202
+ . map_err ( |err| hstreamdb:: Error :: BadArgument ( format ! ( "{err:?}" ) ) ) ?;
203
+ channel_provider_settings = channel_provider_settings. set_concurrency_limit ( v)
204
+ }
205
+ }
206
+ }
207
+
208
+ todo ! ( )
167
209
}
168
210
169
211
#[ rustler:: nif]
@@ -352,16 +394,14 @@ fn async_stop_producer(pid: LocalPid, producer: ResourceArc<NifAppender>) {
352
394
runtime:: spawn ( future) ;
353
395
}
354
396
355
- fn try_append < ' a > (
356
- env : Env < ' a > ,
397
+ # [ rustler :: nif ]
398
+ fn async_append (
357
399
pid : LocalPid ,
358
400
producer : ResourceArc < NifAppender > ,
359
401
partition_key : String ,
360
- raw_payload : Term ,
361
- ) -> Result < ( ) , Term < ' a > > {
362
- let raw_payload = rustler:: Binary :: from_term ( raw_payload)
363
- . map_err ( |err| ( badarg ( ) , format ! ( "{err:?}" ) ) . encode ( env) ) ?
364
- . to_vec ( ) ;
402
+ raw_payload : Binary ,
403
+ ) {
404
+ let raw_payload = raw_payload. to_vec ( ) ;
365
405
let future = async move {
366
406
let record = Record {
367
407
partition_key,
@@ -376,21 +416,6 @@ fn try_append<'a>(
376
416
}
377
417
} ;
378
418
runtime:: spawn ( future) ;
379
- Ok ( ( ) )
380
- }
381
-
382
- #[ rustler:: nif]
383
- fn async_append < ' a > (
384
- env : Env < ' a > ,
385
- pid : LocalPid ,
386
- producer : ResourceArc < NifAppender > ,
387
- partition_key : String ,
388
- raw_payload : Term ,
389
- ) -> Term < ' a > {
390
- match try_append ( env, pid, producer, partition_key, raw_payload) {
391
- Ok ( ( ) ) => ok ( ) . encode ( env) ,
392
- Err ( err) => ( error ( ) , err) . encode ( env) ,
393
- }
394
419
}
395
420
396
421
#[ rustler:: nif]
@@ -732,3 +757,44 @@ fn async_read_shard(
732
757
} ;
733
758
runtime:: spawn ( future) ;
734
759
}
760
+
761
+ #[ derive( Clone ) ]
762
+ struct NifClientTlsConfig ( ClientTlsConfig ) ;
763
+
764
+ #[ rustler:: nif]
765
+ fn new_client_tls_config ( ) -> ResourceArc < NifClientTlsConfig > {
766
+ ResourceArc :: new ( NifClientTlsConfig ( ClientTlsConfig :: new ( ) ) )
767
+ }
768
+
769
+ #[ rustler:: nif]
770
+ fn set_domain_name (
771
+ tls_config : ResourceArc < NifClientTlsConfig > ,
772
+ domain_name : String ,
773
+ ) -> ResourceArc < NifClientTlsConfig > {
774
+ let NifClientTlsConfig ( tls_config) = ( * tls_config) . clone ( ) ;
775
+ ResourceArc :: new ( NifClientTlsConfig ( tls_config. domain_name ( domain_name) ) )
776
+ }
777
+
778
+ #[ rustler:: nif]
779
+ fn set_ca_certificate (
780
+ tls_config : ResourceArc < NifClientTlsConfig > ,
781
+ ca_certificate : Binary ,
782
+ ) -> ResourceArc < NifClientTlsConfig > {
783
+ let NifClientTlsConfig ( tls_config) = ( * tls_config) . clone ( ) ;
784
+ ResourceArc :: new ( NifClientTlsConfig (
785
+ tls_config. ca_certificate ( Certificate :: from_pem ( ca_certificate. as_slice ( ) ) ) ,
786
+ ) )
787
+ }
788
+
789
+ #[ rustler:: nif]
790
+ fn set_identity (
791
+ tls_config : ResourceArc < NifClientTlsConfig > ,
792
+ cert : Binary ,
793
+ key : Binary ,
794
+ ) -> ResourceArc < NifClientTlsConfig > {
795
+ let NifClientTlsConfig ( tls_config) = & * tls_config;
796
+ let tls_config = tls_config. clone ( ) ;
797
+ ResourceArc :: new ( NifClientTlsConfig (
798
+ tls_config. identity ( Identity :: from_pem ( cert. as_slice ( ) , key. as_slice ( ) ) ) ,
799
+ ) )
800
+ }
0 commit comments