Skip to main content

ri/java/classes/
gateway.rs

1//! Copyright © 2025-2026 Wenze Wei. All Rights Reserved.
2//!
3//! This file is part of Ri.
4//! The Ri project belongs to the Dunimd Team.
5//!
6//! Licensed under the Apache License, Version 2.0 (the "License");
7//! You may not use this file except in compliance with the License.
8//! You may obtain a copy of the License at
9//!
10//!     http://www.apache.org/licenses/LICENSE-2.0
11//!
12//! Unless required by applicable law or agreed to in writing, software
13//! distributed under the License is distributed on an "AS IS" BASIS,
14//! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15//! See the License for the specific language governing permissions and
16//! limitations under the License.
17
18//! # Gateway Module JNI Bindings
19//!
20//! JNI bindings for Ri gateway classes.
21
22use crate::gateway::{
23    RiBackendServer, RiCircuitBreaker, RiCircuitBreakerConfig, RiCircuitBreakerMetrics,
24    RiCircuitBreakerState, RiGateway, RiGatewayConfig, RiLoadBalancer, RiLoadBalancerServerStats,
25    RiLoadBalancerStrategy, RiRateLimitConfig, RiRateLimitStats, RiRateLimiter, RiRoute, RiRouter,
26    RiSlidingWindowRateLimiter,
27};
28use jni::objects::{JClass, JString};
29use jni::sys::{jboolean, jdouble, jint, jlong, jstring};
30use jni::JNIEnv;
31
32// ============================================================================
33// RiGateway
34// ============================================================================
35
36#[no_mangle]
37pub extern "system" fn Java_com_dunimd_ri_gateway_RiGateway_new0(
38    _env: JNIEnv,
39    _class: JClass,
40) -> jlong {
41    let gateway = Box::new(RiGateway::new());
42    Box::into_raw(gateway) as jlong
43}
44
45#[no_mangle]
46pub extern "system" fn Java_com_dunimd_ri_gateway_RiGateway_free0(
47    _env: JNIEnv,
48    _class: JClass,
49    ptr: jlong,
50) {
51    if ptr != 0 {
52        unsafe {
53            let _ = Box::from_raw(ptr as *mut RiGateway);
54        }
55    }
56}
57
58// ============================================================================
59// RiGatewayConfig
60// ============================================================================
61
62#[no_mangle]
63pub extern "system" fn Java_com_dunimd_ri_gateway_RiGatewayConfig_new0(
64    _env: JNIEnv,
65    _class: JClass,
66) -> jlong {
67    let config = Box::new(RiGatewayConfig::default());
68    Box::into_raw(config) as jlong
69}
70
71#[no_mangle]
72pub extern "system" fn Java_com_dunimd_ri_gateway_RiGatewayConfig_free0(
73    _env: JNIEnv,
74    _class: JClass,
75    ptr: jlong,
76) {
77    if ptr != 0 {
78        unsafe {
79            let _ = Box::from_raw(ptr as *mut RiGatewayConfig);
80        }
81    }
82}
83
84// ============================================================================
85// RiRouter
86// ============================================================================
87
88#[no_mangle]
89pub extern "system" fn Java_com_dunimd_ri_gateway_RiRouter_new0(
90    _env: JNIEnv,
91    _class: JClass,
92) -> jlong {
93    let router = Box::new(RiRouter::new());
94    Box::into_raw(router) as jlong
95}
96
97#[no_mangle]
98pub extern "system" fn Java_com_dunimd_ri_gateway_RiRouter_free0(
99    _env: JNIEnv,
100    _class: JClass,
101    ptr: jlong,
102) {
103    if ptr != 0 {
104        unsafe {
105            let _ = Box::from_raw(ptr as *mut RiRouter);
106        }
107    }
108}
109
110#[no_mangle]
111pub extern "system" fn Java_com_dunimd_ri_gateway_RiRouter_addRoute0(
112    _env: JNIEnv,
113    _class: JClass,
114    ptr: jlong,
115    route_ptr: jlong,
116) {
117    if ptr != 0 && route_ptr != 0 {
118        unsafe {
119            let router = &*(ptr as *const RiRouter);
120            let route = Box::from_raw(route_ptr as *mut RiRoute);
121            router.add_route(*route);
122        }
123    }
124}
125
126#[no_mangle]
127pub extern "system" fn Java_com_dunimd_ri_gateway_RiRouter_addGetRoute0(
128    env: JNIEnv,
129    _class: JClass,
130    ptr: jlong,
131    path: JString,
132) {
133    if ptr != 0 {
134        let path_str: String = env.get_string(&path).expect("Invalid path string").into();
135        unsafe {
136            let router = &*(ptr as *const RiRouter);
137            let handler = std::sync::Arc::new(|_req| {
138                Box::pin(async move {
139                    Ok(crate::gateway::RiGatewayResponse::new(
140                        200,
141                        b"OK".to_vec(),
142                        String::new(),
143                    ))
144                })
145            });
146            router.get(&path_str, handler);
147        }
148    }
149}
150
151#[no_mangle]
152pub extern "system" fn Java_com_dunimd_ri_gateway_RiRouter_addPostRoute0(
153    env: JNIEnv,
154    _class: JClass,
155    ptr: jlong,
156    path: JString,
157) {
158    if ptr != 0 {
159        let path_str: String = env.get_string(&path).expect("Invalid path string").into();
160        unsafe {
161            let router = &*(ptr as *const RiRouter);
162            let handler = std::sync::Arc::new(|_req| {
163                Box::pin(async move {
164                    Ok(crate::gateway::RiGatewayResponse::new(
165                        200,
166                        b"OK".to_vec(),
167                        String::new(),
168                    ))
169                })
170            });
171            router.post(&path_str, handler);
172        }
173    }
174}
175
176#[no_mangle]
177pub extern "system" fn Java_com_dunimd_ri_gateway_RiRouter_addPutRoute0(
178    env: JNIEnv,
179    _class: JClass,
180    ptr: jlong,
181    path: JString,
182) {
183    if ptr != 0 {
184        let path_str: String = env.get_string(&path).expect("Invalid path string").into();
185        unsafe {
186            let router = &*(ptr as *const RiRouter);
187            let handler = std::sync::Arc::new(|_req| {
188                Box::pin(async move {
189                    Ok(crate::gateway::RiGatewayResponse::new(
190                        200,
191                        b"OK".to_vec(),
192                        String::new(),
193                    ))
194                })
195            });
196            router.put(&path_str, handler);
197        }
198    }
199}
200
201#[no_mangle]
202pub extern "system" fn Java_com_dunimd_ri_gateway_RiRouter_addDeleteRoute0(
203    env: JNIEnv,
204    _class: JClass,
205    ptr: jlong,
206    path: JString,
207) {
208    if ptr != 0 {
209        let path_str: String = env.get_string(&path).expect("Invalid path string").into();
210        unsafe {
211            let router = &*(ptr as *const RiRouter);
212            let handler = std::sync::Arc::new(|_req| {
213                Box::pin(async move {
214                    Ok(crate::gateway::RiGatewayResponse::new(
215                        200,
216                        b"OK".to_vec(),
217                        String::new(),
218                    ))
219                })
220            });
221            router.delete(&path_str, handler);
222        }
223    }
224}
225
226#[no_mangle]
227pub extern "system" fn Java_com_dunimd_ri_gateway_RiRouter_addPatchRoute0(
228    env: JNIEnv,
229    _class: JClass,
230    ptr: jlong,
231    path: JString,
232) {
233    if ptr != 0 {
234        let path_str: String = env.get_string(&path).expect("Invalid path string").into();
235        unsafe {
236            let router = &*(ptr as *const RiRouter);
237            let handler = std::sync::Arc::new(|_req| {
238                Box::pin(async move {
239                    Ok(crate::gateway::RiGatewayResponse::new(
240                        200,
241                        b"OK".to_vec(),
242                        String::new(),
243                    ))
244                })
245            });
246            router.patch(&path_str, handler);
247        }
248    }
249}
250
251#[no_mangle]
252pub extern "system" fn Java_com_dunimd_ri_gateway_RiRouter_addOptionsRoute0(
253    env: JNIEnv,
254    _class: JClass,
255    ptr: jlong,
256    path: JString,
257) {
258    if ptr != 0 {
259        let path_str: String = env.get_string(&path).expect("Invalid path string").into();
260        unsafe {
261            let router = &*(ptr as *const RiRouter);
262            let handler = std::sync::Arc::new(|_req| {
263                Box::pin(async move {
264                    Ok(crate::gateway::RiGatewayResponse::new(
265                        200,
266                        b"OK".to_vec(),
267                        String::new(),
268                    ))
269                })
270            });
271            router.options(&path_str, handler);
272        }
273    }
274}
275
276#[no_mangle]
277pub extern "system" fn Java_com_dunimd_ri_gateway_RiRouter_addCustomRoute0(
278    env: JNIEnv,
279    _class: JClass,
280    ptr: jlong,
281    method: JString,
282    path: JString,
283) {
284    if ptr != 0 {
285        let method_str: String = env
286            .get_string(&method)
287            .expect("Invalid method string")
288            .into();
289        let path_str: String = env.get_string(&path).expect("Invalid path string").into();
290        unsafe {
291            let router = &*(ptr as *const RiRouter);
292            let handler = std::sync::Arc::new(|_req| {
293                Box::pin(async move {
294                    Ok(crate::gateway::RiGatewayResponse::new(
295                        200,
296                        b"OK".to_vec(),
297                        String::new(),
298                    ))
299                })
300            });
301            let route = RiRoute::new(method_str, path_str, handler);
302            router.add_route(route);
303        }
304    }
305}
306
307#[no_mangle]
308pub extern "system" fn Java_com_dunimd_ri_gateway_RiRouter_getRouteCount0(
309    _env: JNIEnv,
310    _class: JClass,
311    ptr: jlong,
312) -> jint {
313    if ptr != 0 {
314        unsafe {
315            let router = &*(ptr as *const RiRouter);
316            router.route_count() as jint
317        }
318    } else {
319        0
320    }
321}
322
323#[no_mangle]
324pub extern "system" fn Java_com_dunimd_ri_gateway_RiRouter_clearRoutes0(
325    _env: JNIEnv,
326    _class: JClass,
327    ptr: jlong,
328) {
329    if ptr != 0 {
330        unsafe {
331            let router = &*(ptr as *const RiRouter);
332            router.clear_routes();
333        }
334    }
335}
336
337// ============================================================================
338// RiRoute
339// ============================================================================
340
341#[no_mangle]
342pub extern "system" fn Java_com_dunimd_ri_gateway_RiRoute_new0(
343    env: JNIEnv,
344    _class: JClass,
345    method: JString,
346    path: JString,
347) -> jlong {
348    let method_str: String = env
349        .get_string(&method)
350        .expect("Invalid method string")
351        .into();
352    let path_str: String = env.get_string(&path).expect("Invalid path string").into();
353
354    let handler = std::sync::Arc::new(|_req| {
355        Box::pin(async move {
356            Ok(crate::gateway::RiGatewayResponse::new(
357                200,
358                b"OK".to_vec(),
359                String::new(),
360            ))
361        })
362    });
363
364    let route = Box::new(RiRoute::new(method_str, path_str, handler));
365    Box::into_raw(route) as jlong
366}
367
368#[no_mangle]
369pub extern "system" fn Java_com_dunimd_ri_gateway_RiRoute_free0(
370    _env: JNIEnv,
371    _class: JClass,
372    ptr: jlong,
373) {
374    if ptr != 0 {
375        unsafe {
376            let _ = Box::from_raw(ptr as *mut RiRoute);
377        }
378    }
379}
380
381#[no_mangle]
382pub extern "system" fn Java_com_dunimd_ri_gateway_RiRoute_getMethod0(
383    env: JNIEnv,
384    _class: JClass,
385    ptr: jlong,
386) -> jstring {
387    if ptr != 0 {
388        unsafe {
389            let route = &*(ptr as *const RiRoute);
390            env.new_string(&route.method)
391                .expect("Failed to create string")
392                .into_raw()
393        }
394    } else {
395        std::ptr::null_mut()
396    }
397}
398
399#[no_mangle]
400pub extern "system" fn Java_com_dunimd_ri_gateway_RiRoute_getPath0(
401    env: JNIEnv,
402    _class: JClass,
403    ptr: jlong,
404) -> jstring {
405    if ptr != 0 {
406        unsafe {
407            let route = &*(ptr as *const RiRoute);
408            env.new_string(&route.path)
409                .expect("Failed to create string")
410                .into_raw()
411        }
412    } else {
413        std::ptr::null_mut()
414    }
415}
416
417// ============================================================================
418// RiRateLimitConfig
419// ============================================================================
420
421#[no_mangle]
422pub extern "system" fn Java_com_dunimd_ri_gateway_RiRateLimitConfig_new0(
423    _env: JNIEnv,
424    _class: JClass,
425) -> jlong {
426    let config = Box::new(RiRateLimitConfig::default());
427    Box::into_raw(config) as jlong
428}
429
430#[no_mangle]
431pub extern "system" fn Java_com_dunimd_ri_gateway_RiRateLimitConfig_newWithValues0(
432    _env: JNIEnv,
433    _class: JClass,
434    requests_per_second: jint,
435    burst_size: jint,
436    window_seconds: jlong,
437) -> jlong {
438    let config = Box::new(RiRateLimitConfig {
439        requests_per_second: requests_per_second as u32,
440        burst_size: burst_size as u32,
441        window_seconds: window_seconds as u64,
442    });
443    Box::into_raw(config) as jlong
444}
445
446#[no_mangle]
447pub extern "system" fn Java_com_dunimd_ri_gateway_RiRateLimitConfig_free0(
448    _env: JNIEnv,
449    _class: JClass,
450    ptr: jlong,
451) {
452    if ptr != 0 {
453        unsafe {
454            let _ = Box::from_raw(ptr as *mut RiRateLimitConfig);
455        }
456    }
457}
458
459#[no_mangle]
460pub extern "system" fn Java_com_dunimd_ri_gateway_RiRateLimitConfig_getRequestsPerSecond0(
461    _env: JNIEnv,
462    _class: JClass,
463    ptr: jlong,
464) -> jint {
465    if ptr != 0 {
466        unsafe {
467            let config = &*(ptr as *const RiRateLimitConfig);
468            config.requests_per_second as jint
469        }
470    } else {
471        0
472    }
473}
474
475#[no_mangle]
476pub extern "system" fn Java_com_dunimd_ri_gateway_RiRateLimitConfig_setRequestsPerSecond0(
477    _env: JNIEnv,
478    _class: JClass,
479    ptr: jlong,
480    value: jint,
481) {
482    if ptr != 0 {
483        unsafe {
484            let config = &mut *(ptr as *mut RiRateLimitConfig);
485            config.requests_per_second = value as u32;
486        }
487    }
488}
489
490#[no_mangle]
491pub extern "system" fn Java_com_dunimd_ri_gateway_RiRateLimitConfig_getBurstSize0(
492    _env: JNIEnv,
493    _class: JClass,
494    ptr: jlong,
495) -> jint {
496    if ptr != 0 {
497        unsafe {
498            let config = &*(ptr as *const RiRateLimitConfig);
499            config.burst_size as jint
500        }
501    } else {
502        0
503    }
504}
505
506#[no_mangle]
507pub extern "system" fn Java_com_dunimd_ri_gateway_RiRateLimitConfig_setBurstSize0(
508    _env: JNIEnv,
509    _class: JClass,
510    ptr: jlong,
511    value: jint,
512) {
513    if ptr != 0 {
514        unsafe {
515            let config = &mut *(ptr as *mut RiRateLimitConfig);
516            config.burst_size = value as u32;
517        }
518    }
519}
520
521#[no_mangle]
522pub extern "system" fn Java_com_dunimd_ri_gateway_RiRateLimitConfig_getWindowSeconds0(
523    _env: JNIEnv,
524    _class: JClass,
525    ptr: jlong,
526) -> jlong {
527    if ptr != 0 {
528        unsafe {
529            let config = &*(ptr as *const RiRateLimitConfig);
530            config.window_seconds as jlong
531        }
532    } else {
533        0
534    }
535}
536
537#[no_mangle]
538pub extern "system" fn Java_com_dunimd_ri_gateway_RiRateLimitConfig_setWindowSeconds0(
539    _env: JNIEnv,
540    _class: JClass,
541    ptr: jlong,
542    value: jlong,
543) {
544    if ptr != 0 {
545        unsafe {
546            let config = &mut *(ptr as *mut RiRateLimitConfig);
547            config.window_seconds = value as u64;
548        }
549    }
550}
551
552// ============================================================================
553// RiRateLimitStats
554// ============================================================================
555
556#[no_mangle]
557pub extern "system" fn Java_com_dunimd_ri_gateway_RiRateLimitStats_new0(
558    _env: JNIEnv,
559    _class: JClass,
560    current_tokens: jlong,
561    total_requests: jlong,
562) -> jlong {
563    let stats = Box::new(RiRateLimitStats {
564        current_tokens: current_tokens as usize,
565        total_requests: total_requests as usize,
566    });
567    Box::into_raw(stats) as jlong
568}
569
570#[no_mangle]
571pub extern "system" fn Java_com_dunimd_ri_gateway_RiRateLimitStats_free0(
572    _env: JNIEnv,
573    _class: JClass,
574    ptr: jlong,
575) {
576    if ptr != 0 {
577        unsafe {
578            let _ = Box::from_raw(ptr as *mut RiRateLimitStats);
579        }
580    }
581}
582
583#[no_mangle]
584pub extern "system" fn Java_com_dunimd_ri_gateway_RiRateLimitStats_getCurrentTokens0(
585    _env: JNIEnv,
586    _class: JClass,
587    ptr: jlong,
588) -> jlong {
589    if ptr != 0 {
590        unsafe {
591            let stats = &*(ptr as *const RiRateLimitStats);
592            stats.current_tokens as jlong
593        }
594    } else {
595        0
596    }
597}
598
599#[no_mangle]
600pub extern "system" fn Java_com_dunimd_ri_gateway_RiRateLimitStats_getTotalRequests0(
601    _env: JNIEnv,
602    _class: JClass,
603    ptr: jlong,
604) -> jlong {
605    if ptr != 0 {
606        unsafe {
607            let stats = &*(ptr as *const RiRateLimitStats);
608            stats.total_requests as jlong
609        }
610    } else {
611        0
612    }
613}
614
615// ============================================================================
616// RiRateLimiter
617// ============================================================================
618
619#[no_mangle]
620pub extern "system" fn Java_com_dunimd_ri_gateway_RiRateLimiter_new0(
621    _env: JNIEnv,
622    _class: JClass,
623    config_ptr: jlong,
624) -> jlong {
625    let config = if config_ptr != 0 {
626        unsafe { (*(config_ptr as *const RiRateLimitConfig)).clone() }
627    } else {
628        RiRateLimitConfig::default()
629    };
630    let limiter = Box::new(RiRateLimiter::new(config));
631    Box::into_raw(limiter) as jlong
632}
633
634#[no_mangle]
635pub extern "system" fn Java_com_dunimd_ri_gateway_RiRateLimiter_free0(
636    _env: JNIEnv,
637    _class: JClass,
638    ptr: jlong,
639) {
640    if ptr != 0 {
641        unsafe {
642            let _ = Box::from_raw(ptr as *mut RiRateLimiter);
643        }
644    }
645}
646
647#[no_mangle]
648pub extern "system" fn Java_com_dunimd_ri_gateway_RiRateLimiter_checkRateLimit0(
649    env: JNIEnv,
650    _class: JClass,
651    ptr: jlong,
652    key: JString,
653    tokens: jint,
654) -> jboolean {
655    if ptr != 0 {
656        let key_str: String = env.get_string(&key).expect("Invalid key string").into();
657        unsafe {
658            let limiter = &*(ptr as *const RiRateLimiter);
659            limiter.check_rate_limit(&key_str, tokens as usize) as jboolean
660        }
661    } else {
662        0
663    }
664}
665
666#[no_mangle]
667pub extern "system" fn Java_com_dunimd_ri_gateway_RiRateLimiter_getStats0(
668    env: JNIEnv,
669    _class: JClass,
670    ptr: jlong,
671    key: JString,
672) -> jlong {
673    if ptr != 0 {
674        let key_str: String = env.get_string(&key).expect("Invalid key string").into();
675        unsafe {
676            let limiter = &*(ptr as *const RiRateLimiter);
677            if let Some(stats) = limiter.get_stats(&key_str) {
678                Box::into_raw(Box::new(stats)) as jlong
679            } else {
680                0
681            }
682        }
683    } else {
684        0
685    }
686}
687
688#[no_mangle]
689pub extern "system" fn Java_com_dunimd_ri_gateway_RiRateLimiter_getRemaining0(
690    env: JNIEnv,
691    _class: JClass,
692    ptr: jlong,
693    key: JString,
694) -> jdouble {
695    if ptr != 0 {
696        let key_str: String = env.get_string(&key).expect("Invalid key string").into();
697        unsafe {
698            let limiter = &*(ptr as *const RiRateLimiter);
699            limiter.get_remaining(&key_str).unwrap_or(0.0)
700        }
701    } else {
702        0.0
703    }
704}
705
706#[no_mangle]
707pub extern "system" fn Java_com_dunimd_ri_gateway_RiRateLimiter_resetBucket0(
708    env: JNIEnv,
709    _class: JClass,
710    ptr: jlong,
711    key: JString,
712) {
713    if ptr != 0 {
714        let key_str: String = env.get_string(&key).expect("Invalid key string").into();
715        unsafe {
716            let limiter = &*(ptr as *const RiRateLimiter);
717            limiter.reset_bucket(&key_str);
718        }
719    }
720}
721
722#[no_mangle]
723pub extern "system" fn Java_com_dunimd_ri_gateway_RiRateLimiter_clearAllBuckets0(
724    _env: JNIEnv,
725    _class: JClass,
726    ptr: jlong,
727) {
728    if ptr != 0 {
729        unsafe {
730            let limiter = &*(ptr as *const RiRateLimiter);
731            limiter.clear_all_buckets();
732        }
733    }
734}
735
736#[no_mangle]
737pub extern "system" fn Java_com_dunimd_ri_gateway_RiRateLimiter_getConfig0(
738    _env: JNIEnv,
739    _class: JClass,
740    ptr: jlong,
741) -> jlong {
742    if ptr != 0 {
743        unsafe {
744            let limiter = &*(ptr as *const RiRateLimiter);
745            let config = limiter.get_config();
746            Box::into_raw(Box::new(config)) as jlong
747        }
748    } else {
749        0
750    }
751}
752
753#[no_mangle]
754pub extern "system" fn Java_com_dunimd_ri_gateway_RiRateLimiter_bucketCount0(
755    _env: JNIEnv,
756    _class: JClass,
757    ptr: jlong,
758) -> jint {
759    if ptr != 0 {
760        unsafe {
761            let limiter = &*(ptr as *const RiRateLimiter);
762            limiter.bucket_count() as jint
763        }
764    } else {
765        0
766    }
767}
768
769// ============================================================================
770// RiSlidingWindowRateLimiter
771// ============================================================================
772
773#[no_mangle]
774pub extern "system" fn Java_com_dunimd_ri_gateway_RiSlidingWindowRateLimiter_new0(
775    _env: JNIEnv,
776    _class: JClass,
777    max_requests: jint,
778    window_seconds: jlong,
779) -> jlong {
780    let limiter = Box::new(RiSlidingWindowRateLimiter::new(
781        max_requests as u32,
782        window_seconds as u64,
783    ));
784    Box::into_raw(limiter) as jlong
785}
786
787#[no_mangle]
788pub extern "system" fn Java_com_dunimd_ri_gateway_RiSlidingWindowRateLimiter_free0(
789    _env: JNIEnv,
790    _class: JClass,
791    ptr: jlong,
792) {
793    if ptr != 0 {
794        unsafe {
795            let _ = Box::from_raw(ptr as *mut RiSlidingWindowRateLimiter);
796        }
797    }
798}
799
800#[no_mangle]
801pub extern "system" fn Java_com_dunimd_ri_gateway_RiSlidingWindowRateLimiter_allowRequest0(
802    _env: JNIEnv,
803    _class: JClass,
804    ptr: jlong,
805) -> jboolean {
806    if ptr != 0 {
807        unsafe {
808            let limiter = &*(ptr as *const RiSlidingWindowRateLimiter);
809            limiter.allow_request() as jboolean
810        }
811    } else {
812        0
813    }
814}
815
816#[no_mangle]
817pub extern "system" fn Java_com_dunimd_ri_gateway_RiSlidingWindowRateLimiter_getCurrentCount0(
818    _env: JNIEnv,
819    _class: JClass,
820    ptr: jlong,
821) -> jint {
822    if ptr != 0 {
823        unsafe {
824            let limiter = &*(ptr as *const RiSlidingWindowRateLimiter);
825            limiter.get_current_count() as jint
826        }
827    } else {
828        0
829    }
830}
831
832#[no_mangle]
833pub extern "system" fn Java_com_dunimd_ri_gateway_RiSlidingWindowRateLimiter_reset0(
834    _env: JNIEnv,
835    _class: JClass,
836    ptr: jlong,
837) {
838    if ptr != 0 {
839        unsafe {
840            let limiter = &*(ptr as *const RiSlidingWindowRateLimiter);
841            limiter.reset();
842        }
843    }
844}
845
846#[no_mangle]
847pub extern "system" fn Java_com_dunimd_ri_gateway_RiSlidingWindowRateLimiter_getMaxRequests0(
848    _env: JNIEnv,
849    _class: JClass,
850    ptr: jlong,
851) -> jint {
852    if ptr != 0 {
853        unsafe {
854            let limiter = &*(ptr as *const RiSlidingWindowRateLimiter);
855            limiter.get_max_requests() as jint
856        }
857    } else {
858        0
859    }
860}
861
862#[no_mangle]
863pub extern "system" fn Java_com_dunimd_ri_gateway_RiSlidingWindowRateLimiter_getWindowSeconds0(
864    _env: JNIEnv,
865    _class: JClass,
866    ptr: jlong,
867) -> jlong {
868    if ptr != 0 {
869        unsafe {
870            let limiter = &*(ptr as *const RiSlidingWindowRateLimiter);
871            limiter.get_window_seconds() as jlong
872        }
873    } else {
874        0
875    }
876}
877
878// ============================================================================
879// RiCircuitBreakerConfig
880// ============================================================================
881
882#[no_mangle]
883pub extern "system" fn Java_com_dunimd_ri_gateway_RiCircuitBreakerConfig_new0(
884    _env: JNIEnv,
885    _class: JClass,
886) -> jlong {
887    let config = Box::new(RiCircuitBreakerConfig::default());
888    Box::into_raw(config) as jlong
889}
890
891#[no_mangle]
892pub extern "system" fn Java_com_dunimd_ri_gateway_RiCircuitBreakerConfig_newWithValues0(
893    _env: JNIEnv,
894    _class: JClass,
895    failure_threshold: jint,
896    success_threshold: jint,
897    timeout_seconds: jlong,
898    monitoring_period_seconds: jlong,
899) -> jlong {
900    let config = Box::new(RiCircuitBreakerConfig {
901        failure_threshold: failure_threshold as u32,
902        success_threshold: success_threshold as u32,
903        timeout_seconds: timeout_seconds as u64,
904        monitoring_period_seconds: monitoring_period_seconds as u64,
905    });
906    Box::into_raw(config) as jlong
907}
908
909#[no_mangle]
910pub extern "system" fn Java_com_dunimd_ri_gateway_RiCircuitBreakerConfig_free0(
911    _env: JNIEnv,
912    _class: JClass,
913    ptr: jlong,
914) {
915    if ptr != 0 {
916        unsafe {
917            let _ = Box::from_raw(ptr as *mut RiCircuitBreakerConfig);
918        }
919    }
920}
921
922#[no_mangle]
923pub extern "system" fn Java_com_dunimd_ri_gateway_RiCircuitBreakerConfig_getFailureThreshold0(
924    _env: JNIEnv,
925    _class: JClass,
926    ptr: jlong,
927) -> jint {
928    if ptr != 0 {
929        unsafe {
930            let config = &*(ptr as *const RiCircuitBreakerConfig);
931            config.failure_threshold as jint
932        }
933    } else {
934        0
935    }
936}
937
938#[no_mangle]
939pub extern "system" fn Java_com_dunimd_ri_gateway_RiCircuitBreakerConfig_setFailureThreshold0(
940    _env: JNIEnv,
941    _class: JClass,
942    ptr: jlong,
943    value: jint,
944) {
945    if ptr != 0 {
946        unsafe {
947            let config = &mut *(ptr as *mut RiCircuitBreakerConfig);
948            config.failure_threshold = value as u32;
949        }
950    }
951}
952
953#[no_mangle]
954pub extern "system" fn Java_com_dunimd_ri_gateway_RiCircuitBreakerConfig_getSuccessThreshold0(
955    _env: JNIEnv,
956    _class: JClass,
957    ptr: jlong,
958) -> jint {
959    if ptr != 0 {
960        unsafe {
961            let config = &*(ptr as *const RiCircuitBreakerConfig);
962            config.success_threshold as jint
963        }
964    } else {
965        0
966    }
967}
968
969#[no_mangle]
970pub extern "system" fn Java_com_dunimd_ri_gateway_RiCircuitBreakerConfig_setSuccessThreshold0(
971    _env: JNIEnv,
972    _class: JClass,
973    ptr: jlong,
974    value: jint,
975) {
976    if ptr != 0 {
977        unsafe {
978            let config = &mut *(ptr as *mut RiCircuitBreakerConfig);
979            config.success_threshold = value as u32;
980        }
981    }
982}
983
984#[no_mangle]
985pub extern "system" fn Java_com_dunimd_ri_gateway_RiCircuitBreakerConfig_getTimeoutSeconds0(
986    _env: JNIEnv,
987    _class: JClass,
988    ptr: jlong,
989) -> jlong {
990    if ptr != 0 {
991        unsafe {
992            let config = &*(ptr as *const RiCircuitBreakerConfig);
993            config.timeout_seconds as jlong
994        }
995    } else {
996        0
997    }
998}
999
1000#[no_mangle]
1001pub extern "system" fn Java_com_dunimd_ri_gateway_RiCircuitBreakerConfig_setTimeoutSeconds0(
1002    _env: JNIEnv,
1003    _class: JClass,
1004    ptr: jlong,
1005    value: jlong,
1006) {
1007    if ptr != 0 {
1008        unsafe {
1009            let config = &mut *(ptr as *mut RiCircuitBreakerConfig);
1010            config.timeout_seconds = value as u64;
1011        }
1012    }
1013}
1014
1015#[no_mangle]
1016pub extern "system" fn Java_com_dunimd_ri_gateway_RiCircuitBreakerConfig_getMonitoringPeriodSeconds0(
1017    _env: JNIEnv,
1018    _class: JClass,
1019    ptr: jlong,
1020) -> jlong {
1021    if ptr != 0 {
1022        unsafe {
1023            let config = &*(ptr as *const RiCircuitBreakerConfig);
1024            config.monitoring_period_seconds as jlong
1025        }
1026    } else {
1027        0
1028    }
1029}
1030
1031#[no_mangle]
1032pub extern "system" fn Java_com_dunimd_ri_gateway_RiCircuitBreakerConfig_setMonitoringPeriodSeconds0(
1033    _env: JNIEnv,
1034    _class: JClass,
1035    ptr: jlong,
1036    value: jlong,
1037) {
1038    if ptr != 0 {
1039        unsafe {
1040            let config = &mut *(ptr as *mut RiCircuitBreakerConfig);
1041            config.monitoring_period_seconds = value as u64;
1042        }
1043    }
1044}
1045
1046// ============================================================================
1047// RiCircuitBreakerMetrics
1048// ============================================================================
1049
1050#[no_mangle]
1051pub extern "system" fn Java_com_dunimd_ri_gateway_RiCircuitBreakerMetrics_new0(
1052    env: JNIEnv,
1053    _class: JClass,
1054    state: JString,
1055    failure_count: jlong,
1056    success_count: jlong,
1057    consecutive_failures: jlong,
1058    consecutive_successes: jlong,
1059) -> jlong {
1060    let state_str: String = env.get_string(&state).expect("Invalid state string").into();
1061    let metrics = Box::new(RiCircuitBreakerMetrics {
1062        state: state_str,
1063        failure_count: failure_count as usize,
1064        success_count: success_count as usize,
1065        consecutive_failures: consecutive_failures as usize,
1066        consecutive_successes: consecutive_successes as usize,
1067    });
1068    Box::into_raw(metrics) as jlong
1069}
1070
1071#[no_mangle]
1072pub extern "system" fn Java_com_dunimd_ri_gateway_RiCircuitBreakerMetrics_free0(
1073    _env: JNIEnv,
1074    _class: JClass,
1075    ptr: jlong,
1076) {
1077    if ptr != 0 {
1078        unsafe {
1079            let _ = Box::from_raw(ptr as *mut RiCircuitBreakerMetrics);
1080        }
1081    }
1082}
1083
1084#[no_mangle]
1085pub extern "system" fn Java_com_dunimd_ri_gateway_RiCircuitBreakerMetrics_getState0(
1086    env: JNIEnv,
1087    _class: JClass,
1088    ptr: jlong,
1089) -> jstring {
1090    if ptr != 0 {
1091        unsafe {
1092            let metrics = &*(ptr as *const RiCircuitBreakerMetrics);
1093            env.new_string(&metrics.state)
1094                .expect("Failed to create string")
1095                .into_raw()
1096        }
1097    } else {
1098        std::ptr::null_mut()
1099    }
1100}
1101
1102#[no_mangle]
1103pub extern "system" fn Java_com_dunimd_ri_gateway_RiCircuitBreakerMetrics_getFailureCount0(
1104    _env: JNIEnv,
1105    _class: JClass,
1106    ptr: jlong,
1107) -> jlong {
1108    if ptr != 0 {
1109        unsafe {
1110            let metrics = &*(ptr as *const RiCircuitBreakerMetrics);
1111            metrics.failure_count as jlong
1112        }
1113    } else {
1114        0
1115    }
1116}
1117
1118#[no_mangle]
1119pub extern "system" fn Java_com_dunimd_ri_gateway_RiCircuitBreakerMetrics_getSuccessCount0(
1120    _env: JNIEnv,
1121    _class: JClass,
1122    ptr: jlong,
1123) -> jlong {
1124    if ptr != 0 {
1125        unsafe {
1126            let metrics = &*(ptr as *const RiCircuitBreakerMetrics);
1127            metrics.success_count as jlong
1128        }
1129    } else {
1130        0
1131    }
1132}
1133
1134#[no_mangle]
1135pub extern "system" fn Java_com_dunimd_ri_gateway_RiCircuitBreakerMetrics_getConsecutiveFailures0(
1136    _env: JNIEnv,
1137    _class: JClass,
1138    ptr: jlong,
1139) -> jlong {
1140    if ptr != 0 {
1141        unsafe {
1142            let metrics = &*(ptr as *const RiCircuitBreakerMetrics);
1143            metrics.consecutive_failures as jlong
1144        }
1145    } else {
1146        0
1147    }
1148}
1149
1150#[no_mangle]
1151pub extern "system" fn Java_com_dunimd_ri_gateway_RiCircuitBreakerMetrics_getConsecutiveSuccesses0(
1152    _env: JNIEnv,
1153    _class: JClass,
1154    ptr: jlong,
1155) -> jlong {
1156    if ptr != 0 {
1157        unsafe {
1158            let metrics = &*(ptr as *const RiCircuitBreakerMetrics);
1159            metrics.consecutive_successes as jlong
1160        }
1161    } else {
1162        0
1163    }
1164}
1165
1166// ============================================================================
1167// RiCircuitBreaker
1168// ============================================================================
1169
1170#[no_mangle]
1171pub extern "system" fn Java_com_dunimd_ri_gateway_RiCircuitBreaker_new0(
1172    _env: JNIEnv,
1173    _class: JClass,
1174    config_ptr: jlong,
1175) -> jlong {
1176    let config = if config_ptr != 0 {
1177        unsafe { (*(config_ptr as *const RiCircuitBreakerConfig)).clone() }
1178    } else {
1179        RiCircuitBreakerConfig::default()
1180    };
1181    let cb = Box::new(RiCircuitBreaker::new(config));
1182    Box::into_raw(cb) as jlong
1183}
1184
1185#[no_mangle]
1186pub extern "system" fn Java_com_dunimd_ri_gateway_RiCircuitBreaker_free0(
1187    _env: JNIEnv,
1188    _class: JClass,
1189    ptr: jlong,
1190) {
1191    if ptr != 0 {
1192        unsafe {
1193            let _ = Box::from_raw(ptr as *mut RiCircuitBreaker);
1194        }
1195    }
1196}
1197
1198#[no_mangle]
1199pub extern "system" fn Java_com_dunimd_ri_gateway_RiCircuitBreaker_allowRequest0(
1200    _env: JNIEnv,
1201    _class: JClass,
1202    ptr: jlong,
1203) -> jboolean {
1204    if ptr != 0 {
1205        unsafe {
1206            let cb = &*(ptr as *const RiCircuitBreaker);
1207            cb.allow_request() as jboolean
1208        }
1209    } else {
1210        0
1211    }
1212}
1213
1214#[no_mangle]
1215pub extern "system" fn Java_com_dunimd_ri_gateway_RiCircuitBreaker_recordSuccess0(
1216    _env: JNIEnv,
1217    _class: JClass,
1218    ptr: jlong,
1219) {
1220    if ptr != 0 {
1221        unsafe {
1222            let cb = &*(ptr as *const RiCircuitBreaker);
1223            cb.record_success();
1224        }
1225    }
1226}
1227
1228#[no_mangle]
1229pub extern "system" fn Java_com_dunimd_ri_gateway_RiCircuitBreaker_recordFailure0(
1230    _env: JNIEnv,
1231    _class: JClass,
1232    ptr: jlong,
1233) {
1234    if ptr != 0 {
1235        unsafe {
1236            let cb = &*(ptr as *const RiCircuitBreaker);
1237            cb.record_failure();
1238        }
1239    }
1240}
1241
1242#[no_mangle]
1243pub extern "system" fn Java_com_dunimd_ri_gateway_RiCircuitBreaker_getState0(
1244    _env: JNIEnv,
1245    _class: JClass,
1246    ptr: jlong,
1247) -> jint {
1248    if ptr != 0 {
1249        unsafe {
1250            let cb = &*(ptr as *const RiCircuitBreaker);
1251            match cb.get_state() {
1252                RiCircuitBreakerState::Closed => 0,
1253                RiCircuitBreakerState::Open => 1,
1254                RiCircuitBreakerState::HalfOpen => 2,
1255            }
1256        }
1257    } else {
1258        0
1259    }
1260}
1261
1262#[no_mangle]
1263pub extern "system" fn Java_com_dunimd_ri_gateway_RiCircuitBreaker_getStats0(
1264    _env: JNIEnv,
1265    _class: JClass,
1266    ptr: jlong,
1267) -> jlong {
1268    if ptr != 0 {
1269        unsafe {
1270            let cb = &*(ptr as *const RiCircuitBreaker);
1271            let stats = cb.get_stats();
1272            Box::into_raw(Box::new(stats)) as jlong
1273        }
1274    } else {
1275        0
1276    }
1277}
1278
1279#[no_mangle]
1280pub extern "system" fn Java_com_dunimd_ri_gateway_RiCircuitBreaker_getConfig0(
1281    _env: JNIEnv,
1282    _class: JClass,
1283    ptr: jlong,
1284) -> jlong {
1285    if ptr != 0 {
1286        unsafe {
1287            let cb = &*(ptr as *const RiCircuitBreaker);
1288            let config = cb.get_config();
1289            Box::into_raw(Box::new(config)) as jlong
1290        }
1291    } else {
1292        0
1293    }
1294}
1295
1296#[no_mangle]
1297pub extern "system" fn Java_com_dunimd_ri_gateway_RiCircuitBreaker_reset0(
1298    _env: JNIEnv,
1299    _class: JClass,
1300    ptr: jlong,
1301) {
1302    if ptr != 0 {
1303        unsafe {
1304            let cb = &*(ptr as *const RiCircuitBreaker);
1305            cb.reset();
1306        }
1307    }
1308}
1309
1310#[no_mangle]
1311pub extern "system" fn Java_com_dunimd_ri_gateway_RiCircuitBreaker_forceOpen0(
1312    _env: JNIEnv,
1313    _class: JClass,
1314    ptr: jlong,
1315) {
1316    if ptr != 0 {
1317        unsafe {
1318            let cb = &*(ptr as *const RiCircuitBreaker);
1319            cb.force_open();
1320        }
1321    }
1322}
1323
1324#[no_mangle]
1325pub extern "system" fn Java_com_dunimd_ri_gateway_RiCircuitBreaker_forceClose0(
1326    _env: JNIEnv,
1327    _class: JClass,
1328    ptr: jlong,
1329) {
1330    if ptr != 0 {
1331        unsafe {
1332            let cb = &*(ptr as *const RiCircuitBreaker);
1333            cb.force_close();
1334        }
1335    }
1336}
1337
1338#[no_mangle]
1339pub extern "system" fn Java_com_dunimd_ri_gateway_RiCircuitBreaker_getFailureRate0(
1340    _env: JNIEnv,
1341    _class: JClass,
1342    ptr: jlong,
1343) -> jdouble {
1344    if ptr != 0 {
1345        unsafe {
1346            let cb = &*(ptr as *const RiCircuitBreaker);
1347            cb.failure_rate()
1348        }
1349    } else {
1350        0.0
1351    }
1352}
1353
1354#[no_mangle]
1355pub extern "system" fn Java_com_dunimd_ri_gateway_RiCircuitBreaker_getSuccessRate0(
1356    _env: JNIEnv,
1357    _class: JClass,
1358    ptr: jlong,
1359) -> jdouble {
1360    if ptr != 0 {
1361        unsafe {
1362            let cb = &*(ptr as *const RiCircuitBreaker);
1363            cb.success_rate()
1364        }
1365    } else {
1366        0.0
1367    }
1368}
1369
1370#[no_mangle]
1371pub extern "system" fn Java_com_dunimd_ri_gateway_RiCircuitBreaker_getTotalRequests0(
1372    _env: JNIEnv,
1373    _class: JClass,
1374    ptr: jlong,
1375) -> jlong {
1376    if ptr != 0 {
1377        unsafe {
1378            let cb = &*(ptr as *const RiCircuitBreaker);
1379            cb.total_requests() as jlong
1380        }
1381    } else {
1382        0
1383    }
1384}
1385
1386#[no_mangle]
1387pub extern "system" fn Java_com_dunimd_ri_gateway_RiCircuitBreaker_isOpen0(
1388    _env: JNIEnv,
1389    _class: JClass,
1390    ptr: jlong,
1391) -> jboolean {
1392    if ptr != 0 {
1393        unsafe {
1394            let cb = &*(ptr as *const RiCircuitBreaker);
1395            cb.is_open() as jboolean
1396        }
1397    } else {
1398        0
1399    }
1400}
1401
1402#[no_mangle]
1403pub extern "system" fn Java_com_dunimd_ri_gateway_RiCircuitBreaker_isClosed0(
1404    _env: JNIEnv,
1405    _class: JClass,
1406    ptr: jlong,
1407) -> jboolean {
1408    if ptr != 0 {
1409        unsafe {
1410            let cb = &*(ptr as *const RiCircuitBreaker);
1411            cb.is_closed() as jboolean
1412        }
1413    } else {
1414        0
1415    }
1416}
1417
1418#[no_mangle]
1419pub extern "system" fn Java_com_dunimd_ri_gateway_RiCircuitBreaker_isHalfOpen0(
1420    _env: JNIEnv,
1421    _class: JClass,
1422    ptr: jlong,
1423) -> jboolean {
1424    if ptr != 0 {
1425        unsafe {
1426            let cb = &*(ptr as *const RiCircuitBreaker);
1427            cb.is_half_open() as jboolean
1428        }
1429    } else {
1430        0
1431    }
1432}
1433
1434// ============================================================================
1435// RiBackendServer
1436// ============================================================================
1437
1438#[no_mangle]
1439pub extern "system" fn Java_com_dunimd_ri_gateway_RiBackendServer_new0(
1440    env: JNIEnv,
1441    _class: JClass,
1442    id: JString,
1443    url: JString,
1444) -> jlong {
1445    let id_str: String = env.get_string(&id).expect("Invalid id string").into();
1446    let url_str: String = env.get_string(&url).expect("Invalid url string").into();
1447    let server = Box::new(RiBackendServer::new(id_str, url_str));
1448    Box::into_raw(server) as jlong
1449}
1450
1451#[no_mangle]
1452pub extern "system" fn Java_com_dunimd_ri_gateway_RiBackendServer_free0(
1453    _env: JNIEnv,
1454    _class: JClass,
1455    ptr: jlong,
1456) {
1457    if ptr != 0 {
1458        unsafe {
1459            let _ = Box::from_raw(ptr as *mut RiBackendServer);
1460        }
1461    }
1462}
1463
1464#[no_mangle]
1465pub extern "system" fn Java_com_dunimd_ri_gateway_RiBackendServer_getId0(
1466    env: JNIEnv,
1467    _class: JClass,
1468    ptr: jlong,
1469) -> jstring {
1470    if ptr != 0 {
1471        unsafe {
1472            let server = &*(ptr as *const RiBackendServer);
1473            env.new_string(&server.id)
1474                .expect("Failed to create string")
1475                .into_raw()
1476        }
1477    } else {
1478        std::ptr::null_mut()
1479    }
1480}
1481
1482#[no_mangle]
1483pub extern "system" fn Java_com_dunimd_ri_gateway_RiBackendServer_getUrl0(
1484    env: JNIEnv,
1485    _class: JClass,
1486    ptr: jlong,
1487) -> jstring {
1488    if ptr != 0 {
1489        unsafe {
1490            let server = &*(ptr as *const RiBackendServer);
1491            env.new_string(&server.url)
1492                .expect("Failed to create string")
1493                .into_raw()
1494        }
1495    } else {
1496        std::ptr::null_mut()
1497    }
1498}
1499
1500#[no_mangle]
1501pub extern "system" fn Java_com_dunimd_ri_gateway_RiBackendServer_getWeight0(
1502    _env: JNIEnv,
1503    _class: JClass,
1504    ptr: jlong,
1505) -> jint {
1506    if ptr != 0 {
1507        unsafe {
1508            let server = &*(ptr as *const RiBackendServer);
1509            server.weight as jint
1510        }
1511    } else {
1512        0
1513    }
1514}
1515
1516#[no_mangle]
1517pub extern "system" fn Java_com_dunimd_ri_gateway_RiBackendServer_setWeight0(
1518    _env: JNIEnv,
1519    _class: JClass,
1520    ptr: jlong,
1521    weight: jint,
1522) {
1523    if ptr != 0 {
1524        unsafe {
1525            let server = &mut *(ptr as *mut RiBackendServer);
1526            server.weight = weight as u32;
1527        }
1528    }
1529}
1530
1531#[no_mangle]
1532pub extern "system" fn Java_com_dunimd_ri_gateway_RiBackendServer_getMaxConnections0(
1533    _env: JNIEnv,
1534    _class: JClass,
1535    ptr: jlong,
1536) -> jint {
1537    if ptr != 0 {
1538        unsafe {
1539            let server = &*(ptr as *const RiBackendServer);
1540            server.max_connections as jint
1541        }
1542    } else {
1543        0
1544    }
1545}
1546
1547#[no_mangle]
1548pub extern "system" fn Java_com_dunimd_ri_gateway_RiBackendServer_setMaxConnections0(
1549    _env: JNIEnv,
1550    _class: JClass,
1551    ptr: jlong,
1552    max_connections: jint,
1553) {
1554    if ptr != 0 {
1555        unsafe {
1556            let server = &mut *(ptr as *mut RiBackendServer);
1557            server.max_connections = max_connections as usize;
1558        }
1559    }
1560}
1561
1562#[no_mangle]
1563pub extern "system" fn Java_com_dunimd_ri_gateway_RiBackendServer_getHealthCheckPath0(
1564    env: JNIEnv,
1565    _class: JClass,
1566    ptr: jlong,
1567) -> jstring {
1568    if ptr != 0 {
1569        unsafe {
1570            let server = &*(ptr as *const RiBackendServer);
1571            env.new_string(&server.health_check_path)
1572                .expect("Failed to create string")
1573                .into_raw()
1574        }
1575    } else {
1576        std::ptr::null_mut()
1577    }
1578}
1579
1580#[no_mangle]
1581pub extern "system" fn Java_com_dunimd_ri_gateway_RiBackendServer_setHealthCheckPath0(
1582    env: JNIEnv,
1583    _class: JClass,
1584    ptr: jlong,
1585    path: JString,
1586) {
1587    if ptr != 0 {
1588        let path_str: String = env.get_string(&path).expect("Invalid path string").into();
1589        unsafe {
1590            let server = &mut *(ptr as *mut RiBackendServer);
1591            server.health_check_path = path_str;
1592        }
1593    }
1594}
1595
1596#[no_mangle]
1597pub extern "system" fn Java_com_dunimd_ri_gateway_RiBackendServer_isHealthy0(
1598    _env: JNIEnv,
1599    _class: JClass,
1600    ptr: jlong,
1601) -> jboolean {
1602    if ptr != 0 {
1603        unsafe {
1604            let server = &*(ptr as *const RiBackendServer);
1605            server.is_healthy as jboolean
1606        }
1607    } else {
1608        0
1609    }
1610}
1611
1612// ============================================================================
1613// RiLoadBalancerServerStats
1614// ============================================================================
1615
1616#[no_mangle]
1617pub extern "system" fn Java_com_dunimd_ri_gateway_RiLoadBalancerServerStats_new0(
1618    _env: JNIEnv,
1619    _class: JClass,
1620    active_connections: jlong,
1621    total_requests: jlong,
1622    failed_requests: jlong,
1623    response_time_ms: jlong,
1624) -> jlong {
1625    let stats = Box::new(RiLoadBalancerServerStats {
1626        active_connections: active_connections as usize,
1627        total_requests: total_requests as usize,
1628        failed_requests: failed_requests as usize,
1629        response_time_ms: response_time_ms as usize,
1630    });
1631    Box::into_raw(stats) as jlong
1632}
1633
1634#[no_mangle]
1635pub extern "system" fn Java_com_dunimd_ri_gateway_RiLoadBalancerServerStats_free0(
1636    _env: JNIEnv,
1637    _class: JClass,
1638    ptr: jlong,
1639) {
1640    if ptr != 0 {
1641        unsafe {
1642            let _ = Box::from_raw(ptr as *mut RiLoadBalancerServerStats);
1643        }
1644    }
1645}
1646
1647#[no_mangle]
1648pub extern "system" fn Java_com_dunimd_ri_gateway_RiLoadBalancerServerStats_getActiveConnections0(
1649    _env: JNIEnv,
1650    _class: JClass,
1651    ptr: jlong,
1652) -> jlong {
1653    if ptr != 0 {
1654        unsafe {
1655            let stats = &*(ptr as *const RiLoadBalancerServerStats);
1656            stats.active_connections as jlong
1657        }
1658    } else {
1659        0
1660    }
1661}
1662
1663#[no_mangle]
1664pub extern "system" fn Java_com_dunimd_ri_gateway_RiLoadBalancerServerStats_getTotalRequests0(
1665    _env: JNIEnv,
1666    _class: JClass,
1667    ptr: jlong,
1668) -> jlong {
1669    if ptr != 0 {
1670        unsafe {
1671            let stats = &*(ptr as *const RiLoadBalancerServerStats);
1672            stats.total_requests as jlong
1673        }
1674    } else {
1675        0
1676    }
1677}
1678
1679#[no_mangle]
1680pub extern "system" fn Java_com_dunimd_ri_gateway_RiLoadBalancerServerStats_getFailedRequests0(
1681    _env: JNIEnv,
1682    _class: JClass,
1683    ptr: jlong,
1684) -> jlong {
1685    if ptr != 0 {
1686        unsafe {
1687            let stats = &*(ptr as *const RiLoadBalancerServerStats);
1688            stats.failed_requests as jlong
1689        }
1690    } else {
1691        0
1692    }
1693}
1694
1695#[no_mangle]
1696pub extern "system" fn Java_com_dunimd_ri_gateway_RiLoadBalancerServerStats_getResponseTimeMs0(
1697    _env: JNIEnv,
1698    _class: JClass,
1699    ptr: jlong,
1700) -> jlong {
1701    if ptr != 0 {
1702        unsafe {
1703            let stats = &*(ptr as *const RiLoadBalancerServerStats);
1704            stats.response_time_ms as jlong
1705        }
1706    } else {
1707        0
1708    }
1709}
1710
1711// ============================================================================
1712// RiLoadBalancer
1713// ============================================================================
1714
1715#[no_mangle]
1716pub extern "system" fn Java_com_dunimd_ri_gateway_RiLoadBalancer_new0(
1717    _env: JNIEnv,
1718    _class: JClass,
1719    strategy: jint,
1720) -> jlong {
1721    let strategy_enum = match strategy {
1722        0 => RiLoadBalancerStrategy::RoundRobin,
1723        1 => RiLoadBalancerStrategy::WeightedRoundRobin,
1724        2 => RiLoadBalancerStrategy::LeastConnections,
1725        3 => RiLoadBalancerStrategy::Random,
1726        4 => RiLoadBalancerStrategy::IpHash,
1727        5 => RiLoadBalancerStrategy::LeastResponseTime,
1728        6 => RiLoadBalancerStrategy::ConsistentHash,
1729        _ => RiLoadBalancerStrategy::RoundRobin,
1730    };
1731    let lb = Box::new(RiLoadBalancer::new(strategy_enum));
1732    Box::into_raw(lb) as jlong
1733}
1734
1735#[no_mangle]
1736pub extern "system" fn Java_com_dunimd_ri_gateway_RiLoadBalancer_free0(
1737    _env: JNIEnv,
1738    _class: JClass,
1739    ptr: jlong,
1740) {
1741    if ptr != 0 {
1742        unsafe {
1743            let _ = Box::from_raw(ptr as *mut RiLoadBalancer);
1744        }
1745    }
1746}
1747
1748#[no_mangle]
1749pub extern "system" fn Java_com_dunimd_ri_gateway_RiLoadBalancer_addServer0(
1750    _env: JNIEnv,
1751    _class: JClass,
1752    ptr: jlong,
1753    server_ptr: jlong,
1754) {
1755    if ptr != 0 && server_ptr != 0 {
1756        unsafe {
1757            let lb = &*(ptr as *const RiLoadBalancer);
1758            let server = Box::from_raw(server_ptr as *mut RiBackendServer);
1759            futures::executor::block_on(async {
1760                lb.add_server(*server).await;
1761            });
1762        }
1763    }
1764}
1765
1766#[no_mangle]
1767pub extern "system" fn Java_com_dunimd_ri_gateway_RiLoadBalancer_removeServer0(
1768    env: JNIEnv,
1769    _class: JClass,
1770    ptr: jlong,
1771    server_id: JString,
1772) -> jboolean {
1773    if ptr != 0 {
1774        let server_id_str: String = env
1775            .get_string(&server_id)
1776            .expect("Invalid server_id string")
1777            .into();
1778        unsafe {
1779            let lb = &*(ptr as *const RiLoadBalancer);
1780            futures::executor::block_on(async { lb.remove_server(&server_id_str).await })
1781                as jboolean
1782        }
1783    } else {
1784        0
1785    }
1786}
1787
1788#[no_mangle]
1789pub extern "system" fn Java_com_dunimd_ri_gateway_RiLoadBalancer_selectBackend0(
1790    env: JNIEnv,
1791    _class: JClass,
1792    ptr: jlong,
1793    client_ip: JString,
1794) -> jlong {
1795    if ptr != 0 {
1796        let client_ip_str: Option<String> = if client_ip.is_null() {
1797            None
1798        } else {
1799            Some(
1800                env.get_string(&client_ip)
1801                    .expect("Invalid client_ip string")
1802                    .into(),
1803            )
1804        };
1805        unsafe {
1806            let lb = &*(ptr as *const RiLoadBalancer);
1807            futures::executor::block_on(async {
1808                match lb.select_server(client_ip_str.as_deref()).await {
1809                    Ok(server) => Box::into_raw(Box::new(server)) as jlong,
1810                    Err(_) => 0,
1811                }
1812            })
1813        }
1814    } else {
1815        0
1816    }
1817}
1818
1819#[no_mangle]
1820pub extern "system" fn Java_com_dunimd_ri_gateway_RiLoadBalancer_releaseServer0(
1821    env: JNIEnv,
1822    _class: JClass,
1823    ptr: jlong,
1824    server_id: JString,
1825) {
1826    if ptr != 0 {
1827        let server_id_str: String = env
1828            .get_string(&server_id)
1829            .expect("Invalid server_id string")
1830            .into();
1831        unsafe {
1832            let lb = &*(ptr as *const RiLoadBalancer);
1833            futures::executor::block_on(async {
1834                lb.release_server(&server_id_str).await;
1835            });
1836        }
1837    }
1838}
1839
1840#[no_mangle]
1841pub extern "system" fn Java_com_dunimd_ri_gateway_RiLoadBalancer_recordServerFailure0(
1842    env: JNIEnv,
1843    _class: JClass,
1844    ptr: jlong,
1845    server_id: JString,
1846) {
1847    if ptr != 0 {
1848        let server_id_str: String = env
1849            .get_string(&server_id)
1850            .expect("Invalid server_id string")
1851            .into();
1852        unsafe {
1853            let lb = &*(ptr as *const RiLoadBalancer);
1854            futures::executor::block_on(async {
1855                lb.record_server_failure(&server_id_str).await;
1856            });
1857        }
1858    }
1859}
1860
1861#[no_mangle]
1862pub extern "system" fn Java_com_dunimd_ri_gateway_RiLoadBalancer_recordResponseTime0(
1863    env: JNIEnv,
1864    _class: JClass,
1865    ptr: jlong,
1866    server_id: JString,
1867    response_time_ms: jlong,
1868) {
1869    if ptr != 0 {
1870        let server_id_str: String = env
1871            .get_string(&server_id)
1872            .expect("Invalid server_id string")
1873            .into();
1874        unsafe {
1875            let lb = &*(ptr as *const RiLoadBalancer);
1876            futures::executor::block_on(async {
1877                lb.record_response_time(&server_id_str, response_time_ms as u64)
1878                    .await;
1879            });
1880        }
1881    }
1882}
1883
1884#[no_mangle]
1885pub extern "system" fn Java_com_dunimd_ri_gateway_RiLoadBalancer_getServerStats0(
1886    env: JNIEnv,
1887    _class: JClass,
1888    ptr: jlong,
1889    server_id: JString,
1890) -> jlong {
1891    if ptr != 0 {
1892        let server_id_str: String = env
1893            .get_string(&server_id)
1894            .expect("Invalid server_id string")
1895            .into();
1896        unsafe {
1897            let lb = &*(ptr as *const RiLoadBalancer);
1898            futures::executor::block_on(async {
1899                match lb.get_server_stats(&server_id_str).await {
1900                    Some(stats) => Box::into_raw(Box::new(stats)) as jlong,
1901                    None => 0,
1902                }
1903            })
1904        }
1905    } else {
1906        0
1907    }
1908}
1909
1910#[no_mangle]
1911pub extern "system" fn Java_com_dunimd_ri_gateway_RiLoadBalancer_markServerHealthy0(
1912    env: JNIEnv,
1913    _class: JClass,
1914    ptr: jlong,
1915    server_id: JString,
1916    healthy: jboolean,
1917) {
1918    if ptr != 0 {
1919        let server_id_str: String = env
1920            .get_string(&server_id)
1921            .expect("Invalid server_id string")
1922            .into();
1923        unsafe {
1924            let lb = &*(ptr as *const RiLoadBalancer);
1925            futures::executor::block_on(async {
1926                lb.mark_server_healthy(&server_id_str, healthy != 0).await;
1927            });
1928        }
1929    }
1930}
1931
1932#[no_mangle]
1933pub extern "system" fn Java_com_dunimd_ri_gateway_RiLoadBalancer_performHealthCheck0(
1934    env: JNIEnv,
1935    _class: JClass,
1936    ptr: jlong,
1937    server_id: JString,
1938) -> jboolean {
1939    if ptr != 0 {
1940        let server_id_str: String = env
1941            .get_string(&server_id)
1942            .expect("Invalid server_id string")
1943            .into();
1944        unsafe {
1945            let lb = &*(ptr as *const RiLoadBalancer);
1946            futures::executor::block_on(async { lb.perform_health_check(&server_id_str).await })
1947                as jboolean
1948        }
1949    } else {
1950        0
1951    }
1952}
1953
1954#[no_mangle]
1955pub extern "system" fn Java_com_dunimd_ri_gateway_RiLoadBalancer_getServerCount0(
1956    _env: JNIEnv,
1957    _class: JClass,
1958    ptr: jlong,
1959) -> jint {
1960    if ptr != 0 {
1961        unsafe {
1962            let lb = &*(ptr as *const RiLoadBalancer);
1963            futures::executor::block_on(async { lb.get_server_count().await as jint })
1964        }
1965    } else {
1966        0
1967    }
1968}
1969
1970#[no_mangle]
1971pub extern "system" fn Java_com_dunimd_ri_gateway_RiLoadBalancer_getHealthyServerCount0(
1972    _env: JNIEnv,
1973    _class: JClass,
1974    ptr: jlong,
1975) -> jint {
1976    if ptr != 0 {
1977        unsafe {
1978            let lb = &*(ptr as *const RiLoadBalancer);
1979            futures::executor::block_on(async { lb.get_healthy_server_count().await as jint })
1980        }
1981    } else {
1982        0
1983    }
1984}
1985
1986#[no_mangle]
1987pub extern "system" fn Java_com_dunimd_ri_gateway_RiLoadBalancer_getStrategy0(
1988    _env: JNIEnv,
1989    _class: JClass,
1990    ptr: jlong,
1991) -> jint {
1992    if ptr != 0 {
1993        unsafe {
1994            let lb = &*(ptr as *const RiLoadBalancer);
1995            match lb.get_strategy() {
1996                RiLoadBalancerStrategy::RoundRobin => 0,
1997                RiLoadBalancerStrategy::WeightedRoundRobin => 1,
1998                RiLoadBalancerStrategy::LeastConnections => 2,
1999                RiLoadBalancerStrategy::Random => 3,
2000                RiLoadBalancerStrategy::IpHash => 4,
2001                RiLoadBalancerStrategy::LeastResponseTime => 5,
2002                RiLoadBalancerStrategy::ConsistentHash => 6,
2003            }
2004        }
2005    } else {
2006        0
2007    }
2008}