Skip to main content

ri/java/classes/
service_mesh.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//! # Service Mesh Module JNI Bindings
19//!
20//! JNI bindings for Ri service mesh classes.
21
22use jni::JNIEnv;
23use jni::objects::{JClass, JString, JObjectArray};
24use jni::sys::{jlong, jboolean, jint, jstring, jobjectArray, jdouble, jlongArray};
25use std::collections::HashMap as FxHashMap;
26
27use crate::service_mesh::{
28    RiServiceMesh, RiServiceMeshConfig, RiServiceMeshStats,
29    RiServiceEndpoint, RiServiceHealthStatus,
30    RiServiceDiscovery, RiServiceInstance, RiServiceStatus,
31    RiHealthChecker, RiHealthSummary, RiHealthStatus, RiHealthCheckType,
32    RiTrafficRoute, RiMatchCriteria, RiRouteAction, RiWeightedDestination, RiTrafficManager,
33};
34use crate::gateway::RiCircuitBreakerConfig;
35use crate::service_mesh::traffic_management::RiRateLimitConfig;
36use crate::java::exception::check_not_null;
37
38// =============================================================================
39// RiServiceMeshConfig JNI Bindings
40// =============================================================================
41
42#[no_mangle]
43pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiServiceMeshConfig_new0(
44    _env: JNIEnv,
45    _class: JClass,
46) -> jlong {
47    let config = Box::new(RiServiceMeshConfig::default());
48    Box::into_raw(config) as jlong
49}
50
51#[no_mangle]
52pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiServiceMeshConfig_free0(
53    _env: JNIEnv,
54    _class: JClass,
55    ptr: jlong,
56) {
57    if ptr != 0 {
58        unsafe {
59            let _ = Box::from_raw(ptr as *mut RiServiceMeshConfig);
60        }
61    }
62}
63
64// =============================================================================
65// RiServiceMesh JNI Bindings
66// =============================================================================
67
68#[no_mangle]
69pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiServiceMesh_new0(
70    mut env: JNIEnv,
71    _class: JClass,
72    config_ptr: jlong,
73) -> jlong {
74    if !check_not_null(&mut env, config_ptr, "RiServiceMeshConfig") {
75        return 0;
76    }
77    
78    let config = unsafe { &*(config_ptr as *const RiServiceMeshConfig) };
79    match RiServiceMesh::new(config.clone()) {
80        Ok(mesh) => {
81            let boxed = Box::new(mesh);
82            Box::into_raw(boxed) as jlong
83        }
84        Err(_) => 0,
85    }
86}
87
88#[no_mangle]
89pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiServiceMesh_free0(
90    _env: JNIEnv,
91    _class: JClass,
92    ptr: jlong,
93) {
94    if ptr != 0 {
95        unsafe {
96            let _ = Box::from_raw(ptr as *mut RiServiceMesh);
97        }
98    }
99}
100
101// =============================================================================
102// RiServiceDiscovery JNI Bindings
103// =============================================================================
104
105#[no_mangle]
106pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiServiceDiscovery_new0(
107    _env: JNIEnv,
108    _class: JClass,
109    enabled: jboolean,
110) -> jlong {
111    let discovery = Box::new(RiServiceDiscovery::new(enabled != 0));
112    Box::into_raw(discovery) as jlong
113}
114
115#[no_mangle]
116pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiServiceDiscovery_register0(
117    mut env: JNIEnv,
118    _class: JClass,
119    ptr: jlong,
120    service_name: JString,
121    host: JString,
122    port: jint,
123    keys: JObjectArray,
124    values: JObjectArray,
125) -> jstring {
126    if !check_not_null(&mut env, ptr, "RiServiceDiscovery") {
127        return std::ptr::null_mut();
128    }
129    
130    let discovery = unsafe { &*(ptr as *const RiServiceDiscovery) };
131    let service_name_str: String = env.get_string(&service_name)
132        .expect("Failed to get service name")
133        .into();
134    let host_str: String = env.get_string(&host)
135        .expect("Failed to get host")
136        .into();
137    
138    let mut metadata = FxHashMap::new();
139    let len = env.get_array_length(&keys).unwrap_or(0);
140    for i in 0..len {
141        let key: JString = env.get_object_array_element(&keys, i)
142            .expect("Failed to get key")
143            .into();
144        let value: JString = env.get_object_array_element(&values, i)
145            .expect("Failed to get value")
146            .into();
147        let key_str: String = env.get_string(&key)
148            .expect("Failed to get key string")
149            .into();
150        let value_str: String = env.get_string(&value)
151            .expect("Failed to get value string")
152            .into();
153        metadata.insert(key_str, value_str);
154    }
155    
156    let rt = tokio::runtime::Runtime::new().expect("Failed to create runtime");
157    let result = rt.block_on(async {
158        discovery.register_service(&service_name_str, &host_str, port as u16, metadata).await
159    });
160    
161    match result {
162        Ok(instance_id) => env.new_string(&instance_id)
163            .expect("Failed to create string")
164            .into_raw(),
165        Err(_) => std::ptr::null_mut(),
166    }
167}
168
169#[no_mangle]
170pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiServiceDiscovery_deregister0(
171    mut env: JNIEnv,
172    _class: JClass,
173    ptr: jlong,
174    instance_id: JString,
175) {
176    if !check_not_null(&mut env, ptr, "RiServiceDiscovery") {
177        return;
178    }
179    
180    let discovery = unsafe { &*(ptr as *const RiServiceDiscovery) };
181    let instance_id_str: String = env.get_string(&instance_id)
182        .expect("Failed to get instance id")
183        .into();
184    
185    let rt = tokio::runtime::Runtime::new().expect("Failed to create runtime");
186    let _ = rt.block_on(async {
187        discovery.deregister_service(&instance_id_str).await
188    });
189}
190
191#[no_mangle]
192pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiServiceDiscovery_discover0(
193    mut env: JNIEnv,
194    _class: JClass,
195    ptr: jlong,
196    service_name: JString,
197) -> jlongArray {
198    if !check_not_null(&mut env, ptr, "RiServiceDiscovery") {
199        return std::ptr::null_mut();
200    }
201    
202    let discovery = unsafe { &*(ptr as *const RiServiceDiscovery) };
203    let service_name_str: String = env.get_string(&service_name)
204        .expect("Failed to get service name")
205        .into();
206    
207    let rt = tokio::runtime::Runtime::new().expect("Failed to create runtime");
208    let result = rt.block_on(async {
209        discovery.discover_service(&service_name_str).await
210    });
211    
212    match result {
213        Ok(instances) => {
214            let ptrs: Vec<jlong> = instances.iter().map(|i| {
215                let boxed = Box::new(i.clone());
216                Box::into_raw(boxed) as jlong
217            }).collect();
218            
219            let array = env.new_long_array(ptrs.len() as i32)
220                .expect("Failed to create long array");
221            env.set_long_array_region(array, 0, &ptrs)
222                .expect("Failed to set long array");
223            array
224        }
225        Err(_) => std::ptr::null_mut(),
226    }
227}
228
229#[no_mangle]
230pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiServiceDiscovery_updateHeartbeat0(
231    mut env: JNIEnv,
232    _class: JClass,
233    ptr: jlong,
234    instance_id: JString,
235) {
236    if !check_not_null(&mut env, ptr, "RiServiceDiscovery") {
237        return;
238    }
239    
240    let discovery = unsafe { &*(ptr as *const RiServiceDiscovery) };
241    let instance_id_str: String = env.get_string(&instance_id)
242        .expect("Failed to get instance id")
243        .into();
244    
245    let rt = tokio::runtime::Runtime::new().expect("Failed to create runtime");
246    let _ = rt.block_on(async {
247        discovery.update_heartbeat(&instance_id_str).await
248    });
249}
250
251#[no_mangle]
252pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiServiceDiscovery_setServiceStatus0(
253    mut env: JNIEnv,
254    _class: JClass,
255    ptr: jlong,
256    instance_id: JString,
257    status_ordinal: jint,
258) {
259    if !check_not_null(&mut env, ptr, "RiServiceDiscovery") {
260        return;
261    }
262    
263    let discovery = unsafe { &*(ptr as *const RiServiceDiscovery) };
264    let instance_id_str: String = env.get_string(&instance_id)
265        .expect("Failed to get instance id")
266        .into();
267    
268    let status = match status_ordinal {
269        0 => RiServiceStatus::Starting,
270        1 => RiServiceStatus::Running,
271        2 => RiServiceStatus::Stopping,
272        3 => RiServiceStatus::Stopped,
273        4 => RiServiceStatus::Unhealthy,
274        _ => RiServiceStatus::Starting,
275    };
276    
277    let rt = tokio::runtime::Runtime::new().expect("Failed to create runtime");
278    let _ = rt.block_on(async {
279        discovery.set_service_status(&instance_id_str, status).await
280    });
281}
282
283#[no_mangle]
284pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiServiceDiscovery_getAllServices0(
285    mut env: JNIEnv,
286    _class: JClass,
287    ptr: jlong,
288) -> jobjectArray {
289    if !check_not_null(&mut env, ptr, "RiServiceDiscovery") {
290        return std::ptr::null_mut();
291    }
292    
293    let discovery = unsafe { &*(ptr as *const RiServiceDiscovery) };
294    
295    let rt = tokio::runtime::Runtime::new().expect("Failed to create runtime");
296    let result = rt.block_on(async {
297        discovery.get_all_services().await
298    });
299    
300    match result {
301        Ok(services) => {
302            let string_class = env.find_class("java/lang/String")
303                .expect("Failed to find String class");
304            let array = env.new_object_array(services.len() as i32, string_class, std::ptr::null_mut())
305                .expect("Failed to create string array");
306            
307            for (i, service) in services.iter().enumerate() {
308                let jstr = env.new_string(service)
309                    .expect("Failed to create string")
310                    .into_raw();
311                env.set_object_array_element(&array, i as i32, jstr)
312                    .expect("Failed to set array element");
313            }
314            
315            array
316        }
317        Err(_) => std::ptr::null_mut(),
318    }
319}
320
321#[no_mangle]
322pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiServiceDiscovery_free0(
323    _env: JNIEnv,
324    _class: JClass,
325    ptr: jlong,
326) {
327    if ptr != 0 {
328        unsafe {
329            let _ = Box::from_raw(ptr as *mut RiServiceDiscovery);
330        }
331    }
332}
333
334// =============================================================================
335// RiServiceInstance JNI Bindings
336// =============================================================================
337
338#[no_mangle]
339pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiServiceInstance_new0(
340    mut env: JNIEnv,
341    _class: JClass,
342    id: JString,
343    service_name: JString,
344    host: JString,
345    port: jint,
346) -> jlong {
347    let id_str: String = env.get_string(&id)
348        .expect("Failed to get id")
349        .into();
350    let service_name_str: String = env.get_string(&service_name)
351        .expect("Failed to get service name")
352        .into();
353    let host_str: String = env.get_string(&host)
354        .expect("Failed to get host")
355        .into();
356    
357    let instance = Box::new(RiServiceInstance {
358        id: id_str,
359        service_name: service_name_str,
360        host: host_str,
361        port: port as u16,
362        metadata: FxHashMap::default(),
363        registered_at: std::time::SystemTime::now(),
364        last_heartbeat: std::time::SystemTime::now(),
365        status: RiServiceStatus::Starting,
366    });
367    Box::into_raw(instance) as jlong
368}
369
370#[no_mangle]
371pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiServiceInstance_getId0(
372    mut env: JNIEnv,
373    _class: JClass,
374    ptr: jlong,
375) -> jstring {
376    if !check_not_null(&mut env, ptr, "RiServiceInstance") {
377        return std::ptr::null_mut();
378    }
379    
380    let instance = unsafe { &*(ptr as *const RiServiceInstance) };
381    env.new_string(&instance.id)
382        .expect("Failed to create string")
383        .into_raw()
384}
385
386#[no_mangle]
387pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiServiceInstance_getServiceName0(
388    mut env: JNIEnv,
389    _class: JClass,
390    ptr: jlong,
391) -> jstring {
392    if !check_not_null(&mut env, ptr, "RiServiceInstance") {
393        return std::ptr::null_mut();
394    }
395    
396    let instance = unsafe { &*(ptr as *const RiServiceInstance) };
397    env.new_string(&instance.service_name)
398        .expect("Failed to create string")
399        .into_raw()
400}
401
402#[no_mangle]
403pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiServiceInstance_getHost0(
404    mut env: JNIEnv,
405    _class: JClass,
406    ptr: jlong,
407) -> jstring {
408    if !check_not_null(&mut env, ptr, "RiServiceInstance") {
409        return std::ptr::null_mut();
410    }
411    
412    let instance = unsafe { &*(ptr as *const RiServiceInstance) };
413    env.new_string(&instance.host)
414        .expect("Failed to create string")
415        .into_raw()
416}
417
418#[no_mangle]
419pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiServiceInstance_getPort0(
420    mut env: JNIEnv,
421    _class: JClass,
422    ptr: jlong,
423) -> jint {
424    if !check_not_null(&mut env, ptr, "RiServiceInstance") {
425        return 0;
426    }
427    
428    let instance = unsafe { &*(ptr as *const RiServiceInstance) };
429    instance.port as jint
430}
431
432#[no_mangle]
433pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiServiceInstance_getStatus0(
434    mut env: JNIEnv,
435    _class: JClass,
436    ptr: jlong,
437) -> jint {
438    if !check_not_null(&mut env, ptr, "RiServiceInstance") {
439        return 0;
440    }
441    
442    let instance = unsafe { &*(ptr as *const RiServiceInstance) };
443    match instance.status {
444        RiServiceStatus::Starting => 0,
445        RiServiceStatus::Running => 1,
446        RiServiceStatus::Stopping => 2,
447        RiServiceStatus::Stopped => 3,
448        RiServiceStatus::Unhealthy => 4,
449    }
450}
451
452#[no_mangle]
453pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiServiceInstance_getMetadataKeys0(
454    mut env: JNIEnv,
455    _class: JClass,
456    ptr: jlong,
457) -> jobjectArray {
458    if !check_not_null(&mut env, ptr, "RiServiceInstance") {
459        return std::ptr::null_mut();
460    }
461    
462    let instance = unsafe { &*(ptr as *const RiServiceInstance) };
463    let keys: Vec<&String> = instance.metadata.keys().collect();
464    
465    let string_class = env.find_class("java/lang/String")
466        .expect("Failed to find String class");
467    let array = env.new_object_array(keys.len() as i32, string_class, std::ptr::null_mut())
468        .expect("Failed to create string array");
469    
470    for (i, key) in keys.iter().enumerate() {
471        let jstr = env.new_string(key)
472            .expect("Failed to create string")
473            .into_raw();
474        env.set_object_array_element(&array, i as i32, jstr)
475            .expect("Failed to set array element");
476    }
477    
478    array
479}
480
481#[no_mangle]
482pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiServiceInstance_getMetadataValue0(
483    mut env: JNIEnv,
484    _class: JClass,
485    ptr: jlong,
486    key: JString,
487) -> jstring {
488    if !check_not_null(&mut env, ptr, "RiServiceInstance") {
489        return std::ptr::null_mut();
490    }
491    
492    let instance = unsafe { &*(ptr as *const RiServiceInstance) };
493    let key_str: String = env.get_string(&key)
494        .expect("Failed to get key")
495        .into();
496    
497    match instance.metadata.get(&key_str) {
498        Some(value) => env.new_string(value)
499            .expect("Failed to create string")
500            .into_raw(),
501        None => std::ptr::null_mut(),
502    }
503}
504
505#[no_mangle]
506pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiServiceInstance_free0(
507    _env: JNIEnv,
508    _class: JClass,
509    ptr: jlong,
510) {
511    if ptr != 0 {
512        unsafe {
513            let _ = Box::from_raw(ptr as *mut RiServiceInstance);
514        }
515    }
516}
517
518// =============================================================================
519// RiServiceMeshStats JNI Bindings
520// =============================================================================
521
522#[no_mangle]
523pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiServiceMeshStats_new0(
524    _env: JNIEnv,
525    _class: JClass,
526) -> jlong {
527    let stats = Box::new(RiServiceMeshStats {
528        total_services: 0,
529        total_endpoints: 0,
530        healthy_endpoints: 0,
531        unhealthy_endpoints: 0,
532    });
533    Box::into_raw(stats) as jlong
534}
535
536#[no_mangle]
537pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiServiceMeshStats_getTotalServices0(
538    mut env: JNIEnv,
539    _class: JClass,
540    ptr: jlong,
541) -> jlong {
542    if !check_not_null(&mut env, ptr, "RiServiceMeshStats") {
543        return 0;
544    }
545    
546    let stats = unsafe { &*(ptr as *const RiServiceMeshStats) };
547    stats.total_services as jlong
548}
549
550#[no_mangle]
551pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiServiceMeshStats_getTotalEndpoints0(
552    mut env: JNIEnv,
553    _class: JClass,
554    ptr: jlong,
555) -> jlong {
556    if !check_not_null(&mut env, ptr, "RiServiceMeshStats") {
557        return 0;
558    }
559    
560    let stats = unsafe { &*(ptr as *const RiServiceMeshStats) };
561    stats.total_endpoints as jlong
562}
563
564#[no_mangle]
565pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiServiceMeshStats_getHealthyEndpoints0(
566    mut env: JNIEnv,
567    _class: JClass,
568    ptr: jlong,
569) -> jlong {
570    if !check_not_null(&mut env, ptr, "RiServiceMeshStats") {
571        return 0;
572    }
573    
574    let stats = unsafe { &*(ptr as *const RiServiceMeshStats) };
575    stats.healthy_endpoints as jlong
576}
577
578#[no_mangle]
579pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiServiceMeshStats_getUnhealthyEndpoints0(
580    mut env: JNIEnv,
581    _class: JClass,
582    ptr: jlong,
583) -> jlong {
584    if !check_not_null(&mut env, ptr, "RiServiceMeshStats") {
585        return 0;
586    }
587    
588    let stats = unsafe { &*(ptr as *const RiServiceMeshStats) };
589    stats.unhealthy_endpoints as jlong
590}
591
592#[no_mangle]
593pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiServiceMeshStats_free0(
594    _env: JNIEnv,
595    _class: JClass,
596    ptr: jlong,
597) {
598    if ptr != 0 {
599        unsafe {
600            let _ = Box::from_raw(ptr as *mut RiServiceMeshStats);
601        }
602    }
603}
604
605// =============================================================================
606// RiServiceEndpoint JNI Bindings
607// =============================================================================
608
609#[no_mangle]
610pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiServiceEndpoint_new0(
611    mut env: JNIEnv,
612    _class: JClass,
613    service_name: JString,
614    endpoint: JString,
615    weight: jint,
616) -> jlong {
617    let service_name_str: String = env.get_string(&service_name)
618        .expect("Failed to get service name")
619        .into();
620    let endpoint_str: String = env.get_string(&endpoint)
621        .expect("Failed to get endpoint")
622        .into();
623    
624    let endpoint = Box::new(RiServiceEndpoint {
625        service_name: service_name_str,
626        endpoint: endpoint_str,
627        weight: weight as u32,
628        metadata: FxHashMap::default(),
629        health_status: RiServiceHealthStatus::Unknown,
630        last_health_check: std::time::SystemTime::now(),
631    });
632    Box::into_raw(endpoint) as jlong
633}
634
635#[no_mangle]
636pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiServiceEndpoint_getServiceName0(
637    mut env: JNIEnv,
638    _class: JClass,
639    ptr: jlong,
640) -> jstring {
641    if !check_not_null(&mut env, ptr, "RiServiceEndpoint") {
642        return std::ptr::null_mut();
643    }
644    
645    let endpoint = unsafe { &*(ptr as *const RiServiceEndpoint) };
646    env.new_string(&endpoint.service_name)
647        .expect("Failed to create string")
648        .into_raw()
649}
650
651#[no_mangle]
652pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiServiceEndpoint_getEndpoint0(
653    mut env: JNIEnv,
654    _class: JClass,
655    ptr: jlong,
656) -> jstring {
657    if !check_not_null(&mut env, ptr, "RiServiceEndpoint") {
658        return std::ptr::null_mut();
659    }
660    
661    let endpoint = unsafe { &*(ptr as *const RiServiceEndpoint) };
662    env.new_string(&endpoint.endpoint)
663        .expect("Failed to create string")
664        .into_raw()
665}
666
667#[no_mangle]
668pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiServiceEndpoint_getWeight0(
669    mut env: JNIEnv,
670    _class: JClass,
671    ptr: jlong,
672) -> jint {
673    if !check_not_null(&mut env, ptr, "RiServiceEndpoint") {
674        return 0;
675    }
676    
677    let endpoint = unsafe { &*(ptr as *const RiServiceEndpoint) };
678    endpoint.weight as jint
679}
680
681#[no_mangle]
682pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiServiceEndpoint_getHealthStatus0(
683    mut env: JNIEnv,
684    _class: JClass,
685    ptr: jlong,
686) -> jint {
687    if !check_not_null(&mut env, ptr, "RiServiceEndpoint") {
688        return 0;
689    }
690    
691    let endpoint = unsafe { &*(ptr as *const RiServiceEndpoint) };
692    match endpoint.health_status {
693        RiServiceHealthStatus::Healthy => 0,
694        RiServiceHealthStatus::Unhealthy => 1,
695        RiServiceHealthStatus::Unknown => 2,
696    }
697}
698
699#[no_mangle]
700pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiServiceEndpoint_getMetadataKeys0(
701    mut env: JNIEnv,
702    _class: JClass,
703    ptr: jlong,
704) -> jobjectArray {
705    if !check_not_null(&mut env, ptr, "RiServiceEndpoint") {
706        return std::ptr::null_mut();
707    }
708    
709    let endpoint = unsafe { &*(ptr as *const RiServiceEndpoint) };
710    let keys: Vec<&String> = endpoint.metadata.keys().collect();
711    
712    let string_class = env.find_class("java/lang/String")
713        .expect("Failed to find String class");
714    let array = env.new_object_array(keys.len() as i32, string_class, std::ptr::null_mut())
715        .expect("Failed to create string array");
716    
717    for (i, key) in keys.iter().enumerate() {
718        let jstr = env.new_string(key)
719            .expect("Failed to create string")
720            .into_raw();
721        env.set_object_array_element(&array, i as i32, jstr)
722            .expect("Failed to set array element");
723    }
724    
725    array
726}
727
728#[no_mangle]
729pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiServiceEndpoint_getMetadataValue0(
730    mut env: JNIEnv,
731    _class: JClass,
732    ptr: jlong,
733    key: JString,
734) -> jstring {
735    if !check_not_null(&mut env, ptr, "RiServiceEndpoint") {
736        return std::ptr::null_mut();
737    }
738    
739    let endpoint = unsafe { &*(ptr as *const RiServiceEndpoint) };
740    let key_str: String = env.get_string(&key)
741        .expect("Failed to get key")
742        .into();
743    
744    match endpoint.metadata.get(&key_str) {
745        Some(value) => env.new_string(value)
746            .expect("Failed to create string")
747            .into_raw(),
748        None => std::ptr::null_mut(),
749    }
750}
751
752#[no_mangle]
753pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiServiceEndpoint_free0(
754    _env: JNIEnv,
755    _class: JClass,
756    ptr: jlong,
757) {
758    if ptr != 0 {
759        unsafe {
760            let _ = Box::from_raw(ptr as *mut RiServiceEndpoint);
761        }
762    }
763}
764
765// =============================================================================
766// RiHealthChecker JNI Bindings
767// =============================================================================
768
769#[no_mangle]
770pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiHealthChecker_new0(
771    _env: JNIEnv,
772    _class: JClass,
773    check_interval_seconds: jlong,
774) -> jlong {
775    let checker = Box::new(RiHealthChecker::new(Duration::from_secs(check_interval_seconds as u64)));
776    Box::into_raw(checker) as jlong
777}
778
779#[no_mangle]
780pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiHealthChecker_startHealthCheck0(
781    mut env: JNIEnv,
782    _class: JClass,
783    ptr: jlong,
784    service_name: JString,
785    endpoint: JString,
786) {
787    if !check_not_null(&mut env, ptr, "RiHealthChecker") {
788        return;
789    }
790    
791    let checker = unsafe { &*(ptr as *const RiHealthChecker) };
792    let service_name_str: String = env.get_string(&service_name)
793        .expect("Failed to get service name")
794        .into();
795    let endpoint_str: String = env.get_string(&endpoint)
796        .expect("Failed to get endpoint")
797        .into();
798    
799    let rt = tokio::runtime::Runtime::new().expect("Failed to create runtime");
800    let _ = rt.block_on(async {
801        checker.start_health_check(&service_name_str, &endpoint_str).await
802    });
803}
804
805#[no_mangle]
806pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiHealthChecker_startHealthCheckWithType0(
807    mut env: JNIEnv,
808    _class: JClass,
809    ptr: jlong,
810    service_name: JString,
811    endpoint: JString,
812    check_type_ordinal: jint,
813) {
814    if !check_not_null(&mut env, ptr, "RiHealthChecker") {
815        return;
816    }
817    
818    let checker = unsafe { &*(ptr as *const RiHealthChecker) };
819    let service_name_str: String = env.get_string(&service_name)
820        .expect("Failed to get service name")
821        .into();
822    let endpoint_str: String = env.get_string(&endpoint)
823        .expect("Failed to get endpoint")
824        .into();
825    
826    let check_type = match check_type_ordinal {
827        0 => RiHealthCheckType::Http,
828        1 => RiHealthCheckType::Tcp,
829        2 => RiHealthCheckType::Grpc,
830        3 => RiHealthCheckType::Custom,
831        _ => RiHealthCheckType::Http,
832    };
833    
834    let rt = tokio::runtime::Runtime::new().expect("Failed to create runtime");
835    let _ = rt.block_on(async {
836        checker.start_health_check_with_type(&service_name_str, &endpoint_str, check_type).await
837    });
838}
839
840#[no_mangle]
841pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiHealthChecker_stopHealthCheck0(
842    mut env: JNIEnv,
843    _class: JClass,
844    ptr: jlong,
845    service_name: JString,
846    endpoint: JString,
847) {
848    if !check_not_null(&mut env, ptr, "RiHealthChecker") {
849        return;
850    }
851    
852    let checker = unsafe { &*(ptr as *const RiHealthChecker) };
853    let service_name_str: String = env.get_string(&service_name)
854        .expect("Failed to get service name")
855        .into();
856    let endpoint_str: String = env.get_string(&endpoint)
857        .expect("Failed to get endpoint")
858        .into();
859    
860    let rt = tokio::runtime::Runtime::new().expect("Failed to create runtime");
861    let _ = rt.block_on(async {
862        checker.stop_health_check(&service_name_str, &endpoint_str).await
863    });
864}
865
866#[no_mangle]
867pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiHealthChecker_getServiceHealthSummary0(
868    mut env: JNIEnv,
869    _class: JClass,
870    ptr: jlong,
871    service_name: JString,
872) -> jlong {
873    if !check_not_null(&mut env, ptr, "RiHealthChecker") {
874        return 0;
875    }
876    
877    let checker = unsafe { &*(ptr as *const RiHealthChecker) };
878    let service_name_str: String = env.get_string(&service_name)
879        .expect("Failed to get service name")
880        .into();
881    
882    let rt = tokio::runtime::Runtime::new().expect("Failed to create runtime");
883    let result = rt.block_on(async {
884        checker.get_service_health_summary(&service_name_str).await
885    });
886    
887    match result {
888        Ok(summary) => {
889            let boxed = Box::new(summary);
890            Box::into_raw(boxed) as jlong
891        }
892        Err(_) => 0,
893    }
894}
895
896#[no_mangle]
897pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiHealthChecker_free0(
898    _env: JNIEnv,
899    _class: JClass,
900    ptr: jlong,
901) {
902    if ptr != 0 {
903        unsafe {
904            let _ = Box::from_raw(ptr as *mut RiHealthChecker);
905        }
906    }
907}
908
909// =============================================================================
910// RiHealthSummary JNI Bindings
911// =============================================================================
912
913#[no_mangle]
914pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiHealthSummary_getServiceName0(
915    mut env: JNIEnv,
916    _class: JClass,
917    ptr: jlong,
918) -> jstring {
919    if !check_not_null(&mut env, ptr, "RiHealthSummary") {
920        return std::ptr::null_mut();
921    }
922    
923    let summary = unsafe { &*(ptr as *const RiHealthSummary) };
924    env.new_string(&summary.service_name)
925        .expect("Failed to create string")
926        .into_raw()
927}
928
929#[no_mangle]
930pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiHealthSummary_getTotalChecks0(
931    mut env: JNIEnv,
932    _class: JClass,
933    ptr: jlong,
934) -> jlong {
935    if !check_not_null(&mut env, ptr, "RiHealthSummary") {
936        return 0;
937    }
938    
939    let summary = unsafe { &*(ptr as *const RiHealthSummary) };
940    summary.total_checks as jlong
941}
942
943#[no_mangle]
944pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiHealthSummary_getHealthyChecks0(
945    mut env: JNIEnv,
946    _class: JClass,
947    ptr: jlong,
948) -> jlong {
949    if !check_not_null(&mut env, ptr, "RiHealthSummary") {
950        return 0;
951    }
952    
953    let summary = unsafe { &*(ptr as *const RiHealthSummary) };
954    summary.healthy_checks as jlong
955}
956
957#[no_mangle]
958pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiHealthSummary_getUnhealthyChecks0(
959    mut env: JNIEnv,
960    _class: JClass,
961    ptr: jlong,
962) -> jlong {
963    if !check_not_null(&mut env, ptr, "RiHealthSummary") {
964        return 0;
965    }
966    
967    let summary = unsafe { &*(ptr as *const RiHealthSummary) };
968    summary.unhealthy_checks as jlong
969}
970
971#[no_mangle]
972pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiHealthSummary_getSuccessRate0(
973    mut env: JNIEnv,
974    _class: JClass,
975    ptr: jlong,
976) -> jdouble {
977    if !check_not_null(&mut env, ptr, "RiHealthSummary") {
978        return 0.0;
979    }
980    
981    let summary = unsafe { &*(ptr as *const RiHealthSummary) };
982    summary.success_rate
983}
984
985#[no_mangle]
986pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiHealthSummary_getAverageResponseTimeMs0(
987    mut env: JNIEnv,
988    _class: JClass,
989    ptr: jlong,
990) -> jlong {
991    if !check_not_null(&mut env, ptr, "RiHealthSummary") {
992        return 0;
993    }
994    
995    let summary = unsafe { &*(ptr as *const RiHealthSummary) };
996    summary.average_response_time.as_millis() as jlong
997}
998
999#[no_mangle]
1000pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiHealthSummary_getOverallStatus0(
1001    mut env: JNIEnv,
1002    _class: JClass,
1003    ptr: jlong,
1004) -> jint {
1005    if !check_not_null(&mut env, ptr, "RiHealthSummary") {
1006        return 0;
1007    }
1008    
1009    let summary = unsafe { &*(ptr as *const RiHealthSummary) };
1010    match summary.overall_status {
1011        RiHealthStatus::Healthy => 0,
1012        RiHealthStatus::Degraded => 1,
1013        RiHealthStatus::Unhealthy => 2,
1014        RiHealthStatus::Unknown => 3,
1015    }
1016}
1017
1018#[no_mangle]
1019pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiHealthSummary_free0(
1020    _env: JNIEnv,
1021    _class: JClass,
1022    ptr: jlong,
1023) {
1024    if ptr != 0 {
1025        unsafe {
1026            let _ = Box::from_raw(ptr as *mut RiHealthSummary);
1027        }
1028    }
1029}
1030
1031// =============================================================================
1032// RiTrafficRoute JNI Bindings
1033// =============================================================================
1034
1035#[no_mangle]
1036pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiTrafficRoute_new0(
1037    mut env: JNIEnv,
1038    _class: JClass,
1039    name: JString,
1040    source_service: JString,
1041    destination_service: JString,
1042) -> jlong {
1043    let name_str: String = env.get_string(&name)
1044        .expect("Failed to get name")
1045        .into();
1046    let source_service_str: String = env.get_string(&source_service)
1047        .expect("Failed to get source service")
1048        .into();
1049    let destination_service_str: String = env.get_string(&destination_service)
1050        .expect("Failed to get destination service")
1051        .into();
1052    
1053    let route = Box::new(RiTrafficRoute {
1054        name: name_str,
1055        source_service: source_service_str,
1056        destination_service: destination_service_str,
1057        match_criteria: RiMatchCriteria {
1058            path_prefix: None,
1059            headers: FxHashMap::default(),
1060            method: None,
1061            query_parameters: FxHashMap::default(),
1062        },
1063        route_action: RiRouteAction::Route(vec![]),
1064        retry_policy: None,
1065        timeout: None,
1066        fault_injection: None,
1067    });
1068    Box::into_raw(route) as jlong
1069}
1070
1071#[no_mangle]
1072pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiTrafficRoute_getName0(
1073    mut env: JNIEnv,
1074    _class: JClass,
1075    ptr: jlong,
1076) -> jstring {
1077    if !check_not_null(&mut env, ptr, "RiTrafficRoute") {
1078        return std::ptr::null_mut();
1079    }
1080    
1081    let route = unsafe { &*(ptr as *const RiTrafficRoute) };
1082    env.new_string(&route.name)
1083        .expect("Failed to create string")
1084        .into_raw()
1085}
1086
1087#[no_mangle]
1088pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiTrafficRoute_getSourceService0(
1089    mut env: JNIEnv,
1090    _class: JClass,
1091    ptr: jlong,
1092) -> jstring {
1093    if !check_not_null(&mut env, ptr, "RiTrafficRoute") {
1094        return std::ptr::null_mut();
1095    }
1096    
1097    let route = unsafe { &*(ptr as *const RiTrafficRoute) };
1098    env.new_string(&route.source_service)
1099        .expect("Failed to create string")
1100        .into_raw()
1101}
1102
1103#[no_mangle]
1104pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiTrafficRoute_getDestinationService0(
1105    mut env: JNIEnv,
1106    _class: JClass,
1107    ptr: jlong,
1108) -> jstring {
1109    if !check_not_null(&mut env, ptr, "RiTrafficRoute") {
1110        return std::ptr::null_mut();
1111    }
1112    
1113    let route = unsafe { &*(ptr as *const RiTrafficRoute) };
1114    env.new_string(&route.destination_service)
1115        .expect("Failed to create string")
1116        .into_raw()
1117}
1118
1119#[no_mangle]
1120pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiTrafficRoute_getMatchCriteria0(
1121    mut env: JNIEnv,
1122    _class: JClass,
1123    ptr: jlong,
1124) -> jlong {
1125    if !check_not_null(&mut env, ptr, "RiTrafficRoute") {
1126        return 0;
1127    }
1128    
1129    let route = unsafe { &*(ptr as *const RiTrafficRoute) };
1130    let criteria = Box::new(route.match_criteria.clone());
1131    Box::into_raw(criteria) as jlong
1132}
1133
1134#[no_mangle]
1135pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiTrafficRoute_setMatchCriteria0(
1136    mut env: JNIEnv,
1137    _class: JClass,
1138    ptr: jlong,
1139    criteria_ptr: jlong,
1140) {
1141    if !check_not_null(&mut env, ptr, "RiTrafficRoute") {
1142        return;
1143    }
1144    if !check_not_null(&mut env, criteria_ptr, "RiMatchCriteria") {
1145        return;
1146    }
1147    
1148    let route = unsafe { &mut *(ptr as *mut RiTrafficRoute) };
1149    let criteria = unsafe { &*(criteria_ptr as *const RiMatchCriteria) };
1150    route.match_criteria = criteria.clone();
1151}
1152
1153#[no_mangle]
1154pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiTrafficRoute_getRouteAction0(
1155    mut env: JNIEnv,
1156    _class: JClass,
1157    ptr: jlong,
1158) -> jlong {
1159    if !check_not_null(&mut env, ptr, "RiTrafficRoute") {
1160        return 0;
1161    }
1162    
1163    let route = unsafe { &*(ptr as *const RiTrafficRoute) };
1164    let action = Box::new(route.route_action.clone());
1165    Box::into_raw(action) as jlong
1166}
1167
1168#[no_mangle]
1169pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiTrafficRoute_setRouteAction0(
1170    mut env: JNIEnv,
1171    _class: JClass,
1172    ptr: jlong,
1173    action_ptr: jlong,
1174) {
1175    if !check_not_null(&mut env, ptr, "RiTrafficRoute") {
1176        return;
1177    }
1178    if !check_not_null(&mut env, action_ptr, "RiRouteAction") {
1179        return;
1180    }
1181    
1182    let route = unsafe { &mut *(ptr as *mut RiTrafficRoute) };
1183    let action = unsafe { &*(action_ptr as *const RiRouteAction) };
1184    route.route_action = action.clone();
1185}
1186
1187#[no_mangle]
1188pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiTrafficRoute_getTimeoutMs0(
1189    mut env: JNIEnv,
1190    _class: JClass,
1191    ptr: jlong,
1192) -> jlong {
1193    if !check_not_null(&mut env, ptr, "RiTrafficRoute") {
1194        return 0;
1195    }
1196    
1197    let route = unsafe { &*(ptr as *const RiTrafficRoute) };
1198    route.timeout.map(|t| t.as_millis() as jlong).unwrap_or(0)
1199}
1200
1201#[no_mangle]
1202pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiTrafficRoute_setTimeoutMs0(
1203    mut env: JNIEnv,
1204    _class: JClass,
1205    ptr: jlong,
1206    timeout_ms: jlong,
1207) {
1208    if !check_not_null(&mut env, ptr, "RiTrafficRoute") {
1209        return;
1210    }
1211    
1212    let route = unsafe { &mut *(ptr as *mut RiTrafficRoute) };
1213    route.timeout = Some(Duration::from_millis(timeout_ms as u64));
1214}
1215
1216#[no_mangle]
1217pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiTrafficRoute_getRetryAttempts0(
1218    mut env: JNIEnv,
1219    _class: JClass,
1220    ptr: jlong,
1221) -> jint {
1222    if !check_not_null(&mut env, ptr, "RiTrafficRoute") {
1223        return 0;
1224    }
1225    
1226    let route = unsafe { &*(ptr as *const RiTrafficRoute) };
1227    route.retry_policy.as_ref().map(|p| p.attempts as jint).unwrap_or(0)
1228}
1229
1230#[no_mangle]
1231pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiTrafficRoute_setRetryAttempts0(
1232    mut env: JNIEnv,
1233    _class: JClass,
1234    ptr: jlong,
1235    attempts: jint,
1236) {
1237    if !check_not_null(&mut env, ptr, "RiTrafficRoute") {
1238        return;
1239    }
1240    
1241    let route = unsafe { &mut *(ptr as *mut RiTrafficRoute) };
1242    if let Some(ref mut policy) = route.retry_policy {
1243        policy.attempts = attempts as u32;
1244    } else {
1245        use crate::service_mesh::traffic_management::RiRetryPolicy;
1246        route.retry_policy = Some(RiRetryPolicy {
1247            attempts: attempts as u32,
1248            per_try_timeout: Duration::from_secs(1),
1249            retry_on: vec!["5xx".to_string()],
1250        });
1251    }
1252}
1253
1254#[no_mangle]
1255pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiTrafficRoute_free0(
1256    _env: JNIEnv,
1257    _class: JClass,
1258    ptr: jlong,
1259) {
1260    if ptr != 0 {
1261        unsafe {
1262            let _ = Box::from_raw(ptr as *mut RiTrafficRoute);
1263        }
1264    }
1265}
1266
1267// =============================================================================
1268// RiMatchCriteria JNI Bindings
1269// =============================================================================
1270
1271#[no_mangle]
1272pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiMatchCriteria_new0(
1273    _env: JNIEnv,
1274    _class: JClass,
1275) -> jlong {
1276    let criteria = Box::new(RiMatchCriteria {
1277        path_prefix: None,
1278        headers: FxHashMap::default(),
1279        method: None,
1280        query_parameters: FxHashMap::default(),
1281    });
1282    Box::into_raw(criteria) as jlong
1283}
1284
1285#[no_mangle]
1286pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiMatchCriteria_getPathPrefix0(
1287    mut env: JNIEnv,
1288    _class: JClass,
1289    ptr: jlong,
1290) -> jstring {
1291    if !check_not_null(&mut env, ptr, "RiMatchCriteria") {
1292        return std::ptr::null_mut();
1293    }
1294    
1295    let criteria = unsafe { &*(ptr as *const RiMatchCriteria) };
1296    match &criteria.path_prefix {
1297        Some(prefix) => env.new_string(prefix)
1298            .expect("Failed to create string")
1299            .into_raw(),
1300        None => std::ptr::null_mut(),
1301    }
1302}
1303
1304#[no_mangle]
1305pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiMatchCriteria_setPathPrefix0(
1306    mut env: JNIEnv,
1307    _class: JClass,
1308    ptr: jlong,
1309    path_prefix: JString,
1310) {
1311    if !check_not_null(&mut env, ptr, "RiMatchCriteria") {
1312        return;
1313    }
1314    
1315    let criteria = unsafe { &mut *(ptr as *mut RiMatchCriteria) };
1316    let prefix_str: String = env.get_string(&path_prefix)
1317        .expect("Failed to get path prefix")
1318        .into();
1319    criteria.path_prefix = Some(prefix_str);
1320}
1321
1322#[no_mangle]
1323pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiMatchCriteria_getMethod0(
1324    mut env: JNIEnv,
1325    _class: JClass,
1326    ptr: jlong,
1327) -> jstring {
1328    if !check_not_null(&mut env, ptr, "RiMatchCriteria") {
1329        return std::ptr::null_mut();
1330    }
1331    
1332    let criteria = unsafe { &*(ptr as *const RiMatchCriteria) };
1333    match &criteria.method {
1334        Some(method) => env.new_string(method)
1335            .expect("Failed to create string")
1336            .into_raw(),
1337        None => std::ptr::null_mut(),
1338    }
1339}
1340
1341#[no_mangle]
1342pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiMatchCriteria_setMethod0(
1343    mut env: JNIEnv,
1344    _class: JClass,
1345    ptr: jlong,
1346    method: JString,
1347) {
1348    if !check_not_null(&mut env, ptr, "RiMatchCriteria") {
1349        return;
1350    }
1351    
1352    let criteria = unsafe { &mut *(ptr as *mut RiMatchCriteria) };
1353    let method_str: String = env.get_string(&method)
1354        .expect("Failed to get method")
1355        .into();
1356    criteria.method = Some(method_str);
1357}
1358
1359#[no_mangle]
1360pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiMatchCriteria_getHeaderKeys0(
1361    mut env: JNIEnv,
1362    _class: JClass,
1363    ptr: jlong,
1364) -> jobjectArray {
1365    if !check_not_null(&mut env, ptr, "RiMatchCriteria") {
1366        return std::ptr::null_mut();
1367    }
1368    
1369    let criteria = unsafe { &*(ptr as *const RiMatchCriteria) };
1370    let keys: Vec<&String> = criteria.headers.keys().collect();
1371    
1372    let string_class = env.find_class("java/lang/String")
1373        .expect("Failed to find String class");
1374    let array = env.new_object_array(keys.len() as i32, string_class, std::ptr::null_mut())
1375        .expect("Failed to create string array");
1376    
1377    for (i, key) in keys.iter().enumerate() {
1378        let jstr = env.new_string(key)
1379            .expect("Failed to create string")
1380            .into_raw();
1381        env.set_object_array_element(&array, i as i32, jstr)
1382            .expect("Failed to set array element");
1383    }
1384    
1385    array
1386}
1387
1388#[no_mangle]
1389pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiMatchCriteria_getHeaderValue0(
1390    mut env: JNIEnv,
1391    _class: JClass,
1392    ptr: jlong,
1393    key: JString,
1394) -> jstring {
1395    if !check_not_null(&mut env, ptr, "RiMatchCriteria") {
1396        return std::ptr::null_mut();
1397    }
1398    
1399    let criteria = unsafe { &*(ptr as *const RiMatchCriteria) };
1400    let key_str: String = env.get_string(&key)
1401        .expect("Failed to get key")
1402        .into();
1403    
1404    match criteria.headers.get(&key_str) {
1405        Some(value) => env.new_string(value)
1406            .expect("Failed to create string")
1407            .into_raw(),
1408        None => std::ptr::null_mut(),
1409    }
1410}
1411
1412#[no_mangle]
1413pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiMatchCriteria_addHeader0(
1414    mut env: JNIEnv,
1415    _class: JClass,
1416    ptr: jlong,
1417    key: JString,
1418    value: JString,
1419) {
1420    if !check_not_null(&mut env, ptr, "RiMatchCriteria") {
1421        return;
1422    }
1423    
1424    let criteria = unsafe { &mut *(ptr as *mut RiMatchCriteria) };
1425    let key_str: String = env.get_string(&key)
1426        .expect("Failed to get key")
1427        .into();
1428    let value_str: String = env.get_string(&value)
1429        .expect("Failed to get value")
1430        .into();
1431    criteria.headers.insert(key_str, value_str);
1432}
1433
1434#[no_mangle]
1435pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiMatchCriteria_getQueryParamKeys0(
1436    mut env: JNIEnv,
1437    _class: JClass,
1438    ptr: jlong,
1439) -> jobjectArray {
1440    if !check_not_null(&mut env, ptr, "RiMatchCriteria") {
1441        return std::ptr::null_mut();
1442    }
1443    
1444    let criteria = unsafe { &*(ptr as *const RiMatchCriteria) };
1445    let keys: Vec<&String> = criteria.query_parameters.keys().collect();
1446    
1447    let string_class = env.find_class("java/lang/String")
1448        .expect("Failed to find String class");
1449    let array = env.new_object_array(keys.len() as i32, string_class, std::ptr::null_mut())
1450        .expect("Failed to create string array");
1451    
1452    for (i, key) in keys.iter().enumerate() {
1453        let jstr = env.new_string(key)
1454            .expect("Failed to create string")
1455            .into_raw();
1456        env.set_object_array_element(&array, i as i32, jstr)
1457            .expect("Failed to set array element");
1458    }
1459    
1460    array
1461}
1462
1463#[no_mangle]
1464pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiMatchCriteria_getQueryParamValue0(
1465    mut env: JNIEnv,
1466    _class: JClass,
1467    ptr: jlong,
1468    key: JString,
1469) -> jstring {
1470    if !check_not_null(&mut env, ptr, "RiMatchCriteria") {
1471        return std::ptr::null_mut();
1472    }
1473    
1474    let criteria = unsafe { &*(ptr as *const RiMatchCriteria) };
1475    let key_str: String = env.get_string(&key)
1476        .expect("Failed to get key")
1477        .into();
1478    
1479    match criteria.query_parameters.get(&key_str) {
1480        Some(value) => env.new_string(value)
1481            .expect("Failed to create string")
1482            .into_raw(),
1483        None => std::ptr::null_mut(),
1484    }
1485}
1486
1487#[no_mangle]
1488pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiMatchCriteria_addQueryParameter0(
1489    mut env: JNIEnv,
1490    _class: JClass,
1491    ptr: jlong,
1492    key: JString,
1493    value: JString,
1494) {
1495    if !check_not_null(&mut env, ptr, "RiMatchCriteria") {
1496        return;
1497    }
1498    
1499    let criteria = unsafe { &mut *(ptr as *mut RiMatchCriteria) };
1500    let key_str: String = env.get_string(&key)
1501        .expect("Failed to get key")
1502        .into();
1503    let value_str: String = env.get_string(&value)
1504        .expect("Failed to get value")
1505        .into();
1506    criteria.query_parameters.insert(key_str, value_str);
1507}
1508
1509#[no_mangle]
1510pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiMatchCriteria_free0(
1511    _env: JNIEnv,
1512    _class: JClass,
1513    ptr: jlong,
1514) {
1515    if ptr != 0 {
1516        unsafe {
1517            let _ = Box::from_raw(ptr as *mut RiMatchCriteria);
1518        }
1519    }
1520}
1521
1522// =============================================================================
1523// RiRouteAction JNI Bindings
1524// =============================================================================
1525
1526#[no_mangle]
1527pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiRouteAction_route0(
1528    mut env: JNIEnv,
1529    _class: JClass,
1530    destination_ptrs: jlongArray,
1531) -> jlong {
1532    let len = env.get_array_length(&destination_ptrs).unwrap_or(0);
1533    let mut ptrs = vec![0i64; len as usize];
1534    env.get_long_array_region(destination_ptrs, 0, &mut ptrs)
1535        .expect("Failed to get long array");
1536    
1537    let destinations: Vec<RiWeightedDestination> = ptrs.iter()
1538        .filter(|&&p| p != 0)
1539        .map(|&p| {
1540            let dest = unsafe { &*(p as *const RiWeightedDestination) };
1541            dest.clone()
1542        })
1543        .collect();
1544    
1545    let action = Box::new(RiRouteAction::Route(destinations));
1546    Box::into_raw(action) as jlong
1547}
1548
1549#[no_mangle]
1550pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiRouteAction_redirect0(
1551    mut env: JNIEnv,
1552    _class: JClass,
1553    uri: JString,
1554) -> jlong {
1555    let uri_str: String = env.get_string(&uri)
1556        .expect("Failed to get uri")
1557        .into();
1558    
1559    let action = Box::new(RiRouteAction::Redirect(uri_str));
1560    Box::into_raw(action) as jlong
1561}
1562
1563#[no_mangle]
1564pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiRouteAction_directResponse0(
1565    mut env: JNIEnv,
1566    _class: JClass,
1567    status_code: jint,
1568    body: JString,
1569) -> jlong {
1570    let body_str: String = env.get_string(&body)
1571        .expect("Failed to get body")
1572        .into();
1573    
1574    let action = Box::new(RiRouteAction::DirectResponse(status_code as u16, body_str));
1575    Box::into_raw(action) as jlong
1576}
1577
1578#[no_mangle]
1579pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiRouteAction_getType0(
1580    mut env: JNIEnv,
1581    _class: JClass,
1582    ptr: jlong,
1583) -> jint {
1584    if !check_not_null(&mut env, ptr, "RiRouteAction") {
1585        return 0;
1586    }
1587    
1588    let action = unsafe { &*(ptr as *const RiRouteAction) };
1589    match action {
1590        RiRouteAction::Route(_) => 0,
1591        RiRouteAction::Redirect(_) => 1,
1592        RiRouteAction::DirectResponse(_, _) => 2,
1593    }
1594}
1595
1596#[no_mangle]
1597pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiRouteAction_getDestinations0(
1598    mut env: JNIEnv,
1599    _class: JClass,
1600    ptr: jlong,
1601) -> jlongArray {
1602    if !check_not_null(&mut env, ptr, "RiRouteAction") {
1603        return std::ptr::null_mut();
1604    }
1605    
1606    let action = unsafe { &*(ptr as *const RiRouteAction) };
1607    
1608    match action {
1609        RiRouteAction::Route(destinations) => {
1610            let ptrs: Vec<jlong> = destinations.iter().map(|d| {
1611                let boxed = Box::new(d.clone());
1612                Box::into_raw(boxed) as jlong
1613            }).collect();
1614            
1615            let array = env.new_long_array(ptrs.len() as i32)
1616                .expect("Failed to create long array");
1617            env.set_long_array_region(array, 0, &ptrs)
1618                .expect("Failed to set long array");
1619            array
1620        }
1621        _ => std::ptr::null_mut(),
1622    }
1623}
1624
1625#[no_mangle]
1626pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiRouteAction_getRedirectUri0(
1627    mut env: JNIEnv,
1628    _class: JClass,
1629    ptr: jlong,
1630) -> jstring {
1631    if !check_not_null(&mut env, ptr, "RiRouteAction") {
1632        return std::ptr::null_mut();
1633    }
1634    
1635    let action = unsafe { &*(ptr as *const RiRouteAction) };
1636    
1637    match action {
1638        RiRouteAction::Redirect(uri) => env.new_string(uri)
1639            .expect("Failed to create string")
1640            .into_raw(),
1641        _ => std::ptr::null_mut(),
1642    }
1643}
1644
1645#[no_mangle]
1646pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiRouteAction_getDirectResponseStatusCode0(
1647    mut env: JNIEnv,
1648    _class: JClass,
1649    ptr: jlong,
1650) -> jint {
1651    if !check_not_null(&mut env, ptr, "RiRouteAction") {
1652        return 0;
1653    }
1654    
1655    let action = unsafe { &*(ptr as *const RiRouteAction) };
1656    
1657    match action {
1658        RiRouteAction::DirectResponse(status_code, _) => *status_code as jint,
1659        _ => 0,
1660    }
1661}
1662
1663#[no_mangle]
1664pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiRouteAction_getDirectResponseBody0(
1665    mut env: JNIEnv,
1666    _class: JClass,
1667    ptr: jlong,
1668) -> jstring {
1669    if !check_not_null(&mut env, ptr, "RiRouteAction") {
1670        return std::ptr::null_mut();
1671    }
1672    
1673    let action = unsafe { &*(ptr as *const RiRouteAction) };
1674    
1675    match action {
1676        RiRouteAction::DirectResponse(_, body) => env.new_string(body)
1677            .expect("Failed to create string")
1678            .into_raw(),
1679        _ => std::ptr::null_mut(),
1680    }
1681}
1682
1683#[no_mangle]
1684pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiRouteAction_free0(
1685    _env: JNIEnv,
1686    _class: JClass,
1687    ptr: jlong,
1688) {
1689    if ptr != 0 {
1690        unsafe {
1691            let _ = Box::from_raw(ptr as *mut RiRouteAction);
1692        }
1693    }
1694}
1695
1696// =============================================================================
1697// RiWeightedDestination JNI Bindings
1698// =============================================================================
1699
1700#[no_mangle]
1701pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiWeightedDestination_new0(
1702    mut env: JNIEnv,
1703    _class: JClass,
1704    service: JString,
1705    weight: jint,
1706) -> jlong {
1707    let service_str: String = env.get_string(&service)
1708        .expect("Failed to get service")
1709        .into();
1710    
1711    let dest = Box::new(RiWeightedDestination {
1712        service: service_str,
1713        weight: weight as u32,
1714        subset: None,
1715    });
1716    Box::into_raw(dest) as jlong
1717}
1718
1719#[no_mangle]
1720pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiWeightedDestination_getService0(
1721    mut env: JNIEnv,
1722    _class: JClass,
1723    ptr: jlong,
1724) -> jstring {
1725    if !check_not_null(&mut env, ptr, "RiWeightedDestination") {
1726        return std::ptr::null_mut();
1727    }
1728    
1729    let dest = unsafe { &*(ptr as *const RiWeightedDestination) };
1730    env.new_string(&dest.service)
1731        .expect("Failed to create string")
1732        .into_raw()
1733}
1734
1735#[no_mangle]
1736pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiWeightedDestination_getWeight0(
1737    mut env: JNIEnv,
1738    _class: JClass,
1739    ptr: jlong,
1740) -> jint {
1741    if !check_not_null(&mut env, ptr, "RiWeightedDestination") {
1742        return 0;
1743    }
1744    
1745    let dest = unsafe { &*(ptr as *const RiWeightedDestination) };
1746    dest.weight as jint
1747}
1748
1749#[no_mangle]
1750pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiWeightedDestination_getSubset0(
1751    mut env: JNIEnv,
1752    _class: JClass,
1753    ptr: jlong,
1754) -> jstring {
1755    if !check_not_null(&mut env, ptr, "RiWeightedDestination") {
1756        return std::ptr::null_mut();
1757    }
1758    
1759    let dest = unsafe { &*(ptr as *const RiWeightedDestination) };
1760    match &dest.subset {
1761        Some(subset) => env.new_string(subset)
1762            .expect("Failed to create string")
1763            .into_raw(),
1764        None => std::ptr::null_mut(),
1765    }
1766}
1767
1768#[no_mangle]
1769pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiWeightedDestination_setSubset0(
1770    mut env: JNIEnv,
1771    _class: JClass,
1772    ptr: jlong,
1773    subset: JString,
1774) {
1775    if !check_not_null(&mut env, ptr, "RiWeightedDestination") {
1776        return;
1777    }
1778    
1779    let dest = unsafe { &mut *(ptr as *mut RiWeightedDestination) };
1780    let subset_str: String = env.get_string(&subset)
1781        .expect("Failed to get subset")
1782        .into();
1783    dest.subset = Some(subset_str);
1784}
1785
1786#[no_mangle]
1787pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiWeightedDestination_free0(
1788    _env: JNIEnv,
1789    _class: JClass,
1790    ptr: jlong,
1791) {
1792    if ptr != 0 {
1793        unsafe {
1794            let _ = Box::from_raw(ptr as *mut RiWeightedDestination);
1795        }
1796    }
1797}
1798
1799// =============================================================================
1800// RiTrafficManager JNI Bindings
1801// =============================================================================
1802
1803#[no_mangle]
1804pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiTrafficManager_new0(
1805    _env: JNIEnv,
1806    _class: JClass,
1807    enabled: jboolean,
1808) -> jlong {
1809    let manager = Box::new(RiTrafficManager::new(enabled != 0));
1810    Box::into_raw(manager) as jlong
1811}
1812
1813#[no_mangle]
1814pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiTrafficManager_addRoute0(
1815    mut env: JNIEnv,
1816    _class: JClass,
1817    ptr: jlong,
1818    route_ptr: jlong,
1819) {
1820    if !check_not_null(&mut env, ptr, "RiTrafficManager") {
1821        return;
1822    }
1823    if !check_not_null(&mut env, route_ptr, "RiTrafficRoute") {
1824        return;
1825    }
1826    
1827    let manager = unsafe { &*(ptr as *const RiTrafficManager) };
1828    let route = unsafe { &*(route_ptr as *const RiTrafficRoute) };
1829    
1830    let rt = tokio::runtime::Runtime::new().expect("Failed to create runtime");
1831    let _ = rt.block_on(async {
1832        manager.add_traffic_route(route.clone()).await
1833    });
1834}
1835
1836#[no_mangle]
1837pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiTrafficManager_removeRoute0(
1838    mut env: JNIEnv,
1839    _class: JClass,
1840    ptr: jlong,
1841    source_service: JString,
1842    route_name: JString,
1843) {
1844    if !check_not_null(&mut env, ptr, "RiTrafficManager") {
1845        return;
1846    }
1847    
1848    let manager = unsafe { &*(ptr as *const RiTrafficManager) };
1849    let source_service_str: String = env.get_string(&source_service)
1850        .expect("Failed to get source service")
1851        .into();
1852    let route_name_str: String = env.get_string(&route_name)
1853        .expect("Failed to get route name")
1854        .into();
1855    
1856    let rt = tokio::runtime::Runtime::new().expect("Failed to create runtime");
1857    let _ = rt.block_on(async {
1858        manager.remove_traffic_route(&source_service_str, &route_name_str).await
1859    });
1860}
1861
1862#[no_mangle]
1863pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiTrafficManager_getRoutes0(
1864    mut env: JNIEnv,
1865    _class: JClass,
1866    ptr: jlong,
1867    source_service: JString,
1868) -> jlongArray {
1869    if !check_not_null(&mut env, ptr, "RiTrafficManager") {
1870        return std::ptr::null_mut();
1871    }
1872    
1873    let manager = unsafe { &*(ptr as *const RiTrafficManager) };
1874    let source_service_str: String = env.get_string(&source_service)
1875        .expect("Failed to get source service")
1876        .into();
1877    
1878    let rt = tokio::runtime::Runtime::new().expect("Failed to create runtime");
1879    let result = rt.block_on(async {
1880        manager.get_traffic_routes(&source_service_str).await
1881    });
1882    
1883    match result {
1884        Ok(routes) => {
1885            let ptrs: Vec<jlong> = routes.iter().map(|r| {
1886                let boxed = Box::new(r.clone());
1887                Box::into_raw(boxed) as jlong
1888            }).collect();
1889            
1890            let array = env.new_long_array(ptrs.len() as i32)
1891                .expect("Failed to create long array");
1892            env.set_long_array_region(array, 0, &ptrs)
1893                .expect("Failed to set long array");
1894            array
1895        }
1896        Err(_) => std::ptr::null_mut(),
1897    }
1898}
1899
1900#[no_mangle]
1901pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiTrafficManager_setCircuitBreakerConfig0(
1902    mut env: JNIEnv,
1903    _class: JClass,
1904    ptr: jlong,
1905    service: JString,
1906    consecutive_errors: jint,
1907    max_ejection_percent: jdouble,
1908) {
1909    if !check_not_null(&mut env, ptr, "RiTrafficManager") {
1910        return;
1911    }
1912    
1913    let manager = unsafe { &*(ptr as *const RiTrafficManager) };
1914    let service_str: String = env.get_string(&service)
1915        .expect("Failed to get service")
1916        .into();
1917    
1918    let config = RiCircuitBreakerConfig {
1919        consecutive_errors: consecutive_errors as u32,
1920        interval: Duration::from_secs(10),
1921        base_ejection_time: Duration::from_secs(30),
1922        max_ejection_percent,
1923    };
1924    
1925    let rt = tokio::runtime::Runtime::new().expect("Failed to create runtime");
1926    let _ = rt.block_on(async {
1927        manager.set_circuit_breaker_config(&service_str, config).await
1928    });
1929}
1930
1931#[no_mangle]
1932pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiTrafficManager_setRateLimitConfig0(
1933    mut env: JNIEnv,
1934    _class: JClass,
1935    ptr: jlong,
1936    service: JString,
1937    requests_per_second: jint,
1938    burst_size: jint,
1939) {
1940    if !check_not_null(&mut env, ptr, "RiTrafficManager") {
1941        return;
1942    }
1943    
1944    let manager = unsafe { &*(ptr as *const RiTrafficManager) };
1945    let service_str: String = env.get_string(&service)
1946        .expect("Failed to get service")
1947        .into();
1948    
1949    let config = RiRateLimitConfig {
1950        requests_per_second: requests_per_second as u32,
1951        burst_size: burst_size as u32,
1952        window: Duration::from_secs(1),
1953    };
1954    
1955    let rt = tokio::runtime::Runtime::new().expect("Failed to create runtime");
1956    let _ = rt.block_on(async {
1957        manager.set_rate_limit_config(&service_str, config).await
1958    });
1959}
1960
1961#[no_mangle]
1962pub extern "system" fn Java_com_dunimd_ri_servicemesh_RiTrafficManager_free0(
1963    _env: JNIEnv,
1964    _class: JClass,
1965    ptr: jlong,
1966) {
1967    if ptr != 0 {
1968        unsafe {
1969            let _ = Box::from_raw(ptr as *mut RiTrafficManager);
1970        }
1971    }
1972}