com.hurence.logisland.service.mongodb.MongoDBControllerService.java Source code

Java tutorial

Introduction

Here is the source code for com.hurence.logisland.service.mongodb.MongoDBControllerService.java

Source

/**
 * Copyright (C) 2016 Hurence (support@hurence.com)
 *
 * 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.hurence.logisland.service.mongodb;

import com.hurence.logisland.annotation.documentation.CapabilityDescription;
import com.hurence.logisland.annotation.documentation.Tags;
import com.hurence.logisland.annotation.lifecycle.OnDisabled;
import com.hurence.logisland.annotation.lifecycle.OnEnabled;
import com.hurence.logisland.component.InitializationException;
import com.hurence.logisland.component.PropertyDescriptor;
import com.hurence.logisland.component.PropertyValue;
import com.hurence.logisland.controller.ControllerServiceInitializationContext;
import com.hurence.logisland.record.Record;
import com.hurence.logisland.service.datastore.DatastoreClientServiceException;
import com.hurence.logisland.service.datastore.MultiGetQueryRecord;
import com.hurence.logisland.service.datastore.MultiGetResponseRecord;
import com.hurence.logisland.util.Tuple;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.UpdateOptions;
import org.bson.BSON;
import org.bson.BsonDocument;
import org.bson.Document;
import org.bson.conversions.Bson;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Tags({ "mongo", "mongodb", "service" })
@CapabilityDescription("Provides a controller service that wraps most of the functionality of the MongoDB driver.")
public class MongoDBControllerService extends AbstractMongoDBControllerService implements MongoDBClientService {
    private MongoDatabase db;
    private MongoCollection<Document> col;
    private MongoDBUpdater updater;
    private PropertyValue upsertCondition;
    private ExecutorService executorService = Executors.newSingleThreadExecutor();
    final BlockingQueue<Tuple<Record, Bson>> queue = new ArrayBlockingQueue<>(100000);

    @Override
    public List<PropertyDescriptor> getSupportedPropertyDescriptors() {
        List<PropertyDescriptor> descriptors = new ArrayList<>();
        descriptors.add(URI);
        descriptors.add(DATABASE_NAME);
        descriptors.add(COLLECTION_NAME);
        descriptors.add(BATCH_SIZE);
        descriptors.add(BULK_SIZE);
        descriptors.add(BULK_MODE);
        descriptors.add(FLUSH_INTERVAL);
        descriptors.add(WRITE_CONCERN);
        descriptors.add(UPSERT_CONDITION);
        return descriptors;
    }

    // public void init(ControllerServiceInitializationContext context) throws InitializationException {

    @Override
    @OnEnabled
    public void init(ControllerServiceInitializationContext context) throws InitializationException {
        super.init(context);
        try {
            this.createClient(context);
        } catch (IOException e) {
            throw new InitializationException(e);
        }
        this.db = this.mongoClient
                .getDatabase(context.getPropertyValue(MongoDBControllerService.DATABASE_NAME).asString());
        this.col = this.db
                .getCollection(context.getPropertyValue(MongoDBControllerService.COLLECTION_NAME).asString());
        if (updater != null) {
            return;
        }

        // setup a thread pool of solr updaters
        int batchSize = context.getPropertyValue(BATCH_SIZE).asInteger();
        long flushInterval = context.getPropertyValue(FLUSH_INTERVAL).asLong();
        String bulkMode = context.getPropertyValue(BULK_MODE).asString();
        updater = new MongoDBUpdater(db, col, queue, batchSize, flushInterval, bulkMode);
        upsertCondition = context.getPropertyValue(UPSERT_CONDITION);
        executorService.execute(updater);
    }

    @OnDisabled
    public void onDisable() {
        this.mongoClient.close();
    }

    @Override
    public long count(Document query) {
        return this.col.count(query);
    }

    @Override
    public void delete(Document query) {
        this.col.deleteMany(query);
    }

    @Override
    public boolean exists(Document query) {
        return this.col.count(query) > 0;
    }

    @Override
    public Document findOne(Document query) {
        MongoCursor<Document> cursor = this.col.find(query).limit(1).iterator();
        Document retVal = cursor.tryNext();
        cursor.close();

        return retVal;
    }

    @Override
    public Document findOne(Document query, Document projection) {
        MongoCursor<Document> cursor = projection != null
                ? this.col.find(query).projection(projection).limit(1).iterator()
                : this.col.find(query).limit(1).iterator();
        Document retVal = cursor.tryNext();
        cursor.close();

        return retVal;
    }

    @Override
    public List<Document> findMany(Document query) {
        return findMany(query, null, -1);
    }

    @Override
    public List<Document> findMany(Document query, int limit) {
        return findMany(query, null, limit);
    }

    @Override
    public List<Document> findMany(Document query, Document sort, int limit) {
        FindIterable<Document> fi = this.col.find(query);
        if (limit > 0) {
            fi = fi.limit(limit);
        }
        if (sort != null) {
            fi = fi.sort(sort);
        }
        MongoCursor<Document> cursor = fi.iterator();
        List<Document> retVal = new ArrayList<>();
        while (cursor.hasNext()) {
            retVal.add(cursor.next());
        }
        cursor.close();

        return retVal;
    }

    @Override
    public void insert(Document doc) {
        this.col.insertOne(doc);
    }

    @Override
    public void insert(List<Document> docs) {
        this.col.insertMany(docs);
    }

    @Override
    public void update(Document query, Document update, boolean multiple) {
        if (multiple) {
            this.col.updateMany(query, update);
        } else {
            this.col.updateOne(query, update);
        }
    }

    @Override
    public void update(Document query, Document update) {
        update(query, update, true);
    }

    @Override
    public void updateOne(Document query, Document update) {
        this.update(query, update, false);
    }

    @Override
    public void upsert(Document query, Document update) {
        this.col.updateOne(query, update, new UpdateOptions().upsert(true));
    }

    @Override
    public void dropDatabase() {
        this.db.drop();
        this.col = null;
    }

    @Override
    public void dropCollection() {
        this.col.drop();
        this.col = null;
    }

    @Override
    public MongoDatabase getDatabase(String name) {
        return mongoClient.getDatabase(name);
    }

    @Override
    public void createCollection(String name, int partitionsCount, int replicationFactor)
            throws DatastoreClientServiceException {

    }

    @Override
    public void dropCollection(String name) throws DatastoreClientServiceException {
        this.dropCollection();
    }

    @Override
    public long countCollection(String name) throws DatastoreClientServiceException {
        return this.count(new Document());
    }

    @Override
    public boolean existsCollection(String name) throws DatastoreClientServiceException {
        return this.col != null;
    }

    @Override
    public void refreshCollection(String name) throws DatastoreClientServiceException {
        getLogger().warn("not implemented for Mongo");
    }

    @Override
    public void copyCollection(String reindexScrollTimeout, String src, String dst)
            throws DatastoreClientServiceException {
        getLogger().warn("not implemented for Mongo");
    }

    @Override
    public void createAlias(String collection, String alias) throws DatastoreClientServiceException {
        getLogger().warn("not implemented for Mongo");
    }

    @Override
    public boolean putMapping(String indexName, String doctype, String mappingAsJsonString)
            throws DatastoreClientServiceException {
        getLogger().warn("not implemented for Mongo");
        return false;
    }

    @Override
    public void bulkFlush() throws DatastoreClientServiceException {
    }

    @Override
    public void bulkPut(String collectionName, Record record) throws DatastoreClientServiceException {
        if (record != null) {
            String cond = upsertCondition != null ? upsertCondition.evaluate(record).asString() : null;
            queue.add(new Tuple<>(record, cond != null ? BsonDocument.parse(cond) : null));

        }
    }

    @Override
    public void put(String collectionName, Record record, boolean asynchronous)
            throws DatastoreClientServiceException {
        this.insert(RecordConverter.convert(record));
    }

    @Override
    public void remove(String collectionName, Record record, boolean asynchronous)
            throws DatastoreClientServiceException {
        this.delete(RecordConverter.convert(record));
    }

    @Override
    public List<MultiGetResponseRecord> multiGet(List<MultiGetQueryRecord> multiGetQueryRecords)
            throws DatastoreClientServiceException {
        throw new UnsupportedOperationException("TODO multiGet");
    }

    @Override
    public Record get(String collectionName, Record record) throws DatastoreClientServiceException {
        return RecordConverter.convert(this.findOne(RecordConverter.convert(record)));
    }

    @Override
    public Collection<Record> query(String query) {
        throw new UnsupportedOperationException("TODO query");
    }

    @Override
    public long queryCount(String query) {
        throw new UnsupportedOperationException("TODO queryCount");
    }
}