OPENJPA-2220: Commit fetch statistic tool. Patch contributed by Helen Xu.

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@1356860 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Richard G. Curtis 2012-07-03 18:21:24 +00:00
parent dc339a98bc
commit 1de868af05
14 changed files with 981 additions and 0 deletions

View File

@ -0,0 +1,136 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- 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. -->
<!-- Maven release plugin requires the project tag to be on a single line. -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.openjpa</groupId>
<artifactId>openjpa-tools</artifactId>
<version>2.3.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>openjpa-fetch-statistics</artifactId>
<packaging>jar</packaging>
<name>OpenJPA Fetching Statistic Tool</name>
<description>
OpenJPA tool to capture the fetching statistic data for the persistent fields .
</description>
<inceptionYear>2012</inceptionYear>
<dependencies>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jpa_2.0_spec</artifactId>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jta_1.1_spec</artifactId>
</dependency>
<dependency>
<groupId>org.apache.openjpa</groupId>
<artifactId>openjpa-kernel</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.openjpa</groupId>
<artifactId>openjpa-lib</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.openjpa</groupId>
<artifactId>openjpa-persistence-jdbc</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
<version>3.8.1</version>
</dependency>
</dependencies>
<licenses>
<license>
<name>Apache License 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>${surefire.jvm.args}</argLine>
<excludes>
<!-- exclude the unit test since the fetch statistic enhancer cannot
be load during maven build -->
<exclude>org/apache/openjpa/enhance/stats/TestFetchStatistics.java</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>default-jar</id>
<goals>
<goal>jar</goal>
</goals>
<phase>package</phase>
<configuration>
<excludes>
<exclude>README-*.txt</exclude>
</excludes>
</configuration>
</execution>
<!-- Create another WAS specific jar -->
<execution>
<id>was</id>
<goals>
<goal>jar</goal>
</goals>
<phase>package</phase>
<configuration>
<finalName>${artifactId}-${version}-websphere</finalName>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
<manifestEntries>
<Fragment-Host>com.ibm.ws.jpa; bundle-version=8.0.0</Fragment-Host>
<Export-Package>org.apache.openjpa.enhance.stats</Export-Package>
<Bundle-SymbolicName>org.apache.openjpa.enhance.stats; singleton:=true</Bundle-SymbolicName>
<Bundle-Name>FetchStatisticsAuxEnhancer</Bundle-Name>
</manifestEntries>
</archive>
<excludes>
<exclude>README.txt</exclude>
</excludes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

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.enhance.stats;
import java.util.Locale;
import org.apache.commons.lang.WordUtils;
import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.enhance.PCEnhancer.AuxiliaryEnhancer;
import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.meta.AccessCode;
import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.meta.FieldMetaData;
import serp.bytecode.BCClass;
import serp.bytecode.BCMethod;
import serp.bytecode.Code;
/**
* FetchStatisticsAuxEnhancer adds the call back function to each persistent fields in the persistent entity which
* will invoke the hit method from FetchStatsCollector whenever the field is fetched at runtime.
*/
public class FetchStatisticsAuxEnhancer implements AuxiliaryEnhancer {
private final String IGNORE_METHODS_REGEX = "(pc(.)*GenericContext)?(pc(.)*StateManager)?"
+ "(pc(.)*DetachedState)?(pc(.)*EnhancementContractVersion)?(pc(.)*ManagedFieldCount)?(pc(.)*GetVersion)?";
public void run(BCClass bcc, ClassMetaData cmd) {
addEnhancement(bcc, cmd);
};
public boolean skipEnhance(BCMethod arg0) {
return false;
};
private void addEnhancement(BCClass bcc, ClassMetaData cmd) {
Log log = cmd.getRepository().getConfiguration().getLog(OpenJPAConfiguration.LOG_RUNTIME);
FetchStatsCollector.setlogger(log);
for (BCMethod meth : bcc.getMethods()) {
String methodName = meth.getName();
FieldMetaData fmd = getFieldName(methodName, cmd);
if (fmd != null && needsTracking(fmd, methodName, cmd)) {
String fqn = bcc.getName() + "." + fmd.getName();
FetchStatsCollector.registerField(fqn);
FetchStatsCollector.registerEntity(cmd);
Code code = meth.getCode(false);
code.constant().setValue(fqn);
code.invokestatic().setMethod(FetchStatsCollector.class, "hit", void.class,
new Class[] { String.class });
}
}
}
private boolean needsTracking(FieldMetaData fmd, String methName, ClassMetaData cmd) {
// Skim out primary key(s), versions, and LAZY fields
if (fmd.isPrimaryKey() || fmd.isVersion() || !fmd.isInDefaultFetchGroup())
return false;
if (AccessCode.isField(fmd) && methName.toLowerCase(Locale.ENGLISH).startsWith("pcget")) {
return true;
} else if (AccessCode.isProperty(fmd) && methName.toLowerCase(Locale.ENGLISH).startsWith("get")
|| methName.toLowerCase(Locale.ENGLISH).startsWith("pcis")) {
return true;
}
return false;
}
private FieldMetaData getFieldName(String methName, ClassMetaData cmd) {
FieldMetaData res = null;
String fieldName = null;
if (methName.matches(IGNORE_METHODS_REGEX)) {
return res;
} else if (methName.startsWith("pcGet")) {
// field access
fieldName = methName.substring(5);
} else if (methName.toLowerCase(Locale.ENGLISH).startsWith("get")) {
// property access
fieldName = WordUtils.uncapitalize(methName.substring(3));
} else if (methName.startsWith("pcis")) {
fieldName = methName.substring(4).toLowerCase(Locale.ENGLISH);
}
for (FieldMetaData fmd : cmd.getDeclaredFields()) {
String fmdName = fmd.getName();
if (fmdName.equals(fieldName)) {
return fmd;
}
}
return null;
}
}

