@Test
  public void testHHH6635() throws Exception {
    MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
    Set<ObjectName> set = mBeanServer.queryNames(null, null);
    boolean mbeanfound = false;
    for (ObjectName obj : set) {
      if (obj.getKeyPropertyListString().indexOf("PooledDataSource") > 0) {
        mbeanfound = true;

        // see according c3p0 settings in META-INF/persistence.xml

        int actual_minPoolSize = (Integer) mBeanServer.getAttribute(obj, "minPoolSize");
        assertEquals(50, actual_minPoolSize);

        int actual_maxPoolSize = (Integer) mBeanServer.getAttribute(obj, "maxPoolSize");
        assertEquals(800, actual_maxPoolSize);

        int actual_maxStatements = (Integer) mBeanServer.getAttribute(obj, "maxStatements");
        assertEquals(50, actual_maxStatements);

        int actual_maxIdleTime = (Integer) mBeanServer.getAttribute(obj, "maxIdleTime");
        assertEquals(300, actual_maxIdleTime);

        int actual_idleConnectionTestPeriod =
            (Integer) mBeanServer.getAttribute(obj, "idleConnectionTestPeriod");
        assertEquals(3000, actual_idleConnectionTestPeriod);
        break;
      }
    }

    assertTrue("PooledDataSource BMean not found, please verify version of c3p0", mbeanfound);
  }
 public static ObjectName buildObjectNameFilter(ObjectName mapName) throws Exception {
   StringBuffer sb = new StringBuffer();
   sb.append(mapName.getDomain()).append(':');
   sb.append(mapName.getKeyPropertyListString());
   sb.append(',');
   sb.append("*");
   return new ObjectName(sb.toString());
 }
 public static ObjectName buildObjectName(ObjectName mapName, Object key) throws Exception {
   StringBuffer sb = new StringBuffer();
   sb.append(mapName.getDomain()).append(':');
   sb.append(mapName.getKeyPropertyListString());
   sb.append(',');
   if (key instanceof String) {
     sb.append("key=").append(ObjectName.quote(key.toString()));
   } else {
     sb.append("name=")
         .append(key.getClass().getName())
         .append('@')
         .append(Integer.toHexString(key.hashCode()));
   }
   return new ObjectName(sb.toString());
 }
  /**
   * see: <code>
   * org.apache.karaf.management.KarafMBeanServerGuard#getNameSegments(javax.management.ObjectName)
   * </code> Assuming <strong>full</strong> {@link ObjectName} (not null, not containing wildcards
   * and other funny stuff), split objectName to elements used then co contruct ordered list of PIDs
   * to check for MBean permissions.
   *
   * @return
   */
  public static List<String> nameSegments(ObjectName objectName) {
    List<String> segments = new ArrayList<>();
    segments.add(objectName.getDomain());
    for (String s : objectName.getKeyPropertyListString().split(",")) {
      int index = s.indexOf('=');
      if (index < 0) {
        continue;
      }
      String key = objectName.getKeyProperty(s.substring(0, index));
      if (s.substring(0, index).equals("type")) {
        segments.add(1, key);
      } else {
        segments.add(key);
      }
    }

    return segments;
  }
 public MBean(ObjectName objectName, MBeanInfo mBeanInfo) {
   _domainName = objectName.getDomain();
   _mBeanName = objectName.getKeyPropertyListString();
   _mBeanInfo = mBeanInfo;
   _loaded = true;
 }
  public MBean(ObjectName objectName) {
    this(objectName.getDomain(), objectName.getKeyPropertyListString());

    _objectName = objectName;
  }
  /**
   * If we have access to {@link ConfigurationAdmin}, we can add RBAC information
   *
   * @param result
   */
  @Override
  @SuppressWarnings("unchecked")
  public void decorate(Map<String, Object> result) throws Exception {
    try {
      ServiceReference<ConfigurationAdmin> cmRef =
          bundleContext.getServiceReference(ConfigurationAdmin.class);
      ServiceReference<JMXSecurityMBean> jmxSecRef =
          bundleContext.getServiceReference(JMXSecurityMBean.class);
      if (cmRef != null && jmxSecRef != null) {
        ConfigurationAdmin configAdmin = bundleContext.getService(cmRef);
        JMXSecurityMBean jmxSec = bundleContext.getService(jmxSecRef);
        if (configAdmin != null && jmxSec != null) {
          // 1. each pair of MBean/operation has to be marked with RBAC flag (can/can't invoke)
          // 2. the information is provided by
          // org.apache.karaf.management.JMXSecurityMBean.canInvoke(java.util.Map)
          // 3. we'll peek into available configadmin jmx.acl* configs, to see which
          // MBeans/operations have to
          //    be examined and which will produce same results
          // 4. only then we'll prepare Map as parameter for canInvoke()

          Configuration[] configurations = configAdmin.listConfigurations("(service.pid=jmx.acl*)");
          List<String> allJmxAclPids = new LinkedList<>();
          for (Configuration cfg : configurations) {
            allJmxAclPids.add(cfg.getPid());
          }
          if (allJmxAclPids.size() == 0) {
            return;
          }

          Map<String, Map<String, Object>> domains =
              (Map<String, Map<String, Object>>) result.get("domains");

          // cache contains MBeanInfos for different MBeans/ObjectNames
          Map<String, Map<String, Object>> cache =
              (Map<String, Map<String, Object>>) result.get("cache");
          // new cache will contain MBeanInfos + RBAC info
          Map<String, Map<String, Object>> rbacCache = new HashMap<>();

          // the fact that some MBeans share JSON MBeanInfo doesn't mean that they can share RBAC
          // info
          // - each MBean's name may have RBAC information configured in different PIDs.

          // when iterating through all reapeating MBeans that share MBeanInfo (that doesn't have
          // RBAC info
          // yet), we have to decide if it'll use shared info after RBAC check or will switch to
          // dedicated
          // info. we have to be careful not to end with most MBeans *not* sharing MBeanInfo (in
          // case if
          // somehow the shared info will be "special case" from RBAC point of view)

          Map<String, List<String>> queryForMBeans = new HashMap<>();
          Map<String, List<String>> queryForMBeanOperations = new HashMap<>();

          for (String domain : domains.keySet()) {
            Map<String, Object> domainMBeansCheck = new HashMap<>(domains.get(domain));
            Map<String, Object> domainMBeans = domains.get(domain);
            for (String name : domainMBeansCheck.keySet()) {
              Object mBeanInfo = domainMBeansCheck.get(name);
              String fullName = domain + ":" + name;
              ObjectName n = new ObjectName(fullName);
              if (mBeanInfo instanceof Map) {
                // not shared JSONified MBeanInfo
                prepareKarafRbacInvocations(
                    fullName,
                    (Map<String, Object>) mBeanInfo,
                    queryForMBeans,
                    queryForMBeanOperations);
              } else /*if (mBeanInfo instanceof String)*/ {
                // shared JSONified MBeanInfo

                // shard mbeanNames sharing MBeanInfo by the hierarchy of jmx.acl* PIDs used to
                // check RBAC info
                String key = (String) mBeanInfo;
                String pidListKey = pidListKey(allJmxAclPids, n);
                if (!rbacCache.containsKey(key + ":" + pidListKey)) {
                  // shallow copy - we can share op/not/attr/desc, but we put specific
                  // canInvoke/opByString keys
                  HashMap<String, Object> sharedMBeanAndRbacInfo = new HashMap<>(cache.get(key));
                  rbacCache.put(key + ":" + pidListKey, sharedMBeanAndRbacInfo);
                  // we'll be checking RBAC only for single (first) MBean having this pidListKey
                  prepareKarafRbacInvocations(
                      fullName, sharedMBeanAndRbacInfo, queryForMBeans, queryForMBeanOperations);
                }
                // switch key from shared MBeanInfo-only to shared MBean+RbacInfo
                domainMBeans.put(name, key + ":" + pidListKey);
              }
            }
          }

          // RBAC per MBeans (can invoke *any* operation or attribute?)
          TabularData dataForMBeans = jmxSec.canInvoke(queryForMBeans);
          Collection<?> results = dataForMBeans.values();
          for (Object cd : results) {
            ObjectName objectName = new ObjectName((String) ((CompositeData) cd).get("ObjectName"));
            boolean canInvoke =
                ((CompositeData) cd).get("CanInvoke") != null
                    ? (Boolean) ((CompositeData) cd).get("CanInvoke")
                    : false;
            Object mBeanInfoOrKey =
                domains.get(objectName.getDomain()).get(objectName.getKeyPropertyListString());
            Map<String, Object> mBeanInfo;
            if (mBeanInfoOrKey instanceof Map) {
              mBeanInfo = (Map<String, Object>) mBeanInfoOrKey;
            } else /*if (mBeanInfoOrKey instanceof String) */ {
              mBeanInfo = rbacCache.get(mBeanInfoOrKey.toString());
            }
            if (mBeanInfo != null) {
              mBeanInfo.put("canInvoke", canInvoke);
            }
          }

          // RBAC per { MBean,operation } (can invoke status for each operation)
          TabularData dataForMBeanOperations = jmxSec.canInvoke(queryForMBeanOperations);
          results = dataForMBeanOperations.values();
          for (Object cd : results) {
            ObjectName objectName = new ObjectName((String) ((CompositeData) cd).get("ObjectName"));
            String method = (String) ((CompositeData) cd).get("Method");
            boolean canInvoke =
                ((CompositeData) cd).get("CanInvoke") != null
                    ? (Boolean) ((CompositeData) cd).get("CanInvoke")
                    : false;
            Object mBeanInfoOrKey =
                domains.get(objectName.getDomain()).get(objectName.getKeyPropertyListString());
            Map<String, Object> mBeanInfo;
            if (mBeanInfoOrKey instanceof Map) {
              mBeanInfo = (Map<String, Object>) mBeanInfoOrKey;
            } else /*if (mBeanInfoOrKey instanceof String) */ {
              mBeanInfo = rbacCache.get(mBeanInfoOrKey.toString());
            }
            if (mBeanInfo != null) {
              ((Map<String, Object>)
                      ((Map<String, Object>) mBeanInfo.get("opByString")).get(method))
                  .put("canInvoke", canInvoke);
            }
          }

          result.remove("cache");
          result.put("cache", rbacCache);
        }
      }
    } catch (Exception e) {
      LOG.error(e.getMessage(), e);
      // simply do not decorate
    }
  }