OPENJPA-1739 Rev 1 of pluggable instrumentation for OpenJPA. Includes an test provider and portions of a JMX platform MBean based provider.

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@981719 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Jeremy Bauer 2010-08-03 01:55:02 +00:00
parent e65737308b
commit 733adeb47b
33 changed files with 2740 additions and 1 deletions

View File

@ -32,6 +32,7 @@ import org.apache.openjpa.event.LifecycleEventManager;
import org.apache.openjpa.event.OrphanedKeyAction;
import org.apache.openjpa.event.RemoteCommitEventManager;
import org.apache.openjpa.event.RemoteCommitProvider;
import org.apache.openjpa.instrumentation.InstrumentationManager;
import org.apache.openjpa.kernel.AutoClear;
import org.apache.openjpa.kernel.AutoDetach;
import org.apache.openjpa.kernel.BrokerFactory;
@ -1836,6 +1837,31 @@ public interface OpenJPAConfiguration
* @since 2.0.0
*/
public void setCacheDistributionPolicy(String policyPlugin);
/**
* Gets the plug-in string that defines instrumentation providers and what
* they instrument.
* @return a plug-in string for the instrumentation configuration
* @since 2.1.0
*/
public String getInstrumentation();
/**
* Sets the plug-in string that defines instrumentation providers and what
* they instrument.
* @param providers a plug-in string for the instrumentation configuration
* @since 2.1.0
*/
public void setInstrumentation(String providers);
/**
* Gets an instance of the instrumentation manager. The instrumentation
* provides access to configured instrumentation providers and can be used
* to manage them at runtime.
* @return an instance of the instrumentation manager
* @since 2.1.0
*/
public InstrumentationManager getInstrumentationManagerInstance();
}

View File

