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

gedi.solutions.geode.client.GemFireJmxClient Maven / Gradle / Ivy

Go to download

GemFire Enterprise Data Integration - common development extensions powered by Apache Geode

The newest version!
package gedi.solutions.geode.client;

import java.lang.reflect.UndeclaredThrowableException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.TreeSet;

import javax.management.InstanceNotFoundException;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.Query;
import javax.management.QueryExp;
import javax.management.openmbean.CompositeData;

import org.apache.geode.cache.CacheClosedException;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.client.ClientCache;
import org.apache.geode.cache.client.ClientCacheFactory;
import org.apache.geode.cache.client.ClientRegionShortcut;
import org.apache.geode.cache.client.Pool;
import org.apache.geode.cache.client.PoolFactory;
import org.apache.geode.cache.client.PoolManager;
import org.apache.geode.cache.execute.FunctionService;
import org.apache.geode.management.DistributedRegionMXBean;
import org.apache.geode.management.DistributedSystemMXBean;
import org.apache.geode.management.GatewayReceiverMXBean;
import org.apache.geode.management.GatewaySenderMXBean;
import org.apache.geode.management.MemberMXBean;

import gedi.solutions.geode.io.GemFireIO;
import gedi.solutions.geode.operations.functions.ClearRegionFunction;
import nyla.solutions.core.patterns.jmx.JMX;

/**
 * Wrapper to establish GemFire client cache based on JMX information.
 * 
 * @author Gregory Green
 *
 */
public class GemFireJmxClient
{
	private static ClientCache clientCache = null;
	private static ResourceBundle _bundle = null;
	private static final String hostPropFileName = "host.properties";

	
	public synchronized static void clearRegion(String regionName, JMX jmx)
			throws Exception
			{
				GemFireIO.exeWithResults(FunctionService.onRegion( GemFireJmxClient.getRegion(regionName,jmx)), 
						new ClearRegionFunction());
			}


