001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.mina.integration.jmx; 018 019import java.net.SocketAddress; 020import java.util.LinkedHashSet; 021import java.util.List; 022import java.util.Set; 023 024import javax.management.MBeanOperationInfo; 025import javax.management.MBeanParameterInfo; 026import javax.management.ObjectName; 027import javax.management.modelmbean.ModelMBeanOperationInfo; 028 029import ognl.Ognl; 030 031import org.apache.mina.core.service.IoService; 032import org.apache.mina.core.session.IoSession; 033import org.apache.mina.integration.ognl.IoSessionFinder; 034 035/** 036 * A JMX MBean wrapper for an {@link IoSession}. 037 * 038 * @author <a href="http://mina.apache.org">Apache MINA Project</a> 039 */ 040public class IoServiceMBean extends ObjectMBean<IoService> { 041 042 static String getSessionIdAsString(long l) { 043 // ID in MINA is a unsigned 32-bit integer. 044 String id = Long.toHexString(l).toUpperCase(); 045 while (id.length() < 8) { 046 id = '0' + id; // padding 047 } 048 id = "0x" + id; 049 return id; 050 } 051 052 public IoServiceMBean(IoService source) { 053 super(source); 054 } 055 056 @Override 057 protected Object invoke0(String name, Object[] params, String[] signature) throws Exception { 058 if (name.equals("findSessions")) { 059 IoSessionFinder finder = new IoSessionFinder((String) params[0]); 060 return finder.find(getSource().getManagedSessions().values()); 061 } 062 063 if (name.equals("findAndRegisterSessions")) { 064 IoSessionFinder finder = new IoSessionFinder((String) params[0]); 065 Set<IoSession> registeredSessions = new LinkedHashSet<IoSession>(); 066 for (IoSession s : finder.find(getSource().getManagedSessions().values())) { 067 try { 068 getServer().registerMBean( 069 new IoSessionMBean(s), 070 new ObjectName(getName().getDomain() + ":type=session,name=" 071 + getSessionIdAsString(s.getId()))); 072 registeredSessions.add(s); 073 } catch (Exception e) { 074 LOGGER.warn("Failed to register a session as a MBean: " + s, e); 075 } 076 } 077 078 return registeredSessions; 079 } 080 081 if (name.equals("findAndProcessSessions")) { 082 IoSessionFinder finder = new IoSessionFinder((String) params[0]); 083 String command = (String) params[1]; 084 Object expr = Ognl.parseExpression(command); 085 Set<IoSession> matches = finder.find(getSource().getManagedSessions().values()); 086 087 for (IoSession s : matches) { 088 try { 089 Ognl.getValue(expr, s); 090 } catch (Exception e) { 091 LOGGER.warn("Failed to execute '" + command + "' for: " + s, e); 092 } 093 } 094 return matches; 095 } 096 097 return super.invoke0(name, params, signature); 098 } 099 100 @Override 101 protected void addExtraOperations(List<ModelMBeanOperationInfo> operations) { 102 operations.add(new ModelMBeanOperationInfo("findSessions", "findSessions", 103 new MBeanParameterInfo[] { new MBeanParameterInfo("ognlQuery", String.class.getName(), 104 "a boolean OGNL expression") }, Set.class.getName(), MBeanOperationInfo.INFO)); 105 operations.add(new ModelMBeanOperationInfo("findAndRegisterSessions", "findAndRegisterSessions", 106 new MBeanParameterInfo[] { new MBeanParameterInfo("ognlQuery", String.class.getName(), 107 "a boolean OGNL expression") }, Set.class.getName(), MBeanOperationInfo.ACTION_INFO)); 108 operations.add(new ModelMBeanOperationInfo("findAndProcessSessions", "findAndProcessSessions", 109 new MBeanParameterInfo[] { 110 new MBeanParameterInfo("ognlQuery", String.class.getName(), "a boolean OGNL expression"), 111 new MBeanParameterInfo("ognlCommand", String.class.getName(), 112 "an OGNL expression that modifies the state of the sessions in the match result") }, 113 Set.class.getName(), MBeanOperationInfo.ACTION_INFO)); 114 } 115 116 @Override 117 protected boolean isOperation(String methodName, Class<?>[] paramTypes) { 118 // Ignore some IoServide methods. 119 if (methodName.matches("(newSession|broadcast|(add|remove)Listener)")) { 120 return false; 121 } 122 123 if ((methodName.equals("bind") || methodName.equals("unbind")) 124 && (paramTypes.length > 1 || paramTypes.length == 1 125 && !SocketAddress.class.isAssignableFrom(paramTypes[0]))) { 126 return false; 127 } 128 129 return super.isOperation(methodName, paramTypes); 130 } 131}