@ -36,6 +36,8 @@ import org.apache.openjpa.event.LifecycleEventManager;
import org.apache.openjpa.event.OrphanedKeyAction;
import org.apache.openjpa.event.RemoteCommitEventManager;
import org.apache.openjpa.event.RemoteCommitProvider;
import org.apache.openjpa.instrumentation.InstrumentationManager;
import org.apache.openjpa.instrumentation.InstrumentationManagerImpl;
import org.apache.openjpa.kernel.AutoClear;
import org.apache.openjpa.kernel.BrokerImpl;
import org.apache.openjpa.kernel.ConnectionRetainModes;
@ -61,6 +63,8 @@ import org.apache.openjpa.lib.conf.ProductDerivations;
import org.apache.openjpa.lib.conf.StringListValue;
import org.apache.openjpa.lib.conf.StringValue;
import org.apache.openjpa.lib.encryption.EncryptionProvider;
import org.apache.openjpa.lib.instrumentation.InstrumentationLevel;
import org.apache.openjpa.lib.instrumentation.InstrumentationProvider;
import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.meta.MetaDataFactory;
@ -167,6 +171,8 @@ public class OpenJPAConfigurationImpl
public StringValue validationGroupPreRemove;
public StringValue dataCacheMode;
public BooleanValue dynamicEnhancementAgent;
public ObjectValue instrumentationManager;
public PluginListValue instrumentationProviders;
// custom values
public BrokerFactoryValue brokerFactoryPlugin;
@ -569,6 +575,19 @@ public class OpenJPAConfigurationImpl
dynamicEnhancementAgent.setDefault("true");
dynamicEnhancementAgent.set(true);
instrumentationManager = addPlugin("InstrumentationManager", true);
aliases =
new String[] { "default", InstrumentationManagerImpl.class.getName(), };
instrumentationManager.setAliases(aliases);
instrumentationManager.setDefault(aliases[0]);
instrumentationManager.setString(aliases[0]);
instrumentationManager.setInstantiatingGetter("getInstrumentationManager");
instrumentationProviders = addPluginList("Instrumentation");
aliases = new String[] { "jmx", "org.apache.openjpa.instrumentation.jmx.JMXProvider" };
instrumentationProviders.setAliases(aliases);
instrumentationProviders.setInstantiatingGetter("getInstrumentationInstances");
// initialize supported options that some runtimes may not support
supportedOptions.add(OPTION_NONTRANS_READ);
supportedOptions.add(OPTION_OPTIMISTIC);
@ -1589,6 +1608,46 @@ public class OpenJPAConfigurationImpl
return vgPreRemove;
}
public String getInstrumentation() {
return instrumentationProviders.getString();
}
public void setInstrumentation(String providers) {
instrumentationProviders.setString(providers);
}
public InstrumentationProvider[] getInstrumentationInstances() {
if (instrumentationProviders.get() == null)
instrumentationProviders.instantiate(InstrumentationProvider.class, this);
return (InstrumentationProvider[]) instrumentationProviders.get();
}
public void setInstrumentationManager(String mgr) {
instrumentationManager.setString(mgr);
}
public String getInstrumentationManager() {
return instrumentationManager.getString();
}
public void setInstrumentationManager(InstrumentationManager im) {
if (im != null)
im.initialize(this, instrumentationProviders);
instrumentationManager.set(im);
}
public InstrumentationManager getInstrumentationManagerInstance() {
InstrumentationManager im = (InstrumentationManager) instrumentationManager.get();
if (im == null) {
im = (InstrumentationManager) instrumentationManager.instantiate(InstrumentationManager.class, this);
if (im != null) {
im.initialize(this, instrumentationProviders);
im.start(InstrumentationLevel.IMMEDIATE, this);
}
}
return im;
}
public void instantiateAll() {
super.instantiateAll();
getMetaDataRepositoryInstance();
@ -1603,6 +1662,7 @@ public class OpenJPAConfigurationImpl
protected void preClose() {
ImplHelper.close(metaRepository);
ImplHelper.close(remoteEventManager);
ImplHelper.close(getInstrumentationManagerInstance());
super.preClose();
}

View File

@ -0,0 +1,238 @@
/*
* 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.openjpa.instrumentation;
import java.util.Date;
import org.apache.openjpa.datacache.CacheStatistics;
import org.apache.openjpa.datacache.DataCache;
import org.apache.openjpa.lib.instrumentation.AbstractInstrument;
import org.apache.openjpa.lib.instrumentation.InstrumentationLevel;
/**
* Provides a basic instrument implementation wrapper for the data cache. This
* class can be extended to create a provider specific instrument for the
* data cache.
*/
public abstract class AbstractDataCacheInstrument extends AbstractInstrument
implements DataCacheInstrument {
/**
* Value indicating that cache statistics are not available.
*/
public static final long NO_STATS = -1;
private DataCache _dc = null;
private String _configID = null;
private String _configRef = null;
public void setDataCache(DataCache dc) {
_dc = dc;
}
public void setConfigId(String cid) {
_configID = cid;
}
public void setContextRef(String cref) {
_configRef = cref;
}
public long getHitCount() {
CacheStatistics stats = getStatistics();
if (stats != null)
return stats.getHitCount();
return NO_STATS;
}
public long getHitCount(String className)
throws ClassNotFoundException {
Class<?> clazz = Class.forName(className);
return getHitCount(clazz);
}
public long getReadCount() {
CacheStatistics stats = getStatistics();
if (stats != null)
return stats.getReadCount();
return NO_STATS;
}
public long getReadCount(String className)
throws ClassNotFoundException {
Class<?> clazz = Class.forName(className);
return getReadCount(clazz);
}
public long getTotalHitCount() {
CacheStatistics stats = getStatistics();
if (stats != null)
return stats.getTotalHitCount();
return NO_STATS;
}
public long getTotalHitCount(String className)
throws ClassNotFoundException {
Class<?> clazz = Class.forName(className);
return getTotalHitCount(clazz);
}
public long getTotalReadCount() {
CacheStatistics stats = getStatistics();
if (stats != null)
return stats.getTotalReadCount();
return NO_STATS;
}
public long getTotalReadCount(String className)
throws ClassNotFoundException {
Class<?> clazz = Class.forName(className);
return getTotalReadCount(clazz);
}
public long getTotalWriteCount() {
CacheStatistics stats = getStatistics();
if (stats != null)
return stats.getTotalWriteCount();
return NO_STATS;
}
public long getTotalWriteCount(String className)
throws ClassNotFoundException {
Class<?> clazz = Class.forName(className);
return getTotalWriteCount(clazz);
}
public long getWriteCount() {
CacheStatistics stats = getStatistics();
if (stats != null)
return stats.getWriteCount();
return NO_STATS;
}
public long getWriteCount(String className)
throws ClassNotFoundException {
Class<?> clazz = Class.forName(className);
return getWriteCount(clazz);
}
public void reset() {
CacheStatistics stats = getStatistics();
if (stats != null)
stats.reset();
}
public Date sinceDate() {
CacheStatistics stats = getStatistics();
if (stats != null)
return stats.since();
return null;
}
public Date startDate() {
CacheStatistics stats = getStatistics();
if (stats != null)
return stats.start();
return null;
}
public long getEvictionCount() {
CacheStatistics stats = getStatistics();
// TODO : Implement eviction count in data cache stats
// if (stats != null)
// return stats.getEvictionCount();
return NO_STATS;
}
public long getTotalEvictionCount() {
CacheStatistics stats = getStatistics();
// TODO : Implement eviction count in data cache stats
// if (stats != null)
// return stats.getTotalEvictionCount();
return NO_STATS;
}
public String getConfigId() {
return _configID;
}
public String getContextRef() {
return _configRef;
}
public String getCacheName() {
if (_dc != null)
return _dc.getName();
return null;
}
private CacheStatistics getStatistics() {
if (_dc != null) {
return _dc.getStatistics();
}
return null;
}
private long getWriteCount(Class<?> c) {
CacheStatistics stats = getStatistics();
if (stats != null)
return stats.getWriteCount(c);
return NO_STATS;
}
private long getTotalWriteCount(Class<?> c) {
CacheStatistics stats = getStatistics();
if (stats != null)
return stats.getTotalWriteCount(c);
return NO_STATS;
}
private long getTotalReadCount(Class<?> c) {
CacheStatistics stats = getStatistics();
if (stats != null)
return stats.getTotalReadCount(c);
return NO_STATS;
}
private long getTotalHitCount(Class<?> c) {
CacheStatistics stats = getStatistics();
if (stats != null)
return stats.getTotalHitCount(c);
return NO_STATS;
}
private long getReadCount(Class<?> c) {
CacheStatistics stats = getStatistics();
if (stats != null)
stats.getReadCount(c);
return NO_STATS;
}
private long getHitCount(Class<?> c) {
CacheStatistics stats = getStatistics();
if (stats != null)
return stats.getHitCount(c);
return NO_STATS;
}
public InstrumentationLevel getLevel() {
return InstrumentationLevel.FACTORY;
}
}

View File

@ -0,0 +1,147 @@
/*
* 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.openjpa.instrumentation;
import java.util.Date;
import org.apache.openjpa.kernel.PreparedQueryCache;
import org.apache.openjpa.kernel.QueryStatistics;
import org.apache.openjpa.lib.instrumentation.AbstractInstrument;
import org.apache.openjpa.lib.instrumentation.InstrumentationLevel;
/**
* Provides a basic instrument implementation wrapper for the prepared query cache. This
* class can be extended to create a provider specific instrument for the
* prepared query cache.
*/
public abstract class AbstractPreparedQueryCacheInstrument extends AbstractInstrument
implements PreparedQueryCacheInstrument {
public static final long NO_STATS = -1;
private PreparedQueryCache _qc;
private String _configID = null;
private String _configRef = null;
public void setConfigId(String cid) {
_configID = cid;
}
public void setContextRef(String cref) {
_configRef = cref;
}
public String getConfigId() {
return _configID;
}
public String getContextRef() {
return _configRef;
}
public void setPreparedQueryCache(PreparedQueryCache qc) {
_qc = qc;
}
private QueryStatistics<String> getStatistics() {
if (_qc == null)
return null;
return _qc.getStatistics();
}
public long getExecutionCount() {
QueryStatistics<String> stats = getStatistics();
if (stats != null)
return stats.getExecutionCount();
return NO_STATS;
}
public long getExecutionCount(String query) {
QueryStatistics<String> stats = getStatistics();
if (stats != null)
return stats.getExecutionCount(query);
return NO_STATS;
}
public long getTotalExecutionCount() {
QueryStatistics<String> stats = getStatistics();
if (stats != null)
return stats.getTotalExecutionCount();
return NO_STATS;
}
public long getTotalExecutionCount(String query) {
QueryStatistics<String> stats = getStatistics();
if (stats != null)
return stats.getTotalExecutionCount(query);
return NO_STATS;
}
public long getHitCount() {
QueryStatistics<String> stats = getStatistics();
if (stats != null)
return stats.getHitCount();
return NO_STATS;
}
public long getHitCount(String query) {
QueryStatistics<String> stats = getStatistics();
if (stats != null)
return stats.getHitCount(query);
return NO_STATS;
}
public long getTotalHitCount() {
QueryStatistics<String> stats = getStatistics();
if (stats != null)
return stats.getTotalHitCount();
return NO_STATS;
}
public long getTotalHitCount(String query) {
QueryStatistics<String> stats = getStatistics();
if (stats != null)
return stats.getTotalHitCount(query);
return NO_STATS;
}
public void reset() {
QueryStatistics<String> stats = getStatistics();
if (stats != null)
stats.reset();
}
public Date sinceDate() {
QueryStatistics<String> stats = getStatistics();
if (stats != null)
return stats.since();
return null;
}
public Date startDate() {
QueryStatistics<String> stats = getStatistics();
if (stats != null)
return stats.start();
return null;
}
public InstrumentationLevel getLevel() {
return InstrumentationLevel.FACTORY;
}
}

View File

@ -0,0 +1,139 @@
/*
* 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.openjpa.instrumentation;
import java.util.Date;
import org.apache.openjpa.datacache.CacheStatistics;
import org.apache.openjpa.datacache.QueryCache;
import org.apache.openjpa.lib.instrumentation.AbstractInstrument;
import org.apache.openjpa.lib.instrumentation.InstrumentationLevel;
/**
* Provides a basic instrument implementation wrapper for the query cache. This
* class can be extended to create a provider specific instrument for the
* query cache.
*/
public abstract class AbstractQueryCacheInstrument extends AbstractInstrument
implements QueryCacheInstrument {
/**
* Value indicating that cache statistics are not available.
*/
public static final long NO_STATS = -1;
private QueryCache _qc;
private String _configId = null;
private String _configRef = null;
public void setQueryCache(QueryCache qc) {
_qc = qc;
}
// TODO : Cache stats must be added to query cache. They will likely be
// tracked by a QueryStatistics type when that takes place.
private CacheStatistics getStatistics() {
if (_qc == null)
return null;
return null; // _qc.getStatistics();
}
public long getHitCount() {
CacheStatistics stats = getStatistics();
if (stats != null)
return stats.getHitCount();
return NO_STATS;
}
public long getReadCount() {
CacheStatistics stats = getStatistics();
if (stats != null)
return stats.getReadCount();
return NO_STATS;
}
public long getTotalHitCount() {
CacheStatistics stats = getStatistics();
if (stats != null)
return stats.getTotalHitCount();
return NO_STATS;
}
public long getTotalReadCount() {
CacheStatistics stats = getStatistics();
if (stats != null)
return stats.getTotalReadCount();
return NO_STATS;
}
public long getTotalWriteCount() {
CacheStatistics stats = getStatistics();
if (stats != null)
return stats.getTotalWriteCount();
return NO_STATS;
}
public long getWriteCount() {
CacheStatistics stats = getStatistics();
if (stats != null)
return stats.getWriteCount();
return NO_STATS;
}
public void reset() {
CacheStatistics stats = getStatistics();
if (stats != null)
stats.reset();
}
public Date sinceDate() {
CacheStatistics stats = getStatistics();
if (stats != null)
return stats.since();
return null;
}
public Date startDate() {
CacheStatistics stats = getStatistics();
if (stats != null)
return stats.start();
return null;
}
public String getConfigId() {
return _configId;
}
public void setConfigId(String cid) {
_configId = cid;
}
public String getContextRef() {
return _configRef;
}
public void setContextRef(String cref) {
_configRef = cref;
}
public InstrumentationLevel getLevel() {
return InstrumentationLevel.FACTORY;
}
}

View File

@ -0,0 +1,122 @@
/*
* 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.openjpa.instrumentation;
import java.util.Date;
/**
* Interface for providing instrumented data cache metrics and operations.
*/
public interface DataCacheInstrument {
/**
* Gets number of total read requests for the given class since last reset.
*/
public long getReadCount(String className) throws ClassNotFoundException;
/**
* Gets number of total read requests that has been found in cache for the
* given class since last reset.
*/
public long getHitCount(String className) throws ClassNotFoundException;
/**
* Gets number of total write requests for the given class since last reset.
*/
public long getWriteCount(String className) throws ClassNotFoundException;
/**
* Gets number of total read requests for the given class since start.
*/
public long getTotalReadCount(String className)
throws ClassNotFoundException;
/**
* Gets number of total read requests that has been found in cache for the
* given class since start.
*/
public long getTotalHitCount(String className)
throws ClassNotFoundException;
/**
* Gets number of total write requests for the given class since start.
*/
public long getTotalWriteCount(String className)
throws ClassNotFoundException;
/**
* Gets the number of cache evictions from the last reset.
*/
public long getEvictionCount();
/**
* Gets the total number of cache evictions since cache start.
*/
public long getTotalEvictionCount();
/**
* Returns the name of the cache
*/
public String getCacheName();
/**
* Returns the hit count since cache statistics were last reset
*/
public long getHitCount();
/**
* Returns the read count since cache statistics were last reset
*/
public long getReadCount();
/**
* Returns the total hits since start.
*/
public long getTotalHitCount();
/**
* Returns the total reads since start.
*/
public long getTotalReadCount();
/**
* Returns the total writes since start.
*/
public long getTotalWriteCount();
/**
* Returns the write count since cache statistics were last reset
*/
public long getWriteCount();
/**
* Resets cache statistics
*/
public void reset();
/**
* Returns date since cache statistics collection were last reset.
*/
public Date sinceDate();
/**
* Returns date cache statistics collection started.
*/
public Date startDate();
}

View File

@ -0,0 +1,30 @@
/*
* 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.openjpa.instrumentation;
/**
* Simple MBean interface for providing instrumented data cache metrics
* and operations.
* Note: Simple MBeans require an MBean interface matching the supplied
* implementation class.
*/
public interface DataCacheInstrumentMBean
extends DataCacheInstrument {
}

View File

@ -0,0 +1,71 @@
/*
* 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.openjpa.instrumentation;
import java.util.Set;
import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.lib.conf.PluginListValue;
import org.apache.openjpa.lib.instrumentation.InstrumentationLevel;
import org.apache.openjpa.lib.instrumentation.InstrumentationProvider;
import org.apache.openjpa.lib.util.Closeable;
/**
* Managers of instrumentation providers must implement this interface. It
* provides methods for initializing multiple providers via configuration in
* addition to managing instrumentation providers and the state of the providers.
*/
public interface InstrumentationManager extends Closeable {
/**
* Used to initialize one or more providers using the supplied configuration.
* @param conf the configuration to use for initialization
* @param providers one or more providers as supplied via plugin list value
*/
public void initialize(OpenJPAConfiguration conf, PluginListValue providers);
/**
* Manage a given provider. This will plug the instruments managed by the
* the provider into the life cycle of the manager
* @param provider the instrumentation provider
*/
public void manageProvider(InstrumentationProvider provider);
/**
* Starts all instruments for all managed providers for a given level
* and context.
* @param level instrumentation level
* @param context instrumentation context (broker, factory, config,...)
*/
public void start(InstrumentationLevel level, Object context);
/**
* Stops all instruments for all managed providers for a given level
* and context.
* @param level instrumentation level
* @param context instrumentation context (broker, factory, config,...)
*/
public void stop(InstrumentationLevel broker, Object context);
/**
* Returns all providers managed by this manager.
* @return all providers managed by this manager
*/
public Set<InstrumentationProvider> getProviders();
}

View File

@ -0,0 +1,108 @@
/*
* 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.openjpa.instrumentation;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.lib.conf.PluginListValue;
import org.apache.openjpa.lib.instrumentation.InstrumentationLevel;
import org.apache.openjpa.lib.instrumentation.InstrumentationProvider;
/**
* An implementation of an instrumentation manager.
*/
public class InstrumentationManagerImpl implements InstrumentationManager {
public Set<InstrumentationProvider> _providers =
Collections.synchronizedSet(new HashSet<InstrumentationProvider>());
private boolean _closed = false;
/**
* Initializes all providers defined for the specified configuration.
* @param conf
* @param providers
*/
public void initialize(OpenJPAConfiguration conf, PluginListValue pluginVal) {
InstrumentationProvider[] providers =
(InstrumentationProvider[])pluginVal.instantiate(InstrumentationProvider.class, conf);
_providers.addAll(Arrays.asList(providers));
}
/**
* Make a provider managed. This will bind its instrumentation to
* InstrumentationLevel type events (factory create/close, broker create/close).
* @param provider
* @param config
*/
public void manageProvider(InstrumentationProvider provider) {
_providers.add(provider);
}
/**
* Returns all providers as an unmodifiable set
*/
public Set<InstrumentationProvider> getProviders() {
return Collections.unmodifiableSet(_providers);
}
/**
* Starts all providers at a specific level and context
*/
public void start(InstrumentationLevel level, Object context) {
if (_providers == null || _providers.size() == 0) {
return;
}
for (InstrumentationProvider provider : _providers) {
if (!provider.isStarted()) {
provider.start();
}
provider.startInstruments(level, context);
}
}
/**
* Stops all providers at a specific level and context
*/
public void stop(InstrumentationLevel level, Object context) {
if (_providers == null || _providers.size() == 0) {
return;
}
for (InstrumentationProvider provider : _providers) {
provider.stopInstruments(level, context);
}
}
/**
* Stops all providers
*/
public void close() throws Exception {
if (_closed) {
return;
}
for (InstrumentationProvider provider : _providers) {
provider.stop();
}
_closed = true;
}
}

View File

@ -0,0 +1,92 @@
/*
* 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.openjpa.instrumentation;
import java.util.Date;
public interface PreparedQueryCacheInstrument {
/**
* Returns number of total exec requests since start.
*/
public long getTotalExecutionCount();
/**
* Returns number of total exec requests since start.
*/
public long getTotalExecutionCount(String query);
/**
* Returns number of total execution requests since last reset
*/
public long getExecutionCount();
/**
* Returns number of total execution requests since last reset
*/
public long getExecutionCount(String query);
/**
* Returns number of total read requests that have been found in cache since
* last reset.
*/
public long getHitCount();
/**
* Returns number of total read requests that have been found in cache since
* last reset.
*/
public long getHitCount(String query);
/**
* Returns number of total read requests that has been found since start.
*/
public long getTotalHitCount();
/**
* Returns number of total read requests that has been found since start.
*/
public long getTotalHitCount(String query);
/**
* Returns the config id for the configuration attached to this cache
*/
public String getConfigId();
/**
* Returns the context unique id for the configuration attached to this
* cache
*/
public String getContextRef();
/**
* Resets cache statistics
*/
public void reset();
/**
* Returns date since cache statistics collection were last reset.
*/
public Date sinceDate();
/**
* Returns date cache statistics collection started.
*/
public Date startDate();
}

