Skip to content

Commit c217dd9

Browse files
committed
Update Rust FFI connection and C# structs to fix connection errors.
Signed-off-by: currantw <[email protected]>
1 parent b8b2cee commit c217dd9

File tree

3 files changed

+74
-23
lines changed

3 files changed

+74
-23
lines changed

rust/src/ffi.rs

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ use std::{
77

88
use glide_core::{
99
client::{
10-
AuthenticationInfo, ConnectionRequest, ConnectionRetryStrategy, NodeAddress,
11-
ReadFrom as coreReadFrom, TlsMode,
10+
ConnectionRequest, ConnectionRetryStrategy, NodeAddress, ReadFrom as coreReadFrom, TlsMode,
1211
},
1312
request_type::RequestType,
1413
};
@@ -65,7 +64,7 @@ pub struct ConnectionConfig {
6564
pub has_connection_retry_strategy: bool,
6665
pub connection_retry_strategy: ConnectionRetryStrategy,
6766
pub has_authentication_info: bool,
68-
pub authentication_info: Credentials,
67+
pub authentication_info: AuthenticationInfo,
6968
pub database_id: u32,
7069
pub has_protocol: bool,
7170
pub protocol: redis::ProtocolVersion,
@@ -114,10 +113,32 @@ pub(crate) unsafe fn create_connection_request(
114113
client_name: unsafe { ptr_to_opt_str(config.client_name) },
115114
lib_name: option_env!("GLIDE_NAME").map(|s| s.to_string()),
116115
authentication_info: if config.has_authentication_info {
117-
Some(AuthenticationInfo {
118-
username: unsafe { ptr_to_opt_str(config.authentication_info.username) },
119-
password: unsafe { ptr_to_opt_str(config.authentication_info.password) },
120-
iam_config: None,
116+
let auth_info = config.authentication_info;
117+
let iam_config = if auth_info.has_iam_credentials {
118+
Some(glide_core::client::IamAuthenticationConfig {
119+
cluster_name: unsafe { ptr_to_str(auth_info.iam_credentials.cluster_name) },
120+
region: unsafe { ptr_to_str(auth_info.iam_credentials.region) },
121+
service_type: match auth_info.iam_credentials.service_type {
122+
ServiceType::ElastiCache => glide_core::iam::ServiceType::ElastiCache,
123+
ServiceType::MemoryDB => glide_core::iam::ServiceType::MemoryDB,
124+
},
125+
refresh_interval_seconds: if auth_info
126+
.iam_credentials
127+
.has_refresh_interval_seconds
128+
{
129+
Some(auth_info.iam_credentials.refresh_interval_seconds)
130+
} else {
131+
None
132+
},
133+
})
134+
} else {
135+
None
136+
};
137+
138+
Some(glide_core::client::AuthenticationInfo {
139+
username: unsafe { ptr_to_opt_str(auth_info.username) },
140+
password: unsafe { ptr_to_opt_str(auth_info.password) },
141+
iam_config,
121142
})
122143
} else {
123144
None
@@ -210,11 +231,29 @@ pub enum ReadFromStrategy {
210231
/// A mirror of [`AuthenticationInfo`] adopted for FFI.
211232
#[repr(C)]
212233
#[derive(Debug, Clone, Copy)]
213-
pub struct Credentials {
214-
/// zero pointer is valid, means no username is given (`None`)
234+
pub struct AuthenticationInfo {
215235
pub username: *const c_char,
216-
/// zero pointer is valid, means no password is given (`None`)
217236
pub password: *const c_char,
237+
pub has_iam_credentials: bool,
238+
pub iam_credentials: IamCredentials,
239+
}
240+
241+
/// A mirror of [`IamCredentials`] adopted for FFI.
242+
#[repr(C)]
243+
#[derive(Debug, Clone, Copy)]
244+
pub struct IamCredentials {
245+
pub cluster_name: *const c_char,
246+
pub region: *const c_char,
247+
pub service_type: ServiceType,
248+
pub has_refresh_interval_seconds: bool,
249+
pub refresh_interval_seconds: u32,
250+
}
251+
252+
#[repr(C)]
253+
#[derive(Debug, Clone, Copy)]
254+
pub enum ServiceType {
255+
ElastiCache = 0,
256+
MemoryDB = 1,
218257
}
219258

220259
#[repr(C)]

sources/Valkey.Glide/Internals/FFI.structs.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -814,7 +814,9 @@ internal readonly struct AuthenticationInfo(string? username, string? password,
814814
/// <summary>
815815
/// IAM credentials for authentication.
816816
/// </summary>
817-
public readonly IamCredentials? IamCredentials = iamCredentials;
817+
[MarshalAs(UnmanagedType.U1)]
818+
public readonly bool HasIamCredentials = iamCredentials.HasValue;
819+
public readonly IamCredentials IamCredentials = iamCredentials ?? default;
818820
}
819821

820822
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
@@ -840,7 +842,8 @@ internal readonly struct IamCredentials(string clusterName, string region, Servi
840842
/// <summary>
841843
/// The refresh interval in seconds for IAM authentication.
842844
/// </summary>
843-
public readonly uint? RefreshIntervalSeconds = refreshIntervalSeconds;
845+
public readonly bool HasRefreshIntervalSeconds = refreshIntervalSeconds.HasValue;
846+
public readonly uint? RefreshIntervalSeconds = refreshIntervalSeconds ?? default;
844847
}
845848

846849
internal enum ServiceType : uint

tests/Valkey.Glide.UnitTests/ConnectionConfigurationTests.cs

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public void WithAuthentication_UsernamePassword()
2626

2727
Assert.Equal(Username, authenticationInfo.Username);
2828
Assert.Equal(Password, authenticationInfo.Password);
29-
Assert.Null(authenticationInfo.IamCredentials);
29+
Assert.False(authenticationInfo.HasIamCredentials);
3030

3131
// Password cannot be null.
3232
Assert.Throws<ArgumentNullException>(() => builder.WithAuthentication(Username, (string)null!));
@@ -43,7 +43,7 @@ public void WithAuthentication_PasswordOnly()
4343

4444
Assert.Null(authenticationInfo.Username);
4545
Assert.Equal(Password, authenticationInfo.Password);
46-
Assert.Null(authenticationInfo.IamCredentials);
46+
Assert.False(authenticationInfo.HasIamCredentials);
4747

4848
// Password cannot be null.
4949
Assert.Throws<ArgumentNullException>(() => builder.WithAuthentication(null!));
@@ -58,13 +58,16 @@ public void WithAuthentication_UsernameIamAuthConfig_ConfiguresCorrectly()
5858

5959
var config = builder.Build();
6060
var authenticationInfo = config!.Request.AuthenticationInfo!.Value;
61-
var iamCredentials = authenticationInfo.IamCredentials!.Value;
6261

6362
Assert.Equal(Username, authenticationInfo.Username);
6463
Assert.Null(authenticationInfo.Password);
64+
Assert.True(authenticationInfo.HasIamCredentials);
65+
66+
var iamCredentials = authenticationInfo.IamCredentials!;
6567
Assert.Equal(ClusterName, iamCredentials.ClusterName);
6668
Assert.Equal(Region, iamCredentials.Region);
6769
Assert.Equal(FFI.ServiceType.ElastiCache, iamCredentials.ServiceType);
70+
Assert.True(iamCredentials.HasRefreshIntervalSeconds);
6871
Assert.Equal(600u, iamCredentials.RefreshIntervalSeconds);
6972

7073
// Username and IamAuthConfig cannot be null.
@@ -86,7 +89,7 @@ public void WithAuthentication_MultipleCalls_LastWins()
8689

8790
Assert.Equal(Username, authenticationInfo.Username);
8891
Assert.Equal(Password, authenticationInfo.Password);
89-
Assert.Null(authenticationInfo.IamCredentials);
92+
Assert.False(authenticationInfo.HasIamCredentials);
9093

9194
// IAM authentication last.
9295
builder = new StandaloneClientConfigurationBuilder();
@@ -95,14 +98,16 @@ public void WithAuthentication_MultipleCalls_LastWins()
9598

9699
config = builder.Build();
97100
authenticationInfo = config!.Request.AuthenticationInfo!.Value;
98-
var iamCredentials = authenticationInfo.IamCredentials!.Value;
99101

100102
Assert.Equal(Username, authenticationInfo.Username);
101103
Assert.Null(authenticationInfo.Password);
104+
Assert.True(authenticationInfo.HasIamCredentials);
105+
106+
var iamCredentials = authenticationInfo.IamCredentials!;
102107
Assert.Equal(ClusterName, iamCredentials.ClusterName);
103108
Assert.Equal(Region, iamCredentials.Region);
104109
Assert.Equal(FFI.ServiceType.MemoryDB, iamCredentials.ServiceType);
105-
Assert.Null(iamCredentials.RefreshIntervalSeconds);
110+
Assert.False(iamCredentials.HasRefreshIntervalSeconds);
106111
}
107112

108113
[Fact]
@@ -115,14 +120,16 @@ public void WithCredentials()
115120

116121
var config = builder.Build();
117122
var authenticationInfo = config.Request.AuthenticationInfo!.Value;
118-
var iamCredentials = authenticationInfo.IamCredentials!.Value;
119123

120124
Assert.Equal(Username, authenticationInfo.Username);
121125
Assert.Null(authenticationInfo.Password);
126+
Assert.True(authenticationInfo.HasIamCredentials);
127+
128+
var iamCredentials = authenticationInfo.IamCredentials!;
122129
Assert.Equal(ClusterName, iamCredentials.ClusterName);
123130
Assert.Equal(Region, iamCredentials.Region);
124131
Assert.Equal(FFI.ServiceType.MemoryDB, iamCredentials.ServiceType);
125-
Assert.Null(iamCredentials.RefreshIntervalSeconds);
132+
Assert.False(iamCredentials.HasRefreshIntervalSeconds);
126133

127134
// Credentials cannot be null.
128135
Assert.Throws<ArgumentNullException>(() => builder.WithCredentials(null!));
@@ -145,7 +152,7 @@ public void WithCredentials_MultipleCalls_LastWins()
145152

146153
Assert.Equal(Username, authenticationInfo.Username);
147154
Assert.Equal(Password, authenticationInfo.Password);
148-
Assert.Null(authenticationInfo.IamCredentials);
155+
Assert.False(authenticationInfo.HasIamCredentials);
149156

150157
// IAM authentication last.
151158
builder = new StandaloneClientConfigurationBuilder();
@@ -154,13 +161,15 @@ public void WithCredentials_MultipleCalls_LastWins()
154161

155162
config = builder.Build();
156163
authenticationInfo = config!.Request.AuthenticationInfo!.Value;
157-
var iamCredentials = authenticationInfo.IamCredentials!.Value;
158164

159165
Assert.Equal(Username, authenticationInfo.Username);
160166
Assert.Null(authenticationInfo.Password);
167+
Assert.True(authenticationInfo.HasIamCredentials);
168+
169+
var iamCredentials = authenticationInfo.IamCredentials!;
161170
Assert.Equal(ClusterName, iamCredentials.ClusterName);
162171
Assert.Equal(Region, iamCredentials.Region);
163172
Assert.Equal(FFI.ServiceType.MemoryDB, iamCredentials.ServiceType);
164-
Assert.Null(iamCredentials.RefreshIntervalSeconds);
173+
Assert.False(iamCredentials.HasRefreshIntervalSeconds);
165174
}
166175
}

0 commit comments

Comments
 (0)