Author: rmannibucau Date: Tue Oct 22 09:07:48 2013 New Revision: 1534546 URL: http://svn.apache.org/r1534546 Log: adding jpa module - doc todo
Added: commons/sandbox/monitoring/trunk/jpa/ commons/sandbox/monitoring/trunk/jpa/pom.xml commons/sandbox/monitoring/trunk/jpa/src/ commons/sandbox/monitoring/trunk/jpa/src/main/ commons/sandbox/monitoring/trunk/jpa/src/main/java/ commons/sandbox/monitoring/trunk/jpa/src/main/java/org/ commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/ commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/ commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/ commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/ commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/JPAProxyFactory.java commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/MonitoringPersistence.java commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/OverridePersistenceXmlClassLoader.java commons/sandbox/monitoring/trunk/jpa/src/main/resources/ commons/sandbox/monitoring/trunk/jpa/src/main/resources/META-INF/ commons/sandbox/monitoring/trunk/jpa/src/main/resources/META-INF/services/ commons/sandbox/monitoring/trunk/jpa/src/main/resources/META-INF/services/javax.persistence.spi.PersistenceProvider commons/sandbox/monitoring/trunk/jpa/src/test/ commons/sandbox/monitoring/trunk/jpa/src/test/java/ commons/sandbox/monitoring/trunk/jpa/src/test/java/org/ commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/ commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/ commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/ commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/ commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/EMFTest.java commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/QueryTest.java commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/entity/ commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/entity/Address.java commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/entity/Person.java commons/sandbox/monitoring/trunk/jpa/src/test/resources/ commons/sandbox/monitoring/trunk/jpa/src/test/resources/META-INF/ commons/sandbox/monitoring/trunk/jpa/src/test/resources/META-INF/persistence.xml Modified: commons/sandbox/monitoring/trunk/aop/src/main/java/org/apache/commons/monitoring/aop/AbstractPerformanceInterceptor.java commons/sandbox/monitoring/trunk/core/src/main/java/org/apache/commons/monitoring/counters/DefaultCounter.java commons/sandbox/monitoring/trunk/jdbc/pom.xml commons/sandbox/monitoring/trunk/pom.xml Modified: commons/sandbox/monitoring/trunk/aop/src/main/java/org/apache/commons/monitoring/aop/AbstractPerformanceInterceptor.java URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/aop/src/main/java/org/apache/commons/monitoring/aop/AbstractPerformanceInterceptor.java?rev=1534546&r1=1534545&r2=1534546&view=diff ============================================================================== --- commons/sandbox/monitoring/trunk/aop/src/main/java/org/apache/commons/monitoring/aop/AbstractPerformanceInterceptor.java (original) +++ commons/sandbox/monitoring/trunk/aop/src/main/java/org/apache/commons/monitoring/aop/AbstractPerformanceInterceptor.java Tue Oct 22 09:07:48 2013 @@ -51,7 +51,7 @@ public abstract class AbstractPerformanc return proceed(invocation); } - final Counter monitor = Repository.INSTANCE.getCounter(new Counter.Key(Role.PERFORMANCES, name)); + final Counter monitor = Repository.INSTANCE.getCounter(new Counter.Key(getRole(), name)); final StopWatch stopwatch = Repository.INSTANCE.start(monitor); Throwable error = null; try { @@ -69,6 +69,10 @@ public abstract class AbstractPerformanc } } + protected Role getRole() { + return Role.PERFORMANCES; + } + protected abstract Object proceed(T invocation) throws Throwable; protected abstract String getCounterName(T invocation); Modified: commons/sandbox/monitoring/trunk/core/src/main/java/org/apache/commons/monitoring/counters/DefaultCounter.java URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/core/src/main/java/org/apache/commons/monitoring/counters/DefaultCounter.java?rev=1534546&r1=1534545&r2=1534546&view=diff ============================================================================== --- commons/sandbox/monitoring/trunk/core/src/main/java/org/apache/commons/monitoring/counters/DefaultCounter.java (original) +++ commons/sandbox/monitoring/trunk/core/src/main/java/org/apache/commons/monitoring/counters/DefaultCounter.java Tue Oct 22 09:07:48 2013 @@ -171,4 +171,15 @@ public class DefaultCounter implements C public ReadWriteLock getLock() { return lock; } + + @Override + public String toString() { + return "DefaultCounter{" + + "concurrency=" + concurrency + + ", key=" + key + + ", dataStore=" + dataStore + + ", maxConcurrency=" + maxConcurrency + + ", statistics=" + statistics + + '}'; + } } Modified: commons/sandbox/monitoring/trunk/jdbc/pom.xml URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/jdbc/pom.xml?rev=1534546&r1=1534545&r2=1534546&view=diff ============================================================================== --- commons/sandbox/monitoring/trunk/jdbc/pom.xml (original) +++ commons/sandbox/monitoring/trunk/jdbc/pom.xml Tue Oct 22 09:07:48 2013 @@ -42,8 +42,6 @@ <dependency> <groupId>org.hsqldb</groupId> <artifactId>hsqldb</artifactId> - <version>2.2.9</version> - <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> Added: commons/sandbox/monitoring/trunk/jpa/pom.xml URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/jpa/pom.xml?rev=1534546&view=auto ============================================================================== --- commons/sandbox/monitoring/trunk/jpa/pom.xml (added) +++ commons/sandbox/monitoring/trunk/jpa/pom.xml Tue Oct 22 09:07:48 2013 @@ -0,0 +1,69 @@ +<?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. +--> +<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> + <artifactId>commons-monitoring-parent</artifactId> + <groupId>org.apache.commons.monitoring</groupId> + <version>1.0-SNAPSHOT</version> + </parent> + + <artifactId>commons-monitoring-jpa</artifactId> + <version>1.0-SNAPSHOT</version> + <name>Commons Monitoring (Sandbox) :: JPA</name> + + <dependencies> + <dependency> + <groupId>org.apache.geronimo.specs</groupId> + <artifactId>geronimo-jpa_2.0_spec</artifactId> + <version>1.1</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.commons.monitoring</groupId> + <artifactId>commons-monitoring-core</artifactId> + </dependency> + <dependency> + <groupId>org.apache.commons.monitoring</groupId> + <artifactId>commons-monitoring-aop</artifactId> + <exclusions> + <exclusion> + <groupId>org.apache.commons</groupId> + <artifactId>commons-proxy</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.hsqldb</groupId> + <artifactId>hsqldb</artifactId> + </dependency> + <dependency> + <groupId>org.apache.openjpa</groupId> + <artifactId>openjpa</artifactId> + <version>2.2.2</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + </dependency> + </dependencies> +</project> \ No newline at end of file Added: commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/JPAProxyFactory.java URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/JPAProxyFactory.java?rev=1534546&view=auto ============================================================================== --- commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/JPAProxyFactory.java (added) +++ commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/JPAProxyFactory.java Tue Oct 22 09:07:48 2013 @@ -0,0 +1,103 @@ +/* + * 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.commons.monitoring.jpa; + +import org.apache.commons.monitoring.Role; +import org.apache.commons.monitoring.aop.AbstractPerformanceInterceptor; +import org.apache.commons.monitoring.util.ClassLoaders; + +import java.io.Serializable; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +public final class JPAProxyFactory { + // more designed as internal than user friendly, that's why it is not in aop module + public static Object monitor(final Class<?>[] classes, final Object instance, final Role role, final boolean cascade) { + return classes[0].cast( + Proxy.newProxyInstance(ClassLoaders.current(), classes, new JSEMonitoringHandler(instance, role, cascade))); + } + + private JPAProxyFactory() { + // no-op + } + + private static class JSEMonitoringHandler extends AbstractPerformanceInterceptor<Invocation> implements InvocationHandler { + private final Object instance; + private final Role role; + private final boolean cascade; + + public JSEMonitoringHandler(final Object instance, final Role role, final boolean cascade) { + this.instance = instance; + this.role = role; + this.cascade = cascade; + } + + @Override + public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { + if ("toString".equals(method.getName())) { + return "MonitoringProxy[" + instance + "]"; + } + + final Object o = doInvoke(new Invocation(instance, method, args)); + final Class<?> returnType = method.getReturnType(); + if (cascade && returnType.isInterface()) { // not java.* + return monitor(classes(returnType, o), o, role, cascade); + } + return o; + } + + @Override + protected Object proceed(final Invocation invocation) throws Throwable { + try { + return invocation.method.invoke(invocation.target, invocation.args); + } catch (final InvocationTargetException ite) { + throw ite.getCause(); + } + } + + @Override + protected String getCounterName(final Invocation invocation) { + return getCounterName(invocation.target, invocation.method); + } + + @Override + protected Role getRole() { + return role; + } + + protected Class<?>[] classes(final Class<?> returnType, final Object o) { + if (Serializable.class.isInstance(o)) { + return new Class<?>[] { returnType, Serializable.class }; + } + return new Class<?>[] { returnType }; + } + } + + private static class Invocation { + private final Object target; + private final Method method; + private final Object[] args; + + private Invocation(final Object target, final Method method, final Object[] args) { + this.target = target; + this.method = method; + this.args = args; + } + } +} Added: commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/MonitoringPersistence.java URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/MonitoringPersistence.java?rev=1534546&view=auto ============================================================================== --- commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/MonitoringPersistence.java (added) +++ commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/MonitoringPersistence.java Tue Oct 22 09:07:48 2013 @@ -0,0 +1,165 @@ +/* + * 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.commons.monitoring.jpa; + +import org.apache.commons.monitoring.Role; +import org.apache.commons.monitoring.configuration.Configuration; +import org.apache.commons.monitoring.counters.Unit; + +import javax.persistence.EntityManagerFactory; +import javax.persistence.spi.PersistenceProvider; +import javax.persistence.spi.PersistenceUnitInfo; +import javax.persistence.spi.ProviderUtil; +import java.io.Serializable; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.Map; + +import static org.apache.commons.monitoring.jpa.JPAProxyFactory.monitor; + +public class MonitoringPersistence implements PersistenceProvider { + public static final Role ROLE = new Role("jpa", Unit.Time.NANOSECOND); + + private static final Class<?>[] PROXY_API = new Class<?>[] { EntityManagerFactory.class, Serializable.class}; + private static final String DELEGATE_PROVIDER_KEY = Configuration.COMMONS_MONITORING_PREFIX + "jpa.provider"; + + private static final String[] PROVIDERS = { + "org.apache.openjpa.persistence.PersistenceProviderImpl", + "org.hibernate.jpa.HibernatePeristenceProvider", + "org.hibernate.ejb.HibernatePeristence", + "org.eclipse.persistence.jpa.PersistenceProvider", + "oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider", + "oracle.toplink.essentials.PersistenceProvider", + "me.prettyprint.hom.CassandraPersistenceProvider", + "org.datanucleus.jpa.PersistenceProviderImpl", + "com.orientechnologies.orient.core.db.object.jpa.OJPAPersistenceProvider", + "com.orientechnologies.orient.object.jpa.OJPAPersistenceProvider", + "com.spaceprogram.simplejpa.PersistenceProviderImpl" + }; + + private volatile PersistenceProvider delegate; + + @Override + public EntityManagerFactory createEntityManagerFactory(final String unit, final Map map) { + final PersistenceProvider persistenceProvider = findDelegate(map); + final ClassLoader tccl = tccl(); + + final ClassLoader hack = new OverridePersistenceXmlClassLoader(tccl, persistenceProvider.getClass().getName()); + Thread.currentThread().setContextClassLoader(hack); + try { + final EntityManagerFactory entityManagerFactory = persistenceProvider.createEntityManagerFactory(unit, map); + if (entityManagerFactory == null) { + return null; + } + return EntityManagerFactory.class.cast( + monitor(PROXY_API, entityManagerFactory, ROLE, true)); + } finally { + Thread.currentThread().setContextClassLoader(tccl); + } + } + + @Override + public EntityManagerFactory createContainerEntityManagerFactory(final PersistenceUnitInfo info, final Map map) { + final PersistenceProvider persistenceProvider = findDelegate(map); + final EntityManagerFactory containerEntityManagerFactory = persistenceProvider.createContainerEntityManagerFactory( + PersistenceUnitInfo.class.cast(Proxy.newProxyInstance(tccl(), new Class<?>[]{PersistenceUnitInfo.class}, new ProviderAwareHandler(persistenceProvider.getClass().getName(), info))), + map); + if (containerEntityManagerFactory == null) { + return null; + } + return EntityManagerFactory.class.cast( + monitor(PROXY_API, containerEntityManagerFactory, ROLE, true)); + } + + @Override + public ProviderUtil getProviderUtil() { // we suppose it is loaded later than createXXXEMF so we'll get the delegate + return loadOrGuessDelegate(null).getProviderUtil(); + } + + private PersistenceProvider findDelegate(final Map map) { + if (map == null) { + return loadOrGuessDelegate(null); + } + return loadOrGuessDelegate(String.class.cast(map.get(DELEGATE_PROVIDER_KEY))); + } + + private PersistenceProvider loadOrGuessDelegate(final String name) { + if (delegate == null) { + synchronized (this) { + if (delegate == null) { + if (name == null) { + for (final String provider : PROVIDERS) { + try { + delegate = newPersistence(provider); + if (delegate != null) { + break; + } + } catch (final Throwable th2) { + // no-op + } + } + + if (delegate == null) { + throw new IllegalStateException(new ClassNotFoundException("Can't find a delegate")); + } + } else { + try { + delegate = newPersistence(name); + } catch (final Exception e) { + throw new IllegalStateException(new ClassNotFoundException("Can't instantiate '" + name + "'")); + } + } + } + } + } + if (name != null && !delegate.getClass().getName().equals(name)) { + try { + return newPersistence(name); + } catch (final Exception e) { + throw new IllegalStateException(new ClassNotFoundException("Can't instantiate '" + name + "'")); + } + } + return delegate; + } + + private static ClassLoader tccl() { + return Thread.currentThread().getContextClassLoader(); + } + + private static PersistenceProvider newPersistence(final String name) throws Exception { + return PersistenceProvider.class.cast(tccl().loadClass(name).newInstance()); + } + + private static class ProviderAwareHandler implements InvocationHandler { + private final String provider; + private final PersistenceUnitInfo info; + + public ProviderAwareHandler(final String provider, final PersistenceUnitInfo info) { + this.provider = provider; + this.info = info; + } + + @Override + public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { + if ("getPersistenceProviderClassName".equals(method.getName())) { + return provider; + } + return method.invoke(info, args); + } + } +} Added: commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/OverridePersistenceXmlClassLoader.java URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/OverridePersistenceXmlClassLoader.java?rev=1534546&view=auto ============================================================================== --- commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/OverridePersistenceXmlClassLoader.java (added) +++ commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/OverridePersistenceXmlClassLoader.java Tue Oct 22 09:07:48 2013 @@ -0,0 +1,142 @@ +/* + * 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.commons.monitoring.jpa; + +import org.apache.commons.monitoring.MonitoringException; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLStreamHandler; +import java.util.Collection; +import java.util.Collections; +import java.util.Enumeration; +import java.util.LinkedList; + +public class OverridePersistenceXmlClassLoader extends ClassLoader { + private static final String PERSISTENCE_XML = "META-INF/persistence.xml"; + private static final String PERSISTENCE_PROVIDER = MonitoringPersistence.class.getName(); + public static final String NO_PROVIDER = "<provider></provider>"; + + private final String replacement; + + public OverridePersistenceXmlClassLoader(final ClassLoader parent, final String replacement) { + super(parent); + this.replacement = replacement; + } + + @Override // don't load anything from here + protected Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException { + return super.loadClass(name, resolve); + } + + @Override + public URL getResource(final String name) { + final URL url = super.getResource(name); + if (PERSISTENCE_XML.equals(name) && url != null) { + return newUrl(url, slurp(url)); + } + return url; + } + + @Override + public Enumeration<URL> getResources(final String name) throws IOException { + final Enumeration<URL> urls = super.getResources(name); + if (PERSISTENCE_XML.equals(name)) { + final Collection<URL> overrided = new LinkedList<URL>(); + while (urls.hasMoreElements()) { + final URL url = urls.nextElement(); + overrided.add(newUrl(url, slurp(url))); + } + return Collections.enumeration(overrided); + } + return urls; + } + + private URL newUrl(final URL url, final String slurp) { + if (slurp.contains(PERSISTENCE_PROVIDER)) { + final String afterReplace = slurp.replace(PERSISTENCE_PROVIDER, replacement).replace(NO_PROVIDER, ""); + try { + return new URL(url.getProtocol(), url.getHost(), url.getPort(), url.getFile(), new ConstantURLStreamHandler(afterReplace)); + } catch (final MalformedURLException e) { + // no-op + } + } + return url; + } + + private static String slurp(final URL url) { + InputStream is = null; + try { + is = url.openStream(); + final ByteArrayOutputStream out = new ByteArrayOutputStream(); + final byte[] buffer = new byte[1024]; + int length; + while ((length = is.read(buffer)) != -1) { + out.write(buffer, 0, length); + } + return new String(out.toByteArray()); + } catch (final IOException e) { + throw new MonitoringException(e); + } finally { + // no need to close out + try { + if (is != null) { + is.close(); + } + } catch (IOException e) { + // no-op + } + } + } + + private static class ConstantURLStreamHandler extends URLStreamHandler { + private final String value; + + private ConstantURLStreamHandler(final String value) { + this.value = value; + } + + @Override + protected URLConnection openConnection(final URL u) throws IOException { + return new ConstantURLConnection(u, value); + } + } + + private static class ConstantURLConnection extends URLConnection { + private final String value; + + private ConstantURLConnection(final URL url, final String value) { + super(url); + this.value = value; + } + + @Override + public void connect() throws IOException { + // no-op + } + + @Override + public InputStream getInputStream() throws IOException { + return new ByteArrayInputStream(value.getBytes()); + } + } +} Added: commons/sandbox/monitoring/trunk/jpa/src/main/resources/META-INF/services/javax.persistence.spi.PersistenceProvider URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/jpa/src/main/resources/META-INF/services/javax.persistence.spi.PersistenceProvider?rev=1534546&view=auto ============================================================================== --- commons/sandbox/monitoring/trunk/jpa/src/main/resources/META-INF/services/javax.persistence.spi.PersistenceProvider (added) +++ commons/sandbox/monitoring/trunk/jpa/src/main/resources/META-INF/services/javax.persistence.spi.PersistenceProvider Tue Oct 22 09:07:48 2013 @@ -0,0 +1 @@ +org.apache.commons.monitoring.jpa.MonitoringPersistence Added: commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/EMFTest.java URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/EMFTest.java?rev=1534546&view=auto ============================================================================== --- commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/EMFTest.java (added) +++ commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/EMFTest.java Tue Oct 22 09:07:48 2013 @@ -0,0 +1,78 @@ +/* + * 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.commons.monitoring.jpa; + +import org.apache.commons.collections.IteratorUtils; +import org.apache.commons.monitoring.counters.Counter; +import org.apache.commons.monitoring.repositories.Repository; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.spi.PersistenceUnitInfo; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class EMFTest { + @Before + @After + public void reset() { + Repository.INSTANCE.clear(); + } + + @Test + public void newEmfJSe() { + final EntityManagerFactory emf = Persistence.createEntityManagerFactory("test-jse"); + assertNotNull(emf); + emf.close(); + + assertCreateCalled(); + } + + @Test + public void newEmfJavaEE() { + final EntityManagerFactory emf = new MonitoringPersistence().createContainerEntityManagerFactory( + PersistenceUnitInfo.class.cast(Proxy.newProxyInstance(getClass().getClassLoader(), new Class<?>[]{PersistenceUnitInfo.class}, new InvocationHandler() { + @Override + public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { + if (boolean.class.equals(method.getReturnType())) { + return false; + } + return null; + } + })), null); + assertNotNull(emf); + emf.close(); + + assertCreateCalled(); + } + + private static void assertCreateCalled() { + final List<Counter> counters = IteratorUtils.toList(Repository.INSTANCE.iterator()); + assertEquals(1, counters.size()); + + final Counter counter = counters.iterator().next(); + assertEquals(1, counter.getHits()); + } +} Added: commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/QueryTest.java URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/QueryTest.java?rev=1534546&view=auto ============================================================================== --- commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/QueryTest.java (added) +++ commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/QueryTest.java Tue Oct 22 09:07:48 2013 @@ -0,0 +1,119 @@ +/* + * 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.commons.monitoring.jpa; + +import org.apache.commons.monitoring.counters.Counter; +import org.apache.commons.monitoring.jpa.entity.Person; +import org.apache.commons.monitoring.repositories.Repository; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.EntityTransaction; +import javax.persistence.Persistence; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +public class QueryTest { + @Before + @After + public void reset() { + Repository.INSTANCE.clear(); + } + + @Test + public void simpleFind() { + final EntityManagerFactory emf = Persistence.createEntityManagerFactory("test-jse"); + assertNotNull(emf); + reset(); // get rid of init counter + + try { + final EntityManager em = emf.createEntityManager(); + assertNotNull(em); + + assertCounter("createEntityManager"); + + reset(); // get rid of createEntityManager counter + try { + em.find(Person.class, 0L); + assertCounter("find"); + reset(); // get rid of em.find() counter + } finally { + em.close(); + assertCounter("EntityManagerImpl.close"); + } + + reset(); // get rid of em.close() counter + } finally { + emf.close(); + } + assertCounter("EntityManagerFactoryImpl.close"); + } + + @Test + public void createNamedQuery() { + final EntityManagerFactory emf = Persistence.createEntityManagerFactory("test-jse"); + + try { + { // init + final EntityManager em = emf.createEntityManager(); + try { + final EntityTransaction transaction = em.getTransaction(); + transaction.begin(); + try { + final Person p = new Person(); + p.setName("sirona"); + + em.persist(p); + transaction.commit(); + } catch (final Exception e) { + transaction.rollback(); + } + } finally { + em.close(); + } + } + + { // checks + final EntityManager em = emf.createEntityManager(); + try { + reset(); + em.createNamedQuery("Person.findByName", Person.class).setParameter("name", "sirona").getSingleResult(); + assertCounter("createNamedQuery"); + } finally { + em.close(); + } + } + } finally { + emf.close(); + } + } + + private static void assertCounter(final String method) { + assertTrue(Repository.INSTANCE.iterator().hasNext()); + + final Counter counter = Repository.INSTANCE.iterator().next(); + assertEquals(1, counter.getHits()); + assertThat(counter.getKey().getName(), containsString(method)); + } +} Added: commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/entity/Address.java URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/entity/Address.java?rev=1534546&view=auto ============================================================================== --- commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/entity/Address.java (added) +++ commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/entity/Address.java Tue Oct 22 09:07:48 2013 @@ -0,0 +1,53 @@ +/* + * 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.commons.monitoring.jpa.entity; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.ManyToOne; + +@Entity +public class Address { + @Id + @GeneratedValue + private long id; + private String street; + + @ManyToOne + private Person person; + + public long getId() { + return id; + } + + public String getStreet() { + return street; + } + + public void setStreet(final String street) { + this.street = street; + } + + public Person getPerson() { + return person; + } + + public void setPerson(final Person person) { + this.person = person; + } +} Added: commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/entity/Person.java URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/entity/Person.java?rev=1534546&view=auto ============================================================================== --- commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/entity/Person.java (added) +++ commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/entity/Person.java Tue Oct 22 09:07:48 2013 @@ -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.commons.monitoring.jpa.entity; + +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.NamedQuery; +import javax.persistence.OneToMany; +import java.util.LinkedList; +import java.util.List; + +@Entity +@NamedQuery(name = "Person.findByName", query = "select p from Person p where p.name = :name") +public class Person { + @Id + @GeneratedValue + private long id; + + private String name; + + @OneToMany(cascade = { CascadeType.ALL }, mappedBy = "person") + private List<Address> addresses = new LinkedList<Address>(); + + public long getId() { + return id; + } + + public String getName() { + return name; + } + + public void setName(final String name) { + this.name = name; + } + + public List<Address> getAddresses() { + return addresses; + } +} Added: commons/sandbox/monitoring/trunk/jpa/src/test/resources/META-INF/persistence.xml URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/jpa/src/test/resources/META-INF/persistence.xml?rev=1534546&view=auto ============================================================================== --- commons/sandbox/monitoring/trunk/jpa/src/test/resources/META-INF/persistence.xml (added) +++ commons/sandbox/monitoring/trunk/jpa/src/test/resources/META-INF/persistence.xml Tue Oct 22 09:07:48 2013 @@ -0,0 +1,50 @@ +<?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 version="2.0" + xmlns="http://java.sun.com/xml/ns/persistence" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://java.sun.com/xml/ns/persistence + http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> + <persistence-unit name="test-jse"> + <provider>org.apache.commons.monitoring.jpa.MonitoringPersistence</provider> + <class>org.apache.commons.monitoring.jpa.entity.Person</class> + <class>org.apache.commons.monitoring.jpa.entity.Address</class> + <properties> + <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/> + <property name="openjpa.ConnectionURL" value="jdbc:hsqldb:mem:jpa;create=true"/> + <property name="openjpa.ConnectionDriverName" value="org.hsqldb.jdbcDriver"/> + <property name="openjpa.ConnectionUserName" value="sa"/> + <property name="openjpa.ConnectionPassword" value=""/> + <property name="openjpa.Log" value="DefaultLevel=WARN, Tool=INFO, SQL=INFO"/> + </properties> + </persistence-unit> + <persistence-unit name="test-jta"> + <provider>org.apache.commons.monitoring.jpa.MonitoringPersistence</provider> + <class>org.apache.commons.monitoring.jpa.entity.Person</class> + <class>org.apache.commons.monitoring.jpa.entity.Address</class> + <properties> + <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/> + <property name="openjpa.ConnectionURL" value="jdbc:hsqldb:mem:jpa;create=true"/> + <property name="openjpa.ConnectionDriverName" value="org.hsqldb.jdbcDriver"/> + <property name="openjpa.ConnectionUserName" value="sa"/> + <property name="openjpa.ConnectionPassword" value=""/> + <property name="openjpa.RuntimeUnenhancedClasses" value="supported"/> + <property name="openjpa.Log" value="DefaultLevel=WARN, Tool=INFO, SQL=INFO"/> + </properties> + </persistence-unit> +</persistence> Modified: commons/sandbox/monitoring/trunk/pom.xml URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/pom.xml?rev=1534546&r1=1534545&r2=1534546&view=diff ============================================================================== --- commons/sandbox/monitoring/trunk/pom.xml (original) +++ commons/sandbox/monitoring/trunk/pom.xml Tue Oct 22 09:07:48 2013 @@ -58,6 +58,7 @@ <module>graphite</module> <module>cube</module> <module>collector</module> + <module>jpa</module> </modules> <developers> @@ -163,6 +164,12 @@ <scope>test</scope> </dependency> <dependency> + <groupId>org.hsqldb</groupId> + <artifactId>hsqldb</artifactId> + <version>2.2.9</version> + <scope>test</scope> + </dependency> + <dependency> <groupId>org.apache.geronimo.specs</groupId> <artifactId>geronimo-servlet_3.0_spec</artifactId> <version>1.0</version>