View File

@ -0,0 +1,24 @@
/*
* 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.openjpa.instrumentation;
public interface PreparedQueryCacheInstrumentationMBean
extends PreparedQueryCacheInstrument {
}

View File

@ -0,0 +1,84 @@
/*
* 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.openjpa.instrumentation;
import java.util.Date;
/**
* Interface for providing instrumented data cache metrics and operations.
*/
public interface QueryCacheInstrument {
/**
* Returns number of total read requests that have been found in cache since
* last reset.
*/
public long getHitCount();
/**
* Returns number of total read requests since last reset
*/
public long getReadCount();
/**
* Returns number of total write requests since last reset.
*/
public long getWriteCount();
/**
* Returns number of total read requests since start.
*/
public long getTotalReadCount();
/**
* Returns number of total read requests that has been found since start.
*/
public long getTotalHitCount();
/**
* Returns number of total write requests for the given class since start.
*/
public long getTotalWriteCount();
/**
* Returns the config id for the configuration attached to this cache
*/
public String getConfigId();
/**
* Returns the system unique id for the configuration attached to this
* cache
*/
public String getContextRef();
/**
* Resets cache statistics
*/
public void reset();
/**
* Returns date since cache statistics collection were last reset.
*/
public Date sinceDate();
/**
* Returns date cache statistics collection started.
*/
public Date startDate();
}

