@Override public CNSSubscription confirmSubscription( boolean authenticateOnUnsubscribe, String token, String topicArn) throws Exception { // get Sub-arn given token CmbColumnSlice<String, String> slice = cassandraHandler.readColumnSlice( AbstractDurablePersistence.CNS_KEYSPACE, columnFamilySubscriptionsTokenIndex, token, null, null, 1, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER); if (slice == null) { throw new CMBException(CMBErrorCodes.NotFound, "Resource not found."); } // get Column from main table String subArn = slice.getColumns().get(0).getName(); // get Subscription given subArn final CNSSubscription s = getSubscription(subArn); if (s == null) { throw new SubscriberNotFoundException( "Could not find subscription given subscription arn " + subArn); } s.setAuthenticateOnUnsubscribe(authenticateOnUnsubscribe); s.setConfirmed(true); s.setConfirmDate(new Date()); // re-insert with no TTL. will clobber the old one which had ttl insertOrUpdateSubsAndIndexes(s, null); cassandraHandler.decrementCounter( AbstractDurablePersistence.CNS_KEYSPACE, columnFamilyTopicStats, s.getTopicArn(), "subscriptionPending", 1, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER); cassandraHandler.incrementCounter( AbstractDurablePersistence.CNS_KEYSPACE, columnFamilyTopicStats, s.getTopicArn(), "subscriptionConfirmed", 1, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER); return s; }
@Override public void unsubscribe(String arn) throws Exception { CNSSubscription s = getSubscription(arn); if (s != null) { deleteIndexes(arn, s.getUserId(), s.getToken()); CmbComposite columnName = cassandraHandler.getCmbComposite(s.getEndpoint(), s.getProtocol().name()); cassandraHandler.delete( AbstractDurablePersistence.CNS_KEYSPACE, columnFamilySubscriptions, Util.getCnsTopicArn(arn), columnName, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.COMPOSITE_SERIALIZER); if (s.isConfirmed()) { cassandraHandler.decrementCounter( AbstractDurablePersistence.CNS_KEYSPACE, columnFamilyTopicStats, s.getTopicArn(), "subscriptionConfirmed", 1, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER); } else { cassandraHandler.decrementCounter( AbstractDurablePersistence.CNS_KEYSPACE, columnFamilyTopicStats, s.getTopicArn(), "subscriptionPending", 1, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER); } cassandraHandler.incrementCounter( AbstractDurablePersistence.CNS_KEYSPACE, columnFamilyTopicStats, s.getTopicArn(), "subscriptionDeleted", 1, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER); } }
private void insertOrUpdateSubsAndIndexes(final CNSSubscription subscription, Integer ttl) throws Exception { subscription.checkIsValid(); CmbComposite columnName = cassandraHandler.getCmbComposite( subscription.getEndpoint(), subscription.getProtocol().name()); cassandraHandler.update( AbstractDurablePersistence.CNS_KEYSPACE, columnFamilySubscriptions, subscription.getTopicArn(), columnName, getColumnValuesJSON(subscription), CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.COMPOSITE_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER, ttl); cassandraHandler.insertRow( AbstractDurablePersistence.CNS_KEYSPACE, subscription.getArn(), columnFamilySubscriptionsIndex, getIndexColumnValues(subscription.getEndpoint(), subscription.getProtocol()), CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER, ttl); cassandraHandler.insertRow( AbstractDurablePersistence.CNS_KEYSPACE, subscription.getUserId(), columnFamilySubscriptionsUserIndex, new HashMap<String, String>() { { put(subscription.getArn(), ""); } }, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER, ttl); cassandraHandler.insertRow( AbstractDurablePersistence.CNS_KEYSPACE, subscription.getToken(), columnFamilySubscriptionsTokenIndex, new HashMap<String, String>() { { put(subscription.getArn(), ""); } }, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER, ttl); }
@Override public CNSSubscription subscribe( String endpoint, CnsSubscriptionProtocol protocol, String topicArn, String userId) throws Exception { // subscription is unique by protocol + endpoint + topic final CNSSubscription subscription = new CNSSubscription(endpoint, protocol, topicArn, userId); CNSTopic t = PersistenceFactory.getTopicPersistence().getTopic(topicArn); if (t == null) { throw new TopicNotFoundException("Resource not found."); } // check if queue exists for cqs endpoints if (protocol.equals(CnsSubscriptionProtocol.cqs)) { CQSQueue queue = PersistenceFactory.getQueuePersistence() .getQueue(com.comcast.cqs.util.Util.getRelativeQueueUrlForArn(endpoint)); if (queue == null) { throw new CMBException( CMBErrorCodes.NotFound, "Queue with arn " + endpoint + " does not exist."); } } subscription.setArn(Util.generateCnsTopicSubscriptionArn(topicArn, protocol, endpoint)); // attempt to delete existing subscription /*Composite superColumnName = new Composite(subscription.getEndpoint(), subscription.getProtocol().name()); HSuperColumn<Composite, String, String> superCol = readColumnFromSuperColumnFamily(columnFamilySubscriptions, subscription.getTopicArn(), superColumnName, new StringSerializer(), new CompositeSerializer(), StringSerializer.get(), StringSerializer.get(), CMBProperties.getInstance().getReadConsistencyLevel()); if (superCol != null) { CNSSubscription exisitingSub = extractSubscriptionFromSuperColumn(superCol, topicArn); deleteIndexes(exisitingSub.getArn(), exisitingSub.getUserId(), exisitingSub.getToken()); deleteSuperColumn(subscriptionsTemplate, exisitingSub.getTopicArn(), superColumnName); }*/ // then set confirmation stuff and update cassandra CNSSubscription retrievedSubscription = getSubscription(subscription.getArn()); if (!CMBProperties.getInstance().getCNSRequireSubscriptionConfirmation()) { subscription.setConfirmed(true); subscription.setConfirmDate(new Date()); insertOrUpdateSubsAndIndexes(subscription, null); if (retrievedSubscription == null) { cassandraHandler.incrementCounter( AbstractDurablePersistence.CNS_KEYSPACE, columnFamilyTopicStats, subscription.getTopicArn(), "subscriptionConfirmed", 1, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER); } } else { // protocols that cannot confirm subscriptions (e.g. redisPubSub) // get an automatic confirmation here if (!protocol.canConfirmSubscription()) { subscription.setConfirmed(true); subscription.setConfirmDate(new Date()); insertOrUpdateSubsAndIndexes(subscription, null); // auto confirm subscription to cqs queue by owner } else if (protocol.equals(CnsSubscriptionProtocol.cqs)) { String queueOwner = com.comcast.cqs.util.Util.getQueueOwnerFromArn(endpoint); if (queueOwner != null && queueOwner.equals(userId)) { subscription.setConfirmed(true); subscription.setConfirmDate(new Date()); insertOrUpdateSubsAndIndexes(subscription, null); if (retrievedSubscription == null) { cassandraHandler.incrementCounter( AbstractDurablePersistence.CNS_KEYSPACE, columnFamilyTopicStats, subscription.getTopicArn(), "subscriptionConfirmed", 1, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER); } } else { // use cassandra ttl to implement expiration after 3 days insertOrUpdateSubsAndIndexes(subscription, 3 * 24 * 60 * 60); if (retrievedSubscription == null) { cassandraHandler.incrementCounter( AbstractDurablePersistence.CNS_KEYSPACE, columnFamilyTopicStats, subscription.getTopicArn(), "subscriptionPending", 1, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER); } } } else { // use cassandra ttl to implement expiration after 3 days insertOrUpdateSubsAndIndexes(subscription, 3 * 24 * 60 * 60); if (retrievedSubscription == null) { cassandraHandler.incrementCounter( AbstractDurablePersistence.CNS_KEYSPACE, columnFamilyTopicStats, subscription.getTopicArn(), "subscriptionPending", 1, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER); } } } CNSSubscriptionAttributes attributes = new CNSSubscriptionAttributes(topicArn, subscription.getArn(), userId); PersistenceFactory.getCNSAttributePersistence() .setSubscriptionAttributes(attributes, subscription.getArn()); return subscription; }