/** * Copyright 2012 Comcast Corporation * * 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.comcast.cqs.persistence; import java.io.IOException; import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.io.Writer; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Random; import java.util.Set; import org.apache.log4j.Logger; import org.json.JSONException; import org.json.JSONObject; import org.json.JSONWriter; import com.comcast.cmb.common.persistence.AbstractDurablePersistence; import com.comcast.cmb.common.persistence.AbstractDurablePersistence.CMB_SERIALIZER; import com.comcast.cmb.common.persistence.AbstractDurablePersistence.CmbColumn; import com.comcast.cmb.common.persistence.AbstractDurablePersistence.CmbColumnSlice; import com.comcast.cmb.common.persistence.AbstractDurablePersistence.CmbComposite; import com.comcast.cmb.common.persistence.DurablePersistenceFactory; import com.comcast.cmb.common.util.CMBErrorCodes; import com.comcast.cmb.common.util.CMBException; import com.comcast.cmb.common.util.CMBProperties; import com.comcast.cmb.common.util.PersistenceException; import com.comcast.cqs.controller.CQSCache; import com.comcast.cqs.model.CQSMessage; import com.comcast.cqs.model.CQSMessageAttribute; import com.comcast.cqs.model.CQSQueue; import com.comcast.cqs.util.CQSConstants; import com.comcast.cqs.util.CQSErrorCodes; import com.comcast.cqs.util.RandomNumberCollection; import com.comcast.cqs.util.Util; import com.eaio.uuid.UUIDGen; /** * Cassandra persistence for CQS Message * @author aseem, vvenkatraman, bwolf * */ public class CQSMessagePartitionedCassandraPersistence implements ICQSMessagePersistence { private static final String COLUMN_FAMILY_PARTITIONED_QUEUE_MESSAGES = "CQSPartitionedQueueMessages"; private static final Random rand = new Random(); private static Logger logger = Logger.getLogger(CQSMessagePartitionedCassandraPersistence.class); private static final AbstractDurablePersistence cassandraHandler = DurablePersistenceFactory.getInstance(); public CQSMessagePartitionedCassandraPersistence() { } @Override public String sendMessage(CQSQueue queue, int shard, CQSMessage message) throws PersistenceException, IOException, InterruptedException, NoSuchAlgorithmException, JSONException { if (queue == null) { throw new PersistenceException(CQSErrorCodes.NonExistentQueue, "The supplied queue does not exist"); } if (message == null) { throw new PersistenceException(CQSErrorCodes.InvalidMessageContents, "The supplied message is invalid"); } int delaySeconds = 0; if (message.getAttributes().containsKey(CQSConstants.DELAY_SECONDS)) { delaySeconds = Integer.parseInt(message.getAttributes().get(CQSConstants.DELAY_SECONDS)); } long ts = System.currentTimeMillis() + delaySeconds*1000; CmbComposite columnName = cassandraHandler.getCmbComposite(AbstractDurablePersistence.newTime(ts, false), UUIDGen.getClockSeqAndNode()); int ttl = queue.getMsgRetentionPeriod(); int partition = rand.nextInt(queue.getNumberOfPartitions()); String key = Util.hashQueueUrl(queue.getRelativeUrl()) + "_" + shard + "_" + partition; if (queue.isCompressed()) { message.setBody(Util.compress(message.getBody())); } message.setMessageId(key + ":" + columnName.get(0) + ":" + columnName.get(1)); logger.debug("event=send_message ttl=" + ttl + " delay_sec=" + delaySeconds + " msg_id=" + message.getMessageId() + " key=" + key + " col=" + columnName); cassandraHandler.update(AbstractDurablePersistence.CQS_KEYSPACE, COLUMN_FAMILY_PARTITIONED_QUEUE_MESSAGES, key, columnName, getMessageJSON(message), CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.COMPOSITE_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER, ttl); return message.getMessageId(); } public List<CQSMessage> extractMessagesFromColumnSlice(String queueUrl, int length, CmbComposite previousHandle, CmbComposite nextHandle, CmbColumnSlice<CmbComposite, String> columnSlice, boolean ignoreFirstLastColumn) throws NoSuchAlgorithmException, IOException, JSONException, PersistenceException { List<CQSMessage> messageList = new ArrayList<CQSMessage>(); if (columnSlice != null && columnSlice.getColumns() != null) { boolean noMatch = true; for (CmbColumn<CmbComposite, String> column : columnSlice.getColumns()) { CmbComposite columnName = column.getName(); if (ignoreFirstLastColumn && (previousHandle != null && columnName.compareTo(previousHandle) == 0) || (nextHandle != null && columnName.compareTo(nextHandle) == 0)) { noMatch = false; continue; } else if (column.getValue() == null || column.getValue().length() == 0) { continue; } CQSMessage message = extractMessageFromJSON(queueUrl, column); messageList.add(message); } if (noMatch && messageList.size() > length) { messageList.remove(messageList.size() - 1); } } return messageList; } private CQSMessage extractMessageFromJSON(String queueUrl, CmbColumn column) throws JSONException, IOException, PersistenceException { CQSQueue queue = null; CQSMessage m = new CQSMessage(); try { queue = CQSCache.getCachedQueue(queueUrl); } catch (Exception ex) { throw new PersistenceException(ex); } if (queue == null) { throw new PersistenceException(CMBErrorCodes.InternalError, "Unknown queue " + queueUrl); } JSONObject json = new JSONObject((String)column.getValue()); m.setMessageId(json.getString("MessageId")); m.setReceiptHandle(json.getString("MessageId")); m.setMD5OfBody(json.getString("MD5OfBody")); m.setBody(json.getString("Body")); if (m.getAttributes() == null) { m.setAttributes(new HashMap<String, String>()); } if (json.has(CQSConstants.SENT_TIMESTAMP)) { m.getAttributes().put(CQSConstants.SENT_TIMESTAMP, json.getString(CQSConstants.SENT_TIMESTAMP)); } if (json.has(CQSConstants.APPROXIMATE_RECEIVE_COUNT)) { m.getAttributes().put(CQSConstants.APPROXIMATE_RECEIVE_COUNT, json.getString(CQSConstants.APPROXIMATE_RECEIVE_COUNT)); } if (json.has(CQSConstants.SENDER_ID)) { m.getAttributes().put(CQSConstants.SENDER_ID, json.getString(CQSConstants.SENDER_ID)); } if (json.has("MessageAttributes")) { m.setMD5OfMessageAttributes(json.getString("MD5OfMessageAttributes")); JSONObject messageAttributes = json.getJSONObject("MessageAttributes"); Map<String, CQSMessageAttribute> ma = new HashMap<String, CQSMessageAttribute>(); Iterator<String> iter = messageAttributes.keys(); while (iter.hasNext()) { String key = iter.next(); ma.put(key, new CQSMessageAttribute(messageAttributes.getJSONObject(key).getString("StringValue"), messageAttributes.getJSONObject(key).getString("DataType"))); } m.setMessageAttributes(ma); } m.setTimebasedId(column.getName()); if (queue.isCompressed()) { m.setBody(Util.decompress(m.getBody())); } return m; } private String getMessageJSON(CQSMessage message) throws JSONException { Writer writer = new StringWriter(); JSONWriter jw = new JSONWriter(writer); jw = jw.object(); jw.key("MessageId").value(message.getMessageId()); jw.key("MD5OfBody").value(message.getMD5OfBody()); jw.key("Body").value(message.getBody()); if (message.getAttributes() == null) { message.setAttributes(new HashMap<String, String>()); } if (!message.getAttributes().containsKey(CQSConstants.SENT_TIMESTAMP)) { message.getAttributes().put(CQSConstants.SENT_TIMESTAMP, "" + System.currentTimeMillis()); } if (!message.getAttributes().containsKey(CQSConstants.APPROXIMATE_RECEIVE_COUNT)) { message.getAttributes().put(CQSConstants.APPROXIMATE_RECEIVE_COUNT, "0"); } if (message.getAttributes() != null) { for (String key : message.getAttributes().keySet()) { String value = message.getAttributes().get(key); if (value == null || value.isEmpty()) { value = ""; } jw.key(key).value(value); } } if (message.getMessageAttributes() != null && message.getMessageAttributes().size() > 0) { jw.key("MD5OfMessageAttributes").value(message.getMD5OfMessageAttributes()); jw.key("MessageAttributes"); jw.object(); for (String key : message.getMessageAttributes().keySet()) { jw.key(key); jw.object(); CQSMessageAttribute messageAttribute = message.getMessageAttributes().get(key); if (messageAttribute.getStringValue() != null) { jw.key("StringValue").value(messageAttribute.getStringValue()); } else if (messageAttribute.getBinaryValue() != null) { jw.key("BinaryValue").value(messageAttribute.getBinaryValue()); } jw.key("DataType").value(messageAttribute.getDataType()); jw.endObject(); } jw.endObject(); } jw.endObject(); return writer.toString(); } @Override public Map<String, String> sendMessageBatch(CQSQueue queue, int shard, List<CQSMessage> messages) throws PersistenceException, IOException, InterruptedException, NoSuchAlgorithmException, JSONException { if (queue == null) { throw new PersistenceException(CQSErrorCodes.NonExistentQueue, "The supplied queue doesn't exist"); } if (messages == null || messages.size() == 0) { throw new PersistenceException(CQSErrorCodes.InvalidQueryParameter, "No messages are supplied."); } Map<CmbComposite, String> messageDataMap = new HashMap<CmbComposite, String>(); Map<String, String> ret = new HashMap<String, String>(); int ttl = queue.getMsgRetentionPeriod(); String key = Util.hashQueueUrl(queue.getRelativeUrl()) + "_" + shard + "_" + rand.nextInt(queue.getNumberOfPartitions()); for (CQSMessage message : messages) { if (message == null) { throw new PersistenceException(CQSErrorCodes.InvalidMessageContents, "The supplied message is invalid"); } if (queue.isCompressed()) { message.setBody(Util.compress(message.getBody())); } int delaySeconds = 0; if (message.getAttributes().containsKey(CQSConstants.DELAY_SECONDS)) { delaySeconds = Integer.parseInt(message.getAttributes().get(CQSConstants.DELAY_SECONDS)); } long ts = System.currentTimeMillis() + delaySeconds*1000; CmbComposite columnName = cassandraHandler.getCmbComposite(AbstractDurablePersistence.newTime(ts, false), UUIDGen.getClockSeqAndNode()); message.setMessageId(key + ":" + columnName.get(0) + ":" + columnName.get(1)); logger.debug("event=send_message_batch msg_id=" + message.getMessageId() + " ttl=" + ttl + " delay_sec=" + delaySeconds + " key=" + key + " col=" + columnName); String messageJson = getMessageJSON(message); messageDataMap.put(columnName, messageJson); ret.put(message.getSuppliedMessageId(), message.getMessageId()); } cassandraHandler.insertRow(AbstractDurablePersistence.CQS_KEYSPACE, key, COLUMN_FAMILY_PARTITIONED_QUEUE_MESSAGES, messageDataMap, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.COMPOSITE_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER, ttl); return ret; } @Override public void deleteMessage(String queueUrl, String receiptHandle) throws PersistenceException { if (receiptHandle == null) { logger.error("event=delete_message event=no_receipt_handle queue_url=" + queueUrl); return; } String[] receiptHandleParts = receiptHandle.split(":"); if (receiptHandleParts.length != 3) { logger.error("event=delete_message event=invalid_receipt_handle queue_url=" + queueUrl + " receipt_handle=" + receiptHandle); return; } CmbComposite columnName = cassandraHandler.getCmbComposite(Arrays.asList(Long.parseLong(receiptHandleParts[1]), Long.parseLong(receiptHandleParts[2]))); if (columnName != null) { logger.debug("event=delete_message receipt_handle=" + receiptHandle + " col=" + columnName + " key=" + receiptHandleParts[0]); cassandraHandler.delete(AbstractDurablePersistence.CQS_KEYSPACE, COLUMN_FAMILY_PARTITIONED_QUEUE_MESSAGES, receiptHandleParts[0], columnName, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.COMPOSITE_SERIALIZER); } } @Override public List<CQSMessage> receiveMessage(CQSQueue queue, Map<String, String> receiveAttributes) throws PersistenceException, IOException, NoSuchAlgorithmException, InterruptedException { throw new UnsupportedOperationException("ReceiveMessage is not supported, please call getMessages instead"); } @Override public boolean changeMessageVisibility(CQSQueue queue, String receiptHandle, int visibilityTO) throws PersistenceException, IOException, NoSuchAlgorithmException, InterruptedException { throw new UnsupportedOperationException("ChangeMessageVisibility is not supported"); } @Override public List<CQSMessage> peekQueue(String queueUrl, int shard, String previousReceiptHandle, String nextReceiptHandle, int length) throws IOException, NoSuchAlgorithmException, JSONException, PersistenceException { String queueHash = Util.hashQueueUrl(queueUrl); String key = queueHash + "_" + shard + "_0"; String handle = null; List<CQSMessage> messageList = new ArrayList<CQSMessage>(); CmbComposite previousHandle = null; CmbComposite nextHandle = null; int numberPartitions = getNumberOfPartitions(queueUrl); int numberShards = getNumberOfShards(queueUrl); logger.debug("event=peek_queue queue_url=" + queueUrl + " prev_receipt_handle=" + previousReceiptHandle + " next_receipt_handle=" + nextReceiptHandle + " length=" + length + " num_partitions=" + numberPartitions); if (previousReceiptHandle != null) { handle = previousReceiptHandle; String[] handleParts = handle.split(":"); if (handleParts.length != 3) { logger.error("event=peek_queue error_code=corrupt_receipt_handle receipt_handle=" + handle); throw new IllegalArgumentException("Corrupt receipt handle " + handle); } key = handleParts[0]; previousHandle = cassandraHandler.getCmbComposite(Arrays.asList(Long.parseLong(handleParts[1]), Long.parseLong(handleParts[2]))); } else if (nextReceiptHandle != null) { handle = nextReceiptHandle; String[] handleParts = handle.split(":"); if (handleParts.length != 3) { logger.error("action=peek_queue error_code=corrupt_receipt_handle receipt_handle=" + handle); throw new IllegalArgumentException("Corrupt receipt handle " + handle); } key = handleParts[0]; nextHandle = cassandraHandler.getCmbComposite(Arrays.asList(Long.parseLong(handleParts[1]), Long.parseLong(handleParts[2]))); } String[] queueParts = key.split("_"); if (queueParts.length != 3) { logger.error("event=peek_queue error_code=invalid_queue_key key=" + key); throw new IllegalArgumentException("Invalid queue key " + key); } int shardNumber = Integer.parseInt(queueParts[1]); int partitionNumber = Integer.parseInt(queueParts[2]); if (partitionNumber < 0 || partitionNumber > numberPartitions-1) { logger.error("event=peek_queue error_code=invalid_partition_number partition_number=" + partitionNumber); throw new IllegalArgumentException("Invalid queue partition number " + partitionNumber); } if (shardNumber < 0 || shardNumber > numberShards-1) { logger.error("event=peek_queue error_code=invalid_shard_number shard_number=" + shardNumber); throw new IllegalArgumentException("Invalid queue shard number " + shardNumber); } while (messageList.size() < length && -1 < partitionNumber && partitionNumber < numberPartitions) { key = queueHash + "_" + shardNumber + "_" + partitionNumber; CmbColumnSlice<CmbComposite, String> columnSlice = cassandraHandler.readColumnSlice( AbstractDurablePersistence.CQS_KEYSPACE, COLUMN_FAMILY_PARTITIONED_QUEUE_MESSAGES, key, previousHandle, nextHandle, length-messageList.size()+1, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.COMPOSITE_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER); messageList.addAll(extractMessagesFromColumnSlice(queueUrl, length-messageList.size(), previousHandle, nextHandle, columnSlice, true)); if (messageList.size() < length && -1 < partitionNumber && partitionNumber < numberPartitions) { if (previousHandle != null) { partitionNumber++; if (partitionNumber > -1) { previousHandle = cassandraHandler.getCmbComposite(Arrays.asList(AbstractDurablePersistence.newTime(System.currentTimeMillis()-1209600000, false), UUIDGen.getClockSeqAndNode())); } } else if (nextHandle != null) { partitionNumber--; if (partitionNumber < numberPartitions) { nextHandle = cassandraHandler.getCmbComposite(Arrays.asList(AbstractDurablePersistence.newTime(System.currentTimeMillis()+1209600000, false), UUIDGen.getClockSeqAndNode())); } } else { partitionNumber++; } } } return messageList; } @Override public void clearQueue(String queueUrl, int shard) throws PersistenceException, NoSuchAlgorithmException, UnsupportedEncodingException { int numberPartitions = getNumberOfPartitions(queueUrl); logger.debug("event=clear_queue queue_url=" + queueUrl + " num_partitions=" + numberPartitions); for (int i=0; i<numberPartitions; i++) { String key = Util.hashQueueUrl(queueUrl) + "_" + shard + "_" + i; //cassandraHandler.deleteSuperColumn(COLUMN_FAMILY_PARTITIONED_QUEUE_MESSAGES, key, null, CMB_SERIALIZER.STRING_SERIALIZER, CompositeSerializer.get()); cassandraHandler.delete(AbstractDurablePersistence.CQS_KEYSPACE, COLUMN_FAMILY_PARTITIONED_QUEUE_MESSAGES, key, null, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER); } } @Override public Map<String, CQSMessage> getMessages(String queueUrl, List<String> ids) throws NoSuchAlgorithmException, IOException, JSONException, PersistenceException { Map<String, CQSMessage> messageMap = new HashMap<String, CQSMessage>(); logger.debug("event=get_messages ids=" + ids); if (ids == null || ids.size() == 0) { return messageMap; } else if (ids.size() > 100) { return getMessagesBulk(queueUrl, ids); } for (String id: ids) { String[] idParts = id.split(":"); if (idParts.length != 3) { logger.error("event=get_messages error_code=invalid_message_id id=" + id); throw new IllegalArgumentException("Invalid message id " + id); } CmbComposite columnName = cassandraHandler.getCmbComposite(Arrays.asList(Long.parseLong(idParts[1]), Long.parseLong(idParts[2]))); CmbColumn<CmbComposite, String> column = cassandraHandler.readColumn(AbstractDurablePersistence.CQS_KEYSPACE, COLUMN_FAMILY_PARTITIONED_QUEUE_MESSAGES, idParts[0], columnName, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.COMPOSITE_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER); CQSMessage message = null; if (column != null) { message = extractMessageFromJSON(queueUrl, column); } messageMap.put(id, message); } return messageMap; } private Map<String, CQSMessage> getMessagesBulk(String queueUrl, List<String> ids) throws NoSuchAlgorithmException, IOException, JSONException, NumberFormatException, PersistenceException { logger.debug("event=get_message_bulk ids=" + ids); Map<String, CQSMessage> messageMap = new HashMap<String, CQSMessage>(); Set<String> messageIdSet = new HashSet<String>(); Map<String, Map<String, String>> firstLastIdsForEachPartition = getFirstAndLastIdsForEachPartition(ids, messageIdSet); if (firstLastIdsForEachPartition.size() == 0) { return messageMap; } for (String queuePartition: firstLastIdsForEachPartition.keySet()) { int messageCount = 200; Map<String, String> firstLastForPartition = firstLastIdsForEachPartition.get(queuePartition); String firstParts[] = firstLastForPartition.get("First").split(":"); String lastParts[] = firstLastForPartition.get("Last").split(":"); CmbColumnSlice<CmbComposite, String> columnSlice = cassandraHandler.readColumnSlice( AbstractDurablePersistence.CQS_KEYSPACE, COLUMN_FAMILY_PARTITIONED_QUEUE_MESSAGES, queuePartition, cassandraHandler.getCmbComposite(Arrays.asList(Long.parseLong(firstParts[0]), Long.parseLong(firstParts[1]))), cassandraHandler.getCmbComposite(Arrays.asList(Long.parseLong(lastParts[0]), Long.parseLong(lastParts[1]))), messageCount, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.COMPOSITE_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER); List<CQSMessage> messageList = extractMessagesFromColumnSlice(queueUrl, messageCount, null, null, columnSlice, false); for (CQSMessage message: messageList) { if (messageIdSet.contains(message.getMessageId())) { messageMap.put(message.getMessageId(), message); messageIdSet.remove(message.getMessageId()); } } } for (String messageId : messageIdSet) { messageMap.put(messageId, null); } return messageMap; } private Map<String, Map<String, String>> getFirstAndLastIdsForEachPartition(List<String> ids, Set<String> messageIdSet) { Map<String, Map<String, String>> firstLastForEachPartitionMap = new HashMap<String, Map<String, String>>(); if (ids == null || ids.size() == 0) { return firstLastForEachPartitionMap; } for (String id: ids) { messageIdSet.add(id); String[] idParts = id.split(":"); if (idParts.length != 3) { logger.error("action=get_messages_bulk error_code=corrupt_receipt_handle receipt_handle=" + id); throw new IllegalArgumentException("Corrupt receipt handle " + id); } String queuePartition = idParts[0]; final String messageId = idParts[1] + ":" + idParts[2]; if (!firstLastForEachPartitionMap.containsKey(queuePartition)) { firstLastForEachPartitionMap.put(queuePartition, new HashMap<String, String>() {{put("First", messageId); put("Last", messageId);}}); } else { Map<String, String> firstLastForPartition = firstLastForEachPartitionMap.get(queuePartition); if (firstLastForPartition.get("First").compareTo(messageId) > 0) { firstLastForPartition.put("First", messageId); } else if (firstLastForPartition.get("Last").compareTo(messageId) < 0) { firstLastForPartition.put("Last", messageId); } } } return firstLastForEachPartitionMap; } private int getNumberOfPartitions(String queueUrl) { int numberPartitions = CMBProperties.getInstance().getCQSNumberOfQueuePartitions(); try { CQSQueue queue = CQSCache.getCachedQueue(queueUrl); if (queue != null) { numberPartitions = queue.getNumberOfPartitions(); } } catch (Exception ex) { logger.warn("event=queue_cache_failure queue_url=" + queueUrl, ex); } return numberPartitions; } private int getNumberOfShards(String queueUrl) { int numberShards = 1; try { CQSQueue queue = CQSCache.getCachedQueue(queueUrl); if (queue != null) { numberShards = queue.getNumberOfShards(); } } catch (Exception ex) { logger.warn("event=queue_cache_failure queue_url=" + queueUrl, ex); } return numberShards; } @Override public List<CQSMessage> peekQueueRandom(String queueUrl, int shard, int length) throws IOException, NoSuchAlgorithmException, JSONException, PersistenceException { String queueHash = Util.hashQueueUrl(queueUrl); int numberPartitions = getNumberOfPartitions(queueUrl); logger.debug("event=peek_queue_random queue_url=" + queueUrl + " shard=" + shard + " queue_hash=" + queueHash + " num_partitions=" + numberPartitions); List<CQSMessage> messageList = new ArrayList<CQSMessage>(); if (length > numberPartitions) { // no randomness, get from all rows, subsequent calls will return the same result return peekQueue(queueUrl, shard, null, null, length); } else { // get from random set of rows // note: as a simplification we may return less messages than length if not all rows contain messages RandomNumberCollection rc = new RandomNumberCollection(numberPartitions); int numFound = 0; for (int i = 0; i < numberPartitions && numFound < length; i++) { int partition = rc.getNext(); String key = queueHash + "_" + shard + "_" + partition; CmbColumnSlice<CmbComposite, String> columnSlice = cassandraHandler.readColumnSlice( AbstractDurablePersistence.CQS_KEYSPACE, COLUMN_FAMILY_PARTITIONED_QUEUE_MESSAGES, key, null, null, 1, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.COMPOSITE_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER); List<CQSMessage> messages = extractMessagesFromColumnSlice(queueUrl, 1, null, null, columnSlice, false); numFound += messages.size(); messageList.addAll(messages); } return messageList; } } @Override public List<String> getIdsFromHead(String queueUrl, int shard, int num) throws PersistenceException { // TODO Auto-generated method stub return null; } @Override public long getQueueMessageCount(String queueUrl) { // TODO Auto-generated method stub return 0; } @Override public boolean checkCacheConsistency(String queueUrl, int shard, boolean trueOnFiller) { // TODO Auto-generated method stub return false; } @Override public long getQueueMessageCount(String queueUrl, boolean processHiddenIds) throws Exception { // TODO Auto-generated method stub return 0; } @Override public int getNumConnections() { // TODO Auto-generated method stub return 0; } @Override public long getCacheQueueMessageCount(String queueUrl) throws Exception { // TODO Auto-generated method stub return 0; } @Override public long getQueueNotVisibleMessageCount(String queueUrl, boolean visibilityProcessFlag) throws Exception { // TODO Auto-generated method stub return 0; } @Override public long getQueueDelayedMessageCount(String queueUrl, boolean visibilityProcessFlag) throws Exception { // TODO Auto-generated method stub return 0; } @Override public void flushAll() { // TODO Auto-generated method stub } @Override public boolean isAlive() { // TODO Auto-generated method stub return false; } @Override public int getNumberOfRedisShards() { // TODO Auto-generated method stub return 0; } @Override public void shutdown() { // TODO Auto-generated method stub } @Override public List<Map<String, String>> getInfo() { // TODO Auto-generated method stub return null; } @Override public long getMemQueueMessageCreatedTS(String memId) { // TODO Auto-generated method stub return 0; } }