/* * RHQ Management Platform * Copyright (C) 2005-2013 Red Hat, Inc. * All rights reserved. * * 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 2 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ package org.rhq.server.metrics; import static org.testng.Assert.fail; import java.util.List; import java.util.concurrent.CountDownLatch; import com.datastax.driver.core.BoundStatement; import com.datastax.driver.core.Cluster; import com.datastax.driver.core.Host; import com.datastax.driver.core.HostDistance; import com.datastax.driver.core.PoolingOptions; import com.datastax.driver.core.PreparedStatement; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Session; import com.google.common.base.Throwables; import com.google.common.util.concurrent.FutureCallback; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.joda.time.DateTime; import org.testng.annotations.AfterSuite; import org.testng.annotations.BeforeSuite; import org.testng.annotations.Listeners; import org.rhq.cassandra.CCMTestNGListener; import org.rhq.cassandra.DeployCluster; import org.rhq.cassandra.ShutdownCluster; import org.rhq.cassandra.util.ClusterBuilder; import org.rhq.server.metrics.domain.AggregateNumericMetric; import org.rhq.server.metrics.domain.AggregateNumericMetricMapper; import org.rhq.server.metrics.domain.Bucket; import org.rhq.server.metrics.domain.MetricsTable; import org.rhq.server.metrics.domain.NumericMetric; import org.rhq.server.metrics.domain.ResultSetMapper; import org.rhq.server.metrics.domain.SimplePagedResult; /** * @author John Sanda */ @Listeners({CCMTestNGListener.class}) public class CassandraIntegrationTest { private static final String RHQADMIN = "rhqadmin"; private static final String RHQADMIN_PASSWORD = "1eeb2f255e832171df8592078de921bc"; protected static Session session; protected static StorageSession storageSession; protected static DateTimeService dateTimeService; private final Log log = LogFactory.getLog(CassandraIntegrationTest.class); @BeforeSuite @DeployCluster(numNodes = 1, username = RHQADMIN, password = RHQADMIN_PASSWORD, waitForSchemaAgreement = true) public void deployCluster() throws Exception { dateTimeService = new DateTimeService(); Cluster cluster = new ClusterBuilder() .addContactPoints("127.0.0.1") .withCredentialsObfuscated(RHQADMIN, RHQADMIN_PASSWORD) .build(); PoolingOptions poolingOptions = cluster.getConfiguration().getPoolingOptions(); poolingOptions.setCoreConnectionsPerHost(HostDistance.LOCAL, 24); poolingOptions.setCoreConnectionsPerHost(HostDistance.REMOTE, 24); poolingOptions.setMaxConnectionsPerHost(HostDistance.LOCAL, 32); poolingOptions.setMaxConnectionsPerHost(HostDistance.REMOTE, 32); cluster.register(new Host.StateListener() { @Override public void onAdd(Host host) { log.info("host " + host + " added"); } @Override public void onUp(Host host) { log.info("host " + host + " up"); } @Override public void onDown(Host host) { log.info("host " + host + " down"); } @Override public void onRemove(Host host) { log.info("host " + host + " removed"); } }); session = cluster.connect("rhq"); storageSession = new StorageSession(session); } @AfterSuite(alwaysRun = true) @ShutdownCluster public void shutdownCluster() throws Exception { } protected DateTime hour0() { return dateTimeService.hour0(); } protected DateTime hour(int hours) { return dateTimeService.hour0().plusHours(hours); } protected Iterable<AggregateNumericMetric> findAggregateMetrics(Bucket bucket, int scheduleId) { String cql = "SELECT schedule_id, time, type, value " + "FROM " + MetricsTable.AGGREGATE + " " + "WHERE schedule_id = ? AND bucket = ? " + "ORDER BY time, type"; PreparedStatement statement = session.prepare(cql); BoundStatement boundStatement = statement.bind(scheduleId, bucket.toString()); return new SimplePagedResult<AggregateNumericMetric>(boundStatement, new AggregateNumericMetricMapper(), storageSession); } protected static class WaitForRead<T extends NumericMetric> implements FutureCallback<ResultSet> { private final Log log = LogFactory.getLog(WaitForRead.class); private CountDownLatch latch; private Throwable throwable; private ResultSetMapper<T> mapper; private List<T> results; public WaitForRead(ResultSetMapper<T> mapper) { latch = new CountDownLatch(1); this.mapper = mapper; } @Override public void onSuccess(ResultSet rows) { try { results = mapper.mapAll(rows); } catch (Exception e) { throwable = e; log.error("There was an error getting the results", e); } finally { latch.countDown(); } } @Override public void onFailure(Throwable throwable) { this.throwable = throwable; log.error("An async operation failed", throwable); latch.countDown(); } public void await(String errorMsg) throws InterruptedException { latch.await(); if (throwable != null) { fail(errorMsg, Throwables.getRootCause(throwable)); } } public List<T> getResults() { return results; } } }