db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kahat...@apache.org
Subject svn commit: r1624469 - in /db/derby/code/trunk/java: engine/org/apache/derby/iapi/services/cache/ engine/org/apache/derby/iapi/services/jmx/ engine/org/apache/derby/impl/services/cache/ engine/org/apache/derby/impl/services/jmx/ engine/org/apache/derby...
Date Fri, 12 Sep 2014 07:41:13 GMT
Author: kahatlen
Date: Fri Sep 12 07:41:12 2014
New Revision: 1624469

URL: http://svn.apache.org/r1624469
Log:
DERBY-6733: Implement an MBean for monitoring caches

Add a new MBean called CacheManagerMBean, which provides information
about a CacheManager instance.

Create CacheManagerMBean instances for the page cache and the
container cache when a database is booted.

Added:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ConcurrentCacheMBeanImpl.java
  (with props)
    db/derby/code/trunk/java/engine/org/apache/derby/mbeans/CacheManagerMBean.java   (with
props)
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/management/CacheManagerMBeanTest.java
  (with props)
Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/cache/CacheManager.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/jmx/ManagementService.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ClockPolicy.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ConcurrentCache.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ReplacementPolicy.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/jmx/JMXManagementService.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/jmxnone/NoManagementService.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/BaseDataFileFactory.java
    db/derby/code/trunk/java/engine/org/apache/derby/security/SystemPermission.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/management/MBeanTest.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/management/_Suite.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/derby_tests.policy

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/cache/CacheManager.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/cache/CacheManager.java?rev=1624469&r1=1624468&r2=1624469&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/cache/CacheManager.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/cache/CacheManager.java
Fri Sep 12 07:41:12 2014
@@ -269,4 +269,14 @@ public interface CacheManager {
 	 * @return a Collection of all the elements in the cache
 	 */
 	public Collection values();
+
+    /**
+     * Register an MBean that allows user to monitor this cache instance.
+     * This is a no-op if the platform does not support Java Management
+     * Extensions (JMX).
+     *
+     * @param dbName the unique name of the database to which the cache belongs
+     * @throws StandardException if an error occurs when registering the MBean
+     */
+    void registerMBean(String dbName) throws StandardException;
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/jmx/ManagementService.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/jmx/ManagementService.java?rev=1624469&r1=1624468&r2=1624469&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/jmx/ManagementService.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/jmx/ManagementService.java
Fri Sep 12 07:41:12 2014
@@ -22,10 +22,8 @@
 package org.apache.derby.iapi.services.jmx;
 
 import org.apache.derby.iapi.error.StandardException;
-import org.apache.derby.iapi.reference.Module;
 import org.apache.derby.mbeans.ManagementMBean;
 
-
 /**
 * This interface represents a Management Service. An implementation of this 
 * service is started by the Derby monitor if the system property derby.system.jmx has
@@ -60,7 +58,7 @@ public interface ManagementService exten
      * type should be first with a short name for the bean, typically the
      * class name without the package.
      * 
-     * @return An idenitifier that can later be used to unregister the mbean.
+     * @return An identifier that can later be used to unregister the mbean.
      */
     public <T> Object registerMBean(T bean,
             Class<T> beanInterface,
@@ -73,4 +71,15 @@ public interface ManagementService exten
      * @param mbeanIdentifier An identifier returned by registerMBean.
      */
     public void unregisterMBean(Object mbeanIdentifier);
+
+    /**
+     * Quote an MBean key property value, so that it is safe to pass to
+     * {@link #registerMBean} even if it potentially contains special
+     * characters.
+     *
+     * @param value the value to quote
+     * @return the quoted value
+     * @see javax.management.ObjectName#quote(String)
+     */
+    String quotePropertyValue(String value);
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ClockPolicy.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ClockPolicy.java?rev=1624469&r1=1624468&r2=1624469&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ClockPolicy.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ClockPolicy.java
Fri Sep 12 07:41:12 2014
@@ -134,6 +134,11 @@ final class ClockPolicy implements Repla
         clock = new ArrayList<Holder>(initialSize);
     }
 
+    @Override
+    public int freeEntries() {
+        return freeEntries.get();
+    }
+
     /**
      * Insert an entry into the cache. If the maximum size is exceeded, evict a
      * <em>not recently used</em> object from the cache. If there are no

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ConcurrentCache.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ConcurrentCache.java?rev=1624469&r1=1624468&r2=1624469&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ConcurrentCache.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ConcurrentCache.java
Fri Sep 12 07:41:12 2014
@@ -24,14 +24,19 @@ package org.apache.derby.impl.services.c
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicLong;
 import org.apache.derby.iapi.error.StandardException;
+import org.apache.derby.iapi.reference.Module;
 import org.apache.derby.iapi.reference.SQLState;
 import org.apache.derby.iapi.services.cache.CacheManager;
 import org.apache.derby.iapi.services.cache.Cacheable;
 import org.apache.derby.iapi.services.cache.CacheableFactory;
 import org.apache.derby.iapi.services.daemon.DaemonService;
+import org.apache.derby.iapi.services.jmx.ManagementService;
+import org.apache.derby.iapi.services.monitor.Monitor;
 import org.apache.derby.shared.common.sanity.SanityManager;
 import org.apache.derby.iapi.util.Matchable;
+import org.apache.derby.mbeans.CacheManagerMBean;
 
 /**
  * A cache manager based on the utilities found in the
@@ -62,6 +67,19 @@ final class ConcurrentCache implements C
     /** Replacement policy to be used for this cache. */
     private final ReplacementPolicy replacementPolicy;
 
+    // Fields used by the MBean that monitors this instance.
+
+    /** The identifier of the MBean that allows monitoring of this instance. */
+    private Object mbean;
+    /** Flag that tells if hit/miss/eviction counts should be collected. */
+    private volatile boolean collectAccessCounts;
+    /** The number of cache hits. */
+    private final AtomicLong hits = new AtomicLong();
+    /** The number of cache misses. */
+    private final AtomicLong misses = new AtomicLong();
+    /** The number of evictions from the cache. */
+    private final AtomicLong evictions = new AtomicLong();
+
     /**
      * Flag that indicates whether this cache instance has been shut down. When
      * it has been stopped, <code>find()</code>, <code>findCached()</code>
and
@@ -187,6 +205,7 @@ final class ConcurrentCache implements C
         CacheEntry entry = cache.remove(key);
         entry.getCacheable().clearIdentity();
         entry.setCacheable(null);
+        countEviction();
     }
 
     /**
@@ -277,11 +296,13 @@ final class ConcurrentCache implements C
                 // The object is already cached. Increase the use count and
                 // return it.
                 entry.keep(true);
+                countHit();
                 return item;
             } else {
                 // The object is not cached. Insert the entry into a free
                 // slot and retrieve a reusable Cacheable.
                 item = insertIntoFreeSlot(key, entry);
+                countMiss();
             }
         } finally {
             entry.unlock();
@@ -322,6 +343,7 @@ final class ConcurrentCache implements C
         CacheEntry entry = cache.get(key);
         if (entry == null) {
             // No such object was found in the cache.
+            countMiss();
             return null;
         }
 
@@ -332,11 +354,15 @@ final class ConcurrentCache implements C
             // for it to complete so that we don't return a cacheable that
             // isn't fully initialized.
             entry.waitUntilIdentityIsSet();
+
             // Return the cacheable. If the entry was removed right before we
             // locked it, getCacheable() returns null and so should we do.
             Cacheable item = entry.getCacheable();
             if (item != null) {
+                countHit();
                 entry.keep(true);
+            } else {
+                countMiss();
             }
             return item;
         } finally {
@@ -599,6 +625,14 @@ final class ConcurrentCache implements C
         if (cleaner != null) {
             cleaner.unsubscribe();
         }
+
+        if (mbean != null) {
+            ManagementService managementService =
+                (ManagementService) Monitor.getSystemModule(Module.JMX);
+            if (managementService != null) {
+                managementService.unregisterMBean(mbean);
+            }
+        }
     }
 
     /**
@@ -681,4 +715,83 @@ final class ConcurrentCache implements C
         }
         return values;
     }
+
+    @Override
+    public void registerMBean(String dbName) throws StandardException {
+        if (SanityManager.DEBUG) {
+            SanityManager.ASSERT(mbean == null, "registerMBean() called twice");
+        }
+
+        ManagementService managementService =
+                (ManagementService) Monitor.getSystemModule(Module.JMX);
+
+        if (managementService != null) {
+            mbean = managementService.registerMBean(
+                    new ConcurrentCacheMBeanImpl(this),
+                    CacheManagerMBean.class,
+                    "type=CacheManager,name=" + name +
+                    ",db=" + managementService.quotePropertyValue(dbName));
+        }
+    }
+
+    /** Count a cache hit. */
+    private void countHit() {
+        if (collectAccessCounts) {
+            hits.getAndIncrement();
+        }
+    }
+
+    /** Count a cache miss. */
+    private void countMiss() {
+        if (collectAccessCounts) {
+            misses.getAndIncrement();
+        }
+    }
+
+    /** Count an eviction from the cache. */
+    private void countEviction() {
+        if (collectAccessCounts) {
+            evictions.getAndIncrement();
+        }
+    }
+
+    /** Enable or disable collection of hit/miss/eviction counts. */
+    void setCollectAccessCounts(boolean collect) {
+        collectAccessCounts = collect;
+    }
+
+    /** Check if collection of hit/miss/eviction counts is enabled. */
+    boolean getCollectAccessCounts() {
+        return collectAccessCounts;
+    }
+
+    /** Get the number of cache hits. */
+    long getHitCount() {
+        return hits.get();
+    }
+
+    /** Get the number of cache misses. */
+    long getMissCount() {
+        return misses.get();
+    }
+
+    /** Get the number of evictions from the cache. */
+    long getEvictionCount() {
+        return evictions.get();
+    }
+
+    /** Get the maximum number of entries in the cache. */
+    long getMaxEntries() {
+        return maxSize;
+    }
+
+    /** Get the number of allocated entries. */
+    long getAllocatedEntries() {
+        return cache.size();
+    }
+
+    /** Get the number of allocated entries that hold valid objects. */
+    long getUsedEntries() {
+        return cache.size() - replacementPolicy.freeEntries();
+    }
 }

