/*
*
* * RHQ Management Platform
* * Copyright (C) 2005-2012 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, version 2, as
* * published by the Free Software Foundation, and/or the GNU Lesser
* * General Public License, version 2.1, also as published by the Free
* * Software Foundation.
* *
* * 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 and the GNU Lesser General Public License
* * for more details.
* *
* * You should have received a copy of the GNU General Public License
* * and the GNU Lesser 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.plugins.cassandra.util;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.mc4j.ems.connection.EmsConnection;
import org.mc4j.ems.connection.bean.EmsBean;
import org.mc4j.ems.connection.bean.attribute.EmsAttribute;
import org.mc4j.ems.connection.bean.operation.EmsOperation;
/**
* @author John Sanda
*/
public class KeyspaceService {
public static final String STORAGE_SERVICE_BEAN = "org.apache.cassandra.db:type=StorageService";
public static final String REPAIR_OPERATION = "forceTableRepair";
public static final String REPAIR_PRIMARY_RANGE = "forceTableRepairPrimaryRange";
public static final String CLEANUP_OPERATION = "forceTableCleanup";
public static final String COMPACT_OPERATION = "forceTableCompaction";
public static final String SNAPSHOT_OPERATION = "takeSnapshot";
public static final String CF_SNAPSHOT_OPERATION = "takeColumnFamilySnapshot";
private EmsConnection emsConnection;
public KeyspaceService(EmsConnection emsConnection) {
this.emsConnection = emsConnection;
}
public void repair(String keyspace, String... columnFamilies) {
EmsBean emsBean = loadBean(STORAGE_SERVICE_BEAN);
EmsOperation operation = emsBean.getOperation(REPAIR_OPERATION, String.class, boolean.class,
boolean.class, String[].class);
// The isSequential param has to be false; otherwise, repair will fail as a result
// of https://issues.apache.org/jira/browse/CASSANDRA-5512.
boolean isSequential = false; // perform sequential repair using snapshot
boolean isLocal = true; // local to data center
operation.invoke(keyspace, isSequential, isLocal, columnFamilies);
}
public void repairPrimaryRange(String keyspace, String... columnFamilies) {
EmsBean emsBean = loadBean(KeyspaceService.STORAGE_SERVICE_BEAN);
EmsOperation operation = emsBean.getOperation(REPAIR_PRIMARY_RANGE, String.class, boolean.class, boolean.class,
String[].class);
// The isSequential param has to be false; otherwise, repair will fail as a result
// of https://issues.apache.org/jira/browse/CASSANDRA-5512.
boolean isSequential = false; // perform sequential repair using snapshot
boolean isLocal = true; // local to data center
operation.invoke(keyspace, isSequential, isLocal, columnFamilies);
}
public void cleanup(String keyspace) {
EmsBean emsBean = loadBean(STORAGE_SERVICE_BEAN);
EmsOperation operation = emsBean.getOperation(CLEANUP_OPERATION, String.class, String[].class);
operation.invoke(keyspace, new String[] {});
}
public void compact(String keyspace, String... columnFamilies) {
EmsBean emsBean = loadBean(STORAGE_SERVICE_BEAN);
EmsOperation operation = emsBean.getOperation(COMPACT_OPERATION, String.class, String[].class);
operation.invoke(keyspace, columnFamilies);
}
public void takeSnapshot(String keyspace, String snapshotName) {
takeSnapshot(new String[]{keyspace}, snapshotName);
}
public void takeSnapshot(String[] keySpaces, String snapshotName) {
EmsBean emsBean = loadBean(STORAGE_SERVICE_BEAN);
EmsOperation operation = emsBean.getOperation(SNAPSHOT_OPERATION, String.class, String[].class);
operation.invoke(snapshotName, keySpaces);
}
public String[] getKeySpaceDataFileLocations() {
EmsBean emsBean = loadBean(KeyspaceService.STORAGE_SERVICE_BEAN);
EmsAttribute attribute = emsBean.getAttribute("AllDataFileLocations");
return (String[]) attribute.getValue();
}
@SuppressWarnings("unchecked")
public List<Object> getKeyspaces() {
List<Object> value = null;
EmsBean emsBean = loadBean(STORAGE_SERVICE_BEAN);
if (emsBean != null) {
EmsAttribute attribute = emsBean.getAttribute("Keyspaces");
if (attribute != null) {
value = (List<Object>) attribute.refresh();
}
}
if (value == null) {
value = new ArrayList<Object>();
}
return value;
}
public List<String> getColumnFamilyDirs() {
List<EmsBean> beans = emsConnection.queryBeans("org.apache.cassandra.db:type=ColumnFamilies,*");
List<String> dirs = new ArrayList<String>(beans.size());
for (EmsBean bean : beans) {
String keySpace = bean.getBeanName().getKeyProperty("keyspace");
String colFamily = bean.getBeanName().getKeyProperty("columnfamily");
dirs.add(keySpace + File.separator + colFamily);
}
return dirs;
}
private EmsBean loadBean(String objectName) {
EmsBean bean = emsConnection.getBean(objectName);
if (bean == null) {
// In some cases, this resource component may have been discovered by some means other than querying its
// parent's EMSConnection (e.g. ApplicationDiscoveryComponent uses a filesystem to discover EARs and
// WARs that are not yet deployed). In such cases, getBean() will return null, since EMS won't have the
// bean in its cache. To cover such cases, make an attempt to query the underlying MBeanServer for the
// bean before giving up.
emsConnection.queryBeans(objectName);
bean = emsConnection.getBean(objectName);
}
return bean;
}
}