View File

@ -0,0 +1,29 @@
/*
* 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.openjpa.instrumentation;
/**
* Simple MBean interface for providing instrumented query cache metrics
* and operations.
* Note: Simple MBeans require an MBean interface matching the supplied
* implementation class.
*/
public interface QueryCacheInstrumentMBean extends QueryCacheInstrument {
}

View File

@ -0,0 +1,99 @@
/*
* 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.openjpa.instrumentation.jmx;
import javax.management.ObjectName;
import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.datacache.DataCache;
import org.apache.openjpa.datacache.DataCacheManager;
import org.apache.openjpa.instrumentation.AbstractDataCacheInstrument;
import org.apache.openjpa.lib.conf.Configurations;
import org.apache.openjpa.lib.instrumentation.InstrumentationLevel;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.lib.util.Options;
import org.apache.openjpa.util.UserException;
/**
* A JMX-specific instrument for the data cache
*/
public class DataCacheJMXInstrument extends AbstractDataCacheInstrument
implements JMXInstrument {
private static Localizer _loc = Localizer.forPackage(DataCacheJMXInstrument.class);
private static final String MBEAN_TYPE = "DataCache";
private ObjectName _objName = null;
@Override
public String getName() {
return MBEAN_TYPE;
}
@Override
public InstrumentationLevel getLevel() {
return InstrumentationLevel.FACTORY;
}
@Override
public void initialize() {
Options opts = new Options();
if (getOptions() != null) {
opts = Configurations.parseProperties(getOptions());
}
String cacheName = opts.getProperty("name",null);
OpenJPAConfiguration conf = (OpenJPAConfiguration)getProvider().getConfiguration();
DataCacheManager dcm = conf.getDataCacheManagerInstance();
DataCache dc = null;
if (cacheName == null || cacheName.trim().length() == 0) {
dc = dcm.getSystemDataCache();
} else {
dc = dcm.getDataCache(cacheName);
}
if (dc == null) {
throw new UserException(_loc.get("data-cache-not-found"));
}
setDataCache(dc);
setConfigId(conf.getId());
setContextRef(Integer.toString(System.identityHashCode(getContext())));
}
public ObjectName getObjectName() {
if (_objName != null) {
return _objName;
}
try {
_objName = JMXProvider.createObjectName(this, null);
return _objName;
} catch (Throwable t) {
throw new UserException(_loc.get("unable-to-create-object-name", getName()), t);
}
}
public void start() {
getProvider().startInstrument(this);
}
public void stop() {
getProvider().stopInstrument(this);
}
}

View File

@ -0,0 +1,63 @@
/*
* 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.openjpa.instrumentation.jmx;
import javax.management.ObjectName;
import org.apache.openjpa.lib.instrumentation.Instrument;
/**
* Interface for JMX-specific instruments
*/
public interface JMXInstrument extends Instrument {
/**
* Returns the JMX object name for the instrument
* @return
*/
public ObjectName getObjectName();
/**
* Sets the context reference for the instrument. Required to register
* the instrument under a unique id.
* @param cref the context reference for the instrument
*/
public void setContextRef(String cref);
/**
* Gets the context reference for the instrument. Required to register
* the instrument under a unique id.
* @param cref the context reference for the instrument
*/
public String getContextRef();
/**
* Sets the config id for the instrument. Required to register
* the instrument under a unique id.
* @return the config id of the instrument
*/
public String getConfigId();
/**
* Gets the config id for the instrument. Required to register
* the instrument under a unique id.
* @param cid the config id of the instrument
*/
public void setConfigId(String cid);
}

View File