View File

@ -0,0 +1,149 @@
/*
* 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.enhance.stats;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.meta.ClassMetaData;
/**
* FetchStatsCollector aggregates fetch statistics and outputs the data periodically (10 minutes).
*/
public final class FetchStatsCollector {
// Fully qualified persistent field name -> number of access
private static ConcurrentHashMap<String, AtomicInteger> _used = new ConcurrentHashMap<String, AtomicInteger>();
private static Set<String> _entities = new TreeSet<String>();
private static Log _log;
private static final Localizer _loc = Localizer.forPackage(FetchStatsCollector.class);
// default to 10 min
private final static int DEFAULT_INTERVAL = 10 * 60 * 1000;
private static Timer timer;
public static void setlogger(Log log) {
if (FetchStatsCollector._log == null) {
FetchStatsCollector._log = log;
FetchStatsCollector._log.info(_loc.get("start-monitoring"));
}
}
static {
Runtime.getRuntime().addShutdownHook(new Shutdown());
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
TimerTask statsOutputTask = new TimerTask() {
public void run() {
dump();
}
};
timer = new Timer();
timer.schedule(statsOutputTask, DEFAULT_INTERVAL, DEFAULT_INTERVAL);
return null;
}
});
}
public static void registerEntity(ClassMetaData cmd) {
_entities.add(cmd.getDescribedTypeString());
}
public static AtomicInteger registerField(String field) {
return _used.putIfAbsent(field, new AtomicInteger(Integer.valueOf(0)));
}
public static void hit(String field) {
AtomicInteger value = _used.get(field);
if (value != null) {
value.incrementAndGet();
}
}
static class Shutdown extends Thread {
@Override
public void run() {
timer.cancel();
dump();
}
}
public static Set<String> getStatistics() {
// TreeSet for a sorted set.
Set<String> noAccess = new TreeSet<String>();
for (Map.Entry<String, AtomicInteger> entry : _used.entrySet()) {
if (entry.getValue().intValue() == 0) {
noAccess.add(entry.getKey());
}
}
return noAccess;
}
public static void dump() {
Set<String> zeroAccessFieldSet = getStatistics();
StringBuilder message = new StringBuilder();
message.append(_loc.get("fields-never-fetched",
new Object[] { _entities, new Integer(zeroAccessFieldSet.size()) }).getMessage());
for (String field : zeroAccessFieldSet) {
message.append("\n\t" + field);
}
_log.info(message);
}
public static void clear() {
for (Map.Entry<String, AtomicInteger> entry : _used.entrySet()) {
entry.setValue(new AtomicInteger(0));
}
}
static class Container {
String _name;
Integer _value;
public Container(String name, int value) {
_name = name;
_value = value;
}
String getName() {
return _name;
}
public Integer getValue() {
return _value;
}
@Override
public String toString() {
return _name;
}
}
}

