Author: rmannibucau Date: Tue Oct 15 07:50:19 2013 New Revision: 1532236 URL: http://svn.apache.org/r1532236 Log: allowing to configure cdi monitoring through properties file
Added: commons/sandbox/monitoring/trunk/cdi/src/main/java/org/apache/commons/monitoring/cdi/internal/ commons/sandbox/monitoring/trunk/cdi/src/main/java/org/apache/commons/monitoring/cdi/internal/CommonsMonitoringPerformanceExtension.java commons/sandbox/monitoring/trunk/cdi/src/main/java/org/apache/commons/monitoring/cdi/internal/WrappedAnnotatedType.java commons/sandbox/monitoring/trunk/cdi/src/main/resources/META-INF/services/ commons/sandbox/monitoring/trunk/cdi/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension commons/sandbox/monitoring/trunk/cdi/src/test/java/org/apache/commons/monitoring/cdi/CommonsMonitoringExtensionTest.java - copied, changed from r1532191, commons/sandbox/monitoring/trunk/cdi/src/test/java/org/apache/commons/monitoring/cdi/CommonsMonitoringInterceptorTest.java commons/sandbox/monitoring/trunk/cdi/src/test/java/org/apache/commons/monitoring/cdi/CommonsMonitoringExtensionTestBase.java commons/sandbox/monitoring/trunk/cdi/src/test/resources/commons-monitoring.properties Modified: commons/sandbox/monitoring/trunk/cdi/src/test/java/org/apache/commons/monitoring/cdi/CommonsMonitoringInterceptorTest.java Added: commons/sandbox/monitoring/trunk/cdi/src/main/java/org/apache/commons/monitoring/cdi/internal/CommonsMonitoringPerformanceExtension.java URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/cdi/src/main/java/org/apache/commons/monitoring/cdi/internal/CommonsMonitoringPerformanceExtension.java?rev=1532236&view=auto ============================================================================== --- commons/sandbox/monitoring/trunk/cdi/src/main/java/org/apache/commons/monitoring/cdi/internal/CommonsMonitoringPerformanceExtension.java (added) +++ commons/sandbox/monitoring/trunk/cdi/src/main/java/org/apache/commons/monitoring/cdi/internal/CommonsMonitoringPerformanceExtension.java Tue Oct 15 07:50:19 2013 @@ -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.commons.monitoring.cdi.internal; + +import org.apache.commons.monitoring.cdi.Monitored; +import org.apache.commons.monitoring.configuration.Configuration; +import org.apache.commons.monitoring.util.ClassLoaders; + +import javax.enterprise.event.Observes; +import javax.enterprise.inject.spi.Extension; +import javax.enterprise.inject.spi.ProcessAnnotatedType; +import java.io.Serializable; +import java.lang.annotation.Annotation; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class CommonsMonitoringPerformanceExtension implements Extension { + private static final Logger LOGGER = Logger.getLogger(CommonsMonitoringPerformanceExtension.class.getName()); + + private static final String PERFORMANCE_MARKER = "performance"; + + private final boolean enabled = Configuration.is(Configuration.COMMONS_MONITORING_PREFIX + "cdi.enabled", true); + private final Monitored binding = newAnnotation(Monitored.class); + private final Map<Class<? extends Annotation>, Annotation> otherBindings = new HashMap<Class<? extends Annotation>, Annotation>(); + + <A> void processAnnotatedType(final @Observes ProcessAnnotatedType<A> pat) { + if (!enabled) { + return; + } + + final String beanClassName = pat.getAnnotatedType().getJavaClass().getName(); + final String configuration = findConfiguration(beanClassName); + if (configuration == null) { + return; + } + + final Collection<String> configForThisBean = Arrays.asList(configuration.split(",")); + if (!configForThisBean.isEmpty()) { + final WrappedAnnotatedType<A> wrapper = new WrappedAnnotatedType<A>(pat.getAnnotatedType()); + for (final String rawConfig : configForThisBean) { + final String config = rawConfig.trim(); + + if (PERFORMANCE_MARKER.equals(config)) { + wrapper.getAnnotations().add(binding); + } else { // convention is from <name> the binding is org.apache.commons.monitoring.<lowercase(name)>.<uppercase(name)>Monitored, ex: jta + final String deducedName = "org.apache.commons.monitoring." + config.toLowerCase(Locale.ENGLISH) + "." + config.toUpperCase(Locale.ENGLISH) + "Monitored"; + try { + final Class<? extends Annotation> annotationType = Class.class.cast(ClassLoaders.current().loadClass(deducedName)); + Annotation instance = otherBindings.get(annotationType); + if (instance == null) { + instance = newAnnotation(annotationType); + otherBindings.put(annotationType, instance); + } + wrapper.getAnnotations().add(instance); + } catch (final ClassNotFoundException e) { + LOGGER.log(Level.SEVERE, e.getMessage(), e); + } + } + } + pat.setAnnotatedType(wrapper); + } + } + + private static String findConfiguration(final String name) { + String current = name; + String property; + do { + property = Configuration.getProperty(current + ".cdi", null); + + final int endIndex = current.lastIndexOf('.'); + if (endIndex > 0) { + current = current.substring(0, endIndex); + } else { + current = null; + } + } while (property == null && current != null); + return property; + } + + private static <T extends Annotation> T newAnnotation(final Class<T> clazz) { + return clazz.cast( + Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), + new Class<?>[]{ Annotation.class, clazz }, + new AnnotationHandler(clazz))); + } + + // Note: for annotations without any members + private static class AnnotationHandler implements InvocationHandler, Annotation, Serializable { + private final Class<? extends Annotation> annotationClass; + + private AnnotationHandler(final Class<? extends Annotation> annotationClass) { + this.annotationClass = annotationClass; + } + + @Override + public Object invoke(final Object proxy, final Method method, final Object[] args) throws Exception { + if ("hashCode".equals(method.getName())) { + return hashCode(); + } else if ("equals".equals(method.getName())) { + if (Proxy.isProxyClass(args[0].getClass()) && AnnotationHandler.class.isInstance(Proxy.getInvocationHandler(args[0]))) { + return equals(Proxy.getInvocationHandler(args[0])); + } + return equals(args[0]); + } else if ("annotationType".equals(method.getName())) { + return annotationType(); + } else if ("toString".equals(method.getName())) { + return toString(); + } + return method.getDefaultValue(); + } + + @Override + public Class<? extends Annotation> annotationType() { + return annotationClass; + } + + @Override + public String toString() { + return "@" + annotationClass.getName(); + } + + @Override + public boolean equals(final Object o) { + return this == o + || Annotation.class.isInstance(o) && Annotation.class.cast(o).annotationType().equals(annotationClass); + } + + @Override + public int hashCode() { + return 0; + } + } +} Added: commons/sandbox/monitoring/trunk/cdi/src/main/java/org/apache/commons/monitoring/cdi/internal/WrappedAnnotatedType.java URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/cdi/src/main/java/org/apache/commons/monitoring/cdi/internal/WrappedAnnotatedType.java?rev=1532236&view=auto ============================================================================== --- commons/sandbox/monitoring/trunk/cdi/src/main/java/org/apache/commons/monitoring/cdi/internal/WrappedAnnotatedType.java (added) +++ commons/sandbox/monitoring/trunk/cdi/src/main/java/org/apache/commons/monitoring/cdi/internal/WrappedAnnotatedType.java Tue Oct 15 07:50:19 2013 @@ -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.commons.monitoring.cdi.internal; + +import javax.enterprise.inject.spi.AnnotatedConstructor; +import javax.enterprise.inject.spi.AnnotatedField; +import javax.enterprise.inject.spi.AnnotatedMethod; +import javax.enterprise.inject.spi.AnnotatedType; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; +import java.util.HashSet; +import java.util.Set; + +public class WrappedAnnotatedType<A> implements AnnotatedType<A> { + private final AnnotatedType<A> delegate; + private final Set<Annotation> annotations; + + public WrappedAnnotatedType(final AnnotatedType<A> at) { + this.delegate = at; + + this.annotations = new HashSet<Annotation>(at.getAnnotations().size()); + this.annotations.addAll(at.getAnnotations()); + } + + @Override + public Set<Annotation> getAnnotations() { + return annotations; + } + + @Override + public <T extends Annotation> T getAnnotation(final Class<T> annotationType) { + for (final Annotation ann : annotations) { + if (ann.annotationType().equals(annotationType)) { + return annotationType.cast(ann); + } + } + return null; + } + + @Override + public boolean isAnnotationPresent(final Class<? extends Annotation> annotationType) { + return getAnnotation(annotationType) != null; + } + + @Override + public Class<A> getJavaClass() { + return delegate.getJavaClass(); + } + + @Override + public Set<AnnotatedConstructor<A>> getConstructors() { + return delegate.getConstructors(); + } + + @Override + public Set<AnnotatedMethod<? super A>> getMethods() { + return delegate.getMethods(); + } + + @Override + public Set<AnnotatedField<? super A>> getFields() { + return delegate.getFields(); + } + + @Override + public Type getBaseType() { + return delegate.getBaseType(); + } + + @Override + public Set<Type> getTypeClosure() { + return delegate.getTypeClosure(); + } +} Added: commons/sandbox/monitoring/trunk/cdi/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/cdi/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension?rev=1532236&view=auto ============================================================================== --- commons/sandbox/monitoring/trunk/cdi/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension (added) +++ commons/sandbox/monitoring/trunk/cdi/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension Tue Oct 15 07:50:19 2013 @@ -0,0 +1 @@ +org.apache.commons.monitoring.cdi.internal.CommonsMonitoringPerformanceExtension Copied: commons/sandbox/monitoring/trunk/cdi/src/test/java/org/apache/commons/monitoring/cdi/CommonsMonitoringExtensionTest.java (from r1532191, commons/sandbox/monitoring/trunk/cdi/src/test/java/org/apache/commons/monitoring/cdi/CommonsMonitoringInterceptorTest.java) URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/cdi/src/test/java/org/apache/commons/monitoring/cdi/CommonsMonitoringExtensionTest.java?p2=commons/sandbox/monitoring/trunk/cdi/src/test/java/org/apache/commons/monitoring/cdi/CommonsMonitoringExtensionTest.java&p1=commons/sandbox/monitoring/trunk/cdi/src/test/java/org/apache/commons/monitoring/cdi/CommonsMonitoringInterceptorTest.java&r1=1532191&r2=1532236&rev=1532236&view=diff ============================================================================== --- commons/sandbox/monitoring/trunk/cdi/src/test/java/org/apache/commons/monitoring/cdi/CommonsMonitoringInterceptorTest.java (original) +++ commons/sandbox/monitoring/trunk/cdi/src/test/java/org/apache/commons/monitoring/cdi/CommonsMonitoringExtensionTest.java Tue Oct 15 07:50:19 2013 @@ -16,43 +16,16 @@ */ package org.apache.commons.monitoring.cdi; -import org.apache.commons.monitoring.Role; -import org.apache.commons.monitoring.counters.Counter; -import org.apache.commons.monitoring.repositories.Repository; -import org.apache.webbeans.cditest.CdiTestContainer; -import org.apache.webbeans.cditest.CdiTestContainerLoader; -import org.junit.Test; - import javax.enterprise.context.ApplicationScoped; -import javax.enterprise.inject.spi.BeanManager; -import java.util.concurrent.TimeUnit; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -public class CommonsMonitoringInterceptorTest { - @Test - public void checkMeasures() throws Exception { - final CdiTestContainer container = CdiTestContainerLoader.getCdiContainer(); - container.bootContainer(); - container.startApplicationScope(); - - final BeanManager beanManager = container.getBeanManager(); - final MonitoredBean bean = MonitoredBean.class.cast(beanManager.getReference(beanManager.resolve(beanManager.getBeans(MonitoredBean.class)), MonitoredBean.class, null)); - - bean.twoSeconds(); - - container.stopApplicationScope(); - container.shutdownContainer(); - final Counter perf = Repository.INSTANCE.getCounter(new Counter.Key(Role.PERFORMANCES, MonitoredBean.class.getName() + ".twoSeconds")); - assertNotNull(perf); - assertEquals(2000, TimeUnit.NANOSECONDS.toMillis((int) perf.getMax()), 200); +public class CommonsMonitoringExtensionTest extends CommonsMonitoringExtensionTestBase { + @Override + protected Class<? extends TwoSeconds> type() { + return AutoMonitoredBean.class; } - @Monitored @ApplicationScoped - public static class MonitoredBean { + public static class AutoMonitoredBean implements TwoSeconds { public void twoSeconds() { try { Thread.sleep(2000); Added: commons/sandbox/monitoring/trunk/cdi/src/test/java/org/apache/commons/monitoring/cdi/CommonsMonitoringExtensionTestBase.java URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/cdi/src/test/java/org/apache/commons/monitoring/cdi/CommonsMonitoringExtensionTestBase.java?rev=1532236&view=auto ============================================================================== --- commons/sandbox/monitoring/trunk/cdi/src/test/java/org/apache/commons/monitoring/cdi/CommonsMonitoringExtensionTestBase.java (added) +++ commons/sandbox/monitoring/trunk/cdi/src/test/java/org/apache/commons/monitoring/cdi/CommonsMonitoringExtensionTestBase.java Tue Oct 15 07:50:19 2013 @@ -0,0 +1,58 @@ +/* + * 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.cdi; + +import org.apache.commons.monitoring.Role; +import org.apache.commons.monitoring.counters.Counter; +import org.apache.commons.monitoring.repositories.Repository; +import org.apache.webbeans.cditest.CdiTestContainer; +import org.apache.webbeans.cditest.CdiTestContainerLoader; +import org.junit.Test; + +import javax.enterprise.inject.spi.BeanManager; +import java.util.concurrent.TimeUnit; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public abstract class CommonsMonitoringExtensionTestBase { + @Test + public void checkMeasures() throws Exception { + final CdiTestContainer container = CdiTestContainerLoader.getCdiContainer(); + container.bootContainer(); + container.startApplicationScope(); + + final BeanManager beanManager = container.getBeanManager(); + final Class<?> type = type(); + final TwoSeconds bean = TwoSeconds.class.cast(beanManager.getReference(beanManager.resolve(beanManager.getBeans(type)), type, null)); + + bean.twoSeconds(); + + container.stopApplicationScope(); + container.shutdownContainer(); + + final Counter perf = Repository.INSTANCE.getCounter(new Counter.Key(Role.PERFORMANCES, type.getName() + ".twoSeconds")); + assertNotNull(perf); + assertEquals(2000, TimeUnit.NANOSECONDS.toMillis((int) perf.getMax()), 200); + } + + protected abstract Class<? extends TwoSeconds> type(); + + protected static interface TwoSeconds { + void twoSeconds(); + } +} Modified: commons/sandbox/monitoring/trunk/cdi/src/test/java/org/apache/commons/monitoring/cdi/CommonsMonitoringInterceptorTest.java URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/cdi/src/test/java/org/apache/commons/monitoring/cdi/CommonsMonitoringInterceptorTest.java?rev=1532236&r1=1532235&r2=1532236&view=diff ============================================================================== --- commons/sandbox/monitoring/trunk/cdi/src/test/java/org/apache/commons/monitoring/cdi/CommonsMonitoringInterceptorTest.java (original) +++ commons/sandbox/monitoring/trunk/cdi/src/test/java/org/apache/commons/monitoring/cdi/CommonsMonitoringInterceptorTest.java Tue Oct 15 07:50:19 2013 @@ -16,43 +16,17 @@ */ package org.apache.commons.monitoring.cdi; -import org.apache.commons.monitoring.Role; -import org.apache.commons.monitoring.counters.Counter; -import org.apache.commons.monitoring.repositories.Repository; -import org.apache.webbeans.cditest.CdiTestContainer; -import org.apache.webbeans.cditest.CdiTestContainerLoader; -import org.junit.Test; - import javax.enterprise.context.ApplicationScoped; -import javax.enterprise.inject.spi.BeanManager; -import java.util.concurrent.TimeUnit; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -public class CommonsMonitoringInterceptorTest { - @Test - public void checkMeasures() throws Exception { - final CdiTestContainer container = CdiTestContainerLoader.getCdiContainer(); - container.bootContainer(); - container.startApplicationScope(); - - final BeanManager beanManager = container.getBeanManager(); - final MonitoredBean bean = MonitoredBean.class.cast(beanManager.getReference(beanManager.resolve(beanManager.getBeans(MonitoredBean.class)), MonitoredBean.class, null)); - - bean.twoSeconds(); - - container.stopApplicationScope(); - container.shutdownContainer(); - final Counter perf = Repository.INSTANCE.getCounter(new Counter.Key(Role.PERFORMANCES, MonitoredBean.class.getName() + ".twoSeconds")); - assertNotNull(perf); - assertEquals(2000, TimeUnit.NANOSECONDS.toMillis((int) perf.getMax()), 200); +public class CommonsMonitoringInterceptorTest extends CommonsMonitoringExtensionTestBase { + @Override + protected Class<? extends TwoSeconds> type() { + return MonitoredBean.class; } @Monitored @ApplicationScoped - public static class MonitoredBean { + public static class MonitoredBean implements TwoSeconds { public void twoSeconds() { try { Thread.sleep(2000); Added: commons/sandbox/monitoring/trunk/cdi/src/test/resources/commons-monitoring.properties URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/cdi/src/test/resources/commons-monitoring.properties?rev=1532236&view=auto ============================================================================== --- commons/sandbox/monitoring/trunk/cdi/src/test/resources/commons-monitoring.properties (added) +++ commons/sandbox/monitoring/trunk/cdi/src/test/resources/commons-monitoring.properties Tue Oct 15 07:50:19 2013 @@ -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.commons.monitoring.cdi.CommonsMonitoringExtensionTest$AutoMonitoredBean.cdi = performance