Search in sources :

Example 1 with ListenResponse

use of com.google.firestore.v1.ListenResponse in project java-firestore by googleapis.

the class WatchTest method snapshotWithChangesEquals.

@Test
public void snapshotWithChangesEquals() throws InterruptedException {
    ListenResponse doc1 = doc("coll/doc1", SINGLE_FIELD_PROTO);
    ListenResponse doc2 = doc("coll/doc2", SINGLE_FIELD_PROTO);
    ListenResponse doc3 = doc("coll/doc3", SINGLE_FIELD_PROTO);
    addQueryListener();
    awaitAddTarget();
    send(addTarget());
    send(doc1);
    send(current());
    send(snapshot());
    QuerySnapshot firstSnapshot = awaitQuerySnapshot(new SnapshotDocument(ChangeType.ADDED, "coll/doc1", SINGLE_FIELD_MAP));
    send(doc2);
    send(doc3);
    send(snapshot());
    QuerySnapshot secondSnapshot = awaitQuerySnapshot(new SnapshotDocument(ChangeType.UNCHANGED, "coll/doc1", SINGLE_FIELD_MAP), new SnapshotDocument(ChangeType.ADDED, "coll/doc2", SINGLE_FIELD_MAP), new SnapshotDocument(ChangeType.ADDED, "coll/doc3", SINGLE_FIELD_MAP));
    assertNotEquals(secondSnapshot, firstSnapshot);
    send(docDelete("coll/doc3"));
    send(snapshot());
    QuerySnapshot thirdSnapshot = awaitQuerySnapshot(new SnapshotDocument(ChangeType.UNCHANGED, "coll/doc1", SINGLE_FIELD_MAP), new SnapshotDocument(ChangeType.UNCHANGED, "coll/doc2", SINGLE_FIELD_MAP), new SnapshotDocument(ChangeType.REMOVED, "coll/doc3", null));
    assertNotEquals(thirdSnapshot, firstSnapshot);
    assertNotEquals(thirdSnapshot, secondSnapshot);
    restartWatch();
    addQueryListener();
    awaitAddTarget();
    send(addTarget());
    send(doc2);
    send(current());
    send(snapshot());
    QuerySnapshot currentSnapshot = awaitQuerySnapshot(new SnapshotDocument(ChangeType.ADDED, "coll/doc2", SINGLE_FIELD_MAP));
    assertNotEquals(currentSnapshot, firstSnapshot);
    send(doc3);
    send(doc1);
    send(snapshot());
    currentSnapshot = awaitQuerySnapshot(new SnapshotDocument(ChangeType.ADDED, "coll/doc1", SINGLE_FIELD_MAP), new SnapshotDocument(ChangeType.UNCHANGED, "coll/doc2", SINGLE_FIELD_MAP), new SnapshotDocument(ChangeType.ADDED, "coll/doc3", SINGLE_FIELD_MAP));
    assertNotEquals(currentSnapshot, secondSnapshot);
    send(docDelete("coll/doc3"));
    send(snapshot());
    currentSnapshot = awaitQuerySnapshot(new SnapshotDocument(ChangeType.UNCHANGED, "coll/doc1", SINGLE_FIELD_MAP), new SnapshotDocument(ChangeType.UNCHANGED, "coll/doc2", SINGLE_FIELD_MAP), new SnapshotDocument(ChangeType.REMOVED, "coll/doc3", null));
    assertEquals(currentSnapshot, thirdSnapshot);
}
Also used : ListenResponse(com.google.firestore.v1.ListenResponse) Test(org.junit.Test)

Example 2 with ListenResponse

use of com.google.firestore.v1.ListenResponse in project java-firestore by googleapis.

the class FirestoreClientTest method listenTest.

@Test
public void listenTest() throws Exception {
    ListenResponse expectedResponse = ListenResponse.newBuilder().build();
    mockFirestore.addResponse(expectedResponse);
    ListenRequest request = ListenRequest.newBuilder().setDatabase("database1789464955").putAllLabels(new HashMap<String, String>()).build();
    MockStreamObserver<ListenResponse> responseObserver = new MockStreamObserver<>();
    BidiStreamingCallable<ListenRequest, ListenResponse> callable = client.listenCallable();
    ApiStreamObserver<ListenRequest> requestObserver = callable.bidiStreamingCall(responseObserver);
    requestObserver.onNext(request);
    requestObserver.onCompleted();
    List<ListenResponse> actualResponses = responseObserver.future().get();
    Assert.assertEquals(1, actualResponses.size());
    Assert.assertEquals(expectedResponse, actualResponses.get(0));
}
Also used : HashMap(java.util.HashMap) ListenRequest(com.google.firestore.v1.ListenRequest) MockStreamObserver(com.google.api.gax.grpc.testing.MockStreamObserver) ListenResponse(com.google.firestore.v1.ListenResponse) Test(org.junit.Test)

Example 3 with ListenResponse

use of com.google.firestore.v1.ListenResponse in project firebase-android-sdk by firebase.

the class RemoteSerializer method decodeWatchChange.

