@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;
  }
  private static CNSSubscription extractSubscriptionFromColumn(
      CmbColumn<CmbComposite, String> column, String topicArn) throws JSONException {

    JSONObject json = new JSONObject(column.getValue());
    CNSSubscription s = new CNSSubscription(json.getString("subArn"));

    s.setEndpoint(json.getString("endPoint"));
    s.setUserId(json.getString("userId"));

    if (json.has("confirmDate")) {
      s.setConfirmDate(new Date(json.getLong("confirmDate")));
    }

    if (json.has("requestDate")) {
      s.setRequestDate(new Date(json.getLong("requestDate")));
    }

    if (json.has("protocol")) {
      s.setProtocol(CnsSubscriptionProtocol.valueOf(json.getString("protocol")));
    }

    if (json.has("isConfirmed")) {
      s.setConfirmed(json.getBoolean("isConfirmed"));
    }

    s.setToken(json.getString("token"));

    if (json.has("authenticateOnSubscribe")) {
      s.setAuthenticateOnUnsubscribe(json.getBoolean("authenticateOnSubscribe"));
    }

    if (json.has("rawMessageDelivery")) {
      s.setRawMessageDelivery(json.getBoolean("rawMessageDelivery"));
    }

    s.setTopicArn(topicArn);

    return s;
  }