use of com.google.cloud.spring.data.firestore.FirestoreDataException in project spring-cloud-gcp by GoogleCloudPlatform.
the class PartTreeFirestoreQuery method validate.
private void validate() {
List parts = this.tree.get().collect(Collectors.toList());
if (parts.size() > 1 && parts.get(0) instanceof PartTree.OrPart) {
throw new FirestoreDataException("Cloud Firestore doesn't support 'OR' (method name: " + this.getQueryMethod().getName() + ")");
}
List<String> unsupportedParts = this.tree.getParts().stream().filter(part -> !isSupportedPart(part.getType())).map(part -> part.getType().toString()).collect(Collectors.toList());
if (!unsupportedParts.isEmpty()) {
throw new FirestoreDataException("Unsupported predicate keywords: " + unsupportedParts + " in " + this.getQueryMethod().getName());
}
}
use of com.google.cloud.spring.data.firestore.FirestoreDataException in project spring-cloud-gcp by GoogleCloudPlatform.
the class PartTreeFirestoreQuery method createBuilderWithFilter.
private StructuredQuery.Builder createBuilderWithFilter(Object[] parameters) {
StructuredQuery.Builder builder = StructuredQuery.newBuilder();
Iterator it = Arrays.asList(parameters).iterator();
StructuredQuery.CompositeFilter.Builder compositeFilter = StructuredQuery.CompositeFilter.newBuilder();
compositeFilter.setOp(StructuredQuery.CompositeFilter.Operator.AND);
this.tree.getParts().forEach(part -> {
StructuredQuery.FieldReference fieldReference = StructuredQuery.FieldReference.newBuilder().setFieldPath(buildName(part)).build();
StructuredQuery.Filter.Builder filter = StructuredQuery.Filter.newBuilder();
if (part.getType() == Part.Type.IS_NULL) {
filter.getUnaryFilterBuilder().setField(fieldReference).setOp(StructuredQuery.UnaryFilter.Operator.IS_NULL);
} else {
if (!it.hasNext()) {
throw new FirestoreDataException("Too few parameters are provided for query method: " + getQueryMethod().getName());
}
Object value = it.next();
StructuredQuery.FieldFilter.Builder fieldFilterBuilder = filter.getFieldFilterBuilder().setField(fieldReference).setOp(getOperator(part, value));
if (fieldReference.getFieldPath().equals(NAME_FIELD)) {
// In Firestore, a field that is used as a document ID can only be of String type
fieldFilterBuilder.setValue(Value.newBuilder().setReferenceValue(this.reactiveOperations.buildResourceName(persistentEntity, (String) value)));
} else {
fieldFilterBuilder.setValue(this.classMapper.toFirestoreValue(value));
}
}
compositeFilter.addFilters(filter.build());
});
builder.setWhere(StructuredQuery.Filter.newBuilder().setCompositeFilter(compositeFilter.build()));
return builder;
}
use of com.google.cloud.spring.data.firestore.FirestoreDataException in project spring-cloud-gcp by GoogleCloudPlatform.
the class ReactiveFirestoreTransactionManagerTest method triggerRollbackCorrectly.
@Test
public void triggerRollbackCorrectly() {
FirestoreTemplate template = getFirestoreTemplate();
ReactiveFirestoreTransactionManager txManager = new ReactiveFirestoreTransactionManager(this.firestoreStub, this.parent, this.classMapper);
TransactionalOperator operator = TransactionalOperator.create(txManager);
template.findById(Mono.defer(() -> {
throw new FirestoreDataException("BOOM!");
}), FirestoreTemplateTests.TestEntity.class).as(operator::transactional).as(StepVerifier::create).expectError().verify();
verify(this.firestoreStub, times(1)).beginTransaction(any(), any());
verify(this.firestoreStub, times(0)).commit(any(), any());
verify(this.firestoreStub, times(1)).rollback(any(), any());
}
use of com.google.cloud.spring.data.firestore.FirestoreDataException in project spring-cloud-gcp by GoogleCloudPlatform.
the class FirestoreIntegrationTests method transactionTest.
@Test
public void transactionTest() {
User alice = new User("Alice", 29);
User bob = new User("Bob", 60);
User user = new User(null, 40);
DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
transactionDefinition.setReadOnly(false);
TransactionalOperator operator = TransactionalOperator.create(this.txManager, transactionDefinition);
reset(this.txManager);
this.firestoreTemplate.save(alice).then(this.firestoreTemplate.save(bob)).then(this.firestoreTemplate.save(user)).as(operator::transactional).block();
assertThat(this.firestoreTemplate.findAll(User.class).collectList().block()).containsExactlyInAnyOrder(bob, alice, user);
verify(this.txManager, times(1)).commit(any());
verify(this.txManager, times(0)).rollback(any());
verify(this.txManager, times(1)).getReactiveTransaction(any());
reset(this.txManager);
// test rollback
this.firestoreTemplate.saveAll(Mono.defer(() -> {
throw new FirestoreDataException("BOOM!");
})).then(this.firestoreTemplate.deleteAll(User.class)).as(operator::transactional).onErrorResume(throwable -> Mono.empty()).block();
verify(this.txManager, times(0)).commit(any());
verify(this.txManager, times(1)).rollback(any());
verify(this.txManager, times(1)).getReactiveTransaction(any());
assertThat(this.firestoreTemplate.count(User.class).block()).isEqualTo(3);
this.firestoreTemplate.findAll(User.class).flatMap(a -> {
a.setAge(a.getAge() - 1);
return this.firestoreTemplate.save(a);
}).as(operator::transactional).collectList().block();
List<User> users = this.firestoreTemplate.findAll(User.class).collectList().block();
assertThat(users).extracting("age").containsExactlyInAnyOrder(28, 59, 39);
assertThat(users).extracting("name").doesNotContainNull();
this.firestoreTemplate.deleteAll(User.class).as(operator::transactional).block();
assertThat(this.firestoreTemplate.findAll(User.class).collectList().block()).isEmpty();
}
Aggregations