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 The Apache MINA Project (dev@mina.apache.org)
39   * @version $Rev: 671827 $, $Date: 2008-06-26 10:49:48 +0200 (jeu, 26 jun 2008) $
40   */
41  public class IoServiceMBean extends ObjectMBean<IoService> {
42  
43      static String getSessionIdAsString(long l) {
44          // ID in MINA is a unsigned 32-bit integer.
45          String id = Long.toHexString(l).toUpperCase();
46          while (id.length() < 8) {
47              id = '0' + id; // padding
48          }
49          id = "0x" + id;
50          return id;
51      }
52  
53      public IoServiceMBean(IoService source) {
54          super(source);
55      }
56  
57      @Override
58      protected Object invoke0(String name, Object[] params, String[] signature) throws Exception {
59          if (name.equals("findSessions")) {
60              IoSessionFinder finder = new IoSessionFinder((String) params[0]);
61              return finder.find(getSource().getManagedSessions().values());
62          }
63  
64          if (name.equals("findAndRegisterSessions")) {
65              IoSessionFinder finder = new IoSessionFinder((String) params[0]);
66              Set<IoSession> registeredSessions = new LinkedHashSet<IoSession>();
67              for (IoSession s: finder.find(getSource().getManagedSessions().values())) {
68                  try {
69                      getServer().registerMBean(
70                              new IoSessionMBean(s),
71                              new ObjectName(
72                                      getName().getDomain() +
73                                      ":type=session,name=" +
74                                      getSessionIdAsString(s.getId())));
75                      registeredSessions.add(s);
76                  } catch (Exception e) {
77                      logger.warn("Failed to register a session as a MBean: " + s, e);
78                  }
79              }
80  
81              return registeredSessions;
82          }
83  
84          if (name.equals("findAndProcessSessions")) {
85              IoSessionFinder finder = new IoSessionFinder((String) params[0]);
86              String command = (String) params[1];
87              Object expr = Ognl.parseExpression(command);
88              Set<IoSession> matches = finder.find(getSource().getManagedSessions().values());
89  
90              for (IoSession s: matches) {
91                  try {
92                      Ognl.getValue(expr, s);
93                  } catch (Exception e) {
94                      logger.warn("Failed to execute '" + command + "' for: " + s, e);
95                  }
96              }
97              return matches;
98          }
99  
100         return super.invoke0(name, params, signature);
101     }
102 
103     @Override
104     protected void addExtraOperations(List<ModelMBeanOperationInfo> operations) {
105         operations.add(new ModelMBeanOperationInfo(
106                 "findSessions", "findSessions",
107                 new MBeanParameterInfo[] {
108                         new MBeanParameterInfo(
109                                 "ognlQuery", String.class.getName(), "a boolean OGNL expression")
110                 }, Set.class.getName(), MBeanOperationInfo.INFO));
111         operations.add(new ModelMBeanOperationInfo(
112                 "findAndRegisterSessions", "findAndRegisterSessions",
113                 new MBeanParameterInfo[] {
114                         new MBeanParameterInfo(
115                                 "ognlQuery", String.class.getName(), "a boolean OGNL expression")
116                 }, Set.class.getName(), MBeanOperationInfo.ACTION_INFO));
117         operations.add(new ModelMBeanOperationInfo(
118                 "findAndProcessSessions", "findAndProcessSessions",
119                 new MBeanParameterInfo[] {
120                         new MBeanParameterInfo(
121                                 "ognlQuery", String.class.getName(), "a boolean OGNL expression"),
122                         new MBeanParameterInfo(
123                                 "ognlCommand", String.class.getName(), "an OGNL expression that modifies the state of the sessions in the match result")
124                 }, Set.class.getName(), MBeanOperationInfo.ACTION_INFO));
125     }
126 
127     @Override
128     protected boolean isOperation(String methodName, Class<?>[] paramTypes) {
129         // Ignore some IoServide methods.
130         if (methodName.matches(
131                 "(newSession|broadcast|(add|remove)Listener)")) {
132             return false;
133         }
134 
135         if ((methodName.equals("bind") || methodName.equals("unbind")) &&
136                 (paramTypes.length > 1 ||
137                         paramTypes.length == 1 && !SocketAddress.class.isAssignableFrom(paramTypes[0]))) {
138             return false;
139         }
140 
141         return super.isOperation(methodName, paramTypes);
142     }
143 }