/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.usergrid.persistence.qakka.serialization.transferlog.impl;
import com.datastax.driver.core.PagingState;
import com.datastax.driver.core.ResultSet;
import com.datastax.driver.core.Row;
import com.datastax.driver.core.Statement;
import com.datastax.driver.core.querybuilder.QueryBuilder;
import com.google.inject.Inject;
import org.apache.usergrid.persistence.core.CassandraConfig;
import org.apache.usergrid.persistence.core.astyanax.MultiTenantColumnFamilyDefinition;
import org.apache.usergrid.persistence.core.datastax.TableDefinition;
import org.apache.usergrid.persistence.core.datastax.impl.TableDefinitionStringImpl;
import org.apache.usergrid.persistence.qakka.core.CassandraClient;
import org.apache.usergrid.persistence.qakka.exceptions.QakkaException;
import org.apache.usergrid.persistence.qakka.serialization.Result;
import org.apache.usergrid.persistence.qakka.serialization.transferlog.TransferLog;
import org.apache.usergrid.persistence.qakka.serialization.transferlog.TransferLogSerialization;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
public class TransferLogSerializationImpl implements TransferLogSerialization {
private static final Logger logger = LoggerFactory.getLogger( TransferLogSerializationImpl.class );
private final CassandraClient cassandraClient;
private final CassandraConfig cassandraConfig;
public final static String TABLE_TRANSFER_LOG = "transfer_log";
public final static String COLUMN_QUEUE_NAME = "queue_name";
public final static String COLUMN_SOURCE_REGION = "source_region";
public final static String COLUMN_DEST_REGION = "dest_region";
public final static String COLUMN_MESSAGE_ID = "message_id";
public final static String COLUMN_TRANSFER_TIME = "transfer_time";
static final String CQL =
"CREATE TABLE IF NOT EXISTS transfer_log ( " +
"queue_name text, " +
"source_region text, " +
"dest_region text, " +
"message_id timeuuid, " +
"transfer_time bigint, " +
"PRIMARY KEY ((queue_name, dest_region, message_id)) " +
"); ";
@Inject
public TransferLogSerializationImpl( CassandraConfig cassandraConfig, CassandraClient cassandraClient ) {
this.cassandraConfig = cassandraConfig;
this.cassandraClient = cassandraClient;
}
@Override
public void recordTransferLog(
String queueName, String source, String dest, UUID messageId) {
Statement insert = QueryBuilder.insertInto(TABLE_TRANSFER_LOG)
.value(COLUMN_QUEUE_NAME, queueName )
.value(COLUMN_SOURCE_REGION, source )
.value(COLUMN_DEST_REGION, dest )
.value(COLUMN_MESSAGE_ID, messageId )
.value(COLUMN_TRANSFER_TIME, System.currentTimeMillis() );
cassandraClient.getApplicationSession().execute(insert);
// logger.debug("Recorded transfer log for queue {} dest {} messageId {}",
// queueName, dest, messageId);
}
@Override
public void removeTransferLog(
String queueName, String source, String dest, UUID messageId ) throws QakkaException {
Statement query = QueryBuilder.select().all().from(TABLE_TRANSFER_LOG)
.where( QueryBuilder.eq( COLUMN_QUEUE_NAME, queueName ))
.and( QueryBuilder.eq( COLUMN_DEST_REGION, dest ))
.and( QueryBuilder.eq( COLUMN_MESSAGE_ID, messageId ));
ResultSet rs = cassandraClient.getApplicationSession().execute( query );
if ( rs.getAvailableWithoutFetching() == 0 ) {
StringBuilder sb = new StringBuilder();
sb.append( "Transfer log entry not found for queueName=" ).append( queueName );
sb.append( " dest=" ).append( dest );
sb.append( " messageId=" ).append( messageId );
throw new QakkaException( sb.toString() );
}
Statement deleteQuery = QueryBuilder.delete().from(TABLE_TRANSFER_LOG)
.where( QueryBuilder.eq( COLUMN_QUEUE_NAME, queueName ))
.and( QueryBuilder.eq( COLUMN_DEST_REGION, dest ))
.and( QueryBuilder.eq( COLUMN_MESSAGE_ID, messageId ));
cassandraClient.getApplicationSession().execute( deleteQuery );
}
@Override
public Result<TransferLog> getAllTransferLogs(PagingState pagingState, int fetchSize ) {
Statement query = QueryBuilder.select().all().from(TABLE_TRANSFER_LOG);
query.setFetchSize( fetchSize );
if ( pagingState != null ) {
query.setPagingState( pagingState );
}
ResultSet rs = cassandraClient.getApplicationSession().execute( query );
final PagingState newPagingState = rs.getExecutionInfo().getPagingState();
final List<TransferLog> transferLogs = new ArrayList<>();
int numReturned = rs.getAvailableWithoutFetching();
for ( int i=0; i<numReturned; i++ ) {
Row row = rs.one();
TransferLog tlog = new TransferLog(
row.getString( COLUMN_QUEUE_NAME ),
row.getString( COLUMN_SOURCE_REGION ),
row.getString( COLUMN_DEST_REGION ),
row.getUUID( COLUMN_MESSAGE_ID ),
row.getLong( COLUMN_TRANSFER_TIME ));
transferLogs.add( tlog );
}
return new Result<TransferLog>() {
@Override
public PagingState getPagingState() {
return newPagingState;
}
@Override
public List<TransferLog> getEntities() {
return transferLogs;
}
};
}
@Override
public Collection<MultiTenantColumnFamilyDefinition> getColumnFamilies() {
return Collections.EMPTY_LIST;
}
@Override
public Collection<TableDefinition> getTables() {
return Collections.singletonList(
new TableDefinitionStringImpl( cassandraConfig.getApplicationKeyspace(), TABLE_TRANSFER_LOG, CQL ) );
}
}