src/jdk.management.jfr/share/classes/jdk/management/jfr/FlightRecorderMXBeanImpl.java
author cito
Mon, 07 Oct 2019 16:44:12 +0200
changeset 58480 8ca46e186a63
parent 50113 caf115bb98ad
permissions -rw-r--r--
8225694: Destination option missing in FlightRecorderMXBeanImpl Reviewed-by: egahlin
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     1
/*
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     2
 * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     4
 *
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    10
 *
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    15
 * accompanied this code).
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    16
 *
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    20
 *
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    23
 * questions.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    24
 */
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    25
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    26
package jdk.management.jfr;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    27
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    28
import java.io.IOException;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    29
import java.io.InputStream;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    30
import java.io.StringReader;
58480
8ca46e186a63 8225694: Destination option missing in FlightRecorderMXBeanImpl
cito
parents: 50113
diff changeset
    31
import java.nio.file.Path;
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    32
import java.nio.file.Paths;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    33
import java.security.AccessControlContext;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    34
import java.security.AccessController;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    35
import java.security.PrivilegedAction;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    36
import java.text.ParseException;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    37
import java.time.Instant;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    38
import java.util.ArrayList;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    39
import java.util.Arrays;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    40
import java.util.Collections;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    41
import java.util.HashMap;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    42
import java.util.List;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    43
import java.util.Map;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    44
import java.util.Objects;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    45
import java.util.concurrent.ConcurrentHashMap;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    46
import java.util.concurrent.CopyOnWriteArrayList;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    47
import java.util.concurrent.atomic.AtomicLong;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    48
import java.util.function.Consumer;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    49
import java.util.function.Function;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    50
import java.util.function.Predicate;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    51
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    52
import javax.management.AttributeChangeNotification;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    53
import javax.management.AttributeNotFoundException;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    54
import javax.management.ListenerNotFoundException;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    55
import javax.management.MBeanException;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    56
import javax.management.MBeanNotificationInfo;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    57
import javax.management.Notification;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    58
import javax.management.NotificationBroadcasterSupport;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    59
import javax.management.NotificationEmitter;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    60
import javax.management.NotificationFilter;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    61
import javax.management.NotificationListener;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    62
import javax.management.ObjectName;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    63
import javax.management.ReflectionException;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    64
import javax.management.StandardEmitterMBean;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    65
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    66
import jdk.jfr.Configuration;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    67
import jdk.jfr.EventType;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    68
import jdk.jfr.FlightRecorder;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    69
import jdk.jfr.FlightRecorderListener;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    70
import jdk.jfr.FlightRecorderPermission;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    71
import jdk.jfr.Recording;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    72
import jdk.jfr.RecordingState;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    73
import jdk.jfr.internal.management.ManagementSupport;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    74
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    75
// Instantiated by service provider
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    76
final class FlightRecorderMXBeanImpl extends StandardEmitterMBean implements FlightRecorderMXBean, NotificationEmitter {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    77
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    78
    final class MXBeanListener implements FlightRecorderListener {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    79
        private final NotificationListener listener;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    80
        private final NotificationFilter filter;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    81
        private final Object handback;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    82
        private final AccessControlContext context;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    83
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    84
        public MXBeanListener(NotificationListener listener, NotificationFilter filter, Object handback) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    85
            this.context = AccessController.getContext();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    86
            this.listener = listener;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    87
            this.filter = filter;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    88
            this.handback = handback;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    89
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    90
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    91
        public void recordingStateChanged(Recording recording) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    92
            AccessController.doPrivileged(new PrivilegedAction<Void>() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    93
                @Override
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    94
                public Void run() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    95
                    sendNotification(createNotication(recording));
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    96
                    return null;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    97
                }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    98
            }, context);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    99
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   100
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   101
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   102
    private static final String ATTRIBUTE_RECORDINGS = "Recordings";
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   103
    private static final String OPTION_MAX_SIZE = "maxSize";
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   104
    private static final String OPTION_MAX_AGE = "maxAge";
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   105
    private static final String OPTION_NAME = "name";
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   106
    private static final String OPTION_DISK = "disk";
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   107
    private static final String OPTION_DUMP_ON_EXIT = "dumpOnExit";
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   108
    private static final String OPTION_DURATION = "duration";
