Skip to content
This repository was archived by the owner on Jan 19, 2022. It is now read-only.

Commit dfe538d

Browse files
authoredAug 27, 2019
Firestore find by (#1836)
findById and findAllById in FirestoreTemplate ; fixes #1778
1 parent 83e5cbe commit dfe538d

File tree

3 files changed

+100
-0
lines changed

3 files changed

+100
-0
lines changed
 

‎spring-cloud-gcp-data-firestore/src/main/java/org/springframework/cloud/gcp/data/firestore/FirestoreTemplate.java

+15
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import com.google.firestore.v1.DeleteDocumentRequest;
2525
import com.google.firestore.v1.Document;
2626
import com.google.firestore.v1.FirestoreGrpc.FirestoreStub;
27+
import com.google.firestore.v1.GetDocumentRequest;
2728
import com.google.firestore.v1.RunQueryRequest;
2829
import com.google.firestore.v1.RunQueryResponse;
2930
import com.google.firestore.v1.StructuredQuery;
@@ -74,6 +75,20 @@ public FirestoreTemplate(FirestoreStub firestore, String parent) {
7475
this.databasePath = parent.substring(0, StringUtils.ordinalIndexOf(parent, "/", 4));
7576
}
7677

78+
public <T> Mono<T> findById(Publisher idPublisher, Class<T> aClass) {
79+
return findAllById(idPublisher, aClass).next();
80+
}
81+
82+
public <T> Flux<T> findAllById(Publisher idPublisher, Class<T> aClass) {
83+
return ((Flux<String>) Flux.from(idPublisher)).flatMap(id -> {
84+
FirestorePersistentEntity<?> persistentEntity = this.mappingContext.getPersistentEntity(aClass);
85+
GetDocumentRequest request = GetDocumentRequest.newBuilder()
86+
.setName(this.parent + "/" + persistentEntity.collectionName() + "/" + id).build();
87+
return ObservableReactiveUtil.<Document>unaryCall(obs -> this.firestore.getDocument(request, obs));
88+
}).onErrorMap(throwable -> new FirestoreDataException("Unable to find an entry by id", throwable))
89+
.map(document -> PublicClassMapper.convertToCustomClass(document, aClass));
90+
}
91+
7792
public <T> Mono<T> save(T entity) {
7893
return Mono.defer(() -> {
7994
FirestorePersistentEntity<?> persistentEntity = this.mappingContext.getPersistentEntity(entity.getClass());

‎spring-cloud-gcp-data-firestore/src/test/java/org/springframework/cloud/gcp/data/firestore/FirestoreIntegrationTests.java

+6
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.junit.Test;
3232
import org.slf4j.LoggerFactory;
3333
import reactor.core.publisher.Flux;
34+
import reactor.core.publisher.Mono;
3435

3536
import org.springframework.data.annotation.Id;
3637

@@ -85,6 +86,10 @@ public void writeReadDeleteTest() {
8586
this.firestoreTemplate.save(alice).block();
8687
this.firestoreTemplate.save(bob).block();
8788

89+
assertThat(this.firestoreTemplate.findById(Mono.just("Bob"), User.class).block()).isEqualTo(bob);
90+
assertThat(this.firestoreTemplate.findAllById(Flux.just("Bob", "Alice"), User.class).collectList().block())
91+
.containsExactly(bob, alice);
92+
8893
List<User> usersBeforeDelete = this.firestoreTemplate.findAll(User.class).collectList().block();
8994

9095
assertThat(this.firestoreTemplate.deleteAll(User.class).block()).isEqualTo(2);
@@ -104,6 +109,7 @@ public void saveAllTest() throws InterruptedException {
104109
this.firestoreTemplate.saveAll(users).collectList().block();
105110

106111
assertThat(this.firestoreTemplate.findAll(User.class).collectList().block().size()).isEqualTo(2);
112+
assertThat(this.firestoreTemplate.deleteAll(User.class).block()).isEqualTo(2);
107113
}
108114
}
109115

‎spring-cloud-gcp-data-firestore/src/test/java/org/springframework/cloud/gcp/data/firestore/FirestoreTemplateTests.java

+79
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import com.google.firestore.v1.DeleteDocumentRequest;
2525
import com.google.firestore.v1.Document;
2626
import com.google.firestore.v1.FirestoreGrpc.FirestoreStub;
27+
import com.google.firestore.v1.GetDocumentRequest;
2728
import com.google.firestore.v1.RunQueryRequest;
2829
import com.google.firestore.v1.RunQueryResponse;
2930
import com.google.firestore.v1.StructuredQuery;
@@ -32,6 +33,8 @@
3233
import io.grpc.stub.StreamObserver;
3334
import org.junit.Before;
3435
import org.junit.Test;
36+
import reactor.core.publisher.Flux;
37+
import reactor.core.publisher.Mono;
3538
import reactor.test.StepVerifier;
3639

3740
import org.springframework.data.annotation.Id;
@@ -104,6 +107,82 @@ public void findAllTest() {
104107
verify(this.firestoreStub, times(1)).runQuery(any(), any());
105108
}
106109

110+
@Test
111+
public void findByIdTest() {
112+
doAnswer(invocation -> {
113+
StreamObserver<Document> streamObserver = invocation.getArgument(1);
114+
streamObserver.onNext(buildDocument("e1", 100L));
115+
116+
streamObserver.onCompleted();
117+
return null;
118+
}).when(this.firestoreStub).getDocument(any(), any());
119+
120+
StepVerifier.create(this.firestoreTemplate.findById(Mono.just("e1"), TestEntity.class))
121+
.expectNext(new TestEntity("e1", 100L))
122+
.verifyComplete();
123+
124+
GetDocumentRequest request = GetDocumentRequest.newBuilder()
125+
.setName(this.parent + "/testEntities/" + "e1")
126+
.build();
127+
128+
verify(this.firestoreStub, times(1)).getDocument(eq(request), any());
129+
}
130+
131+
@Test
132+
public void findByIdErrorTest() {
133+
doAnswer(invocation -> {
134+
StreamObserver<Document> streamObserver = invocation.getArgument(1);
135+
streamObserver.onError(new RuntimeException("Firestore error"));
136+
return null;
137+
}).when(this.firestoreStub).getDocument(any(), any());
138+
139+
StepVerifier.create(this.firestoreTemplate.findById(Mono.just("e1"), TestEntity.class))
140+
.expectErrorMatches(e ->
141+
e instanceof FirestoreDataException
142+
&& e.getMessage().contains("Firestore error")
143+
&& e.getMessage().contains("Unable to find an entry by id"))
144+
.verify();
145+
146+
GetDocumentRequest request = GetDocumentRequest.newBuilder()
147+
.setName(this.parent + "/testEntities/" + "e1")
148+
.build();
149+
150+
verify(this.firestoreStub, times(1)).getDocument(eq(request), any());
151+
}
152+
153+
@Test
154+
public void findAllByIdTest() {
155+
GetDocumentRequest request1 = GetDocumentRequest.newBuilder()
156+
.setName(this.parent + "/testEntities/" + "e1")
157+
.build();
158+
159+
GetDocumentRequest request2 = GetDocumentRequest.newBuilder()
160+
.setName(this.parent + "/testEntities/" + "e2")
161+
.build();
162+
163+
doAnswer(invocation -> {
164+
StreamObserver<Document> streamObserver = invocation.getArgument(1);
165+
streamObserver.onNext(buildDocument("e1", 100L));
166+
167+
streamObserver.onCompleted();
168+
return null;
169+
}).when(this.firestoreStub).getDocument(eq(request1), any());
170+
171+
doAnswer(invocation -> {
172+
StreamObserver<Document> streamObserver = invocation.getArgument(1);
173+
streamObserver.onNext(buildDocument("e2", 200L));
174+
175+
streamObserver.onCompleted();
176+
return null;
177+
}).when(this.firestoreStub).getDocument(eq(request2), any());
178+
179+
StepVerifier.create(this.firestoreTemplate.findAllById(Flux.just("e1", "e2"), TestEntity.class))
180+
.expectNext(new TestEntity("e1", 100L), new TestEntity("e2", 200L))
181+
.verifyComplete();
182+
183+
verify(this.firestoreStub, times(1)).getDocument(eq(request1), any());
184+
}
185+
107186
@Test
108187
public void deleteAllTest() {
109188
mockRunQueryMethod();

0 commit comments

Comments
 (0)