// Watch changes
public WatchChange decodeWatchChange(ListenResponse protoChange) {
    WatchChange watchChange;
    switch(protoChange.getResponseTypeCase()) {
        case TARGET_CHANGE:
            com.google.firestore.v1.TargetChange targetChange = protoChange.getTargetChange();
            WatchTargetChangeType changeType;
            Status cause = null;
            switch(targetChange.getTargetChangeType()) {
                case NO_CHANGE:
                    changeType = WatchTargetChangeType.NoChange;
                    break;
                case ADD:
                    changeType = WatchTargetChangeType.Added;
                    break;
                case REMOVE:
                    changeType = WatchTargetChangeType.Removed;
                    cause = fromStatus(targetChange.getCause());
                    break;
                case CURRENT:
                    changeType = WatchTargetChangeType.Current;
                    break;
                case RESET:
                    changeType = WatchTargetChangeType.Reset;
                    break;
                case UNRECOGNIZED:
                default:
                    throw new IllegalArgumentException("Unknown target change type");
            }
            watchChange = new WatchTargetChange(changeType, targetChange.getTargetIdsList(), targetChange.getResumeToken(), cause);
            break;
        case DOCUMENT_CHANGE:
            DocumentChange docChange = protoChange.getDocumentChange();
            List<Integer> added = docChange.getTargetIdsList();
            List<Integer> removed = docChange.getRemovedTargetIdsList();
            DocumentKey key = decodeKey(docChange.getDocument().getName());
            SnapshotVersion version = decodeVersion(docChange.getDocument().getUpdateTime());
            hardAssert(!version.equals(SnapshotVersion.NONE), "Got a document change without an update time");
            ObjectValue data = ObjectValue.fromMap(docChange.getDocument().getFieldsMap());
            MutableDocument document = MutableDocument.newFoundDocument(key, version, data);
            watchChange = new WatchChange.DocumentChange(added, removed, document.getKey(), document);
            break;
        case DOCUMENT_DELETE:
            DocumentDelete docDelete = protoChange.getDocumentDelete();
            removed = docDelete.getRemovedTargetIdsList();
            key = decodeKey(docDelete.getDocument());
            // Note that version might be unset in which case we use SnapshotVersion.NONE
            version = decodeVersion(docDelete.getReadTime());
            MutableDocument doc = MutableDocument.newNoDocument(key, version);
            watchChange = new WatchChange.DocumentChange(Collections.emptyList(), removed, doc.getKey(), doc);
            break;
        case DOCUMENT_REMOVE:
            DocumentRemove docRemove = protoChange.getDocumentRemove();
            removed = docRemove.getRemovedTargetIdsList();
            key = decodeKey(docRemove.getDocument());
            watchChange = new WatchChange.DocumentChange(Collections.emptyList(), removed, key, null);
            break;
        case FILTER:
            com.google.firestore.v1.ExistenceFilter protoFilter = protoChange.getFilter();
            // TODO: implement existence filter parsing (see b/33076578)
            ExistenceFilter filter = new ExistenceFilter(protoFilter.getCount());
            int targetId = protoFilter.getTargetId();
            watchChange = new ExistenceFilterWatchChange(targetId, filter);
            break;
        case RESPONSETYPE_NOT_SET:
        default:
            throw new IllegalArgumentException("Unknown change type set");
    }
    return watchChange;
}
Also used : Status(io.grpc.Status) DocumentRemove(com.google.firestore.v1.DocumentRemove) MutableDocument(com.google.firebase.firestore.model.MutableDocument) WatchTargetChangeType(com.google.firebase.firestore.remote.WatchChange.WatchTargetChangeType) DocumentChange(com.google.firestore.v1.DocumentChange) WatchTargetChange(com.google.firebase.firestore.remote.WatchChange.WatchTargetChange) DocumentDelete(com.google.firestore.v1.DocumentDelete) ObjectValue(com.google.firebase.firestore.model.ObjectValue) SnapshotVersion(com.google.firebase.firestore.model.SnapshotVersion) ExistenceFilterWatchChange(com.google.firebase.firestore.remote.WatchChange.ExistenceFilterWatchChange) DocumentKey(com.google.firebase.firestore.model.DocumentKey) ExistenceFilterWatchChange(com.google.firebase.firestore.remote.WatchChange.ExistenceFilterWatchChange)

Example 4 with ListenResponse

use of com.google.firestore.v1.ListenResponse in project java-firestore by googleapis.

the class Watch method onResponse.

