Skip to content

Commit

Permalink
[RKOTLIN-1023] Add support for changing App Services base URL (#1733)
Browse files Browse the repository at this point in the history
Co-authored-by: Claus Rørbech <[email protected]>
  • Loading branch information
clementetb and rorbech authored May 1, 2024
1 parent 3f2f9aa commit 8704401
Show file tree
Hide file tree
Showing 11 changed files with 237 additions and 22 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/include-deploy-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ on:

jobs:
deploy:
runs-on: macos-latest
runs-on: macos-12
name: Deploy release

steps:
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/include-integration-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:

# TODO: The Monkey seems to crash the app all the time, but with failures that are not coming from the app. Figure out why.
# android-sample-app:
# runs-on: macos-latest
# runs-on: macos-12
# steps:
# - name: Checkout code
# uses: actions/checkout@v3
Expand Down Expand Up @@ -87,7 +87,7 @@ jobs:
./gradlew assembleDebug jvmJar
realm-java-compatibiliy:
runs-on: macos-latest
runs-on: macos-12
steps:
- name: Checkout code
uses: actions/checkout@v3
Expand Down Expand Up @@ -217,7 +217,7 @@ jobs:
- type: gradle75
path: integration-tests/gradle/gradle75-test
arguments: integrationTest
runs-on: macos-latest
runs-on: macos-12
steps:
- uses: actions/checkout@v3

Expand Down Expand Up @@ -295,7 +295,7 @@ jobs:
- type: gradle8
path: integration-tests/gradle/gradle8-test
arguments: integrationTest
runs-on: macos-latest
runs-on: macos-12
steps:
- uses: actions/checkout@v3

Expand Down
32 changes: 16 additions & 16 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ jobs:
retention-days: 1

build-jvm-macos-native-lib:
runs-on: macos-latest
runs-on: macos-12
needs: [check-cache, build-jni-swig-stub]
if: |
always() &&
Expand Down Expand Up @@ -395,7 +395,7 @@ jobs:
# This task is also responsible for creating the Gradle and Compiler Plugin as well as
# all Kotlin Multiplatform Metadata
build-jvm-packages:
runs-on: macos-latest
runs-on: macos-12
needs: [check-cache, build-jvm-linux-native-lib, build-jvm-windows-native-lib, build-jvm-macos-native-lib]
if: |
always() &&
Expand Down Expand Up @@ -638,7 +638,7 @@ jobs:
# TODO: ccache is not being used by this build for some reason
build-macos-x64-packages:
runs-on: macos-latest
runs-on: macos-12
needs: check-cache
if: always() && !cancelled() && needs.check-cache.outputs.packages-macos-x64-cache-hit != 'true'

Expand Down Expand Up @@ -706,7 +706,7 @@ jobs:
retention-days: 1

build-macos-arm64-packages:
runs-on: macos-latest
runs-on: macos-12
needs: check-cache
# needs: static-analysis
if: always() && !cancelled() && needs.check-cache.outputs.packages-macos-arm64-cache-hit != 'true'
Expand Down Expand Up @@ -774,7 +774,7 @@ jobs:
retention-days: 1

build-ios-x64-packages:
runs-on: macos-latest
runs-on: macos-12
needs: check-cache
# needs: static-analysis
if: always() && !cancelled() && needs.check-cache.outputs.packages-ios-x64-cache-hit != 'true'
Expand Down Expand Up @@ -843,7 +843,7 @@ jobs:
retention-days: 1

build-ios-arm64-packages:
runs-on: macos-latest
runs-on: macos-12
needs: check-cache
# needs: static-analysis
if: always() && !cancelled() && needs.check-cache.outputs.packages-ios-arm64-cache-hit != 'true'
Expand Down Expand Up @@ -931,7 +931,7 @@ jobs:
- type: sync
test-title: Unit Test Results - Android Sync (Emulator)

runs-on: macos-latest
runs-on: macos-12
needs: [check-cache, build-android-packages, build-jvm-packages, build-kotlin-metadata-package]
if: |
always() &&
Expand Down Expand Up @@ -1175,15 +1175,15 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [macos-latest] # , macos-arm]
os: [macos-12] # , macos-arm]
type: [base, sync]
include:
- os: macos-latest
- os: macos-12
type: base
os-id: macos
package-prefix: macos-x64
test-title: Unit Test Results - MacOS x64 Base
- os: macos-latest
- os: macos-12
type: sync
os-id: macos
package-prefix: macos-x64
Expand Down Expand Up @@ -1297,15 +1297,15 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [macos-latest] # , macos-arm]
os: [macos-12] # , macos-arm]
type: [base, sync]
include:
- os: macos-latest
- os: macos-12
type: base
package-prefix: x64
test-title: Unit Test Results - iOS x64 Base
test-task: iosTest
- os: macos-latest
- os: macos-12
type: sync
package-prefix: x64
test-title: Unit Test Results - iOS x64 Sync
Expand Down Expand Up @@ -1419,10 +1419,10 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [macos-latest, ubuntu-latest, windows-latest] # TODO Should we also test om MacOS arm64?
os: [macos-12, ubuntu-latest, windows-latest] # TODO Should we also test om MacOS arm64?
type: [base, sync]
include:
- os: macos-latest
- os: macos-12
os-id: mac
type: base
test-title: Unit Test Results - Base JVM MacOS x64
Expand All @@ -1434,7 +1434,7 @@ jobs:
os-id: win
type: base
test-title: Unit Test Results - Base JVM Windows
- os: macos-latest
- os: macos-12
os-id: mac
type: sync
test-title: Unit Test Results - Sync JVM MacOS x64
Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ This release will bump the Realm file format from version 23 to 24. Opening a fi
* None.

### Enhancements
* None.
* Add support for changing the App Services base URL. It allows to roam between Atlas and Edge Server. Changing the url would trigger a client reset. (Issue [#1659](https://github.com/realm/realm-kotlin/issues/1659)/[RKOTLIN-1013](https://jira.mongodb.org/browse/RKOTLIN-1023))

### Fixed
* None.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,16 @@ expect object RealmInterop {
callback: AppCallback<Array<ApiKeyWrapper>>,
)

fun realm_app_get_base_url(
app: RealmAppPointer,
): String

fun realm_app_update_base_url(
app: RealmAppPointer,
baseUrl: String?,
callback: AppCallback<Unit>,
)

// User
fun realm_user_get_all_identities(user: RealmUserPointer): List<SyncUserIdentity>
fun realm_user_get_identity(user: RealmUserPointer): String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1170,6 +1170,18 @@ actual object RealmInterop {
return result
}

actual fun realm_app_get_base_url(
app: RealmAppPointer,
): String = realmc.realm_app_get_base_url(app.cptr())

actual fun realm_app_update_base_url(
app: RealmAppPointer,
baseUrl: String?,
callback: AppCallback<Unit>,
) {
realmc.realm_app_update_base_url(app.cptr(), baseUrl, callback)
}

actual fun realm_user_get_all_identities(user: RealmUserPointer): List<SyncUserIdentity> {
val count = AuthProvider.values().size.toLong() // Optimistically allocate the max size of the array
val keys = realmc.new_identityArray(count.toInt())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2309,6 +2309,33 @@ actual object RealmInterop {
.also { realm_wrapper.realm_free(cPath) }
}

actual fun realm_app_get_base_url(
app: RealmAppPointer,
): String = realm_wrapper.realm_app_get_base_url(app.cptr())?.toKString()!!

actual fun realm_app_update_base_url(
app: RealmAppPointer,
baseUrl: String?,
callback: AppCallback<Unit>,
) {
checkedBooleanResult(
realm_wrapper.realm_app_update_base_url(
app.cptr(),
baseUrl,
callback = staticCFunction { userData, error ->
handleAppCallback(
userData,
error
) { /* No-op, returns Unit */ }
},
StableRef.create(callback).asCPointer(),
staticCFunction { userdata ->
disposeUserData<AppCallback<Unit>>(userdata)
}
)
)
}

actual fun realm_user_get_all_identities(user: RealmUserPointer): List<SyncUserIdentity> {
memScoped {
val count = AuthProvider.values().size
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package io.realm.kotlin.mongodb

import io.realm.kotlin.internal.util.Validation
import io.realm.kotlin.mongodb.annotations.ExperimentalEdgeServerApi
import io.realm.kotlin.mongodb.auth.EmailPasswordAuth
import io.realm.kotlin.mongodb.exceptions.AppException
import io.realm.kotlin.mongodb.exceptions.AuthException
Expand Down Expand Up @@ -84,6 +85,23 @@ public interface App {
*/
public val sync: Sync

/**
* Current base URL to communicate with App Services.
*/
@ExperimentalEdgeServerApi
public val baseUrl: String

/**
* Sets the App Services base url.
*
* *NOTE* Changing the URL would trigger a client reset.
*
* @param baseUrl The new App Services base url. If `null` it will be using the default value
* ([AppConfiguration.DEFAULT_BASE_URL]).
*/
@ExperimentalEdgeServerApi
public suspend fun updateBaseUrl(baseUrl: String?)

/**
* Returns all known users that are either [User.State.LOGGED_IN] or [User.State.LOGGED_OUT].
* Only users that at some point logged into this device will be returned.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright 2024 Realm Inc.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package io.realm.kotlin.mongodb.annotations

/**
* This annotation mark Realm APIs specific to the Atlas Edge server and are considered
* **experimental**, i.e. there are no guarantees given that these APIs cannot change without
* warning between minor and major versions. They will not change between patch versions.
*
* For all other purposes these APIs are considered stable, i.e. they undergo the same testing
* as other parts of the API and should behave as documented with no bugs. They are primarily
* marked as experimental because we are unsure if these APIs provide value and solve the use
* cases that people have. If not, they will be changed or removed altogether.
*/
@MustBeDocumented
@Target(
AnnotationTarget.CLASS,
AnnotationTarget.PROPERTY,
AnnotationTarget.FUNCTION,
AnnotationTarget.TYPEALIAS
)
@RequiresOptIn(level = RequiresOptIn.Level.ERROR)
public annotation class ExperimentalEdgeServerApi
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import io.realm.kotlin.mongodb.AppConfiguration
import io.realm.kotlin.mongodb.AuthenticationChange
import io.realm.kotlin.mongodb.Credentials
import io.realm.kotlin.mongodb.User
import io.realm.kotlin.mongodb.annotations.ExperimentalEdgeServerApi
import io.realm.kotlin.mongodb.auth.EmailPasswordAuth
import io.realm.kotlin.mongodb.sync.Sync
import io.realm.kotlin.types.RealmInstant
Expand Down Expand Up @@ -63,6 +64,24 @@ public class AppImpl(
@Suppress("MagicNumber")
private val reconnectThreshold = 5.seconds

@ExperimentalEdgeServerApi
override val baseUrl: String
get() = RealmInterop.realm_app_get_base_url(nativePointer)

@ExperimentalEdgeServerApi
override suspend fun updateBaseUrl(baseUrl: String?) {
Channel<Result<Unit>>(1).use { channel ->
RealmInterop.realm_app_update_base_url(
app = nativePointer,
baseUrl = baseUrl?.trimEnd('/'), // trailing slashes are not handled properly in core
callback = channelResultCallback<Unit, Unit>(channel) {
// No-op
}
)
channel.receive().getOrThrow()
}
}

@Suppress("invisible_member", "invisible_reference", "MagicNumber")
private val connectionListener = NetworkStateObserver.ConnectionListener { connectionAvailable ->
// In an ideal world, we would be able to reliably detect the network coming and
Expand Down
Loading

0 comments on commit 8704401

Please sign in to comment.