Package com.comcast.cns.persistence

Source Code of com.comcast.cns.persistence.CNSTopicCassandraPersistence

/**
* 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.cns.persistence;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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.DurablePersistenceFactory;
import com.comcast.cmb.common.persistence.PersistenceFactory;
import com.comcast.cmb.common.util.CMBException;
import com.comcast.cmb.common.util.CMBProperties;
import com.comcast.cmb.common.util.PersistenceException;
import com.comcast.cns.controller.CNSCache;
import com.comcast.cns.model.CNSTopic;
import com.comcast.cns.model.CNSTopicAttributes;
import com.comcast.cns.util.CNSErrorCodes;
import com.comcast.cns.util.Util;
import com.comcast.cqs.util.CQSErrorCodes;

import org.apache.log4j.Logger;

/**
* Provide Cassandra persistence for topics
* @author aseem, bwolf, jorge, vvenkatraman, tina, michael
*
* Class is immutable
*/
public class CNSTopicCassandraPersistence implements ICNSTopicPersistence {

  private static Logger logger = Logger.getLogger(CNSTopicCassandraPersistence.class);

  private static final String columnFamilyTopics = "CNSTopics";
  private static final String columnFamilyTopicsByUserId = "CNSTopicsByUserId";
  private static final String columnFamilyTopicAttributes = "CNSTopicAttributes";
  private static final String columnFamilyTopicStats = "CNSTopicStats";
 
  private static final AbstractDurablePersistence cassandraHandler = DurablePersistenceFactory.getInstance();

  public CNSTopicCassandraPersistence() {
  }

