@Override public QueueSet getSubscriptions( String subscriberQueuePath, String firstSubscriptionQueuePath, int limit) { UUID subscriberQueueId = getQueueId(subscriberQueuePath); Keyspace ko = cass.getApplicationKeyspace(applicationId); if (firstSubscriptionQueuePath != null) { limit += 1; } List<HColumn<String, UUID>> columns = createSliceQuery(ko, ue, se, ue) .setKey(subscriberQueueId) .setColumnFamily(QUEUE_SUBSCRIPTIONS.getColumnFamily()) .setRange(normalizeQueuePath(firstSubscriptionQueuePath), null, false, limit + 1) .execute() .get() .getColumns(); QueueSet queues = new QueueSet(); int count = Math.min(limit, columns.size()); if (columns != null) { for (int i = firstSubscriptionQueuePath != null ? 1 : 0; i < count; i++) { HColumn<String, UUID> column = columns.get(i); queues.addQueue(column.getName(), column.getValue()); } } if (columns.size() > limit) { queues.setMore(true); } return queues; }
public void batchUpdateQueuePropertiesIndexes( Mutator<ByteBuffer> batch, String subscriberQueuePath, UUID subscriberQueueId, Map<String, Object> properties, UUID timestampUuid) throws Exception { QueueSet subscriptions = getSubscriptions(subscriberQueuePath, null, ALL_COUNT); if (subscriptions != null) { for (Map.Entry<String, Object> property : properties.entrySet()) { if (!Queue.QUEUE_PROPERTIES.containsKey(property.getKey())) { QueueIndexUpdate indexUpdate = batchStartQueueIndexUpdate( batch, subscriberQueuePath, subscriberQueueId, property.getKey(), property.getValue(), timestampUuid); for (QueueInfo subscription : subscriptions.getQueues()) { batchUpdateQueueIndex(indexUpdate, subscription.getUuid()); } } } } }
@Override public QueueSet unsubscribeFromQueues( String subscriberQueuePath, List<String> publisherQueuePaths) { subscriberQueuePath = normalizeQueuePath(subscriberQueuePath); UUID subscriberQueueId = getQueueId(subscriberQueuePath); UUID timestampUuid = newTimeUUID(); long timestamp = getTimestampInMicros(timestampUuid); Mutator<ByteBuffer> batch = createMutator(cass.getApplicationKeyspace(applicationId), be); QueueSet queues = new QueueSet(); for (String publisherQueuePath : publisherQueuePaths) { publisherQueuePath = normalizeQueuePath(publisherQueuePath); UUID publisherQueueId = getQueueId(publisherQueuePath); batchUnsubscribeFromQueue( batch, publisherQueuePath, publisherQueueId, subscriberQueuePath, subscriberQueueId, timestamp); try { Queue queue = getQueue(subscriberQueuePath, subscriberQueueId); batchUpdateQueuePropertiesIndexes( batch, publisherQueueId, subscriberQueuePath, subscriberQueueId, emptyMapWithKeys(queue.getProperties()), timestampUuid); } catch (Exception e) { logger.error("Unable to update index", e); } queues.addQueue(publisherQueuePath, publisherQueueId); } batchExecute(batch, RETRY_COUNT); return queues; }
public QueueSet searchQueueIndex(UUID publisherQueueId, QuerySlice slice, int count) throws Exception { ByteBuffer start = null; if (slice.getCursor() != null) { start = slice.getCursor(); } else if (slice.getStart() != null) { DynamicComposite s = new DynamicComposite(slice.getStart().getCode(), slice.getStart().getValue()); if (!slice.getStart().isInclusive()) { setEqualityFlag(s, ComponentEquality.GREATER_THAN_EQUAL); } start = s.serialize(); } ByteBuffer finish = null; if (slice.getFinish() != null) { DynamicComposite f = new DynamicComposite(slice.getFinish().getCode(), slice.getFinish().getValue()); if (slice.getFinish().isInclusive()) { setEqualityFlag(f, ComponentEquality.GREATER_THAN_EQUAL); } finish = f.serialize(); } if (slice.isReversed() && (start != null) && (finish != null)) { ByteBuffer temp = start; start = finish; finish = temp; } List<HColumn<ByteBuffer, ByteBuffer>> results = createSliceQuery(cass.getApplicationKeyspace(applicationId), be, be, be) .setColumnFamily(PROPERTY_INDEX.getColumnFamily()) .setKey(bytebuffer(key(publisherQueueId, slice.getPropertyName()))) .setRange(start, finish, slice.isReversed(), count) .execute() .get() .getColumns(); QueueSet queues = new QueueSet(); for (HColumn<ByteBuffer, ByteBuffer> column : results) { DynamicComposite c = DynamicComposite.fromByteBuffer(column.getName()); queues.addQueue(c.get(3, se), c.get(2, ue)); } return queues; }
@Override public Message postToQueue(String queuePath, Message message) { long timestamp = cass.createTimestamp(); Mutator<ByteBuffer> batch = createMutator(cass.getApplicationKeyspace(applicationId), be); queuePath = normalizeQueuePath(queuePath); MessageIndexUpdate indexUpdate = new MessageIndexUpdate(message); batchPostToQueue(batch, queuePath, message, indexUpdate, timestamp); batchExecute(batch, RETRY_COUNT); String firstSubscriberQueuePath = null; while (true) { QueueSet subscribers = getSubscribers(queuePath, firstSubscriberQueuePath, 1000); if (subscribers.getQueues().isEmpty()) { break; } batch = createMutator(cass.getApplicationKeyspace(applicationId), be); for (QueueInfo q : subscribers.getQueues()) { batchPostToQueue(batch, q.getPath(), message, indexUpdate, timestamp); firstSubscriberQueuePath = q.getPath(); } batchExecute(batch, RETRY_COUNT); if (!subscribers.hasMore()) { break; } } return message; }
@Override public QueueSet searchSubscribers(String publisherQueuePath, Query query) { if (query == null) { query = new Query(); } publisherQueuePath = normalizeQueuePath(publisherQueuePath); UUID publisherQueueId = getQueueId(publisherQueuePath); if (!query.hasFilterPredicates() && !query.hasSortPredicates()) { return getSubscribers(publisherQueuePath, null, query.getLimit()); } QueueSet results = null; String composite_cursor = null; QueryProcessor qp = new QueryProcessor(query); List<QuerySlice> slices = qp.getSlices(); int search_count = query.getLimit() + 1; if (slices.size() > 1) { search_count = DEFAULT_SEARCH_COUNT; } for (QuerySlice slice : slices) { QueueSet r = null; try { r = searchQueueIndex(publisherQueueId, slice, search_count); } catch (Exception e) { logger.error("Error during search", e); } if (r == null) { continue; } if (r.size() > query.getLimit()) { r.setCursorToLastResult(); } if (r.getCursor() != null) { if (composite_cursor != null) { composite_cursor += "|"; } else { composite_cursor = ""; } int hashCode = slice.hashCode(); logger.info("Cursor hash code: {} ", hashCode); composite_cursor += hashCode + ":" + r.getCursor(); } if (results != null) { results.and(r); } else { results = r; } } return results; }