	/**
	 * 
	 * @param jmx the JMX managers
	 */
	public static void startGatewaySenders(JMX jmx)
	{
		Collection senders = listGatewaySenders(jmx);
		
		if(senders == null || senders.isEmpty())
			return;
		
		for (GatewaySenderMXBean gatewaySenderMXBean : senders)
		{			
			gatewaySenderMXBean.start();
		}
	}// --------------------------------------------------------
	/**
	 * 
	 * @param jmx the JMX managers
	 * @throws Exception when an unknown error occurs
	 */
	public static void stopGatewaySenders(JMX jmx)
	throws Exception
	{
		Collection senders = listGatewaySenders(jmx);
		
		if(senders == null || senders.isEmpty())
			return;
		
		
		for (GatewaySenderMXBean gatewaySenderMXBean : senders)
		{			
			gatewaySenderMXBean.stop();
		}
	}// --------------------------------------------------------
	/***
	 * 
	 * @param distributedRegionMXBean the distributed region JMX bean
	 * @return return if region.getRegionType contains the term  REPLICATE
	 */
	public static boolean isReplicatedRegion(DistributedRegionMXBean distributedRegionMXBean)
	{
		if(distributedRegionMXBean == null)
			return true;
		
		String type = distributedRegionMXBean.getRegionType();
		
		return type != null && type.toUpperCase(Locale.US).contains("REPLICATE");
	}// --------------------------------------------------------
	/**
	 * 
	 * @param jmx the JMX connection
	 * @return the collection of distributed region names
	 */
	public static Collection listEnabledGatewayRegionMBeans(JMX jmx)
	{	
		QueryExp queryExp = Query.eq(Query.attr("GatewayEnabled"), Query.value(true)); 
		Collection ons = jmx.searchObjectNames("GemFire:service=Region,name=*,type=Distributed", queryExp);
	
		if(ons == null || ons.isEmpty())
			return null;
		
		ArrayList regions = new ArrayList(ons.size());
		
		for (ObjectName objectName : ons)
		{
			DistributedRegionMXBean region = jmx.newBean(DistributedRegionMXBean.class, objectName);
			regions.add(region);
		}
		
		return regions;
	}// --------------------------------------------------------
	public static DistributedRegionMXBean getRegionMBean(String regionName, JMX jmx)
	{	
		ObjectName on = getRegionObjectName(regionName, jmx);
		
		if(on ==null)
			return null;
		
		DistributedRegionMXBean region = jmx.newBean(DistributedRegionMXBean.class, on);
		return region;
	}// --------------------------------------------------------
	/**
	 * 
	 * @param memberName the member name
	 * @param propertyName the property name
	 * @param jmx the JMX connection
	 * @return the GemFire property on the member
	 * @throws MalformedObjectNameException when the member name is invalid
	 */
	public static String getMemberGemFireProperty(String memberName, String propertyName, JMX jmx)
	throws MalformedObjectNameException
	{
		
		ObjectName objectName = new ObjectName(new StringBuilder("GemFire:type=Member,member=").append(memberName).toString());
		
		CompositeData cd = (CompositeData)jmx.invoke(objectName, "listGemFireProperties", null,null);
	
		return String.valueOf(cd.get(propertyName));
	}// --------------------------------------------------------
	/**
	 * Dynamically create a GemFire pool with just the server
	 * @param serverName the server name to create a pool for
	 * @param jmx the JMX connection
	 * @return the pool with the server name and its host/port configured
	 * @throws InstanceNotFoundException when the server name does not exist
	 */
	public static synchronized Pool getPoolForServer(String serverName, JMX jmx)
	throws InstanceNotFoundException
	{
		Pool pool = PoolManager.find(serverName);
		
		if(pool != null)
			return pool;
		
		PoolFactory poolFactory = PoolManager.createFactory();
		
		//LogWriter logWriter = getClientCache(jmx).getLogger();
		
		try
		{
			//get host name
			//ex: object GemFire:type=Member,member=server_1
			ObjectName objectName = new ObjectName(new StringBuilder("GemFire:type=Member,member=").append(serverName).toString());
			
			String host =  jmx.getAttribute(objectName, "Host");
			
			if(host == null || host.length() == 0)
				throw new IllegalArgumentException("host not found for serverName:"+serverName+" not found");
			
		    host = lookupNetworkHost(host);
		    
		    
				String findJmxPort = new StringBuilder("GemFire:service=CacheServer,port=*,type=Member,member=")
			.append(serverName).toString();
			
			//search ObjectNames
			Set objectNames = jmx.searchObjectNames(findJmxPort);
			
			if(objectNames == null || objectNames.isEmpty())
				throw new IllegalArgumentException("Unable to to find port with server name:"+serverName);
			
			ObjectName portObjectName  = objectNames.iterator().next();
			Integer port = jmx.getAttribute(portObjectName, "Port");
			
			
			if(port == null)
				throw new IllegalArgumentException("Unable to obtain port for objectName:"+portObjectName+" for server:"+serverName);
			
			System.out.println("Found cache server host"+host+" port:"+port);
			
			poolFactory= poolFactory.addServer(host, port.intValue());
			
			return poolFactory.create(serverName);
		}
		catch(InstanceNotFoundException e)
		{
			throw e;
		}
		catch (Exception e)
		{
			throw new RuntimeException("Unable to create pool for servername:"+serverName+" error:"+e.getMessage(),e);
		}
		
	}// --------------------------------------------------------
	/**
	 * This methods create a pool for connecting to a locator
	 * @param jmx the JMX connection
	 * @return the pool instance
	 */
	public static synchronized Pool getPoolForLocator(JMX jmx)
	{
		String locatorsPoolName = jmx.getHost()+"["+jmx.getPort()+"]";
		
		Pool pool = PoolManager.find(locatorsPoolName);
				
		if(pool != null)
					return pool;
				
				
				PoolFactory poolFactory = PoolManager.createFactory();
				
				try
				{
					int port = getLocatorPort(jmx);
					
					poolFactory= poolFactory.addLocator(jmx.getHost(), port);
					
					return poolFactory.create(locatorsPoolName);
				}
				catch (Exception e)
				{
					throw new RuntimeException("Unable to create pool for locator:"+jmx.getHost()+" error:"+e.getMessage(),e);
				}
				
			}// --------------------------------------------------------
	/**
	 * Get region based on a given name (create the region if it exists on the server, but not on the client).
	 * @param regionName the region name the obtains
	 * @param jmx the GemFire JMX connection
	 * @param  the key type
	 * @param  the value type
	 * @return the created region
	 */
	@SuppressWarnings("unchecked")
	public static  Region getRegion(String regionName, JMX jmx)
	{
		Region	region = getClientCache(jmx).getRegion(regionName);


		if (region == null)
		{
			//check if region exist on server
			
			if(isExistingRegionOnServer(regionName,jmx))
			{		// create it locally

				region = (Region)clientCache.createClientRegionFactory(
					ClientRegionShortcut.PROXY).create(regionName);
			}
		}

		return region;

	}// --------------------------------------------------------

