Skip to content

Commit

Permalink
Address translation (#624)
Browse files Browse the repository at this point in the history
## Usage and product changes

We allow the user to provide a translation map from the advertised
server addresses (now treated as generic server names) to the actual
addresses the driver shall use to connect to the cloud instances. We
require the user to provide the full mapping.

Example usage:

Python:
```python
with TypeDB.cloud_driver({
            "0.deployment-UUID.cloud.typedb.com:1729": "localhost:11729",
            "1.deployment-UUID.cloud.typedb.com:1729": "localhost:21729",
            "2.deployment-UUID.cloud.typedb.com:1729": "localhost:31729"
        }, credential) as driver:
    pass
```

Rust:
```rust
Connection::new_cloud_with_translation(                                                        
    [                                                                                          
        ("0.deployment-UUID.cloud.typedb.com:1729", "localhost:11729"),
        ("1.deployment-UUID.cloud.typedb.com:1729", "localhost:21729"),
        ("2.deployment-UUID.cloud.typedb.com:1729", "localhost:31729"),
    ].into(),                                                                                  
    credential                                                                                   
)                                                                                              
```
  • Loading branch information
dmitrii-ubskii authored Apr 11, 2024
1 parent 8153146 commit dbc7be3
Show file tree
Hide file tree
Showing 68 changed files with 1,053 additions and 353 deletions.
94 changes: 35 additions & 59 deletions .factory/automation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ build:
source tool/test/start-cloud-servers.sh 3 && # use source to receive export vars
bazel test //rust/tests --test_output=streamed --test_env=ROOT_CA=$ROOT_CA --test_arg=-- \
--test_arg=integration::queries::cloud \
--test_arg=integration::runtimes &&
--test_arg=integration::runtimes \
--test_arg=integration::network &&
export CLOUD_FAILED= || export CLOUD_FAILED=1
tool/test/stop-cloud-servers.sh
if [[ -n "$CLOUD_FAILED" ]]; then exit 1; fi
Expand Down Expand Up @@ -272,7 +273,7 @@ build:
tool/test/stop-cloud-servers.sh
exit $TEST_SUCCESS
test-python-integration-core:
test-python-integration:
image: vaticle-ubuntu-22.04
dependencies:
- build
Expand All @@ -285,29 +286,18 @@ build:
bazel run @vaticle_dependencies//distribution/artifact:create-netrc
tool/test/start-core-server.sh &&
bazel test //python/tests/integration:test_connection --test_output=streamed --jobs=1 &&
bazel test //python/tests/integration:test_stream --test_output=streamed --jobs=1 &&
export TEST_SUCCESS=0 || export TEST_SUCCESS=1
export CORE_FAILED= || export CORE_FAILED=1
tool/test/stop-core-server.sh
exit $TEST_SUCCESS
if [[ -n "$CORE_FAILED" ]]; then exit 1; fi
# test-python-integration-cloud-failover:
# machine: 4-core-16-gb
# image: vaticle-ubuntu-22.04
# dependencies:
# - build
# type: foreground
# command: |
# export PATH="$HOME/.local/bin:$PATH"
# sudo apt-get update
# sudo apt install python3-pip -y
# python3 -m pip install -U pip
# python3 -m pip install -r python/requirements_dev.txt
# export ARTIFACT_USERNAME=$REPO_TYPEDB_USERNAME
# export ARTIFACT_PASSWORD=$REPO_TYPEDB_PASSWORD
# bazel run @vaticle_dependencies//tool/bazelinstall:remote_cache_setup.sh
# bazel run @vaticle_dependencies//distribution/artifact:create-netrc
# bazel test //python/tests/integration:test_cloud_failover --test_output=errors
source tool/test/start-cloud-servers.sh 3 && # use source to receive export vars
bazel test //python/tests/integration:test_connection --test_env=ROOT_CA=$ROOT_CA --test_output=streamed --jobs=1 &&
# TODO currently broken test
# bazel test //python/tests/integration:test_cloud_failover --test_env=ROOT_CA=$ROOT_CA --test_output=streamed --jobs=1 &&
export CLOUD_FAILED= || export CLOUD_FAILED=1
tool/test/stop-cloud-servers.sh
if [[ -n "$CLOUD_FAILED" ]]; then exit 1; fi
test-nodejs-integration:
image: vaticle-ubuntu-22.04
Expand All @@ -322,29 +312,18 @@ build:
cp -rL bazel-bin/nodejs/dist nodejs/.
tool/test/start-core-server.sh &&
node nodejs/test/integration/test-concept.js &&
node nodejs/test/integration/test-connection.js &&
node nodejs/test/integration/test-query.js &&
export TEST_SUCCESS=0 || export TEST_SUCCESS=1
node nodejs/test/integration/test-connection-core.js &&
export CORE_FAILED= || export CORE_FAILED=1
tool/test/stop-core-server.sh
exit $TEST_SUCCESS
if [[ -n "$CORE_FAILED" ]]; then exit 1; fi
test-nodejs-cloud-failover:
machine: 4-core-16-gb
image: vaticle-ubuntu-22.04
dependencies:
- build
command: |
export ARTIFACT_USERNAME=$REPO_TYPEDB_USERNAME
export ARTIFACT_PASSWORD=$REPO_TYPEDB_PASSWORD
bazel run @vaticle_dependencies//distribution/artifact:create-netrc
bazel build //nodejs/...
cp -rL bazel-bin/nodejs/node_modules nodejs/.
cp -rL bazel-bin/nodejs/dist nodejs/.
source tool/test/start-cloud-servers.sh 3 && # use source to receive export vars
node nodejs/test/integration/test-connection-cloud.js &&
node nodejs/test/integration/test-cloud-failover.js &&
export TEST_SUCCESS=0 || export TEST_SUCCESS=1
export CLOUD_FAILED= || export CLOUD_FAILED=1
tool/test/stop-cloud-servers.sh
exit $TEST_SUCCESS
if [[ -n "$CLOUD_FAILED" ]]; then exit 1; fi
test-nodejs-behaviour-core:
image: vaticle-ubuntu-22.04
Expand Down Expand Up @@ -385,7 +364,7 @@ build:
tool/test/stop-cloud-servers.sh
exit $TEST_SUCCESS
test-cpp-integration-core:
test-cpp-integration:
image: vaticle-ubuntu-22.04
dependencies:
- build
Expand All @@ -398,10 +377,16 @@ build:
bazel run @vaticle_dependencies//tool/bazelinstall:remote_cache_setup.sh
bazel run @vaticle_dependencies//distribution/artifact:create-netrc
tool/test/start-core-server.sh &&
bazel test //cpp/test/integration/... --test_output=streamed --jobs=1 &&
export TEST_SUCCESS=0 || export TEST_SUCCESS=1
bazel test //cpp/test/integration:test-cpp-driver-core --test_output=streamed --jobs=1 &&
export CORE_FAILED= || export CORE_FAILED=1
tool/test/stop-core-server.sh
exit $TEST_SUCCESS
if [[ -n "$CORE_FAILED" ]]; then exit 1; fi
source tool/test/start-cloud-servers.sh 3 && # use source to receive export vars
bazel test //cpp/test/integration:test-cpp-driver-cloud --test_env=ROOT_CA=$ROOT_CA --test_output=streamed --jobs=1 &&
export CLOUD_FAILED= || export CLOUD_FAILED=1
tool/test/stop-cloud-servers.sh
if [[ -n "$CLOUD_FAILED" ]]; then exit 1; fi
test-cpp-behaviour-core:
image: vaticle-ubuntu-22.04
Expand Down Expand Up @@ -448,7 +433,7 @@ build:
tool/test/stop-cloud-servers.sh
exit $TEST_SUCCESS
test-csharp-integration-core:
test-csharp-integration:
image: vaticle-ubuntu-22.04
dependencies:
- build
Expand All @@ -463,25 +448,16 @@ build:
bazel test //csharp/Test/Integration/Data/... --test_output=streamed --jobs=1 &&
bazel test //csharp/Test/Integration/Marshal/... --test_output=streamed --jobs=1 &&
.factory/test-core.sh //csharp/Test/Integration/Examples/... --test_output=streamed --jobs=1 &&
export TEST_SUCCESS=0 || export TEST_SUCCESS=1
export CORE_FAILED= || export CORE_FAILED=1
tool/test/stop-core-server.sh
exit $TEST_SUCCESS
if [[ -n "$CORE_FAILED" ]]; then exit 1; fi
test-csharp-integration-cloud:
image: vaticle-ubuntu-22.04
dependencies:
- build
type: foreground
command: |
export ARTIFACT_USERNAME=$REPO_TYPEDB_USERNAME
export ARTIFACT_PASSWORD=$REPO_TYPEDB_PASSWORD
bazel run @vaticle_dependencies//tool/bazelinstall:remote_cache_setup.sh
bazel run @vaticle_dependencies//distribution/artifact:create-netrc
source tool/test/start-cloud-servers.sh &&
source tool/test/start-cloud-servers.sh 3 && # use source to receive export vars
bazel test //csharp/Test/Integration/Network/... --test_env=ROOT_CA=$ROOT_CA --test_output=streamed --jobs=1 &&
.factory/test-cloud.sh //csharp/Test/Integration/Examples/... --test_env=ROOT_CA=$ROOT_CA --test_output=streamed --jobs=1 &&
export TEST_SUCCESS=0 || export TEST_SUCCESS=1
export CLOUD_FAILED= || export CLOUD_FAILED=1
tool/test/stop-cloud-servers.sh
exit $TEST_SUCCESS
if [[ -n "$CLOUD_FAILED" ]]; then exit 1; fi
test-csharp-behaviour-core:
image: vaticle-ubuntu-22.04
Expand Down
28 changes: 28 additions & 0 deletions c/docs/connection/connection.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,34 @@ a| `credential` a| The ``Credential`` to connect with a| `const struct Credentia
.Returns
`struct Connection*`
[#_connection_open_cloud_translated]
==== connection_open_cloud_translated
[source,cpp]
----
struct Connection* connection_open_cloud_translated(const char*const* advertised_addresses, const char*const* translated_addresses, const struct Credential* credential)
----
Open a TypeDB Driver to TypeDB Cloud server(s), using provided address translation, with the provided credential.
[caption=""]
.Input parameters
[cols=",,"]
[options="header"]
|===
|Name |Description |Type
a| `advertised_addresses` a| A null-terminated array holding the address(es) the TypeDB server(s) are configured to advertise a| `const char*const*`
a| `translated_addresses` a| A null-terminated array holding the address(es) of the TypeDB server(s) the driver will connect to. This array _must_ have the same length as ``advertised_addresses`` a| `const char*const*`
a| `credential` a| The ``Credential`` to connect with a| `const struct Credential*`
|===

[caption=""]
.Returns
`struct Connection*`

[#_connection_open_core]
==== connection_open_core
Expand Down
8 changes: 4 additions & 4 deletions c/docs/connection/replica.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,17 @@ Frees the native rust ``ReplicaInfo`` object
.Returns
`void`
[#_replica_info_get_address]
==== replica_info_get_address
[#_replica_info_get_server]
==== replica_info_get_server
[source,cpp]
----
char* replica_info_get_address(const struct ReplicaInfo* replica_info)
char* replica_info_get_server(const struct ReplicaInfo* replica_info)
----
Retrieves the address of the server hosting this replica
The server hosting this replica
[caption=""]
.Returns
Expand Down
19 changes: 19 additions & 0 deletions c/src/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

use std::{ffi::c_char, path::Path};

use itertools::Itertools;
use typedb_driver::{Connection, Credential};

use super::{
Expand Down Expand Up @@ -48,6 +49,24 @@ pub extern "C" fn connection_open_cloud(
try_release(Connection::new_cloud(&addresses, borrow(credential).clone()))
}

/// Open a TypeDB Driver to TypeDB Cloud server(s), using provided address translation, with
/// the provided credential.
///
/// @param advertised_addresses A null-terminated array holding the address(es) the TypeDB server(s)
/// are configured to advertise
/// @param translated_addresses A null-terminated array holding the address(es) of the TypeDB server(s)
/// the driver will connect to. This array <i>must</i> have the same length as <code>advertised_addresses</code>
/// @param credential The <code>Credential</code> to connect with
#[no_mangle]
pub extern "C" fn connection_open_cloud_translated(
advertised_addresses: *const *const c_char,
translated_addresses: *const *const c_char,
credential: *const Credential,
) -> *mut Connection {
let addresses = string_array_view(advertised_addresses).zip_eq(string_array_view(translated_addresses)).collect();
try_release(Connection::new_cloud_with_translation(addresses, borrow(credential).clone()))
}

/// Closes the driver. Before instantiating a new driver, the driver that’s currently open should first be closed.
/// Closing a connction frees the underlying rust object.
#[no_mangle]
Expand Down
6 changes: 3 additions & 3 deletions c/src/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,10 @@ pub extern "C" fn replica_info_drop(replica_info: *mut ReplicaInfo) {
free(replica_info);
}

/// Retrieves the address of the server hosting this replica
/// The server hosting this replica
#[no_mangle]
pub extern "C" fn replica_info_get_address(replica_info: *const ReplicaInfo) -> *mut c_char {
release_string(borrow(replica_info).address.to_string())
pub extern "C" fn replica_info_get_server(replica_info: *const ReplicaInfo) -> *mut c_char {
release_string(borrow(replica_info).server.to_string())
}

/// Checks whether this is the primary replica of the raft cluster.
Expand Down
12 changes: 6 additions & 6 deletions c/swig/typedb_driver_csharp.swg
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@
%noexception user_get_username;
%noexception user_get_password_expiry_seconds;

%noexception replica_info_get_address;
%noexception replica_info_get_server;
%noexception replica_info_is_primary;
%noexception replica_info_is_preferred;
%noexception replica_info_get_term;
Expand Down Expand Up @@ -620,27 +620,27 @@
%typemap(
csin,
pre="
int arraySize = $csinput.Length;
int arraySize$csinput = $csinput.Length;
global::System.IntPtr unmanaged$csinput = System.Runtime.InteropServices.Marshal.AllocHGlobal(
(arraySize + 1) * System.Runtime.InteropServices.Marshal.SizeOf<global::System.IntPtr>());
(arraySize$csinput + 1) * System.Runtime.InteropServices.Marshal.SizeOf<global::System.IntPtr>());

unsafe
{
global::System.IntPtr* arrayPtr = (global::System.IntPtr*)unmanaged$csinput.ToPointer();

for (int i = 0; i < arraySize; i++)
for (int i = 0; i < arraySize$csinput; i++)
{
arrayPtr[i] = global::System.Runtime.InteropServices.Marshal.StringToCoTaskMemAnsi($csinput[i]);
}

arrayPtr[arraySize] = global::System.IntPtr.Zero;
arrayPtr[arraySize$csinput] = global::System.IntPtr.Zero;
}",
post="
unsafe
{
global::System.IntPtr* arrayPtr = (global::System.IntPtr*)unmanaged$csinput.ToPointer();

for (int i = 0; i < arraySize; i++)
for (int i = 0; i < arraySize$csinput; i++)
{
global::System.Runtime.InteropServices.Marshal.FreeHGlobal(arrayPtr[i]);
}
Expand Down
2 changes: 1 addition & 1 deletion c/swig/typedb_driver_java.swg
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@
%nojavaexception user_get_username;
%nojavaexception user_get_password_expiry_seconds;

%nojavaexception replica_info_get_address;
%nojavaexception replica_info_get_server;
%nojavaexception replica_info_is_primary;
%nojavaexception replica_info_is_preferred;
%nojavaexception replica_info_get_term;
Expand Down
3 changes: 2 additions & 1 deletion c/typedb_driver.i
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ void transaction_on_close_register(const Transaction* transaction, TransactionCa

%newobject connection_open_core;
%newobject connection_open_cloud;
%newobject connection_open_cloud_translated;

%newobject credential_new;

Expand All @@ -357,7 +358,7 @@ void transaction_on_close_register(const Transaction* transaction, TransactionCa
%newobject database_get_primary_replica_info;
%newobject database_get_replicas_info;

%newobject replica_info_get_address;
%newobject replica_info_get_server;
%newobject replica_info_iterator_next;

%newobject databases_all;
Expand Down
12 changes: 6 additions & 6 deletions cpp/docs/connection/Driver.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ Closes the driver. Before instantiating a new driver, the driver that’s curren
driver.close()
----

[#_static_Driver_TypeDBDrivercloudDriver___const_stdvector__stdstring____cloudAddresses__const_Credential__credential_]
[#_static_Driver_TypeDBDrivercloudDriver___const_stdvector__stdstring____addresses__const_Credential__credential_]
==== cloudDriver

[source,cpp]
----
static Driver TypeDB::Driver::cloudDriver(const std::vector< std::string >& cloudAddresses, const Credential& credential)
static Driver TypeDB::Driver::cloudDriver(const std::vector< std::string >& addresses, const Credential& credential)
----


Expand All @@ -63,7 +63,7 @@ Open a TypeDB Driver to TypeDB Cloud server(s) available at the provided address
[options="header"]
|===
|Name |Description |Type
a| `addresses` a| The address(es) of the TypeDB server(s) a|
a| `addresses` a| The address(es) of the TypeDB server(s) or translation map from addresses received from the TypeDB server(s) to addresses to be used by the driver for connection a| `const std::vector< std::string >&`
a| `credential` a| The Credential to connect with a| `const Credential&`
|===

Expand All @@ -78,12 +78,12 @@ a| `credential` a| The Credential to connect with a| `const Credential&`
Driver::cloudDriver(addresses, credential);
----

[#_static_Driver_TypeDBDrivercoreDriver___const_stdstring__coreAddress_]
[#_static_Driver_TypeDBDrivercoreDriver___const_stdstring__address_]
==== coreDriver

[source,cpp]
----
static Driver TypeDB::Driver::coreDriver(const std::string& coreAddress)
static Driver TypeDB::Driver::coreDriver(const std::string& address)
----


Expand All @@ -97,7 +97,7 @@ Open a TypeDB Driver to a TypeDB Core server available at the provided address.
[options="header"]
|===
|Name |Description |Type
a| `address` a| The address of the TypeDB server a|
a| `address` a| The address of the TypeDB server a| `const std::string&`
|===

[caption=""]
Expand Down
Loading

0 comments on commit dbc7be3

Please sign in to comment.