@ -0,0 +1,155 @@
/*
* 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.openjpa.instrumentation.jmx;
import java.lang.management.ManagementFactory;
import java.util.Map;
import java.util.Map.Entry;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import org.apache.openjpa.lib.instrumentation.AbstractInstrumentationProvider;
import org.apache.openjpa.lib.instrumentation.Instrument;
import org.apache.openjpa.util.UserException;
/**
* A simple MBean JMX instrumentation provider
*/
public class JMXProvider
extends AbstractInstrumentationProvider {
// Aliases for built-in JMX Instrumentation
public static final String[] JMX_INSTRUMENT_ALIASES = {
"DataCache", "org.apache.openjpa.instrumentation.jmx.DataCacheJMXInstrument",
"QueryCache", "org.apache.openjpa.insrumentation.jmx.QueryCacheJMXInstrument",
"QuerySQLCache", "org.apache.openjpa.insrumentation.jmx.PreparedQueryCacheJMXInstrument"
};
/**
* The standard mbean package for OpenJPA
*/
public static final String MBEAN_PACKAGE = "org.apache.openjpa";
private MBeanServer _mbs = null;
/**
* Register an MBean with the mbean server.
* @param mBean
*/
protected void registerMBean(JMXInstrument mBean) {
MBeanServer mbs = getMBeanServer();
try {
mbs.registerMBean(mBean, mBean.getObjectName());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Returns the mbean server
* @return
*/
public MBeanServer getMBeanServer() {
if (_mbs == null) {
_mbs = ManagementFactory.getPlatformMBeanServer();
}
return _mbs;
}
@Override
public void start() {
try {
MBeanServer mbs = getMBeanServer();
if (mbs == null) {
throw new UserException("jmx-server-failed-creation");
}
} catch (Throwable t) {
throw new UserException("jmx-server-unavailable",t);
}
}
@Override
public void stop() {
// no-op with the built in MBean server
}
/**
* Creates an object name for the supplied instrument and key properties
* @param instrument the instrument
* @param props additional key properties
* @return the JMX object name
* @throws Exception a generic JMX-type exception
*/
public static ObjectName createObjectName(JMXInstrument instrument, Map<String,String> props)
throws Exception {
// Construct the base name
StringBuilder sbName = new StringBuilder(MBEAN_PACKAGE);
sbName.append("type=");
sbName.append(instrument.getName());
sbName.append(",cfgid=");
sbName.append(instrument.getConfigId());
sbName.append(",cfgref=");
sbName.append(instrument.getContextRef());
// Add any additional key properties that were provided
if (props != null && !props.isEmpty()) {
for (Entry<String,String> prop : props.entrySet()) {
sbName.append(",");
sbName.append(prop.getKey());
sbName.append("=");
sbName.append(prop.getValue());
}
}
return new ObjectName(sbName.toString());
}
/**
* Start an instrument. Registers an mbean with the server.
*/
public void startInstrument(Instrument instrument) {
if (!instrument.isStarted()) {
registerMBean((JMXInstrument)instrument);
}
}
/**
* Stop an instrument. Unregisters an mbean with the server.
*/
public void stopInstrument(Instrument instrument, boolean force) {
if (instrument.isStarted() || force) {
try {
getMBeanServer().unregisterMBean(((JMXInstrument)instrument).getObjectName());
} catch (Exception e) {
// If force, swallow the exception since the bean may not even
// be registered.
if (!force) {
throw new UserException("cannot-stop-instrument",e);
}
}
}
}
/**
* Returns aliases for built-in instruments.
*/
@Override
public String[] getInstrumentAliases() {
return JMX_INSTRUMENT_ALIASES;
}
}

View File

@ -0,0 +1,88 @@
/*
* 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.openjpa.instrumentation.jmx;
import javax.management.ObjectName;
import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.instrumentation.AbstractPreparedQueryCacheInstrument;
import org.apache.openjpa.kernel.PreparedQueryCache;
import org.apache.openjpa.lib.instrumentation.InstrumentationLevel;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.util.UserException;
/**
* A JMX-specific instrument for the query cache
*/
public class PreparedQueryCacheJMXInstrument extends AbstractPreparedQueryCacheInstrument
implements JMXInstrument {
private static Localizer _loc = Localizer.forPackage(PreparedQueryCacheJMXInstrument.class);
private static final String MBEAN_TYPE = "QuerySQLCache";
private ObjectName _objName = null;
@Override
public String getName() {
return MBEAN_TYPE;
}
@Override
public InstrumentationLevel getLevel() {
return InstrumentationLevel.FACTORY;
}
@Override
public void initialize() {
OpenJPAConfiguration conf = (OpenJPAConfiguration)getProvider().getConfiguration();
PreparedQueryCache pqc = conf.getQuerySQLCacheInstance();
if (pqc == null) {
throw new UserException(_loc.get("prep-query-cache-not-found"));
}
setPreparedQueryCache(pqc);
setConfigId(conf.getId());
setContextRef(Integer.toString(System.identityHashCode(getContext())));
}
public ObjectName getObjectName() {
if (_objName != null) {
return _objName;
}
try {
_objName = JMXProvider.createObjectName(this, null);
return _objName;
} catch (Throwable t) {
throw new UserException(_loc.get("unable-to-create-object-name", getName()), t);
}
}
public void start() {
getProvider().startInstrument(this);
}
public void stop() {
getProvider().stopInstrument(this);
}
}

View File

@ -0,0 +1,89 @@
/*
* 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.openjpa.instrumentation.jmx;
import javax.management.ObjectName;
import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.datacache.DataCacheManager;
import org.apache.openjpa.datacache.QueryCache;
import org.apache.openjpa.instrumentation.AbstractQueryCacheInstrument;
import org.apache.openjpa.lib.instrumentation.InstrumentationLevel;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.util.UserException;
/**
* A JMX-specific instrument for the query cache
*/
public class QueryCacheJMXInstrument extends AbstractQueryCacheInstrument
implements JMXInstrument {
private static Localizer _loc = Localizer.forPackage(QueryCacheJMXInstrument.class);
private static final String MBEAN_TYPE = "QueryCache";
private ObjectName _objName = null;
@Override
public String getName() {
return MBEAN_TYPE;
}
@Override
public InstrumentationLevel getLevel() {
return InstrumentationLevel.FACTORY;
}
@Override
public void initialize() {
OpenJPAConfiguration conf = (OpenJPAConfiguration)getProvider().getConfiguration();
DataCacheManager dcm = conf.getDataCacheManagerInstance();
QueryCache qc = dcm.getSystemQueryCache();
if (qc == null) {
throw new UserException(_loc.get("query-cache-not-found"));
}
setQueryCache(qc);
setConfigId(conf.getId());
setContextRef(Integer.toString(System.identityHashCode(getContext())));
}
public ObjectName getObjectName() {
if (_objName != null) {
return _objName;
}
try {
_objName = JMXProvider.createObjectName(this, null);
return _objName;
} catch (Throwable t) {
throw new UserException(_loc.get("unable-to-create-object-name", getName()), t);
}
}
public void start() {
getProvider().startInstrument(this);
}
public void stop() {
getProvider().stopInstrument(this);
}
}

View File

@ -53,8 +53,10 @@ import org.apache.openjpa.enhance.PCRegistry;
import org.apache.openjpa.enhance.PersistenceCapable;
import org.apache.openjpa.event.BrokerFactoryEvent;
import org.apache.openjpa.event.RemoteCommitEventManager;
import org.apache.openjpa.instrumentation.InstrumentationManager;
import org.apache.openjpa.lib.conf.Configuration;
import org.apache.openjpa.lib.conf.Configurations;
import org.apache.openjpa.lib.instrumentation.InstrumentationLevel;
import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.lib.util.J2DoPrivHelper;
import org.apache.openjpa.lib.util.Localizer;
@ -868,6 +870,12 @@ public abstract class AbstractBrokerFactory
// Get a DataCacheManager instance up front to avoid threading concerns on first call.
// _conf.getDataCacheManagerInstance();
InstrumentationManager imgr = _conf.getInstrumentationManagerInstance();
if (imgr != null) {
// Start all factory level instrumentation
imgr.start(InstrumentationLevel.FACTORY, this);
}
}
}

View File

