diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/datastore/snippets/DatastoreSnippets.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/datastore/snippets/DatastoreSnippets.java new file mode 100644 index 000000000000..6b1d1e0563e5 --- /dev/null +++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/datastore/snippets/DatastoreSnippets.java @@ -0,0 +1,313 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * EDITING INSTRUCTIONS + * This file is referenced in Datastore's javadoc. Any change to this file should be reflected in + * Datastore's javadoc. + */ + +package com.google.cloud.examples.datastore.snippets; + +import com.google.cloud.datastore.Batch; +import com.google.cloud.datastore.Datastore; +import com.google.cloud.datastore.Datastore.TransactionCallable; +import com.google.cloud.datastore.DatastoreReaderWriter; +import com.google.cloud.datastore.Entity; +import com.google.cloud.datastore.IncompleteKey; +import com.google.cloud.datastore.Key; +import com.google.cloud.datastore.KeyFactory; +import com.google.cloud.datastore.Query; +import com.google.cloud.datastore.QueryResults; +import com.google.cloud.datastore.StructuredQuery; +import com.google.cloud.datastore.StructuredQuery.Filter; +import com.google.cloud.datastore.StructuredQuery.PropertyFilter; +import com.google.common.collect.Lists; +import com.google.datastore.v1.PropertyFilter.Operator; +import java.util.Iterator; +import java.util.List; + +/** + * This class contains a number of snippets for the {@link Datastore} interface. + */ +public class DatastoreSnippets { + + private final Datastore datastore; + + public DatastoreSnippets(Datastore datastore) { + this.datastore = datastore; + } + + /** + * Example of running in a transaction. + */ + // [TARGET runInTransaction(TransactionCallable callable)] + // [VARIABLE "my_callable_result"] + public String runInTransaction(final String callableResult) { + // [START runInTransaction] + TransactionCallable callable = new TransactionCallable() { + @Override + public String run(DatastoreReaderWriter readerWriter) { + return callableResult; + } + }; + String result = datastore.runInTransaction(callable); + return result; + // [END runInTransaction] + } + + /** + * Example of starting a new batch. + */ + // [TARGET newBatch()] + // [VARIABLE "my_key_name_1"] + // [VARIABLE "my_key_name_2"] + public Batch newBatch(String keyName1, String keyName2) { + // [START newBatch] + Key key1 = datastore.newKeyFactory().kind("MyClass").newKey(keyName1); + Key key2 = datastore.newKeyFactory().kind("MyClass").newKey(keyName2); + Batch batch = datastore.newBatch(); + Entity entity1 = Entity.builder(key1).set("name", "John").build(); + Entity entity2 = Entity.builder(key2).set("title", "title").build(); + batch.add(entity1); + batch.add(entity2); + batch.submit(); + return batch; + // [END newBatch] + } + + /** + * Example of allocating an id + */ + // [TARGET allocateId(IncompleteKey key)] + public Key allocateIdSingle() { + // [START allocateIdSingle] + KeyFactory keyFactory = datastore.newKeyFactory().kind("MyClass"); + IncompleteKey incompleteKey = keyFactory.newKey(); + + // let cloud datastore automatically assign an id + Key key = datastore.allocateId(incompleteKey); + // [END allocateIdSingle] + return key; + } + + /** + * Example of allocating multiple ids in a single batch + */ + // [TARGET allocateId(IncompleteKey... keys)] + public List batchAllocateId() { + // [START batchAllocateId] + KeyFactory keyFactory = datastore.newKeyFactory().kind("MyClass"); + IncompleteKey incompleteKey1 = keyFactory.newKey(); + IncompleteKey incompleteKey2 = keyFactory.newKey(); + + // let cloud datastore automatically assign the ids + List keys = datastore.allocateId(incompleteKey1, incompleteKey2); + // [END batchAllocateId] + return keys; + } + + /** + * Example of updating multiple entities + */ + // [TARGET update(Entity... entities)] + // [VARIABLE "my_key_name"] + public void batchUpdateEntities(String keyName1, String keyName2) { + // [START batchUpdateEntities] + Key key1 = datastore.newKeyFactory().kind("MyClass").newKey(keyName1); + Entity.Builder entityBuilder1 = Entity.builder(key1); + entityBuilder1.set("propertyName", "updatedValue1"); + Entity entity1 = entityBuilder1.build(); + + Key key2 = datastore.newKeyFactory().kind("MyClass").newKey(keyName2); + Entity.Builder entityBuilder2 = Entity.builder(key2); + entityBuilder2.set("propertyName", "updatedValue2"); + Entity entity2 = entityBuilder2.build(); + + datastore.update(entity1, entity2); + // [END batchUpdateEntities] + } + + /** + * Example of putting a single entity + */ + // [TARGET put(FullEntity entity)] + // [VARIABLE "my_key_name"] + public void putSingleEntity(String keyName) { + // [START putSingleEntity] + Key key = datastore.newKeyFactory().kind("MyClass").newKey(keyName); + Entity.Builder entityBuilder = Entity.builder(key); + entityBuilder.set("propertyName", "value"); + Entity entity = entityBuilder.build(); + datastore.put(entity); + // [END putSingleEntity] + } + + /** + * Example of putting multiple entities + */ + // [TARGET put(FullEntity... entity)] + // [VARIABLE "my_key_name1"] + // [VARIABLE "my_key_name2"] + public void batchPutEntities(String keyName1, String keyName2) { + // [START batchPutEntities] + Key key1 = datastore.newKeyFactory().kind("MyClass").newKey(keyName1); + Entity.Builder entityBuilder1 = Entity.builder(key1); + entityBuilder1.set("propertyName", "value1"); + Entity entity1 = entityBuilder1.build(); + + Key key2 = datastore.newKeyFactory().kind("MyClass").newKey(keyName2); + Entity.Builder entityBuilder2 = Entity.builder(key2); + entityBuilder2.set("propertyName", "value2"); + Entity entity2 = entityBuilder2.build(); + + datastore.put(entity1, entity2); + // [END batchPutEntities] + } + + /** + * Example of deleting multiplie entities + */ + // [TARGET delete(Key... keys)] + // [VARIABLE "my_key_name1"] + // [VARIABLE "my_key_name2"] + public void batchDeleteEntities(String keyName1, String keyName2) { + // [START batchDeleteEntities] + Key key1 = datastore.newKeyFactory().kind("MyClass").newKey(keyName1); + Key key2 = datastore.newKeyFactory().kind("MyClass").newKey(keyName2); + datastore.delete(key1, key2); + // [END batchDeleteEntities] + } + + /** + * Example of creating a KeyFactory. + */ + // [TARGET newKeyFactory()] + public KeyFactory createKeyFactory() { + // [START createKeyFactory] + KeyFactory keyFactory = datastore.newKeyFactory(); + // [END createKeyFactory] + return keyFactory; + } + + /** + * Example of getting an Entity. + */ + // [TARGET get(Key key, ReadOption... options)] + // [VARIABLE "my_key_name"] + public Entity getEntityWithKey(String keyName) { + // [START getEntityWithKey] + Key key = datastore.newKeyFactory().kind("MyClass").newKey(keyName); + Entity entity = datastore.get(key); + // Do something with the entity + // [END getEntityWithKey] + return entity; + } + + /** + * Example of getting multiple Entity objects. + */ + // [TARGET get(Iterable key, ReadOption... options)] + // [VARIABLE "my_first_key_name"] + // [VARIABLE "my_second_key_name"] + public List getEntitiesWithKeys(String firstKeyName, String secondKeyName) { + // [START getEntitiesWithKeys] + KeyFactory keyFactory = datastore.newKeyFactory().kind("MyClass"); + Key firstKey = keyFactory.newKey(firstKeyName); + Key secondKey = keyFactory.newKey(secondKeyName); + Iterator entitiesIterator = datastore.get(Lists.newArrayList(firstKey, secondKey)); + // TODO make a change so that it's not necessary to hold the entities in a list for + // integration testing + List entities = Lists.newArrayList(); + while (entitiesIterator.hasNext()) { + Entity entity = entitiesIterator.next(); + // do something with the entity + entities.add(entity); + } + // [END getEntitiesWithKeys] + return entities; + } + + /** + * Example of fetching a list of Entity objects. + */ + // [TARGET fetch(Iterable key, ReadOption... options)] + // [VARIABLE "my_first_key_name"] + // [VARIABLE "my_second_key_name"] + public List fetchEntitiesWithKeys(String firstKeyName, String secondKeyName) { + // [START fetchEntitiesWithKeys] + KeyFactory keyFactory = datastore.newKeyFactory().kind("MyClass"); + Key firstKey = keyFactory.newKey(firstKeyName); + Key secondKey = keyFactory.newKey(secondKeyName); + List entities = datastore.fetch(Lists.newArrayList(firstKey, secondKey)); + for (Entity entity : entities) { + // do something with the entity + } + // [END fetchEntitiesWithKeys] + return entities; + } + + /** + * Example of running a query to find all keys of one kind. + */ + // [TARGET run(Query query, ReadOption... options)] + // [VARIABLE "my_kind"] + public List runQuery(String kind) { + // [START runQuery] + StructuredQuery query = + Query.entityQueryBuilder() + .kind(kind) + .build(); + QueryResults results = datastore.run(query); + // TODO make a change so that it's not necessary to hold the entities in a list for + // integration testing + List entities = Lists.newArrayList(); + while (results.hasNext()) { + Entity result = results.next(); + // do something with result + entities.add(result); + } + // [END runQuery] + return entities; + } + + /** + * Example of running a query to find all keys with a matching property value. + */ + // [TARGET run(Query query, ReadOption... options)] + // [VARIABLE "my_kind"] + // [VARIABLE "my_property"] + // [VARIABLE "my_value"] + public List runQueryOnProperty(String kind, String property, String value) { + // [START runQueryOnProperty] + StructuredQuery query = + Query.entityQueryBuilder() + .kind(kind) + .filter(PropertyFilter.eq(property, value)) + .build(); + QueryResults results = datastore.run(query); + // TODO make a change so that it's not necessary to hold the entities in a list for + // integration testing + List entities = Lists.newArrayList(); + while (results.hasNext()) { + Entity result = results.next(); + // do something with result + entities.add(result); + } + // [END runQueryOnProperty] + return entities; + } +} diff --git a/google-cloud-examples/src/test/java/com/google/cloud/examples/datastore/snippets/ITDatastoreSnippets.java b/google-cloud-examples/src/test/java/com/google/cloud/examples/datastore/snippets/ITDatastoreSnippets.java new file mode 100644 index 000000000000..4c2292f8433d --- /dev/null +++ b/google-cloud-examples/src/test/java/com/google/cloud/examples/datastore/snippets/ITDatastoreSnippets.java @@ -0,0 +1,196 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.examples.datastore.snippets; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import com.google.cloud.datastore.Batch; +import com.google.cloud.datastore.Datastore; +import com.google.cloud.datastore.DatastoreOptions; +import com.google.cloud.datastore.Entity; +import com.google.cloud.datastore.Key; +import com.google.cloud.datastore.KeyFactory; +import com.google.cloud.examples.datastore.snippets.DatastoreSnippets; +import com.google.common.collect.Lists; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.After; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.rules.Timeout; + +public class ITDatastoreSnippets { + + private static Datastore datastore; + private static DatastoreSnippets datastoreSnippets; + + private List registeredKeys = new ArrayList<>(); + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Rule + public Timeout globalTimeout = Timeout.seconds(300); + + @BeforeClass + public static void beforeClass() { + datastore = DatastoreOptions.defaultInstance().service(); + datastoreSnippets = new DatastoreSnippets(datastore); + } + + @After + public void afterTest() { + datastore.delete(registeredKeys.toArray(new Key[0])); + } + + private String registerKey(String keyName) { + return registerKey(keyName, "MyClass"); + } + + private String registerKey(String keyName, String kind) { + Key key = datastore.newKeyFactory().kind(kind).newKey(keyName); + registeredKeys.add(key); + return key.name(); + } + + private Map createEntityMap(List entities) { + Map entityMap = new HashMap<>(); + for (Entity entity : entities) { + entityMap.put(entity.key().name(), entity); + } + return entityMap; + } + + private void addEntity(String keyName, String keyClass, String property, String value) { + Key key = datastore.newKeyFactory().kind(keyClass).newKey(keyName); + Entity.Builder entityBuilder = Entity.builder(key); + entityBuilder.set(property, value); + Entity entity = entityBuilder.build(); + datastore.put(entity); + } + + @Test + public void testRunInTransaction() { + String testString = "Test String"; + String result = datastoreSnippets.runInTransaction(testString); + assertEquals(testString, result); + } + + @Test + public void testNewBatch() { + String testKey1 = registerKey("new_batch_key1"); + String testKey2 = registerKey("new_batch_key2"); + Batch batch = datastoreSnippets.newBatch(testKey1, testKey2); + assertNotNull(batch); + } + + @Test + public void testAllocateIdSingle() { + Key key = datastoreSnippets.allocateIdSingle(); + assertNotNull(key); + } + + @Test + public void testAllocateIdMultiple() { + List keys = datastoreSnippets.batchAllocateId(); + assertEquals(2, keys.size()); + } + + @Test + public void testEntityPutGet() { + String key = registerKey("my_single_key"); + datastoreSnippets.putSingleEntity(key); + Entity entity = datastoreSnippets.getEntityWithKey(key); + assertEquals("value", entity.getString("propertyName")); + } + + @Test + public void testBatchEntityCrud() { + String key1 = registerKey("batch_key1"); + String key2 = registerKey("batch_key2"); + datastoreSnippets.batchPutEntities(key1, key2); + + assertNotNull(datastoreSnippets.getEntityWithKey(key1)); + assertNotNull(datastoreSnippets.getEntityWithKey(key2)); + + List entities = Lists + .newArrayList(datastoreSnippets.getEntitiesWithKeys(key1, key2)); + assertEquals(2, entities.size()); + Map entityMap = createEntityMap(entities); + assertEquals("value1", entityMap.get(key1).getString("propertyName")); + assertEquals("value2", entityMap.get(key2).getString("propertyName")); + + datastoreSnippets.batchUpdateEntities(key1, key2); + + List fetchedEntities = datastoreSnippets.fetchEntitiesWithKeys(key1, key2); + assertEquals(2, fetchedEntities.size()); + Map fetchedEntityMap = createEntityMap(fetchedEntities); + assertEquals("updatedValue1", fetchedEntityMap.get(key1).getString("propertyName")); + assertEquals("updatedValue2", fetchedEntityMap.get(key2).getString("propertyName")); + + datastoreSnippets.batchDeleteEntities(key1, key2); + + assertNull(datastoreSnippets.getEntityWithKey(key1)); + assertNull(datastoreSnippets.getEntityWithKey(key2)); + + List fetchedEntities2 = datastoreSnippets.fetchEntitiesWithKeys(key1, key2); + assertEquals(2, fetchedEntities2.size()); + assertNull(fetchedEntities2.get(0)); + assertNull(fetchedEntities2.get(1)); + } + + @Test + public void testCreateKeyFactory() { + KeyFactory keyFactory = datastoreSnippets.createKeyFactory(); + assertNotNull(keyFactory); + } + + @Test + public void testRunQuery() { + String kindToFind = "ClassToFind"; + String kindToMiss = "OtherClass"; + + String keyNameToFind = registerKey("my_key_name_to_find", kindToFind); + String otherKeyNameToFind = registerKey("other_key_name_to_find", kindToFind); + String keyNameToMiss = registerKey("my_key_name_to_miss", kindToMiss); + + String property = "my_property_name"; + + String valueToFind = "my_value_to_find"; + String valueToMiss = "my_value_to_miss"; + + addEntity(keyNameToFind, kindToFind, property, valueToFind); + addEntity(otherKeyNameToFind, kindToFind, property, valueToMiss); + addEntity(keyNameToMiss, kindToMiss, property, valueToFind); + + List queryResults = datastoreSnippets.runQuery(kindToFind); + assertNotNull(queryResults); + assertEquals(2, queryResults.size()); + + queryResults = datastoreSnippets.runQueryOnProperty(kindToFind, property, valueToFind); + assertNotNull(queryResults); + assertEquals(1, queryResults.size()); + } +}