All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.mongodb.client.internal.ChangeStreamIterableImpl Maven / Gradle / Ivy

Go to download

The MongoDB Driver uber-artifact that combines mongodb-driver-sync and the legacy driver

There is a newer version: 3.12.14
Show newest version
/*
 * Copyright 2008-present MongoDB, Inc.
 *
 * 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.mongodb.client.internal;

import com.mongodb.MongoNamespace;
import com.mongodb.ReadConcern;
import com.mongodb.ReadPreference;
import com.mongodb.client.ChangeStreamIterable;
import com.mongodb.client.ClientSession;
import com.mongodb.client.MongoChangeStreamCursor;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoIterable;
import com.mongodb.client.model.Collation;
import com.mongodb.client.model.changestream.ChangeStreamDocument;
import com.mongodb.client.model.changestream.ChangeStreamLevel;
import com.mongodb.client.model.changestream.FullDocument;
import com.mongodb.lang.Nullable;
import com.mongodb.operation.BatchCursor;
import com.mongodb.operation.ChangeStreamOperation;
import com.mongodb.operation.ReadOperation;
import org.bson.BsonDocument;
import org.bson.BsonTimestamp;
import org.bson.RawBsonDocument;
import org.bson.codecs.Codec;
import org.bson.codecs.RawBsonDocumentCodec;
import org.bson.codecs.configuration.CodecRegistry;
import org.bson.conversions.Bson;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static com.mongodb.assertions.Assertions.notNull;
import static java.util.concurrent.TimeUnit.MILLISECONDS;

/**
 * This class is NOT part of the public API. It may change at any time without notification.
 */
class ChangeStreamIterableImpl extends MongoIterableImpl> implements ChangeStreamIterable {
    private final MongoNamespace namespace;
    private final CodecRegistry codecRegistry;
    private final List pipeline;
    private final Codec> codec;
    private final ChangeStreamLevel changeStreamLevel;

    private FullDocument fullDocument = FullDocument.DEFAULT;
    private BsonDocument resumeToken;
    private BsonDocument startAfter;
    private long maxAwaitTimeMS;
    private Collation collation;
    private BsonTimestamp startAtOperationTime;

    ChangeStreamIterableImpl(@Nullable final ClientSession clientSession, final String databaseName,
                             final CodecRegistry codecRegistry, final ReadPreference readPreference, final ReadConcern readConcern,
                             final OperationExecutor executor, final List pipeline, final Class resultClass,
                             final ChangeStreamLevel changeStreamLevel, final boolean retryReads) {
        this(clientSession, new MongoNamespace(databaseName, "ignored"), codecRegistry, readPreference, readConcern, executor, pipeline,
                resultClass, changeStreamLevel, retryReads);
    }

    ChangeStreamIterableImpl(@Nullable final ClientSession clientSession, final MongoNamespace namespace,
                             final CodecRegistry codecRegistry, final ReadPreference readPreference, final ReadConcern readConcern,
                             final OperationExecutor executor, final List pipeline, final Class resultClass,
                             final ChangeStreamLevel changeStreamLevel, final boolean retryReads) {
        super(clientSession, executor, readConcern, readPreference, retryReads);
        this.namespace = notNull("namespace", namespace);
        this.codecRegistry = notNull("codecRegistry", codecRegistry);
        this.pipeline = notNull("pipeline", pipeline);
        this.codec = ChangeStreamDocument.createCodec(notNull("resultClass", resultClass), codecRegistry);
        this.changeStreamLevel = notNull("changeStreamLevel", changeStreamLevel);
    }

    @Override
    public ChangeStreamIterable fullDocument(final FullDocument fullDocument) {
        this.fullDocument = notNull("fullDocument", fullDocument);
        return this;
    }

    @Override
    public ChangeStreamIterable resumeAfter(final BsonDocument resumeAfter) {
        this.resumeToken = notNull("resumeAfter", resumeAfter);
        return this;
    }

    @Override
    public ChangeStreamIterable batchSize(final int batchSize) {
        super.batchSize(batchSize);
        return this;
    }

    @Override
    public ChangeStreamIterable maxAwaitTime(final long maxAwaitTime, final TimeUnit timeUnit) {
        notNull("timeUnit", timeUnit);
        this.maxAwaitTimeMS = MILLISECONDS.convert(maxAwaitTime, timeUnit);
        return this;
    }

    @Override
    public ChangeStreamIterable collation(@Nullable final Collation collation) {
        this.collation = notNull("collation", collation);
        return this;
    }

    @Override
    public  MongoIterable withDocumentClass(final Class clazz) {
        return new MongoIterableImpl(getClientSession(), getExecutor(), getReadConcern(), getReadPreference(), getRetryReads()) {
            @Override
            public MongoCursor iterator() {
                return cursor();
            }

            @Override
            public MongoChangeStreamCursor cursor() {
                return new MongoChangeStreamCursorImpl(execute(), codecRegistry.get(clazz), initialResumeToken());
            }

            @Override
            public ReadOperation> asReadOperation() {
                throw new UnsupportedOperationException();
            }
        };
    }

    @Override
    public ChangeStreamIterable startAtOperationTime(final BsonTimestamp startAtOperationTime) {
        this.startAtOperationTime = notNull("startAtOperationTime", startAtOperationTime);
        return this;
    }

    @Override
    public ChangeStreamIterableImpl startAfter(final BsonDocument startAfter) {
        this.startAfter = notNull("startAfter", startAfter);
        return this;
    }

    @Override
    public MongoCursor> iterator() {
        return cursor();
    }

    @Override
    public MongoChangeStreamCursor> cursor() {
        return new MongoChangeStreamCursorImpl>(execute(), codec, initialResumeToken());
    }

    @Nullable
    @Override
    public ChangeStreamDocument first() {
        MongoChangeStreamCursor> cursor = cursor();
        try {
            if (!cursor.hasNext()) {
                return null;
            }
            return cursor.next();
        } finally {
            cursor.close();
        }
    }

    @Override
    public ReadOperation>> asReadOperation() {
        throw new UnsupportedOperationException();
    }

    private ReadOperation> createChangeStreamOperation() {
        return new ChangeStreamOperation(namespace, fullDocument,  createBsonDocumentList(pipeline),
                new RawBsonDocumentCodec(), changeStreamLevel)
                        .batchSize(getBatchSize())
                        .collation(collation)
                        .maxAwaitTime(maxAwaitTimeMS, MILLISECONDS)
                        .resumeAfter(resumeToken)
                        .startAtOperationTime(startAtOperationTime)
                        .startAfter(startAfter)
                        .retryReads(getRetryReads());
    }

    private List createBsonDocumentList(final List pipeline) {
        List aggregateList = new ArrayList(pipeline.size());
        for (Bson obj : pipeline) {
            if (obj == null) {
                throw new IllegalArgumentException("pipeline cannot contain a null value");
            }
            aggregateList.add(obj.toBsonDocument(BsonDocument.class, codecRegistry));
        }
        return aggregateList;
    }

    private BatchCursor execute() {
        return getExecutor().execute(createChangeStreamOperation(), getReadPreference(), getReadConcern(), getClientSession());
    }

    private BsonDocument initialResumeToken() {
        return startAfter != null ? startAfter : resumeToken;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy