View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.mina.integration.jmx;
18  
19  import java.net.SocketAddress;
20  import java.util.LinkedHashSet;
21  import java.util.List;
22  import java.util.Set;
23  
24  import javax.management.MBeanOperationInfo;
25  import javax.management.MBeanParameterInfo;
26  import javax.management.ObjectName;
27  import javax.management.modelmbean.ModelMBeanOperationInfo;
28  
29  import ognl.Ognl;
30  
31  import org.apache.mina.core.service.IoService;
32  import org.apache.mina.core.session.IoSession;
33  import org.apache.mina.integration.ognl.IoSessionFinder;
34  
35  /**
36   * A JMX MBean wrapper for an {@link IoSession}.
37   *
38   * @author <a href="http://mina.apache.org">Apache MINA Project</a>
39   */
40  public class IoServiceMBean extends ObjectMBean<IoService> {
41  
42      static String getSessionIdAsString(long l) {
43          // ID in MINA is a unsigned 32-bit integer.
44          String id = Long.toHexString(l).toUpperCase();
45          
46          while (id.length() < 8) {
47              id = '0' + id; // padding
48          }
49          
50          id = "0x" + id;
51          
52          return id;
53      }
54  
55      /**
56       * Creates a new IoServiceMBean instance
57       * 
58       * @param source The IoService to monitor
59       */
60      public IoServiceMBean(IoService source) {
61          super(source);
62      }
63  
64      @Override
65      protected Object invoke0(String name, Object[] params, String[] signature) throws Exception {
66          if (name.equals("findSessions")) {
67              IoSessionFinder finder = new IoSessionFinder((String) params[0]);
68              return finder.find(getSource().getManagedSessions().values());
69          }
70  
71          if (name.equals("findAndRegisterSessions")) {
72              IoSessionFinder finder = new IoSessionFinder((String) params[0]);
73              Set<IoSession> registeredSessions = new LinkedHashSet<IoSession>();
74              
75              for (IoSession s : finder.find(getSource().getManagedSessions().values())) {
76                  try {
77                      getServer().registerMBean(
78                              new IoSessionMBean(s),
79                              new ObjectName(getName().getDomain() + ":type=session,name="
80                                      + getSessionIdAsString(s.getId())));
81                      registeredSessions.add(s);
82                  } catch (Exception e) {
83                      LOGGER.warn("Failed to register a session as a MBean: " + s, e);
84                  }
85              }
86  
87              return registeredSessions;
88          }
89  
90          if (name.equals("findAndProcessSessions")) {
91              IoSessionFinder finder = new IoSessionFinder((String) params[0]);
92              String command = (String) params[1];
93              Object expr = Ognl.parseExpression(command);
94              Set<IoSession> matches = finder.find(getSource().getManagedSessions().values());
95  
96              for (IoSession s : matches) {
97                  try {
98                      Ognl.getValue(expr, s);
99                  } catch (Exception e) {
100                     LOGGER.warn("Failed to execute '" + command + "' for: " + s, e);
101                 }
102             }
103             
104             return matches;
105         }
106 
107         return super.invoke0(name, params, signature);
108     }
109 
110     @Override
111     protected void addExtraOperations(List<ModelMBeanOperationInfo> operations) {
112         operations.add(new ModelMBeanOperationInfo("findSessions", "findSessions",
113                 new MBeanParameterInfo[] { new MBeanParameterInfo("ognlQuery", String.class.getName(),
114                         "a boolean OGNL expression") }, Set.class.getName(), MBeanOperationInfo.INFO));
115         operations.add(new ModelMBeanOperationInfo("findAndRegisterSessions", "findAndRegisterSessions",
116                 new MBeanParameterInfo[] { new MBeanParameterInfo("ognlQuery", String.class.getName(),
117                         "a boolean OGNL expression") }, Set.class.getName(), MBeanOperationInfo.ACTION_INFO));
118         operations.add(new ModelMBeanOperationInfo("findAndProcessSessions", "findAndProcessSessions",
119                 new MBeanParameterInfo[] {
120                         new MBeanParameterInfo("ognlQuery", String.class.getName(), "a boolean OGNL expression"),
121                         new MBeanParameterInfo("ognlCommand", String.class.getName(),
122                                 "an OGNL expression that modifies the state of the sessions in the match result") },
123                 Set.class.getName(), MBeanOperationInfo.ACTION_INFO));
124     }
125 
126     @Override
127     protected boolean isOperation(String methodName, Class<?>[] paramTypes) {
128         // Ignore some IoServide methods.
129         if (methodName.matches("(newSession|broadcast|(add|remove)Listener)")) {
130             return false;
131         }
132 
133         if ((methodName.equals("bind") || methodName.equals("unbind"))
134                 && (paramTypes.length > 1 || paramTypes.length == 1
135                         && !SocketAddress.class.isAssignableFrom(paramTypes[0]))) {
136             return false;
137         }
138 
139         return super.isOperation(methodName, paramTypes);
140     }
141 }