  private Map<String, String> getColumnValues(CNSTopic t) {

    Map<String, String> columnValues = new HashMap<String, String>();

    if (t.getUserId() != null) {
      columnValues.put("userId", t.getUserId());
    }

    if (t.getName() != null) {
      columnValues.put("name", t.getName());
    }

    if (t.getDisplayName() != null) {
      columnValues.put("displayName", t.getDisplayName());
    }

    return columnValues;
 

  @Override
  public CNSTopic createTopic(String name, String displayName, String userId) throws Exception {

    String arn = Util.generateCnsTopicArn(name, CMBProperties.getInstance().getRegion(), userId);

    // disable user topic limit for now

    /*List<CNSTopic> topics = listTopics(userId, null);

    if (topics.size() >= Util.CNS_USER_TOPIC_LIMIT) {
      throw new CMBException(CNSErrorCodes.CNS_TopicLimitExceeded, "Topic limit exceeded.");
    }*/

    CNSTopic topic = getTopic(arn);

    if (topic != null) {
      return topic;
    } else {

      topic = new CNSTopic(arn, name, displayName, userId);
      topic.checkIsValid();
     
      cassandraHandler.insertRow(AbstractDurablePersistence.CNS_KEYSPACE, topic.getArn(), columnFamilyTopics, getColumnValues(topic), CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER, null);
      cassandraHandler.update(AbstractDurablePersistence.CNS_KEYSPACE, columnFamilyTopicsByUserId, userId, topic.getArn(), "", CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER, null);
      cassandraHandler.delete(AbstractDurablePersistence.CNS_KEYSPACE, columnFamilyTopicStats, arn, null, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER);
     
      cassandraHandler.deleteCounter(AbstractDurablePersistence.CNS_KEYSPACE, columnFamilyTopicStats, arn, "subscriptionConfirmed", CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER);
      cassandraHandler.deleteCounter(AbstractDurablePersistence.CNS_KEYSPACE, columnFamilyTopicStats, arn, "subscriptionPending", CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER);
      cassandraHandler.deleteCounter(AbstractDurablePersistence.CNS_KEYSPACE, columnFamilyTopicStats, arn, "subscriptionDeleted", CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER);
     
      cassandraHandler.incrementCounter(AbstractDurablePersistence.CNS_KEYSPACE, columnFamilyTopicStats, arn, "subscriptionConfirmed", 0, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER);
      cassandraHandler.incrementCounter(AbstractDurablePersistence.CNS_KEYSPACE, columnFamilyTopicStats, arn, "subscriptionPending", 0, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER);
      cassandraHandler.incrementCounter(AbstractDurablePersistence.CNS_KEYSPACE, columnFamilyTopicStats, arn, "subscriptionDeleted", 0, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER);
     
      CNSTopicAttributes attributes = new CNSTopicAttributes(arn, userId);
      PersistenceFactory.getCNSAttributePersistence().setTopicAttributes(attributes, arn);

      return topic;
    }
  }

  @Override
  public void deleteTopic(String topicArn) throws Exception {

    CNSTopic topic = getTopic(topicArn);

    if (topic == null) {
      throw new CMBException(CNSErrorCodes.CNS_NotFound, "Topic not found.");
    }

    // delete all subscriptions first

    PersistenceFactory.getSubscriptionPersistence().unsubscribeAll(topic.getArn());   

    cassandraHandler.delete(AbstractDurablePersistence.CNS_KEYSPACE, columnFamilyTopics, topicArn, null, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER);
    cassandraHandler.delete(AbstractDurablePersistence.CNS_KEYSPACE, columnFamilyTopicsByUserId, topic.getUserId(), topicArn, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER);
    cassandraHandler.delete(AbstractDurablePersistence.CNS_KEYSPACE, columnFamilyTopicAttributes, topicArn, null, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER);
    cassandraHandler.delete(AbstractDurablePersistence.CNS_KEYSPACE, columnFamilyTopicStats, topicArn, null, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER);
    cassandraHandler.deleteCounter(AbstractDurablePersistence.CNS_KEYSPACE, columnFamilyTopicStats, topicArn, "subscriptionConfirmed", CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER);
    cassandraHandler.deleteCounter(AbstractDurablePersistence.CNS_KEYSPACE, columnFamilyTopicStats, topicArn, "subscriptionPending", CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER);
    cassandraHandler.deleteCounter(AbstractDurablePersistence.CNS_KEYSPACE, columnFamilyTopicStats, topicArn, "subscriptionDeleted", CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER);
   
    CNSCache.removeTopic(topicArn);
  }
 
  @Override
  public long getNumberOfTopicsByUser(String userId) throws PersistenceException {
   
    if (userId == null || userId.trim().length() == 0) {
      logger.error("event=list_queues error_code=invalid_user user_id=" + userId);
      throw new PersistenceException(CQSErrorCodes.InvalidParameterValue, "Invalid userId " + userId);
    }
     
    String lastArn = null;
    int sliceSize;
    long numTopics = 0;

    do {
     
      sliceSize = 0;
     
      CmbColumnSlice<String, String> slice = cassandraHandler.readColumnSlice(AbstractDurablePersistence.CNS_KEYSPACE, columnFamilyTopicsByUserId, userId, lastArn, null, 10000, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER);
     
      if (slice != null && slice.getColumns().size() > 0) {
        sliceSize = slice.getColumns().size();
        numTopics += sliceSize;
        lastArn = slice.getColumns().get(sliceSize-1).getName();
      }
     
    } while (sliceSize >= 10000);
   
    return numTopics;
  }

  @Override
  public List<CNSTopic> listTopics(String userId, String nextToken) throws Exception {

    if (nextToken != null) {
      if (getTopic(nextToken) == null) {
        nextToken = null;
        //throw new CMBException(CMBErrorCodes.InvalidParameterValue, "Invalid parameter nextToken");
      }
    }

    List<CNSTopic> topics = new ArrayList<CNSTopic>();
    CmbColumnSlice<String, String> slice = cassandraHandler.readColumnSlice(AbstractDurablePersistence.CNS_KEYSPACE, columnFamilyTopicsByUserId, userId, nextToken, null, 100, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER);

    if (slice != null) {
     
      for (CmbColumn<String, String> c : slice.getColumns()) {
       
        String arn = c.getName();

        slice = cassandraHandler.readColumnSlice(AbstractDurablePersistence.CNS_KEYSPACE, columnFamilyTopics, arn, null, null, 100, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER);

        if (slice != null) {

          String name = slice.getColumnByName("name").getValue();

          String displayName = null;

          if (slice.getColumnByName("displayName") != null) {
            displayName = slice.getColumnByName("displayName").getValue();
          }

          CNSTopic t = new CNSTopic(arn, name, displayName, userId);

          topics.add(t);

        } else {
          cassandraHandler.delete(AbstractDurablePersistence.CNS_KEYSPACE, columnFamilyTopicsByUserId, userId, arn, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER);
        }
      }
    }

    return topics;
  }

  @Override
  public CNSTopic getTopic(String arn) throws Exception {

    CNSTopic topic = null;
    CmbColumnSlice<String, String> slice = cassandraHandler.readColumnSlice(AbstractDurablePersistence.CNS_KEYSPACE, columnFamilyTopics, arn, null, null, 10, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER);

    if (slice != null) {

      String name = slice.getColumnByName("name").getValue();
      String displayName = null;

      if (slice.getColumnByName("displayName") != null) {
        displayName = slice.getColumnByName("displayName").getValue();
      }

      String user = slice.getColumnByName("userId").getValue();
      topic = new CNSTopic(arn, name, displayName, user);
    }

    return topic;
  }

  @Override
  public void updateTopicDisplayName(String arn, String displayName) throws Exception {

    CNSTopic topic = getTopic(arn);

    if (topic != null) {
      topic.setDisplayName(displayName);
      topic.checkIsValid();
      cassandraHandler.insertRow(AbstractDurablePersistence.CNS_KEYSPACE, topic.getArn(), columnFamilyTopics, getColumnValues(topic), CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER, null);
    }
   
    CNSCache.removeTopic(arn);
  }
}
TOP

Related Classes of com.comcast.cns.persistence.CNSTopicCassandraPersistence

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.