@ -62,8 +62,10 @@ import org.apache.openjpa.event.LifecycleEventManager;
import org.apache.openjpa.event.RemoteCommitEventManager;
import org.apache.openjpa.event.TransactionEvent;
import org.apache.openjpa.event.TransactionEventManager;
import org.apache.openjpa.instrumentation.InstrumentationManager;
import org.apache.openjpa.kernel.exps.ExpressionParser;
import org.apache.openjpa.lib.conf.Configurations;
import org.apache.openjpa.lib.instrumentation.InstrumentationLevel;
import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.lib.util.J2DoPrivHelper;
import org.apache.openjpa.lib.util.Localizer;
@ -170,6 +172,7 @@ public class BrokerImpl
private transient ReentrantLock _lock = null;
private transient OpCallbacks _call = null;
private transient RuntimeExceptionTranslator _extrans = null;
private transient InstrumentationManager _instm = null;
// ref to producing factory and configuration
private transient AbstractBrokerFactory _factory = null;
@ -366,6 +369,11 @@ public class BrokerImpl
_fc = _store.newFetchConfiguration();
_fc.setContext(this);
}
_instm = _conf.getInstrumentationManagerInstance();
if (_instm != null) {
_instm.start(InstrumentationLevel.BROKER, this);
}
// synch with the global transaction in progress, if any
if (_factory.syncWithManagedTransaction(this, false))
@ -4348,6 +4356,9 @@ public class BrokerImpl
_lm.close();
_store.close();
if (_instm != null) {
_instm.stop(InstrumentationLevel.BROKER, this);
}
_flags = 0;
_closed = true;
if (_log.isTraceEnabled())

View File

@ -0,0 +1,29 @@
# 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.
data-cache-not-found: A data cache instance could not be located by the instrumentation. \
Ensure the data cache is properly configured and available.
query-cache-not-found: A query cache instance could not be located by the instrumentation. \
Ensure the query cache is properly configured and available.
unable-to-create-object-name: Error while attempting to create JMX object name for "{0}". \
See nested exception for details.
jmx-server-failed-creation: The JMX server could not be created.
jmx-server-unavailable: The JMX server is not available. See nested exception for details.
cannot-stop-instrument: Unable to stop JMX instrument. Instrument may not have been \
started or may not be responding. See nested exception for details.
prep-query-cache-not-found: A data cache instance could not be located by the instrumentation. \
Ensure the prepared query cache (QuerySQLCache) is properly configured and available.

View File

@ -0,0 +1,77 @@
/*
* 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.openjpa.lib.instrumentation;
/**
* Provides a base for creating instruments. Specialized instruments can
* extend this class to get base instrument capabilities and then add their
* own specialized functionality.
*/
public abstract class AbstractInstrument implements Instrument {
private boolean _started = false;
private InstrumentationProvider _provider;
private Object _context;
private String _options;
public Object getContext() {
return _context;
}
public void setContext(Object context) {
_context = context;
}
public String getOptions() {
return _options;
}
public void setOptions(String options) {
_options = options;
}
public boolean isStarted() {
return _started;
}
public void setStarted(boolean started) {
_started = started;
}
public void restart() {
stop();
start();
}
public void setProvider(InstrumentationProvider provider) {
_provider = provider;
}
public InstrumentationProvider getProvider() {
return _provider;
}
public InstrumentationLevel getLevel() {
return InstrumentationLevel.MANUAL;
}
public abstract String getName();
public abstract void initialize();
}

View File

