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   */
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          while (id.length() < 8) {
46              id = '0' + id; // padding
47          }
48          id = "0x" + id;
49          return id;
50      }
51  
52      public IoServiceMBean(IoService source) {
53          super(source);
54      }
55  
56      @Override
57      protected Object invoke0(String name, Object[] params, String[] signature) throws Exception {
58          if (name.equals("findSessions")) {
59              IoSessionFinder finder = new IoSessionFinder((String) params[0]);
60              return finder.find(getSource().getManagedSessions().values());
61          }
62  
63          if (name.equals("findAndRegisterSessions")) {
64              IoSessionFinder finder = new IoSessionFinder((String) params[0]);
65              Set<IoSession> registeredSessions = new LinkedHashSet<IoSession>();
66              for (IoSession s: finder.find(getSource().getManagedSessions().values())) {
67                  try {
68                      getServer().registerMBean(
69                              new IoSessionMBean(s),
70                              new ObjectName(
71                                      getName().getDomain() +
72                                      ":type=session,name=" +
73                                      getSessionIdAsString(s.getId())));
74                      registeredSessions.add(s);
75                  } catch (Exception e) {
76                      LOGGER.warn("Failed to register a session as a MBean: " + s, e);
77                  }
78              }
79  
80              return registeredSessions;
81          }
82  
83          if (name.equals("findAndProcessSessions")) {
84              IoSessionFinder finder = new IoSessionFinder((String) params[0]);
85              String command = (String) params[1];
86              Object expr = Ognl.parseExpression(command);
87              Set<IoSession> matches = finder.find(getSource().getManagedSessions().values());
88  
89              for (IoSession s: matches) {
90                  try {
91                      Ognl.getValue(expr, s);
92                  } catch (Exception e) {
93                      LOGGER.warn("Failed to execute '" + command + "' for: " + s, e);
94                  }
95              }
96              return matches;
97          }
98  
99          return super.invoke0(name, params, signature);
100     }
101 
102     @Override
103     protected void addExtraOperations(List<ModelMBeanOperationInfo> operations) {
104         operations.add(new ModelMBeanOperationInfo(
105                 "findSessions", "findSessions",
106                 new MBeanParameterInfo[] {
107                         new MBeanParameterInfo(
108                                 "ognlQuery", String.class.getName(), "a boolean OGNL expression")
109                 }, Set.class.getName(), MBeanOperationInfo.INFO));
110         operations.add(new ModelMBeanOperationInfo(
111                 "findAndRegisterSessions", "findAndRegisterSessions",
112                 new MBeanParameterInfo[] {
113                         new MBeanParameterInfo(
114                                 "ognlQuery", String.class.getName(), "a boolean OGNL expression")
115                 }, Set.class.getName(), MBeanOperationInfo.ACTION_INFO));
116         operations.add(new ModelMBeanOperationInfo(
117                 "findAndProcessSessions", "findAndProcessSessions",
118                 new MBeanParameterInfo[] {
119                         new MBeanParameterInfo(
120                                 "ognlQuery", String.class.getName(), "a boolean OGNL expression"),
121                         new MBeanParameterInfo(
122                                 "ognlCommand", String.class.getName(), "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(
130                 "(newSession|broadcast|(add|remove)Listener)")) {
131             return false;
132         }
133 
134         if ((methodName.equals("bind") || methodName.equals("unbind")) &&
135                 (paramTypes.length > 1 ||
136                         paramTypes.length == 1 && !SocketAddress.class.isAssignableFrom(paramTypes[0]))) {
137             return false;
138         }
139 
140         return super.isOperation(methodName, paramTypes);
141     }
142 }