Added: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ConcurrentCacheMBeanImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ConcurrentCacheMBeanImpl.java?rev=1624469&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ConcurrentCacheMBeanImpl.java
(added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ConcurrentCacheMBeanImpl.java
Fri Sep 12 07:41:12 2014
@@ -0,0 +1,102 @@
+/*
+
+   Derby - Class org.apache.derby.impl.services.cache.ConcurrentCacheMBeanImpl
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to you under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+
+package org.apache.derby.impl.services.cache;
+
+import java.security.AccessControlException;
+import java.security.AccessController;
+import org.apache.derby.mbeans.CacheManagerMBean;
+import org.apache.derby.security.SystemPermission;
+
+/**
+ * This class provides monitoring capabilities for ConcurrentCache through
+ * Java Management Extension (JMX).
+ */
+final class ConcurrentCacheMBeanImpl implements CacheManagerMBean {
+
+    private final ConcurrentCache cache;
+
+    ConcurrentCacheMBeanImpl(ConcurrentCache cache) {
+        this.cache = cache;
+    }
+
+    @Override
+    public void setCollectAccessCounts(boolean collect) {
+        checkPermission();
+        cache.setCollectAccessCounts(collect);
+    }
+
+    @Override
+    public boolean getCollectAccessCounts() {
+        checkPermission();
+        return cache.getCollectAccessCounts();
+    }
+
+    @Override
+    public long getHitCount() {
+        checkPermission();
+        return cache.getHitCount();
+    }
+
+    @Override
+    public long getMissCount() {
+        checkPermission();
+        return cache.getMissCount();
+    }
+
+    @Override
+    public long getEvictionCount() {
+        checkPermission();
+        return cache.getEvictionCount();
+    }
+
+    @Override
+    public long getMaxEntries() {
+        checkPermission();
+        return cache.getMaxEntries();
+    }
+
+    @Override
+    public long getAllocatedEntries() {
+        checkPermission();
+        return cache.getAllocatedEntries();
+    }
+
+    @Override
+    public long getUsedEntries() {
+        checkPermission();
+        return cache.getUsedEntries();
+    }
+
+    private static void checkPermission() {
+        if (System.getSecurityManager() != null) {
+            try {
+                AccessController.checkPermission(
+                        SystemPermission.ENGINE_MONITOR);
+            } catch (AccessControlException ace) {
+                // Need to throw a simplified version as AccessControlException
+                // will have a reference to Derby's SystemPermission class,
+                // which most likely will not be available on the client.
+                throw new SecurityException(ace.getMessage());
+            }
+        }
+    }
+}

Propchange: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ConcurrentCacheMBeanImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ReplacementPolicy.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ReplacementPolicy.java?rev=1624469&r1=1624468&r2=1624469&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ReplacementPolicy.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ReplacementPolicy.java
Fri Sep 12 07:41:12 2014
@@ -56,6 +56,14 @@ interface ReplacementPolicy {
     void doShrink();
 
     /**
+     * Get the number of free entries that could be reused for new objects
+     * without growing the cache.
+     *
+     * @return the number of free entries
+     */
+    int freeEntries();
+
+    /**
      * The interface for the callback objects that <code>ConcurrentCache</code>
      * uses to notify the replacement algorithm about events such as look-ups
      * and removals. Each <code>Callback</code> object is associated with a

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/jmx/JMXManagementService.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/jmx/JMXManagementService.java?rev=1624469&r1=1624468&r2=1624469&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/jmx/JMXManagementService.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/jmx/JMXManagementService.java
Fri Sep 12 07:41:12 2014
@@ -424,4 +424,9 @@ public final class JMXManagementService 
     public synchronized String getSystemIdentifier() {
         return systemIdentifier;
     }
+
+    @Override
+    public String quotePropertyValue(String value) {
+        return ObjectName.quote(value);
+    }
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/jmxnone/NoManagementService.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/jmxnone/NoManagementService.java?rev=1624469&r1=1624468&r2=1624469&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/jmxnone/NoManagementService.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/jmxnone/NoManagementService.java
Fri Sep 12 07:41:12 2014
@@ -25,7 +25,7 @@ import org.apache.derby.iapi.services.jm
 
 /** 
  * Dummy management service for environments that do not support
- * JMX, such as JDK 1.4 and J2ME.
+ * JMX, such as Java SE compact profile 2.
 */
 public final class NoManagementService implements ManagementService {
     public NoManagementService() {
@@ -48,4 +48,7 @@ public final class NoManagementService i
     public String getSystemIdentifier() {
         return null;
     }
+    public String quotePropertyValue(String value) {
+        return null;
+    }
 }
\ No newline at end of file

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/BaseDataFileFactory.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/BaseDataFileFactory.java?rev=1624469&r1=1624468&r2=1624469&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/BaseDataFileFactory.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/BaseDataFileFactory.java
Fri Sep 12 07:41:12 2014
@@ -442,6 +442,11 @@ public class BaseDataFileFactory
             cf.newCacheManager(
                 this, "ContainerCache", fileCacheSize / 2, fileCacheSize);
 
+        // Register MBeans that allow users to monitor the page cache
+        // and the container cache.
+        pageCache.registerMBean(dataDirectory);
+        containerCache.registerMBean(dataDirectory);
+
 		if (create)
 		{
 			String noLog =

Added: db/derby/code/trunk/java/engine/org/apache/derby/mbeans/CacheManagerMBean.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/mbeans/CacheManagerMBean.java?rev=1624469&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/mbeans/CacheManagerMBean.java (added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/mbeans/CacheManagerMBean.java Fri Sep
12 07:41:12 2014
@@ -0,0 +1,99 @@
+/*
+
+   Derby - Class org.apache.derby.mbeans.CacheManagerMBean
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to you under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+
+package org.apache.derby.mbeans;
+
+/**
+ * This is an MBean that provides information about one of Derby's cache
+ * managers.
+ */
+public interface CacheManagerMBean {
+    /**
+     * Enable or disable collection of cache access counts. That is, whether
+     * or not each hit, miss and eviction should be counted. Enabling it might
+     * impose a small overhead on cache accesses, and might reduce the system
+     * performance. Access counts are disabled by default.
+     *
+     * @param collect {@code true} if access counts should be collected, or
+     *                {@code false} otherwise
+     * @see #getCollectAccessCounts()
+     * @see #getHitCount()
+     * @see #getMissCount()
+     * @see #getEvictionCount()
+     */
+    void setCollectAccessCounts(boolean collect);
+
+    /**
+     * Check if collection of cache access counts is enabled.
+     *
+     * @return {@code true} if access counts are enabled,
+     *         {@code false} otherwise
+     * @see #setCollectAccessCounts(boolean)
+     */
+    boolean getCollectAccessCounts();
+
+    /**
+     * Get the number of cache accesses where the requested object was
+     * already in the cache.
+     *
+     * @return the number of cache hits
+     */
+    long getHitCount();
+
+    /**
+     * Get the number of cache accesses where the requested object was
+     * not already in the cache.
+     *
+     * @return the number of cache misses
+     */
+    long getMissCount();
+
+    /**
+     * Get the number of cached objects that have been evicted from the
+     * cache in order to make room for other objects.
+     *
+     * @return the number of evicted objects
+     */
+    long getEvictionCount();
+
+    /**
+     * Get the maximum number of entries that could be held by this cache.
+     *
+     * @return the maximum number of entries in the cache
+     */
+    long getMaxEntries();
+
+    /**
+     * Get the number of entries currently allocated in the cache. This
+     * number includes entries for objects that have been removed from the
+     * cache, whose entries have not yet been reused for other objects.
+     *
+     * @return the number of entries in the cache
+     */
+    long getAllocatedEntries();
+
+    /**
+     * Get the number of objects that are currently in the cache.
+     *
+     * @return the number of objects in the cache
+     */
+    long getUsedEntries();
+}

Propchange: db/derby/code/trunk/java/engine/org/apache/derby/mbeans/CacheManagerMBean.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/engine/org/apache/derby/security/SystemPermission.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/security/SystemPermission.java?rev=1624469&r1=1624468&r2=1624469&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/security/SystemPermission.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/security/SystemPermission.java Fri Sep
12 07:41:12 2014
@@ -117,6 +117,10 @@ final public class SystemPermission exte
         LEGAL_ACTIONS.add(SHUTDOWN);
     }
     
+    /** Constant representing {@code SystemPermission("engine, "monitor")}. */
+    public static final SystemPermission ENGINE_MONITOR =
+            new SystemPermission(ENGINE, MONITOR);
+
     /**
      * Actions for this permission.
      */

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/management/CacheManagerMBeanTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/management/CacheManagerMBeanTest.java?rev=1624469&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/management/CacheManagerMBeanTest.java
(added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/management/CacheManagerMBeanTest.java
Fri Sep 12 07:41:12 2014
@@ -0,0 +1,192 @@
+/*
+
+   Derby - Class org.apache.derbyTesting.functionTests.tests.management.CacheManagerMBeanTest
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to you under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+
+package org.apache.derbyTesting.functionTests.tests.management;
+
+import java.sql.PreparedStatement;
+import java.util.Hashtable;
+import java.util.Set;
+import javax.management.ObjectName;
+import junit.framework.Test;
+import org.apache.derbyTesting.junit.JDBC;
+import org.apache.derbyTesting.junit.TestConfiguration;
+
+/**
+ * Test cases for {@code CacheManagerMBean}.
+ */
+public class CacheManagerMBeanTest extends MBeanTest {
+
+    public CacheManagerMBeanTest(String name) {
+        super(name);
+    }
+
+    public static Test suite() {
+        return MBeanTest.suite(CacheManagerMBeanTest.class,
+                               "CacheManagerMBeanTest");
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        // Set up management.
+        super.setUp();
+
+        // Shut down the database before running the test case, so that the
+        // test case can assume that it starts from a clean state where the
+        // cache beans have not started yet. shutdownDatabase() fails if
+        // the database is not already booted, so get a connection first to
+        // ensure that it is booted (otherwise, the test will fail if it
+        // runs standalone or first in a suite).
+        getConnection().close();
+        TestConfiguration.getCurrent().shutdownDatabase();
+    }
+
+    /**
+     * Create an {@code ObjectName} that identifies a {@code CacheManager}
+     * management bean, or a pattern that potentially matches multiple
+     * beans.
+     *
+     * @param cacheName the name of the cache (such as PageCache), or
+     *   {@code null} to create a pattern that matches all cache names
+     * @param dbName the name of the database, or {@code null} to create
+     *   a pattern that matches all database names
+     * @return an {@code ObjectName} suitable for looking up beans
+     */
+    private ObjectName createObjectName(String cacheName, String dbName)
+            throws Exception {
+        Hashtable<String, String> props = new Hashtable<String, String>();
+        props.put("type", "CacheManager");
+        props.put("name", cacheName == null ? "*" : cacheName);
+        props.put("db", dbName == null ? "*" : ObjectName.quote(dbName));
+        return getDerbyMBeanName(props);
+    }
+
+    /**
+     * Test case that verifies that {@code CacheManagerMBean}s start when
+     * a database is started, and stop when the database is shut down.
+     */
+    public void testAllMBeansStartedAndStopped() throws Exception {
+        // This pattern matches all CacheManager management beans when used
+        // in a query.
+        ObjectName pattern = createObjectName(null, null);
+
+        // There should be no CacheManager MBeans before the database
+        // is booted.
+        Set<ObjectName> names = queryMBeans(pattern);
+        if (!names.isEmpty()) {
+            fail("Should not find MBeans before boot, found: " + names);
+        }
+
+        // Boot the database, so that the MBeans are started.
+        getConnection();
+
+        // There should be two CacheManager beans. One for the page cache
+        // and one for the container cache.
+        names = queryMBeans(pattern);
+        assertEquals("Incorrect number of MBeans found in " + names,
+                     2, names.size());
+
+        // Shut down the database.
+        TestConfiguration.getCurrent().shutdownDatabase();
+
+        // There should be no CacheManager MBeans after the database has
+        // been shut down.
+        names = queryMBeans(pattern);
+        if (!names.isEmpty()) {
+            fail("Should not find MBeans after shutdown, found: " + names);
+        }
+    }
+
+    /**
+     * Test the {@code CacheManagerMBean} for the page cache.
+     */
+    public void testPageCache() throws Exception {
+        getConnection(); // boot the database
+        Set<ObjectName> names =
+                queryMBeans(createObjectName("PageCache", null));
+
+        assertEquals("Should have a single page cache", 1, names.size());
+
+        ObjectName name = names.iterator().next();
+
+        assertBooleanAttribute(false, name, "CollectAccessCounts");
+        assertLongAttribute(0, name, "HitCount");
+        assertLongAttribute(0, name, "MissCount");
+        assertLongAttribute(0, name, "EvictionCount");
+        // Default page cache size is 1000
+        assertLongAttribute(1000, name, "MaxEntries");
+        // Cannot reliably tell how many entries to expect.
+        // More than 0 for sure.
+        Long allocated = (Long) getAttribute(name, "AllocatedEntries");
+        assertTrue("Allocated entries: " + allocated, allocated > 0);
+        Long used = (Long) getAttribute(name, "UsedEntries");
+        assertTrue("Used entries: " + used, used > 0);
+
+        // Execute a statement against a table, so that the cache will be
+        // accessed.
+        PreparedStatement ps = prepareStatement(
+                                    "select * from sysibm.sysdummy1");
+        JDBC.assertDrainResults(ps.executeQuery());
+
+        // Since collection of access counts is disabled by default, don't
+        // expect the counts to be updated.
+        assertLongAttribute(0, name, "HitCount");
+        assertLongAttribute(0, name, "MissCount");
+        assertLongAttribute(0, name, "EvictionCount");
+
+        // Now enable the access counts and re-execute the query. It
+        // should result in a hit in the page cache.
+        setAttribute(name, "CollectAccessCounts", Boolean.TRUE);
+        assertBooleanAttribute(true, name, "CollectAccessCounts");
+        JDBC.assertDrainResults(ps.executeQuery());
+        assertLongAttribute(1, name, "HitCount");
+        assertLongAttribute(0, name, "MissCount");
+
+        // Disable the access counts.
+        setAttribute(name, "CollectAccessCounts", Boolean.FALSE);
+        assertBooleanAttribute(false, name, "CollectAccessCounts");
+    }
+
+    /**
+     * Test the {@code CacheManagerMBean} for the page cache.
+     */
+    public void testContainerCache() throws Exception {
+        getConnection(); // boot the database
+        Set<ObjectName> names =
+                queryMBeans(createObjectName("ContainerCache", null));
+
+        assertEquals("Should have a single container cache", 1, names.size());
+
+        ObjectName name = names.iterator().next();
+
+        assertBooleanAttribute(false, name, "CollectAccessCounts");
+        assertLongAttribute(0, name, "HitCount");
+        assertLongAttribute(0, name, "MissCount");
+        assertLongAttribute(0, name, "EvictionCount");
+        // Default container cache size is 100
+        assertLongAttribute(100, name, "MaxEntries");
+        // Cannot reliably tell how many entries to expect.
+        // More than 0 for sure.
+        Long allocated = (Long) getAttribute(name, "AllocatedEntries");
+        assertTrue("Allocated entries: " + allocated, allocated > 0);
+        Long used = (Long) getAttribute(name, "UsedEntries");
+        assertTrue("Used entries: " + used, used > 0);
+    }
+}

Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/management/CacheManagerMBeanTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/management/MBeanTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/management/MBeanTest.java?rev=1624469&r1=1624468&r2=1624469&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/management/MBeanTest.java
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/management/MBeanTest.java
Fri Sep 12 07:41:12 2014
@@ -27,6 +27,7 @@ import java.security.PrivilegedException
 import java.util.ArrayList;
 import java.util.Hashtable;
 import java.util.Set;
+import javax.management.Attribute;
 import javax.management.AttributeNotFoundException;
 import javax.management.InstanceAlreadyExistsException;
 import javax.management.InstanceNotFoundException;
@@ -252,12 +253,21 @@ abstract class MBeanTest extends BaseJDB
     protected Set<ObjectName> getDerbyDomainMBeans() throws Exception
     {
         final ObjectName derbyDomain = new ObjectName("org.apache.derby:*");
+        return queryMBeans(derbyDomain);
+    }
+
+    /**
+     * Get all MBeans that match the specified name.
+     * @param name the name pattern to look for
+     * @return a set of names that match
+     */
+    Set<ObjectName> queryMBeans(final ObjectName name) throws Exception {
         final MBeanServerConnection serverConn = getMBeanServerConnection(); 
         
         return AccessController.doPrivileged(
             new PrivilegedExceptionAction<Set<ObjectName>>() {
                 public Set<ObjectName> run() throws IOException {
-                    return serverConn.queryNames(derbyDomain, null);
+                    return serverConn.queryNames(name, null);
                }   
             }
         );   
@@ -358,6 +368,27 @@ abstract class MBeanTest extends BaseJDB
             }
         );
     }
+
+    /**
+     * Set the value of an attribute via JMX.
+     *
+     * @param objName the name of the object that has the attribute
+     * @param name the name of the attribute
+     * @param value the new value of the attribute
+     * @throws Exception if an error occurs when changing the attribute
+     */
+    void setAttribute(final ObjectName objName, String name, Object value)
+            throws Exception {
+        final MBeanServerConnection jmxConn = getMBeanServerConnection();
+        final Attribute attribute = new Attribute(name, value);
+        AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
+            @Override
+            public Void run() throws Exception {
+                jmxConn.setAttribute(objName, attribute);
+                return null;
+            }
+        });
+    }
     
     /**
      * Gets the value of a given attribute that is exposed by the MBean 

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/management/_Suite.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/management/_Suite.java?rev=1624469&r1=1624468&r2=1624469&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/management/_Suite.java
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/management/_Suite.java
Fri Sep 12 07:41:12 2014
@@ -60,6 +60,7 @@ public class _Suite extends BaseTestCase
             suite.addTest(JDBCMBeanTest.suite());
             suite.addTest(NetworkServerMBeanTest.suite());
             suite.addTest(CustomMBeanServerBuilderTest.suite());
+            suite.addTest(CacheManagerMBeanTest.suite());
         }
 
         return suite;

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/derby_tests.policy
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/derby_tests.policy?rev=1624469&r1=1624468&r2=1624469&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/derby_tests.policy
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/derby_tests.policy
Fri Sep 12 07:41:12 2014
@@ -271,7 +271,7 @@ grant codeBase "${derbyTesting.testjar}d
   permission javax.management.MBeanTrustPermission "register";
    
   // And to find and use Derby's MBeans
-  permission javax.management.MBeanPermission "org.apache.derby.mbeans.*#[org.apache.derby:*]",
"getAttribute,invoke";
+  permission javax.management.MBeanPermission "org.apache.derby.mbeans.*#[org.apache.derby:*]",
"getAttribute,setAttribute,invoke";
   permission javax.management.MBeanPermission "org.apache.derby.mbeans.*#-[org.apache.derby:*]",
"getMBeanInfo";
   permission javax.management.MBeanPermission "-#-[-]", "queryNames";
   permission javax.management.MBeanPermission "org.apache.derby.mbeans.*#-[org.apache.derby:*]",
"queryNames";
@@ -372,7 +372,7 @@ grant codeBase "${derbyTesting.codeclass
   
    
   // And to find and use Derby's MBeans
-  permission javax.management.MBeanPermission "org.apache.derby.mbeans.*#[org.apache.derby:*]",
"getAttribute,invoke";
+  permission javax.management.MBeanPermission "org.apache.derby.mbeans.*#[org.apache.derby:*]",
"getAttribute,setAttribute,invoke";
   permission javax.management.MBeanPermission "org.apache.derby.mbeans.*#-[org.apache.derby:*]",
"getMBeanInfo";
   permission javax.management.MBeanPermission "-#-[-]", "queryNames";
   permission javax.management.MBeanPermission "org.apache.derby.mbeans.*#-[org.apache.derby:*]",
"queryNames";



Mime
View raw message