Package com.comcast.cns.controller

Source Code of com.comcast.cns.controller.CNSControllerServlet

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

import java.lang.management.ManagementFactory;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;

import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;

import com.comcast.cmb.common.controller.Action;
import com.comcast.cmb.common.controller.CMBControllerServlet;
import com.comcast.cmb.common.controller.HealthCheckShallow;
import com.comcast.cmb.common.model.CMBPolicy;
import com.comcast.cmb.common.model.User;
import com.comcast.cmb.common.persistence.AbstractDurablePersistence;
import com.comcast.cmb.common.persistence.AbstractDurablePersistence.CMB_SERIALIZER;
import com.comcast.cmb.common.persistence.DurablePersistenceFactory;
import com.comcast.cmb.common.persistence.PersistenceFactory;
import com.comcast.cmb.common.util.CMBErrorCodes;
import com.comcast.cmb.common.util.CMBException;
import com.comcast.cmb.common.util.CMBProperties;
import com.comcast.cns.model.CNSTopicAttributes;
import com.comcast.cns.persistence.ICNSSubscriptionPersistence;
import com.comcast.cns.persistence.ICNSTopicPersistence;

/**
* Servlet for handling all CNS actions
* @author vvenkatraman, jorge, michael, bwolf, aseem, baosen
*/
public class CNSControllerServlet extends CMBControllerServlet {
 
  private static final long serialVersionUID = 1L;
  protected static volatile ICNSTopicPersistence topicHandler;
  private static volatile ICNSSubscriptionPersistence subscriptionHandler;
    private static volatile HashMap<String, Action> actionMap;

    public static volatile AtomicLong lastCNSPingMinute = new AtomicLong(0);
   
    private static Logger logger = Logger.getLogger(CNSControllerServlet.class);
   
    private static final String CNS_API_SERVERS = "CNSAPIServers";
    /**
     * NodeName global constant is used to identify this process uniquely across all API servers
     * and is used to identify creators of recovery logs
     */
    private static volatile String NodeName = UUID.randomUUID().toString();
   
    public static String getNodeName() {
      return NodeName;
    }
   
    /**
     * Used by unit tests to ensure we can start with a fresh baseline for testing recovery
     * and overflow logic  
     */
    public static void resetNodeName() {
      NodeName = UUID.randomUUID().toString();
    }
   
    /**
     * Default constructor.
     */
    public CNSControllerServlet() {
    }

    protected boolean isValidAction(String action) throws ServletException {
     
      if (action == null) {
        return false;
      }
     
        if (actionMap == null) {
          init();
        }
       
        return actionMap.containsKey(action);
    }   
   
    @Override   
    public void init() throws ServletException {
       
      super.init();
     
        try {
         
        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
          ObjectName name = new ObjectName("com.comcast.cns.controller:type=CNSMonitorMBean");
         
          if (!mbs.isRegistered(name)) {
            mbs.registerMBean(CNSMonitor.getInstance(), name);
          }
         
        } catch (Exception ex) {
          logger.warn("event=failed_to_register_monitor", ex);
        }
     
      topicHandler = PersistenceFactory.getTopicPersistence();
      subscriptionHandler = PersistenceFactory.getSubscriptionPersistence();
     
      final CNSConfirmSubscriptionAction confirmSubscription = new CNSConfirmSubscriptionAction();
      final CNSPublishAction publish = new CNSPublishAction();
      final CNSCreateTopicAction createTopic = new CNSCreateTopicAction();
      final CNSDeleteTopicAction deleteTopic = new CNSDeleteTopicAction();
      final CNSListTopicsAction listTopics = new CNSListTopicsAction();
      final CNSSubscribeAction subscribe = new CNSSubscribeAction();
      final CNSUnsubscribeAction unsubscribe = new CNSUnsubscribeAction();
      final CNSListSubscriptionsAction listSubscriptions = new CNSListSubscriptionsAction();
      final CNSListSubscriptionsByTopicAction listSubscriptionsByTopic = new CNSListSubscriptionsByTopicAction();
      final CNSSetSubscriptionAttributesAction setSubscriptionAttributes = new CNSSetSubscriptionAttributesAction();
      final CNSGetSubscriptionAttributesAction getSubscriptionAttributes = new CNSGetSubscriptionAttributesAction();
      final CNSSetTopicAttributesAction setTopicAttributes = new CNSSetTopicAttributesAction();
      final CNSGetTopicAttributesAction getTopicAttributes = new CNSGetTopicAttributesAction();
      final CNSAddPermissionAction addPermission = new CNSAddPermissionAction();
      final CNSRemovePermissionAction removePermission = new CNSRemovePermissionAction();
      final CNSGetWorkerStatsAction getWorkerStats = new CNSGetWorkerStatsAction();
      final CNSManageServiceAction manageService = new CNSManageServiceAction();
      final HealthCheckShallow healthCheckShallow = new HealthCheckShallow();
        final CNSGetAPIStatsAction getAPIStats = new CNSGetAPIStatsAction();
     
      actionMap = new HashMap<String, Action>(){{
          put(confirmSubscription.getName(), confirmSubscription);         
          put(publish.getName(), publish);
          put(createTopic.getName(), createTopic);
          put(deleteTopic.getName(), deleteTopic);
          put(listTopics.getName(), listTopics);
          put(subscribe.getName(), subscribe);
          put(unsubscribe.getName(), unsubscribe);
          put(listSubscriptions.getName(), listSubscriptions);
          put(listSubscriptionsByTopic.getName(), listSubscriptionsByTopic);
          put(setSubscriptionAttributes.getName(), setSubscriptionAttributes);
          put(getSubscriptionAttributes.getName(), getSubscriptionAttributes);
          put(setTopicAttributes.getName(), setTopicAttributes);
          put(getTopicAttributes.getName(), getTopicAttributes);
          put(addPermission.getName(), addPermission);
          put(removePermission.getName(), removePermission);
          put(healthCheckShallow.getName(), healthCheckShallow);
            put("healthCheckShallow", healthCheckShallow); // for backward-compatibility
          put(getWorkerStats.getName(), getWorkerStats);
          put(manageService.getName(), manageService);
          put(getAPIStats.getName(), getAPIStats);
      }};
     
    for (String action : actionMap.keySet()) {
      callResponseTimesByApi.putIfAbsent(action, new AtomicLong[NUM_MINUTES][NUM_BUCKETS]);
      AtomicLong[][] callResponseTimes = callResponseTimesByApi.get(action);
      for (int i=0; i<NUM_MINUTES; i++) {
        for (int k=0; k<NUM_BUCKETS; k++) {
          callResponseTimes[i][k] = new AtomicLong();
        }
      }
    }
    }
   
