All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.dataforte.cassandra.pool.jmx.ConnectionPoolMBean Maven / Gradle / Ivy

There is a newer version: 1.0.0.CR1
Show newest version
/**
 * Copyright 2010 Tristan Tarrant
 *
 * 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 net.dataforte.cassandra.pool.jmx;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;

import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.AttributeNotFoundException;
import javax.management.DynamicMBean;
import javax.management.InvalidAttributeValueException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanNotificationInfo;
import javax.management.MBeanOperationInfo;
import javax.management.Notification;
import javax.management.NotificationBroadcasterSupport;
import javax.management.NotificationListener;
import javax.management.ReflectionException;

import net.dataforte.cassandra.pool.PoolConfiguration;
import net.dataforte.cassandra.pool.PoolProperties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ConnectionPoolMBean extends NotificationBroadcasterSupport implements DynamicMBean {
	/**
	 * logger
	 */
	private static final Logger log = LoggerFactory.getLogger(ConnectionPoolMBean.class);

	/**
	 * the connection pool
	 */
	protected net.dataforte.cassandra.pool.ConnectionPool pool = null;
	/**
	 * sequence for JMX notifications
	 */
	protected AtomicInteger sequence = new AtomicInteger(0);

	/**
	 * Listeners that are local and interested in our notifications, no need for
	 * JMX
	 */
	protected ConcurrentLinkedQueue listeners = new ConcurrentLinkedQueue();

	public ConnectionPoolMBean(net.dataforte.cassandra.pool.ConnectionPool pool) {
		super();
		this.pool = pool;
	}

	public net.dataforte.cassandra.pool.ConnectionPool getPool() {
		return pool;
	}

	public PoolConfiguration getPoolProperties() {
		return pool.getPoolProperties();
	}

	@Override
	public Object invoke(String actionName, Object[] params, String[] signature) throws MBeanException, ReflectionException {
		if(log.isDebugEnabled()) {
			log.debug("Invoking {}", actionName);
		}
		//TODO
		return null;
	}

	@Override
	public MBeanInfo getMBeanInfo() {
		List attributes = new ArrayList();
		
		// Dynamically add all of the properties specified in the PoolProperties
		try {
			BeanInfo beanInfo = Introspector.getBeanInfo(PoolProperties.class);
			for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
				// skip a few "sensitive" attributes
				if(!("password".equals(pd.getName())||"class".equals(pd.getName()))) {
					attributes.add(new MBeanAttributeInfo(pd.getName(), pd.getPropertyType().getName(), pd.getDisplayName(), true, true, false));
				}
			}
		} catch(Exception e) {
			// Should not happen
		}
		
		// Add the ConnectionPool properties
		attributes.add(new MBeanAttributeInfo("size", "int", "size", true, false, false));
		attributes.add(new MBeanAttributeInfo("active", "int", "active", true, false, false));
		attributes.add(new MBeanAttributeInfo("idle", "int", "idle", true, false, false));
		attributes.add(new MBeanAttributeInfo("waitCount", "int", "waitCount", true, false, false));		
		
		List operations = new ArrayList();
		String ops[] = new String[]{ "checkIdle", "checkAbandoned", "testIdle" };
		
		for(String op : ops) {
			try {
				operations.add(new MBeanOperationInfo(op, this.getClass().getMethod(op, null)));
			} catch (Exception e) {
				// Will not happen
			}
		}
		
		
		return new MBeanInfo(this.getClass().getName(), "Cassandra Connection Pool", attributes.toArray(new MBeanAttributeInfo[0]), null, operations.toArray(new MBeanOperationInfo[0]), null);
	}
	

	@Override
	public void setAttribute(Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException {
		pool.getPoolProperties().set(attribute.getName(), attribute.getValue());
	}

	@Override
	public AttributeList setAttributes(AttributeList attributes) {
		AttributeList list = new AttributeList();
		for(Attribute attribute : attributes.asList()) {
			try {
				setAttribute(attribute);
				list.add(attribute);
			} catch (Exception e) {
				// setAttribute will have already logged
			}
		}
		return list;
	}

	@Override
	public Object getAttribute(String attribute) throws AttributeNotFoundException, MBeanException {
		if("size".equals(attribute)) {
			return pool.getSize();
		} else if("active".equals(attribute)) {
			return pool.getActive();
		} else if("idle".equals(attribute)) {
			return pool.getIdle();
		} else if("waitCount".equals(attribute)) {
			return pool.getWaitCount();
		} else {
			return pool.getPoolProperties().get(attribute);
		}
	}

	@Override
	public AttributeList getAttributes(String[] attributes) {
		AttributeList list = new AttributeList();
		for (String attribute : attributes) {
			try {
				list.add(new Attribute(attribute, getAttribute(attribute)));
			} catch (Exception e) {
				log.error("Error while adding attribute " + attribute, e);
			}
		}
		return list;
	}

	// =================================================================
	// NOTIFICATION INFO
	// =================================================================
	public static final String NOTIFY_INIT = "INIT FAILED";
	public static final String NOTIFY_CONNECT = "CONNECTION FAILED";
	public static final String NOTIFY_ABANDON = "CONNECTION ABANDONED";
	public static final String SUSPECT_ABANDONED_NOTIFICATION = "SUSPECT CONNECTION ABANDONED";

	@Override
	public MBeanNotificationInfo[] getNotificationInfo() {
		MBeanNotificationInfo[] pres = super.getNotificationInfo();
		MBeanNotificationInfo[] loc = getDefaultNotificationInfo();
		MBeanNotificationInfo[] aug = new MBeanNotificationInfo[pres.length + loc.length];
		if (pres.length > 0)
			System.arraycopy(pres, 0, aug, 0, pres.length);
		if (loc.length > 0)
			System.arraycopy(loc, 0, aug, pres.length, loc.length);
		return aug;
	}

	public static MBeanNotificationInfo[] getDefaultNotificationInfo() {
		String[] types = new String[] { NOTIFY_INIT, NOTIFY_CONNECT, NOTIFY_ABANDON, SUSPECT_ABANDONED_NOTIFICATION };
		String name = Notification.class.getName();
		String description = "A connection pool error condition was met.";
		MBeanNotificationInfo info = new MBeanNotificationInfo(types, name, description);
		return new MBeanNotificationInfo[] { info };
	}

	/**
	 * Return true if the notification was sent successfully, false otherwise.
	 * 
	 * @param type
	 * @param message
	 * @return true if the notification succeeded
	 */	
	public boolean notify(final String type, String message) {
		try {
			Notification n = new Notification(type, this, sequence.incrementAndGet(), System.currentTimeMillis(), "[" + type + "] " + message);
			sendNotification(n);
			for (NotificationListener listener : listeners) {
				listener.handleNotification(n, this);
			}
			return true;
		} catch (Exception x) {
			if (log.isDebugEnabled()) {
				log.debug("Notify failed. Type=" + type + "; Message=" + message, x);
			}
			return false;
		}

	}

	public void addListener(NotificationListener list) {
		listeners.add(list);
	}

	public boolean removeListener(NotificationListener list) {
		return listeners.remove(list);
	}

	// =================================================================
	// POOL OPERATIONS
	// =================================================================
	public void checkIdle() {
		pool.checkIdle();
	}

	public void checkAbandoned() {
		pool.checkAbandoned();
	}

	public void testIdle() {
		pool.testAllIdle();
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy