0N/A/*
2362N/A * Copyright (c) 2004, 2008, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage sun.jvmstat.perfdata.monitor.protocol.local;
0N/A
0N/Aimport sun.jvmstat.monitor.*;
0N/Aimport sun.jvmstat.monitor.event.*;
0N/Aimport sun.jvmstat.perfdata.monitor.*;
0N/Aimport java.util.*;
0N/Aimport java.net.*;
0N/A
0N/A/**
0N/A * Concrete implementation of the MonitoredHost interface for the
0N/A * <em>local</em> protocol of the HotSpot PerfData monitoring implementation.
0N/A *
0N/A * @author Brian Doherty
0N/A * @since 1.5
0N/A */
0N/Apublic class MonitoredHostProvider extends MonitoredHost {
0N/A private static final int DEFAULT_POLLING_INTERVAL = 1000;
0N/A
0N/A private ArrayList<HostListener> listeners;
0N/A private NotifierTask task;
0N/A private HashSet<Integer> activeVms;
0N/A private LocalVmManager vmManager;
0N/A
0N/A /**
0N/A * Create a MonitoredHostProvider instance using the given HostIdentifier.
0N/A *
0N/A * @param hostId the host identifier for this MonitoredHost
0N/A */
0N/A public MonitoredHostProvider(HostIdentifier hostId) {
0N/A this.hostId = hostId;
0N/A this.listeners = new ArrayList<HostListener>();
0N/A this.interval = DEFAULT_POLLING_INTERVAL;
0N/A this.activeVms = new HashSet<Integer>();
0N/A this.vmManager = new LocalVmManager();
0N/A }
0N/A
0N/A /**
0N/A * {@inheritDoc}
0N/A */
0N/A public MonitoredVm getMonitoredVm(VmIdentifier vmid)
0N/A throws MonitorException {
0N/A return getMonitoredVm(vmid, DEFAULT_POLLING_INTERVAL);
0N/A }
0N/A
0N/A /**
0N/A * {@inheritDoc}
0N/A */
0N/A public MonitoredVm getMonitoredVm(VmIdentifier vmid, int interval)
0N/A throws MonitorException {
0N/A try {
0N/A VmIdentifier nvmid = hostId.resolve(vmid);
0N/A return new LocalMonitoredVm(nvmid, interval);
0N/A } catch (URISyntaxException e) {
0N/A /*
0N/A * the VmIdentifier is expected to be a valid and it should
0N/A * resolve reasonably against the host identifier. A
0N/A * URISyntaxException here is most likely a programming error.
0N/A */
0N/A throw new IllegalArgumentException("Malformed URI: "
0N/A + vmid.toString(), e);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * {@inheritDoc}
0N/A */
0N/A public void detach(MonitoredVm vm) {
0N/A vm.detach();
0N/A }
0N/A
0N/A /**
0N/A * {@inheritDoc}
0N/A */
0N/A public void addHostListener(HostListener listener) {
0N/A synchronized(listeners) {
0N/A listeners.add(listener);
0N/A if (task == null) {
0N/A task = new NotifierTask();
0N/A LocalEventTimer timer = LocalEventTimer.getInstance();
0N/A timer.schedule(task, interval, interval);
0N/A }
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * {@inheritDoc}
0N/A */
0N/A public void removeHostListener(HostListener listener) {
0N/A synchronized(listeners) {
0N/A listeners.remove(listener);
0N/A if (listeners.isEmpty() && (task != null)) {
0N/A task.cancel();
0N/A task = null;
0N/A }
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * {@inheritDoc}
0N/A */
0N/A public void setInterval(int newInterval) {
0N/A synchronized(listeners) {
0N/A if (newInterval == interval) {
0N/A return;
0N/A }
0N/A
0N/A int oldInterval = interval;
440N/A super.setInterval(newInterval);
0N/A
0N/A if (task != null) {
0N/A task.cancel();
0N/A NotifierTask oldTask = task;
0N/A task = new NotifierTask();
0N/A LocalEventTimer timer = LocalEventTimer.getInstance();
0N/A CountedTimerTaskUtils.reschedule(timer, oldTask, task,
0N/A oldInterval, newInterval);
0N/A }
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * {@inheritDoc}
0N/A */
0N/A public Set<Integer> activeVms() {
0N/A return vmManager.activeVms();
0N/A }
0N/A
0N/A /**
0N/A * Fire VmEvent events.
0N/A *
0N/A * @param active a set of Integer objects containing the vmid of
0N/A * the active Vms
0N/A * @param started a set of Integer objects containing the vmid of
0N/A * new Vms started since last interval.
0N/A * @param terminated a set of Integer objects containing the vmid of
0N/A * terminated Vms since last interval.
0N/A */
0N/A private void fireVmStatusChangedEvents(Set active, Set started,
0N/A Set terminated) {
0N/A ArrayList registered = null;
0N/A VmStatusChangeEvent ev = null;
0N/A
0N/A synchronized(listeners) {
0N/A registered = (ArrayList)listeners.clone();
0N/A }
0N/A
0N/A for (Iterator i = registered.iterator(); i.hasNext(); /* empty */) {
0N/A HostListener l = (HostListener)i.next();
0N/A if (ev == null) {
0N/A ev = new VmStatusChangeEvent(this, active, started, terminated);
0N/A }
0N/A l.vmStatusChanged(ev);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Class to poll the local system and generate event notifications.
0N/A */
0N/A private class NotifierTask extends CountedTimerTask {
0N/A public void run() {
0N/A super.run();
0N/A
0N/A // save the last set of active JVMs
0N/A Set lastActiveVms = activeVms;
0N/A
0N/A // get the current set of active JVMs
0N/A activeVms = (HashSet<Integer>)vmManager.activeVms();
0N/A
0N/A if (activeVms.isEmpty()) {
0N/A return;
0N/A }
0N/A Set<Integer> startedVms = new HashSet<Integer>();
0N/A Set<Object> terminatedVms = new HashSet<Object>();
0N/A
0N/A for (Iterator i = activeVms.iterator(); i.hasNext(); /* empty */) {
0N/A Integer vmid = (Integer)i.next();
0N/A if (!lastActiveVms.contains(vmid)) {
0N/A // a new file has been detected, add to set
0N/A startedVms.add(vmid);
0N/A }
0N/A }
0N/A
0N/A for (Iterator i = lastActiveVms.iterator(); i.hasNext();
0N/A /* empty */) {
0N/A Object o = i.next();
0N/A if (!activeVms.contains(o)) {
0N/A // JVM has terminated, remove it from the active list
0N/A terminatedVms.add(o);
0N/A }
0N/A }
0N/A
0N/A if (!startedVms.isEmpty() || !terminatedVms.isEmpty()) {
0N/A fireVmStatusChangedEvents(activeVms, startedVms,
0N/A terminatedVms);
0N/A }
0N/A }
0N/A }
0N/A}