View File

@ -0,0 +1,17 @@
# 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.
org.apache.openjpa.enhance.stats.FetchStatisticsAuxEnhancer

View File

@ -0,0 +1,29 @@
Apache OpenJPA - README.txt
Licensed under Apache License 2.0 - http://www.apache.org/licenses/LICENSE-2.0
--------------------------------------------------------------------------------
Open JPA Fetch Statistics Tool monitors persistent field access and determines which fields are never used. This tool
can be used to help tune an application.
Note: Open JPA Fetching Statistics Tool works with the runtime enhancement.
Usage instructions:
1.] Configuration
* Add openjpa-fetch-statistics-[VERSION]-websphere.jar into the [WAS_HOME]\plugins directory.
* Run [WAS_HOME]\bin\osgiCfgInit.sh(bat) to clear the osgi cache.
2.] Statistics Collecting and Monitoring
* When this tool is configured, it will be active for all persistence units in the JVM. Statistics will be dumped via the
openjpa.Runtime channel with the INFO level every 10 minutes, or when the JVM terminates. Any field that is logged
has not been accessed by an application.
3.] Configuration removal
* Stop all WebSphere processes using the [WAS_HOME]\plugins installation.
* Remove the openjpa-fetch-statistics-[VERSION]-websphere.jar jar from the [WAS_HOME]\plugins directory.
* Run [WAS_HOME]\bin\osgiCfgInit.sh(bat) to clear the osgi cache.
Performance Consideration
There will be a large performance impact when running this tooling. It is not supported, nor recommended for production
use. This tool should not be used on a production machine.

View File

@ -0,0 +1,64 @@
Apache OpenJPA - README.txt
Licensed under Apache License 2.0 - http://www.apache.org/licenses/LICENSE-2.0
--------------------------------------------------------------------------------
Open JPA Fetching Statistics Tool monitors the persistent fields
fetching and finds out the fields which are never accessed. Based on the
statistic data, user can set the field access type to LAZY to improve the
performance by eliminating the data loading and processing time.
Note: Open JPA Fetching Statistics Tool works with the runtime enhancement.
Usage instructions:
1 Classpath Configuration
Append the path of openjpa-fetch-statistics-version-SNAPSHOT.jar file
to the classpath of the application before starting the application.
2 Statistics Collecting and Monitoring
Start the application with openjpa-fetch-statistics-<version>-SNAPSHOT.jar
in the classpath. The tool will start collecting the statistics of the
persistent field fetching and output the list of the persistent fields
which have never been fetched to the log file every ten minutes.It will
output the last list when the JVM is shutdown.
3 Termination
Shut down the JVM to stop the fetching statistics collecting.
Roll back the classpath configuration.
Start the application without the fetching statistics jar in the classpath
Performance Consideration
There will be performance impact when the fetching statistics collection is on.
The recommendation is to use it in the testing environment.
Apache OpenJPA - README.txt
Licensed under Apache License 2.0 - http://www.apache.org/licenses/LICENSE-2.0
--------------------------------------------------------------------------------
Open JPA Fetch Statistics Tool monitors persistent field access and determines which fields are never used. This tool
can be used to help tune an application.
Note: Open JPA Fetching Statistics Tool works with the runtime enhancement.
Usage instructions:
1.] Configuration
* Append the path of openjpa-fetch-statistics-version-SNAPSHOT.jar file to the classpath prior to lanuching the JVM.
2.] Statistics Collecting and Monitoring
* When this tool is configured, it will be active for all persistence units in the JVM. Statistics will be dumped via the
openjpa.Runtime channel with the INFO level every 10 minutes, or when the JVM terminates. Any field that is logged
has not been accessed by an application.
3.] Configuration removal
* Stop the JVM.
* Remove openjpa-fetch-statistics-version-SNAPSHOT.jar from the classpath.
Performance Consideration
There will be a large performance impact when running this tooling. It is not supported, nor recommended for production
use. This tool should not be used on a production machine.

