/* * Copyright 2014-2016 CyberVision, 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 org.kaaproject.kaa.server.common.nosql.cassandra.dao; import com.datastax.driver.core.BatchStatement; import com.datastax.driver.core.ConsistencyLevel; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Session; import com.datastax.driver.core.Statement; import com.datastax.driver.core.UserType; import com.datastax.driver.core.querybuilder.QueryBuilder; import com.datastax.driver.mapping.Mapper; import com.datastax.driver.mapping.Result; import org.kaaproject.kaa.server.common.nosql.cassandra.dao.client.CassandraClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import java.util.Arrays; import java.util.Collections; import java.util.List; public abstract class AbstractCassandraDao<T, K> { private static final Logger LOG = LoggerFactory.getLogger(AbstractCassandraDao.class); private static final String KAA = "kaa"; /** * Cassandra client classes. */ @Autowired protected CassandraClient cassandraClient; @Value("#{cassandra_properties[read_consistency_level]}") private String readConsistencyLevel; @Value("#{cassandra_properties[write_consistency_level]}") private String writeConsistencyLevel; @Value("#{cassandra_properties[batch_type]}") private String batchType; private Session session; protected abstract Class<T> getColumnFamilyClass(); protected abstract String getColumnFamilyName(); protected Session getSession() { if (session == null) { session = cassandraClient.getSession(); } return session; } protected Mapper<T> getMapper(Class<T> clazz) { return cassandraClient.getMapper(clazz); } protected Mapper<T> getMapper() { return cassandraClient.getMapper(getColumnFamilyClass()); } protected List<T> findListByStatement(Statement statement) { List<T> list = Collections.emptyList(); if (statement != null) { statement.setConsistencyLevel(getReadConsistencyLevel()); ResultSet resultSet = getSession().execute(statement); Result<T> result = getMapper().map(resultSet); if (result != null) { list = result.all(); } } return list; } protected UserType getUserType(String userType) { return getSession().getCluster().getMetadata().getKeyspace(KAA).getUserType(userType); } protected T findOneByStatement(Statement statement) { T object = null; if (statement != null) { statement.setConsistencyLevel(getReadConsistencyLevel()); ResultSet resultSet = getSession().execute(statement); Result<T> result = getMapper().map(resultSet); if (result != null) { object = result.one(); } } return object; } protected Statement getSaveQuery(T dto) { Mapper<T> mapper = (Mapper<T>) getMapper(getColumnFamilyClass()); return mapper.saveQuery(dto); } /** * Save entity in cassandra database. * * @param object is entity for saving * @return saved entity */ public T save(T object) { LOG.debug("Save entity {}", object); Statement saveStatement = getSaveQuery(object); saveStatement.setConsistencyLevel(getWriteConsistencyLevel()); execute(saveStatement); return object; } protected void executeBatch(BatchStatement batch) { LOG.debug("Execute cassandra batch {}", batch); batch.setConsistencyLevel(getWriteConsistencyLevel()); ResultSet resultSet = getSession().execute(batch); LOG.debug("Executed batch {}", resultSet); } protected void executeBatch(Statement... statements) { LOG.debug("Execute cassandra list of statements"); if (LOG.isDebugEnabled()) { LOG.debug("Execute cassandra statements {} ", Arrays.toString(statements)); } BatchStatement batchStatement = new BatchStatement(getBatchType()); for (Statement statement : statements) { batchStatement.add(statement); } executeBatch(batchStatement); } protected ResultSet execute(Statement statement, ConsistencyLevel consistencyLevel) { LOG.debug("Execute cassandra statement {}", statement); statement.setConsistencyLevel( consistencyLevel == null ? ConsistencyLevel.ONE : consistencyLevel); return getSession().execute(statement); } protected ResultSet execute(Statement statement) { return execute(statement, statement.getConsistencyLevel()); } /** * Get all entities from cassandra database. * @return <code>List</code> of entities */ public List<T> find() { LOG.debug("Get all entities from column family {}", getColumnFamilyName()); return findListByStatement( QueryBuilder.select() .all().from(getColumnFamilyName()) .setConsistencyLevel(getReadConsistencyLevel())); } public T findById(K key) { LOG.debug("Get entity by key {}", key); return (T) getMapper().get(key); } /** * Remove all entities from cassandra database. */ public void removeAll() { Statement truncate = QueryBuilder.truncate(getColumnFamilyName()) .setConsistencyLevel(getWriteConsistencyLevel()); session.execute(truncate); } public void removeById(K key) { getMapper().delete(key); } protected ConsistencyLevel getReadConsistencyLevel() { ConsistencyLevel defaultConsistencyLevel = ConsistencyLevel.ONE; if (readConsistencyLevel != null) { ConsistencyLevel cl = ConsistencyLevel.valueOf(readConsistencyLevel); if (cl != null) { defaultConsistencyLevel = cl; } } return defaultConsistencyLevel; } protected ConsistencyLevel getWriteConsistencyLevel() { ConsistencyLevel defaultConsistencyLevel = ConsistencyLevel.ONE; if (writeConsistencyLevel != null) { ConsistencyLevel cl = ConsistencyLevel.valueOf(writeConsistencyLevel); if (cl != null) { defaultConsistencyLevel = cl; } } return defaultConsistencyLevel; } protected BatchStatement.Type getBatchType() { BatchStatement.Type type = BatchStatement.Type.LOGGED; if (batchType != null && BatchStatement.Type.UNLOGGED.name().equalsIgnoreCase(batchType)) { type = BatchStatement.Type.UNLOGGED; } return type; } }