Skip to content

Commit

Permalink
Add platform networking section to kotlin
Browse files Browse the repository at this point in the history
  • Loading branch information
cbullinger committed Mar 18, 2024
1 parent 7db4302 commit 9fa1d15
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 65 deletions.
4 changes: 2 additions & 2 deletions examples/kotlin/settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pluginManagement {
dependencyResolutionManagement {
versionCatalogs {
create("libs") {
version("realm", "1.13.0")
version("realm", "1.14.0")
version("kotlinx-coroutines", "1.7.0")
version("kotlinx-serialization", "1.5.0")
library("realm-plugin", "io.realm.kotlin", "gradle-plugin").versionRef("realm")
Expand All @@ -25,4 +25,4 @@ dependencyResolutionManagement {

rootProject.name = "RealmKMMApp"
include(":androidRealmKMMApp")
include(":shared")
include(":shared")
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.mongodb.realm.realmkmmapp

import io.realm.kotlin.internal.interop.sync.WebSocketObserver
import io.realm.kotlin.internal.platform.runBlocking
import io.realm.kotlin.log.LogLevel
import io.realm.kotlin.log.RealmLog
Expand All @@ -10,7 +11,10 @@ import io.realm.kotlin.mongodb.Credentials
import io.realm.kotlin.mongodb.exceptions.ConnectionException
import io.realm.kotlin.mongodb.exceptions.InvalidCredentialsException
import io.realm.kotlin.mongodb.exceptions.ServiceException
import io.realm.kotlin.mongodb.internal.AppResources
import io.realm.kotlin.mongodb.internal.platformWebsocketClient
import kotlinx.coroutines.channels.Channel
import kotlin.test.Ignore
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
Expand All @@ -19,7 +23,6 @@ import kotlin.time.Duration.Companion.minutes
import kotlin.time.Duration.Companion.seconds



class AppClientTest: RealmTest() {
@Test
fun initializeAndCloseAppClientTest() {
Expand Down Expand Up @@ -95,8 +98,8 @@ class AppClientTest: RealmTest() {
@Test
fun encryptAppMetadata() {
val myEncryptionKey = getEncryptionKey()
val config =
// :snippet-start: encrypted-app-client
val config =
AppConfiguration.Builder(YOUR_APP_ID)
// Specify the encryption key
.encryptionKey(myEncryptionKey)
Expand All @@ -105,6 +108,25 @@ class AppClientTest: RealmTest() {
assertTrue(config.encryptionKey.contentEquals(myEncryptionKey))
}

@Ignore
// Ignored unless there's a way to test this in a reasonable way...
fun enablePlatformNetworking() {
// :snippet-start: enable-platform-networking
val config =
AppConfiguration.Builder(YOUR_APP_ID)
.usePlatformNetworking(true)
.build()
val webSocketTransport = platformWebsocketClient(
observer = WebSocketObserver,
path = String,
address = String,
port = Long,
isSsl = false,
supportedSyncProtocols = String,
transport = String)
// :snippet-end:
}

@Test
fun setCustomHttpHeadersTest() {
val config1 = AppConfiguration.Builder(YOUR_APP_ID)
Expand Down Expand Up @@ -202,4 +224,4 @@ class AppClientTest: RealmTest() {
app.close()
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
val config =
AppConfiguration.Builder(YOUR_APP_ID)
.usePlatformNetworking(true)
.build()
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
AppConfiguration.Builder(YOUR_APP_ID)
// Specify the encryption key
.encryptionKey(myEncryptionKey)
.build()
val config =
AppConfiguration.Builder(YOUR_APP_ID)
// Specify the encryption key
.encryptionKey(myEncryptionKey)
.build()
138 changes: 82 additions & 56 deletions source/sdk/kotlin/app-services/connect-to-app-services-backend.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Connect to Atlas App Services - Kotlin SDK

.. meta::
:keywords: code example
:description: Initialize your app client and connect to the Atlas App Services backend using the Kotlin SDK.
:description: Initialize your app client and connect to the Atlas App Services backend using the Kotlin SDK.

.. facet::
:name: genre
Expand All @@ -18,42 +18,42 @@ Connect to Atlas App Services - Kotlin SDK
:depth: 2
:class: singlecol

This page describes how to initialize your App client and connect to the Atlas
This page describes how to initialize your App client and connect to the Atlas
App Services backend using the Kotlin SDK.

The App client is the interface to the App Services backend. It provides
The App client is the interface to the App Services backend. It provides
access to App Services functionality, including:

- :ref:`Authenticating <kotlin-authenticate>` app users
- :ref:`Synchronizing data <kotlin-sync>` between the Atlas backend and the
- :ref:`Synchronizing data <kotlin-sync>` between the Atlas backend and the
client app using Device Sync
- :ref:`Calling Atlas functions <kotlin-call-function>`

Each App client is associated with a single App ID.
Each App client is associated with a single App ID.

Prerequisites
-------------

Before you can connect to Atlas App Services, you need an App Services App
with an App ID. To get started, refer to :ref:`Create an App <create-a-realm-app>`
Before you can connect to Atlas App Services, you need an App Services App
with an App ID. To get started, refer to :ref:`Create an App <create-a-realm-app>`
in the App Services documentation.

To learn how to find your App ID in the App Services UI, refer to
To learn how to find your App ID in the App Services UI, refer to
:ref:`Find Your App ID <find-your-app-id>` in the App Services documentation.

.. _kotlin-access-the-app-client:

Access the App Client
---------------------

The Kotlin SDK uses the
The Kotlin SDK uses the
`App <{+kotlin-sync-prefix+}io.realm.kotlin.mongodb/-app/index.html>`__
interface to access an ``App`` client.
interface to access an ``App`` client.

You can initialize an App with default configuration values using
`App.create()
<{+kotlin-sync-prefix+}io.realm.kotlin.mongodb/-app-configuration/-companion/create.html>`__.
You only need to pass the App ID for your App.
You can initialize an App with default configuration values using
`App.create()
<{+kotlin-sync-prefix+}io.realm.kotlin.mongodb/-app-configuration/-companion/create.html>`__.
You only need to pass the App ID for your App.

.. literalinclude:: /examples/generated/kotlin/AppClientTest.snippet.initialize-app-client.kt
:language: kotlin
Expand All @@ -67,12 +67,12 @@ Configure the App Client
------------------------

You can add optional arguments to the ``AppConfiguration`` for more
granular control of your app connection details, such as custom
request headers and keys for local encryption.
granular control of your app connection details, such as custom
request headers and keys for local encryption.

To control the additional configuration options, use the
To control the additional configuration options, use the
`AppConfiguration.Builder
<{+kotlin-sync-prefix+}io.realm.kotlin.mongodb/-app-configuration/-builder/index.html>`__
<{+kotlin-sync-prefix+}io.realm.kotlin.mongodb/-app-configuration/-builder/index.html>`__
and call the ``.build()`` method to pass a configuration object:

.. literalinclude:: /examples/generated/kotlin/AppClientTest.snippet.configure-app-client.kt
Expand All @@ -89,32 +89,32 @@ Share Sync Connections

.. versionadded:: 1.13.0

By default, the SDK opens a separate connection to the server for
By default, the SDK opens a separate connection to the server for
each synced realm. In Kotlin v1.13.0 and later, you can enable
**session multiplexing**. When enabled, the SDK
shares a connection to the server for all synced realms opened with
a single App Services user. Sharing a connection across multiple
sessions reduces resources and can improve performance.
**session multiplexing**. When enabled, the SDK
shares a connection to the server for all synced realms opened with
a single App Services user. Sharing a connection across multiple
sessions reduces resources and can improve performance.

Multiplexing is disabled by default. You can enable it on the
``AppConfiguration`` using the `.enableSessionMultiplexing()
<{+kotlin-sync-prefix+}io.realm.kotlin.mongodb/-app-configuration/-builder/index.html#-839865185%2FFunctions%2F380376748>`__
method, which accepts a Boolean value.
Multiplexing is disabled by default. You can enable it on the
``AppConfiguration`` using the `.enableSessionMultiplexing()
<{+kotlin-sync-prefix+}io.realm.kotlin.mongodb/-app-configuration/-builder/index.html#-839865185%2FFunctions%2F380376748>`__
method, which accepts a Boolean value.

.. literalinclude:: /examples/generated/kotlin/AppClientTest.snippet.enable-multiplexing.kt
:language: kotlin

When enabled, the shared connection does not immediately close when all sessions are closed.
Instead, it remains open for the ``connectionLingerTime``, which defaults to
30 seconds. You can override this duration by passing a new value to
`SyncTimeoutOptions.connectionLingerTime()
<{+kotlin-sync-prefix+}io.realm.kotlin.mongodb.sync/-sync-timeout-options/connection-linger-time.html>`__
on the ``AppConfiguration``.
Instead, it remains open for the ``connectionLingerTime``, which defaults to
30 seconds. You can override this duration by passing a new value to
`SyncTimeoutOptions.connectionLingerTime()
<{+kotlin-sync-prefix+}io.realm.kotlin.mongodb.sync/-sync-timeout-options/connection-linger-time.html>`__
on the ``AppConfiguration``.

.. literalinclude:: /examples/generated/kotlin/AppClientTest.snippet.enable-multiplexing-with-timeout.kt
:language: kotlin

For more information, refer to the
For more information, refer to the
:ref:`kotlin-configure-sync-timeouts` section on this page.

.. _kotlin-configure-sync-timeouts:
Expand All @@ -126,39 +126,39 @@ Configure Sync Timeouts

.. versionadded:: 1.13.0

In Kotlin v1.13.0 and later, you can override the default
timeout settings used when syncing data between the Atlas backend
In Kotlin v1.13.0 and later, you can override the default
timeout settings used when syncing data between the Atlas backend
and the client app.

You can set various sync timeout settings on the
You can set various sync timeout settings on the
``AppConfiguration`` using the `.syncTimeouts()
<{+kotlin-sync-prefix+}io.realm.kotlin.mongodb/-app-configuration/-builder/index.html#90306255%2FFunctions%2F380376748>`__
method. Pass specific timeout property values you want to override. The
<{+kotlin-sync-prefix+}io.realm.kotlin.mongodb/-app-configuration/-builder/index.html#90306255%2FFunctions%2F380376748>`__
method. Pass specific timeout property values you want to override. The
configured timeouts apply to all sync sessions in the app.

.. literalinclude:: /examples/generated/kotlin/AppClientTest.snippet.sync-timeout-configuration.kt
:language: kotlin

For a complete list of the available timeout properties and their
For a complete list of the available timeout properties and their
definitions, refer to the
`SyncTimeoutOptionsBuilder <{+kotlin-sync-prefix+}io.realm.kotlin.mongodb.sync/-sync-timeout-options-builder/index.html>`__
`SyncTimeoutOptionsBuilder <{+kotlin-sync-prefix+}io.realm.kotlin.mongodb.sync/-sync-timeout-options-builder/index.html>`__
API reference.

.. _kotlin-encrypt-app-metadata:

Encrypt App Metadata
Encrypt App Metadata
~~~~~~~~~~~~~~~~~~~~

When you connect to App Services, Realm creates additional metadata files on
a device. For more information about these metadata files, refer to
When you connect to App Services, Realm creates additional metadata files on
a device. For more information about these metadata files, refer to
:ref:`<kotlin-realm-database-internals>`.

You can encrypt the metadata that App Services stores on client devices,
similar to how you :ref:`<kotlin-encrypt-a-synced-realm>`.
similar to how you :ref:`<kotlin-encrypt-a-synced-realm>`.

To encrypt App metadata, pass your encryption key to the
To encrypt App metadata, pass your encryption key to the
`encryptionKey <{+kotlin-sync-prefix+}io.realm.kotlin.mongodb/-app-configuration/encryption-key.html>`__
property when you initialize the App:
property when you initialize the App:

.. literalinclude:: /examples/generated/kotlin/AppClientTest.snippet.encrypted-app-client.kt
:language: kotlin
Expand All @@ -168,29 +168,55 @@ Set Custom HTTP Headers

.. versionadded:: 1.11.0

If you use App Services or Device Sync with a proxy setup, you may need to set
custom HTTP headers. The Realm Kotlin SDK supports setting custom HTTP headers
on the App. These headers are appended to every request to the App Services
If you use App Services or Device Sync with a proxy setup, you may need to set
custom HTTP headers. The Kotlin SDK supports setting custom HTTP headers
on the App. These headers are appended to every request to the App Services
App, including :ref:`function calls <kotlin-call-function>`.

When you initialize the App, you can pass:
When you initialize the App, you can pass:

- the custom `authorizationHeaderName
- the custom `authorizationHeaderName
<{+kotlin-sync-prefix+}io.realm.kotlin.mongodb/-app-configuration/authorization-header-name.html>`__
``String`` value
- any `customRequestHeaders
<{+kotlin-sync-prefix+}io.realm.kotlin.mongodb/-app-configuration/custom-request-headers.html>`__
in a map of ``String`` header keys and values (SDK accepts empty values but
- any `customRequestHeaders
<{+kotlin-sync-prefix+}io.realm.kotlin.mongodb/-app-configuration/custom-request-headers.html>`__
in a map of ``String`` header keys and values (SDK accepts empty values but
not empty keys)

.. literalinclude:: /examples/generated/kotlin/AppClientTest.snippet.set-custom-http-headers.kt
:language: kotlin

.. _kotlin-enable-platform-networking:

Enable Platform Networking
--------------------------

.. versionadded:: 1.14.0

Kotlin SDK v1.14.0 introduces **platform networking** support for Atlas Device
Sync traffic. This feature allows applications running on Android and
Java Virtual Machine (JVM) platforms to enable managed WebSockets via
:github:`OkHttp </square/okhttp/blob/master/CHANGELOG.md>` instead of the
database's default C++ WebSocket client. Managed WebSockets provide advanced
proxy configuration support for firewalls and allow for
certificate pinning and other advanced networking features.

To enable managed WebSockets, pass the `AppConfiguration.usePlatformNetworking()
<{+kotlin-sync-prefix+}io.realm.kotlin.mongodb/-app-configuration/-builder/use-platform-networking.html>`__
method when you initialize the App:

.. literalinclude:: /examples/generated/kotlin/AppClientTest.snippet.enable-platform-networking.kt
:language: kotlin

.. note::

This feature is currently only available on Android and JVM platforms.

Close the App Client
--------------------

You can manually close an App instance and release all underlying resources
using the `App.close()
You can manually close an App instance and release all underlying resources
using the `App.close()
<{+kotlin-sync-prefix+}io.realm.kotlin.mongodb/-app/close.html>`__ method:

.. literalinclude:: /examples/generated/kotlin/AppClientTest.snippet.close-app-client.kt
Expand Down

0 comments on commit 9fa1d15

Please sign in to comment.