Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion buildSrc/src/main/kotlin/io/spine/gradle/internal/deps.kt
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ object Versions {
val javaPoet = "1.13.0"
val autoService = "1.0-rc7"
val autoCommon = "0.10"
val jackson = "2.9.10.5"
val jackson = "2.9.10.8"
val animalSniffer = "1.19"
val apiguardian = "1.1.0"
val javaxAnnotation = "1.3.2"
Expand Down
2 changes: 1 addition & 1 deletion client-js/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "spine-web",
"version": "1.7.1",
"version": "1.7.2",
"license": "Apache-2.0",
"description": "A JS client for interacting with Spine applications.",
"homepage": "https://spine.io",
Expand Down
2 changes: 1 addition & 1 deletion config
26 changes: 19 additions & 7 deletions firebase-web/src/main/java/io/spine/web/firebase/DatabaseUrls.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,29 +28,41 @@

import io.spine.net.Urls;

import static com.google.common.base.Preconditions.checkNotNull;
import static io.spine.util.Preconditions2.checkNotEmptyOrBlank;

/**
* Utilities and static factories dealing with {@link DatabaseUrl}.
*/
public final class DatabaseUrls {

/** Prevents instantiation of this utility class. */
/**
* Prevents instantiation of this utility class.
*/
private DatabaseUrls() {
}

/**
* Creates a {@code DatabaseUrls} instance from the given string.
* Creates a {@code DatabaseUrl} instance from the given string.
*
* @param url
* @param dbUrl
* a {@code String} containing database URL
* @return a new instance of {@code DatabaseUrls}
* @return a new instance of {@code DatabaseUrl}
* @see com.google.firebase.database.util.EmulatorHelper
*/
public static DatabaseUrl from(String url) {
checkNotNull(url);
public static DatabaseUrl from(String dbUrl) {
checkNotEmptyOrBlank(dbUrl);
String namespace = "";
String url = dbUrl;
String namespaceQuery = "?ns=";
int queryIndex = dbUrl.indexOf(namespaceQuery);
if (queryIndex > 0) {
namespace = dbUrl.substring(queryIndex + namespaceQuery.length());
url = dbUrl.substring(0, queryIndex);
}
return DatabaseUrl
.newBuilder()
.setUrl(Urls.create(url))
.setNamespace(namespace)
.vBuild();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
import io.spine.web.firebase.DatabaseUrl;
import io.spine.web.firebase.NodePath;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Strings.isNullOrEmpty;
import static java.lang.String.format;

/**
Expand All @@ -40,25 +42,46 @@
*/
final class RestNodeUrls {

private final String template;
private final DatabaseUrl database;

RestNodeUrls(DatabaseUrl url) {
this.template = Urls.toString(url.getUrl()) + "/%s.json";
/**
* Creates a new factory for the specified {@code database}.
*/
RestNodeUrls(DatabaseUrl database) {
this.database = checkNotNull(database);
}

/**
* Creates a new {@link RestNodeUrl} for a node at the specified {@link NodePath path}.
*/
RestNodeUrl with(NodePath path) {
Url url = Urls.create(format(template, path.getValue()));
checkNotNull(path);
Url url = withinDatabase(path);
RestNodeUrl node = RestNodeUrl
.newBuilder()
.setUrl(url)
.vBuild();
return node;
}

private Url withinDatabase(NodePath path) {
Url dbUrl = database.getUrl();
String result;
if (isNullOrEmpty(database.getNamespace())) {
result = format("%s/%s.json", dbUrl.getSpec(), path.getValue());
} else {
result = format(
"%s/%s.json?ns=%s", dbUrl.getSpec(), path.getValue(), database.getNamespace()
);
}
return Urls.create(result);
}

/**
* Converts supplied {@code node} into a {@code GenericUrl}.
*/
static GenericUrl asGenericUrl(RestNodeUrl node) {
checkNotNull(node);
GenericUrl url = new GenericUrl(Urls.toString(node.getUrl()));
return url;
}
Expand Down
12 changes: 12 additions & 0 deletions firebase-web/src/main/proto/spine/web/firebase/client.proto
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,20 @@ import "spine/net/url.proto";

// A Firebase database URL.
//
// The Firebase endpoint URL may be of two formats.
// The first one is a URL to connect to a remote database which must be specified as
// `https://<project-id>.firebaseio.com` or `https://<database-alias>.firebaseio.com`.
// The second one is a URL to connect to an emulator database that has the following format:
// `http://<local-ip>:<local-port>?ns=<database-alias>`. The `ns` stands for a `namespace`
// and by default is set to the project ID.
//
message DatabaseUrl {

// The Firebase RDB endpoint.
spine.net.Url url = 1 [(required) = true];

// The namespace to connect to.
string namespace = 2;
}

// A path in a Firebase Realtime Database.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,35 @@
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;

@DisplayName("`DatabaseUrls` should")
class DatabaseUrlsTest extends UtilityClassTest<DatabaseUrls> {

private static final String VALID_URL = "https://spine-dev.appspot.com/";

DatabaseUrlsTest() {
super(DatabaseUrls.class);
}

@Test
@DisplayName("be successfully created from valid URL")
void acceptValidUrl() {
DatabaseUrl url = DatabaseUrls.from(VALID_URL);
@DisplayName("be created from a remote RDB URL")
void acceptRemoteRdb() {
String dbUrl = "https://spine-dev.firebaseio.com";
DatabaseUrl url = DatabaseUrls.from(dbUrl);
assertThat(url.getUrl())
.isEqualTo(Urls.create(dbUrl));
assertThat(url.getNamespace())
.isEmpty();
}

@Test
@DisplayName("be created from a local emulator URL")
void acceptLocalEmulator() {
String dbUrl = "http://localhost:5000?ns=spine-dev";
DatabaseUrl url = DatabaseUrls.from(dbUrl);
assertThat(url.getUrl())
.isEqualTo(Urls.create(VALID_URL));
.isEqualTo(Urls.create("http://localhost:5000"));
assertThat(url.getNamespace())
.isEqualTo("spine-dev");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Copyright 2021, TeamDev. All rights reserved.
*
* 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
*
* Redistribution and use in source and/or binary forms, with or without
* modification, must retain the above copyright notice and the following
* disclaimer.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package io.spine.web.firebase.rest;

import com.google.common.testing.NullPointerTester;
import com.google.common.testing.NullPointerTester.Visibility;
import io.spine.net.Urls;
import io.spine.web.firebase.DatabaseUrl;
import io.spine.web.firebase.DatabaseUrls;
import io.spine.web.firebase.NodePaths;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;

@DisplayName("`RestNodeUrls` should")
final class RestNodeUrlsTest {

@Test
@DisplayName("not accept `null`s")
void notAcceptNulls() {
NullPointerTester tester = new NullPointerTester();
tester.testConstructors(RestNodeUrls.class, Visibility.PACKAGE);
tester.testAllPublicInstanceMethods(new RestNodeUrls(DatabaseUrl.getDefaultInstance()));
}

@Test
@DisplayName("create a `RestNodeUrl` for the specified `NodePath` and remote RDB")
void createRemoteDbUrl() {
String dbUrl = "https://spine-dev.firebaseio.com";
RestNodeUrls factory = new RestNodeUrls(DatabaseUrls.from(dbUrl));
String node = "subscriptions/111";
RestNodeUrl result = factory.with(NodePaths.of(node));
assertThat(result.getUrl())
.isEqualTo(Urls.create(dbUrl + '/' + node + ".json"));
}

@Test
@DisplayName("create a `RestNodeUrl` for the specified `NodePath` and local emulator")
void createEmulatorUrl() {
String dbUrl = "http://localhost:5000?ns=spine-dev";
RestNodeUrls factory = new RestNodeUrls(DatabaseUrls.from(dbUrl));
String node = "query/currentYear";
RestNodeUrl result = factory.with(NodePaths.of(node));
assertThat(result.getUrl())
.isEqualTo(Urls.create("http://localhost:5000/" + node + ".json?ns=spine-dev"));
}
}
2 changes: 1 addition & 1 deletion integration-tests/js-tests/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "client-js-tests",
"version": "1.7.1",
"version": "1.7.2",
"license": "Apache-2.0",
"description": "Tests of a `spine-web` JS library against the Spine-based application.",
"scripts": {
Expand Down
Loading