58480
8ca46e186a63 8225694: Destination option missing in FlightRecorderMXBeanImpl
cito
parents: 50113
diff changeset
   109
    private static final String OPTION_DESTINATION = "destination";
8ca46e186a63 8225694: Destination option missing in FlightRecorderMXBeanImpl
cito
parents: 50113
diff changeset
   110
    private static final List<String> OPTIONS = Arrays.asList(new String[] { OPTION_DUMP_ON_EXIT, OPTION_DURATION, OPTION_NAME, OPTION_MAX_AGE, OPTION_MAX_SIZE, OPTION_DISK, OPTION_DESTINATION, });
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   111
    private final StreamManager streamHandler = new StreamManager();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   112
    private final Map<Long, Object> changes = new ConcurrentHashMap<>();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   113
    private final AtomicLong sequenceNumber = new AtomicLong();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   114
    private final List<MXBeanListener> listeners = new CopyOnWriteArrayList<>();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   115
    private FlightRecorder recorder;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   116
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   117
    FlightRecorderMXBeanImpl() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   118
        super(FlightRecorderMXBean.class, true, new NotificationBroadcasterSupport(createNotificationInfo()));
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   119
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   120
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   121
    @Override
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   122
    public void startRecording(long id) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   123
        MBeanUtils.checkControl();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   124
        getExistingRecording(id).start();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   125
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   126
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   127
    @Override
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   128
    public boolean stopRecording(long id) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   129
        MBeanUtils.checkControl();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   130
        return getExistingRecording(id).stop();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   131
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   132
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   133
    @Override
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   134
    public void closeRecording(long id) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   135
        MBeanUtils.checkControl();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   136
        getExistingRecording(id).close();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   137
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   138
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   139
    @Override
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   140
    public long openStream(long id, Map<String, String> options) throws IOException {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   141
        MBeanUtils.checkControl();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   142
        if (!FlightRecorder.isInitialized()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   143
            throw new IllegalArgumentException("No recording available with id " + id);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   144
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   145
        // Make local copy to prevent concurrent modification
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   146
        Map<String, String> s = options == null ? new HashMap<>() : new HashMap<>(options);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   147
        Instant starttime = MBeanUtils.parseTimestamp(s.get("startTime"), Instant.MIN);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   148
        Instant endtime = MBeanUtils.parseTimestamp(s.get("endTime"), Instant.MAX);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   149
        int blockSize = MBeanUtils.parseBlockSize(s.get("blockSize"), StreamManager.DEFAULT_BLOCK_SIZE);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   150
        InputStream is = getExistingRecording(id).getStream(starttime, endtime);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   151
        if (is == null) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   152
            throw new IOException("No recording data available");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   153
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   154
        return streamHandler.create(is, blockSize).getId();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   155
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   156
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   157
    @Override
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   158
    public void closeStream(long streamIdentifier) throws IOException {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   159
        MBeanUtils.checkControl();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   160
        streamHandler.getStream(streamIdentifier).close();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   161
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   162
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   163
    @Override
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   164
    public byte[] readStream(long streamIdentifier) throws IOException {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   165
        MBeanUtils.checkMonitor();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   166
        return streamHandler.getStream(streamIdentifier).read();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   167
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   168
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   169
    @Override
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   170
    public List<RecordingInfo> getRecordings() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   171
        MBeanUtils.checkMonitor();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   172
        if (!FlightRecorder.isInitialized()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   173
            return Collections.emptyList();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   174
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   175
        return MBeanUtils.transformList(getRecorder().getRecordings(), RecordingInfo::new);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   176
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   177
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   178
    @Override
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   179
    public List<ConfigurationInfo> getConfigurations() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   180
        MBeanUtils.checkMonitor();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   181
        return MBeanUtils.transformList(Configuration.getConfigurations(), ConfigurationInfo::new);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   182
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   183
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   184
    @Override
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   185
    public List<EventTypeInfo> getEventTypes() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   186
        MBeanUtils.checkMonitor();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   187
        List<EventType> eventTypes = AccessController.doPrivileged(new PrivilegedAction<List<EventType>>() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   188
            @Override
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   189
            public List<EventType> run() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   190
                return ManagementSupport.getEventTypes();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   191
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   192
        }, null, new FlightRecorderPermission("accessFlightRecorder"));
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   193
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   194
        return MBeanUtils.transformList(eventTypes, EventTypeInfo::new);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   195
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   196
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   197
    @Override
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   198
    public Map<String, String> getRecordingSettings(long recording) throws IllegalArgumentException {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   199
        MBeanUtils.checkMonitor();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   200
        return getExistingRecording(recording).getSettings();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   201
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   202
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   203
    @Override
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   204
    public void setRecordingSettings(long recording, Map<String, String> values) throws IllegalArgumentException {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   205
        Objects.requireNonNull(values);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   206
        MBeanUtils.checkControl();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   207
        getExistingRecording(recording).setSettings(values);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   208
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   209
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   210
    @Override
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   211
    public long newRecording() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   212
        MBeanUtils.checkControl();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   213
        getRecorder(); // ensure notification listener is setup
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   214
        return AccessController.doPrivileged(new PrivilegedAction<Recording>() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   215
            @Override
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   216
            public Recording run() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   217
                return new Recording();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   218
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   219
        }, null, new FlightRecorderPermission("accessFlightRecorder")).getId();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   220
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   221
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   222
    @Override
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   223
    public long takeSnapshot() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   224
        MBeanUtils.checkControl();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   225
        return getRecorder().takeSnapshot().getId();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   226
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   227
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   228
    @Override
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   229
    public void setConfiguration(long recording, String configuration) throws IllegalArgumentException {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   230
        Objects.requireNonNull(configuration);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   231
        MBeanUtils.checkControl();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   232
        try {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   233
            Configuration c = Configuration.create(new StringReader(configuration));
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   234
            getExistingRecording(recording).setSettings(c.getSettings());
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   235
        } catch (IOException | ParseException e) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   236
            throw new IllegalArgumentException("Could not parse configuration", e);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   237
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   238
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   239
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   240
    @Override
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   241
    public void setPredefinedConfiguration(long recording, String configurationName) throws IllegalArgumentException {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   242
        Objects.requireNonNull(configurationName);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   243
        MBeanUtils.checkControl();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   244
        Recording r = getExistingRecording(recording);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   245
        for (Configuration c : Configuration.getConfigurations()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   246
            if (c.getName().equals(configurationName)) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   247
                r.setSettings(c.getSettings());
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   248
                return;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   249
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   250
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   251
        throw new IllegalArgumentException("Could not find configuration with name " + configurationName);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   252
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   253
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   254
    @Override
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   255
    public void copyTo(long recording, String path) throws IOException {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   256
        Objects.requireNonNull(path);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   257
        MBeanUtils.checkControl();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   258
        getExistingRecording(recording).dump(Paths.get(path));
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   259
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   260
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   261
    @Override
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   262
    public void setRecordingOptions(long recording, Map<String, String> options) throws IllegalArgumentException {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   263
        Objects.requireNonNull(options);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   264
        MBeanUtils.checkControl();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   265
        // Make local copy to prevent concurrent modification
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   266
        Map<String, String> ops = new HashMap<String, String>(options);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   267
        for (Map.Entry<String, String> entry : ops.entrySet()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   268
            Object key = entry.getKey();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   269
            Object value = entry.getValue();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   270
            if (!(key instanceof String)) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   271
                throw new IllegalArgumentException("Option key must not be null, or other type than " + String.class);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   272
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   273
            if (!OPTIONS.contains(key)) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   274
                throw new IllegalArgumentException("Unknown recording option: " + key + ". Valid options are " + OPTIONS + ".");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   275
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   276
            if (value != null && !(value instanceof String)) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   277
                throw new IllegalArgumentException("Incorrect value for option " + key + ". Values must be of type " + String.class + " .");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   278
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   279
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   280
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   281
        Recording r = getExistingRecording(recording);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   282
        validateOption(ops, OPTION_DUMP_ON_EXIT, MBeanUtils::booleanValue);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   283
        validateOption(ops, OPTION_DISK, MBeanUtils::booleanValue);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   284
        validateOption(ops, OPTION_NAME, Function.identity());
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   285
        validateOption(ops, OPTION_MAX_AGE, MBeanUtils::duration);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   286
        validateOption(ops, OPTION_MAX_SIZE, MBeanUtils::size);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   287
        validateOption(ops, OPTION_DURATION, MBeanUtils::duration);
58480
8ca46e186a63 8225694: Destination option missing in FlightRecorderMXBeanImpl
cito
parents: 50113
diff changeset
   288
        validateOption(ops, OPTION_DESTINATION, x -> MBeanUtils.destination(r, x));
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   289
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   290
        // All OK, now set them.atomically
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   291
        setOption(ops, OPTION_DUMP_ON_EXIT, "false", MBeanUtils::booleanValue, x -> r.setDumpOnExit(x));
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   292
        setOption(ops, OPTION_DISK, "true", MBeanUtils::booleanValue, x -> r.setToDisk(x));
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   293
        setOption(ops, OPTION_NAME, String.valueOf(r.getId()), Function.identity(), x -> r.setName(x));
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   294
        setOption(ops, OPTION_MAX_AGE, null, MBeanUtils::duration, x -> r.setMaxAge(x));
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   295
        setOption(ops, OPTION_MAX_SIZE, "0", MBeanUtils::size, x -> r.setMaxSize(x));
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   296
        setOption(ops, OPTION_DURATION, null, MBeanUtils::duration, x -> r.setDuration(x));
58480
8ca46e186a63 8225694: Destination option missing in FlightRecorderMXBeanImpl
cito
parents: 50113
diff changeset
   297
        setOption(ops, OPTION_DESTINATION, null, x -> MBeanUtils.destination(r, x), x -> setOptionDestination(r, x));
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   298
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   299
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   300
    @Override
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   301
    public Map<String, String> getRecordingOptions(long recording) throws IllegalArgumentException {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   302
        MBeanUtils.checkMonitor();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   303
        Recording r = getExistingRecording(recording);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   304
        Map<String, String> options = new HashMap<>(10);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   305
        options.put(OPTION_DUMP_ON_EXIT, String.valueOf(r.getDumpOnExit()));
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   306
        options.put(OPTION_DISK, String.valueOf(r.isToDisk()));
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   307
        options.put(OPTION_NAME, String.valueOf(r.getName()));
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   308
        options.put(OPTION_MAX_AGE, ManagementSupport.formatTimespan(r.getMaxAge(), " "));
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   309
        Long maxSize = r.getMaxSize();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   310
        options.put(OPTION_MAX_SIZE, String.valueOf(maxSize == null ? "0" : maxSize.toString()));
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   311
        options.put(OPTION_DURATION, ManagementSupport.formatTimespan(r.getDuration(), " "));
58480
8ca46e186a63 8225694: Destination option missing in FlightRecorderMXBeanImpl
cito
parents: 50113
diff changeset
   312
        options.put(OPTION_DESTINATION, ManagementSupport.getDestinationOriginalText(r));
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   313
        return options;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   314
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   315
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   316
    @Override
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   317
    public long cloneRecording(long id, boolean stop) throws IllegalStateException, SecurityException {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   318
        MBeanUtils.checkControl();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   319
        return getRecording(id).copy(stop).getId();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   320
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   321
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   322
    @Override
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   323
    public ObjectName getObjectName() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   324
        return MBeanUtils.createObjectName();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   325
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   326
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   327
    private Recording getExistingRecording(long id) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   328
        if (FlightRecorder.isInitialized()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   329
            Recording recording = getRecording(id);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   330
            if (recording != null) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   331
                return recording;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   332
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   333
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   334
        throw new IllegalArgumentException("No recording available with id " + id);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   335
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   336
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   337
    private Recording getRecording(long id) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   338
        List<Recording> recs = getRecorder().getRecordings();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   339
        return recs.stream().filter(r -> r.getId() == id).findFirst().orElse(null);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   340
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   341
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   342
    private static <T, U> void setOption(Map<String, String> options, String name, String defaultValue, Function<String, U> converter, Consumer<U> setter) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   343
        if (!options.containsKey(name)) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   344
            return;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   345
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   346
        String v = options.get(name);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   347
        if (v == null) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   348
            v = defaultValue;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   349
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   350
        try {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   351
            setter.accept(converter.apply(v));
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   352
        } catch (IllegalArgumentException iae) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   353
            throw new IllegalArgumentException("Not a valid value for option '" + name + "'. " + iae.getMessage());
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   354
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   355
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   356
58480
8ca46e186a63 8225694: Destination option missing in FlightRecorderMXBeanImpl
cito
parents: 50113
diff changeset
   357
    private static void setOptionDestination(Recording recording, String destination){
8ca46e186a63 8225694: Destination option missing in FlightRecorderMXBeanImpl
cito
parents: 50113
diff changeset
   358
        try {
8ca46e186a63 8225694: Destination option missing in FlightRecorderMXBeanImpl
cito
parents: 50113
diff changeset
   359
            Path pathDestination = null;
8ca46e186a63 8225694: Destination option missing in FlightRecorderMXBeanImpl
cito
parents: 50113
diff changeset
   360
            if(destination != null){
8ca46e186a63 8225694: Destination option missing in FlightRecorderMXBeanImpl
cito
parents: 50113
diff changeset
   361
                pathDestination = Paths.get(destination);
8ca46e186a63 8225694: Destination option missing in FlightRecorderMXBeanImpl
cito
parents: 50113
diff changeset
   362
            }
8ca46e186a63 8225694: Destination option missing in FlightRecorderMXBeanImpl
cito
parents: 50113
diff changeset
   363
            recording.setDestination(pathDestination);
8ca46e186a63 8225694: Destination option missing in FlightRecorderMXBeanImpl
cito
parents: 50113
diff changeset
   364
        } catch (IOException e) {
8ca46e186a63 8225694: Destination option missing in FlightRecorderMXBeanImpl
cito
parents: 50113
diff changeset
   365
            IllegalArgumentException iae = new IllegalArgumentException("Not a valid destination " + destination);
8ca46e186a63 8225694: Destination option missing in FlightRecorderMXBeanImpl
cito
parents: 50113
diff changeset
   366
            iae.addSuppressed(e);
8ca46e186a63 8225694: Destination option missing in FlightRecorderMXBeanImpl
cito
parents: 50113
diff changeset
   367
            throw iae;
8ca46e186a63 8225694: Destination option missing in FlightRecorderMXBeanImpl
cito
parents: 50113
diff changeset
   368
        }
8ca46e186a63 8225694: Destination option missing in FlightRecorderMXBeanImpl
cito
parents: 50113
diff changeset
   369
    }
8ca46e186a63 8225694: Destination option missing in FlightRecorderMXBeanImpl
cito
parents: 50113
diff changeset
   370
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   371
    private static <T, U> void validateOption(Map<String, String> options, String name, Function<String, U> validator) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   372
        try {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   373
            String v = options.get(name);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   374
            if (v == null) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   375
                return; // OK, will set default
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   376
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   377
            validator.apply(v);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   378
        } catch (IllegalArgumentException iae) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   379
            throw new IllegalArgumentException("Not a valid value for option '" + name + "'. " + iae.getMessage());
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   380
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   381
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   382
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   383
    private FlightRecorder getRecorder() throws SecurityException {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   384
        // Synchronize on some private object that is always available
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   385
        synchronized (streamHandler) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   386
            if (recorder == null) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   387
                recorder = AccessController.doPrivileged(new PrivilegedAction<FlightRecorder>() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   388
                    @Override
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   389
                    public FlightRecorder run() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   390
                        return FlightRecorder.getFlightRecorder();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   391
                    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   392
                }, null, new FlightRecorderPermission("accessFlightRecorder"));
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   393
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   394
            return recorder;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   395
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   396
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   397
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   398
    private static MBeanNotificationInfo[] createNotificationInfo() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   399
        String[] types = new String[] { AttributeChangeNotification.ATTRIBUTE_CHANGE };
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   400
        String name = AttributeChangeNotification.class.getName();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   401
        String description = "Notifies if the RecordingState has changed for one of the recordings, for example if a recording starts or stops";
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   402
        MBeanNotificationInfo info = new MBeanNotificationInfo(types, name, description);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   403
        return new MBeanNotificationInfo[] { info };
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   404
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   405
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   406
    @Override
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   407
    public void addNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   408
        MXBeanListener mxbeanListener = new MXBeanListener(listener, filter, handback);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   409
        listeners.add(mxbeanListener);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   410
        AccessController.doPrivileged(new PrivilegedAction<Void>() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   411
            @Override
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   412
            public Void run(){
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   413
                FlightRecorder.addListener(mxbeanListener);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   414
                return null;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   415
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   416
        }, null, new FlightRecorderPermission("accessFlightRecorder"));
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   417
        super.addNotificationListener(listener, filter, handback);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   418
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   419
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   420
    @Override
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   421
    public void removeNotificationListener(NotificationListener listener) throws ListenerNotFoundException {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   422
        removeListeners( x -> listener == x.listener);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   423
        super.removeNotificationListener(listener);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   424
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   425
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   426
    @Override
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   427
    public void removeNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) throws ListenerNotFoundException {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   428
        removeListeners( x -> listener == x.listener && filter == x.filter && handback == x.handback);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   429
        super.removeNotificationListener(listener, filter, handback);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   430
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   431
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   432
    private void removeListeners(Predicate<MXBeanListener> p) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   433
        List<MXBeanListener> toBeRemoved = new ArrayList<>(listeners.size());
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   434
        for (MXBeanListener l : listeners) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   435
            if (p.test(l)) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   436
                toBeRemoved.add(l);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   437
                FlightRecorder.removeListener(l);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   438
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   439
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   440
        listeners.removeAll(toBeRemoved);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   441
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   442
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   443
    private Notification createNotication(Recording recording) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   444
        try {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   445
            Long id = recording.getId();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   446
            Object oldValue = changes.get(recording.getId());
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   447
            Object newValue = getAttribute(ATTRIBUTE_RECORDINGS);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   448
            if (recording.getState() != RecordingState.CLOSED) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   449
                changes.put(id, newValue);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   450
            } else {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   451
                changes.remove(id);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   452
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   453
            return new AttributeChangeNotification(getObjectName(), sequenceNumber.incrementAndGet(), System.currentTimeMillis(), "Recording " + recording.getName() + " is "
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   454
                    + recording.getState(), ATTRIBUTE_RECORDINGS, newValue.getClass().getName(), oldValue, newValue);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   455
        } catch (AttributeNotFoundException | MBeanException | ReflectionException e) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   456
            throw new RuntimeException("Could not create notifcation for FlightRecorderMXBean. " + e.getMessage(), e);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   457
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   458
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   459
}