/** * Returns a list with a value for each given key (ordered by input). {@code null} values are * returned for nonexistent keys. */ static List<Entity> fetch(Datastore reader, Key[] keys, ReadOption... options) { return compileEntities(keys, reader.get(Arrays.asList(keys), options)); }
static Entity get(Datastore reader, Key key, ReadOption... options) { return Iterators.getNext(reader.get(Collections.singletonList(key), options), null); }
@Override public <T extends DataModel> T findData(UUID jobId, String key, Class<T> type) { Key entityKey = getDataKey(jobId, key); Entity entity = datastore.get(entityKey); if (entity == null) { return null; } String serializedEntity = entity.getString(type.getName()); try { return objectMapper.readValue(serializedEntity, type); } catch (IOException t) { throw new RuntimeException("Failed to deserialize entity: " + serializedEntity, t); } }
/** * Returns the job keyed by {@code jobId} in Datastore, or null if not found. */ @Override public PortabilityJob findJob(UUID jobId) { Entity entity = datastore.get(getKey(jobId)); if (entity == null) { return null; } try { return PortabilityJob.fromMap(getProperties(entity)); } catch (IOException | ClassNotFoundException e) { // TODO: Rethrow as IOException and propagate to callers throw new RuntimeException(e); } }
/** Example of getting multiple entity objects. */ // [TARGET get(Iterable, ReadOption...)] // [VARIABLE "my_first_key_name"] // [VARIABLE "my_second_key_name"] public List<Entity> getEntitiesWithKeys(String firstKeyName, String secondKeyName) { // TODO change so that it's not necessary to hold the entities in a list for integration testing // [START getEntitiesWithKeys] KeyFactory keyFactory = datastore.newKeyFactory().setKind("MyKind"); Key firstKey = keyFactory.newKey(firstKeyName); Key secondKey = keyFactory.newKey(secondKeyName); Iterator<Entity> entitiesIterator = datastore.get(Lists.newArrayList(firstKey, secondKey)); List<Entity> entities = Lists.newArrayList(); while (entitiesIterator.hasNext()) { Entity entity = entitiesIterator.next(); // do something with the entity entities.add(entity); } // [END getEntitiesWithKeys] return entities; }
/** Example of getting an entity. */ // [TARGET get(Key, ReadOption...)] // [VARIABLE "my_key_name"] public Entity getEntityWithKey(String keyName) { // [START getEntityWithKey] Key key = datastore.newKeyFactory().setKind("MyKind").newKey(keyName); Entity entity = datastore.get(key); // Do something with the entity // [END getEntityWithKey] return entity; }
@Test public void testGetArrayDeferredResults() throws DatastoreException { Set<Key> requestedKeys = new HashSet<>(); requestedKeys.add(KEY1); requestedKeys.add(KEY2); requestedKeys.add(KEY3); requestedKeys.add(KEY4); requestedKeys.add(KEY5); Iterator<Entity> iter = createDatastoreForDeferredLookup().get(KEY1, KEY2, KEY3, KEY4, KEY5); Set<Key> keysOfFoundEntities = new HashSet<>(); while (iter.hasNext()) { keysOfFoundEntities.add(iter.next().getKey()); } assertEquals(requestedKeys, keysOfFoundEntities); }
@Test public void testGetWithDatastore() throws Exception { Datastore datastore = createStrictMock(Datastore.class); IncompleteKey pKey1 = IncompleteKey.newBuilder("ds", "k").build(); Key key1 = Key.newBuilder(pKey1, 1).build(); Entity entity1 = Entity.newBuilder(key1).build(); Key key2 = Key.newBuilder(pKey1, 2).build(); ReadOption eventualConsistency = ReadOption.eventualConsistency(); expect(datastore.get(Collections.singletonList(key1))) .andReturn(Collections.singletonList(entity1).iterator()); expect(datastore.get(Collections.singletonList(key2))) .andReturn(Collections.<Entity>emptyIterator()); expect(datastore.get(Collections.singletonList(key1), eventualConsistency)) .andReturn(Collections.singletonList(entity1).iterator()); replay(datastore); assertEquals(entity1, DatastoreHelper.get(datastore, key1)); assertNull(DatastoreHelper.get(datastore, key2)); assertEquals(entity1, DatastoreHelper.get(datastore, key1, eventualConsistency)); verify(datastore); }
public static void main(String... args) { Datastore datastore = DatastoreOptions.getDefaultInstance().getService(); KeyFactory keyFactory = datastore.newKeyFactory().setKind("keyKind"); Key key = keyFactory.newKey("keyName"); Entity entity = datastore.get(key); if (entity != null) { System.out.println("Updating access_time for " + entity.getString("name")); entity = Entity.newBuilder(entity).set("access_time", Timestamp.now()).build(); datastore.update(entity); } } }
@Test public void testRuntimeException() throws Exception { LookupRequest requestPb = LookupRequest.newBuilder().addKeys(KEY1.toPb()).build(); String exceptionMessage = "Artificial runtime exception"; EasyMock.expect(rpcMock.lookup(requestPb)).andThrow(new RuntimeException(exceptionMessage)); EasyMock.replay(rpcFactoryMock, rpcMock); Datastore datastore = rpcMockOptions.getService(); thrown.expect(DatastoreException.class); thrown.expectMessage(exceptionMessage); datastore.get(KEY1); EasyMock.verify(rpcFactoryMock, rpcMock); } }
@Test public void testPut() { Entity updatedEntity = Entity.newBuilder(ENTITY1).set("new_property", 42L).build(); assertEquals(updatedEntity, datastore.put(updatedEntity)); assertEquals(updatedEntity, datastore.get(updatedEntity.getKey())); Entity entity2 = Entity.newBuilder(ENTITY2).clear().set("bla", new NullValue()).build(); assertNotEquals(ENTITY2, entity2); List<Entity> entities = datastore.put(ENTITY1, entity2, ENTITY3, PARTIAL_ENTITY1); assertEquals(ENTITY1, entities.get(0)); assertEquals(entity2, entities.get(1)); assertEquals(ENTITY3, entities.get(2)); assertEquals(PARTIAL_ENTITY1.getProperties(), entities.get(3).getProperties()); assertEquals(PARTIAL_ENTITY1.getKey().getAncestors(), entities.get(3).getKey().getAncestors()); assertEquals(ENTITY1, datastore.get(ENTITY1.getKey())); assertEquals(entity2, datastore.get(entity2.getKey())); assertEquals(ENTITY3, datastore.get(ENTITY3.getKey())); Entity entity = datastore.get(entities.get(3).getKey()); assertEquals(entities.get(3), entity); }
@Test public void testNonRetryableException() throws Exception { LookupRequest requestPb = LookupRequest.newBuilder().addKeys(KEY1.toPb()).build(); EasyMock.expect(rpcMock.lookup(requestPb)) .andThrow( new DatastoreException(DatastoreException.UNKNOWN_CODE, "denied", "PERMISSION_DENIED")) .times(1); EasyMock.replay(rpcFactoryMock, rpcMock); Datastore datastore = rpcMockOptions.getService(); thrown.expect(DatastoreException.class); thrown.expectMessage("denied"); datastore.get(KEY1); EasyMock.verify(rpcFactoryMock, rpcMock); }
@Test public void testAddEntity() { List<Entity> keys = datastore.fetch(ENTITY1.getKey(), ENTITY3.getKey()); assertEquals(ENTITY1, keys.get(0)); assertNull(keys.get(1)); assertEquals(2, keys.size()); try { datastore.add(ENTITY1); fail("Expecting a failure"); } catch (DatastoreException expected) { // expected; } List<Entity> entities = datastore.add(ENTITY3, PARTIAL_ENTITY1, PARTIAL_ENTITY2); assertEquals(ENTITY3, datastore.get(ENTITY3.getKey())); assertEquals(ENTITY3, entities.get(0)); assertEquals(PARTIAL_ENTITY1.getProperties(), entities.get(1).getProperties()); assertEquals(PARTIAL_ENTITY1.getKey().getAncestors(), entities.get(1).getKey().getAncestors()); assertNotNull(datastore.get(entities.get(1).getKey())); assertEquals(PARTIAL_ENTITY2.getProperties(), entities.get(2).getProperties()); assertEquals(PARTIAL_ENTITY2.getKey().getAncestors(), entities.get(2).getKey().getAncestors()); assertNotNull(datastore.get(entities.get(2).getKey())); }
@Test public void testStartStopReset() throws IOException, InterruptedException, TimeoutException { LocalDatastoreHelper helper = LocalDatastoreHelper.create(); helper.start(); Datastore datastore = helper.getOptions().getService(); Key key = datastore.newKeyFactory().setKind("kind").newKey("name"); datastore.put(Entity.newBuilder(key).build()); assertNotNull(datastore.get(key)); helper.reset(); assertNull(datastore.get(key)); helper.stop(Duration.ofMinutes(1)); thrown.expect(DatastoreException.class); datastore.get(key); } }
@Test public void testRetryableException() throws Exception { LookupRequest requestPb = LookupRequest.newBuilder().addKeys(KEY1.toPb()).build(); LookupResponse responsePb = LookupResponse.newBuilder() .addFound(EntityResult.newBuilder().setEntity(ENTITY1.toPb())) .build(); EasyMock.expect(rpcMock.lookup(requestPb)) .andThrow(new DatastoreException(14, "UNAVAILABLE", "UNAVAILABLE", null)) .andReturn(responsePb); EasyMock.replay(rpcFactoryMock, rpcMock); Datastore datastore = rpcMockOptions.getService(); Entity entity = datastore.get(KEY1); assertEquals(ENTITY1, entity); EasyMock.verify(rpcFactoryMock, rpcMock); }
@Test public void testUpdate() { List<Entity> keys = datastore.fetch(ENTITY1.getKey(), ENTITY3.getKey()); assertEquals(ENTITY1, keys.get(0)); assertNull(keys.get(1)); assertEquals(2, keys.size()); try { datastore.update(ENTITY3); fail("Expecting a failure"); } catch (DatastoreException expected) { // expected; } datastore.add(ENTITY3); assertEquals(ENTITY3, datastore.get(ENTITY3.getKey())); Entity entity3 = Entity.newBuilder(ENTITY3).clear().set("bla", new NullValue()).build(); assertNotEquals(ENTITY3, entity3); datastore.update(entity3); assertEquals(entity3, datastore.get(ENTITY3.getKey())); }
@Test public void testUpdate() { List<Entity> keys = DATASTORE.fetch(ENTITY1.getKey(), ENTITY3.getKey()); assertEquals(ENTITY1, keys.get(0)); assertNull(keys.get(1)); assertEquals(2, keys.size()); try { DATASTORE.update(ENTITY3); fail("Expecting a failure"); } catch (DatastoreException expected) { // expected; } DATASTORE.add(ENTITY3); assertEquals(ENTITY3, DATASTORE.get(ENTITY3.getKey())); Entity entity3 = Entity.newBuilder(ENTITY3).clear().set("bla", new NullValue()).build(); assertNotEquals(ENTITY3, entity3); DATASTORE.update(entity3); assertEquals(entity3, DATASTORE.get(ENTITY3.getKey())); }
@Test public void testGet() { Entity entity = DATASTORE.get(KEY3); assertNull(entity); entity = DATASTORE.get(KEY1); assertEquals(ENTITY1, entity); StringValue value1 = entity.getValue("str"); assertEquals(STR_VALUE, value1); BooleanValue value2 = entity.getValue("bool"); assertEquals(BOOL_VALUE, value2); ListValue value3 = entity.getValue("list"); assertEquals(LIST_VALUE2, value3); TimestampValue value4 = entity.getValue("date"); assertEquals(TIMESTAMP_VALUE, value4); LatLngValue value5 = entity.getValue("latLng"); assertEquals(LAT_LNG_VALUE, value5); FullEntity<IncompleteKey> value6 = entity.getEntity("partial1"); assertEquals(PARTIAL_ENTITY1, value6); ListValue value7 = entity.getValue("emptyList"); assertEquals(EMPTY_LIST_VALUE, value7); assertEquals(7, entity.getNames().size()); assertFalse(entity.contains("bla")); }
@Test public void testTransactionWithRead() { Transaction transaction = datastore.newTransaction(); assertNull(transaction.get(KEY3)); transaction.add(ENTITY3); transaction.commit(); assertEquals(ENTITY3, datastore.get(KEY3)); transaction = datastore.newTransaction(); assertEquals(ENTITY3, transaction.get(KEY3)); // update entity3 during the transaction datastore.put(Entity.newBuilder(ENTITY3).clear().build()); transaction.update(ENTITY2); try { transaction.commit(); fail("Expecting a failure"); } catch (DatastoreException expected) { assertEquals("ABORTED", expected.getReason()); } }
@Test public void testTransactionWithRead() { Transaction transaction = DATASTORE.newTransaction(); assertNull(transaction.get(KEY3)); transaction.add(ENTITY3); transaction.commit(); assertEquals(ENTITY3, DATASTORE.get(KEY3)); transaction = DATASTORE.newTransaction(); assertEquals(ENTITY3, transaction.get(KEY3)); // update entity3 during the transaction DATASTORE.put(Entity.newBuilder(ENTITY2).clear().set("from", "datastore").build()); transaction.update(Entity.newBuilder(ENTITY2).clear().set("from", "transaction").build()); try { transaction.commit(); fail("Expecting a failure"); } catch (DatastoreException expected) { assertEquals("ABORTED", expected.getReason()); } }