    @Override
    protected boolean isAuthenticationRequired(String action) {
       
        if (!actionMap.containsKey(action)) {
            throw new IllegalArgumentException("action not supported:" + action);
        }
        return actionMap.get(action).isAuthRequired();       
    }

    @Override
    protected boolean handleAction(String action, User user, AsyncContext asyncContext) throws Exception {
     
        HttpServletRequest request = (HttpServletRequest)asyncContext.getRequest();
     
        long now = System.currentTimeMillis();
     
      if (lastCNSPingMinute.getAndSet(now/(1000*60)) != now/(1000*60)) {

          try {

            AbstractDurablePersistence cassandraHandler = DurablePersistenceFactory.getInstance();

            // write ping
           
            String serverIp = InetAddress.getLocalHost().getHostAddress();
            String serverPort = CMBProperties.getInstance().getCNSServerPort() + "";
           
            logger.info("event=ping version=" + CMBControllerServlet.VERSION + " ip=" + serverIp + " port=" + serverPort);
           
            Map<String, String> values = new HashMap<String, String>();
           
            values.put("timestamp", now + "");
            values.put("jmxport", System.getProperty("com.sun.management.jmxremote.port", "0"));
            values.put("dataCenter", CMBProperties.getInstance().getCMBDataCenter());
            values.put("serviceUrl", CMBProperties.getInstance().getCNSServiceUrl());
           
                cassandraHandler.insertRow(AbstractDurablePersistence.CNS_KEYSPACE, serverIp + ":" + serverPort, CNS_API_SERVERS, values, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER, CMB_SERIALIZER.STRING_SERIALIZER, null);
               
          } catch (Exception ex) {
            logger.warn("event=ping_failed", ex);
          }
        }
     
      if (!CMBProperties.getInstance().getCNSServiceEnabled()) {
            throw new CMBException(CMBErrorCodes.InternalError, "CNS service is disabled");
      }
     
      if (actionMap == null || subscriptionHandler == null || topicHandler == null) {
        init();
      }
     
      if (isAuthenticationRequired(action)) {

        String topicArn = request.getParameter("TopicArn");
           
        CNSTopicAttributes attributes = CNSCache.getTopicAttributes(topicArn);         
            if (attributes != null) {
                if (!actionMap.get(action).isActionAllowed(user, request, "CNS", new CMBPolicy(attributes.getPolicy()))) {
                    throw new CMBException(CMBErrorCodes.AccessDenied, "You don't have permission for " + actionMap.get(action).getName());
                }
            }
      }

      if (actionMap.containsKey(action)) {
        return actionMap.get(action).doAction(user, asyncContext);
      }
     
        throw new CMBException(CMBErrorCodes.InvalidAction, action + " is not a valid action");
    }
}
TOP

Related Classes of com.comcast.cns.controller.CNSControllerServlet

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.