com.dell.doradus.service.db.DBService Maven / Gradle / Ivy
The newest version!
/*
* Copyright (C) 2014 Dell, Inc.
*
* Licensed 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 com.dell.doradus.service.db;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import com.dell.doradus.common.UserDefinition;
import com.dell.doradus.common.Utils;
import com.dell.doradus.core.ServerConfig;
import com.dell.doradus.service.Service;
import com.dell.doradus.service.db.cql.CQLService;
import com.dell.doradus.service.db.thrift.ThriftService;
/**
* Provides methods that access the physical database. This is currently Cassandra but
* could be other physical stores. Database configuration options (host, port, keyspace,
* etc.) are defined in doradus.yaml and loaded via {@link ServerConfig}.
*/
public abstract class DBService extends Service {
// Choose service based on doradus.yaml setting
private static final DBService INSTANCE = selectService();
private static DBService selectService() {
String dbServiceName = ServerConfig.getInstance().dbservice;
if (!Utils.isEmpty(dbServiceName)) {
try {
@SuppressWarnings("unchecked")
Class serviceClass = (Class) Class.forName(dbServiceName);
Method instanceMethod = serviceClass.getMethod("instance", (Class>[])null);
DBService instance = (DBService)instanceMethod.invoke(null, (Object[])null);
return instance;
} catch (Exception e) {
throw new RuntimeException("Error initializing DBService: " + dbServiceName, e);
}
} else if (ServerConfig.getInstance().use_cql) {
return CQLService.instance();
} else {
return ThriftService.instance();
}
}
// Only subclasses can construct an object.
protected DBService() {
// Give up to 1 second after start() to allow startService() to succeed
m_startDelayMillis = 1000;
}
/**
* Get the singleton instance of this service. The service may or may not have been
* initialized yet.
*
* @return The singleton instance of this service.
*/
public static DBService instance() {
return INSTANCE;
} // instance
//----- Public Service methods
// Implemented by subclasses
//----- Public DBService methods: Tenant management
/**
* Create a new tenant with the given options.
*
* @param tenant {@link Tenant} that defines new tenant.
* @param options Optional map of options for new tenant.
*/
public abstract void createTenant(Tenant tenant, Map options);
/**
* Modify the given tenant with the given options.
*
* @param tenant {@link Tenant} to be modified.
* @param options Map of options to apply to tenant.
*/
public abstract void modifyTenant(Tenant tenant, Map options);
/**
* Drop the given tenant.
*
* @param tenant {@link Tenant} to drop.
*/
public abstract void dropTenant(Tenant tenant);
/**
* Add the given list of users to the database with the defined permissions for the
* given tenant.
*
* @param tenant {@link Tenant} to add users for.
* @param users List of {@link UserDefinition} to add.
*/
public abstract void addUsers(Tenant tenant, Iterable users);
/**
* Modify the given list of users to for the given tenant. Currently, only passwords
* can be modified.
*
* @param tenant {@link Tenant} whose users are to be modified.
* @param users List of {@link UserDefinition} to modify.
*/
public abstract void modifyUsers(Tenant tenant, Iterable users);
/**
* Delete the given list of users for the given tenant.
*
* @param tenant {@link Tenant} to delete users for.
* @param users List of {@link UserDefinition} to delete.
*/
public abstract void deleteUsers(Tenant tenant, Iterable users);
/**
* Get a list of all known {@link Tenant}s.
*
* @return Map of tenants to application names.
*/
public abstract Collection getTenants();
//----- Public DBService methods: Store management
/**
* Create a new store in the given tenant. Columns hold string or binary values as
* requested. If the given store already exists, this is a no-op.
*
* @param tenant {@link Tenant} that holds new store.
* @param storeName Name of new store to create.
* @param bBinaryValues True to ensure that new store holds binary values. False means
* columns hold string values.
*/
public abstract void createStoreIfAbsent(Tenant tenant, String storeName, boolean bBinaryValues);
/**
* Delete the store with the given name belonging to the given tenant. If the store
* does not exist, this is a no-op.
*
* @param tenant Tenant that owns store.
* @param storeName Name of store to delete.
*/
public abstract void deleteStoreIfPresent(Tenant tenant, String storeName);
//----- Public DBService methods: Updates
/**
* Create a new {@link DBTransaction} object that holds updates for stores in the
* given tenant that will be committed together. The transactions can be committed by
* calling {@link #commit(DBTransaction)}.
*
* @param tenant {@link Tenant} in which updates will be made.
* @return New {@link DBTransaction}.
*/
public abstract DBTransaction startTransaction(Tenant tenant);
/**
* Commit the updates in the given {@link DBTransaction}. An exception is thrown if
* the updates cannot be committed after all retries. Regardless of whether the
* updates are successful or not, the updates are cleared from the transaction object
* before returning.
*
* @param dbTran {@link DBTransaction} containing updates to commit.
*/
public abstract void commit(DBTransaction dbTran);
//----- Public DBService methods: Queries
/**
* Get all columns for the row with the given key in the given store. Columns are
* returned as an Iterator of {@link DColumn}s. If no row is found with the given key,
* the iterator's hasNext() will be false.
*
* @param tenant {@link Tenant} that owns the store.
* @param storeName Name of store to query.
* @param rowKey Key of row to fetch.
* @return Iterator of {@link DColumn}s. If there is no such row, hasNext()
* will be false.
*/
public abstract Iterator getAllColumns(Tenant tenant,
String storeName,
String rowKey);
/**
* Get columns for the row with the given key in the given store. Columns range
* is defined by an interval [startCol, endCol]. Columns are returned
* as an Iterator of {@link DColumn}s. Empty iterator is returned if no row
* is found with the given key or no columns in the given interval found.
*
* @param tenant {@link Tenant} that owns the store.
* @param storeName Name of store to query.
* @param rowKey Key of row to fetch.
* @param startCol First name in the column names interval.
* @param endCol Last name in the column names interval.
* @param reversed Flag: reverse iteration?
* @return Iterator of {@link DColumn}s. If there is no such row, the
* iterator's hasNext() will be false.
*/
public abstract Iterator getColumnSlice(Tenant tenant, String storeName,
String rowKey, String startCol, String endCol, boolean reversed);
/**
* Get columns for the row with the given key in the given store. Columns range
* is defined by an interval [startCol, endCol]. Columns are returned
* as an Iterator of {@link DColumn}s. Empty iterator is returned if no row
* is found with the given key or no columns in the given interval found.
*
* @param tenant {@link Tenant} that owns the store.
* @param storeName Name of store to query.
* @param rowKey Key of row to fetch.
* @param startCol First name in the column names interval.
* @param endCol Last name in the column names interval.
* @return Iterator of {@link DColumn}s. If there is no such row, the
* iterator's hasNext() will be false.
*/
public abstract Iterator getColumnSlice(Tenant tenant, String storeName,
String rowKey, String startCol, String endCol);
/**
* Get all rows of all columns in the given store. The results are returned as an
* Iterator for {@link DRow} objects. If no rows are found, the iterator's hasNext()
* method will immediately return false. If more rows are fetched than an internal
* limit allows, an exception is thrown.
*
* @param tenant {@link Tenant} that owns the store.
* @param storeName Name of physical store to query.
* @return Iterator of {@link DRow} objects. May be empty but not null.
*/
public abstract Iterator getAllRowsAllColumns(Tenant tenant, String storeName);
/**
* Get a single column for a single row in the given store. If the given row or column
* is not found, null is returned. Otherwise, a {@link DColumn} containing the column
* name and value is returned.
*
* @param tenant {@link Tenant} that owns the store.
* @param storeName Name of store to query.
* @param rowKey Key of row to read.
* @param colName Name of column to fetch.
* @return {@link DColumn} containing the column name and value or null if
* the row or column was not found.
*/
public abstract DColumn getColumn(Tenant tenant, String storeName, String rowKey, String colName);
/**
* Get all columns for rows with a specific set of keys. Results are returned as an
* Iterator of {@link DRow} objects. If any given row is not found, no entry will
* with its key will be returned.
*
* @param tenant {@link Tenant} that owns the store.
* @param storeName Name of store to query.
* @param rowKeys Collection of row keys to read.
* @return Iterator of {@link DRow} objects. May be empty but not null.
*/
public abstract Iterator getRowsAllColumns(Tenant tenant, String storeName,
Collection rowKeys);
/**
* Get a specific set of columns for a specific set of rows. Results are returned as an
* Iterator of {@link DRow} objects. If any given row is not found, no entry will exist
* for it in iterator. If a row is found but none of the requested columns were found,
* DRow object's column iterator will be empty.
*
* @param tenant {@link Tenant} that owns the store.
* @param storeName Name of store to query.
* @param rowKeys Collection of row keys to read.
* @param colNames Collection of column names to read.
* @return Iterator for {@link DRow} objects. May be empty but not null.
*/
public abstract Iterator getRowsColumns(Tenant tenant, String storeName,
Collection rowKeys, Collection colNames);
/**
* Get a range of columns for a specific set of rows. Results are returned as an
* Iterator of {@link DRow} objects. If any given row is not found, no entry will exist
* for it in iterator. If a row is found but no columns were found in the requested
* range, DRow object's column iterator will be empty.
*
* @param tenant {@link Tenant} that owns the store.
* @param storeName Name of store to query.
* @param rowKeys Collection of row keys to read.
* @param startCol Column names >= this name are returned.
* @param endCol Column names <= this name are returned.
* @return Iterator for {@link DRow} objects. May be empty but not null.
*/
public abstract Iterator getRowsColumnSlice(Tenant tenant, String storeName,
Collection rowKeys, String startCol, String endCol);
//----- Protected methods
/**
* Throw a DBNotAvailableException if we're not running yet.
*/
protected void checkState() {
if (!getState().isRunning()) {
throw new DBNotAvailableException("Cassandra connection has not been established");
}
} // checkState
} // class DBService
© 2015 - 2025 Weber Informatics LLC | Privacy Policy