View File

@ -0,0 +1,20 @@
# 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.
fields-never-fetched: Successfully collected fetch statistics from Entities {0}. The following fields are \
FetchType.EAGER and were never fetched [ total {1} ] :
start-monitoring: The FetchStatisticsAuxEnhancer has been loaded and is tracking persistent field usage.

View File

@ -0,0 +1,65 @@
/*
* 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.enhance.stats;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
@Entity
public class AEntity {
@Id
private int id;
private String name;
private String desc;
private boolean checked;
private EEntity extraInfo;
@ManyToOne
private BEntity referredBEntity;
public AEntity(int id, String name, String desc, BEntity bEntity) {
super();
this.id = id;
this.name = name;
this.desc = desc;
referredBEntity = bEntity;
extraInfo = new EEntity("extra " + desc, "E" + id);
}
public String getFullInfo(){
return name + desc;
}
public boolean isChecked(){
return checked;
}
public String getReferredBEntityName(){
return referredBEntity.getName();
}
public String getExtraInfo(){
return extraInfo.getExtraDesc();
}
}

View File

@ -0,0 +1,86 @@
/*
* 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.enhance.stats;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Basic;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
@Entity
@Inheritance(strategy=InheritanceType.JOINED)
@Access(AccessType.PROPERTY)
public class BEntity {
private int id;
private String name;
private boolean bool;
@Id
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setDesc(String desc) {
this.desc = desc;
}
@Access(AccessType.FIELD)
private String desc;
public String getName() {
return name;
}
public String getCustomDesc(){
return desc;
}
public BEntity(int id, String name, String desc) {
super();
setId(id);
setName(name);
setDesc(desc);
}
public BEntity() {
super();
}
public void setBool(boolean b){
bool = b;
}
@Basic
public boolean isBool(){
return bool;
}
}

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.enhance.stats;
import javax.persistence.Entity;
import javax.persistence.PrimaryKeyJoinColumn;
@Entity
@PrimaryKeyJoinColumn(name = "CHILDID", referencedColumnName = "ID")
public class ChildEntity extends BEntity {
private int childId;
private String childName;
private String childDesc;
public int getChildId() {
return childId;
}
public void setChildId(int childId) {
this.childId = childId;
}
public void setChildDesc(String childDesc) {
this.childDesc = childDesc;
}
public String getChildDesc() {
return childDesc;
}
public String getChildName() {
return childName;
}
public void setChildName(String childName) {
this.childName = childName;
}
public ChildEntity(int id, String name, String desc, String childName) {
super(id, name, desc);
setChildName(childName);
setChildDesc("test");
setChildId(id);
}
}

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.enhance.stats;
import javax.persistence.Embeddable;
@Embeddable
public class EEntity {
String extraDesc;
public String getExtraDesc() {
return extraDesc;
}
public String getCode() {
return code;
}
String code;
public EEntity (String desc, String code) {
this.extraDesc = desc;
this.code = code;
}
}

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.enhance.stats;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Set;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import org.apache.openjpa.enhance.PCEnhancer;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Unit test for Open JPA Fetch Statistic.
*/
public class TestFetchStatistics extends TestCase {
/**
* Create the test case
*
* @param testName
* name of the test case
*/
public TestFetchStatistics(String testName) {
super(testName);
}
/**
* @return the suite of tests being tested
*/
public static Test suite() {
return new TestSuite(TestFetchStatistics.class);
}
public void setUp() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("fetchStatisticPU");
emf.createEntityManager().close();
FetchStatsCollector.clear();
}
public void tearDown() {
}
public void testFieldAccess() {
FetchStatsCollector.clear();
AEntity aEntity = new AEntity(1, "t", "d", null);
Set<String> res = FetchStatsCollector.getStatistics();
assertTrue(res.contains("org.apache.openjpa.enhance.stats.AEntity.name"));
assertTrue(res.contains("org.apache.openjpa.enhance.stats.AEntity.desc"));
assertEquals("td", aEntity.getFullInfo());
res = FetchStatsCollector.getStatistics();
assertFalse(res.contains("org.apache.openjpa.enhance.stats.AEntity.name"));
assertFalse(res.contains("org.apache.openjpa.enhance.stats.AEntity.desc"));
}
public void testEmbeddedEntityFieldAccess() {
AEntity aEntity = new AEntity(1, "t1", "d1", null);
assertEquals("extra d1", aEntity.getExtraInfo());
Set<String> res = FetchStatsCollector.getStatistics();
assertFalse(res.contains("org.apache.openjpa.enhance.stats.AEntity.extraInfo"));
}
public void testPropertyFieldMixedAccess() {
FetchStatsCollector.clear();
BEntity b = new BEntity(2, "t2", "d2");
Set<String> res = FetchStatsCollector.getStatistics();
assertTrue(res.toString(), res.contains("org.apache.openjpa.enhance.stats.BEntity.name"));
assertTrue(res.toString(), res.contains("org.apache.openjpa.enhance.stats.BEntity.bool"));
b.getName();
b.isBool();
res = FetchStatsCollector.getStatistics();
assertFalse(res.contains("org.apache.openjpa.enhance.stats.BEntity.name"));
assertFalse(res.contains("org.apache.openjpa.enhance.stats.BEntity.bool"));
}
public void testMixedAccess() {
BEntity e = new BEntity(1, "t1", "d1");
Set<String> res = FetchStatsCollector.getStatistics();
assertTrue(res.contains("org.apache.openjpa.enhance.stats.BEntity.name"));
assertTrue(res.contains("org.apache.openjpa.enhance.stats.BEntity.desc"));
e.getName();
e.getCustomDesc();
res = FetchStatsCollector.getStatistics();
assertFalse(res.contains("org.apache.openjpa.enhance.stats.BEntity.name"));
assertFalse(res.contains("org.apache.openjpa.enhance.stats.BEntity.desc"));
}
public void testFieldAccessThroughRelationship() {
BEntity bf1 = new BEntity(1, "t1", "d1");
AEntity af3 = new AEntity(3, "t3", "d3", bf1);
assertEquals("t1", af3.getReferredBEntityName());
af3.isChecked();
Set<String> res = FetchStatsCollector.getStatistics();
assertFalse(res.contains("org.apache.openjpa.enhance.stats.AEntity.checked"));
}
public void testPropertyAccessThroughInheritance() {
FetchStatsCollector.clear();
ChildEntity cEntity = new ChildEntity(1, "t1", "d1", "cn1");
Set<String> res = FetchStatsCollector.getStatistics();
assertTrue(res.contains("org.apache.openjpa.enhance.stats.ChildEntity.childName"));
assertTrue(res.contains("org.apache.openjpa.enhance.stats.BEntity.name"));
assertTrue(res.contains("org.apache.openjpa.enhance.stats.BEntity.desc"));
// touch fields
cEntity.getChildName();
cEntity.getName();
cEntity.getCustomDesc();
res = FetchStatsCollector.getStatistics();
assertFalse(res.contains("org.apache.openjpa.enhance.stats.ChildEntity.childName"));
assertFalse(res.contains("org.apache.openjpa.enhance.stats.BEntity.name"));
assertFalse(res.contains("org.apache.openjpa.enhance.stats.BEntity.desc"));
}
// used for manual test of the output interval
public void _testOutputInterval() throws InterruptedException {
Thread.currentThread().sleep(60 * 60 * 1000);
}
}

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- 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. -->
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0">
<persistence-unit name="fetchStatisticPU" transaction-type="RESOURCE_LOCAL">
<description>PU for openjpa fetch statistic testing</description>
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl
</provider>
<class>org.apache.openjpa.enhance.stats.AEntity</class>
<class>org.apache.openjpa.enhance.stats.BEntity</class>
<class>org.apache.openjpa.enhance.stats.ChildEntity</class>
<class>org.apache.openjpa.enhance.stats.EEntity</class>
</persistence-unit>
</persistence>

View File

@ -42,6 +42,8 @@
<modules>
<module>openjpa-maven-plugin</module>
<module>openjpa-fetch-statistics</module>
</modules>
<profiles>