diff --git a/README.md b/README.md index 8e4f692c9..1156f01ab 100644 --- a/README.md +++ b/README.md @@ -14,10 +14,13 @@ dependencies { implementation ( // Datastore Storage support library. - "io.spine.gcloud:spine-datastore:1.1.2", + "io.spine.gcloud:spine-datastore:1.1.3-SNAPSHOT+1", // Stackdriver Trace support library. - "io.spine.gcloud:spine-stackdriver-trace:1.1.2" + "io.spine.gcloud:spine-stackdriver-trace:1.1.3-SNAPSHOT+1", + + // Datastore-related test utilities (if needed). + "io.spine.gcloud:testutil-gcloud:1.1.3-SNAPSHOT+1" ) } ``` diff --git a/build.gradle b/build.gradle index ba9e9bd44..615d4f43e 100644 --- a/build.gradle +++ b/build.gradle @@ -44,7 +44,7 @@ ext { credentialsPropertyFile = 'credentials.properties' spineProtobufPluginId = 'io.spine.tools.spine-model-compiler' - projectsToPublish = ['datastore', 'stackdriver-trace'] + projectsToPublish = ['datastore', 'stackdriver-trace', 'testutil-gcloud'] } allprojects { diff --git a/config b/config index 5c31b0830..6a07e48f8 160000 --- a/config +++ b/config @@ -1 +1 @@ -Subproject commit 5c31b083088b5ce66223a9b09639d5a33a7b8b84 +Subproject commit 6a07e48f83113e89198f75462a76911e74546152 diff --git a/datastore/build.gradle b/datastore/build.gradle index 1c8e9a0c2..f411d5ce3 100644 --- a/datastore/build.gradle +++ b/datastore/build.gradle @@ -29,6 +29,7 @@ dependencies { exclude group: 'com.google.guava' } + testImplementation project(path: ":testutil-gcloud") testImplementation "io.spine:spine-server:" } diff --git a/datastore/src/main/java/io/spine/server/storage/datastore/DatastoreStorageFactory.java b/datastore/src/main/java/io/spine/server/storage/datastore/DatastoreStorageFactory.java index e9b80b026..e5b31ea71 100644 --- a/datastore/src/main/java/io/spine/server/storage/datastore/DatastoreStorageFactory.java +++ b/datastore/src/main/java/io/spine/server/storage/datastore/DatastoreStorageFactory.java @@ -90,7 +90,7 @@ public class DatastoreStorageFactory implements StorageFactory { private final NsConverterFactory converterFactory; - DatastoreStorageFactory(Builder builder) { + protected DatastoreStorageFactory(Builder builder) { this.typeRegistry = builder.typeRegistry; this.datastore = builder.datastore; this.converterFactory = builder.converterFactory; @@ -217,7 +217,7 @@ protected Iterable wrappers() { } /** - * Returs the instance of wrapped {@link Datastore}. + * Returns the instance of wrapped {@link Datastore}. */ @VisibleForTesting protected Datastore datastore() { 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 e7377925b..4fda458ad 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 @@ -48,6 +48,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Objects; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; @@ -76,7 +77,7 @@ public class DatastoreWrapper implements Logging { private static final int MAX_KEYS_PER_READ_REQUEST = 1000; static final int MAX_ENTITIES_PER_WRITE_REQUEST = 500; - private static final Map keyFactories = new HashMap<>(); + private static final Map keyFactories = new HashMap<>(); private static final Key[] EMPTY_KEY_ARRAY = new Key[0]; @@ -198,7 +199,7 @@ public void createOrUpdate(Collection entities) { * @return the {@link Entity} or {@code null} in case of no results for the key given * @see DatastoreReader#get(Key) */ - public Entity read(Key key) { + public @Nullable Entity read(Key key) { return actor.get(key); } @@ -301,7 +302,7 @@ public DsQueryIterator read(StructuredQuery query) { * @throws IllegalArgumentException * if the provided {@linkplain StructuredQuery#getLimit() query includes a limit} */ - Iterator readAll(StructuredQuery query, int pageSize) { + public Iterator readAll(StructuredQuery query, int pageSize) { return readAllPageByPage(query, pageSize); } @@ -322,7 +323,7 @@ Iterator readAll(StructuredQuery query, int pageSize) { * @throws IllegalArgumentException * if the provided {@linkplain StructuredQuery#getLimit() query includes a limit} */ - Iterator readAll(StructuredQuery query) { + public Iterator readAll(StructuredQuery query) { return readAllPageByPage(query, null); } @@ -386,7 +387,8 @@ public void delete(Key... keys) { * @param table * kind (a.k.a. type, table, etc.) of the records to delete */ - void dropTable(String table) { + @VisibleForTesting + protected void dropTable(String table) { Namespace namespace = currentNamespace(); StructuredQuery query = Query.newEntityQueryBuilder() @@ -504,7 +506,8 @@ public boolean isTransactionActive() { * @return an instance of {@link KeyFactory} for given kind */ public KeyFactory keyFactory(Kind kind) { - KeyFactory keyFactory = keyFactories.get(kind); + DatastoreKind datastoreKind = new DatastoreKind(projectId(), kind); + KeyFactory keyFactory = keyFactories.get(datastoreKind); if (keyFactory == null) { keyFactory = initKeyFactory(kind); } @@ -522,17 +525,26 @@ public DatastoreOptions datastoreOptions() { return options; } - Datastore datastore() { + @VisibleForTesting + public Datastore datastore() { return datastore; } private KeyFactory initKeyFactory(Kind kind) { KeyFactory keyFactory = datastore.newKeyFactory() - .setKind(kind.getValue()); - keyFactories.put(kind, keyFactory); + .setKind(kind.value()); + DatastoreKind datastoreKind = new DatastoreKind(projectId(), kind); + keyFactories.put(datastoreKind, keyFactory); return keyFactory; } + private ProjectId projectId() { + String projectId = datastore.getOptions() + .getProjectId(); + ProjectId result = ProjectId.of(projectId); + return result; + } + /** * Reads big number of records. * @@ -587,4 +599,37 @@ private Namespace currentNamespace() { private void writeSmallBulk(Entity[] entities) { actor.put(entities); } + + /** + * A Datastore {@link Kind} by project ID. + */ + private static class DatastoreKind { + + private final ProjectId projectId; + private final Kind kind; + + private DatastoreKind(ProjectId projectId, Kind kind) { + this.projectId = projectId; + this.kind = kind; + } + + @SuppressWarnings("EqualsGetClass") // The class is effectively final. + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + DatastoreKind kind1 = (DatastoreKind) o; + return Objects.equals(projectId, kind1.projectId) && + Objects.equals(kind, kind1.kind); + } + + @Override + public int hashCode() { + return Objects.hash(projectId, kind); + } + } } 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 61ca7066b..62bf0fb82 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 @@ -200,7 +200,7 @@ public void writeAll(Iterable messages) { */ Iterator readAll(EntityQuery.Builder queryBuilder, int readBatchSize) { StructuredQuery query = - queryBuilder.setKind(kind.getValue()) + queryBuilder.setKind(kind.value()) .build(); Iterator iterator = datastore.readAll(query, readBatchSize); Iterator transformed = diff --git a/datastore/src/main/java/io/spine/server/storage/datastore/Indexes.java b/datastore/src/main/java/io/spine/server/storage/datastore/Indexes.java index 299707bc8..5b8caad3e 100644 --- a/datastore/src/main/java/io/spine/server/storage/datastore/Indexes.java +++ b/datastore/src/main/java/io/spine/server/storage/datastore/Indexes.java @@ -63,7 +63,7 @@ static Iterator indexIterator(DatastoreWrapper datastore, Kind kind, Clas checkNotNull(idType); StructuredQuery query = Query.newKeyQueryBuilder() - .setKind(kind.getValue()) + .setKind(kind.value()) .build(); Iterator allEntities = datastore.read(query); Iterator idIterator = Streams.stream(allEntities) diff --git a/datastore/src/main/java/io/spine/server/storage/datastore/Kind.java b/datastore/src/main/java/io/spine/server/storage/datastore/Kind.java index 31e11628c..c0720c249 100644 --- a/datastore/src/main/java/io/spine/server/storage/datastore/Kind.java +++ b/datastore/src/main/java/io/spine/server/storage/datastore/Kind.java @@ -20,12 +20,12 @@ package io.spine.server.storage.datastore; -import com.google.common.base.Objects; import com.google.protobuf.Descriptors.Descriptor; import com.google.protobuf.Message; import io.spine.annotation.Internal; import io.spine.type.TypeName; import io.spine.type.TypeUrl; +import io.spine.value.StringTypeValue; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; @@ -34,7 +34,9 @@ * A data transfer object representing a Datastore * kind. */ -public final class Kind { +public final class Kind extends StringTypeValue { + + private static final long serialVersionUID = 0L; private static final String INVALID_KIND_ERROR_MESSAGE = "Datastore kind cannot start with \"__\". See " + @@ -44,10 +46,8 @@ public final class Kind { private static final String NAMESPACE_KIND = "__namespace__"; - private final String value; - private Kind(String value) { - this.value = checkValidKind(value); + super(checkValidKind(value)); } /** @@ -59,8 +59,8 @@ private Kind(String value) { * the flag showing that the {@code Kind} is ancillary; must be set to {@code true} */ private Kind(String value, boolean ancillary) { + super(value); checkArgument(ancillary); - this.value = value; } public static Kind of(String value) { @@ -92,30 +92,9 @@ public static Kind ofNamespace() { return new Kind(NAMESPACE_KIND, true); } - public String getValue() { - return value; - } - private static String checkValidKind(String kind) { checkNotNull(kind); checkArgument(!kind.startsWith(FORBIDDEN_PREFIX), INVALID_KIND_ERROR_MESSAGE); return kind; } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Kind kind = (Kind) o; - return Objects.equal(getValue(), kind.getValue()); - } - - @Override - public int hashCode() { - return Objects.hashCode(getValue()); - } } diff --git a/datastore/src/main/java/io/spine/server/storage/datastore/QueryWithFilter.java b/datastore/src/main/java/io/spine/server/storage/datastore/QueryWithFilter.java index 88bf58610..6096642a4 100644 --- a/datastore/src/main/java/io/spine/server/storage/datastore/QueryWithFilter.java +++ b/datastore/src/main/java/io/spine/server/storage/datastore/QueryWithFilter.java @@ -46,7 +46,7 @@ final class QueryWithFilter implements Function run() { Query query = Query.newKeyQueryBuilder() - .setKind(NAMESPACE_KIND.getValue()) + .setKind(NAMESPACE_KIND.value()) .build(); Iterator result = datastore.run(query); return result; diff --git a/datastore/src/test/java/io/spine/server/storage/datastore/BigDataTester.java b/datastore/src/test/java/io/spine/server/storage/datastore/BigDataTester.java index dea0e4fa4..d63bf3f55 100644 --- a/datastore/src/test/java/io/spine/server/storage/datastore/BigDataTester.java +++ b/datastore/src/test/java/io/spine/server/storage/datastore/BigDataTester.java @@ -55,7 +55,7 @@ * @param * the type of the ID in the tested {@linkplain RecordStorage} */ -public class BigDataTester implements Logging { +public final class BigDataTester implements Logging { private static final int DEFAULT_BULK_SIZE = 500; @@ -80,13 +80,14 @@ public static Builder newBuilder() { * *

The execution flow is as follows: *

    - *
  1. 1. Produce the records with the given {@link EntryFactory} - *
  2. 2. Measure the time of the {@linkplain RecordStorage#write(Map) bulk write} - *
  3. 3. Fail if the time is over the specified limit - *
  4. 4. Wait 1 second to ensure the Datastore has established the data consistency - *
  5. 5. Measure the time of the {@linkplain RecordStorage#readAll() bulk read} - *
  6. 6. Fail if the time is over the specified limit - *
  7. 7. Check the count of the records written and read is equal + *
  8. Produce the records with the given {@link EntryFactory}. + *
  9. Measure the time of the {@linkplain RecordStorage#write(Map) bulk write}. + *
  10. Fail if the time is over the specified limit. + *
  11. Wait 1 second to ensure the Datastore has established the data consistency. + *
  12. Measure the time of the + * {@linkplain RecordStorage#readAll(ResponseFormat) bulk read}. + *
  13. Fail if the time is over the specified limit. + *
  14. Check the count of the records written and read is equal. *
* *

This method performs {@code debug} logging of the measure results. To see the log, run diff --git a/datastore/src/test/java/io/spine/server/storage/datastore/DatastoreStorageFactoryBuilderTest.java b/datastore/src/test/java/io/spine/server/storage/datastore/DatastoreStorageFactoryBuilderTest.java index 016e4e313..19d4594bd 100644 --- a/datastore/src/test/java/io/spine/server/storage/datastore/DatastoreStorageFactoryBuilderTest.java +++ b/datastore/src/test/java/io/spine/server/storage/datastore/DatastoreStorageFactoryBuilderTest.java @@ -27,8 +27,8 @@ import io.spine.server.entity.storage.ColumnType; import io.spine.server.entity.storage.ColumnTypeRegistry; import io.spine.server.storage.datastore.given.Columns.ByteColumnType; -import io.spine.server.storage.datastore.given.TestDatastores; import io.spine.server.storage.datastore.type.DatastoreTypeRegistryFactory; +import io.spine.testing.server.storage.datastore.TestDatastores; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -36,11 +36,11 @@ import static io.spine.server.ContextSpec.singleTenant; import static io.spine.server.storage.datastore.given.Columns.byteColumn; -import static io.spine.server.storage.datastore.given.TestDatastores.projectId; import static io.spine.server.storage.datastore.type.DatastoreTypeRegistryFactory.predefinedValuesAnd; import static io.spine.testing.DisplayNames.HAVE_PARAMETERLESS_CTOR; import static io.spine.testing.DisplayNames.NOT_ACCEPT_NULLS; import static io.spine.testing.Tests.assertHasPrivateParameterlessCtor; +import static io.spine.testing.server.storage.datastore.TestDatastores.defaultLocalProjectId; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -102,7 +102,7 @@ class Namespaces { void setUp() { builder = DatastoreOptions .newBuilder() - .setProjectId(projectId().getValue()); + .setProjectId(defaultLocalProjectId().getValue()); } @Test diff --git a/datastore/src/test/java/io/spine/server/storage/datastore/DatastoreStorageFactoryTest.java b/datastore/src/test/java/io/spine/server/storage/datastore/DatastoreStorageFactoryTest.java index 57a0e502c..e72af9276 100644 --- a/datastore/src/test/java/io/spine/server/storage/datastore/DatastoreStorageFactoryTest.java +++ b/datastore/src/test/java/io/spine/server/storage/datastore/DatastoreStorageFactoryTest.java @@ -44,10 +44,10 @@ import static com.google.common.truth.Truth.assertThat; import static io.spine.server.ContextSpec.multitenant; -import static io.spine.server.storage.datastore.given.TestDatastores.local; -import static io.spine.server.storage.datastore.given.TestDatastores.projectId; import static io.spine.server.tenant.TenantAwareRunner.with; import static io.spine.testing.DisplayNames.NOT_ACCEPT_NULLS; +import static io.spine.testing.server.storage.datastore.TestDatastores.local; +import static io.spine.testing.server.storage.datastore.TestDatastores.defaultLocalProjectId; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertSame; @@ -81,7 +81,8 @@ void testCreateMultitenant() { StorageFactory factory = DatastoreStorageFactory.newBuilder() .setDatastore(datastore) .build(); - RecordStorage storage = factory.createRecordStorage(TestEnvironment.multiTenantSpec(), TestEntity.class); + RecordStorage storage = + factory.createRecordStorage(TestEnvironment.multiTenantSpec(), TestEntity.class); assertTrue(storage.isMultitenant()); storage.close(); } @@ -176,7 +177,7 @@ private static Key.Builder whiteForTenant(DsPropertyStorage storage, TenantId te with(tenant).run( () -> storage.write(recordId, message) ); - return Key.newBuilder(projectId().getValue(), + return Key.newBuilder(defaultLocalProjectId().getValue(), TypeName.of(message) .value(), recordId.getValue()); 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 97ddbbeb6..76d02115d 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 @@ -29,8 +29,8 @@ import io.spine.core.TenantId; import io.spine.net.EmailAddress; import io.spine.net.InternetDomain; -import io.spine.server.storage.datastore.given.TestDatastores; import io.spine.server.tenant.TenantAwareFunction0; +import io.spine.testing.server.storage.datastore.TestDatastoreWrapper; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -48,7 +48,7 @@ import static com.google.cloud.datastore.Query.newEntityQueryBuilder; import static com.google.common.collect.Lists.newArrayList; import static com.google.common.truth.Truth.assertThat; -import static io.spine.server.storage.datastore.TestDatastoreWrapper.wrap; +import static io.spine.server.storage.datastore.DatastoreWrapper.wrap; import static io.spine.server.storage.datastore.given.DatastoreWrapperTestEnv.GENERIC_ENTITY_KIND; import static io.spine.server.storage.datastore.given.DatastoreWrapperTestEnv.NAMESPACE_HOLDER_KIND; import static io.spine.server.storage.datastore.given.DatastoreWrapperTestEnv.checkTenantIdInKey; @@ -58,6 +58,7 @@ import static io.spine.server.storage.datastore.given.TestEnvironment.runsOnCi; import static io.spine.server.storage.datastore.tenant.TestNamespaceSuppliers.multitenant; import static io.spine.server.storage.datastore.tenant.TestNamespaceSuppliers.singleTenant; +import static io.spine.testing.server.storage.datastore.TestDatastoreWrapper.wrap; import static java.lang.String.format; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -171,7 +172,7 @@ void testBigBulkRead() throws InterruptedException { Thread.sleep(bulkSize * 3L); StructuredQuery query = newEntityQueryBuilder() - .setKind(GENERIC_ENTITY_KIND.getValue()) + .setKind(GENERIC_ENTITY_KIND.value()) .build(); Collection readEntities = newArrayList(wrapper.read(query)); assertEquals(entities.size(), readEntities.size()); @@ -318,6 +319,8 @@ void tearDown() { wrapper.dropAllTables(); } + @SuppressWarnings({"CheckReturnValue", "ResultOfMethodCallIgnored"}) + // Called to throw exception. @Test @DisplayName("throws IAE during batch read with limit") void testIaeOnBatchReadWithLimit() { @@ -327,6 +330,8 @@ void testIaeOnBatchReadWithLimit() { .build(), 1)); } + @SuppressWarnings({"CheckReturnValue", "ResultOfMethodCallIgnored"}) + // Called to throw exception. @Test @DisplayName("throws IAE during batch read of 0 size") void testIaeOnBatchReadWithZeroSize() { @@ -338,7 +343,6 @@ void testIaeOnBatchReadWithZeroSize() { @Test @DisplayName("generate key factories aware of tenancy") void testGenerateKeyFactory() { - ProjectId projectId = TestDatastores.projectId(); DatastoreWrapper wrapper = wrap(localDatastore(), multitenant()); String tenantId1 = "first-tenant-ID"; String tenantId1Prefixed = "Vfirst-tenant-ID"; @@ -382,7 +386,7 @@ void testLazyIterator() { wrapper.createOrUpdate(expctedEntities); StructuredQuery query = newEntityQueryBuilder() - .setKind(GENERIC_ENTITY_KIND.getValue()) + .setKind(GENERIC_ENTITY_KIND.value()) .build(); Iterator result = wrapper.read(query); diff --git a/datastore/src/test/java/io/spine/server/storage/datastore/DsAggregateStorageLifecycleHandlingTest.java b/datastore/src/test/java/io/spine/server/storage/datastore/DsAggregateStorageLifecycleHandlingTest.java index 4fadf85b1..3d89151e6 100644 --- a/datastore/src/test/java/io/spine/server/storage/datastore/DsAggregateStorageLifecycleHandlingTest.java +++ b/datastore/src/test/java/io/spine/server/storage/datastore/DsAggregateStorageLifecycleHandlingTest.java @@ -24,19 +24,20 @@ import io.spine.server.aggregate.AggregateStorage; import io.spine.server.aggregate.AggregateStorageLifecycleFlagsHandlingTest; import io.spine.test.aggregate.ProjectId; +import io.spine.testing.server.storage.datastore.TestDatastoreStorageFactory; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.DisplayName; -import static io.spine.server.storage.datastore.TestDatastoreStorageFactory.defaultInstance; import static io.spine.server.storage.datastore.given.TestEnvironment.singleTenantSpec; +import static io.spine.testing.server.storage.datastore.TestDatastoreStorageFactory.local; @DisplayName("`DsAggregateStorage` lifecycle handling should") class DsAggregateStorageLifecycleHandlingTest extends AggregateStorageLifecycleFlagsHandlingTest { - private static final TestDatastoreStorageFactory datastoreFactory = defaultInstance(); + private static final TestDatastoreStorageFactory datastoreFactory = local(); @BeforeAll static void setUpClass() { diff --git a/datastore/src/test/java/io/spine/server/storage/datastore/DsAggregateStorageTest.java b/datastore/src/test/java/io/spine/server/storage/datastore/DsAggregateStorageTest.java index 46bfff463..dea6e16c8 100644 --- a/datastore/src/test/java/io/spine/server/storage/datastore/DsAggregateStorageTest.java +++ b/datastore/src/test/java/io/spine/server/storage/datastore/DsAggregateStorageTest.java @@ -50,6 +50,8 @@ import io.spine.testdata.Sample; import io.spine.testing.client.TestActorRequestFactory; import io.spine.testing.server.TestEventFactory; +import io.spine.testing.server.storage.datastore.SpyStorageFactory; +import io.spine.testing.server.storage.datastore.TestDatastoreStorageFactory; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; @@ -68,9 +70,9 @@ import static io.spine.server.ContextSpec.singleTenant; import static io.spine.server.aggregate.given.Given.CommandMessage.addTask; import static io.spine.server.storage.datastore.DatastoreWrapper.MAX_ENTITIES_PER_WRITE_REQUEST; -import static io.spine.server.storage.datastore.TestDatastoreStorageFactory.defaultInstance; import static io.spine.server.storage.datastore.given.DsRecordStorageTestEnv.datastoreFactory; import static io.spine.server.storage.datastore.given.TestEnvironment.singleTenantSpec; +import static io.spine.testing.server.storage.datastore.TestDatastoreStorageFactory.local; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; @@ -80,7 +82,7 @@ @DisplayName("`DsAggregateStorage` should") class DsAggregateStorageTest extends AggregateStorageTest { - private static final TestDatastoreStorageFactory datastoreFactory = defaultInstance(); + private static final TestDatastoreStorageFactory datastoreFactory = local(); @BeforeAll static void setUpClass() { diff --git a/datastore/src/test/java/io/spine/server/storage/datastore/DsAggregateStorageTruncationTest.java b/datastore/src/test/java/io/spine/server/storage/datastore/DsAggregateStorageTruncationTest.java index 983a764d5..2cfec67e3 100644 --- a/datastore/src/test/java/io/spine/server/storage/datastore/DsAggregateStorageTruncationTest.java +++ b/datastore/src/test/java/io/spine/server/storage/datastore/DsAggregateStorageTruncationTest.java @@ -22,6 +22,7 @@ import io.spine.server.aggregate.AggregateStorageTruncationTest; import io.spine.server.storage.StorageFactory; +import io.spine.testing.server.storage.datastore.TestDatastoreStorageFactory; import org.junit.jupiter.api.DisplayName; @DisplayName("`DsAggregateStorage` after truncation should") @@ -29,6 +30,6 @@ public class DsAggregateStorageTruncationTest extends AggregateStorageTruncation @Override protected StorageFactory storageFactory() { - return TestDatastoreStorageFactory.defaultInstance(); + return TestDatastoreStorageFactory.local(); } } diff --git a/datastore/src/test/java/io/spine/server/storage/datastore/DsInboxStorageTest.java b/datastore/src/test/java/io/spine/server/storage/datastore/DsInboxStorageTest.java index 4791d28c5..45fc19e89 100644 --- a/datastore/src/test/java/io/spine/server/storage/datastore/DsInboxStorageTest.java +++ b/datastore/src/test/java/io/spine/server/storage/datastore/DsInboxStorageTest.java @@ -35,6 +35,7 @@ import io.spine.server.delivery.Page; import io.spine.server.delivery.ShardIndex; import io.spine.server.storage.datastore.given.DsInboxStorageTestEnv; +import io.spine.testing.server.storage.datastore.TestDatastoreStorageFactory; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -57,7 +58,7 @@ class DsInboxStorageTest extends InboxStorageTest { private final TestDatastoreStorageFactory factory = - TestDatastoreStorageFactory.defaultInstance(); + TestDatastoreStorageFactory.local(); @Override @BeforeEach diff --git a/datastore/src/test/java/io/spine/server/storage/datastore/DsProjectionStorageTest.java b/datastore/src/test/java/io/spine/server/storage/datastore/DsProjectionStorageTest.java index d7052145b..fd11e0b51 100644 --- a/datastore/src/test/java/io/spine/server/storage/datastore/DsProjectionStorageTest.java +++ b/datastore/src/test/java/io/spine/server/storage/datastore/DsProjectionStorageTest.java @@ -31,17 +31,18 @@ import io.spine.test.storage.Project; import io.spine.test.storage.ProjectId; import io.spine.testdata.Sample; +import io.spine.testing.server.storage.datastore.TestDatastoreStorageFactory; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.DisplayName; import static io.spine.base.Time.currentTime; -import static io.spine.server.storage.datastore.TestDatastoreStorageFactory.defaultInstance; import static io.spine.server.storage.datastore.given.TestEnvironment.singleTenantSpec; +import static io.spine.testing.server.storage.datastore.TestDatastoreStorageFactory.local; @DisplayName("`DsProjectionStorage` should") class DsProjectionStorageTest extends ProjectionStorageTest { - private static final TestDatastoreStorageFactory datastoreFactory = defaultInstance(); + private static final TestDatastoreStorageFactory datastoreFactory = local(); @Override protected Class getTestEntityClass() { diff --git a/datastore/src/test/java/io/spine/server/storage/datastore/DsPropertyStorageTest.java b/datastore/src/test/java/io/spine/server/storage/datastore/DsPropertyStorageTest.java index a2ab18667..2bcfa0b5d 100644 --- a/datastore/src/test/java/io/spine/server/storage/datastore/DsPropertyStorageTest.java +++ b/datastore/src/test/java/io/spine/server/storage/datastore/DsPropertyStorageTest.java @@ -19,17 +19,18 @@ */ package io.spine.server.storage.datastore; +import io.spine.testing.server.storage.datastore.TestDatastoreStorageFactory; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import static io.spine.server.storage.datastore.TestDatastoreStorageFactory.defaultInstance; import static io.spine.server.storage.datastore.given.TestEnvironment.singleTenantSpec; +import static io.spine.testing.server.storage.datastore.TestDatastoreStorageFactory.local; import static org.junit.jupiter.api.Assertions.assertNotNull; @DisplayName("`DsPropertyStorage` should") class DsPropertyStorageTest { - private static final TestDatastoreStorageFactory datastoreFactory = defaultInstance(); + private static final TestDatastoreStorageFactory datastoreFactory = local(); @SuppressWarnings("DuplicateStringLiteralInspection") // OK for tests. @Test diff --git a/datastore/src/test/java/io/spine/server/storage/datastore/DsRecordStorageTest.java b/datastore/src/test/java/io/spine/server/storage/datastore/DsRecordStorageTest.java index ef14dd979..15878a644 100644 --- a/datastore/src/test/java/io/spine/server/storage/datastore/DsRecordStorageTest.java +++ b/datastore/src/test/java/io/spine/server/storage/datastore/DsRecordStorageTest.java @@ -54,6 +54,8 @@ import io.spine.test.storage.Project; import io.spine.test.storage.ProjectId; import io.spine.test.storage.Task; +import io.spine.testing.server.storage.datastore.SpyStorageFactory; +import io.spine.testing.server.storage.datastore.TestDatastoreStorageFactory; import io.spine.type.TypeUrl; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; diff --git a/datastore/src/test/java/io/spine/server/storage/datastore/DsShardedWorkRegistryTest.java b/datastore/src/test/java/io/spine/server/storage/datastore/DsShardedWorkRegistryTest.java index dd8d36bd2..a500a020d 100644 --- a/datastore/src/test/java/io/spine/server/storage/datastore/DsShardedWorkRegistryTest.java +++ b/datastore/src/test/java/io/spine/server/storage/datastore/DsShardedWorkRegistryTest.java @@ -30,6 +30,7 @@ import io.spine.server.delivery.ShardSessionRecord; import io.spine.server.delivery.ShardedWorkRegistry; import io.spine.server.delivery.ShardedWorkRegistryTest; +import io.spine.testing.server.storage.datastore.TestDatastoreStorageFactory; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -51,7 +52,7 @@ class DsShardedWorkRegistryTest extends ShardedWorkRegistryTest { private static final NodeId nodeId = newNode(); private final TestDatastoreStorageFactory factory = - TestDatastoreStorageFactory.defaultInstance(); + TestDatastoreStorageFactory.local(); private DsShardedWorkRegistry registry; diff --git a/datastore/src/test/java/io/spine/server/storage/datastore/IndexesTest.java b/datastore/src/test/java/io/spine/server/storage/datastore/IndexesTest.java index 2f38b596e..3078608b9 100644 --- a/datastore/src/test/java/io/spine/server/storage/datastore/IndexesTest.java +++ b/datastore/src/test/java/io/spine/server/storage/datastore/IndexesTest.java @@ -21,7 +21,8 @@ package io.spine.server.storage.datastore; import com.google.common.testing.NullPointerTester; -import io.spine.server.storage.datastore.given.TestDatastores; +import io.spine.testing.server.storage.datastore.TestDatastoreWrapper; +import io.spine.testing.server.storage.datastore.TestDatastores; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/datastore/src/test/java/io/spine/server/storage/datastore/KindTest.java b/datastore/src/test/java/io/spine/server/storage/datastore/KindTest.java index 6c94da00b..51de4916a 100644 --- a/datastore/src/test/java/io/spine/server/storage/datastore/KindTest.java +++ b/datastore/src/test/java/io/spine/server/storage/datastore/KindTest.java @@ -78,7 +78,7 @@ void testCheckValidity() { void testFromString() { String type = "my.custom.type"; Kind kind = Kind.of(type); - assertEquals(type, kind.getValue()); + assertEquals(type, kind.value()); } @Test @@ -87,9 +87,9 @@ void testFromTypeUrl() { Descriptors.Descriptor descriptor = Any.getDescriptor(); TypeUrl type = TypeUrl.from(descriptor); Kind kind = Kind.of(type); - assertEquals(descriptor.getFullName(), kind.getValue()); + assertEquals(descriptor.getFullName(), kind.value()); assertEquals(type.toTypeName() - .value(), kind.getValue()); + .value(), kind.value()); } @Test @@ -97,7 +97,7 @@ void testFromTypeUrl() { void testFromDescriptor() { Descriptors.Descriptor descriptor = Any.getDescriptor(); Kind kind = Kind.of(descriptor); - assertEquals(descriptor.getFullName(), kind.getValue()); + assertEquals(descriptor.getFullName(), kind.value()); } @Test @@ -106,7 +106,7 @@ void testFromMessage() { Message message = Any.getDefaultInstance(); Kind kind = Kind.of(message); assertEquals(message.getDescriptorForType() - .getFullName(), kind.getValue()); + .getFullName(), kind.value()); } @Test @@ -115,7 +115,7 @@ void testFromTypeName() { Descriptors.Descriptor descriptor = Any.getDescriptor(); TypeName type = TypeName.from(descriptor); Kind kind = Kind.of(type); - assertEquals(descriptor.getFullName(), kind.getValue()); - assertEquals(type.value(), kind.getValue()); + assertEquals(descriptor.getFullName(), kind.value()); + assertEquals(type.value(), kind.value()); } } diff --git a/datastore/src/test/java/io/spine/server/storage/datastore/NewBoundedContextBuilderTest.java b/datastore/src/test/java/io/spine/server/storage/datastore/NewBoundedContextBuilderTest.java index 55bc2cff7..ed377c5b9 100644 --- a/datastore/src/test/java/io/spine/server/storage/datastore/NewBoundedContextBuilderTest.java +++ b/datastore/src/test/java/io/spine/server/storage/datastore/NewBoundedContextBuilderTest.java @@ -23,9 +23,9 @@ import com.google.cloud.datastore.Datastore; import io.spine.server.BoundedContext; import io.spine.server.BoundedContextBuilder; -import io.spine.server.storage.datastore.given.TestDatastores; import io.spine.server.storage.datastore.tenant.TestNamespaceIndex; import io.spine.server.tenant.TenantIndex; +import io.spine.testing.server.storage.datastore.TestDatastores; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/datastore/src/test/java/io/spine/server/storage/datastore/ProjectIdTest.java b/datastore/src/test/java/io/spine/server/storage/datastore/ProjectIdTest.java index b7001d314..fabaa8ed2 100644 --- a/datastore/src/test/java/io/spine/server/storage/datastore/ProjectIdTest.java +++ b/datastore/src/test/java/io/spine/server/storage/datastore/ProjectIdTest.java @@ -24,13 +24,13 @@ import com.google.cloud.datastore.DatastoreOptions; import com.google.common.testing.EqualsTester; import com.google.common.testing.NullPointerTester; -import io.spine.server.storage.datastore.given.TestDatastores; +import io.spine.testing.server.storage.datastore.TestDatastores; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static com.google.common.truth.Truth.assertThat; -import static io.spine.server.storage.datastore.given.TestDatastores.local; import static io.spine.testing.DisplayNames.NOT_ACCEPT_NULLS; +import static io.spine.testing.server.storage.datastore.TestDatastores.local; @DisplayName("`ProjectId` should") class ProjectIdTest { diff --git a/datastore/src/test/java/io/spine/server/storage/datastore/given/CountingDatastoreWrapper.java b/datastore/src/test/java/io/spine/server/storage/datastore/given/CountingDatastoreWrapper.java index 9700b85fe..29eaf21cc 100644 --- a/datastore/src/test/java/io/spine/server/storage/datastore/given/CountingDatastoreWrapper.java +++ b/datastore/src/test/java/io/spine/server/storage/datastore/given/CountingDatastoreWrapper.java @@ -25,7 +25,7 @@ import com.google.cloud.datastore.Key; import com.google.cloud.datastore.StructuredQuery; import io.spine.server.storage.datastore.DsQueryIterator; -import io.spine.server.storage.datastore.TestDatastoreWrapper; +import io.spine.testing.server.storage.datastore.TestDatastoreWrapper; import org.checkerframework.checker.nullness.qual.Nullable; import java.util.Collection; diff --git a/datastore/src/test/java/io/spine/server/storage/datastore/given/DatastoreWrapperTestEnv.java b/datastore/src/test/java/io/spine/server/storage/datastore/given/DatastoreWrapperTestEnv.java index e9aff5396..f63a8361e 100644 --- a/datastore/src/test/java/io/spine/server/storage/datastore/given/DatastoreWrapperTestEnv.java +++ b/datastore/src/test/java/io/spine/server/storage/datastore/given/DatastoreWrapperTestEnv.java @@ -28,6 +28,7 @@ import io.spine.server.storage.datastore.DatastoreWrapper; import io.spine.server.storage.datastore.Kind; import io.spine.server.tenant.TenantAwareOperation; +import io.spine.testing.server.storage.datastore.TestDatastores; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -39,6 +40,8 @@ public class DatastoreWrapperTestEnv { public static final String NAMESPACE_HOLDER_KIND = "spine.test.NAMESPACE_HOLDER_KIND"; public static final Kind GENERIC_ENTITY_KIND = Kind.of("my.entity"); + private static final String SERVICE_ACCOUNT_RESOURCE_PATH = "spine-dev.json"; + /** * Prevents instantiation of this test environment. */ @@ -70,6 +73,6 @@ public static Datastore localDatastore() { } public static Datastore remoteDatastore() { - return TestDatastores.remote(); + return TestDatastores.remote(SERVICE_ACCOUNT_RESOURCE_PATH); } } diff --git a/datastore/src/test/java/io/spine/server/storage/datastore/given/DsRecordStorageTestEnv.java b/datastore/src/test/java/io/spine/server/storage/datastore/given/DsRecordStorageTestEnv.java index b238ef713..0c6b0c6fd 100644 --- a/datastore/src/test/java/io/spine/server/storage/datastore/given/DsRecordStorageTestEnv.java +++ b/datastore/src/test/java/io/spine/server/storage/datastore/given/DsRecordStorageTestEnv.java @@ -38,11 +38,11 @@ import io.spine.server.entity.storage.Column; import io.spine.server.entity.storage.EntityRecordWithColumns; import io.spine.server.storage.RecordStorage; -import io.spine.server.storage.datastore.TestDatastoreStorageFactory; import io.spine.test.datastore.College; import io.spine.test.datastore.CollegeId; import io.spine.test.storage.Project; import io.spine.test.storage.ProjectId; +import io.spine.testing.server.storage.datastore.TestDatastoreStorageFactory; import java.security.SecureRandom; import java.util.ArrayList; @@ -90,7 +90,7 @@ private DsRecordStorageTestEnv() { } public static TestDatastoreStorageFactory datastoreFactory() { - return TestDatastoreStorageFactory.defaultInstance(); + return TestDatastoreStorageFactory.local(); } public static OrderBy emptyOrderBy() { diff --git a/datastore/src/test/java/io/spine/server/storage/datastore/given/TestDatastores.java b/datastore/src/test/java/io/spine/server/storage/datastore/given/TestDatastores.java deleted file mode 100644 index b43958d9a..000000000 --- a/datastore/src/test/java/io/spine/server/storage/datastore/given/TestDatastores.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * 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.given; - -import com.google.auth.oauth2.ServiceAccountCredentials; -import com.google.cloud.NoCredentials; -import com.google.cloud.datastore.Datastore; -import com.google.cloud.datastore.DatastoreOptions; -import io.spine.logging.Logging; -import io.spine.server.storage.datastore.ProjectId; - -import java.io.BufferedInputStream; -import java.io.IOException; -import java.io.InputStream; - -import static com.google.auth.oauth2.ServiceAccountCredentials.fromStream; - -/** - * Provides test {@link Datastore} instances. - */ -public class TestDatastores { - - private static final ProjectId TEST_PROJECT_ID = ProjectId.of("spine-dev"); - - /** Prevent this test utility class from being instantiated. */ - private TestDatastores() { - } - - /** - * Obtains Datastore instance used for testing on a developer's workstation. - */ - public static Datastore local() { - return Local.INSTANCE.getService(); - } - - /** - * Obtains Datastore instance used for testing in a CI environment. - */ - public static Datastore remote() { - return Ci.INSTANCE.getService(); - } - - /** - * Obtains ProjectId of the test environment. - */ - public static ProjectId projectId() { - return TEST_PROJECT_ID; - } - - /** - * Abstract base for options factories. - */ - private abstract static class Options { - - private final DatastoreOptions.Builder builder; - - private Options() { - builder = DatastoreOptions.newBuilder() - .setProjectId(projectId().getValue()); - } - - final DatastoreOptions.Builder builder() { - return builder; - } - - final DatastoreOptions create() { - return builder.build(); - } - } - - /** - * Local Datastore options used on developers' machines. - */ - private static final class Local extends Options { - - private static final String DEFAULT_HOST = "localhost:8080"; - private static final DatastoreOptions INSTANCE = new Local().create(); - - private Local() { - super(); - builder().setHost(DEFAULT_HOST); - builder().setCredentials(NoCredentials.getInstance()); - } - } - - /** - * Options used to run tests in CI environment, which uses connection to - * a real Datastore instance in the testing Google Cloud environment. - */ - @SuppressWarnings("NewClassNamingConvention") - private static final class Ci extends Options implements Logging { - - private static final String CREDENTIALS_FILE_PATH = "/spine-dev.json"; - private static final DatastoreOptions INSTANCE = new Ci().create(); - - private Ci() { - try { - InputStream is = TestDatastores.class.getResourceAsStream(CREDENTIALS_FILE_PATH); - BufferedInputStream bufferedStream = new BufferedInputStream(is); - ServiceAccountCredentials credentials = fromStream(bufferedStream); - builder().setCredentials(credentials); - } catch (@SuppressWarnings("OverlyBroadCatchBlock") IOException e) { - _warn().log("Cannot find the credentials file `%s`.", CREDENTIALS_FILE_PATH); - } - } - } -} diff --git a/datastore/src/test/java/io/spine/server/storage/datastore/tenant/DatastoreTenantsTest.java b/datastore/src/test/java/io/spine/server/storage/datastore/tenant/DatastoreTenantsTest.java index 364075aa4..423cb6b8f 100644 --- a/datastore/src/test/java/io/spine/server/storage/datastore/tenant/DatastoreTenantsTest.java +++ b/datastore/src/test/java/io/spine/server/storage/datastore/tenant/DatastoreTenantsTest.java @@ -21,8 +21,8 @@ package io.spine.server.storage.datastore.tenant; import io.spine.core.TenantId; -import io.spine.server.storage.datastore.given.TestDatastores; import io.spine.server.tenant.TenantIndex; +import io.spine.testing.server.storage.datastore.TestDatastores; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/datastore/src/test/java/io/spine/server/storage/datastore/tenant/NamespaceConvertersTest.java b/datastore/src/test/java/io/spine/server/storage/datastore/tenant/NamespaceConvertersTest.java index 23b205878..3a31c5a6e 100644 --- a/datastore/src/test/java/io/spine/server/storage/datastore/tenant/NamespaceConvertersTest.java +++ b/datastore/src/test/java/io/spine/server/storage/datastore/tenant/NamespaceConvertersTest.java @@ -21,6 +21,7 @@ package io.spine.server.storage.datastore.tenant; import io.spine.core.TenantId; +import io.spine.testing.UtilityClassTest; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -29,11 +30,15 @@ import static org.junit.jupiter.api.Assertions.assertEquals; @DisplayName("`NamespaceConverters` should") -class NamespaceConvertersTest { +class NamespaceConvertersTest extends UtilityClassTest { + + NamespaceConvertersTest() { + super(NamespaceConverters.class); + } @Test @DisplayName(HAVE_PARAMETERLESS_CTOR) - void have_private_utility_ctor() { + void haveUtilityCtor() { assertHasPrivateParameterlessCtor(NamespaceConverters.class); } diff --git a/datastore/src/test/java/io/spine/server/storage/datastore/tenant/NamespaceIndexTest.java b/datastore/src/test/java/io/spine/server/storage/datastore/tenant/NamespaceIndexTest.java index f8c9221a6..719ededf2 100644 --- a/datastore/src/test/java/io/spine/server/storage/datastore/tenant/NamespaceIndexTest.java +++ b/datastore/src/test/java/io/spine/server/storage/datastore/tenant/NamespaceIndexTest.java @@ -34,10 +34,10 @@ import io.spine.server.entity.EntityRecord; import io.spine.server.storage.RecordStorage; import io.spine.server.storage.datastore.DatastoreStorageFactory; -import io.spine.server.storage.datastore.given.TestDatastores; import io.spine.server.storage.datastore.tenant.given.TestProjection; import io.spine.test.datastore.College; import io.spine.testing.TestValues; +import io.spine.testing.server.storage.datastore.TestDatastores; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -53,7 +53,6 @@ import static com.google.common.base.Throwables.getStackTraceAsString; import static com.google.common.truth.Truth.assertThat; import static io.spine.protobuf.AnyPacker.pack; -import static io.spine.server.storage.datastore.given.TestDatastores.local; import static io.spine.server.tenant.TenantAwareRunner.with; import static io.spine.testing.DisplayNames.NOT_ACCEPT_NULLS; import static java.lang.String.format; @@ -297,10 +296,12 @@ private static Key key(String name) { private static Datastore datastore() { String namespace = "Vsome-namespace"; - DatastoreOptions options = local().getOptions() - .toBuilder() - .setNamespace(namespace) - .build(); + DatastoreOptions options = TestDatastores + .local() + .getOptions() + .toBuilder() + .setNamespace(namespace) + .build(); Datastore datastore = options.getService(); return datastore; } diff --git a/datastore/src/test/java/io/spine/server/storage/datastore/tenant/NamespaceTest.java b/datastore/src/test/java/io/spine/server/storage/datastore/tenant/NamespaceTest.java index fd6b39be1..f865a0da2 100644 --- a/datastore/src/test/java/io/spine/server/storage/datastore/tenant/NamespaceTest.java +++ b/datastore/src/test/java/io/spine/server/storage/datastore/tenant/NamespaceTest.java @@ -27,11 +27,11 @@ import io.spine.net.EmailAddress; import io.spine.net.InternetDomain; import io.spine.server.storage.datastore.ProjectId; -import io.spine.server.storage.datastore.given.TestDatastores; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static io.spine.testing.DisplayNames.NOT_ACCEPT_NULLS; +import static io.spine.testing.server.storage.datastore.TestDatastores.defaultLocalProjectId; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -44,7 +44,7 @@ class NamespaceTest { @Test @DisplayName(NOT_ACCEPT_NULLS) void testNulls() { - ProjectId defaultProjectId = TestDatastores.projectId(); + ProjectId defaultProjectId = defaultLocalProjectId(); Key defaultKey = Key.newBuilder(defaultProjectId.getValue(), "kind", "name") .build(); new NullPointerTester() diff --git a/datastore/src/test/java/io/spine/server/storage/datastore/type/DsColumnTypesTest.java b/datastore/src/test/java/io/spine/server/storage/datastore/type/DsColumnTypesTest.java index 412252512..518f63d04 100644 --- a/datastore/src/test/java/io/spine/server/storage/datastore/type/DsColumnTypesTest.java +++ b/datastore/src/test/java/io/spine/server/storage/datastore/type/DsColumnTypesTest.java @@ -28,7 +28,6 @@ import io.spine.core.Version; import io.spine.core.Versions; import io.spine.json.Json; -import io.spine.server.storage.datastore.given.TestDatastores; import io.spine.test.storage.Project; import io.spine.testdata.Sample; import org.junit.jupiter.api.BeforeEach; @@ -41,6 +40,7 @@ import static io.spine.server.storage.datastore.type.DsColumnTypes.timestampType; import static io.spine.testing.DisplayNames.HAVE_PARAMETERLESS_CTOR; import static io.spine.testing.Tests.assertHasPrivateParameterlessCtor; +import static io.spine.testing.server.storage.datastore.TestDatastores.defaultLocalProjectId; @DisplayName("DsColumnTypes should") class DsColumnTypesTest { @@ -225,8 +225,7 @@ private void setDatastoreType(DatastoreColumnType type, } private static BaseEntity.Builder entityBuilder() { - String projectId = TestDatastores.projectId() - .value(); + String projectId = defaultLocalProjectId().value(); Key key = Key.newBuilder(projectId, "some-entity-kind", "some-name") .build(); Entity.Builder builder = Entity.newBuilder(key); diff --git a/license-report.md b/license-report.md index ecea747de..5e7fcc1e3 100644 --- a/license-report.md +++ b/license-report.md @@ -1,6 +1,6 @@ -# Dependencies of `io.spine.gcloud:spine-datastore:1.1.2` +# Dependencies of `io.spine.gcloud:spine-datastore:1.1.3-SNAPSHOT+1` ## Runtime 1. **Group:** com.fasterxml.jackson.core **Name:** jackson-core **Version:** 2.9.9 @@ -734,12 +734,12 @@ The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu Sep 26 15:14:26 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 **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). -# Dependencies of `io.spine.gcloud:spine-stackdriver-trace:1.1.2` +# Dependencies of `io.spine.gcloud:spine-stackdriver-trace:1.1.3-SNAPSHOT+1` ## Runtime 1. **Group:** com.fasterxml.jackson.core **Name:** jackson-core **Version:** 2.9.6 @@ -1474,4 +1474,764 @@ This report was generated on **Thu Sep 26 15:14:26 EEST 2019** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu Sep 26 15:14:38 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 **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). + + + + +# Dependencies of `io.spine.gcloud:spine-testutil-gcloud:1.1.3-SNAPSHOT+1` + +## Runtime +1. **Group:** com.fasterxml.jackson.core **Name:** jackson-core **Version:** 2.9.9 + * **Project URL:** [https://github.com/FasterXML/jackson-core](https://github.com/FasterXML/jackson-core) + * **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.android **Name:** annotations **Version:** 4.1.1.4 + * **POM Project URL:** [http://source.android.com/](http://source.android.com/) + * **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) + +1. **Group:** com.google.api **Name:** api-common **Version:** 1.8.1 + * **POM Project URL:** [https://github.com/googleapis/api-common-java](https://github.com/googleapis/api-common-java) + * **POM License: BSD** - [https://github.com/googleapis/api-common-java/blob/master/LICENSE](https://github.com/googleapis/api-common-java/blob/master/LICENSE) + +1. **Group:** com.google.api **Name:** gax **Version:** 1.48.1 + * **POM Project URL:** [https://github.com/googleapis/gax-java](https://github.com/googleapis/gax-java) + * **POM License: BSD** - [https://github.com/googleapis/gax-java/blob/master/LICENSE](https://github.com/googleapis/gax-java/blob/master/LICENSE) + +1. **Group:** com.google.api **Name:** gax-httpjson **Version:** 0.65.1 + * **POM Project URL:** [https://github.com/googleapis/gax-java](https://github.com/googleapis/gax-java) + * **POM License: BSD** - [https://github.com/googleapis/gax-java/blob/master/LICENSE](https://github.com/googleapis/gax-java/blob/master/LICENSE) + +1. **Group:** com.google.api-client **Name:** google-api-client **Version:** 1.30.2 + * **Manifest Project URL:** [https://developers.google.com/api-client-library/java/](https://developers.google.com/api-client-library/java/) + * **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 + * **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 + * **POM Project URL:** [https://github.com/googleapis/common-protos-java](https://github.com/googleapis/common-protos-java) + * **POM License: Apache** - [https://github.com/googleapis/common-protos-java/blob/master/LICENSE](https://github.com/googleapis/common-protos-java/blob/master/LICENSE) + +1. **Group:** com.google.api.grpc **Name:** proto-google-iam-v1 **Version:** 0.12.0 + * **POM Project URL:** [https://github.com/googleapis/api-client-staging](https://github.com/googleapis/api-client-staging) + * **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.auth **Name:** google-auth-library-credentials **Version:** 0.17.1 + * **POM License: BSD New license** - [http://opensource.org/licenses/BSD-3-Clause](http://opensource.org/licenses/BSD-3-Clause) + +1. **Group:** com.google.auth **Name:** google-auth-library-oauth2-http **Version:** 0.17.1 + * **POM License: BSD New license** - [http://opensource.org/licenses/BSD-3-Clause](http://opensource.org/licenses/BSD-3-Clause) + +1. **Group:** com.google.auto.value **Name:** auto-value-annotations **Version:** 1.6.6 + * **POM Project URL:** [https://github.com/google/auto/tree/master/value](https://github.com/google/auto/tree/master/value) + * **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group:** com.google.cloud **Name:** google-cloud-core **Version:** 1.90.0 + * **POM Project URL:** [https://github.com/googleapis/google-cloud-java/tree/master/google-cloud-clients/google-cloud-core](https://github.com/googleapis/google-cloud-java/tree/master/google-cloud-clients/google-cloud-core) + * **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-core-http **Version:** 1.90.0 + * **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 + * **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) + +1. **Group:** com.google.cloud.datastore **Name:** datastore-v1-proto-client **Version:** 1.6.0 + * **POM License: The Apache 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.code.findbugs **Name:** jsr305 **Version:** 3.0.2 + * **Manifest license URL:** [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + * **POM Project URL:** [http://findbugs.sourceforge.net/](http://findbugs.sourceforge.net/) + * **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.code.gson **Name:** gson **Version:** 2.8.5 + * **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group:** com.google.errorprone **Name:** error_prone_annotations **Version:** 2.3.3 + * **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group:** com.google.errorprone **Name:** error_prone_type_annotations **Version:** 2.3.3 + * **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group:** com.google.flogger **Name:** flogger **Version:** 0.4 + * **POM Project URL:** [https://github.com/google/flogger](https://github.com/google/flogger) + * **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group:** com.google.flogger **Name:** flogger-system-backend **Version:** 0.4 + * **POM Project URL:** [https://github.com/google/flogger](https://github.com/google/flogger) + * **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group:** com.google.guava **Name:** failureaccess **Version:** 1.0.1 + * **Manifest Project URL:** [https://github.com/google/guava/](https://github.com/google/guava/) + * **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.guava **Name:** guava **Version:** 28.1-jre + * **Manifest Project URL:** [https://github.com/google/guava/](https://github.com/google/guava/) + * **Manifest license URL:** [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + * **POM License: Apache 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.guava **Name:** listenablefuture **Version:** 9999.0-empty-to-avoid-conflict-with-guava + * **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.http-client **Name:** google-http-client **Version:** 1.31.0 + * **Manifest Project URL:** [http://www.google.com/](http://www.google.com/) + * **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.http-client **Name:** google-http-client-appengine **Version:** 1.31.0 + * **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.http-client **Name:** google-http-client-jackson **Version:** 1.20.0 + * **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.http-client **Name:** google-http-client-jackson2 **Version:** 1.31.0 + * **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.http-client **Name:** google-http-client-protobuf **Version:** 1.20.0 + * **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.j2objc **Name:** j2objc-annotations **Version:** 1.3 + * **POM Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/) + * **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.oauth-client **Name:** google-oauth-client **Version:** 1.30.1 + * **Manifest Project URL:** [http://www.google.com/](http://www.google.com/) + * **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.protobuf **Name:** protobuf-java **Version:** 3.9.0 + * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) + * **Manifest license URL:** [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) + * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) + +1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.9.0 + * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) + * **Manifest license URL:** [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) + * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) + +1. **Group:** com.squareup.okhttp **Name:** okhttp **Version:** 2.5.0 + * **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group:** com.squareup.okio **Name:** okio **Version:** 1.13.0 + * **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group:** commons-codec **Name:** commons-codec **Version:** 1.11 + * **Project URL:** [http://commons.apache.org/proper/commons-codec/](http://commons.apache.org/proper/commons-codec/) + * **Manifest license URL:** [https://www.apache.org/licenses/LICENSE-2.0.txt](https://www.apache.org/licenses/LICENSE-2.0.txt) + * **POM License: Apache License, Version 2.0** - [https://www.apache.org/licenses/LICENSE-2.0.txt](https://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group:** commons-logging **Name:** commons-logging **Version:** 1.2 + * **Project URL:** [http://commons.apache.org/proper/commons-logging/](http://commons.apache.org/proper/commons-logging/) + * **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 + * **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 + * **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 + * **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-okhttp **Version:** 1.22.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-protobuf **Version:** 1.22.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-protobuf-lite **Version:** 1.22.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-stub **Version:** 1.22.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.opencensus **Name:** opencensus-api **Version:** 0.23.0 + * **POM Project URL:** [https://github.com/census-instrumentation/opencensus-java](https://github.com/census-instrumentation/opencensus-java) + * **POM License: The Apache 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.opencensus **Name:** opencensus-contrib-grpc-metrics **Version:** 0.21.0 + * **POM Project URL:** [https://github.com/census-instrumentation/opencensus-java](https://github.com/census-instrumentation/opencensus-java) + * **POM License: The Apache 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.opencensus **Name:** opencensus-contrib-http-util **Version:** 0.21.0 + * **POM Project URL:** [https://github.com/census-instrumentation/opencensus-java](https://github.com/census-instrumentation/opencensus-java) + * **POM License: The Apache 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.perfmark **Name:** perfmark-api **Version:** 0.17.0 + * **POM Project URL:** [https://github.com/perfmark/perfmark](https://github.com/perfmark/perfmark) + * **POM License: Apache 2.0** - [https://opensource.org/licenses/Apache-2.0](https://opensource.org/licenses/Apache-2.0) + +1. **Group:** javax.annotation **Name:** javax.annotation-api **Version:** 1.3.2 + * **Manifest Project URL:** [https://javaee.github.io/glassfish](https://javaee.github.io/glassfish) + * **Manifest license URL:** [https://github.com/javaee/javax.annotation/blob/master/LICENSE](https://github.com/javaee/javax.annotation/blob/master/LICENSE) + * **POM Project URL:** [http://jcp.org/en/jsr/detail?id=250](http://jcp.org/en/jsr/detail?id=250) + * **POM License: CDDL + GPLv2 with classpath exception** - [https://github.com/javaee/javax.annotation/blob/master/LICENSE](https://github.com/javaee/javax.annotation/blob/master/LICENSE) + +1. **Group:** org.apache.httpcomponents **Name:** httpclient **Version:** 4.5.9 + * **POM Project URL:** [http://hc.apache.org/httpcomponents-client](http://hc.apache.org/httpcomponents-client) + * **POM License: Apache License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group:** org.apache.httpcomponents **Name:** httpcore **Version:** 4.4.11 + * **POM Project URL:** [http://hc.apache.org/httpcomponents-core-ga](http://hc.apache.org/httpcomponents-core-ga) + * **POM License: Apache License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group:** org.apiguardian **Name:** apiguardian-api **Version:** 1.1.0 + * **POM Project URL:** [https://github.com/apiguardian-team/apiguardian](https://github.com/apiguardian-team/apiguardian) + * **POM License: The Apache License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group:** org.checkerframework **Name:** checker-qual **Version:** 2.9.0 + * **POM Project URL:** [https://checkerframework.org](https://checkerframework.org) + * **POM License: The MIT License** - [http://opensource.org/licenses/MIT](http://opensource.org/licenses/MIT) + +1. **Group:** org.codehaus.jackson **Name:** jackson-core-asl **Version:** 1.9.11 + * **Manifest license URL:** [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + * **POM Project URL:** [http://jackson.codehaus.org](http://jackson.codehaus.org) + * **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:** org.codehaus.mojo **Name:** animal-sniffer-annotations **Version:** 1.18 + * **POM License: MIT license** - [http://www.opensource.org/licenses/mit-license.php](http://www.opensource.org/licenses/mit-license.php) + * **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:** org.junit.jupiter **Name:** junit-jupiter-api **Version:** 5.5.1 + * **POM Project URL:** [https://junit.org/junit5/](https://junit.org/junit5/) + * **POM License: Eclipse Public License v2.0** - [https://www.eclipse.org/legal/epl-v20.html](https://www.eclipse.org/legal/epl-v20.html) + +1. **Group:** org.junit.jupiter **Name:** junit-jupiter-params **Version:** 5.5.1 + * **POM Project URL:** [https://junit.org/junit5/](https://junit.org/junit5/) + * **POM License: Eclipse Public License v2.0** - [https://www.eclipse.org/legal/epl-v20.html](https://www.eclipse.org/legal/epl-v20.html) + +1. **Group:** org.junit.platform **Name:** junit-platform-commons **Version:** 1.5.1 + * **POM Project URL:** [https://junit.org/junit5/](https://junit.org/junit5/) + * **POM License: Eclipse Public License v2.0** - [https://www.eclipse.org/legal/epl-v20.html](https://www.eclipse.org/legal/epl-v20.html) + +1. **Group:** org.opentest4j **Name:** opentest4j **Version:** 1.2.0 + * **Manifest License:** The Apache License, Version 2.0 (Not packaged) + * **POM Project URL:** [https://github.com/ota4j-team/opentest4j](https://github.com/ota4j-team/opentest4j) + * **POM License: The Apache License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group:** org.threeten **Name:** threetenbp **Version:** 1.3.3 + * **Manifest Project URL:** [http://www.threeten.org](http://www.threeten.org) + * **Manifest license URL:** [https://raw.githubusercontent.com/ThreeTen/threetenbp/master/LICENSE.txt](https://raw.githubusercontent.com/ThreeTen/threetenbp/master/LICENSE.txt) + * **POM Project URL:** [https://www.threeten.org/threetenbp](https://www.threeten.org/threetenbp) + * **POM License: BSD 3-clause** - [https://raw.githubusercontent.com/ThreeTen/threetenbp/master/LICENSE.txt](https://raw.githubusercontent.com/ThreeTen/threetenbp/master/LICENSE.txt) + +## Compile, tests and tooling +1. **Group:** aopalliance **Name:** aopalliance **Version:** 1.0 + * **POM Project URL:** [http://aopalliance.sourceforge.net](http://aopalliance.sourceforge.net) + * **POM License: Public Domain** + +1. **Group:** com.beust **Name:** jcommander **Version:** 1.72 + * **Manifest license URL:** [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) + * **POM Project URL:** [http://jcommander.org](http://jcommander.org) + * **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) + +1. **Group:** com.fasterxml.jackson.core **Name:** jackson-core **Version:** 2.9.9 + * **Project URL:** [https://github.com/FasterXML/jackson-core](https://github.com/FasterXML/jackson-core) + * **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.github.kevinstern **Name:** software-and-algorithms **Version:** 1.0 + * **POM Project URL:** [https://www.github.com/KevinStern/software-and-algorithms](https://www.github.com/KevinStern/software-and-algorithms) + * **POM License: MIT License** - [http://www.opensource.org/licenses/mit-license.php](http://www.opensource.org/licenses/mit-license.php) + +1. **Group:** com.github.stephenc.jcip **Name:** jcip-annotations **Version:** 1.0-1 + * **POM Project URL:** [http://stephenc.github.com/jcip-annotations](http://stephenc.github.com/jcip-annotations) + * **POM License: Apache 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.android **Name:** annotations **Version:** 4.1.1.4 + * **POM Project URL:** [http://source.android.com/](http://source.android.com/) + * **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) + +1. **Group:** com.google.api **Name:** api-common **Version:** 1.8.1 + * **POM Project URL:** [https://github.com/googleapis/api-common-java](https://github.com/googleapis/api-common-java) + * **POM License: BSD** - [https://github.com/googleapis/api-common-java/blob/master/LICENSE](https://github.com/googleapis/api-common-java/blob/master/LICENSE) + +1. **Group:** com.google.api **Name:** gax **Version:** 1.48.1 + * **POM Project URL:** [https://github.com/googleapis/gax-java](https://github.com/googleapis/gax-java) + * **POM License: BSD** - [https://github.com/googleapis/gax-java/blob/master/LICENSE](https://github.com/googleapis/gax-java/blob/master/LICENSE) + +1. **Group:** com.google.api **Name:** gax-httpjson **Version:** 0.65.1 + * **POM Project URL:** [https://github.com/googleapis/gax-java](https://github.com/googleapis/gax-java) + * **POM License: BSD** - [https://github.com/googleapis/gax-java/blob/master/LICENSE](https://github.com/googleapis/gax-java/blob/master/LICENSE) + +1. **Group:** com.google.api-client **Name:** google-api-client **Version:** 1.30.2 + * **Manifest Project URL:** [https://developers.google.com/api-client-library/java/](https://developers.google.com/api-client-library/java/) + * **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 + * **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 + * **POM Project URL:** [https://github.com/googleapis/common-protos-java](https://github.com/googleapis/common-protos-java) + * **POM License: Apache** - [https://github.com/googleapis/common-protos-java/blob/master/LICENSE](https://github.com/googleapis/common-protos-java/blob/master/LICENSE) + +1. **Group:** com.google.api.grpc **Name:** proto-google-iam-v1 **Version:** 0.12.0 + * **POM Project URL:** [https://github.com/googleapis/api-client-staging](https://github.com/googleapis/api-client-staging) + * **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.auth **Name:** google-auth-library-credentials **Version:** 0.17.1 + * **POM License: BSD New license** - [http://opensource.org/licenses/BSD-3-Clause](http://opensource.org/licenses/BSD-3-Clause) + +1. **Group:** com.google.auth **Name:** google-auth-library-oauth2-http **Version:** 0.17.1 + * **POM License: BSD New license** - [http://opensource.org/licenses/BSD-3-Clause](http://opensource.org/licenses/BSD-3-Clause) + +1. **Group:** com.google.auto **Name:** auto-common **Version:** 0.10 + * **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group:** com.google.auto.value **Name:** auto-value-annotations **Version:** 1.6.6 + * **POM Project URL:** [https://github.com/google/auto/tree/master/value](https://github.com/google/auto/tree/master/value) + * **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group:** com.google.cloud **Name:** google-cloud-core **Version:** 1.90.0 + * **POM Project URL:** [https://github.com/googleapis/google-cloud-java/tree/master/google-cloud-clients/google-cloud-core](https://github.com/googleapis/google-cloud-java/tree/master/google-cloud-clients/google-cloud-core) + * **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-core-http **Version:** 1.90.0 + * **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 + * **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) + +1. **Group:** com.google.cloud.datastore **Name:** datastore-v1-proto-client **Version:** 1.6.0 + * **POM License: The Apache 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.code.findbugs **Name:** jFormatString **Version:** 3.0.0 + * **POM Project URL:** [http://findbugs.sourceforge.net/](http://findbugs.sourceforge.net/) + * **POM License: GNU Lesser Public License** - [http://www.gnu.org/licenses/lgpl.html](http://www.gnu.org/licenses/lgpl.html) + +1. **Group:** com.google.code.findbugs **Name:** jsr305 **Version:** 3.0.2 + * **Manifest license URL:** [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + * **POM Project URL:** [http://findbugs.sourceforge.net/](http://findbugs.sourceforge.net/) + * **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.code.gson **Name:** gson **Version:** 2.7 + * **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group:** com.google.code.gson **Name:** gson **Version:** 2.8.5 + * **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group:** com.google.errorprone **Name:** error_prone_annotation **Version:** 2.3.3 + * **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group:** com.google.errorprone **Name:** error_prone_annotations **Version:** 2.3.3 + * **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group:** com.google.errorprone **Name:** error_prone_check_api **Version:** 2.3.3 + * **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group:** com.google.errorprone **Name:** error_prone_core **Version:** 2.3.3 + * **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group:** com.google.errorprone **Name:** error_prone_type_annotations **Version:** 2.3.3 + * **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group:** com.google.errorprone **Name:** javac **Version:** 9+181-r4173-1 + * **POM Project URL:** [https://github.com/google/error-prone-javac](https://github.com/google/error-prone-javac) + * **POM License: GNU General Public License, version 2, with the Classpath Exception** - [http://openjdk.java.net/legal/gplv2+ce.html](http://openjdk.java.net/legal/gplv2+ce.html) + +1. **Group:** com.google.flogger **Name:** flogger **Version:** 0.4 + * **POM Project URL:** [https://github.com/google/flogger](https://github.com/google/flogger) + * **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group:** com.google.flogger **Name:** flogger-system-backend **Version:** 0.4 + * **POM Project URL:** [https://github.com/google/flogger](https://github.com/google/flogger) + * **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group:** com.google.gradle **Name:** osdetector-gradle-plugin **Version:** 1.4.0 + * **POM Project URL:** [https://github.com/google/osdetector-gradle-plugin](https://github.com/google/osdetector-gradle-plugin) + * **POM License: Apache License 2.0** - [http://opensource.org/licenses/Apache-2.0](http://opensource.org/licenses/Apache-2.0) + +1. **Group:** com.google.guava **Name:** failureaccess **Version:** 1.0.1 + * **Manifest Project URL:** [https://github.com/google/guava/](https://github.com/google/guava/) + * **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.guava **Name:** guava **Version:** 28.1-jre + * **Manifest Project URL:** [https://github.com/google/guava/](https://github.com/google/guava/) + * **Manifest license URL:** [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + * **POM License: Apache 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.guava **Name:** guava-testlib **Version:** 28.1-jre + * **POM License: Apache 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.guava **Name:** listenablefuture **Version:** 9999.0-empty-to-avoid-conflict-with-guava + * **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.http-client **Name:** google-http-client **Version:** 1.31.0 + * **Manifest Project URL:** [http://www.google.com/](http://www.google.com/) + * **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.http-client **Name:** google-http-client-appengine **Version:** 1.31.0 + * **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.http-client **Name:** google-http-client-jackson **Version:** 1.20.0 + * **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.http-client **Name:** google-http-client-jackson2 **Version:** 1.31.0 + * **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.http-client **Name:** google-http-client-protobuf **Version:** 1.20.0 + * **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.j2objc **Name:** j2objc-annotations **Version:** 1.3 + * **POM Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/) + * **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.oauth-client **Name:** google-oauth-client **Version:** 1.30.1 + * **Manifest Project URL:** [http://www.google.com/](http://www.google.com/) + * **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.protobuf **Name:** protobuf-gradle-plugin **Version:** 0.8.8 + * **POM Project URL:** [https://github.com/google/protobuf-gradle-plugin](https://github.com/google/protobuf-gradle-plugin) + * **POM License: BSD 3-Clause** - [http://opensource.org/licenses/BSD-3-Clause](http://opensource.org/licenses/BSD-3-Clause) + +1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.4.0 + * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) + * **Manifest license URL:** [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) + * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) + * **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.protobuf **Name:** protobuf-java **Version:** 3.9.0 + * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) + * **Manifest license URL:** [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) + * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) + +1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.9.0 + * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) + * **Manifest license URL:** [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) + * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) + +1. **Group:** com.google.protobuf **Name:** protoc **Version:** 3.9.0 + * **POM Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) + * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) + * **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.truth **Name:** truth **Version:** 1.0 + * **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.truth.extensions **Name:** truth-java8-extension **Version:** 1.0 + * **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.truth.extensions **Name:** truth-liteproto-extension **Version:** 1.0 + * **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.truth.extensions **Name:** truth-proto-extension **Version:** 1.0 + * **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.googlecode.java-diff-utils **Name:** diffutils **Version:** 1.3.0 + * **Manifest license URL:** [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + * **POM Project URL:** [http://code.google.com/p/java-diff-utils/](http://code.google.com/p/java-diff-utils/) + * **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.squareup **Name:** javapoet **Version:** 1.11.0 + * **POM Project URL:** [http://github.com/square/javapoet/](http://github.com/square/javapoet/) + * **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group:** com.squareup.okhttp **Name:** okhttp **Version:** 2.5.0 + * **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group:** com.squareup.okio **Name:** okio **Version:** 1.13.0 + * **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group:** commons-codec **Name:** commons-codec **Version:** 1.11 + * **Project URL:** [http://commons.apache.org/proper/commons-codec/](http://commons.apache.org/proper/commons-codec/) + * **Manifest license URL:** [https://www.apache.org/licenses/LICENSE-2.0.txt](https://www.apache.org/licenses/LICENSE-2.0.txt) + * **POM License: Apache License, Version 2.0** - [https://www.apache.org/licenses/LICENSE-2.0.txt](https://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group:** commons-io **Name:** commons-io **Version:** 2.6 + * **Project URL:** [http://commons.apache.org/proper/commons-io/](http://commons.apache.org/proper/commons-io/) + * **Manifest license URL:** [https://www.apache.org/licenses/LICENSE-2.0.txt](https://www.apache.org/licenses/LICENSE-2.0.txt) + * **POM License: Apache License, Version 2.0** - [https://www.apache.org/licenses/LICENSE-2.0.txt](https://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group:** commons-lang **Name:** commons-lang **Version:** 2.6 + * **Project URL:** [http://commons.apache.org/lang/](http://commons.apache.org/lang/) + * **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:** commons-logging **Name:** commons-logging **Version:** 1.2 + * **Project URL:** [http://commons.apache.org/proper/commons-logging/](http://commons.apache.org/proper/commons-logging/) + * **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 + * **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 + * **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 + * **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-okhttp **Version:** 1.22.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-protobuf **Version:** 1.22.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-protobuf-lite **Version:** 1.22.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-stub **Version:** 1.22.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:** protoc-gen-grpc-java **Version:** 1.22.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.opencensus **Name:** opencensus-api **Version:** 0.23.0 + * **POM Project URL:** [https://github.com/census-instrumentation/opencensus-java](https://github.com/census-instrumentation/opencensus-java) + * **POM License: The Apache 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.opencensus **Name:** opencensus-contrib-grpc-metrics **Version:** 0.21.0 + * **POM Project URL:** [https://github.com/census-instrumentation/opencensus-java](https://github.com/census-instrumentation/opencensus-java) + * **POM License: The Apache 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.opencensus **Name:** opencensus-contrib-http-util **Version:** 0.21.0 + * **POM Project URL:** [https://github.com/census-instrumentation/opencensus-java](https://github.com/census-instrumentation/opencensus-java) + * **POM License: The Apache 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.perfmark **Name:** perfmark-api **Version:** 0.17.0 + * **POM Project URL:** [https://github.com/perfmark/perfmark](https://github.com/perfmark/perfmark) + * **POM License: Apache 2.0** - [https://opensource.org/licenses/Apache-2.0](https://opensource.org/licenses/Apache-2.0) + +1. **Group:** javax.annotation **Name:** javax.annotation-api **Version:** 1.3.2 + * **Manifest Project URL:** [https://javaee.github.io/glassfish](https://javaee.github.io/glassfish) + * **Manifest license URL:** [https://github.com/javaee/javax.annotation/blob/master/LICENSE](https://github.com/javaee/javax.annotation/blob/master/LICENSE) + * **POM Project URL:** [http://jcp.org/en/jsr/detail?id=250](http://jcp.org/en/jsr/detail?id=250) + * **POM License: CDDL + GPLv2 with classpath exception** - [https://github.com/javaee/javax.annotation/blob/master/LICENSE](https://github.com/javaee/javax.annotation/blob/master/LICENSE) + +1. **Group:** javax.annotation **Name:** jsr250-api **Version:** 1.0 + * **POM Project URL:** [http://jcp.org/aboutJava/communityprocess/final/jsr250/index.html](http://jcp.org/aboutJava/communityprocess/final/jsr250/index.html) + * **POM License: COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0** - [https://glassfish.dev.java.net/public/CDDLv1.0.html](https://glassfish.dev.java.net/public/CDDLv1.0.html) + +1. **Group:** javax.enterprise **Name:** cdi-api **Version:** 1.0 + * **POM License: Apache License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) + +1. **Group:** javax.inject **Name:** javax.inject **Version:** 1 + * **POM Project URL:** [http://code.google.com/p/atinject/](http://code.google.com/p/atinject/) + * **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:** junit **Name:** junit **Version:** 4.12 + * **POM Project URL:** [http://junit.org](http://junit.org) + * **POM License: Eclipse Public License 1.0** - [http://www.eclipse.org/legal/epl-v10.html](http://www.eclipse.org/legal/epl-v10.html) + +1. **Group:** kr.motd.maven **Name:** os-maven-plugin **Version:** 1.4.0.Final + * **POM Project URL:** [https://github.com/trustin/os-maven-plugin/](https://github.com/trustin/os-maven-plugin/) + * **POM License: Apache License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) + +1. **Group:** net.java.dev.javacc **Name:** javacc **Version:** 5.0 + * **POM Project URL:** [https://javacc.dev.java.net/](https://javacc.dev.java.net/) + * **POM License: Berkeley Software Distribution (BSD) License** - [http://www.opensource.org/licenses/bsd-license.html](http://www.opensource.org/licenses/bsd-license.html) + +1. **Group:** net.sourceforge.pmd **Name:** pmd-core **Version:** 6.16.0 + * **POM License: BSD-style** - [http://pmd.sourceforge.net/license.html](http://pmd.sourceforge.net/license.html) + +1. **Group:** net.sourceforge.pmd **Name:** pmd-java **Version:** 6.16.0 + * **POM License: BSD-style** - [http://pmd.sourceforge.net/license.html](http://pmd.sourceforge.net/license.html) + +1. **Group:** net.sourceforge.saxon **Name:** saxon **Version:** 9.1.0.8 + * **POM Project URL:** [http://saxon.sourceforge.net/](http://saxon.sourceforge.net/) + * **POM License: Mozilla Public License Version 1.0** - [http://www.mozilla.org/MPL/MPL-1.0.txt](http://www.mozilla.org/MPL/MPL-1.0.txt) + +1. **Group:** org.antlr **Name:** antlr4-runtime **Version:** 4.7 + * **Manifest Project URL:** [http://www.antlr.org](http://www.antlr.org) + * **Manifest license URL:** [http://www.antlr.org/license.html](http://www.antlr.org/license.html) + * **POM License: The BSD License** - [http://www.antlr.org/license.html](http://www.antlr.org/license.html) + +1. **Group:** org.apache.commons **Name:** commons-lang3 **Version:** 3.8.1 + * **Project URL:** [http://commons.apache.org/proper/commons-lang/](http://commons.apache.org/proper/commons-lang/) + * **Manifest license URL:** [https://www.apache.org/licenses/LICENSE-2.0.txt](https://www.apache.org/licenses/LICENSE-2.0.txt) + * **POM License: Apache License, Version 2.0** - [https://www.apache.org/licenses/LICENSE-2.0.txt](https://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group:** org.apache.httpcomponents **Name:** httpclient **Version:** 4.5.9 + * **POM Project URL:** [http://hc.apache.org/httpcomponents-client](http://hc.apache.org/httpcomponents-client) + * **POM License: Apache License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group:** org.apache.httpcomponents **Name:** httpcore **Version:** 4.4.11 + * **POM Project URL:** [http://hc.apache.org/httpcomponents-core-ga](http://hc.apache.org/httpcomponents-core-ga) + * **POM License: Apache License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group:** org.apache.maven **Name:** maven-artifact **Version:** 3.2.1 + * **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:** org.apache.maven **Name:** maven-model **Version:** 3.2.1 + * **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:** org.apache.maven **Name:** maven-plugin-api **Version:** 3.2.1 + * **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:** org.apiguardian **Name:** apiguardian-api **Version:** 1.1.0 + * **POM Project URL:** [https://github.com/apiguardian-team/apiguardian](https://github.com/apiguardian-team/apiguardian) + * **POM License: The Apache License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group:** org.checkerframework **Name:** checker-compat-qual **Version:** 2.5.5 + * **POM Project URL:** [https://checkerframework.org](https://checkerframework.org) + * **POM License: GNU General Public License, version 2 (GPL2), with the classpath exception** - [http://www.gnu.org/software/classpath/license.html](http://www.gnu.org/software/classpath/license.html) + * **POM License: The MIT License** - [http://opensource.org/licenses/MIT](http://opensource.org/licenses/MIT) + +1. **Group:** org.checkerframework **Name:** checker-qual **Version:** 2.8.1 + * **POM Project URL:** [https://checkerframework.org](https://checkerframework.org) + * **POM License: The MIT License** - [http://opensource.org/licenses/MIT](http://opensource.org/licenses/MIT) + +1. **Group:** org.checkerframework **Name:** checker-qual **Version:** 2.9.0 + * **POM Project URL:** [https://checkerframework.org](https://checkerframework.org) + * **POM License: The MIT License** - [http://opensource.org/licenses/MIT](http://opensource.org/licenses/MIT) + +1. **Group:** org.checkerframework **Name:** dataflow **Version:** 2.5.3 + * **POM Project URL:** [https://checkerframework.org](https://checkerframework.org) + * **POM License: GNU General Public License, version 2 (GPL2), with the classpath exception** - [http://www.gnu.org/software/classpath/license.html](http://www.gnu.org/software/classpath/license.html) + * **POM License: The MIT License** - [http://opensource.org/licenses/MIT](http://opensource.org/licenses/MIT) + +1. **Group:** org.checkerframework **Name:** javacutil **Version:** 2.5.3 + * **POM Project URL:** [https://checkerframework.org](https://checkerframework.org) + * **POM License: GNU General Public License, version 2 (GPL2), with the classpath exception** - [http://www.gnu.org/software/classpath/license.html](http://www.gnu.org/software/classpath/license.html) + * **POM License: The MIT License** - [http://opensource.org/licenses/MIT](http://opensource.org/licenses/MIT) + +1. **Group:** org.codehaus.jackson **Name:** jackson-core-asl **Version:** 1.9.11 + * **Manifest license URL:** [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + * **POM Project URL:** [http://jackson.codehaus.org](http://jackson.codehaus.org) + * **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:** org.codehaus.mojo **Name:** animal-sniffer-annotations **Version:** 1.18 + * **POM License: MIT license** - [http://www.opensource.org/licenses/mit-license.php](http://www.opensource.org/licenses/mit-license.php) + * **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:** org.codehaus.plexus **Name:** plexus-classworlds **Version:** 2.4 + * **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:** org.codehaus.plexus **Name:** plexus-component-annotations **Version:** 1.5.5 + * **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:** org.codehaus.plexus **Name:** plexus-utils **Version:** 3.0.17 + * **POM Project URL:** [http://plexus.codehaus.org/plexus-utils](http://plexus.codehaus.org/plexus-utils) + * **POM License: Apache License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) + * **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:** org.eclipse.sisu **Name:** org.eclipse.sisu.inject **Version:** 0.0.0.M5 + * **Manifest Project URL:** [http://www.eclipse.org/sisu/](http://www.eclipse.org/sisu/) + * **Manifest license URL:** [http://www.eclipse.org/legal/epl-v10.html](http://www.eclipse.org/legal/epl-v10.html) + * **POM License: Eclipse Public License, Version 1.0** - [http://www.eclipse.org/legal/epl-v10.html](http://www.eclipse.org/legal/epl-v10.html) + +1. **Group:** org.eclipse.sisu **Name:** org.eclipse.sisu.plexus **Version:** 0.0.0.M5 + * **Manifest Project URL:** [http://www.eclipse.org/sisu/](http://www.eclipse.org/sisu/) + * **Manifest license URL:** [http://www.eclipse.org/legal/epl-v10.html](http://www.eclipse.org/legal/epl-v10.html) + * **POM License: Eclipse Public License, Version 1.0** - [http://www.eclipse.org/legal/epl-v10.html](http://www.eclipse.org/legal/epl-v10.html) + +1. **Group:** org.hamcrest **Name:** hamcrest-all **Version:** 1.3 + * **POM License: New BSD License** - [http://www.opensource.org/licenses/bsd-license.php](http://www.opensource.org/licenses/bsd-license.php) + +1. **Group:** org.hamcrest **Name:** hamcrest-core **Version:** 1.3 + * **POM License: New BSD License** - [http://www.opensource.org/licenses/bsd-license.php](http://www.opensource.org/licenses/bsd-license.php) + +1. **Group:** org.jacoco **Name:** org.jacoco.agent **Version:** 0.8.4 + * **Manifest license URL:** [http://www.eclipse.org/legal/epl-v10.html](http://www.eclipse.org/legal/epl-v10.html) + * **POM License: Eclipse Public License v1.0** - [http://www.eclipse.org/legal/epl-v10.html](http://www.eclipse.org/legal/epl-v10.html) + +1. **Group:** org.jacoco **Name:** org.jacoco.ant **Version:** 0.8.4 + * **Manifest license URL:** [http://www.eclipse.org/legal/epl-v10.html](http://www.eclipse.org/legal/epl-v10.html) + * **POM License: Eclipse Public License v1.0** - [http://www.eclipse.org/legal/epl-v10.html](http://www.eclipse.org/legal/epl-v10.html) + +1. **Group:** org.jacoco **Name:** org.jacoco.core **Version:** 0.8.4 + * **Manifest license URL:** [http://www.eclipse.org/legal/epl-v10.html](http://www.eclipse.org/legal/epl-v10.html) + * **POM License: Eclipse Public License v1.0** - [http://www.eclipse.org/legal/epl-v10.html](http://www.eclipse.org/legal/epl-v10.html) + +1. **Group:** org.jacoco **Name:** org.jacoco.report **Version:** 0.8.4 + * **Manifest license URL:** [http://www.eclipse.org/legal/epl-v10.html](http://www.eclipse.org/legal/epl-v10.html) + * **POM License: Eclipse Public License v1.0** - [http://www.eclipse.org/legal/epl-v10.html](http://www.eclipse.org/legal/epl-v10.html) + +1. **Group:** org.junit.jupiter **Name:** junit-jupiter-api **Version:** 5.5.1 + * **POM Project URL:** [https://junit.org/junit5/](https://junit.org/junit5/) + * **POM License: Eclipse Public License v2.0** - [https://www.eclipse.org/legal/epl-v20.html](https://www.eclipse.org/legal/epl-v20.html) + +1. **Group:** org.junit.jupiter **Name:** junit-jupiter-engine **Version:** 5.5.1 + * **POM Project URL:** [https://junit.org/junit5/](https://junit.org/junit5/) + * **POM License: Eclipse Public License v2.0** - [https://www.eclipse.org/legal/epl-v20.html](https://www.eclipse.org/legal/epl-v20.html) + +1. **Group:** org.junit.jupiter **Name:** junit-jupiter-params **Version:** 5.5.1 + * **POM Project URL:** [https://junit.org/junit5/](https://junit.org/junit5/) + * **POM License: Eclipse Public License v2.0** - [https://www.eclipse.org/legal/epl-v20.html](https://www.eclipse.org/legal/epl-v20.html) + +1. **Group:** org.junit.platform **Name:** junit-platform-commons **Version:** 1.5.1 + * **POM Project URL:** [https://junit.org/junit5/](https://junit.org/junit5/) + * **POM License: Eclipse Public License v2.0** - [https://www.eclipse.org/legal/epl-v20.html](https://www.eclipse.org/legal/epl-v20.html) + +1. **Group:** org.junit.platform **Name:** junit-platform-engine **Version:** 1.5.1 + * **POM Project URL:** [https://junit.org/junit5/](https://junit.org/junit5/) + * **POM License: Eclipse Public License v2.0** - [https://www.eclipse.org/legal/epl-v20.html](https://www.eclipse.org/legal/epl-v20.html) + +1. **Group:** org.opentest4j **Name:** opentest4j **Version:** 1.2.0 + * **Manifest License:** The Apache License, Version 2.0 (Not packaged) + * **POM Project URL:** [https://github.com/ota4j-team/opentest4j](https://github.com/ota4j-team/opentest4j) + * **POM License: The Apache License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) + +1. **Group:** org.ow2.asm **Name:** asm **Version:** 7.1 + * **Manifest Project URL:** [http://asm.ow2.org](http://asm.ow2.org) + * **POM Project URL:** [http://asm.ow2.org/](http://asm.ow2.org/) + * **POM License: BSD** - [http://asm.ow2.org/license.html](http://asm.ow2.org/license.html) + * **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:** org.ow2.asm **Name:** asm-analysis **Version:** 7.1 + * **Manifest Project URL:** [http://asm.ow2.org](http://asm.ow2.org) + * **POM Project URL:** [http://asm.ow2.org/](http://asm.ow2.org/) + * **POM License: BSD** - [http://asm.ow2.org/license.html](http://asm.ow2.org/license.html) + * **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:** org.ow2.asm **Name:** asm-commons **Version:** 7.1 + * **Manifest Project URL:** [http://asm.ow2.org](http://asm.ow2.org) + * **POM Project URL:** [http://asm.ow2.org/](http://asm.ow2.org/) + * **POM License: BSD** - [http://asm.ow2.org/license.html](http://asm.ow2.org/license.html) + * **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:** org.ow2.asm **Name:** asm-tree **Version:** 7.1 + * **Manifest Project URL:** [http://asm.ow2.org](http://asm.ow2.org) + * **POM Project URL:** [http://asm.ow2.org/](http://asm.ow2.org/) + * **POM License: BSD** - [http://asm.ow2.org/license.html](http://asm.ow2.org/license.html) + * **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:** org.pcollections **Name:** pcollections **Version:** 2.1.2 + * **POM Project URL:** [http://pcollections.org](http://pcollections.org) + * **POM License: The MIT License** - [http://www.opensource.org/licenses/mit-license.php](http://www.opensource.org/licenses/mit-license.php) + +1. **Group:** org.sonatype.sisu **Name:** sisu-guice **Version:** 3.1.0 + * **Manifest Project URL:** [http://code.google.com/p/google-guice/](http://code.google.com/p/google-guice/) + * **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:** org.threeten **Name:** threetenbp **Version:** 1.3.3 + * **Manifest Project URL:** [http://www.threeten.org](http://www.threeten.org) + * **Manifest license URL:** [https://raw.githubusercontent.com/ThreeTen/threetenbp/master/LICENSE.txt](https://raw.githubusercontent.com/ThreeTen/threetenbp/master/LICENSE.txt) + * **POM Project URL:** [https://www.threeten.org/threetenbp](https://www.threeten.org/threetenbp) + * **POM License: BSD 3-clause** - [https://raw.githubusercontent.com/ThreeTen/threetenbp/master/LICENSE.txt](https://raw.githubusercontent.com/ThreeTen/threetenbp/master/LICENSE.txt) + + + + 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 diff --git a/pom.xml b/pom.xml index ca0d06f82..d1d3883cc 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.2 +1.1.3-SNAPSHOT+1 2015 @@ -114,12 +114,12 @@ all modules and does not describe the project structure per-subproject. io.spine.tools spine-errorprone-checks - 1.1.2 + 1.1.3-SNAPSHOT+1 io.spine.tools spine-protoc-plugin - 1.1.2 + 1.1.3-SNAPSHOT+1 net.sourceforge.pmd diff --git a/scripts/start-datastore.bat b/scripts/start-datastore.bat index 2d3890a00..f4bf0957f 100644 --- a/scripts/start-datastore.bat +++ b/scripts/start-datastore.bat @@ -1 +1 @@ -gcloud beta emulators datastore start --project=spine-dev --host-port=localhost:8080 --consistency 1.0 --no-store-on-disk +gcloud beta emulators datastore start --project=test-project --consistency 1.0 --no-store-on-disk diff --git a/scripts/start-datastore.sh b/scripts/start-datastore.sh index 2d3890a00..f4bf0957f 100755 --- a/scripts/start-datastore.sh +++ b/scripts/start-datastore.sh @@ -1 +1 @@ -gcloud beta emulators datastore start --project=spine-dev --host-port=localhost:8080 --consistency 1.0 --no-store-on-disk +gcloud beta emulators datastore start --project=test-project --consistency 1.0 --no-store-on-disk diff --git a/settings.gradle b/settings.gradle index 99fcd5b56..1bdb8a9c4 100644 --- a/settings.gradle +++ b/settings.gradle @@ -22,3 +22,4 @@ rootProject.name = 'spine-gcloud-java' include 'datastore' include 'stackdriver-trace' +include 'testutil-gcloud' diff --git a/testutil-gcloud/build.gradle b/testutil-gcloud/build.gradle new file mode 100644 index 000000000..a4e28bf13 --- /dev/null +++ b/testutil-gcloud/build.gradle @@ -0,0 +1,24 @@ +/* + * 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. + */ + +dependencies { + implementation project(path: ':datastore') + implementation deps.test.junit5Api +} diff --git a/testutil-gcloud/src/main/java/io/spine/testing/server/storage/datastore/SpyStorageFactory.java b/testutil-gcloud/src/main/java/io/spine/testing/server/storage/datastore/SpyStorageFactory.java new file mode 100644 index 000000000..0d6b13145 --- /dev/null +++ b/testutil-gcloud/src/main/java/io/spine/testing/server/storage/datastore/SpyStorageFactory.java @@ -0,0 +1,68 @@ +/* + * 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.testing.server.storage.datastore; + +import com.google.cloud.datastore.Datastore; +import com.google.common.annotations.VisibleForTesting; +import io.spine.server.storage.datastore.DatastoreWrapper; +import org.checkerframework.checker.nullness.qual.Nullable; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * A {@link TestDatastoreStorageFactory} which allows to inject a custom {@link DatastoreWrapper}. + */ +public final class SpyStorageFactory extends TestDatastoreStorageFactory { + + private static @Nullable DatastoreWrapper injectedWrapper = null; + + /** + * Injects a given {@code DatastoreWrapper} into the storage factory. + * + *

All storages created by this factory will operate based on the given wrapper. + * + *

Should be called before the {@code SpyStorageFactory} instance is created. + */ + public static void injectWrapper(DatastoreWrapper wrapper) { + checkNotNull(wrapper); + injectedWrapper = wrapper; + } + + public SpyStorageFactory() { + super(checkNotNull(injectedWrapper).datastore()); + } + + @Override + protected DatastoreWrapper createDatastoreWrapper(boolean multitenant) { + return injectedWrapper; + } + + @VisibleForTesting + static void clearInjectedWrapper() { + injectedWrapper = null; + } + + @VisibleForTesting + @Override + protected Datastore datastore() { + return super.datastore(); + } +} diff --git a/datastore/src/test/java/io/spine/server/storage/datastore/TestDatastoreStorageFactory.java b/testutil-gcloud/src/main/java/io/spine/testing/server/storage/datastore/TestDatastoreStorageFactory.java similarity index 63% rename from datastore/src/test/java/io/spine/server/storage/datastore/TestDatastoreStorageFactory.java rename to testutil-gcloud/src/main/java/io/spine/testing/server/storage/datastore/TestDatastoreStorageFactory.java index 7aab653cc..6799efca1 100644 --- a/datastore/src/test/java/io/spine/server/storage/datastore/TestDatastoreStorageFactory.java +++ b/testutil-gcloud/src/main/java/io/spine/testing/server/storage/datastore/TestDatastoreStorageFactory.java @@ -18,49 +18,32 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.server.storage.datastore; +package io.spine.testing.server.storage.datastore; import com.google.cloud.datastore.Datastore; -import com.google.cloud.datastore.DatastoreOptions; +import com.google.common.collect.ImmutableSet; import com.google.common.flogger.FluentLogger; import io.spine.annotation.Internal; -import io.spine.server.storage.datastore.given.TestDatastores; +import io.spine.server.storage.datastore.DatastoreStorageFactory; +import io.spine.server.storage.datastore.DatastoreWrapper; import io.spine.server.storage.datastore.type.DatastoreTypeRegistryFactory; -import org.checkerframework.checker.nullness.qual.MonotonicNonNull; + +import java.util.Collection; +import java.util.HashSet; + +import static com.google.common.base.Preconditions.checkNotNull; /** - * Creates storages based on the local Google {@link Datastore}. + * A test implementation of the {@link DatastoreStorageFactory}. + * + *

Wraps the datastore with an instance of {@link TestDatastoreWrapper} and provides additional + * clean up {@linkplain #tearDown() methods}. */ public class TestDatastoreStorageFactory extends DatastoreStorageFactory { private static final FluentLogger logger = FluentLogger.forEnclosingClass(); - private static @MonotonicNonNull TestDatastoreStorageFactory instance = null; - /** - * Returns a default factory instance. A {@link Datastore} is created with - * default {@link DatastoreOptions}: - * - *

Dataset name: {@code spine-dev} - * - *

Connects to a localhost Datastore emulator. - */ - public static synchronized TestDatastoreStorageFactory defaultInstance() { - try { - if (instance == null) { - instance = createInstance(); - } - return instance; - } catch (Throwable e) { - logger.atSevere() - .withCause(e) - .log("Failed to initialize local datastore factory."); - throw new IllegalStateException(e); - } - } - - private static TestDatastoreStorageFactory createInstance() { - return new TestDatastoreStorageFactory(TestDatastores.local()); - } + private final Collection allCreatedWrappers = new HashSet<>(); protected TestDatastoreStorageFactory(Datastore datastore) { super(DatastoreStorageFactory @@ -70,20 +53,43 @@ protected TestDatastoreStorageFactory(Datastore datastore) { ); } + /** + * Creates a new instance which works with a local Datastore emulator. + * + *

A shortcut for {@code basedOn(TestDatastores.local())}. + */ + public static TestDatastoreStorageFactory local() { + return basedOn(TestDatastores.local()); + } + + /** + * Creates a new factory instance which wraps the given Datastore. + */ + public static TestDatastoreStorageFactory basedOn(Datastore datastore) { + checkNotNull(datastore); + return new TestDatastoreStorageFactory(datastore); + } + @Internal @Override protected DatastoreWrapper createDatastoreWrapper(boolean multitenant) { - return TestDatastoreWrapper.wrap(datastore(), false); + TestDatastoreWrapper wrapper = TestDatastoreWrapper.wrap(datastore(), false); + allCreatedWrappers.add(wrapper); + return wrapper; + } + + @Override + protected Iterable wrappers() { + return ImmutableSet.copyOf(allCreatedWrappers); } /** * Performs operations on setting up the local datastore. * - *

General usage is testing. - *

By default is a NoOp, but can be overridden. + *

By default is a NO-OP, but can be overridden. */ - @SuppressWarnings("EmptyMethod") public void setUp() { + // NO-OP. See doc. } /** @@ -93,14 +99,14 @@ public void setUp() { * *

NOTE: does not stop the server but just deletes all records. * - *

Equivalent to dropping all tables in an SQL-base storage. + *

Equivalent to dropping all tables in an SQL-based storage. */ public void tearDown() { clear(); } /** - * Clears all data in the local Datastore. + * Clears all data in the Datastore. * * @see #tearDown() */ diff --git a/datastore/src/test/java/io/spine/server/storage/datastore/TestDatastoreWrapper.java b/testutil-gcloud/src/main/java/io/spine/testing/server/storage/datastore/TestDatastoreWrapper.java similarity index 72% rename from datastore/src/test/java/io/spine/server/storage/datastore/TestDatastoreWrapper.java rename to testutil-gcloud/src/main/java/io/spine/testing/server/storage/datastore/TestDatastoreWrapper.java index 48e8f09f4..49b840334 100644 --- a/datastore/src/test/java/io/spine/server/storage/datastore/TestDatastoreWrapper.java +++ b/testutil-gcloud/src/main/java/io/spine/testing/server/storage/datastore/TestDatastoreWrapper.java @@ -18,7 +18,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.server.storage.datastore; +package io.spine.testing.server.storage.datastore; import com.google.cloud.datastore.Datastore; import com.google.cloud.datastore.DatastoreException; @@ -26,13 +26,18 @@ import com.google.cloud.datastore.KeyFactory; import com.google.cloud.datastore.Query; import com.google.cloud.datastore.StructuredQuery; -import io.spine.server.storage.datastore.tenant.TestNamespaceSuppliers; +import com.google.common.annotations.VisibleForTesting; +import io.spine.server.storage.datastore.DatastoreWrapper; +import io.spine.server.storage.datastore.Kind; +import io.spine.server.storage.datastore.tenant.NamespaceSupplier; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.Lists.newArrayList; +import static io.spine.util.Exceptions.newIllegalStateException; /** * Custom extension of the {@link DatastoreWrapper} for the integration testing. @@ -41,17 +46,20 @@ */ public class TestDatastoreWrapper extends DatastoreWrapper { - // Default time to wait before each read operation to ensure the data is consistent. - // NOTE: enabled only if {@link #shouldWaitForConsistency} is {@code true}. + /** + * Default time to wait before each read operation to ensure the data is consistent. + * + *

NOTE: enabled only if {@link #waitForConsistency} is {@code true}. + */ private static final int CONSISTENCY_AWAIT_TIME_MS = 10; private static final int CONSISTENCY_AWAIT_ITERATIONS = 20; /** - * Due to eventual consistency, {@link #dropTable(String) is performed iteratively until + * Due to eventual consistency, {@linkplain #dropTable(String) is performed iteratively until * the table has no records}. * - * This constant represents the maximum number of cleanup attempts before the execution - * is continued + *

This constant represents the maximum number of cleanup attempts before the execution + * is continued. */ private static final int MAX_CLEANUP_ATTEMPTS = 5; @@ -60,17 +68,27 @@ public class TestDatastoreWrapper extends DatastoreWrapper { private final boolean waitForConsistency; protected TestDatastoreWrapper(Datastore datastore, boolean waitForConsistency) { - super(datastore, TestNamespaceSuppliers.singleTenant()); + super(datastore, NamespaceSupplier.singleTenant()); this.waitForConsistency = waitForConsistency; } + /** + * Wraps a given Datastore. + * + *

The {@code waitForConsistency} parameter allows to add a delay to each write operation to + * compensate for the eventual consistency of the storage. + * + *

The {@code waitForConsistency} parameter should usually be set to {@code false} when + * working with a local Datastore emulator. + */ public static TestDatastoreWrapper wrap(Datastore datastore, boolean waitForConsistency) { + checkNotNull(datastore); return new TestDatastoreWrapper(datastore, waitForConsistency); } @Override public KeyFactory keyFactory(Kind kind) { - kindsCache.add(kind.getValue()); + kindsCache.add(kind.value()); return super.keyFactory(kind); } @@ -93,7 +111,7 @@ public void update(Entity entity) throws DatastoreException { } @Override - void dropTable(String table) { + protected void dropTable(String table) { if (!waitForConsistency) { super.dropTable(table); } else { @@ -101,7 +119,7 @@ void dropTable(String table) { } } - @SuppressWarnings("BusyWait") // allow Datastore some time between cleanup attempts. + @SuppressWarnings("BusyWait") // allows Datastore some time between cleanup attempts. private void dropTableConsistently(String table) { Integer remainingEntityCount = null; int cleanupAttempts = 0; @@ -115,7 +133,7 @@ private void dropTableConsistently(String table) { try { Thread.sleep(CONSISTENCY_AWAIT_TIME_MS); } catch (InterruptedException e) { - throw new RuntimeException(e); + throw new IllegalStateException(e); } } @@ -131,14 +149,13 @@ private void dropTableConsistently(String table) { } } - if (cleanupAttempts >= MAX_CLEANUP_ATTEMPTS && remainingEntityCount > 0) { - throw new RuntimeException("Cannot cleanup the table: " + table + - ". Remaining entity count is " + - remainingEntityCount); + if (cleanupAttempts >= MAX_CLEANUP_ATTEMPTS) { + throw newIllegalStateException( + "Cannot cleanup the table: %s. Remaining entity count is %d", + table, remainingEntityCount); } } - @SuppressWarnings("BusyWait") // allow Datastore to become consistent before reading. private void waitForConsistency() { if (!waitForConsistency) { _debug().log("Wait for consistency is not required."); @@ -146,11 +163,17 @@ private void waitForConsistency() { } _debug().log("Waiting for data consistency to establish."); + doWaitForConsistency(); + } + + @SuppressWarnings("BusyWait") // allow Datastore to become consistent before reading. + @VisibleForTesting + protected void doWaitForConsistency() { for (int awaitCycle = 0; awaitCycle < CONSISTENCY_AWAIT_ITERATIONS; awaitCycle++) { try { Thread.sleep(CONSISTENCY_AWAIT_TIME_MS); } catch (InterruptedException e) { - throw new RuntimeException(e); + throw new IllegalStateException(e); } } } diff --git a/testutil-gcloud/src/main/java/io/spine/testing/server/storage/datastore/TestDatastores.java b/testutil-gcloud/src/main/java/io/spine/testing/server/storage/datastore/TestDatastores.java new file mode 100644 index 000000000..8b6d8e340 --- /dev/null +++ b/testutil-gcloud/src/main/java/io/spine/testing/server/storage/datastore/TestDatastores.java @@ -0,0 +1,152 @@ +/* + * 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.testing.server.storage.datastore; + +import com.google.auth.Credentials; +import com.google.auth.oauth2.ServiceAccountCredentials; +import com.google.cloud.NoCredentials; +import com.google.cloud.datastore.Datastore; +import com.google.cloud.datastore.DatastoreOptions; +import com.google.common.annotations.VisibleForTesting; +import io.spine.io.Resource; +import io.spine.logging.Logging; +import io.spine.server.storage.datastore.ProjectId; + +import java.io.IOException; +import java.io.InputStream; + +import static com.google.auth.oauth2.ServiceAccountCredentials.fromStream; +import static com.google.common.base.Preconditions.checkNotNull; +import static io.spine.io.Resource.file; +import static io.spine.util.Exceptions.newIllegalStateException; +import static java.lang.String.format; + +/** + * A factory of test {@link Datastore} instances. + */ +public final class TestDatastores implements Logging { + + /** + * The default port to which the local Datastore emulator is bound. + * + *

See + * {@code gcloud} docs. + */ + @VisibleForTesting + static final int DEFAULT_EMULATOR_PORT = 8081; + private static final String LOCALHOST = "localhost"; + + /** + * The default project ID to use when running on a local Datastore emulator. + */ + private static final ProjectId DEFAULT_LOCAL_PROJECT_ID = ProjectId.of("test-project"); + + /** Prevents instantiation of this utility class. */ + private TestDatastores() { + } + + /** + * Creates a {@link Datastore} connected to the local Datastore emulator at + * {@link #DEFAULT_EMULATOR_PORT}. + * + *

The {@linkplain #DEFAULT_LOCAL_PROJECT_ID default project ID} will be used. For most + * tests, it's okay to use this ID even if some other project ID was passed to the emulator via + * the {@code --project} switch. + * + *

If, for some reason, you need to specify a custom project ID, please use + * {@link #local(ProjectId, int)}. + */ + public static Datastore local() { + return local(DEFAULT_EMULATOR_PORT); + } + + /** + * Creates a {@link Datastore} connected to the local Datastore emulator at the specified port. + * + *

The {@linkplain #DEFAULT_LOCAL_PROJECT_ID default project ID} will be used. For most + * tests, it's okay to use this ID even if some other project ID was passed to the emulator via + * the {@code --project} switch. + * + *

If, for some reason, you need to specify a custom project ID, please use + * {@link #local(ProjectId, int)}. + */ + public static Datastore local(int port) { + return local(DEFAULT_LOCAL_PROJECT_ID, port); + } + + /** + * Creates a {@link Datastore} connected to the local Datastore emulator at the specified port + * which runs with the specified project ID. + */ + public static Datastore local(ProjectId projectId, int port) { + String address = format("%s:%d", LOCALHOST, port); + DatastoreOptions options = DatastoreOptions + .newBuilder() + .setProjectId(projectId.value()) + .setHost(address) + .setCredentials(NoCredentials.getInstance()) + .build(); + Datastore datastore = options.getService(); + return datastore; + } + + /** + * Creates a {@link Datastore} connected to the remote Google Cloud Datastore described by the + * given service account resource. + * + *

The {@code serviceAccountPath} is a path to the resource file, specified relative to the + * classpath. + */ + public static Datastore remote(String serviceAccountPath) { + checkNotNull(serviceAccountPath); + return remote(file(serviceAccountPath)); + } + + /** + * Creates a {@link Datastore} connected to the remote Google Cloud Datastore described by the + * given service account resource. + */ + public static Datastore remote(Resource serviceAccount) { + checkNotNull(serviceAccount); + try { + Credentials credentials = credentialsFrom(serviceAccount); + DatastoreOptions options = DatastoreOptions + .newBuilder() + .setCredentials(credentials) + .build(); + Datastore datastore = options.getService(); + return datastore; + } catch (IOException e) { + throw newIllegalStateException( + e, "Problems parsing the credentials file `%s`.", serviceAccount); + } + } + + private static Credentials credentialsFrom(Resource serviceAccount) throws IOException { + InputStream is = serviceAccount.open(); + ServiceAccountCredentials credentials = fromStream(is); + return credentials; + } + + public static ProjectId defaultLocalProjectId() { + return DEFAULT_LOCAL_PROJECT_ID; + } +} diff --git a/datastore/src/test/java/io/spine/server/storage/datastore/SpyStorageFactory.java b/testutil-gcloud/src/main/java/io/spine/testing/server/storage/datastore/package-info.java similarity index 57% rename from datastore/src/test/java/io/spine/server/storage/datastore/SpyStorageFactory.java rename to testutil-gcloud/src/main/java/io/spine/testing/server/storage/datastore/package-info.java index 3a5fed069..7f61b24ca 100644 --- a/datastore/src/test/java/io/spine/server/storage/datastore/SpyStorageFactory.java +++ b/testutil-gcloud/src/main/java/io/spine/testing/server/storage/datastore/package-info.java @@ -18,31 +18,15 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.server.storage.datastore; - -import io.spine.annotation.Internal; - /** - * A {@link TestDatastoreStorageFactory} which allows to inject a custom {@link DatastoreWrapper}. - * - *

This class is not moved to the test environment because it uses the package-private method of - * {@link DatastoreWrapper}. + * This package contains the testing utils for the Google Cloud Datastore-based storage + * implementation. */ -final class SpyStorageFactory extends TestDatastoreStorageFactory { - - private static DatastoreWrapper injectedWrapper = null; - static void injectWrapper(DatastoreWrapper wrapper) { - injectedWrapper = wrapper; - } +@CheckReturnValue +@ParametersAreNonnullByDefault +package io.spine.testing.server.storage.datastore; - SpyStorageFactory() { - super(injectedWrapper.datastore()); - } +import com.google.errorprone.annotations.CheckReturnValue; - @Internal - @Override - protected DatastoreWrapper createDatastoreWrapper(boolean multitenant) { - return injectedWrapper; - } -} +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/testutil-gcloud/src/test/java/io/spine/testing/server/storage/datastore/SpyStorageFactoryTest.java b/testutil-gcloud/src/test/java/io/spine/testing/server/storage/datastore/SpyStorageFactoryTest.java new file mode 100644 index 000000000..0ee50f387 --- /dev/null +++ b/testutil-gcloud/src/test/java/io/spine/testing/server/storage/datastore/SpyStorageFactoryTest.java @@ -0,0 +1,60 @@ +/* + * 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.testing.server.storage.datastore; + +import com.google.cloud.datastore.Datastore; +import com.google.common.testing.NullPointerTester; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static com.google.common.truth.Truth.assertThat; +import static io.spine.testing.DisplayNames.NOT_ACCEPT_NULLS; +import static org.junit.jupiter.api.Assertions.assertThrows; + +@DisplayName("`SpyStorageFactory` should") +class SpyStorageFactoryTest { + + @Test + @DisplayName(NOT_ACCEPT_NULLS) + void passNullToleranceCheck() { + new NullPointerTester() + .testAllPublicStaticMethods(SpyStorageFactory.class); + } + + @Test + @DisplayName("inject a given `DatastoreWrapper`") + void injectDatastoreWrapper() { + Datastore datastore = TestDatastores.local(); + TestDatastoreWrapper wrapper = TestDatastoreWrapper.wrap(datastore, false); + SpyStorageFactory.injectWrapper(wrapper); + SpyStorageFactory factory = new SpyStorageFactory(); + Datastore datastoreFromFactory = factory.datastore(); + + assertThat(datastoreFromFactory).isSameInstanceAs(datastore); + } + + @Test + @DisplayName("throw `NPE` if being created while no wrapper was injected") + void throwWithoutWrapperInjected() { + SpyStorageFactory.clearInjectedWrapper(); + assertThrows(NullPointerException.class, SpyStorageFactory::new); + } +} diff --git a/testutil-gcloud/src/test/java/io/spine/testing/server/storage/datastore/TestDatastoreStorageFactoryTest.java b/testutil-gcloud/src/test/java/io/spine/testing/server/storage/datastore/TestDatastoreStorageFactoryTest.java new file mode 100644 index 000000000..73d27ccea --- /dev/null +++ b/testutil-gcloud/src/test/java/io/spine/testing/server/storage/datastore/TestDatastoreStorageFactoryTest.java @@ -0,0 +1,75 @@ +/* + * 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.testing.server.storage.datastore; + +import com.google.cloud.datastore.Entity; +import com.google.cloud.datastore.Key; +import com.google.common.testing.NullPointerTester; +import io.spine.server.storage.datastore.DatastoreWrapper; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static com.google.common.truth.Truth.assertThat; +import static io.spine.testing.DisplayNames.NOT_ACCEPT_NULLS; +import static io.spine.testing.server.storage.datastore.given.AnEntity.withKeyCreatedBy; + +@DisplayName("`TestDatastoreStorageFactory` should") +class TestDatastoreStorageFactoryTest { + + @Test + @DisplayName(NOT_ACCEPT_NULLS) + void passNullToleranceCheck() { + new NullPointerTester() + .testAllPublicStaticMethods(TestDatastoreStorageFactory.class); + } + + @Test + @DisplayName("wrap the specified Datastore with a `TestDatastoreWrapper`") + void wrapDatastore() { + TestDatastoreStorageFactory factory = TestDatastoreStorageFactory.local(); + DatastoreWrapper wrapper = factory.createDatastoreWrapper(false); + assertThat(wrapper).isInstanceOf(TestDatastoreWrapper.class); + } + + @Test + @DisplayName("clear all data in the Datastore") + void clearDatastore() { + // Initialize the factory. + TestDatastoreStorageFactory factory = TestDatastoreStorageFactory.local(); + DatastoreWrapper wrapper = factory.createDatastoreWrapper(false); + + // Create an entity. + Entity entity = withKeyCreatedBy(wrapper); + Key key = entity.getKey(); + wrapper.createOrUpdate(entity); + + // Make sure the entity is read from the Datastore by key. + Entity entityReadBeforeClear = wrapper.read(key); + assertThat(entityReadBeforeClear).isNotNull(); + + // Clear the Datastore. + factory.clear(); + + // Make sure entity is no longer present. + Entity entityReadAfterClear = wrapper.read(key); + assertThat(entityReadAfterClear).isNull(); + } +} diff --git a/testutil-gcloud/src/test/java/io/spine/testing/server/storage/datastore/TestDatastoreWrapperTest.java b/testutil-gcloud/src/test/java/io/spine/testing/server/storage/datastore/TestDatastoreWrapperTest.java new file mode 100644 index 000000000..eb83baba5 --- /dev/null +++ b/testutil-gcloud/src/test/java/io/spine/testing/server/storage/datastore/TestDatastoreWrapperTest.java @@ -0,0 +1,87 @@ +/* + * 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.testing.server.storage.datastore; + +import com.google.cloud.datastore.Entity; +import com.google.cloud.datastore.Key; +import com.google.common.testing.NullPointerTester; +import io.spine.testing.server.storage.datastore.given.ATestDatastoreWrapper; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static com.google.common.truth.Truth.assertThat; +import static io.spine.testing.DisplayNames.NOT_ACCEPT_NULLS; +import static io.spine.testing.server.storage.datastore.given.ATestDatastoreWrapper.wrap; +import static io.spine.testing.server.storage.datastore.given.AnEntity.withKeyCreatedBy; + +@DisplayName("`TestDatastoreWrapper` should") +class TestDatastoreWrapperTest { + + @Test + @DisplayName(NOT_ACCEPT_NULLS) + void passNullToleranceCheck() { + new NullPointerTester() + .testAllPublicStaticMethods(TestDatastoreWrapper.class); + } + + @Test + @DisplayName("wait for consistency if the parameter is specified on creation") + void waitForConsistency() { + ATestDatastoreWrapper wrapper = wrap(TestDatastores.local(), true); + Entity entity = withKeyCreatedBy(wrapper); + wrapper.createOrUpdate(entity); + + assertThat(wrapper.waitedForConsistency()).isTrue(); + } + + @Test + @DisplayName("ignore the wait for consistency if the parameter was set to `false`") + void notWaitForConsistency() { + ATestDatastoreWrapper wrapper = wrap(TestDatastores.local(), false); + Entity entity = withKeyCreatedBy(wrapper); + wrapper.createOrUpdate(entity); + + assertThat(wrapper.waitedForConsistency()).isFalse(); + } + + @Test + @DisplayName("drop all tables in the Datastore") + void dropAllTables() { + // Initialize the wrapper. + TestDatastoreWrapper wrapper = TestDatastoreWrapper.wrap(TestDatastores.local(), false); + + // Create an entity. + Entity entity = withKeyCreatedBy(wrapper); + Key key = entity.getKey(); + wrapper.createOrUpdate(entity); + + // Make sure the entity is read from the Datastore by key. + Entity entityReadBeforeClear = wrapper.read(key); + assertThat(entityReadBeforeClear).isNotNull(); + + // Drop all data. + wrapper.dropAllTables(); + + // Make sure the entity is no longer present in the Datastore. + Entity entityReadAfterClear = wrapper.read(key); + assertThat(entityReadAfterClear).isNull(); + } +} diff --git a/testutil-gcloud/src/test/java/io/spine/testing/server/storage/datastore/TestDatastoresTest.java b/testutil-gcloud/src/test/java/io/spine/testing/server/storage/datastore/TestDatastoresTest.java new file mode 100644 index 000000000..3aac0f6e4 --- /dev/null +++ b/testutil-gcloud/src/test/java/io/spine/testing/server/storage/datastore/TestDatastoresTest.java @@ -0,0 +1,122 @@ +/* + * 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.testing.server.storage.datastore; + +import com.google.cloud.datastore.Datastore; +import com.google.cloud.datastore.DatastoreOptions; +import io.spine.io.Resource; +import io.spine.server.storage.datastore.ProjectId; +import io.spine.testing.UtilityClassTest; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import static com.google.common.truth.Truth.assertThat; +import static io.spine.testing.server.storage.datastore.TestDatastores.DEFAULT_EMULATOR_PORT; +import static java.lang.String.format; +import static org.junit.jupiter.api.Assertions.assertThrows; + +@DisplayName("`TestDatastores` utility should") +class TestDatastoresTest extends UtilityClassTest { + + TestDatastoresTest() { + super(TestDatastores.class); + } + + @Nested + @DisplayName("create a `Datastore` connected to the local Datastore emulator running at") + class CreateLocalDatastore { + + private static final String ADDRESS_FORMAT = "localhost:%d"; + + @Test + @DisplayName("the default emulator address") + void atDefaultAddress() { + Datastore datastore = TestDatastores.local(); + String host = datastore.getOptions() + .getHost(); + String expectedHost = format(ADDRESS_FORMAT, DEFAULT_EMULATOR_PORT); + assertThat(host).isEqualTo(expectedHost); + } + + @Test + @DisplayName("a custom port") + void atCustomPort() { + int port = 8080; + Datastore datastore = TestDatastores.local(port); + String host = datastore.getOptions() + .getHost(); + String expectedHost = format(ADDRESS_FORMAT, port); + assertThat(host).isEqualTo(expectedHost); + } + + @Test + @DisplayName("a custom port with a custom project ID") + void atCustomPortWithCustomId() { + int port = 8080; + String id = "the-test-project"; + ProjectId projectId = ProjectId.of(id); + Datastore datastore = TestDatastores.local(projectId, port); + + DatastoreOptions options = datastore.getOptions(); + String host = options.getHost(); + String expectedHost = format(ADDRESS_FORMAT, port); + assertThat(host).isEqualTo(expectedHost); + + String actualProjectId = options.getProjectId(); + assertThat(actualProjectId).isEqualTo(id); + } + } + + @Nested + @DisplayName("create a `Datastore` connected to the remote Datastore described by") + class CreateRemoteDatastore { + + private static final String SPINE_DEV_JSON = "spine-dev.json"; + private static final String PROJECT_ID = "spine-dev"; + + @Test + @DisplayName("the service account resource at path") + void byResourceAtPath() { + Datastore datastore = TestDatastores.remote(SPINE_DEV_JSON); + String projectId = datastore.getOptions() + .getProjectId(); + assertThat(projectId).isEqualTo(PROJECT_ID); + } + + @Test + @DisplayName("the service account resource") + void byResource() { + Resource serviceAccount = Resource.file(SPINE_DEV_JSON); + Datastore datastore = TestDatastores.remote(serviceAccount); + String projectId = datastore.getOptions() + .getProjectId(); + assertThat(projectId).isEqualTo(PROJECT_ID); + } + } + + @Test + @DisplayName("throw an `ISE` when can't properly parse account credentials from resource") + void throwOnInvalidResource() { + Resource resource = Resource.file("random.json"); + assertThrows(IllegalStateException.class, () -> TestDatastores.remote(resource)); + } +} diff --git a/testutil-gcloud/src/test/java/io/spine/testing/server/storage/datastore/given/ATestDatastoreWrapper.java b/testutil-gcloud/src/test/java/io/spine/testing/server/storage/datastore/given/ATestDatastoreWrapper.java new file mode 100644 index 000000000..360f281f5 --- /dev/null +++ b/testutil-gcloud/src/test/java/io/spine/testing/server/storage/datastore/given/ATestDatastoreWrapper.java @@ -0,0 +1,47 @@ +/* + * 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.testing.server.storage.datastore.given; + +import com.google.cloud.datastore.Datastore; +import io.spine.testing.server.storage.datastore.TestDatastoreWrapper; + +public final class ATestDatastoreWrapper extends TestDatastoreWrapper { + + private boolean waitedForConsistency; + + private ATestDatastoreWrapper(Datastore datastore, boolean waitForConsistency) { + super(datastore, waitForConsistency); + } + + public static ATestDatastoreWrapper wrap(Datastore datastore, boolean waitForConsistency) { + return new ATestDatastoreWrapper(datastore, waitForConsistency); + } + + @Override + protected void doWaitForConsistency() { + super.doWaitForConsistency(); + waitedForConsistency = true; + } + + public boolean waitedForConsistency() { + return waitedForConsistency; + } +} diff --git a/testutil-gcloud/src/test/java/io/spine/testing/server/storage/datastore/given/AnEntity.java b/testutil-gcloud/src/test/java/io/spine/testing/server/storage/datastore/given/AnEntity.java new file mode 100644 index 000000000..5fce1e72c --- /dev/null +++ b/testutil-gcloud/src/test/java/io/spine/testing/server/storage/datastore/given/AnEntity.java @@ -0,0 +1,55 @@ +/* + * 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.testing.server.storage.datastore.given; + +import com.google.cloud.datastore.Entity; +import com.google.cloud.datastore.Key; +import com.google.cloud.datastore.KeyFactory; +import io.spine.server.storage.datastore.DatastoreWrapper; +import io.spine.server.storage.datastore.Kind; + +public final class AnEntity { + + private static final Kind ENTITY_KIND = Kind.of("the-entity-kind"); + + /** Prevents instantiation of this test env class. */ + private AnEntity() { + } + + public static Entity withKeyCreatedBy(DatastoreWrapper wrapper) { + Key key = keyCreatedBy(wrapper); + Entity entity = withKey(key); + return entity; + } + + private static Entity withKey(Key key) { + Entity entity = Entity.newBuilder(key) + .build(); + return entity; + } + + private static Key keyCreatedBy(DatastoreWrapper wrapper) { + KeyFactory keyFactory = wrapper.keyFactory(ENTITY_KIND); + int someId = 151; + Key key = keyFactory.newKey(someId); + return key; + } +} diff --git a/testutil-gcloud/src/test/java/io/spine/testing/server/storage/datastore/given/package-info.java b/testutil-gcloud/src/test/java/io/spine/testing/server/storage/datastore/given/package-info.java new file mode 100644 index 000000000..a5a1c50d7 --- /dev/null +++ b/testutil-gcloud/src/test/java/io/spine/testing/server/storage/datastore/given/package-info.java @@ -0,0 +1,31 @@ +/* + * 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. + */ + +/** + * This package contains the test env classes for the `testutil-gcloud` module. + */ + +@CheckReturnValue +@ParametersAreNonnullByDefault +package io.spine.testing.server.storage.datastore.given; + +import com.google.errorprone.annotations.CheckReturnValue; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/testutil-gcloud/src/test/resources/random.json b/testutil-gcloud/src/test/resources/random.json new file mode 100644 index 000000000..afe65fa61 --- /dev/null +++ b/testutil-gcloud/src/test/resources/random.json @@ -0,0 +1,3 @@ +{ + "random": "json" +} diff --git a/version.gradle b/version.gradle index faacd50cb..4f15fcc23 100644 --- a/version.gradle +++ b/version.gradle @@ -25,13 +25,13 @@ * {@code .config/gradle/dependencies.gradle}. */ -def final SPINE_VERSION = '1.1.2' +def final SPINE_VERSION = '1.1.3-SNAPSHOT+1' ext { versionToPublish = SPINE_VERSION spineBaseVersion = SPINE_VERSION - spineCoreVersion = SPINE_VERSION + spineCoreVersion = '1.1.2' datastoreVersion = '1.91.0' }