org.jberet.support.io.MongoItemReaderTest.java Source code

Java tutorial

Introduction

Here is the source code for org.jberet.support.io.MongoItemReaderTest.java

Source

/*
 * Copyright (c) 2014 Red Hat, Inc. and/or its affiliates.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 * Cheng Fang - Initial API and implementation
 */

package org.jberet.support.io;

import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import javax.batch.operations.JobOperator;
import javax.batch.runtime.BatchRuntime;
import javax.batch.runtime.BatchStatus;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.MappingJsonFactory;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.Mongo;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientURI;
import com.mongodb.util.JSON;
import org.jberet.runtime.JobExecutionImpl;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

/**
 * A test class that reads resource from MongoDB and writes to another MongoDB collection.
 */
public final class MongoItemReaderTest {
    static MongoClient mongoClient;
    static DB db;
    static final String jobName = "org.jberet.support.io.MongoItemReaderTest";
    private final JobOperator jobOperator = BatchRuntime.getJobOperator();

    static final String databaseName = "testData";
    static final String mongoClientUri = "mongodb://localhost/" + databaseName;
    static final String movieCollection = "movies";
    static final String movieOutCollection = "movies.out";
    static final String githubDataCollection = "githubData";
    static final String githubDataOutCollection = "githubData.out";

    @BeforeClass
    public static void beforeClass() throws Exception {
        mongoClient = (MongoClient) Mongo.Holder.singleton().connect(new MongoClientURI(mongoClientUri));
        db = mongoClient.getDB(databaseName);
    }

    @Before
    public void before() throws Exception {
        dropCollection(movieOutCollection);
        addTestData(JsonItemReaderTest.movieJson, movieCollection, 100);
    }

    @Test
    public void testMongoGithubData() throws Exception {
        dropCollection(githubDataOutCollection);
        addTestData(JsonItemReaderTest.githubJson, githubDataCollection, 5);
        testReadWrite0(mongoClientUri, null, null, -1, GithubData.class, "{_id : 0}", githubDataCollection,
                githubDataOutCollection, null, null);
    }

    @Test
    public void testMongoMovieBeanTypeLimit2() throws Exception {
        testReadWrite0(mongoClientUri, null, "2", 2, Movie.class, null, movieCollection, movieOutCollection,
                MovieTest.expect1_2, MovieTest.forbid1_2);
    }

    @Test
    public void testMongoMovieBeanTypeLimit3Skip1() throws Exception {
        testReadWrite0(null, "1", "3", 3, Movie.class, null, movieCollection, movieOutCollection,
                MovieTest.expect2_4, MovieTest.forbid2_4);
    }

    @Test
    public void testMongoMovieBeanTypeFull() throws Exception {
        testReadWrite0(null, null, null, 100, Movie.class, null, movieCollection, movieOutCollection,
                MovieTest.expectFull, null);
    }

    private void testReadWrite0(final String uri, final String skip, final String limit, final int size,
            final Class<?> beanType, final String projection, final String collection, final String collectionOut,
            final String expect, final String forbid) throws Exception {
        final Properties params = CsvItemReaderWriterTest.createParams(CsvProperties.BEAN_TYPE_KEY,
                beanType.getName());
        params.setProperty("collection", collection);
        params.setProperty("collection.out", collectionOut);
        if (uri != null) {
            params.setProperty("uri", uri);
        }
        if (projection != null) {
            params.setProperty("projection", projection);
        }
        if (skip != null) {
            params.setProperty("skip", skip);
        }
        if (limit != null) {
            params.setProperty("limit", limit);
        }

        final long jobExecutionId = jobOperator.start(jobName, params);
        final JobExecutionImpl jobExecution = (JobExecutionImpl) jobOperator.getJobExecution(jobExecutionId);
        jobExecution.awaitTermination(CsvItemReaderWriterTest.waitTimeoutMinutes, TimeUnit.MINUTES);
        Assert.assertEquals(BatchStatus.COMPLETED, jobExecution.getBatchStatus());

        validate(size, expect, forbid);
    }

    static void dropCollection(final String coll) throws Exception {
        final DBCollection collection = db.getCollection(coll);
        collection.drop();
    }

    static void addTestData(final String dataResource, final String mongoCollection, final int minSizeIfExists)
            throws Exception {
        final DBCollection collection = db.getCollection(mongoCollection);
        if (collection.find().count() >= minSizeIfExists) {
            System.out.printf("The readCollection %s already contains 100 items, skip adding test data.%n",
                    mongoCollection);
            return;
        }

        InputStream inputStream = MongoItemReaderTest.class.getClassLoader().getResourceAsStream(dataResource);
        if (inputStream == null) {
            try {
                final URL url = new URI(dataResource).toURL();
                inputStream = url.openStream();
            } catch (final Exception e) {
                System.out.printf("Failed to convert dataResource %s to URL: %s%n", dataResource, e);
            }
        }
        if (inputStream == null) {
            throw new IllegalStateException("The inputStream for the test data is null");
        }

        final JsonFactory jsonFactory = new MappingJsonFactory();
        final JsonParser parser = jsonFactory.createParser(inputStream);
        final JsonNode arrayNode = parser.readValueAs(ArrayNode.class);

        final Iterator<JsonNode> elements = arrayNode.elements();
        final List<DBObject> dbObjects = new ArrayList<DBObject>();
        while (elements.hasNext()) {
            final DBObject dbObject = (DBObject) JSON.parse(elements.next().toString());
            dbObjects.add(dbObject);
        }
        collection.insert(dbObjects);
    }

    static void validate(final int size, final String expect, final String forbid) {
        final DBCollection collection = db.getCollection(movieOutCollection);
        final DBCursor cursor = collection.find();

        try {
            //if size is negative number, it means the size is unknown and so skip the size check.
            if (size >= 0) {
                Assert.assertEquals(size, cursor.size());
            }
            final List<String> expects = new ArrayList<String>();
            String[] forbids = CellProcessorConfig.EMPTY_STRING_ARRAY;
            if (expect != null && !expect.isEmpty()) {
                Collections.addAll(expects, expect.split(","));
            }
            if (forbid != null && !forbid.isEmpty()) {
                forbids = forbid.split(",");
            }
            if (expects.size() == 0 && forbids.length == 0) {
                return;
            }
            while (cursor.hasNext()) {
                final DBObject next = cursor.next();
                final String stringValue = next.toString();
                for (final String s : forbids) {
                    if (stringValue.contains(s.trim())) {
                        throw new IllegalStateException("Forbidden string found: " + s);
                    }
                }
                for (final Iterator<String> it = expects.iterator(); it.hasNext();) {
                    final String s = it.next();
                    if (stringValue.contains(s.trim())) {
                        System.out.printf("Found expected string: %s%n", s);
                        it.remove();
                    }
                }
            }
            if (expects.size() > 0) {
                throw new IllegalStateException("Some expected strings are still not found: " + expects);
            }
        } finally {
            cursor.close();
        }
    }
}