org.apache.fluo.mini.MiniFluoImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.fluo.mini.MiniFluoImpl.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 org.apache.fluo.mini;

import java.io.File;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.collect.Iterables;
import com.google.common.util.concurrent.Uninterruptibles;
import org.apache.accumulo.core.client.Scanner;
import org.apache.accumulo.minicluster.MiniAccumuloCluster;
import org.apache.accumulo.minicluster.MiniAccumuloConfig;
import org.apache.fluo.api.client.FluoAdmin;
import org.apache.fluo.api.client.FluoAdmin.InitOpts;
import org.apache.fluo.api.client.FluoFactory;
import org.apache.fluo.api.config.FluoConfiguration;
import org.apache.fluo.api.config.SimpleConfiguration;
import org.apache.fluo.api.mini.MiniFluo;
import org.apache.fluo.core.client.FluoClientImpl;
import org.apache.fluo.core.impl.Environment;
import org.apache.fluo.core.impl.FluoConfigurationImpl;
import org.apache.fluo.core.impl.Notification;
import org.apache.fluo.core.oracle.OracleServer;
import org.apache.fluo.core.util.UtilWaitThread;
import org.apache.fluo.core.worker.NotificationFinder;
import org.apache.fluo.core.worker.NotificationFinderFactory;
import org.apache.fluo.core.worker.NotificationProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Implementation of MiniFluo
 */
public class MiniFluoImpl implements MiniFluo {

    private static final Logger log = LoggerFactory.getLogger(MiniFluoImpl.class);

    private static final AtomicInteger reporterCounter = new AtomicInteger(1);

    private final Environment env;
    private OracleServer oserver;

    private NotificationProcessor mnp;
    private NotificationFinder notificationFinder;
    private FluoConfiguration config;
    private MiniAccumuloCluster cluster = null;

    protected static String USER = "root";
    protected static String PASSWORD = "secret";

    private AutoCloseable reporter;

    public static String clientPropsPath(FluoConfiguration config) {
        return config.getMiniDataDir() + "/client.properties";
    }

    @VisibleForTesting
    public NotificationProcessor getNotificationProcessor() {
        return mnp;
    }

    public MiniFluoImpl(FluoConfiguration fluoConfig) {
        if (!fluoConfig.hasRequiredMiniFluoProps()) {
            throw new IllegalArgumentException("MiniFluo configuration is not valid");
        }
        config = fluoConfig;

        try {
            if (config.getMiniStartAccumulo()) {
                startMiniAccumulo();
            }

            config.setProperty(FluoConfigurationImpl.MIN_SLEEP_TIME_PROP, 50);
            config.setProperty(FluoConfigurationImpl.MAX_SLEEP_TIME_PROP, 100);

            env = new Environment(config);

            reporter = FluoClientImpl.setupReporters(env, "mini", reporterCounter);

            oserver = new OracleServer(env);
            oserver.start();

            mnp = new NotificationProcessor(env);
            notificationFinder = NotificationFinderFactory.newNotificationFinder(env.getConfiguration());
            notificationFinder.init(env, mnp);
            notificationFinder.start();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private void startMiniAccumulo() {
        try {
            // start mini accumulo cluster
            MiniAccumuloConfig cfg = new MiniAccumuloConfig(new File(config.getMiniDataDir()), PASSWORD);
            cluster = new MiniAccumuloCluster(cfg);
            cluster.start();

            log.debug("Started MiniAccumulo(accumulo=" + cluster.getInstanceName() + " zk="
                    + cluster.getZooKeepers() + ")");

            // configuration that must overridden
            config.setAccumuloInstance(cluster.getInstanceName());
            config.setAccumuloUser(USER);
            config.setAccumuloPassword(PASSWORD);
            config.setAccumuloZookeepers(cluster.getZooKeepers());
            config.setInstanceZookeepers(cluster.getZooKeepers() + "/fluo");

            // configuration that only needs to be set if not by user
            if ((config.containsKey(FluoConfiguration.ADMIN_ACCUMULO_TABLE_PROP) == false)
                    || config.getAccumuloTable().trim().isEmpty()) {
                config.setAccumuloTable("fluo");
            }

            InitOpts opts = new InitOpts();
            try (FluoAdmin admin = FluoFactory.newAdmin(config)) {
                admin.initialize(opts);
            }

            File miniProps = new File(clientPropsPath(config));
            config.getClientConfiguration().save(miniProps);

            log.debug("Wrote MiniFluo client properties to {}", miniProps.getAbsolutePath());

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public SimpleConfiguration getClientConfiguration() {
        return config.getClientConfiguration();
    }

    @Override
    public void close() {
        try {
            if (oserver != null) {
                notificationFinder.stop();
                mnp.close();
                oserver.stop();
                env.close();
                reporter.close();
                if (cluster != null) {
                    cluster.stop();
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void waitForObservers() {
        try {
            Scanner scanner = env.getConnector().createScanner(env.getTable(), env.getAuthorizations());
            Notification.configureScanner(scanner);

            while (true) {
                long ts1 = env.getSharedResources().getOracleClient().getStamp().getTxTimestamp();
                long ntfyCount = Iterables.size(scanner);
                long ts2 = env.getSharedResources().getOracleClient().getStamp().getTxTimestamp();
                if (ntfyCount == 0 && ts1 == (ts2 - 1)) {
                    break;
                }

                long sleepTime = ntfyCount / 2;
                sleepTime = Math.min(Math.max(10, sleepTime), 10000);
                Uninterruptibles.sleepUninterruptibly(sleepTime, TimeUnit.MILLISECONDS);
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {

        try {
            if (args.length != 1) {
                System.err.println("Usage: MiniFluoImpl <fluoPropsPath>");
                System.exit(-1);
            }
            String propsPath = args[0];
            Objects.requireNonNull(propsPath);
            File propsFile = new File(propsPath);
            if (!propsFile.exists()) {
                System.err.println("ERROR - Fluo properties file does not exist: " + propsPath);
                System.exit(-1);
            }
            Preconditions.checkArgument(propsFile.exists());

            FluoConfiguration config = new FluoConfiguration(propsFile);
            if (!config.hasRequiredMiniFluoProps()) {
                log.error("Failed to start MiniFluo - fluo.properties is missing required properties for "
                        + "MiniFluo");
                System.exit(-1);
            }
            try (MiniFluo mini = new MiniFluoImpl(config)) {
                log.info("MiniFluo is running");

                while (true) {
                    UtilWaitThread.sleep(1000);
                }
            }
        } catch (Exception e) {
            log.error("Exception running MiniFluo: ", e);
        }

        log.info("MiniFluo is exiting.");
    }
}