com.eucalyptus.portal.awsusage.CassandraSessionManager.java Source code

Java tutorial

Introduction

Here is the source code for com.eucalyptus.portal.awsusage.CassandraSessionManager.java

Source

/*************************************************************************
 * (c) Copyright 2017 Hewlett Packard Enterprise Development Company LP
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 3 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see http://www.gnu.org/licenses/.
 ************************************************************************/
package com.eucalyptus.portal.awsusage;

import com.datastax.driver.core.Cluster;
import com.datastax.driver.core.Session;
import com.eucalyptus.cassandra.common.CassandraComponent;
import com.eucalyptus.cassandra.common.CassandraKeyspaceSpecification;
import com.eucalyptus.cassandra.common.CassandraPersistence;
import com.eucalyptus.cassandra.common.util.CqlUtil;
import com.eucalyptus.configurable.ConfigurableClass;
import com.eucalyptus.configurable.ConfigurableField;
import com.eucalyptus.configurable.ConfigurableProperty;
import com.eucalyptus.configurable.ConfigurablePropertyException;
import com.eucalyptus.configurable.PropertyChangeListener;
import com.eucalyptus.util.Exceptions;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import com.google.common.io.Resources;
import org.apache.log4j.Logger;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.util.List;
import java.util.function.Function;

/**
 * Created by ethomas on 11/22/16.
 */
@CassandraKeyspaceSpecification("eucalyptus_billing")
@ConfigurableClass(root = "services.billing", description = "Parameters controlling billing service")
public class CassandraSessionManager implements CassandraComponent {
    // TODO: this is a temporary class and needs to be replaced once the cassandra framework is committed to master.
    private static final Logger LOG = Logger.getLogger(CassandraSessionManager.class);
    @ConfigurableField(initial = "postgres", description = "The db to use")
    public static volatile String DB_TO_USE = "postgres";
    @ConfigurableField(initial = "127.0.0.1", description = "The host for cassandra", changeListener = CassandraSessionManager.ChangeListener.class)
    public static volatile String CASSANDRA_HOST = "127.0.0.1";
    private static Cluster cluster = null;
    private static Session session = null;

    private static synchronized void initCluster() {
        initCluster(CassandraSessionManager.CASSANDRA_HOST);
    }

    private static synchronized void initCluster(String contactPoint) {
        if (session != null) {
            session.close();
            session = null;
        }
        if (cluster != null) {
            cluster.close();
            cluster = null;
        }
        LOG.info("Trying to connect to the cluster " + contactPoint);
        List<String> contactPoints = Lists.newArrayList();
        for (String s : Splitter.on(",").omitEmptyStrings().split(contactPoint)) {
            contactPoints.add(s);
        }
        cluster = Cluster.builder().addContactPoints(contactPoints.toArray(new String[0])).build();
        session = cluster.connect();

        // create new keyspace/tables (should not do here)  TODO: move
        session.execute("CREATE KEYSPACE IF NOT EXISTS eucalyptus_billing "
                + "WITH replication = {'class':'SimpleStrategy', 'replication_factor':1}; ");

        session.execute("USE eucalyptus_billing;");

        try {
            final String cql = Resources.toString(Resources.getResource("2017-03-28-eucalyptus-billing-base.cql"),
                    StandardCharsets.UTF_8);
            CqlUtil.splitCql(cql).forEach(session::execute);
        } catch (final IOException | ParseException e) {
            throw Exceptions.toUndeclared(e);
        }
    }

    private static synchronized Session getSession() {
        if (session == null) {
            initCluster();
        }
        return session;
    }

    /**
     * Perform work using a datastax session in a callback.
     */
    public static <R> R doWithSession(final Function<? super Session, ? extends R> callbackFunction) {
        if ("cassandra".equals(DB_TO_USE)) {
            return callbackFunction.apply(getSession());
        } else {
            return CassandraPersistence.doWithSession("eucalyptus_billing", callbackFunction);
        }
    };

    public static class ChangeListener implements PropertyChangeListener {
        @Override
        public void fireChange(ConfigurableProperty t, Object newValue) throws ConfigurablePropertyException {
            try {
                initCluster((String) newValue);
            } catch (Exception e) {
                throw new ConfigurablePropertyException(e.getMessage());
            }
        }
    }
}