gobblin.cluster.GobblinHelixJobLauncherTest.java Source code

Java tutorial

Introduction

Here is the source code for gobblin.cluster.GobblinHelixJobLauncherTest.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 gobblin.cluster;

import gobblin.metastore.DatasetStateStore;
import gobblin.util.ClassAliasResolver;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.List;
import java.util.Properties;

import org.apache.avro.Schema;
import org.apache.curator.test.TestingServer;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.helix.HelixManager;
import org.apache.helix.HelixManagerFactory;
import org.apache.helix.InstanceType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.io.Closer;
import com.typesafe.config.Config;
import com.typesafe.config.ConfigFactory;
import com.typesafe.config.ConfigValueFactory;

import gobblin.configuration.ConfigurationKeys;
import gobblin.configuration.WorkUnitState;
import gobblin.metrics.Tag;
import gobblin.runtime.FsDatasetStateStore;
import gobblin.runtime.JobException;
import gobblin.runtime.JobState;
import gobblin.util.ConfigUtils;

/**
 * Unit tests for {@link GobblinHelixJobLauncher}.
 *
 * <p>
 *   This class uses a {@link TestingServer} as an embedded ZooKeeper server for testing. This class
 *   also uses the {@link HelixManager} to act as a testing Helix controller to be passed into the
 *   {@link GobblinHelixJobLauncher} instance. A {@link GobblinTaskRunner} is also used to run
 *   the single task of the test job. A {@link FsDatasetStateStore} is used to check the state store
 *   after the job is done. The test job writes everything to the local file system as returned by
 *   {@link FileSystem#getLocal(Configuration)}.
 * </p>
 *
 * @author Yinan Li
 */
@Test(groups = { "gobblin.cluster" })
public class GobblinHelixJobLauncherTest {
    public final static Logger LOG = LoggerFactory.getLogger(GobblinHelixJobLauncherTest.class);

    private HelixManager helixManager;

    private FileSystem localFs;

    private Path appWorkDir;

    private String jobName;

    private File jobOutputFile;

    private GobblinHelixJobLauncher gobblinHelixJobLauncher;

    private GobblinTaskRunner gobblinTaskRunner;

    private DatasetStateStore datasetStateStore;

    private Thread thread;

    private final Closer closer = Closer.create();

    @BeforeClass
    public void setUp() throws Exception {
        TestingServer testingZKServer = this.closer.register(new TestingServer(-1));
        LOG.info("Testing ZK Server listening on: " + testingZKServer.getConnectString());

        URL url = GobblinHelixJobLauncherTest.class.getClassLoader()
                .getResource(GobblinHelixJobLauncherTest.class.getSimpleName() + ".conf");
        Assert.assertNotNull(url, "Could not find resource " + url);

        Config config = ConfigFactory.parseURL(url).withValue("gobblin.cluster.zk.connection.string",
                ConfigValueFactory.fromAnyRef(testingZKServer.getConnectString())).resolve();

        String zkConnectingString = config.getString(GobblinClusterConfigurationKeys.ZK_CONNECTION_STRING_KEY);
        String helixClusterName = config.getString(GobblinClusterConfigurationKeys.HELIX_CLUSTER_NAME_KEY);

        HelixUtils.createGobblinHelixCluster(zkConnectingString, helixClusterName);

        this.helixManager = HelixManagerFactory.getZKHelixManager(helixClusterName,
                TestHelper.TEST_HELIX_INSTANCE_NAME, InstanceType.CONTROLLER, zkConnectingString);
        this.closer.register(new Closeable() {
            @Override
            public void close() throws IOException {
                helixManager.disconnect();
            }
        });
        this.helixManager.connect();

        Properties properties = ConfigUtils.configToProperties(config);

        this.localFs = FileSystem.getLocal(new Configuration());

        this.appWorkDir = new Path(GobblinHelixJobLauncherTest.class.getSimpleName());
        this.closer.register(new Closeable() {
            @Override
            public void close() throws IOException {
                if (localFs.exists(appWorkDir)) {
                    localFs.delete(appWorkDir, true);
                }
            }
        });

        this.jobName = config.getString(ConfigurationKeys.JOB_NAME_KEY);

        this.jobOutputFile = new File(config.getString(ConfigurationKeys.DATA_PUBLISHER_FINAL_DIR),
                config.getString(ConfigurationKeys.WRITER_FILE_PATH) + File.separator
                        + config.getString(ConfigurationKeys.WRITER_FILE_NAME));

        // Prepare the source Json file
        File sourceJsonFile = new File(this.appWorkDir.toString(), TestHelper.TEST_JOB_NAME + ".json");
        TestHelper.createSourceJsonFile(sourceJsonFile);
        properties.setProperty(ConfigurationKeys.SOURCE_FILEBASED_FILES_TO_PULL, sourceJsonFile.getAbsolutePath());

        this.gobblinHelixJobLauncher = this.closer.register(new GobblinHelixJobLauncher(properties,
                this.helixManager, this.appWorkDir, ImmutableList.<Tag<?>>of()));

        this.gobblinTaskRunner = new GobblinTaskRunner(TestHelper.TEST_APPLICATION_NAME,
                TestHelper.TEST_HELIX_INSTANCE_NAME, TestHelper.TEST_APPLICATION_ID, TestHelper.TEST_TASK_RUNNER_ID,
                config, Optional.of(appWorkDir));

        String stateStoreType = properties.getProperty(ConfigurationKeys.STATE_STORE_TYPE_KEY,
                ConfigurationKeys.DEFAULT_STATE_STORE_TYPE);

        ClassAliasResolver<DatasetStateStore.Factory> resolver = new ClassAliasResolver<>(
                DatasetStateStore.Factory.class);

        DatasetStateStore.Factory stateStoreFactory = resolver.resolveClass(stateStoreType).newInstance();

        this.datasetStateStore = stateStoreFactory.createStateStore(config);

        this.thread = new Thread(new Runnable() {
            @Override
            public void run() {
                gobblinTaskRunner.start();
            }
        });
        this.thread.start();
    }

    public void testLaunchJob() throws JobException, IOException {
        this.gobblinHelixJobLauncher.launchJob(null);

        Assert.assertTrue(this.jobOutputFile.exists());

        Schema schema = new Schema.Parser().parse(TestHelper.SOURCE_SCHEMA);
        TestHelper.assertGenericRecords(this.jobOutputFile, schema);

        List<JobState.DatasetState> datasetStates = this.datasetStateStore.getAll(this.jobName,
                FsDatasetStateStore.CURRENT_DATASET_STATE_FILE_SUFFIX
                        + FsDatasetStateStore.DATASET_STATE_STORE_TABLE_SUFFIX);
        Assert.assertEquals(datasetStates.size(), 1);
        JobState.DatasetState datasetState = datasetStates.get(0);
        Assert.assertEquals(datasetState.getCompletedTasks(), 1);
        Assert.assertEquals(datasetState.getState(), JobState.RunningState.COMMITTED);

        Assert.assertEquals(datasetState.getTaskStates().size(), 1);
        Assert.assertEquals(datasetState.getTaskStates().get(0).getWorkingState(),
                WorkUnitState.WorkingState.COMMITTED);
    }

    @AfterClass
    public void tearDown() throws IOException {
        try {
            this.gobblinTaskRunner.stop();
            this.thread.join();
        } catch (InterruptedException ie) {
            Thread.currentThread().interrupt();
        } finally {
            this.closer.close();
        }
    }
}