diff --git a/.gitignore b/.gitignore
index 22bfc4f7d..b18ee9b69 100644
--- a/.gitignore
+++ b/.gitignore
@@ -29,8 +29,6 @@ gcs-auth-key.json
# They are stored in the encrypted file and are decrypted on the CI server only.
# This file extracted form credentials.tar
-spine-dev*.json
-/datastore/src/test/resources/spine-dev.json
-/stackdriver-trace/src/test/resources/spine-dev.json
+**/spine-dev*.json
package-lock.json
diff --git a/config b/config
index 6a07e48f8..ad7e43fe6 160000
--- a/config
+++ b/config
@@ -1 +1 @@
-Subproject commit 6a07e48f83113e89198f75462a76911e74546152
+Subproject commit ad7e43fe61289282a1662b21ec35d2c78d212ebd
diff --git a/datastore/src/main/java/io/spine/server/storage/datastore/DatastoreWrapper.java b/datastore/src/main/java/io/spine/server/storage/datastore/DatastoreWrapper.java
index 4fda458ad..49227af1c 100644
--- a/datastore/src/main/java/io/spine/server/storage/datastore/DatastoreWrapper.java
+++ b/datastore/src/main/java/io/spine/server/storage/datastore/DatastoreWrapper.java
@@ -432,6 +432,17 @@ private void deleteEntities(Key[] keys) {
}
}
+ /**
+ * Starts a new database transaction.
+ *
+ * @return the new transaction
+ * @see TransactionWrapper
+ */
+ public final TransactionWrapper newTransaction() {
+ Transaction tx = datastore.newTransaction();
+ return new TransactionWrapper(tx);
+ }
+
/**
* Starts a transaction.
*
@@ -443,7 +454,9 @@ private void deleteEntities(Key[] keys) {
* if a transaction is already started on this instance of
* {@code DatastoreWrapper}
* @see #isTransactionActive()
+ * @deprecated Use {@link #newTransaction()} instead.
*/
+ @Deprecated
public void startTransaction() throws IllegalStateException {
checkState(!isTransactionActive(), NOT_ACTIVE_TRANSACTION_CONDITION_MESSAGE);
activeTransaction = datastore.newTransaction();
@@ -461,7 +474,9 @@ public void startTransaction() throws IllegalStateException {
* if no transaction is started on this instance of
* {@code DatastoreWrapper}
* @see #isTransactionActive()
+ * @deprecated Use {@link #newTransaction()} instead.
*/
+ @Deprecated
public void commitTransaction() throws IllegalStateException {
checkState(isTransactionActive(), ACTIVE_TRANSACTION_CONDITION_MESSAGE);
activeTransaction.commit();
@@ -481,7 +496,9 @@ public void commitTransaction() throws IllegalStateException {
* if no transaction is active for the current
* instance of {@code DatastoreWrapper}
* @see #isTransactionActive()
+ * @deprecated Use {@link #newTransaction()} instead.
*/
+ @Deprecated
public void rollbackTransaction() throws IllegalStateException {
checkState(isTransactionActive(), ACTIVE_TRANSACTION_CONDITION_MESSAGE);
activeTransaction.rollback();
@@ -492,7 +509,9 @@ public void rollbackTransaction() throws IllegalStateException {
* Checks whether there is an active transaction on this instance of {@code DatastoreWrapper}.
*
* @return {@code true} if there is an active transaction, {@code false} otherwise
+ * @deprecated Use {@link #newTransaction()} instead.
*/
+ @Deprecated
public boolean isTransactionActive() {
return activeTransaction != null && activeTransaction.isActive();
}
diff --git a/datastore/src/main/java/io/spine/server/storage/datastore/DsMessageStorage.java b/datastore/src/main/java/io/spine/server/storage/datastore/DsMessageStorage.java
index 62bf0fb82..1d8a4a5e4 100644
--- a/datastore/src/main/java/io/spine/server/storage/datastore/DsMessageStorage.java
+++ b/datastore/src/main/java/io/spine/server/storage/datastore/DsMessageStorage.java
@@ -141,31 +141,20 @@ public final void write(I id, M message) {
* Behaves similarly to {@link #write(Message)}, but performs the operation
* in scope of a Datastore transaction.
*
- *
If there is no active transaction at the moment, the new transaction is started
- * and committed. In case there is already an active transaction, the write operation
- * is performed in its scope.
- *
* @param message
* the message to write
*/
- @SuppressWarnings("OverlyBroadCatchBlock") // handling all possible transaction-related issues.
final void writeTransactionally(M message) {
checkNotNull(message);
- boolean txRequired = !datastore.isTransactionActive();
- if (txRequired) {
- datastore.startTransaction();
- }
- try {
- write(message);
- if (txRequired) {
- datastore.commitTransaction();
- }
- } catch (Exception e) {
- if (txRequired && datastore.isTransactionActive()) {
- datastore.rollbackTransaction();
- }
- throw newIllegalStateException("Error committing the transaction.", e);
+ try (TransactionWrapper tx = datastore.newTransaction()) {
+ Entity entity = toEntity(message);
+ tx.createOrUpdate(entity);
+ tx.commit();
+ } catch (RuntimeException e) {
+ throw newIllegalStateException(e,
+ "Error writing a `%s` in transaction.",
+ message.getClass().getName());
}
}
diff --git a/datastore/src/main/java/io/spine/server/storage/datastore/MessageColumn.java b/datastore/src/main/java/io/spine/server/storage/datastore/MessageColumn.java
index 23e215ae1..f1fc7a7c4 100644
--- a/datastore/src/main/java/io/spine/server/storage/datastore/MessageColumn.java
+++ b/datastore/src/main/java/io/spine/server/storage/datastore/MessageColumn.java
@@ -22,6 +22,7 @@
import com.google.cloud.datastore.Entity;
import com.google.cloud.datastore.Value;
+import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.errorprone.annotations.Immutable;
import com.google.protobuf.Message;
@@ -55,6 +56,7 @@ interface MessageColumn {
* the message which field value is going to be set
* @return the same instance of {@code builder} with the property filled
*/
+ @CanIgnoreReturnValue
default Entity.Builder fill(Entity.Builder builder, M message) {
Value> value = getter().apply(message);
builder.set(columnName(), value);
diff --git a/datastore/src/main/java/io/spine/server/storage/datastore/RecordStorageBuilder.java b/datastore/src/main/java/io/spine/server/storage/datastore/RecordStorageBuilder.java
index 3ff71daaf..30c562285 100644
--- a/datastore/src/main/java/io/spine/server/storage/datastore/RecordStorageBuilder.java
+++ b/datastore/src/main/java/io/spine/server/storage/datastore/RecordStorageBuilder.java
@@ -20,6 +20,7 @@
package io.spine.server.storage.datastore;
+import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.protobuf.Descriptors.Descriptor;
import io.spine.server.entity.Entity;
import io.spine.server.entity.model.EntityClass;
@@ -58,6 +59,7 @@ abstract class RecordStorageBuilder idClass) {
this.idClass = checkNotNull(idClass);
return self();
@@ -77,6 +80,7 @@ public B setIdClass(Class idClass) {
/**
* Assigns the class of the stored entity.
*/
+ @CanIgnoreReturnValue
public B setEntityClass(Class extends Entity, ?>> entityClass) {
this.entityClass = checkNotNull(entityClass);
return self();
@@ -90,6 +94,7 @@ public B setEntityClass(Class extends Entity, ?>> entityClass) {
* {@linkplain #setEntityClass(Class) entity class} separately.
*/
@SuppressWarnings("unchecked") // The ID class is ensured by the parameter type.
+ @CanIgnoreReturnValue
public B setModelClass(EntityClass extends Entity> modelClass) {
TypeUrl stateType = modelClass.stateType();
Class idClass = (Class) modelClass.idClass();
@@ -104,6 +109,7 @@ public B setModelClass(EntityClass extends Entity> modelClass) {
/**
* Sets the {@link io.spine.server.storage.datastore.DatastoreWrapper} to use in this storage.
*/
+ @CanIgnoreReturnValue
public B setDatastore(DatastoreWrapper datastore) {
this.datastore = checkNotNull(datastore);
return self();
@@ -117,6 +123,7 @@ public B setDatastore(DatastoreWrapper datastore) {
* {@link io.spine.server.storage.Storage#isMultitenant multitenant},
* {@code false} otherwise
*/
+ @CanIgnoreReturnValue
public B setMultitenant(boolean multitenant) {
this.multitenant = multitenant;
return self();
@@ -126,6 +133,7 @@ public B setMultitenant(boolean multitenant) {
* Assigns the type registry of
* the {@linkplain io.spine.server.entity.storage.EntityColumn entity columns}.
*/
+ @CanIgnoreReturnValue
public B setColumnTypeRegistry(
ColumnTypeRegistry extends DatastoreColumnType, ?>> columnTypeRegistry) {
this.columnTypeRegistry = checkNotNull(columnTypeRegistry);
diff --git a/datastore/src/main/java/io/spine/server/storage/datastore/TransactionWrapper.java b/datastore/src/main/java/io/spine/server/storage/datastore/TransactionWrapper.java
new file mode 100644
index 000000000..d1c51d955
--- /dev/null
+++ b/datastore/src/main/java/io/spine/server/storage/datastore/TransactionWrapper.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2019, TeamDev. All rights reserved.
+ *
+ * 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.server.storage.datastore;
+
+import com.google.cloud.datastore.DatastoreException;
+import com.google.cloud.datastore.Entity;
+import com.google.cloud.datastore.Key;
+import com.google.cloud.datastore.Transaction;
+
+import java.util.Optional;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * A Cloud Datastore transaction wrapper.
+ */
+public final class TransactionWrapper implements AutoCloseable {
+
+ private final Transaction tx;
+
+ TransactionWrapper(Transaction tx) {
+ this.tx = checkNotNull(tx);
+ }
+
+ /**
+ * Puts the given entity into the Datastore in the transaction.
+ */
+ public void createOrUpdate(Entity entity) {
+ tx.put(entity);
+ }
+
+ /**
+ * Reads an entity from the Datastore in the transaction.
+ *
+ * @return the entity with the given key or {@code Optional.empty()} if such an entity does not
+ * exist
+ */
+ public Optional read(Key key) {
+ Entity entity = tx.get(key);
+ return Optional.ofNullable(entity);
+ }
+
+ /**
+ * Commits this transaction.
+ *
+ * @throws DatastoreException if the transaction is no longer active
+ */
+ public void commit() {
+ tx.commit();
+ }
+
+ /**
+ * Rolls back this transaction.
+ *
+ * @throws DatastoreException if the transaction is no longer active
+ */
+ public void rollback() {
+ tx.rollback();
+ }
+
+ /**
+ * Rolls back this transaction if it's still active.
+ */
+ @Override
+ public void close() {
+ if (tx.isActive()) {
+ rollback();
+ }
+ }
+}
diff --git a/datastore/src/main/java/io/spine/server/storage/datastore/package-info.java b/datastore/src/main/java/io/spine/server/storage/datastore/package-info.java
index 15f903655..1245d58e4 100644
--- a/datastore/src/main/java/io/spine/server/storage/datastore/package-info.java
+++ b/datastore/src/main/java/io/spine/server/storage/datastore/package-info.java
@@ -17,12 +17,16 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+
/**
* This package contains Google Cloud Datastore implementation of the storages.
*
* @see io.spine.server.storage.AbstractStorage
*/
+@CheckReturnValue
@ParametersAreNonnullByDefault
package io.spine.server.storage.datastore;
+import com.google.errorprone.annotations.CheckReturnValue;
+
import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/datastore/src/test/java/io/spine/server/storage/datastore/DatastoreWrapperTest.java b/datastore/src/test/java/io/spine/server/storage/datastore/DatastoreWrapperTest.java
index 76d02115d..99575e349 100644
--- a/datastore/src/test/java/io/spine/server/storage/datastore/DatastoreWrapperTest.java
+++ b/datastore/src/test/java/io/spine/server/storage/datastore/DatastoreWrapperTest.java
@@ -77,6 +77,7 @@ static void tearDown() {
wrapper.dropTable(NAMESPACE_HOLDER_KIND);
}
+ @SuppressWarnings("deprecation") // To be deleted alongside with the tested API.
@Nested
class SingleTenant {
diff --git a/datastore/src/test/java/io/spine/server/storage/datastore/TransactionWrapperTest.java b/datastore/src/test/java/io/spine/server/storage/datastore/TransactionWrapperTest.java
new file mode 100644
index 000000000..5da08aed2
--- /dev/null
+++ b/datastore/src/test/java/io/spine/server/storage/datastore/TransactionWrapperTest.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright 2019, TeamDev. All rights reserved.
+ *
+ * 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.server.storage.datastore;
+
+import com.google.cloud.datastore.Entity;
+import com.google.cloud.datastore.Key;
+import com.google.cloud.datastore.KeyFactory;
+import com.google.protobuf.Empty;
+import io.spine.testing.server.storage.datastore.TestDatastoreWrapper;
+import io.spine.type.TypeUrl;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.ExecutorService;
+import java.util.stream.Stream;
+
+import static com.google.common.truth.Truth.assertThat;
+import static io.spine.base.Identifier.newUuid;
+import static io.spine.server.storage.datastore.given.DatastoreWrapperTestEnv.localDatastore;
+import static java.util.concurrent.Executors.newFixedThreadPool;
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static java.util.stream.Collectors.toList;
+
+@DisplayName("`TransactionWrapper` should")
+class TransactionWrapperTest {
+
+ private TestDatastoreWrapper datastore;
+ private KeyFactory keyFactory;
+
+ @BeforeEach
+ void setUp() {
+ datastore = TestDatastoreWrapper.wrap(localDatastore(), false);
+ keyFactory = datastore.keyFactory(Kind.of(TypeUrl.of(Empty.class)
+ .value()));
+ }
+
+ @AfterEach
+ void cleanUpDatastore() {
+ datastore.dropAllTables();
+ }
+
+ @Test
+ @DisplayName("write transactionally")
+ void write() {
+ Key key = keyFactory.newKey(newUuid());
+ Entity entity = Entity.newBuilder(key)
+ .set("field", 42)
+ .build();
+ TransactionWrapper tx = datastore.newTransaction();
+ tx.createOrUpdate(entity);
+ tx.commit();
+ Entity readEntity = datastore.read(key);
+ assertThat(readEntity)
+ .isEqualTo(entity);
+ }
+
+ @Test
+ @DisplayName("read transactionally")
+ void read() {
+ Key key = keyFactory.newKey(newUuid());
+ Entity entity = Entity.newBuilder(key)
+ .set("field_name", newUuid())
+ .build();
+ datastore.create(entity);
+ TransactionWrapper tx = datastore.newTransaction();
+ Optional read = tx.read(key);
+ tx.commit();
+ Entity readEntity = read.orElseGet(Assertions::fail);
+ assertThat(readEntity)
+ .isEqualTo(entity);
+ }
+
+ @Test
+ @DisplayName("read and write transactionally")
+ void readWrite() {
+ Key key = keyFactory.newKey(newUuid());
+ String field = "number";
+ Entity original = Entity.newBuilder(key)
+ .set(field, 1)
+ .build();
+ datastore.create(original);
+ TransactionWrapper tx = datastore.newTransaction();
+ Entity updated = Entity.newBuilder(original)
+ .set(field, 2)
+ .build();
+ assertThat(tx.read(key)
+ .orElseGet(Assertions::fail)
+ .getLong(field))
+ .isEqualTo(original.getLong(field));
+
+ tx.createOrUpdate(updated);
+
+ assertThat(tx.read(key)
+ .orElseGet(Assertions::fail)
+ .getLong(field))
+ .isEqualTo(original.getLong(field));
+
+ tx.commit();
+
+ Entity finalEntity = datastore.read(key);
+ assertThat(finalEntity)
+ .isNotNull();
+ assertThat(finalEntity.getLong(field))
+ .isEqualTo(updated.getLong(field));
+ }
+
+ @Test
+ @DisplayName("rollback changes")
+ void rollback() {
+ Key key = keyFactory.newKey(newUuid());
+ Entity entity = Entity.newBuilder(key)
+ .set("example", newUuid())
+ .build();
+ TransactionWrapper tx = datastore.newTransaction();
+ tx.createOrUpdate(entity);
+ tx.rollback();
+ Entity readEntity = datastore.read(key);
+ assertThat(readEntity)
+ .isNull();
+ }
+
+ @Test
+ @DisplayName("rollback on close")
+ void closeAndRollback() {
+ Key key = keyFactory.newKey(newUuid());
+ try (TransactionWrapper tx = datastore.newTransaction()) {
+ Entity entity = Entity.newBuilder(key)
+ .set("test", newUuid())
+ .build();
+ tx.createOrUpdate(entity);
+ }
+ Entity readEntity = datastore.read(key);
+ assertThat(readEntity)
+ .isNull();
+ }
+
+ @Test
+ @DisplayName("not rollback if already committed")
+ void notRollbackIfNotActive() {
+ Key key = keyFactory.newKey(newUuid());
+ try (TransactionWrapper tx = datastore.newTransaction()) {
+ Entity entity = Entity.newBuilder(key)
+ .set("test1", newUuid())
+ .build();
+ tx.createOrUpdate(entity);
+ tx.commit();
+ }
+ Entity readEntity = datastore.read(key);
+ assertThat(readEntity)
+ .isNotNull();
+ }
+
+ @Test
+ @DisplayName("run many transactions at a time")
+ void runManyAtATime() throws InterruptedException {
+ int workerCount = 1117;
+ ExecutorService service = newFixedThreadPool(workerCount);
+ List keys = Stream.generate(() -> keyFactory.newKey(newUuid()))
+ .limit(workerCount)
+ .collect(toList());
+ keys.stream()
+ .map(key -> Entity
+ .newBuilder(key)
+ .set("a", newUuid())
+ .build())
+ .forEach(entity -> service.execute(() -> {
+ TransactionWrapper tx = datastore.newTransaction();
+ tx.createOrUpdate(entity);
+ tx.commit();
+ }));
+ service.awaitTermination(5, SECONDS);
+ for (Key key : keys) {
+ Entity read = datastore.read(key);
+ assertThat(read)
+ .isNotNull();
+ }
+ }
+}
diff --git a/license-report.md b/license-report.md
index 5e7fcc1e3..21dbc572a 100644
--- a/license-report.md
+++ b/license-report.md
@@ -1,6 +1,6 @@
-# Dependencies of `io.spine.gcloud:spine-datastore:1.1.3-SNAPSHOT+1`
+# Dependencies of `io.spine.gcloud:spine-datastore:1.1.4`
## Runtime
1. **Group:** com.fasterxml.jackson.core **Name:** jackson-core **Version:** 2.9.9
@@ -29,7 +29,7 @@
* **Manifest license URL:** [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
* **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-1. **Group:** com.google.api.grpc **Name:** proto-google-cloud-datastore-v1 **Version:** 0.74.0
+1. **Group:** com.google.api.grpc **Name:** proto-google-cloud-datastore-v1 **Version:** 0.79.0
* **POM License: Apache-2.0** - [https://www.apache.org/licenses/LICENSE-2.0.txt](https://www.apache.org/licenses/LICENSE-2.0.txt)
1. **Group:** com.google.api.grpc **Name:** proto-google-common-protos **Version:** 1.16.0
@@ -58,7 +58,7 @@
* **POM Project URL:** [https://github.com/googleapis/google-cloud-java/tree/master/google-cloud-clients/google-cloud-core-http](https://github.com/googleapis/google-cloud-java/tree/master/google-cloud-clients/google-cloud-core-http)
* **POM License: Apache-2.0** - [https://www.apache.org/licenses/LICENSE-2.0.txt](https://www.apache.org/licenses/LICENSE-2.0.txt)
-1. **Group:** com.google.cloud **Name:** google-cloud-datastore **Version:** 1.91.0
+1. **Group:** com.google.cloud **Name:** google-cloud-datastore **Version:** 1.96.0
* **POM Project URL:** [https://github.com/googleapis/google-cloud-java/tree/master/google-cloud-clients/google-cloud-datastore](https://github.com/googleapis/google-cloud-java/tree/master/google-cloud-clients/google-cloud-datastore)
* **POM License: Apache-2.0** - [https://www.apache.org/licenses/LICENSE-2.0.txt](https://www.apache.org/licenses/LICENSE-2.0.txt)
@@ -152,15 +152,15 @@
* **Manifest license URL:** [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
* **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-1. **Group:** io.grpc **Name:** grpc-api **Version:** 1.23.0
+1. **Group:** io.grpc **Name:** grpc-api **Version:** 1.24.0
* **POM Project URL:** [https://github.com/grpc/grpc-java](https://github.com/grpc/grpc-java)
* **POM License: Apache 2.0** - [https://opensource.org/licenses/Apache-2.0](https://opensource.org/licenses/Apache-2.0)
-1. **Group:** io.grpc **Name:** grpc-context **Version:** 1.23.0
+1. **Group:** io.grpc **Name:** grpc-context **Version:** 1.24.0
* **POM Project URL:** [https://github.com/grpc/grpc-java](https://github.com/grpc/grpc-java)
* **POM License: Apache 2.0** - [https://opensource.org/licenses/Apache-2.0](https://opensource.org/licenses/Apache-2.0)
-1. **Group:** io.grpc **Name:** grpc-core **Version:** 1.23.0
+1. **Group:** io.grpc **Name:** grpc-core **Version:** 1.24.0
* **POM Project URL:** [https://github.com/grpc/grpc-java](https://github.com/grpc/grpc-java)
* **POM License: Apache 2.0** - [https://opensource.org/licenses/Apache-2.0](https://opensource.org/licenses/Apache-2.0)
@@ -273,7 +273,7 @@
* **Manifest license URL:** [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
* **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-1. **Group:** com.google.api.grpc **Name:** proto-google-cloud-datastore-v1 **Version:** 0.74.0
+1. **Group:** com.google.api.grpc **Name:** proto-google-cloud-datastore-v1 **Version:** 0.79.0
* **POM License: Apache-2.0** - [https://www.apache.org/licenses/LICENSE-2.0.txt](https://www.apache.org/licenses/LICENSE-2.0.txt)
1. **Group:** com.google.api.grpc **Name:** proto-google-common-protos **Version:** 1.16.0
@@ -305,7 +305,7 @@
* **POM Project URL:** [https://github.com/googleapis/google-cloud-java/tree/master/google-cloud-clients/google-cloud-core-http](https://github.com/googleapis/google-cloud-java/tree/master/google-cloud-clients/google-cloud-core-http)
* **POM License: Apache-2.0** - [https://www.apache.org/licenses/LICENSE-2.0.txt](https://www.apache.org/licenses/LICENSE-2.0.txt)
-1. **Group:** com.google.cloud **Name:** google-cloud-datastore **Version:** 1.91.0
+1. **Group:** com.google.cloud **Name:** google-cloud-datastore **Version:** 1.96.0
* **POM Project URL:** [https://github.com/googleapis/google-cloud-java/tree/master/google-cloud-clients/google-cloud-datastore](https://github.com/googleapis/google-cloud-java/tree/master/google-cloud-clients/google-cloud-datastore)
* **POM License: Apache-2.0** - [https://www.apache.org/licenses/LICENSE-2.0.txt](https://www.apache.org/licenses/LICENSE-2.0.txt)
@@ -472,15 +472,15 @@
* **Manifest license URL:** [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
* **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-1. **Group:** io.grpc **Name:** grpc-api **Version:** 1.23.0
+1. **Group:** io.grpc **Name:** grpc-api **Version:** 1.24.0
* **POM Project URL:** [https://github.com/grpc/grpc-java](https://github.com/grpc/grpc-java)
* **POM License: Apache 2.0** - [https://opensource.org/licenses/Apache-2.0](https://opensource.org/licenses/Apache-2.0)
-1. **Group:** io.grpc **Name:** grpc-context **Version:** 1.23.0
+1. **Group:** io.grpc **Name:** grpc-context **Version:** 1.24.0
* **POM Project URL:** [https://github.com/grpc/grpc-java](https://github.com/grpc/grpc-java)
* **POM License: Apache 2.0** - [https://opensource.org/licenses/Apache-2.0](https://opensource.org/licenses/Apache-2.0)
-1. **Group:** io.grpc **Name:** grpc-core **Version:** 1.23.0
+1. **Group:** io.grpc **Name:** grpc-core **Version:** 1.24.0
* **POM Project URL:** [https://github.com/grpc/grpc-java](https://github.com/grpc/grpc-java)
* **POM License: Apache 2.0** - [https://opensource.org/licenses/Apache-2.0](https://opensource.org/licenses/Apache-2.0)
@@ -734,12 +734,12 @@
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
-This report was generated on **Wed Oct 02 16:28:12 EEST 2019** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Tue Oct 08 16:00:25 EEST 2019** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
-# Dependencies of `io.spine.gcloud:spine-stackdriver-trace:1.1.3-SNAPSHOT+1`
+# Dependencies of `io.spine.gcloud:spine-stackdriver-trace:1.1.4`
## Runtime
1. **Group:** com.fasterxml.jackson.core **Name:** jackson-core **Version:** 2.9.6
@@ -1474,12 +1474,12 @@ This report was generated on **Wed Oct 02 16:28:12 EEST 2019** using [Gradle-Lic
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
-This report was generated on **Wed Oct 02 16:28:25 EEST 2019** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Tue Oct 08 16:00:29 EEST 2019** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
-# Dependencies of `io.spine.gcloud:spine-testutil-gcloud:1.1.3-SNAPSHOT+1`
+# Dependencies of `io.spine.gcloud:spine-testutil-gcloud:1.1.4`
## Runtime
1. **Group:** com.fasterxml.jackson.core **Name:** jackson-core **Version:** 2.9.9
@@ -1508,7 +1508,7 @@ This report was generated on **Wed Oct 02 16:28:25 EEST 2019** using [Gradle-Lic
* **Manifest license URL:** [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
* **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-1. **Group:** com.google.api.grpc **Name:** proto-google-cloud-datastore-v1 **Version:** 0.74.0
+1. **Group:** com.google.api.grpc **Name:** proto-google-cloud-datastore-v1 **Version:** 0.79.0
* **POM License: Apache-2.0** - [https://www.apache.org/licenses/LICENSE-2.0.txt](https://www.apache.org/licenses/LICENSE-2.0.txt)
1. **Group:** com.google.api.grpc **Name:** proto-google-common-protos **Version:** 1.16.0
@@ -1537,7 +1537,7 @@ This report was generated on **Wed Oct 02 16:28:25 EEST 2019** using [Gradle-Lic
* **POM Project URL:** [https://github.com/googleapis/google-cloud-java/tree/master/google-cloud-clients/google-cloud-core-http](https://github.com/googleapis/google-cloud-java/tree/master/google-cloud-clients/google-cloud-core-http)
* **POM License: Apache-2.0** - [https://www.apache.org/licenses/LICENSE-2.0.txt](https://www.apache.org/licenses/LICENSE-2.0.txt)
-1. **Group:** com.google.cloud **Name:** google-cloud-datastore **Version:** 1.91.0
+1. **Group:** com.google.cloud **Name:** google-cloud-datastore **Version:** 1.96.0
* **POM Project URL:** [https://github.com/googleapis/google-cloud-java/tree/master/google-cloud-clients/google-cloud-datastore](https://github.com/googleapis/google-cloud-java/tree/master/google-cloud-clients/google-cloud-datastore)
* **POM License: Apache-2.0** - [https://www.apache.org/licenses/LICENSE-2.0.txt](https://www.apache.org/licenses/LICENSE-2.0.txt)
@@ -1631,15 +1631,15 @@ This report was generated on **Wed Oct 02 16:28:25 EEST 2019** using [Gradle-Lic
* **Manifest license URL:** [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
* **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-1. **Group:** io.grpc **Name:** grpc-api **Version:** 1.23.0
+1. **Group:** io.grpc **Name:** grpc-api **Version:** 1.24.0
* **POM Project URL:** [https://github.com/grpc/grpc-java](https://github.com/grpc/grpc-java)
* **POM License: Apache 2.0** - [https://opensource.org/licenses/Apache-2.0](https://opensource.org/licenses/Apache-2.0)
-1. **Group:** io.grpc **Name:** grpc-context **Version:** 1.23.0
+1. **Group:** io.grpc **Name:** grpc-context **Version:** 1.24.0
* **POM Project URL:** [https://github.com/grpc/grpc-java](https://github.com/grpc/grpc-java)
* **POM License: Apache 2.0** - [https://opensource.org/licenses/Apache-2.0](https://opensource.org/licenses/Apache-2.0)
-1. **Group:** io.grpc **Name:** grpc-core **Version:** 1.23.0
+1. **Group:** io.grpc **Name:** grpc-core **Version:** 1.24.0
* **POM Project URL:** [https://github.com/grpc/grpc-java](https://github.com/grpc/grpc-java)
* **POM License: Apache 2.0** - [https://opensource.org/licenses/Apache-2.0](https://opensource.org/licenses/Apache-2.0)
@@ -1773,7 +1773,7 @@ This report was generated on **Wed Oct 02 16:28:25 EEST 2019** using [Gradle-Lic
* **Manifest license URL:** [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
* **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-1. **Group:** com.google.api.grpc **Name:** proto-google-cloud-datastore-v1 **Version:** 0.74.0
+1. **Group:** com.google.api.grpc **Name:** proto-google-cloud-datastore-v1 **Version:** 0.79.0
* **POM License: Apache-2.0** - [https://www.apache.org/licenses/LICENSE-2.0.txt](https://www.apache.org/licenses/LICENSE-2.0.txt)
1. **Group:** com.google.api.grpc **Name:** proto-google-common-protos **Version:** 1.16.0
@@ -1805,7 +1805,7 @@ This report was generated on **Wed Oct 02 16:28:25 EEST 2019** using [Gradle-Lic
* **POM Project URL:** [https://github.com/googleapis/google-cloud-java/tree/master/google-cloud-clients/google-cloud-core-http](https://github.com/googleapis/google-cloud-java/tree/master/google-cloud-clients/google-cloud-core-http)
* **POM License: Apache-2.0** - [https://www.apache.org/licenses/LICENSE-2.0.txt](https://www.apache.org/licenses/LICENSE-2.0.txt)
-1. **Group:** com.google.cloud **Name:** google-cloud-datastore **Version:** 1.91.0
+1. **Group:** com.google.cloud **Name:** google-cloud-datastore **Version:** 1.96.0
* **POM Project URL:** [https://github.com/googleapis/google-cloud-java/tree/master/google-cloud-clients/google-cloud-datastore](https://github.com/googleapis/google-cloud-java/tree/master/google-cloud-clients/google-cloud-datastore)
* **POM License: Apache-2.0** - [https://www.apache.org/licenses/LICENSE-2.0.txt](https://www.apache.org/licenses/LICENSE-2.0.txt)
@@ -1972,15 +1972,15 @@ This report was generated on **Wed Oct 02 16:28:25 EEST 2019** using [Gradle-Lic
* **Manifest license URL:** [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
* **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-1. **Group:** io.grpc **Name:** grpc-api **Version:** 1.23.0
+1. **Group:** io.grpc **Name:** grpc-api **Version:** 1.24.0
* **POM Project URL:** [https://github.com/grpc/grpc-java](https://github.com/grpc/grpc-java)
* **POM License: Apache 2.0** - [https://opensource.org/licenses/Apache-2.0](https://opensource.org/licenses/Apache-2.0)
-1. **Group:** io.grpc **Name:** grpc-context **Version:** 1.23.0
+1. **Group:** io.grpc **Name:** grpc-context **Version:** 1.24.0
* **POM Project URL:** [https://github.com/grpc/grpc-java](https://github.com/grpc/grpc-java)
* **POM License: Apache 2.0** - [https://opensource.org/licenses/Apache-2.0](https://opensource.org/licenses/Apache-2.0)
-1. **Group:** io.grpc **Name:** grpc-core **Version:** 1.23.0
+1. **Group:** io.grpc **Name:** grpc-core **Version:** 1.24.0
* **POM Project URL:** [https://github.com/grpc/grpc-java](https://github.com/grpc/grpc-java)
* **POM License: Apache 2.0** - [https://opensource.org/licenses/Apache-2.0](https://opensource.org/licenses/Apache-2.0)
@@ -2234,4 +2234,4 @@ This report was generated on **Wed Oct 02 16:28:25 EEST 2019** using [Gradle-Lic
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
-This report was generated on **Wed Oct 02 16:28:37 EEST 2019** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
\ No newline at end of file
+This report was generated on **Tue Oct 08 16:00:30 EEST 2019** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index d1d3883cc..282e36af7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -12,7 +12,7 @@ all modules and does not describe the project structure per-subproject.
io.spine.gcloud
spine-gcloud-java
-1.1.3-SNAPSHOT+1
+1.1.4
2015
@@ -28,7 +28,7 @@ all modules and does not describe the project structure per-subproject.
com.google.cloud
google-cloud-datastore
- 1.91.0
+ 1.96.0
compile
@@ -40,7 +40,7 @@ all modules and does not describe the project structure per-subproject.
io.spine
spine-server
- 1.1.2
+ 1.1.4
compile
@@ -58,7 +58,7 @@ all modules and does not describe the project structure per-subproject.
io.spine
spine-testutil-server
- 1.1.2
+ 1.1.4
test
@@ -114,12 +114,12 @@ all modules and does not describe the project structure per-subproject.
io.spine.tools
spine-errorprone-checks
- 1.1.3-SNAPSHOT+1
+ 1.1.4
io.spine.tools
spine-protoc-plugin
- 1.1.3-SNAPSHOT+1
+ 1.1.4
net.sourceforge.pmd
diff --git a/version.gradle b/version.gradle
index 4f15fcc23..bf9823a9e 100644
--- a/version.gradle
+++ b/version.gradle
@@ -25,13 +25,13 @@
* {@code .config/gradle/dependencies.gradle}.
*/
-def final SPINE_VERSION = '1.1.3-SNAPSHOT+1'
+def final SPINE_VERSION = '1.1.4'
ext {
versionToPublish = SPINE_VERSION
spineBaseVersion = SPINE_VERSION
- spineCoreVersion = '1.1.2'
+ spineCoreVersion = SPINE_VERSION
- datastoreVersion = '1.91.0'
+ datastoreVersion = '1.96.0'
}