@Override
public synchronized void onResponse(ListenResponse listenResponse) {
    switch(listenResponse.getResponseTypeCase()) {
        case TARGET_CHANGE:
            TargetChange change = listenResponse.getTargetChange();
            boolean noTargetIds = change.getTargetIdsCount() == 0;
            switch(change.getTargetChangeType()) {
                case NO_CHANGE:
                    if (noTargetIds && change.hasReadTime() && current) {
                        // This means everything is up-to-date, so emit the current set of docs as a snapshot,
                        // if there were changes.
                        pushSnapshot(Timestamp.fromProto(change.getReadTime()), change.getResumeToken());
                    }
                    break;
                case ADD:
                    if (WATCH_TARGET_ID != change.getTargetIds(0)) {
                        closeStream(FirestoreException.forInvalidArgument("Target ID must be 0x01"));
                    }
                    break;
                case REMOVE:
                    Status status = change.hasCause() ? Status.fromCodeValue(change.getCause().getCode()) : Status.CANCELLED;
                    closeStream(FirestoreException.forServerRejection(status, "Backend ended Listen stream: " + change.getCause().getMessage()));
                    break;
                case CURRENT:
                    current = true;
                    break;
                case RESET:
                    resetDocs();
                    break;
                default:
                    closeStream(FirestoreException.forInvalidArgument("Encountered invalid target change type: " + change.getTargetChangeType()));
            }
            if (change.getResumeToken() != null && affectsTarget(change.getTargetIdsList(), WATCH_TARGET_ID)) {
                nextAttempt = backoff.createFirstAttempt();
            }
            break;
        case DOCUMENT_CHANGE:
            // No other targetIds can show up here, but we still need to see if the targetId was in the
            // added list or removed list.
            List<Integer> targetIds = listenResponse.getDocumentChange().getTargetIdsList();
            List<Integer> removedTargetIds = listenResponse.getDocumentChange().getRemovedTargetIdsList();
            boolean changed = targetIds.contains(WATCH_TARGET_ID);
            boolean removed = removedTargetIds.contains(WATCH_TARGET_ID);
            Document document = listenResponse.getDocumentChange().getDocument();
            ResourcePath name = ResourcePath.create(document.getName());
            if (changed) {
                changeMap.put(name, document);
            } else if (removed) {
                changeMap.put(name, null);
            }
            break;
        case DOCUMENT_DELETE:
            changeMap.put(ResourcePath.create(listenResponse.getDocumentDelete().getDocument()), null);
            break;
        case DOCUMENT_REMOVE:
            changeMap.put(ResourcePath.create(listenResponse.getDocumentRemove().getDocument()), null);
            break;
        case FILTER:
            if (listenResponse.getFilter().getCount() != currentSize()) {
                // We need to remove all the current results.
                resetDocs();
                // The filter didn't match, so re-issue the query.
                resetStream();
            }
            break;
        default:
            closeStream(FirestoreException.forInvalidArgument("Encountered invalid listen response type"));
            break;
    }
}
Also used : Status(io.grpc.Status) TargetChange(com.google.firestore.v1.TargetChange) Document(com.google.firestore.v1.Document)

Example 5 with ListenResponse

use of com.google.firestore.v1.ListenResponse in project java-firestore by googleapis.

the class WatchTest method queryWatchHandlesDeletesAndAddInSingleSnapshot.

@Test
public void queryWatchHandlesDeletesAndAddInSingleSnapshot() throws InterruptedException {
    ListenResponse document = doc("coll/doc1", SINGLE_FIELD_PROTO);
    addQueryListener();
    awaitAddTarget();
    send(addTarget());
    send(current());
    send(document);
    send(snapshot());
    awaitQuerySnapshot(new SnapshotDocument(ChangeType.ADDED, "coll/doc1", SINGLE_FIELD_MAP));
    send(docDelete("coll/doc1"));
    send(doc("coll/doc2", SINGLE_FIELD_PROTO));
    send(document);
    send(snapshot());
    awaitQuerySnapshot(new SnapshotDocument(ChangeType.UNCHANGED, "coll/doc1", SINGLE_FIELD_MAP), new SnapshotDocument(ChangeType.ADDED, "coll/doc2", SINGLE_FIELD_MAP));
}
Also used : ListenResponse(com.google.firestore.v1.ListenResponse) Test(org.junit.Test)

Aggregations

ListenResponse (com.google.firestore.v1.ListenResponse)4 Test (org.junit.Test)4 MockStreamObserver (com.google.api.gax.grpc.testing.MockStreamObserver)2 ListenRequest (com.google.firestore.v1.ListenRequest)2 Status (io.grpc.Status)2 HashMap (java.util.HashMap)2 InvalidArgumentException (com.google.api.gax.rpc.InvalidArgumentException)1 DocumentKey (com.google.firebase.firestore.model.DocumentKey)1 MutableDocument (com.google.firebase.firestore.model.MutableDocument)1 ObjectValue (com.google.firebase.firestore.model.ObjectValue)1 SnapshotVersion (com.google.firebase.firestore.model.SnapshotVersion)1 ExistenceFilterWatchChange (com.google.firebase.firestore.remote.WatchChange.ExistenceFilterWatchChange)1 WatchTargetChange (com.google.firebase.firestore.remote.WatchChange.WatchTargetChange)1 WatchTargetChangeType (com.google.firebase.firestore.remote.WatchChange.WatchTargetChangeType)1 Document (com.google.firestore.v1.Document)1 DocumentChange (com.google.firestore.v1.DocumentChange)1 DocumentDelete (com.google.firestore.v1.DocumentDelete)1 DocumentRemove (com.google.firestore.v1.DocumentRemove)1 TargetChange (com.google.firestore.v1.TargetChange)1 StatusRuntimeException (io.grpc.StatusRuntimeException)1