	/**
	 * 
	 * List all regions that match a wildcard expression (ex: R*).
	 * Note that special internal regions that begin with the name __ will be skipped.
	 * 
* @param regionPattern the region pattern * @param jmx the JMX manager connection * @return the collection of region */ public static Collection> listRootRegions(String regionPattern, JMX jmx) { //Use JMX to query for distributed regions //Ex: name GemFire:service=Region,name=/exampleRegion,type=Distributed String regionJmxPattern = String.format("GemFire:service=Region,name=/%s,type=Distributed",regionPattern); //this.getLogger().info("Searching for JMX region patterns: "+regionJmxPattern); Set regionObjNameSet = jmx.searchObjectNames(regionJmxPattern); if(regionObjNameSet == null || regionObjNameSet.isEmpty()) { //search with quotes regionJmxPattern = String.format("GemFire:service=Region,name=\"/%s\",type=Distributed",regionPattern); regionObjNameSet = jmx.searchObjectNames(regionJmxPattern); } if(regionObjNameSet == null || regionObjNameSet.isEmpty()) { //this.getLogger().warn("No regions found"); return null; } //sort the list regionObjNameSet = new TreeSet(regionObjNameSet); ArrayList> regionSet = new ArrayList>(regionObjNameSet.size()); String regionName = null; try { for (ObjectName regionObjectName : regionObjNameSet) { regionName = jmx.getAttribute(regionObjectName, "Name"); if(regionName.startsWith("__")) { continue; //skip special regions } regionSet.add(getRegion(regionName,jmx)); } return regionSet; } catch (InstanceNotFoundException e) { throw new RuntimeException("Cannot list regions:"+regionPattern+" ERROR:"+e.getMessage(),e); } }// -------------------------------------------------------- /** * * @param jmx the JMX connection * @return the locator port obtained from JMX */ public static int getLocatorPort(JMX jmx) { // Get Locator port // locator bean GemFire:service=Locator,type=Member,member=locator String locatorNamePattern = "GemFire:type=Member,member=*"; QueryExp queryExp = Query.eq(Query.attr("Manager"), Query.value(true)); Set objectNames = jmx.searchObjectNames(locatorNamePattern, queryExp); if (objectNames == null || objectNames.isEmpty()) { throw new RuntimeException( "Data export error: no manager locators found through JMX connection"); } ObjectName locatorJmxMgrObjName = objectNames.iterator().next(); try { String locatorMemberName = jmx.getAttribute(locatorJmxMgrObjName, "Member"); ObjectName locatorServiceObjName = new ObjectName(String.format( "GemFire:service=Locator,type=Member,member=%s", locatorMemberName)); // get port return jmx.getAttribute(locatorServiceObjName, "Port"); } catch (InstanceNotFoundException | MalformedObjectNameException e) { throw new RuntimeException(e.getMessage(),e); } }// -------------------------------------------------------- /** * Return the client cache based on the JMX connection (if no cache instance) * @param jmx the gemfire JMX manager connection * @return the Client cache instance */ public static synchronized ClientCache getClientCache(JMX jmx) { try { if (clientCache == null || clientCache.isClosed()) { try { clientCache = ClientCacheFactory.getAnyInstance(); } catch(CacheClosedException e) { clientCache = null; } if (clientCache != null) return clientCache; // Get Locator port // locator bean GemFire:service=Locator,type=Member,member=locator String locatorNamePattern = "GemFire:type=Member,member=*"; QueryExp queryExp = Query.eq(Query.attr("Manager"), Query.value(true)); Set objectNames = jmx.searchObjectNames(locatorNamePattern, queryExp); if (objectNames == null || objectNames.isEmpty()) { throw new RuntimeException( "Data export error: no manager locators found through JMX connection"); } ObjectName locatorJmxMgrObjName = objectNames.iterator().next(); String locatorMemberName = jmx.getAttribute(locatorJmxMgrObjName, "Member"); ObjectName locatorServiceObjName = new ObjectName(String.format( "GemFire:service=Locator,type=Member,member=%s", locatorMemberName)); // get port int port = jmx.getAttribute(locatorServiceObjName, "Port"); String host = jmx.getAttribute(locatorJmxMgrObjName, "Host"); host = lookupNetworkHost(host); clientCache = new ClientCacheFactory().addPoolLocator( host, port) .setPoolSubscriptionEnabled(false) .setPdxReadSerialized( Boolean.valueOf( System.getProperty("PdxReadSerialized","false")) .booleanValue() ) .create(); } return clientCache; } catch(RuntimeException e) { throw e; } catch (Exception e) { throw new RuntimeException("JMX connection error "+e.getMessage(),e); } }// -------------------------------------------------------- /** * Determine if a given region exists * @param regionName the region to create * @param jmx the GemFire JMX manager connection * @return true if the region exists, else false */ private static boolean isExistingRegionOnServer(String regionName,JMX jmx) { String regionJmxPattern = String.format("GemFire:service=Region,name=/%s,type=Distributed",regionName); //System.out.println("searching for:"+regionJmxPattern); Set regionObjNameSet = jmx.searchObjectNames(regionJmxPattern); if(regionObjNameSet == null || regionObjNameSet.isEmpty()) { //search with quotes regionJmxPattern = String.format("GemFire:service=Region,name=\"/%s\",type=Distributed",regionName); //System.out.println("searching for:"+regionJmxPattern); regionObjNameSet = jmx.searchObjectNames(regionJmxPattern); } return regionObjNameSet != null && !regionObjNameSet.isEmpty(); }// -------------------------------------------------------- private static ObjectName getRegionObjectName(String regionName,JMX jmx) { String regionJmxPattern = String.format("GemFire:service=Region,name=/%s,type=Distributed",regionName); //System.out.println("searching for:"+regionJmxPattern); Set regionObjNameSet = jmx.searchObjectNames(regionJmxPattern); if(regionObjNameSet == null || regionObjNameSet.isEmpty()) { //search with quotes //GemFire:service=Region,name="/ui-test-region",type=Distributed regionJmxPattern = String.format("GemFire:service=Region,name=\"/%s\",type=Distributed",regionName); //System.out.println("searching for:"+regionJmxPattern); regionObjNameSet = jmx.searchObjectNames(regionJmxPattern); } if(regionObjNameSet == null) return null; return regionObjNameSet.iterator().next(); }// -------------------------------------------------------- /** * @param jmx the JMX connection * @return the string containing the */ public static String getPrimaryGatewaySenderMember(JMX jmx) { String objectNamePattern = "GemFire:service=GatewaySender,gatewaySender=REMOTE,type=Member,member=*"; Collection objectNames = jmx.searchObjectNames(objectNamePattern); if(objectNames == null) return null; GatewaySenderMXBean bean = null; GatewaySenderMXBean primarySender = null; ObjectName primaryObjectName = null; for (ObjectName objectName : objectNames) { bean = jmx.newBean(GatewaySenderMXBean.class, objectName); if(bean.isPrimary()) { primarySender = bean; primaryObjectName = objectName; break; } } if(primarySender == null) return null; return primaryObjectName.getKeyProperty("member"); }// -------------------------------------------------------- /** * @param jmx the JMX connection * @return list of gateway senders */ public static Collection listGatewaySenders(JMX jmx) { try { DistributedSystemMXBean system = jmx.newBean(DistributedSystemMXBean.class, new ObjectName("GemFire:service=System,type=Distributed")); ObjectName[] objectNames = system.listGatewaySenderObjectNames(); if(objectNames == null) return null; GatewaySenderMXBean gatewaySender = null; ArrayList list = new ArrayList(objectNames.length); for (ObjectName objectName : objectNames) { gatewaySender = jmx.newBean(GatewaySenderMXBean.class, objectName); list.add(gatewaySender); } return list; } catch (MalformedObjectNameException e) { throw new RuntimeException(e.getMessage()); } }// -------------------------------------------------------- /** * Obtain a GemFire JMX client * @param name the JMX client name * @param jmx the JMX connection * @return JMX member object */ public static MemberMXBean getMember(String name,JMX jmx) { try { String pattern = "GemFire:type=Member,member="+name; Set objectNames = jmx.searchObjectNames(pattern); if(objectNames == null || objectNames.isEmpty()) return null; ObjectName serverName = new ObjectName(pattern); return jmx.newBean(MemberMXBean.class,serverName); } catch (MalformedObjectNameException e) { throw new RuntimeException("Unable to get member "+name +" ERROR:"+e.getMessage(),e); } }// -------------------------------------------------------- static DistributedSystemMXBean getDistributedSystemMXBean(JMX jmx) throws Exception { DistributedSystemMXBean system = jmx.newBean(DistributedSystemMXBean.class, new ObjectName("GemFire:service=System,type=Distributed")); return system; }// -------------------------------------------------------- public static Collection listGatewayReceivers(JMX jmx) throws Exception { DistributedSystemMXBean system = jmx.newBean(DistributedSystemMXBean.class, new ObjectName("GemFire:service=System,type=Distributed")); ObjectName[] objectNames = system.listGatewayReceiverObjectNames(); if(objectNames == null) return null; GatewayReceiverMXBean gatewayReceiver = null; ArrayList list = new ArrayList(objectNames.length); for (ObjectName objectName : objectNames) { gatewayReceiver = jmx.newBean(GatewayReceiverMXBean.class, objectName); list.add(gatewayReceiver); } return list; }// -------------------------------------------------------- /** * @param jmx the JMX connection object * @return member names */ public static Collection listMembers(JMX jmx) { Set memberObjects = jmx.searchObjectNames("GemFire:type=Member,member=*"); if(memberObjects == null || memberObjects.isEmpty()) { return null; } ArrayList memberList = new ArrayList(memberObjects.size()); MemberMXBean bean = null; for (ObjectName objectName : memberObjects) { bean = jmx.newBean(MemberMXBean.class, objectName); try { memberList.add(bean.getName()); } catch(UndeclaredThrowableException e) { //will not be added } } return memberList; }// -------------------------------------------------------- /** * * @param jmx the JMX connection * @return the locator host[port] */ public static Collection listLocators(JMX jmx) { Set locatorObjects = jmx.searchObjectNames("GemFire:service=Locator,type=Member,member=*"); if(locatorObjects == null || locatorObjects.isEmpty()) { return null; } ArrayList locatorList = new ArrayList(locatorObjects.size()); for (ObjectName objectName : locatorObjects) { locatorList.add(objectName.getKeyProperty("member")); } return locatorList; }// -------------------------------------------------------- /** * Determines the unique set of the host names for the distributed system * @param jmx the JMX connection * @return string of server host names */ public static Collection listHosts(JMX jmx) { Set objectNames = jmx.searchObjectNames("GemFire:type=Member,member=*"); if(objectNames == null || objectNames.isEmpty()) { return null; } HashSet hostLists = new HashSet(objectNames.size()); MemberMXBean memberMXBean = null; for (ObjectName objectName : objectNames) { memberMXBean = jmx.newBean(MemberMXBean.class, objectName); hostLists.add(memberMXBean.getHost()); } return hostLists; }// -------------------------------------------------------- /** * List the unique locator * @param jmx the JMX * @return the unique list of host names */ public static Set listLocatorHosts(JMX jmx) { Set objectNames = jmx.searchObjectNames("GemFire:type=Member,member=*"); if(objectNames == null || objectNames.isEmpty()) { return null; } HashSet hostLists = new HashSet(objectNames.size()); MemberMXBean memberMXBean = null; for (ObjectName objectName : objectNames) { memberMXBean = jmx.newBean(MemberMXBean.class, objectName); if(memberMXBean.isLocator()) hostLists.add(memberMXBean.getHost()); } return hostLists; }// -------------------------------------------------------- /** * List the unique cache server hosts * @param jmx the JMX * @return the unique list of host names */ public static Set listCacheServerHosts(JMX jmx) { Set objectNames = jmx.searchObjectNames("GemFire:type=Member,member=*"); if(objectNames == null || objectNames.isEmpty()) { return null; } HashSet hostLists = new HashSet(objectNames.size()); MemberMXBean memberMXBean = null; for (ObjectName objectName : objectNames) { memberMXBean = jmx.newBean(MemberMXBean.class, objectName); if(memberMXBean.isCacheServer()) hostLists.add(memberMXBean.getHost()); } return hostLists; }// -------------------------------------------------------- /** * * @param serverName the member name * @param jmx the JMX connection * @return true if the member is running and connected */ public static boolean checkMemberStatus(String serverName,JMX jmx) { try { ObjectName objectName = new ObjectName("GemFire:type=Member,member="+serverName); String status = (String)jmx.invoke(objectName, "status", null, null); return status != null && status.contains("online"); } catch (Exception e) { return false; } }// -------------------------------------------------------- /** * @param jmx the JMX object * @return ObjectName(GemFire:service=System,type=Distributed) TotalRegionEntryCount attribute */ public static long getTotalRegionEntryCount(JMX jmx) { try { ObjectName on = new ObjectName("GemFire:service=System,type=Distributed"); return jmx.getAttribute(on, "TotalRegionEntryCount"); } catch (InstanceNotFoundException | MalformedObjectNameException e) { throw new RuntimeException("Unable to obtain TotalRegionEntryCount ERROR:"+e.getMessage(),e); } }// -------------------------------------------------------- /** * @param jmx the JMX connection * @return the region name that do not have redundancy * @throws Exception the collection of the region names */ public static Collection listRegionsWithNumBucketsWithoutRedundancy(JMX jmx) throws Exception { //Get object GemFire:service=System,type=Distributed ObjectName objectName = new ObjectName("GemFire:service=System,type=Distributed"); //DistributedSystemMXBean distributedSystemMXBean = DistributedSystemMXBean bean = jmx.newBean(DistributedSystemMXBean.class, objectName); //listDistributedRegionObjectNames ObjectName [] regionObjectNames = bean.listDistributedRegionObjectNames(); if(regionObjectNames == null) return null; //com.gemstone.gemfire.management.DistributedRegionMXBean DistributedRegionMXBean region = null; ArrayList regionNamesWithoutRedundancy = new ArrayList(); for (ObjectName regionObjectName : regionObjectNames) { region = jmx.newBean(DistributedRegionMXBean.class, regionObjectName); if(region.getNumBucketsWithoutRedundancy() > 0) regionNamesWithoutRedundancy.add(region.getName()); } if(regionNamesWithoutRedundancy.isEmpty()) return null; return regionNamesWithoutRedundancy; }// -------------------------------------------------------- /** * Supports resolving host network lookup issues * @param host the host to resolve the IP * @return the resolved host (or original if mapping does not exists) */ static synchronized String lookupNetworkHost(String host) { try { if(_bundle == null) { URL url = GemFireJmxClient.class.getResource(hostPropFileName); String filePath = null; if(url == null) filePath = hostPropFileName; else filePath = url.toString(); System.out.println(new StringBuilder("Loading IP addresses from ") .append(filePath).toString()); _bundle = ResourceBundle.getBundle("host"); } System.out.println(new StringBuilder("Looking for host name \"").append(host).append("\" IP address in ") .append(hostPropFileName).toString()); String newHost = _bundle.getString(host); System.out.println(new StringBuilder(host).append("=").append(newHost).toString()); return newHost; } catch(RuntimeException e) { System.out.println("Using host:"+host); return host; } }// -------------------------------------------------------- /** * Closes the client cache */ public static void closeClientCache() { if(clientCache != null) { clientCache.close(); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy