ReportedBean { static ReportedBean forTarget(Object target, BucketIdProvider bucketIdProvider) { requireNonNull(target, "target is null"); List<ReportedBeanAttribute> attributes = new ArrayList<>(); List<PrometheusBeanAttribute> prometheusAttributes = new ArrayList<>(); if (target instanceof Bucketed) { ((Bucketed<?>) target).setBucketIdProvider(bucketIdProvider); BucketInfo bucketInfo = null; try { bucketInfo = (BucketInfo) GET_PREVIOUS_BUCKET.invoke(target); } catch (Exception ignored) { } if (bucketInfo != null) { ReportedBean reportedBean = ReportedBean.forTarget(bucketInfo.getBucket(), bucketIdProvider); for (ReportedBeanAttribute attribute : reportedBean.getAttributes()) { attributes.add(new BucketedReportedBeanAttribute(target, attribute)); } for (PrometheusBeanAttribute prometheusAttribute : reportedBean.getPrometheusAttributes()) { prometheusAttributes.add(new BucketedPrometheusBeanAttribute(target, prometheusAttribute)); } } } Map<String, ReportedMethodInfoBuilder> methodInfoBuilders = new TreeMap<>(); for (Map.Entry<Method, Method> entry : METHODS_CACHE.getUnchecked(target.getClass())) { Method concreteMethod = entry.getKey(); Method annotatedMethod = entry.getValue(); if (!isGetter(concreteMethod)) { throw new RuntimeException("report annotation on non-getter " + annotatedMethod.toGenericString()); } String attributeName = getAttributeName(concreteMethod); ReportedMethodInfoBuilder attributeBuilder = methodInfoBuilders.get(attributeName); if (attributeBuilder == null) { attributeBuilder = new ReportedMethodInfoBuilder(bucketIdProvider).named(attributeName).onInstance(target); } attributeBuilder = attributeBuilder .withConcreteGetter(concreteMethod) .withAnnotatedGetter(annotatedMethod); methodInfoBuilders.put(attributeName, attributeBuilder); } for (ReportedMethodInfoBuilder methodInfoBuilder : methodInfoBuilders.values()) { ReportedMethodInfo methodInfo = methodInfoBuilder.build(); attributes.addAll(methodInfo.getAttributes()); prometheusAttributes.addAll(methodInfo.getPrometheusAttributes()); } return new ReportedBean(attributes, prometheusAttributes); } private  ReportedBean(Collection<ReportedBeanAttribute> attributes, Collection<PrometheusBeanAttribute> prometheusAttributes);   }
@Test(expectedExceptions = RuntimeException.class, expectedExceptionsMessageRegExp = "report annotation on non-getter .*operation\\(\\)") public void testNonAttribute() { ReportedBean.forTarget(new Object() { @Reported public int operation() { return 3; } }, bucketIdProvider); }
@Test(expectedExceptions = RuntimeException.class, expectedExceptionsMessageRegExp = "report annotation on non-getter .*operation\\(int\\)") public void testSetter() { ReportedBean.forTarget(new Object() { @Reported public void operation(int param) { } }, bucketIdProvider); }
@Test(expectedExceptions = RuntimeException.class, expectedExceptionsMessageRegExp = "report annotation on non-getter .*getVoid\\(\\)") public void testInvalidGetter() { ReportedBean.forTarget(new Object() { @Reported public void getVoid() { } }, bucketIdProvider); }