@ -0,0 +1,173 @@
/*
* 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.openjpa.lib.instrumentation;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.openjpa.lib.conf.Configurable;
import org.apache.openjpa.lib.conf.Configuration;
import org.apache.openjpa.lib.conf.PluginListValue;
/**
* Specialized instrumentation providers can extend this class to get basic
* provider state and capabilities. It implements Configurable so it can
* be used within the configuration framework to participate in automatic
* configuration.
*/
public abstract class AbstractInstrumentationProvider implements InstrumentationProvider, Configurable {
private Map<String, Instrument> _instruments = new ConcurrentHashMap<String, Instrument>();
private boolean _started = false;
private PluginListValue _instrumentValues;
private String _options;
private Configuration _config;
public void setConfiguration(Configuration conf) {
_config = conf;
}
public Configuration getConfiguration() {
return _config;
}
public void startConfiguration() {
}
public void endConfiguration() {
}
public void setInstrument(String instrument) {
_instrumentValues = new PluginListValue("Instrument");
if (getInstrumentAliases() != null) {
_instrumentValues.setAliases(getInstrumentAliases());
}
_instrumentValues.setString(instrument);
Instrument[] instruments = (Instrument[])_instrumentValues.instantiate(Instrument.class, _config);
for (Instrument inst : instruments) {
inst.setProvider(this);
_instruments.put(inst.getName(), inst);
}
}
public String getInstrument() {
return _instrumentValues.getString();
}
public void setOptions(String options) {
_options = options;
}
public String getOptions() {
return _options;
}
public void addInstrument(Instrument instrument) {
if (instrument == null) {
return;
}
instrument.setProvider(this);
_instruments.put(instrument.getName(), instrument);
}
public void initializeInstrument(Instrument instrument, Object context) {
initializeInstrument(instrument, _options, context);
}
public void initializeInstrument(Instrument instrument, String options, Object context) {
instrument.setProvider(this);
instrument.setOptions(options);
instrument.setContext(context);
instrument.initialize();
}
public Instrument getInstrumentByName(String name) {
return _instruments.get(name);
}
public Set<Instrument> getInstruments() {
return new HashSet<Instrument>(_instruments.values());
}
public void stopInstruments(InstrumentationLevel level, Object context) {
try {
Set<Instrument> instruments = getInstruments();
for (Instrument instrument : instruments) {
if (instrument.getLevel() == level &&
contextEquals(instrument.getContext(),context)) {
stopInstrument(instrument);
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void startInstruments(InstrumentationLevel level, Object context) {
Set<Instrument> instruments = getInstruments();
for (Instrument instrument : instruments) {
if (instrument.getLevel() == level) {
initializeInstrument(instrument, context);
startInstrument(instrument);
}
}
}
public void stopInstrument(Instrument instrument) {
stopInstrument(instrument, true);
}
public void removeInstrumentByName(String name) {
Instrument ins = _instruments.remove(name);
if (ins != null) {
ins.stop();
}
}
public boolean isStarted() {
return _started;
}
protected void setStarted(boolean started) {
_started = started;
}
public String[] getInstrumentAliases() {
return null;
}
public abstract void start();
public abstract void stop();
private static boolean contextEquals(Object ctx1, Object ctx2) {
if (ctx1 == ctx2) {
return true;
}
if (ctx1 == null) {
return false;
}
return ctx1.equals(ctx2);
}
}

View File

@ -0,0 +1,106 @@
/*
* 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.openjpa.lib.instrumentation;
/**
* Interface that must be implemented by instruments.
*/
public interface Instrument {
/**
* Returns the name of the instrument. Must be unique per-provider.
*/
public String getName();
/**
* Returns the options specified for the instrument in string form.
* @return options configuration options for the instrument
*/
public String getOptions();
/**
* Sets options to specify for the instrument in standard string form.
* ex. DataCache(Options='Start=true')
* @param options options
*/
public void setOptions(String options);
/**
* Gets the context of the instrument. Typically, a reference to a broker
* or broker factory.
* @return the context associated with the instrument.
*/
public Object getContext();
/**
* Sets the context of the instrument. Typically, a reference to a broker
* or broker factory.
* @return the context associated with the instrument.
*/
public void setContext(Object context);
/**
* Sets the instrumentation provider for the instrument.
* @param provider instrumentation provider of the instrument
*/
public void setProvider(InstrumentationProvider provider);
/**
* Gets the instrumentation provider for the instrument.
* @return instrumentation provider of the instrument
*/
public InstrumentationProvider getProvider();
/**
* Initializes the instrument. Depending on the instrument, the provider,
* options, and various options may need to be set before calling this method.
*/
public void initialize();
/**
* Gets the instrumentation level of this instrument. The instrumentation level
* determines if and when the instrument will automatically start and stop.
* @return the instrumentation level of the instrument
*/
public InstrumentationLevel getLevel();
/**
* Returns true if the instrument is started.
* @return
*/
public boolean isStarted();
/**
* Starts the instrument. Typically this will be performed through the provider,
* but in some cases an instrument will have its own specialized startup.
*/
public void start();
/**
* Starts the instrument. Typically this will be performed through the provider,
* but in some cases an instrument will have its own specialized shutdown.
*/
public void stop();
/**
* Restarts the instrument. Typically this will be performed through the provider,
* but in some cases an instrument will have its own specialized restart.
*/
public void restart();
}

View File

@ -0,0 +1,44 @@
/*
* 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.openjpa.lib.instrumentation;
/**
* The instrumentation level can be used to indicate if and when an instrument will be
* automatically started and stopped.
*
*/
public enum InstrumentationLevel {
/**
* Start immediately (no special requirements on the broker or factory) and
* stop when the configuration is closed.
*/
IMMEDIATE,
/**
* Start following factory initialization and stop when the factory is closed.
*/
FACTORY,
/**
* Start following broker/em initialization and stop when the broker/em is closed.
*/
BROKER,
/**
* Manual start and stop.
*/
MANUAL
}

View File

@ -0,0 +1,169 @@
/*
* 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.openjpa.lib.instrumentation;
import java.util.Set;
import org.apache.openjpa.lib.conf.Configuration;
/**
* Pluggable instrumentation providers (ex. JMX) must implement this interface. It
* provides methods for controlling the provider and the instruments instrumented
* by the provider.
*/
public interface InstrumentationProvider {
/**
* Whether the instrumentation provider started
* @return true if the provider is started
*/
public boolean isStarted();
/**
* Starts the instrumentation provider
*/
public void stop();
/**
* Stops the instrumentation provider
*/
public void start();
/**
* Gets the configuration associated with the instrumentation provider
* @return the configuration associated with the provider
*/
public Configuration getConfiguration();
/**
* Used to associate one or more instruments to a provider. Instruments
* are specified by class name or alias. Multiple instruments must be
* specified as a comma separated list.
*
* example: DataCache,QueryCache,com.my.MyInstrument
* where DataCache and QueryCache have aliases and com.my.MyInstrument is
* a class implementing an Instrument.
*
* @param instruments one or more instrument class names or aliases
*/
public void setInstrument(String instruments);
/**
* Returns the string-based list of instruments directly configured by
* this provider via setInstrument.
* @return
*/
public String getInstrument();
/**
* Sets configuration options for this provider
* @param options
*/
public void setOptions(String options);
/**
* Gets configuration options for this provider
* @param options
*/
public String getOptions();
/**
* Returns an string array of identifier to class name aliases for
* instruments known to the instrumentation provider. Example:
*
* {"DataCache", "org.apache.openjpa.instrumentation.DataCacheInstrument",
* "QueryCache", "org.apache.openjpa.instrumentation.QueryCacheInstrument"}
* @return a string array of identifier, class name pairs.
*/
public String[] getInstrumentAliases();
/**
* Adds an instrument to this providers list of managed instruments. The
* instrument will participate in context-based lifecycle routines,
* depending on the instrumentation level.
* @param instrument
*/
public void addInstrument(Instrument instrument);
/**
* Stops all instruments of the specified instrumentation level and context.
* @param level instrumentation level
* @param context instrumentation context (factory, broker, config)
*/
public void stopInstruments(InstrumentationLevel level, Object context);
/**
* Starts all instruments of the specified instrumentation level and context.
* @param level instrumentation level
* @param context instrumentation context (factory, broker, config)
*/
public void startInstruments(InstrumentationLevel level, Object context);
/**
* Initializes an instrument within the provided context.
* @param instrument an instrument
* @param context instrumentation context (factory, broker, config)
*/
public void initializeInstrument(Instrument instrument, Object context);
/**
* Initializes an instrument within the provided options and context.
* @param instrument an instrument
* @param options configuration options to provide the instrument during initialization
* @param context instrumentation context (factory, broker, config)
*/
public void initializeInstrument(Instrument instrument, String options, Object context);
/**
* Returns an instrument instrumented by this provider by name
* @param name the name of the instrument to return
* @return the instrument or null if not instrumented by this provider
*/
public Instrument getInstrumentByName(String name);
/**
* Removes an instrument instrumented by this provider by name
* @param name the name of the instrument to remove
*/
public void removeInstrumentByName(String name);
/**
* Gets all instruments instrumented by this provider
* @return instruments instrumented by this provider
*/
public Set<Instrument> getInstruments();
/**
* Starts an instrument
* @param instrument this instrument to start
*/
public void startInstrument(Instrument instrument);
/**
* Stops an instrument
* @param instrument the instrument to stop
*/
public void stopInstrument(Instrument instrument);
/**
* Stops an instrument, forcing the stop, if necessary.
* @param instrument the instrument to stop
* @param force forces the stop if the instrument does not stop gracefully.
*/
public void stopInstrument(Instrument instrument, boolean force);
}

View File

@ -0,0 +1,60 @@
/*
* 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.openjpa.instrumentation;
import org.apache.openjpa.lib.instrumentation.AbstractInstrument;
import org.apache.openjpa.lib.instrumentation.InstrumentationLevel;
public class BrokerLevelInstrument extends AbstractInstrument {
public static String NAME = "NoneInstrument";
private boolean _initialized;
@Override
public String getName() {
return NAME;
}
@Override
public void initialize() {
setInitialized(true);
}
public void start() {
setStarted(true);
}
public void stop() {
setStarted(false);
}
public InstrumentationLevel getLevel() {
return InstrumentationLevel.BROKER;
}
public void setInitialized(boolean _initialized) {
this._initialized = _initialized;
}
public boolean isInitialized() {
return _initialized;
}
}

View File

@ -0,0 +1,44 @@
/*
* 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.openjpa.instrumentation;
import org.apache.openjpa.conf.OpenJPAConfiguration;
public class DCInstrument extends AbstractDataCacheInstrument {
public static final String NAME = "SimpleDCInstrument";
@Override
public String getName() {
return NAME;
}
public void initialize() {
OpenJPAConfiguration config = (OpenJPAConfiguration)getProvider().getConfiguration();
setDataCache(config.getDataCacheManagerInstance().getSystemDataCache());
}
public void start() {
setStarted(true);
}
public void stop() {
setStarted(false);
}
}

View File

@ -0,0 +1,51 @@
/*
* 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.openjpa.instrumentation;
import org.apache.openjpa.lib.instrumentation.AbstractInstrumentationProvider;
import org.apache.openjpa.lib.instrumentation.Instrument;
public class DynamicProvider extends AbstractInstrumentationProvider {
public static final String[] DYNAMIC_INSTRUMENT_ALIASES = { };
public void start() {
setStarted(true);
}
public void stop() {
setStarted(false);
for (Instrument inst : getInstruments()) {
stopInstrument(inst);
}
}
public void startInstrument(Instrument instrument) {
instrument.start();
}
public void stopInstrument(Instrument instrument, boolean force) {
instrument.stop();
}
@Override
public String[] getInstrumentAliases() {
return DYNAMIC_INSTRUMENT_ALIASES;
}
}

View File

@ -0,0 +1,44 @@
/*
* 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.openjpa.instrumentation;
import org.apache.openjpa.conf.OpenJPAConfiguration;
public class QCInstrument extends AbstractQueryCacheInstrument {
public static final String NAME = "SimpleQCInstrument";
@Override
public String getName() {
return NAME;
}
public void initialize() {
OpenJPAConfiguration config = (OpenJPAConfiguration)getProvider().getConfiguration();
setQueryCache(config.getDataCacheManagerInstance().getSystemQueryCache());
}
public void start() {
setStarted(true);
}
public void stop() {
setStarted(false);
}
}

View File

@ -0,0 +1,45 @@
/*
* 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.openjpa.instrumentation;
import org.apache.openjpa.conf.OpenJPAConfiguration;
public class QSCInstrument extends AbstractPreparedQueryCacheInstrument {
public static final String NAME = "SimpleQSCInstrument";
@Override
public String getName() {
return NAME;
}
@Override
public void initialize() {
OpenJPAConfiguration config = (OpenJPAConfiguration)getProvider().getConfiguration();
setPreparedQueryCache(config.getQuerySQLCacheInstance());
}
public void start() {
setStarted(true);
}
public void stop() {
setStarted(false);
}
}

View File

@ -0,0 +1,55 @@
/*
* 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.openjpa.instrumentation;
import org.apache.openjpa.lib.instrumentation.AbstractInstrumentationProvider;
import org.apache.openjpa.lib.instrumentation.Instrument;
public class SimpleProvider extends AbstractInstrumentationProvider {
public static final String[] SIMPLE_INSTRUMENT_ALIASES = {
"DataCache", "org.apache.openjpa.instrumentation.DCInstrument",
"QueryCache","org.apache.openjpa.instrumentation.QCInstrument",
"QuerySQLCache","org.apache.openjpa.instrumentation.QSCInstrument"
};
public void start() {
setStarted(true);
}
public void stop() {
setStarted(false);
for (Instrument inst : getInstruments()) {
stopInstrument(inst);
}
}
public void startInstrument(Instrument instrument) {
instrument.start();
}
public void stopInstrument(Instrument instrument, boolean force) {
instrument.stop();
}
@Override
public String[] getInstrumentAliases() {
return SIMPLE_INSTRUMENT_ALIASES;
}
}

View File

@ -0,0 +1,159 @@
/*
* 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.openjpa.instrumentation;
import java.util.Set;
import javax.persistence.EntityManager;
import org.apache.openjpa.lib.instrumentation.Instrument;
import org.apache.openjpa.lib.instrumentation.InstrumentationProvider;
import org.apache.openjpa.persistence.test.SingleEMFTestCase;
/**
* Verifies the configuration and usage of a simple instrumentation
* provider.
* @author jrbauer
*
*/
public class TestInstrumentationProvider extends SingleEMFTestCase {
public static final String INSTRUMENTATION =
"org.apache.openjpa.instrumentation.SimpleProvider(Instrument='DataCache,QueryCache,QuerySQLCache')";
public void setUp() throws Exception {
super.setUp("openjpa.Instrumentation",
INSTRUMENTATION,
"openjpa.DataCache",
"true(EnableStatistics=true)",
"openjpa.QueryCache",
"true",
"openjpa.RemoteCommitProvider",
"sjvm");
}
/**
* Verifies simple instrumentation provider config with instruments defined
* for data cache and query cache.
*/
public void testProviderConfig() {
// Verify an EMF was created with the supplied instrumentation
assertNotNull(emf);
// Verify the instrumentation value was stored in the config
String instrValue = emf.getConfiguration().getInstrumentation();
assertEquals(instrValue, INSTRUMENTATION);
// Verify an instrumentation manager is available
InstrumentationManager mgr = emf.getConfiguration().getInstrumentationManagerInstance();
assertNotNull(mgr);
// Verify the manager is managing the correct provider
Set<InstrumentationProvider> providers = mgr.getProviders();
assertNotNull(providers);
assertEquals(1, providers.size());
InstrumentationProvider provider = providers.iterator().next();
assertEquals(provider.getClass(), SimpleProvider.class);
// Verify the provider has instruments registered for the caches
Set<Instrument> instruments = provider.getInstruments();
assertNotNull(instruments);
assertEquals(3,instruments.size());
// Lightweight verification of the instruments
Instrument inst = provider.getInstrumentByName(DCInstrument.NAME);
assertNotNull(inst);
assertTrue(inst instanceof DataCacheInstrument);
DataCacheInstrument dci = (DataCacheInstrument)inst;
assertEquals(dci.getCacheName(), "default");
inst = provider.getInstrumentByName(QCInstrument.NAME);
assertNotNull(inst);
assertTrue(inst instanceof QueryCacheInstrument);
inst = provider.getInstrumentByName(QSCInstrument.NAME);
assertNotNull(inst);
assertTrue(inst instanceof PreparedQueryCacheInstrument);
}
/**
* Verifies configuring and adding an instrument to a provider after the provider
* has been initialized within the persistence unit.
*/
public void testDynamicInstrumentConfig() {
InstrumentationManager mgr = emf.getConfiguration().getInstrumentationManagerInstance();
assertNotNull(mgr);
Set<InstrumentationProvider> providers = mgr.getProviders();
assertNotNull(providers);
assertEquals(1, providers.size());
InstrumentationProvider provider = providers.iterator().next();
assertEquals(provider.getClass(), SimpleProvider.class);
verifyBrokerLevelInstrument(provider);
}
/**
* Verifies configuring and adding an instrumentation provider dynamically after
* the persistence unit has been created.
*/
public void testDynamicProviderConfig() {
InstrumentationManager mgr = emf.getConfiguration().getInstrumentationManagerInstance();
assertNotNull(mgr);
DynamicProvider dyp = new DynamicProvider();
mgr.manageProvider(dyp);
verifyBrokerLevelInstrument(dyp);
assertTrue(dyp.isStarted());
assertNotNull(dyp.getInstrumentByName(BrokerLevelInstrument.NAME));
assertEquals(2, mgr.getProviders().size());
}
public void verifyBrokerLevelInstrument(InstrumentationProvider provider) {
// Create a new broker level instrument and register it with the
// provider
BrokerLevelInstrument bli = new BrokerLevelInstrument();
provider.addInstrument(bli);
// Verify instrument has not been initialized or started
assertFalse(bli.isInitialized());
assertFalse(bli.isStarted());
// Create a new EM/Broker
EntityManager em = emf.createEntityManager();
// Vfy the instrument has been initialized and started
assertTrue(bli.isInitialized());
assertTrue(bli.isStarted());
// Close the EM/Broker
em.close();
// Vfy the instrument has stopped
assertFalse(bli.isStarted());
}
/**
* Verifies the cache metrics are available through simple instrumentation.
*/
// public void testCacheInstruments() {
//
// }
/**
* Verifies multiple instrumentation providers can be specified.
*/
// public void testMultipleProviderConfig() {
//
// }
}