--- /dev/null 2017-11-09 09:38:01.297999907 +0100 +++ new/test/jdk/jdk/jfr/api/event/dynamic/TestDynamicAnnotations.java 2018-04-09 16:42:06.940776982 +0200 @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jfr.api.event.dynamic; + +import java.io.IOException; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import jdk.jfr.AnnotationElement; +import jdk.jfr.Category; +import jdk.jfr.Description; +import jdk.jfr.Event; +import jdk.jfr.EventFactory; +import jdk.jfr.EventType; +import jdk.jfr.Label; +import jdk.jfr.MetadataDefinition; +import jdk.jfr.Name; +import jdk.jfr.Recording; +import jdk.jfr.Relational; +import jdk.jfr.ValueDescriptor; +import jdk.jfr.consumer.RecordedEvent; +import jdk.test.lib.jfr.Events; + +/* + * @test + * @key jfr + * @library /test/lib + * @run main/othervm jdk.jfr.api.event.dynamic.TestDynamicAnnotations + */ +public class TestDynamicAnnotations { + + @Label("Execution Context Id") + @Description("A unique identifier to correlate events or requests associated with the same task across several components") + @Relational + @MetadataDefinition + @Target(ElementType.FIELD) + @Retention(RetentionPolicy.RUNTIME) + private @interface ECID { + } + + @MetadataDefinition + @Target({ ElementType.FIELD, ElementType.TYPE }) + @Retention(RetentionPolicy.RUNTIME) + private @interface Array { + String[] stringArray(); + + int[] intArray(); + + long[] longArray(); + + float[] floatArray(); + + double[] doubleArray(); + + boolean[] booleanArray(); + + short[] shortArray(); + + byte[] byteArray(); + + char[] charArray(); + } + + public static void main(String[] args) throws Throwable { + testEventFactoryExample(); + testECID(); + testArray(); + } + + // Copy of sample code in Javadoc for jdk.jfr.EVentFactory + public static void testEventFactoryExample() throws IOException { + List fields = new ArrayList<>(); + List messageAnnotations = Collections.singletonList(new AnnotationElement(Label.class, "Message")); + fields.add(new ValueDescriptor(String.class, "message", messageAnnotations)); + List numberAnnotations = Collections.singletonList(new AnnotationElement(Label.class, "Number")); + fields.add(new ValueDescriptor(int.class, "number", numberAnnotations)); + + String[] category = { "Example", "Getting Started" }; + List eventAnnotations = new ArrayList<>(); + eventAnnotations.add(new AnnotationElement(Name.class, "com.example.HelloWorld")); + eventAnnotations.add(new AnnotationElement(Label.class, "Hello World")); + eventAnnotations.add(new AnnotationElement(Description.class, "Helps programmer getting started")); + eventAnnotations.add(new AnnotationElement(Category.class, category)); + + EventFactory f = EventFactory.create(eventAnnotations, fields); + + Event event = f.newEvent(); + event.set(0, "hello, world!"); + event.set(1, 4711); + event.commit(); + } + + public static void testECID() throws Exception { + List fields = new ArrayList<>(); + + List fieldAnnotations = new ArrayList<>(); + fieldAnnotations.add(new AnnotationElement(ECID.class)); + ValueDescriptor ecidField = new ValueDescriptor(String.class, "ecid", fieldAnnotations); + fields.add(ecidField); + + EventFactory f = EventFactory.create(fieldAnnotations, fields); + + String ecidValue = "131739871298371279812"; + try (Recording r = new Recording()) { + r.start(); + Event event = f.newEvent(); + event.set(0, ecidValue); + event.commit(); + r.stop(); + List events = Events.fromRecording(r); + Events.hasEvents(events); + Events.assertField(events.get(0), "ecid").equal(ecidValue); + } + EventType type = f.getEventType(); + ECID e = type.getAnnotation(ECID.class); + if (e == null) { + throw new Exception("Missing ECID annotation"); + } + } + + public static void testArray() throws Exception { + List annotations = new ArrayList<>(); + Map values = new HashMap<>(); + values.put("stringArray", new String[] {"zero", "one"}); + values.put("intArray", new int[] {0, 1}); + values.put("longArray", new long[] {0L, 1L}); + values.put("floatArray", new float[] {0.0f, 1.0f}); + values.put("doubleArray", new double[] {0.0, 1.0}); + values.put("booleanArray", new boolean[] {false, true}); + values.put("shortArray", new short[] {(short)0, (short)1}); + values.put("byteArray", new byte[] {(byte)0, (byte)1}); + values.put("charArray", new char[] {'0','1'}); + + annotations.add(new AnnotationElement(Array.class, values)); + EventFactory f = EventFactory.create(annotations, Collections.emptyList()); + Array a = f.getEventType().getAnnotation(Array.class); + if (a == null) { + throw new Exception("Missing array annotation"); + } + verifyArrayAnnotation(a); + System.out.println("Event metadata is correct"); + try (Recording r = new Recording()) { + r.start(); + Event e = f.newEvent(); + e.commit(); + r.stop(); + List events = Events.fromRecording(r); + Events.hasEvents(events); + RecordedEvent re = events.get(0); + Array arrayAnnotation = re.getEventType().getAnnotation(Array.class); + if (arrayAnnotation== null) { + throw new Exception("Missing array annotation"); + } + verifyArrayAnnotation(arrayAnnotation); + System.out.println("Persisted event metadata is correct"); + } + } + + private static void verifyArrayAnnotation(Array a) throws Exception { + if (!a.stringArray()[0].equals("zero") || !a.stringArray()[1].equals("one")) { + throw new Exception("string[] doesn't match"); + } + if (a.intArray()[0] != 0 || a.intArray()[1] != 1) { + throw new Exception("int[] doesn't match"); + } + if (a.longArray()[0] != 0 || a.longArray()[1] != 1) { + throw new Exception("long[] doesn't match"); + } + if (a.floatArray()[0] != 0.0f || a.floatArray()[1] != 1.0f) { + throw new Exception("float[] doesn't match"); + } + if (a.doubleArray()[0] != 0.0 || a.doubleArray()[1] != 1.0) { + throw new Exception("double[] doesn't match"); + } + if (a.booleanArray()[0] != false || a.booleanArray()[1] != true) { + throw new Exception("boolean[] doesn't match"); + } + if (a.shortArray()[0] != (short)0 || a.shortArray()[1] != (short)1) { + throw new Exception("short[] doesn't match"); + } + if (a.byteArray()[0] != (byte)0 || a.byteArray()[1] != (byte)1) { + throw new Exception("byte[] doesn't match"); + } + if (a.charArray()[0] != '0' || a.charArray()[1] != '1') { + throw new Exception("char[] doesn't match"); + } + } +}