starting spec v3 impl (still some failling tests)
diff --git a/geronimo-metrics-common/src/main/java/org/apache/geronimo/microprofile/metrics/common/RegistryImpl.java b/geronimo-metrics-common/src/main/java/org/apache/geronimo/microprofile/metrics/common/RegistryImpl.java
index 0897ce6..d2ae98e 100644
--- a/geronimo-metrics-common/src/main/java/org/apache/geronimo/microprofile/metrics/common/RegistryImpl.java
+++ b/geronimo-metrics-common/src/main/java/org/apache/geronimo/microprofile/metrics/common/RegistryImpl.java
@@ -16,19 +16,6 @@
*/
package org.apache.geronimo.microprofile.metrics.common;
-import static java.util.stream.Collectors.toCollection;
-import static java.util.stream.Collectors.toMap;
-
-import java.util.Map;
-import java.util.Objects;
-import java.util.SortedMap;
-import java.util.SortedSet;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.atomic.AtomicBoolean;
-
import org.eclipse.microprofile.metrics.ConcurrentGauge;
import org.eclipse.microprofile.metrics.Counter;
import org.eclipse.microprofile.metrics.Gauge;
@@ -41,14 +28,33 @@
import org.eclipse.microprofile.metrics.MetricRegistry;
import org.eclipse.microprofile.metrics.MetricType;
import org.eclipse.microprofile.metrics.MetricUnits;
+import org.eclipse.microprofile.metrics.SimpleTimer;
import org.eclipse.microprofile.metrics.Tag;
import org.eclipse.microprofile.metrics.Timer;
-public class RegistryImpl extends MetricRegistry {
+import java.util.Map;
+import java.util.Objects;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static java.util.stream.Collectors.toCollection;
+import static java.util.stream.Collectors.toMap;
+
+public class RegistryImpl implements MetricRegistry {
private static final Tag[] NO_TAG = new Tag[0];
+ private final Type type;
private final ConcurrentMap<MetricID, Holder<? extends Metric>> metrics = new ConcurrentHashMap<>();
+ public RegistryImpl(final Type type) {
+ this.type = type;
+ }
+
@Override
public <T extends Metric> T register(final Metadata metadata, final T metric) throws IllegalArgumentException {
return register(metadata, metric, NO_TAG);
@@ -124,6 +130,11 @@
}
@Override
+ public ConcurrentGauge concurrentGauge(final MetricID metricID) {
+ return concurrentGauge(metricID.getName(), metricID.getTagsAsArray());
+ }
+
+ @Override
public ConcurrentGauge concurrentGauge(final Metadata metadata) {
return concurrentGauge(metadata, NO_TAG);
}
@@ -151,6 +162,11 @@
}
@Override
+ public Gauge<?> gauge(final MetricID metricID, final Gauge<?> gauge) {
+ return gauge(metricID.getName(), gauge, metricID.getTagsAsArray());
+ }
+
+ @Override
public Histogram histogram(final Metadata metadata) {
return histogram(metadata, NO_TAG);
}
@@ -229,6 +245,49 @@
}
@Override
+ public SimpleTimer simpleTimer(final MetricID metricID) {
+ return simpleTimer(metricID.getName(), metricID.getTagsAsArray());
+ }
+
+ @Override
+ public SimpleTimer simpleTimer(final Metadata metadata) {
+ return simpleTimer(metadata, NO_TAG);
+ }
+
+ @Override
+ public SimpleTimer simpleTimer(final Metadata metadata, final Tag... tags) {
+ final MetricID metricID = new MetricID(metadata.getName(), tags);
+ Holder<? extends Metric> holder = metrics.get(metricID);
+ if (holder == null) {
+ holder = new Holder<>(new SimpleTimerImpl(metadata.getUnit().orElse(MetricUnits.NONE)), metadata, metricID);
+ final Holder<? extends Metric> existing = metrics.putIfAbsent(metricID, holder);
+ if (existing != null) {
+ holder = existing;
+ }
+ } else if (!metadata.isReusable()) {
+ throw new IllegalArgumentException("Metric " + metadata.getName() + " already exists and is not set as reusable");
+ } else if (!holder.metadata.isReusable()) {
+ throw new IllegalArgumentException("Metric " + metadata.getName() + " already exists and was not set as reusable");
+ }
+ if (!SimpleTimer.class.isInstance(holder.metric)) {
+ throw new IllegalArgumentException(holder.metric + " is not a timer");
+ }
+ return SimpleTimer.class.cast(holder.metric);
+ }
+
+ @Override
+ public Metric getMetric(final MetricID metricID) {
+ final Holder<? extends Metric> holder = metrics.get(metricID);
+ return holder == null ? null : holder.metric;
+ }
+
+ @Override
+ public Metadata getMetadata(final String name) {
+ final Holder<? extends Metric> holder = metrics.get(new MetricID(name));
+ return holder == null ? null : holder.metadata;
+ }
+
+ @Override
public Counter counter(final String name) {
return counter(Metadata.builder().withName(name).withType(MetricType.COUNTER).build(), NO_TAG);
}
@@ -239,6 +298,11 @@
}
@Override
+ public Counter counter(final MetricID metricID) {
+ return counter(metricID.getName(), metricID.getTagsAsArray());
+ }
+
+ @Override
public Histogram histogram(final String name) {
return histogram(Metadata.builder().withName(name).withType(MetricType.HISTOGRAM).build());
}
@@ -249,6 +313,11 @@
}
@Override
+ public Histogram histogram(final MetricID metricID) {
+ return histogram(metricID.getName(), metricID.getTagsAsArray());
+ }
+
+ @Override
public Meter meter(final String name) {
return meter(Metadata.builder().withName(name).withType(MetricType.METERED).build());
}
@@ -259,6 +328,11 @@
}
@Override
+ public Meter meter(final MetricID metricID) {
+ return meter(metricID.getName(), metricID.getTagsAsArray());
+ }
+
+ @Override
public Timer timer(final String name) {
return timer(Metadata.builder().withName(name).withType(MetricType.TIMER).build());
}
@@ -269,6 +343,11 @@
}
@Override
+ public Timer timer(final MetricID metricID) {
+ return timer(metricID.getName(), metricID.getTagsAsArray());
+ }
+
+ @Override
public boolean remove(final String name) {
final AtomicBoolean done = new AtomicBoolean(false);
removeMatching((metricID, metric) -> {
@@ -362,6 +441,21 @@
}
@Override
+ public SortedMap<MetricID, SimpleTimer> getSimpleTimers() {
+ return filterByType(MetricFilter.ALL, SimpleTimer.class);
+ }
+
+ @Override
+ public SortedMap<MetricID, SimpleTimer> getSimpleTimers(final MetricFilter filter) {
+ return filterByType(filter, SimpleTimer.class);
+ }
+
+ @Override
+ public SortedMap<MetricID, Metric> getMetrics(final MetricFilter metricFilter) {
+ return filterByType(metricFilter, Metric.class);
+ }
+
+ @Override
public Map<MetricID, Metric> getMetrics() {
return metrics.entrySet().stream().collect(toMap(Map.Entry::getKey, e -> e.getValue().metric));
}
@@ -372,6 +466,11 @@
.collect(toMap(e -> e.getKey().getName(), e -> e.getValue().metadata, (a, b) -> a));
}
+ @Override
+ public Type getType() {
+ return type;
+ }
+
private <T extends Metric> SortedMap<MetricID, T> filterByType(final MetricFilter filter, final Class<T> type) {
return metrics.entrySet().stream()
.filter(it -> type.isInstance(it.getValue().metric))
diff --git a/geronimo-metrics-common/src/main/java/org/apache/geronimo/microprofile/metrics/common/SimpleTimerImpl.java b/geronimo-metrics-common/src/main/java/org/apache/geronimo/microprofile/metrics/common/SimpleTimerImpl.java
new file mode 100644
index 0000000..5945762
--- /dev/null
+++ b/geronimo-metrics-common/src/main/java/org/apache/geronimo/microprofile/metrics/common/SimpleTimerImpl.java
@@ -0,0 +1,153 @@
+/*
+ * 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.geronimo.microprofile.metrics.common;
+
+import org.eclipse.microprofile.metrics.SimpleTimer;
+
+import java.time.Clock;
+import java.time.Duration;
+import java.time.Instant;
+import java.time.ZoneId;
+import java.util.concurrent.Callable;
+
+public class SimpleTimerImpl implements SimpleTimer {
+ private static final Clock MINUTE_CLOCK = Clock.tickMinutes(ZoneId.of("UTC"));
+ private static final Clock CLOCK = Clock.systemUTC();
+
+ // same logic than ConcurrentGaugeImpl
+ private volatile Instant currentMinute = CLOCK.instant();
+
+ private volatile Duration current;
+ private volatile Duration min;
+ private volatile Duration max;
+ private volatile Duration previousMin;
+ private volatile Duration previousMax;
+ private volatile long count;
+
+ private final String unit;
+
+ public SimpleTimerImpl(final String unit) {
+ this.unit = unit;
+ }
+
+ public String getUnit() {
+ return unit;
+ }
+
+ @Override
+ public void update(final Duration duration) {
+ if (duration.isNegative() || duration.isZero()) {
+ return;
+ }
+ maybeRotate();
+ synchronized (this) {
+ count++;
+ current = duration;
+ if (max == null || duration.toMillis() > max.toMillis()) {
+ max = duration;
+ }
+ if (min == null || duration.toMillis() < min.toMillis()) {
+ min = duration;
+ }
+ }
+ }
+
+ @Override
+ public <T> T time(final Callable<T> callable) throws Exception {
+ final Instant startTime = CLOCK.instant();
+ try {
+ return callable.call();
+ } finally {
+ update(Duration.between(startTime, CLOCK.instant()));
+ }
+ }
+
+ @Override
+ public void time(final Runnable runnable) {
+ try {
+ time(() -> {
+ runnable.run();
+ return null;
+ });
+ } catch (final RuntimeException re) {
+ throw re;
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ @Override
+ public Context time() {
+ return new ContextImpl();
+ }
+
+ @Override
+ public Duration getElapsedTime() {
+ return current;
+ }
+
+ @Override
+ public long getCount() {
+ return count;
+ }
+
+ @Override
+ public Duration getMaxTimeDuration() {
+ maybeRotate();
+ return max;
+ }
+
+ @Override
+ public Duration getMinTimeDuration() {
+ maybeRotate();
+ return min;
+ }
+
+ private void maybeRotate() {
+ final Instant now = MINUTE_CLOCK.instant();
+ if (now.isAfter(currentMinute)) {
+ synchronized (this) {
+ if (now.isAfter(currentMinute)) {
+ rotate(now);
+ }
+ }
+ }
+ }
+
+ private void rotate(final Instant now) {
+ previousMax = max;
+ previousMin = min;
+ max = min = null;
+ currentMinute = now;
+ }
+
+ private class ContextImpl implements Context {
+ private final Instant start = CLOCK.instant();
+
+ @Override
+ public long stop() {
+ final Duration duration = Duration.between(start, CLOCK.instant());
+ update(duration);
+ return duration.toNanos();
+ }
+
+ @Override
+ public void close() {
+ stop();
+ }
+ }
+}
diff --git a/geronimo-metrics-common/src/main/java/org/apache/geronimo/microprofile/metrics/common/TimerImpl.java b/geronimo-metrics-common/src/main/java/org/apache/geronimo/microprofile/metrics/common/TimerImpl.java
index 51cdbcd..38cf11e 100644
--- a/geronimo-metrics-common/src/main/java/org/apache/geronimo/microprofile/metrics/common/TimerImpl.java
+++ b/geronimo-metrics-common/src/main/java/org/apache/geronimo/microprofile/metrics/common/TimerImpl.java
@@ -16,17 +16,17 @@
*/
package org.apache.geronimo.microprofile.metrics.common;
-import java.util.concurrent.Callable;
-import java.util.concurrent.TimeUnit;
-
-import javax.json.bind.annotation.JsonbProperty;
-import javax.json.bind.annotation.JsonbTransient;
-
import org.eclipse.microprofile.metrics.Histogram;
import org.eclipse.microprofile.metrics.Meter;
import org.eclipse.microprofile.metrics.Snapshot;
import org.eclipse.microprofile.metrics.Timer;
+import javax.json.bind.annotation.JsonbProperty;
+import javax.json.bind.annotation.JsonbTransient;
+import java.time.Duration;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+
public class TimerImpl implements Timer {
private final Histogram histogram;
private final Meter meter;
@@ -37,11 +37,12 @@
}
@Override
- public void update(final long duration, final TimeUnit unit) {
- if (duration >= 0) {
- histogram.update(unit.toNanos(duration));
- meter.mark();
+ public void update(final Duration duration) {
+ if (duration.isNegative() || duration.isZero()) {
+ return;
}
+ histogram.update(duration.toNanos());
+ meter.mark();
}
@Override
@@ -71,6 +72,11 @@
}
@Override
+ public Duration getElapsedTime() {
+ return null;
+ }
+
+ @Override
public long getCount() {
return histogram.getCount();
}
@@ -150,7 +156,7 @@
@Override
public long stop() {
final long duration = System.nanoTime() - start;
- update(duration, TimeUnit.NANOSECONDS);
+ update(Duration.ofNanos(duration));
return duration;
}
diff --git a/geronimo-metrics-common/src/main/java/org/apache/geronimo/microprofile/metrics/common/prometheus/PrometheusFormatter.java b/geronimo-metrics-common/src/main/java/org/apache/geronimo/microprofile/metrics/common/prometheus/PrometheusFormatter.java
index dda1a0c..09b16d6 100644
--- a/geronimo-metrics-common/src/main/java/org/apache/geronimo/microprofile/metrics/common/prometheus/PrometheusFormatter.java
+++ b/geronimo-metrics-common/src/main/java/org/apache/geronimo/microprofile/metrics/common/prometheus/PrometheusFormatter.java
@@ -16,12 +16,22 @@
*/
package org.apache.geronimo.microprofile.metrics.common.prometheus;
-import static java.lang.Math.pow;
-import static java.util.Optional.of;
-import static java.util.stream.Collectors.joining;
-import static java.util.stream.Collectors.toList;
-import static java.util.stream.Collectors.toMap;
-import static java.util.stream.Collectors.toSet;
+import org.eclipse.microprofile.metrics.ConcurrentGauge;
+import org.eclipse.microprofile.metrics.Counter;
+import org.eclipse.microprofile.metrics.Gauge;
+import org.eclipse.microprofile.metrics.Histogram;
+import org.eclipse.microprofile.metrics.Metadata;
+import org.eclipse.microprofile.metrics.Meter;
+import org.eclipse.microprofile.metrics.Metered;
+import org.eclipse.microprofile.metrics.Metric;
+import org.eclipse.microprofile.metrics.MetricID;
+import org.eclipse.microprofile.metrics.MetricRegistry;
+import org.eclipse.microprofile.metrics.MetricType;
+import org.eclipse.microprofile.metrics.MetricUnits;
+import org.eclipse.microprofile.metrics.SimpleTimer;
+import org.eclipse.microprofile.metrics.Snapshot;
+import org.eclipse.microprofile.metrics.Tag;
+import org.eclipse.microprofile.metrics.Timer;
import java.io.IOException;
import java.io.InputStream;
@@ -36,21 +46,12 @@
import java.util.function.Predicate;
import java.util.stream.Stream;
-import org.eclipse.microprofile.metrics.ConcurrentGauge;
-import org.eclipse.microprofile.metrics.Counter;
-import org.eclipse.microprofile.metrics.Gauge;
-import org.eclipse.microprofile.metrics.Histogram;
-import org.eclipse.microprofile.metrics.Metadata;
-import org.eclipse.microprofile.metrics.Meter;
-import org.eclipse.microprofile.metrics.Metered;
-import org.eclipse.microprofile.metrics.Metric;
-import org.eclipse.microprofile.metrics.MetricID;
-import org.eclipse.microprofile.metrics.MetricRegistry;
-import org.eclipse.microprofile.metrics.MetricType;
-import org.eclipse.microprofile.metrics.MetricUnits;
-import org.eclipse.microprofile.metrics.Snapshot;
-import org.eclipse.microprofile.metrics.Tag;
-import org.eclipse.microprofile.metrics.Timer;
+import static java.lang.Math.pow;
+import static java.util.Optional.of;
+import static java.util.stream.Collectors.joining;
+import static java.util.stream.Collectors.toList;
+import static java.util.stream.Collectors.toMap;
+import static java.util.stream.Collectors.toSet;
// note: we keep this name for backward compat but this is now an "openmetrics" formatter
// todo: cache all the keys, can easily be done decorating the registry and enriching metadata (ExtendedMetadata/MetricsID)
@@ -161,6 +162,12 @@
final Timer timer = Timer.class.cast(entry.metric);
return timer(registryKey, entry, tagsAsList, keyBase, keyUnit, timer);
}
+ case SIMPLE_TIMER: {
+ final String keyBase = toPrometheus(entry.metadata);
+ final String keyUnit = toUnitSuffix(entry.metadata, false);
+ final SimpleTimer timer = SimpleTimer.class.cast(entry.metric);
+ return simpleTimer(registryKey, entry, tagsAsList, keyBase, keyUnit, timer);
+ }
case HISTOGRAM:
final String keyBase = toPrometheus(entry.metadata);
final String keyUnit = toUnitSuffix(entry.metadata, false);
@@ -188,6 +195,12 @@
.append(toPrometheus(registryKey, keyBase, keyUnit, timer.getSnapshot(), entry.metadata, tagsAsList));
}
+ private StringBuilder simpleTimer(final String registryKey, final Entry entry, final List<Tag> tagsAsList, final String keyBase, final String keyUnit, final SimpleTimer timer) {
+ return new StringBuilder()
+ .append(type(registryKey, keyBase + keyUnit + " summary", entry.metadata))
+ .append(value(registryKey, keyBase + keyUnit + "_count", timer.getCount(), entry.metadata, tagsAsList));
+ }
+
private StringBuilder meter(final String registryKey, final Entry entry, final List<Tag> tagsAsList, final Metered meter, final String keyBase) {
return new StringBuilder()
.append(value(registryKey, keyBase + "_rate_per_second", meter.getMeanRate(), entry.metadata, tagsAsList))
diff --git a/geronimo-metrics-common/src/test/java/org/apache/geronimo/microprofile/metrics/common/json/JsonMetricTest.java b/geronimo-metrics-common/src/test/java/org/apache/geronimo/microprofile/metrics/common/json/JsonMetricTest.java
index 554f6ac..f5f1879 100644
--- a/geronimo-metrics-common/src/test/java/org/apache/geronimo/microprofile/metrics/common/json/JsonMetricTest.java
+++ b/geronimo-metrics-common/src/test/java/org/apache/geronimo/microprofile/metrics/common/json/JsonMetricTest.java
@@ -22,6 +22,7 @@
import org.apache.geronimo.microprofile.metrics.common.jaxrs.SecurityValidator;
import org.apache.geronimo.microprofile.metrics.common.prometheus.PrometheusFormatter;
import org.eclipse.microprofile.metrics.Gauge;
+import org.eclipse.microprofile.metrics.MetricRegistry;
import org.junit.Test;
import javax.ws.rs.core.SecurityContext;
@@ -34,7 +35,7 @@
@Test
public void testJsonGaugeValue() {
- final RegistryImpl registry = new RegistryImpl();
+ final RegistryImpl registry = new RegistryImpl(MetricRegistry.Type.APPLICATION);
registry.register("foo", (Gauge<Long>) () -> 1L);
final MetricsEndpoints endpoints = new MetricsEndpoints();
diff --git a/geronimo-metrics-common/src/test/java/org/apache/geronimo/microprofile/metrics/common/prometheus/PrometheusFormatterTest.java b/geronimo-metrics-common/src/test/java/org/apache/geronimo/microprofile/metrics/common/prometheus/PrometheusFormatterTest.java
index f73a48f..92ada93 100644
--- a/geronimo-metrics-common/src/test/java/org/apache/geronimo/microprofile/metrics/common/prometheus/PrometheusFormatterTest.java
+++ b/geronimo-metrics-common/src/test/java/org/apache/geronimo/microprofile/metrics/common/prometheus/PrometheusFormatterTest.java
@@ -19,7 +19,6 @@
import static java.util.Collections.singletonMap;
import static org.junit.Assert.assertEquals;
-import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;
@@ -27,13 +26,14 @@
import org.apache.geronimo.microprofile.metrics.common.RegistryImpl;
import org.eclipse.microprofile.metrics.Gauge;
import org.eclipse.microprofile.metrics.Metric;
+import org.eclipse.microprofile.metrics.MetricRegistry;
import org.junit.Test;
public class PrometheusFormatterTest {
@Test
public void rename() {
final PrometheusFormatter prometheusFormatter = new PrometheusFormatter().enableOverriding();
- final RegistryImpl registry = new RegistryImpl();
+ final RegistryImpl registry = new RegistryImpl(MetricRegistry.Type.APPLICATION);
final Map<String, Metric> metrics = singletonMap("myMetric", (Gauge<Long>) () -> 1234L);
metrics.forEach(registry::register);
assertEquals(
@@ -59,7 +59,7 @@
@Test
public void filter() {
final PrometheusFormatter prometheusFormatter = new PrometheusFormatter().enableOverriding();
- final RegistryImpl registry = new RegistryImpl();
+ final RegistryImpl registry = new RegistryImpl(MetricRegistry.Type.APPLICATION);
final Map<String, Metric> metrics = new LinkedHashMap<>();
metrics.put("myMetric1", (Gauge<Long>) () -> 1234L);
metrics.put("myMetric2", (Gauge<Long>) () -> 1235L);
diff --git a/geronimo-metrics/src/main/java/org/apache/geronimo/microprofile/metrics/cdi/ConcurrentGaugeInterceptor.java b/geronimo-metrics/src/main/java/org/apache/geronimo/microprofile/metrics/cdi/ConcurrentGaugeInterceptor.java
index 586d16c..fe7147c 100644
--- a/geronimo-metrics/src/main/java/org/apache/geronimo/microprofile/metrics/cdi/ConcurrentGaugeInterceptor.java
+++ b/geronimo-metrics/src/main/java/org/apache/geronimo/microprofile/metrics/cdi/ConcurrentGaugeInterceptor.java
@@ -16,14 +16,10 @@
*/
package org.apache.geronimo.microprofile.metrics.cdi;
-import static java.util.Optional.ofNullable;
-
-import java.io.Serializable;
-import java.lang.reflect.Executable;
-import java.lang.reflect.Modifier;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.stream.Stream;
+import org.eclipse.microprofile.metrics.ConcurrentGauge;
+import org.eclipse.microprofile.metrics.MetricID;
+import org.eclipse.microprofile.metrics.MetricRegistry;
+import org.eclipse.microprofile.metrics.Tag;
import javax.annotation.Priority;
import javax.enterprise.inject.Intercepted;
@@ -35,11 +31,14 @@
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;
+import java.io.Serializable;
+import java.lang.reflect.Executable;
+import java.lang.reflect.Modifier;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.stream.Stream;
-import org.eclipse.microprofile.metrics.ConcurrentGauge;
-import org.eclipse.microprofile.metrics.MetricID;
-import org.eclipse.microprofile.metrics.MetricRegistry;
-import org.eclipse.microprofile.metrics.Tag;
+import static java.util.Optional.ofNullable;
@Interceptor
@Priority(Interceptor.Priority.LIBRARY_BEFORE)
@@ -100,12 +99,12 @@
Modifier.isAbstract(executable.getDeclaringClass().getModifiers()) ? type.getJavaClass() : executable.getDeclaringClass(),
executable, concurrentGauge == null ? null : concurrentGauge.name(),
concurrentGauge != null && concurrentGauge.absolute(),
- ofNullable(type.getAnnotation(org.eclipse.microprofile.metrics.annotation.ConcurrentGauge.class))
+ ofNullable(extension.getAnnotation(type, org.eclipse.microprofile.metrics.annotation.ConcurrentGauge.class))
.map(org.eclipse.microprofile.metrics.annotation.ConcurrentGauge::name)
.orElse(""));
- final ConcurrentGauge gauge = ConcurrentGauge.class.cast(registry.getMetrics().get(
- new MetricID(name, concurrentGauge == null ? new Tag[0] : extension.createTags(concurrentGauge.tags()))));
+ final ConcurrentGauge gauge = registry.getConcurrentGauge(
+ new MetricID(name, concurrentGauge == null ? new Tag[0] : extension.createTags(concurrentGauge.tags())));
if (gauge == null) {
throw new IllegalStateException("No counter with name [" + name + "] found in registry [" + registry + "]");
}
diff --git a/geronimo-metrics/src/main/java/org/apache/geronimo/microprofile/metrics/cdi/CountedInterceptor.java b/geronimo-metrics/src/main/java/org/apache/geronimo/microprofile/metrics/cdi/CountedInterceptor.java
index 386f745..7357071 100644
--- a/geronimo-metrics/src/main/java/org/apache/geronimo/microprofile/metrics/cdi/CountedInterceptor.java
+++ b/geronimo-metrics/src/main/java/org/apache/geronimo/microprofile/metrics/cdi/CountedInterceptor.java
@@ -16,14 +16,11 @@
*/
package org.apache.geronimo.microprofile.metrics.cdi;
-import static java.util.Optional.ofNullable;
-
-import java.io.Serializable;
-import java.lang.reflect.Executable;
-import java.lang.reflect.Modifier;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.stream.Stream;
+import org.eclipse.microprofile.metrics.Counter;
+import org.eclipse.microprofile.metrics.MetricID;
+import org.eclipse.microprofile.metrics.MetricRegistry;
+import org.eclipse.microprofile.metrics.Tag;
+import org.eclipse.microprofile.metrics.annotation.Counted;
import javax.annotation.Priority;
import javax.enterprise.inject.Intercepted;
@@ -35,12 +32,14 @@
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;
+import java.io.Serializable;
+import java.lang.reflect.Executable;
+import java.lang.reflect.Modifier;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.stream.Stream;
-import org.eclipse.microprofile.metrics.Counter;
-import org.eclipse.microprofile.metrics.MetricID;
-import org.eclipse.microprofile.metrics.MetricRegistry;
-import org.eclipse.microprofile.metrics.Tag;
-import org.eclipse.microprofile.metrics.annotation.Counted;
+import static java.util.Optional.ofNullable;
@Counted
@Interceptor
@@ -97,10 +96,10 @@
Modifier.isAbstract(executable.getDeclaringClass().getModifiers()) ? type.getJavaClass() : executable.getDeclaringClass(),
executable, counted == null ? null : counted.name(),
counted != null && counted.absolute(),
- ofNullable(type.getAnnotation(Counted.class)).map(Counted::name).orElse(""));
+ ofNullable(extension.getAnnotation(type, Counted.class)).map(Counted::name).orElse(""));
- final Counter counter = Counter.class.cast(registry.getMetrics().get(
- new MetricID(name, counted == null ? new Tag[0] : extension.createTags(counted.tags()))));
+ final Counter counter = registry.getCounter(
+ new MetricID(name, counted == null ? new Tag[0] : extension.createTags(counted.tags())));
if (counter == null) {
throw new IllegalStateException("No counter with name [" + name + "] found in registry [" + registry + "]");
}
diff --git a/geronimo-metrics/src/main/java/org/apache/geronimo/microprofile/metrics/cdi/MeteredInterceptor.java b/geronimo-metrics/src/main/java/org/apache/geronimo/microprofile/metrics/cdi/MeteredInterceptor.java
index a944811..bb56b77 100644
--- a/geronimo-metrics/src/main/java/org/apache/geronimo/microprofile/metrics/cdi/MeteredInterceptor.java
+++ b/geronimo-metrics/src/main/java/org/apache/geronimo/microprofile/metrics/cdi/MeteredInterceptor.java
@@ -16,14 +16,11 @@
*/
package org.apache.geronimo.microprofile.metrics.cdi;
-import static java.util.Optional.ofNullable;
-
-import java.io.Serializable;
-import java.lang.reflect.Executable;
-import java.lang.reflect.Modifier;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.stream.Stream;
+import org.eclipse.microprofile.metrics.Meter;
+import org.eclipse.microprofile.metrics.MetricID;
+import org.eclipse.microprofile.metrics.MetricRegistry;
+import org.eclipse.microprofile.metrics.Tag;
+import org.eclipse.microprofile.metrics.annotation.Metered;
import javax.annotation.Priority;
import javax.enterprise.inject.Intercepted;
@@ -35,12 +32,14 @@
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;
+import java.io.Serializable;
+import java.lang.reflect.Executable;
+import java.lang.reflect.Modifier;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.stream.Stream;
-import org.eclipse.microprofile.metrics.Meter;
-import org.eclipse.microprofile.metrics.MetricID;
-import org.eclipse.microprofile.metrics.MetricRegistry;
-import org.eclipse.microprofile.metrics.Tag;
-import org.eclipse.microprofile.metrics.annotation.Metered;
+import static java.util.Optional.ofNullable;
@Metered
@Interceptor
@@ -93,10 +92,10 @@
Modifier.isAbstract(executable.getDeclaringClass().getModifiers()) ? type.getJavaClass() : executable.getDeclaringClass(),
executable, metered == null ? null : metered.name(),
metered != null && metered.absolute(),
- ofNullable(type.getAnnotation(Metered.class)).map(Metered::name).orElse(""));
+ ofNullable(extension.getAnnotation(type, Metered.class)).map(Metered::name).orElse(""));
- meter = Meter.class.cast(registry.getMetrics().get(
- new MetricID(name, metered == null ? new Tag[0] : extension.createTags(metered.tags()))));
+ meter = registry.getMeter(
+ new MetricID(name, metered == null ? new Tag[0] : extension.createTags(metered.tags())));
if (meter == null) {
throw new IllegalStateException("No meter with name [" + name + "] found in registry [" + registry + "]");
}
diff --git a/geronimo-metrics/src/main/java/org/apache/geronimo/microprofile/metrics/cdi/MetricsExtension.java b/geronimo-metrics/src/main/java/org/apache/geronimo/microprofile/metrics/cdi/MetricsExtension.java
index cb50015..79e6b90 100644
--- a/geronimo-metrics/src/main/java/org/apache/geronimo/microprofile/metrics/cdi/MetricsExtension.java
+++ b/geronimo-metrics/src/main/java/org/apache/geronimo/microprofile/metrics/cdi/MetricsExtension.java
@@ -16,28 +16,36 @@
*/
package org.apache.geronimo.microprofile.metrics.cdi;
-import static java.util.Optional.of;
-import static java.util.Optional.ofNullable;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Member;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.function.Function;
-import java.util.stream.Stream;
+import org.apache.geronimo.microprofile.metrics.common.BaseMetrics;
+import org.apache.geronimo.microprofile.metrics.common.GaugeImpl;
+import org.apache.geronimo.microprofile.metrics.common.RegistryImpl;
+import org.apache.geronimo.microprofile.metrics.common.jaxrs.MetricsEndpoints;
+import org.apache.geronimo.microprofile.metrics.jaxrs.CdiMetricsEndpoints;
+import org.eclipse.microprofile.metrics.Counter;
+import org.eclipse.microprofile.metrics.Gauge;
+import org.eclipse.microprofile.metrics.Histogram;
+import org.eclipse.microprofile.metrics.Metadata;
+import org.eclipse.microprofile.metrics.Meter;
+import org.eclipse.microprofile.metrics.Metric;
+import org.eclipse.microprofile.metrics.MetricID;
+import org.eclipse.microprofile.metrics.MetricRegistry;
+import org.eclipse.microprofile.metrics.MetricType;
+import org.eclipse.microprofile.metrics.SimpleTimer;
+import org.eclipse.microprofile.metrics.Tag;
+import org.eclipse.microprofile.metrics.Timer;
+import org.eclipse.microprofile.metrics.annotation.ConcurrentGauge;
+import org.eclipse.microprofile.metrics.annotation.Counted;
+import org.eclipse.microprofile.metrics.annotation.Metered;
+import org.eclipse.microprofile.metrics.annotation.RegistryType;
+import org.eclipse.microprofile.metrics.annotation.SimplyTimed;
+import org.eclipse.microprofile.metrics.annotation.Timed;
import javax.enterprise.context.Dependent;
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.Any;
import javax.enterprise.inject.Default;
+import javax.enterprise.inject.Stereotype;
import javax.enterprise.inject.spi.AfterBeanDiscovery;
import javax.enterprise.inject.spi.AfterDeploymentValidation;
import javax.enterprise.inject.spi.Annotated;
@@ -56,35 +64,30 @@
import javax.enterprise.inject.spi.configurator.BeanConfigurator;
import javax.enterprise.util.AnnotationLiteral;
import javax.enterprise.util.Nonbinding;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Function;
+import java.util.stream.Stream;
-import org.apache.geronimo.microprofile.metrics.common.BaseMetrics;
-import org.apache.geronimo.microprofile.metrics.common.GaugeImpl;
-import org.apache.geronimo.microprofile.metrics.common.RegistryImpl;
-import org.apache.geronimo.microprofile.metrics.common.jaxrs.MetricsEndpoints;
-import org.apache.geronimo.microprofile.metrics.jaxrs.CdiMetricsEndpoints;
-import org.eclipse.microprofile.metrics.Counter;
-import org.eclipse.microprofile.metrics.Gauge;
-import org.eclipse.microprofile.metrics.Histogram;
-import org.eclipse.microprofile.metrics.Metadata;
-import org.eclipse.microprofile.metrics.Meter;
-import org.eclipse.microprofile.metrics.Metric;
-import org.eclipse.microprofile.metrics.MetricID;
-import org.eclipse.microprofile.metrics.MetricRegistry;
-import org.eclipse.microprofile.metrics.MetricType;
-import org.eclipse.microprofile.metrics.Tag;
-import org.eclipse.microprofile.metrics.Timer;
-import org.eclipse.microprofile.metrics.annotation.ConcurrentGauge;
-import org.eclipse.microprofile.metrics.annotation.Counted;
-import org.eclipse.microprofile.metrics.annotation.Metered;
-import org.eclipse.microprofile.metrics.annotation.RegistryType;
-import org.eclipse.microprofile.metrics.annotation.Timed;
+import static java.util.Optional.of;
+import static java.util.Optional.ofNullable;
public class MetricsExtension implements Extension {
private static final Tag[] NO_TAG = new Tag[0];
- private final MetricRegistry applicationRegistry = new RegistryImpl();
- private final MetricRegistry baseRegistry = new RegistryImpl();
- private final MetricRegistry vendorRegistry = new RegistryImpl();
+ private final MetricRegistry applicationRegistry = new RegistryImpl(MetricRegistry.Type.APPLICATION);
+ private final MetricRegistry baseRegistry = new RegistryImpl(MetricRegistry.Type.BASE);
+ private final MetricRegistry vendorRegistry = new RegistryImpl(MetricRegistry.Type.VENDOR);
private final Map<MetricID, Metadata> registrations = new HashMap<>();
private final Map<MetricID, Function<BeanManager, Gauge<?>>> gaugeFactories = new HashMap<>();
@@ -228,6 +231,7 @@
void findInterceptorMetrics(@Observes @WithAnnotations({
Counted.class,
+ SimplyTimed.class,
Timed.class,
ConcurrentGauge.class,
org.eclipse.microprofile.metrics.annotation.Metered.class,
@@ -248,11 +252,11 @@
final Member javaMember = method.getJavaMember();
final Counted counted = ofNullable(method.getAnnotation(Counted.class)).orElseGet(() ->
- annotatedType.getAnnotation(Counted.class));
+ getAnnotation(annotatedType, Counted.class));
if (counted != null) {
final boolean isMethod = method.isAnnotationPresent(Counted.class);
final String name = Names.findName(javaClass, javaMember, isMethod ? counted.name() : "", counted.absolute(),
- ofNullable(annotatedType.getAnnotation(Counted.class)).map(Counted::name).orElse(""));
+ ofNullable(getAnnotation(annotatedType, Counted.class)).map(Counted::name).orElse(""));
final Metadata metadata = Metadata.builder()
.withName(name)
.withDisplayName(counted.displayName())
@@ -265,11 +269,11 @@
}
final ConcurrentGauge concurrentGauge = ofNullable(method.getAnnotation(ConcurrentGauge.class)).orElseGet(() ->
- annotatedType.getAnnotation(ConcurrentGauge.class));
+ getAnnotation(annotatedType, ConcurrentGauge.class));
if (concurrentGauge != null) {
final boolean isMethod = method.isAnnotationPresent(ConcurrentGauge.class);
final String name = Names.findName(javaClass, javaMember, isMethod ? concurrentGauge.name() : "", concurrentGauge.absolute(),
- ofNullable(annotatedType.getAnnotation(ConcurrentGauge.class)).map(ConcurrentGauge::name).orElse(""));
+ ofNullable(getAnnotation(annotatedType, ConcurrentGauge.class)).map(ConcurrentGauge::name).orElse(""));
final Metadata metadata = Metadata.builder()
.withName(name)
.withDisplayName(concurrentGauge.displayName())
@@ -281,11 +285,11 @@
addRegistration(metadata, metricID, concurrentGauge.reusable() || !isMethod);
}
- final Timed timed = ofNullable(method.getAnnotation(Timed.class)).orElseGet(() -> annotatedType.getAnnotation(Timed.class));
+ final Timed timed = ofNullable(method.getAnnotation(Timed.class)).orElseGet(() -> getAnnotation(annotatedType, Timed.class));
if (timed != null) {
final boolean isMethod = method.isAnnotationPresent(Timed.class);
final String name = Names.findName(javaClass, javaMember, isMethod ? timed.name() : "", timed.absolute(),
- ofNullable(annotatedType.getAnnotation(Timed.class)).map(Timed::name).orElse(""));
+ ofNullable(getAnnotation(annotatedType, Timed.class)).map(Timed::name).orElse(""));
final Metadata metadata = Metadata.builder()
.withName(name)
.withDisplayName(timed.displayName())
@@ -297,12 +301,28 @@
addRegistration(metadata, metricID, timed.reusable() || !isMethod);
}
+ final SimplyTimed simplyTimed = ofNullable(method.getAnnotation(SimplyTimed.class)).orElseGet(() -> getAnnotation(annotatedType, SimplyTimed.class));
+ if (simplyTimed != null) {
+ final boolean isMethod = method.isAnnotationPresent(SimplyTimed.class);
+ final String name = Names.findName(javaClass, javaMember, isMethod ? simplyTimed.name() : "", simplyTimed.absolute(),
+ ofNullable(getAnnotation(annotatedType, SimplyTimed.class)).map(SimplyTimed::name).orElse(""));
+ final Metadata metadata = Metadata.builder()
+ .withName(name)
+ .withDisplayName(simplyTimed.displayName())
+ .withDescription(simplyTimed.description())
+ .withType(MetricType.SIMPLE_TIMER)
+ .withUnit(simplyTimed.unit())
+ .build();
+ final MetricID metricID = new MetricID(name, createTags(simplyTimed.tags()));
+ addRegistration(metadata, metricID, simplyTimed.reusable() || !isMethod);
+ }
+
final org.eclipse.microprofile.metrics.annotation.Metered metered = ofNullable(method.getAnnotation(org.eclipse.microprofile.metrics.annotation.Metered.class))
- .orElseGet(() -> annotatedType.getAnnotation(org.eclipse.microprofile.metrics.annotation.Metered.class));
+ .orElseGet(() -> getAnnotation(annotatedType, org.eclipse.microprofile.metrics.annotation.Metered.class));
if (metered != null) {
final boolean isMethod = method.isAnnotationPresent(Metered.class);
final String name = Names.findName(javaClass, javaMember, isMethod ? metered.name() : "", metered.absolute(),
- ofNullable(annotatedType.getAnnotation(Metered.class)).map(Metered::name).orElse(""));
+ ofNullable(getAnnotation(annotatedType, Metered.class)).map(Metered::name).orElse(""));
final Metadata metadata = Metadata.builder()
.withName(name)
.withDisplayName(metered.displayName())
@@ -315,12 +335,11 @@
}
final org.eclipse.microprofile.metrics.annotation.Gauge gauge = ofNullable(method.getAnnotation(org.eclipse.microprofile.metrics.annotation.Gauge.class))
- .orElseGet(() -> annotatedType.getAnnotation(org.eclipse.microprofile.metrics.annotation
- .Gauge.class));
+ .orElseGet(() -> getAnnotation(annotatedType, org.eclipse.microprofile.metrics.annotation.Gauge.class));
if (gauge != null) {
final String name = Names.findName(
javaClass, javaMember, gauge.name(), gauge.absolute(),
- ofNullable(annotatedType.getAnnotation(org.eclipse.microprofile.metrics.annotation.Gauge.class)).map(org.eclipse.microprofile.metrics.annotation.Gauge::name).orElse(""));
+ ofNullable(getAnnotation(annotatedType, org.eclipse.microprofile.metrics.annotation.Gauge.class)).map(org.eclipse.microprofile.metrics.annotation.Gauge::name).orElse(""));
final Metadata metadata = Metadata.builder()
.withName(name)
.withDisplayName(gauge.displayName())
@@ -367,6 +386,10 @@
addBean(afterBeanDiscovery, idSuffix, Timer.class, new MetricImpl(metadata, id),
applicationRegistry.timer(metadata, id.getTagsAsList().toArray(NO_TAG)), true);
break;
+ case SIMPLE_TIMER:
+ addBean(afterBeanDiscovery, idSuffix, SimpleTimer.class, new MetricImpl(metadata, id),
+ applicationRegistry.simpleTimer(metadata, id.getTagsAsList().toArray(NO_TAG)), true);
+ break;
case COUNTER:
addBean(afterBeanDiscovery, idSuffix, Counter.class, new MetricImpl(metadata, id),
applicationRegistry.counter(metadata, id.getTagsAsList().toArray(NO_TAG)), true);
@@ -454,6 +477,8 @@
type = MetricType.METERED;
} else if (Timer.class.isAssignableFrom(clazz)) {
type = MetricType.TIMER;
+ } else if (SimpleTimer.class.isAssignableFrom(clazz)) {
+ type = MetricType.SIMPLE_TIMER;
} else if (Histogram.class.isAssignableFrom(clazz)) {
type = MetricType.HISTOGRAM;
} else if (org.eclipse.microprofile.metrics.ConcurrentGauge.class.isAssignableFrom(clazz)) {
@@ -508,6 +533,20 @@
}
}
+ public <T extends Annotation> T getAnnotation(final AnnotatedType<?> type, final Class<T> expected) {
+ final T annotation = type.getAnnotation(expected);
+ if (annotation != null) {
+ return annotation;
+ }
+ // not sexy but not great to use too
+ return type.getAnnotations().stream()
+ .filter(a -> a.annotationType().isAnnotationPresent(Stereotype.class))
+ .map(a -> a.annotationType().getAnnotation(expected))
+ .filter(Objects::nonNull)
+ .findFirst()
+ .orElse(null);
+ }
+
private static final class MetricImpl extends AnnotationLiteral<org.eclipse.microprofile.metrics.annotation.Metric> implements org.eclipse.microprofile.metrics.annotation.Metric {
private final Metadata metadata;
private final String[] tags;
@@ -573,14 +612,4 @@
return RegistryType.class;
}
}
-
- private static class Registration {
- private final MetricID id;
- private final Metadata metadata;
-
- private Registration(final MetricID id, final Metadata metadata) {
- this.id = id;
- this.metadata = metadata;
- }
- }
}
diff --git a/geronimo-metrics/src/main/java/org/apache/geronimo/microprofile/metrics/cdi/SimplyTimedInterceptor.java b/geronimo-metrics/src/main/java/org/apache/geronimo/microprofile/metrics/cdi/SimplyTimedInterceptor.java
new file mode 100644
index 0000000..b97e8d7
--- /dev/null
+++ b/geronimo-metrics/src/main/java/org/apache/geronimo/microprofile/metrics/cdi/SimplyTimedInterceptor.java
@@ -0,0 +1,101 @@
+/*
+ * 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.geronimo.microprofile.metrics.cdi;
+
+import org.eclipse.microprofile.metrics.MetricID;
+import org.eclipse.microprofile.metrics.MetricRegistry;
+import org.eclipse.microprofile.metrics.SimpleTimer;
+import org.eclipse.microprofile.metrics.Tag;
+import org.eclipse.microprofile.metrics.annotation.SimplyTimed;
+
+import javax.annotation.Priority;
+import javax.enterprise.inject.Intercepted;
+import javax.enterprise.inject.spi.AnnotatedType;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.inject.Inject;
+import javax.interceptor.AroundConstruct;
+import javax.interceptor.AroundInvoke;
+import javax.interceptor.Interceptor;
+import javax.interceptor.InvocationContext;
+import java.io.Serializable;
+import java.lang.reflect.Executable;
+import java.lang.reflect.Modifier;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.stream.Stream;
+
+import static java.util.Optional.ofNullable;
+
+@SimplyTimed
+@Interceptor
+@Priority(Interceptor.Priority.LIBRARY_BEFORE)
+public class SimplyTimedInterceptor implements Serializable {
+ @Inject
+ private MetricRegistry registry;
+
+ @Inject
+ @Intercepted
+ private Bean<?> bean;
+
+ @Inject
+ private BeanManager beanManager;
+
+ @Inject
+ private MetricsExtension extension;
+
+ private transient volatile ConcurrentMap<Executable, SimpleTimer> timers = new ConcurrentHashMap<>();
+
+ @AroundConstruct
+ public Object onConstructor(final InvocationContext context) throws Exception {
+ return findTimer(context.getConstructor()).time(context::proceed);
+ }
+
+ @AroundInvoke
+ public Object onMethod(final InvocationContext context) throws Exception {
+ return findTimer(context.getMethod()).time(context::proceed);
+ }
+
+ private SimpleTimer findTimer(final Executable executable) {
+ if (timers == null) {
+ synchronized (this) {
+ if (timers == null) {
+ timers = new ConcurrentHashMap<>();
+ }
+ }
+ }
+ SimpleTimer timer = timers.get(executable);
+ if (timer == null) {
+ final AnnotatedType<?> type = beanManager.createAnnotatedType(bean.getBeanClass());
+ final SimplyTimed timed = Stream.concat(type.getMethods().stream(), type.getConstructors().stream())
+ .filter(it -> it.getJavaMember().equals(executable))
+ .findFirst()
+ .map(m -> m.getAnnotation(SimplyTimed.class))
+ .orElse(null);
+ final String name = Names.findName(
+ Modifier.isAbstract(executable.getDeclaringClass().getModifiers()) ? type.getJavaClass() : executable.getDeclaringClass(),
+ executable, timed == null ? null : timed.name(), timed != null && timed.absolute(),
+ ofNullable(extension.getAnnotation(type, SimplyTimed.class)).map(SimplyTimed::name).orElse(""));
+ timer = registry.getSimpleTimer(new MetricID(name, timed == null ? new Tag[0] : extension.createTags(timed.tags())));
+ if (timer == null) {
+ throw new IllegalStateException("No timer with name [" + name + "] found in registry [" + registry + "]");
+ }
+ timers.putIfAbsent(executable, timer);
+ }
+ return timer;
+ }
+}
diff --git a/geronimo-metrics/src/main/java/org/apache/geronimo/microprofile/metrics/cdi/TimedInterceptor.java b/geronimo-metrics/src/main/java/org/apache/geronimo/microprofile/metrics/cdi/TimedInterceptor.java
index f760c83..d736fc1 100644
--- a/geronimo-metrics/src/main/java/org/apache/geronimo/microprofile/metrics/cdi/TimedInterceptor.java
+++ b/geronimo-metrics/src/main/java/org/apache/geronimo/microprofile/metrics/cdi/TimedInterceptor.java
@@ -90,9 +90,8 @@
final String name = Names.findName(
Modifier.isAbstract(executable.getDeclaringClass().getModifiers()) ? type.getJavaClass() : executable.getDeclaringClass(),
executable, timed == null ? null : timed.name(), timed != null && timed.absolute(),
- ofNullable(type.getAnnotation(Timed.class)).map(Timed::name).orElse(""));
- timer = Timer.class.cast(registry.getMetrics().get(
- new MetricID(name, timed == null ? new Tag[0] : extension.createTags(timed.tags()))));
+ ofNullable(extension.getAnnotation(type, Timed.class)).map(Timed::name).orElse(""));
+ timer = registry.getTimer(new MetricID(name, timed == null ? new Tag[0] : extension.createTags(timed.tags())));
if (timer == null) {
throw new IllegalStateException("No timer with name [" + name + "] found in registry [" + registry + "]");
}
diff --git a/pom.xml b/pom.xml
index e33d4c5..616437a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -42,7 +42,7 @@
</scm>
<properties>
- <spec.version>2.2.1</spec.version>
+ <spec.version>3.0-M2</spec.version>
<arquillian.version>1.1.8.Final</arquillian.version>
<meecrowave.version>1.2.8</meecrowave.version>
</properties>
@@ -116,13 +116,13 @@
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jcdi_2.0_spec</artifactId>
- <version>1.0.1</version>
+ <version>1.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-annotation_1.3_spec</artifactId>
- <version>1.0</version>
+ <version>1.2</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -147,7 +147,7 @@
<dependency>
<groupId>org.apache.openwebbeans</groupId>
<artifactId>openwebbeans-web</artifactId>
- <version>2.0.7</version>
+ <version>2.0.16</version>
<scope>test</scope>
</dependency>
</dependencies>
@@ -158,7 +158,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
- <version>3.8.0</version>
+ <version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>