/**
* 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.io.IOException;
import java.lang.management.ManagementFactory;
import java.util.List;
import java.util.Map;
import javax.management.MBeanServer;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import javax.servlet.AsyncContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import com.comcast.cmb.common.model.CMBPolicy;
import com.comcast.cmb.common.model.User;
import com.comcast.cmb.common.util.PersistenceException;
import com.comcast.cns.io.CNSWorkerStatsPopulator;
import com.comcast.cns.model.CNSWorkerStats;
import com.comcast.cns.tools.CNSWorkerMonitor;
import com.comcast.cns.util.CNSWorkerStatWrapper;
/**
* Subscribe action
* @author bwolf, jorge
*
*/
public class CNSGetWorkerStatsAction extends CNSAction {
private static Logger logger = Logger.getLogger(CNSGetWorkerStatsAction.class);
static {
//register JMX Bean
try{
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
ObjectName name = new ObjectName("com.comcast.cns.tools:type=CNSWorkerMonitorMBean");
if (!mbs.isRegistered(name)) {
mbs.registerMBean(CNSWorkerMonitor.getInstance(), name);
}
} catch (Exception ex){
logger.error("event=failed_to_register_jmx_Bean", ex);
}
}
public CNSGetWorkerStatsAction() {
super("GetWorkerStats");
}
@Override
public boolean isActionAllowed(User user, HttpServletRequest request, String service, CMBPolicy policy) throws Exception {
return true;
}
public static List<CNSWorkerStats> getWorkerStats(String dataCenter) throws IOException, PersistenceException {
List<CNSWorkerStats> statsList = null;
if(dataCenter == null || dataCenter.length() == 0){
statsList = CNSWorkerStatWrapper.getCassandraWorkerStats();
} else{
statsList = CNSWorkerStatWrapper.getCassandraWorkerStatsByDataCenter(dataCenter);
}
for (CNSWorkerStats stats : statsList) {
long now = System.currentTimeMillis();
if (stats.getJmxPort() > 0 && (now-stats.getConsumerTimestamp()<5*60*1000 || now-stats.getProducerTimestamp()<5*60*1000)) {
JMXConnector jmxConnector = null;
String url = null;
try {
String host = stats.getIpAddress();
long port = stats.getJmxPort();
url = "service:jmx:rmi:///jndi/rmi://" + host + ":" + port + "/jmxrmi";
JMXServiceURL serviceUrl = new JMXServiceURL(url);
jmxConnector = JMXConnectorFactory.connect(serviceUrl);
MBeanServerConnection mbeanConn = jmxConnector.getMBeanServerConnection();
//Set<ObjectName> beanSet = mbeanConn.queryNames(null, null);
ObjectName cnsWorkerMonitor = new ObjectName("com.comcast.cns.tools:type=CNSWorkerMonitorMBean");
Integer deliveryQueueSize = (Integer)mbeanConn.getAttribute(cnsWorkerMonitor, "DeliveryQueueSize");
stats.setDeliveryQueueSize(deliveryQueueSize);
Integer redeliveryQueueSize = (Integer)mbeanConn.getAttribute(cnsWorkerMonitor, "RedeliveryQueueSize");
stats.setRedeliveryQueueSize(redeliveryQueueSize);
Boolean consumerOverloaded = (Boolean)mbeanConn.getAttribute(cnsWorkerMonitor, "ConsumerOverloaded");
stats.setConsumerOverloaded(consumerOverloaded);
Integer numPublishedMessages = (Integer)mbeanConn.getAttribute(cnsWorkerMonitor, "RecentNumberOfPublishedMessages");
stats.setNumPublishedMessages(numPublishedMessages);
@SuppressWarnings("unchecked")
Map<String, Integer> errorCountForEndpoints = (Map<String, Integer>)mbeanConn.getAttribute(cnsWorkerMonitor, "RecentErrorCountForEndpoints");
stats.setErrorCountForEndpoints(errorCountForEndpoints);
Boolean cqsServiceAvailable = (Boolean)mbeanConn.getAttribute(cnsWorkerMonitor, "CQSServiceAvailable");
stats.setCqsServiceAvailable(cqsServiceAvailable);
Integer numPooledHttpConnections = (Integer)mbeanConn.getAttribute(cnsWorkerMonitor, "PublishHttpPoolSize");
stats.setNumPooledHttpConnections(numPooledHttpConnections);
} catch (Exception ex) {
logger.warn("event=failed_to_connect_to_jmx_server url=" + url, ex);
} finally {
if (jmxConnector != null) {
jmxConnector.close();
}
}
}
}
return statsList;
}
/**
* Get various stats about active cns workers
* @param user the user for whom we are subscribing.
* @param asyncContext
*/
@Override
public boolean doAction(User user, AsyncContext asyncContext) throws Exception {
HttpServletResponse response = (HttpServletResponse)asyncContext.getResponse();
HttpServletRequest request = (HttpServletRequest)asyncContext.getRequest();
String dataCenter = request.getParameter("DataCenter");
List<CNSWorkerStats> statsList = getWorkerStats(dataCenter);
String out = CNSWorkerStatsPopulator.getGetWorkerStatsResponse(statsList);
writeResponse(out, response);
return true;
}
}