/*
 * Copyright 2004-2019 H2 Group. Multiple-Licensed under the MPL 2.0,
 * and the EPL 1.0 (http://h2database.com/html/license.html).
 * Initial Developer: H2 Group
 */
package org.h2.jmx;

import java.lang.management.ManagementFactory;

import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.TreeMap;
import javax.management.JMException;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import org.h2.command.Command;
import org.h2.engine.ConnectionInfo;
import org.h2.engine.Constants;
import org.h2.engine.Database;
import org.h2.engine.Session;
import org.h2.store.PageStore;
import org.h2.table.Table;

The MBean implementation.
Author:Eric Dong, Thomas Mueller
/** * The MBean implementation. * * @author Eric Dong * @author Thomas Mueller */
public class DatabaseInfo implements DatabaseInfoMBean { private static final Map<String, ObjectName> MBEANS = new HashMap<>();
Database.
/** Database. */
private final Database database; private DatabaseInfo(Database database) { if (database == null) { throw new IllegalArgumentException("Argument 'database' must not be null"); } this.database = database; }
Returns a JMX new ObjectName instance.
Params:
  • name – name of the MBean
  • path – the path
Throws:
Returns:a new ObjectName instance
/** * Returns a JMX new ObjectName instance. * * @param name name of the MBean * @param path the path * @return a new ObjectName instance * @throws JMException if the ObjectName could not be created */
private static ObjectName getObjectName(String name, String path) throws JMException { name = name.replace(':', '_'); path = path.replace(':', '_'); Hashtable<String, String> map = new Hashtable<>(); map.put("name", name); map.put("path", path); return new ObjectName("org.h2", map); }
Registers an MBean for the database.
Params:
  • connectionInfo – connection info
  • database – database
/** * Registers an MBean for the database. * * @param connectionInfo connection info * @param database database */
public static void registerMBean(ConnectionInfo connectionInfo, Database database) throws JMException { String path = connectionInfo.getName(); if (!MBEANS.containsKey(path)) { MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer(); String name = database.getShortName(); ObjectName mbeanObjectName = getObjectName(name, path); MBEANS.put(path, mbeanObjectName); DatabaseInfo info = new DatabaseInfo(database); Object mbean = new DocumentedMBean(info, DatabaseInfoMBean.class); mbeanServer.registerMBean(mbean, mbeanObjectName); } }
Unregisters the MBean for the database if one is registered.
Params:
  • name – database name
/** * Unregisters the MBean for the database if one is registered. * * @param name database name */
public static void unregisterMBean(String name) throws Exception { ObjectName mbeanObjectName = MBEANS.remove(name); if (mbeanObjectName != null) { MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer(); mbeanServer.unregisterMBean(mbeanObjectName); } } @Override public boolean isExclusive() { return database.getExclusiveSession() != null; } @Override public boolean isReadOnly() { return database.isReadOnly(); } @Override public String getMode() { return database.getMode().getName(); } @Override public boolean isMultiThreaded() { return database.isMultiThreaded(); } @Deprecated @Override public boolean isMvcc() { return database.isMVStore(); } @Override public int getLogMode() { return database.getLogMode(); } @Override public void setLogMode(int value) { database.setLogMode(value); } @Override public int getTraceLevel() { return database.getTraceSystem().getLevelFile(); } @Override public void setTraceLevel(int level) { database.getTraceSystem().setLevelFile(level); } @Override public long getFileWriteCountTotal() { if (!database.isPersistent()) { return 0; } PageStore p = database.getPageStore(); if (p != null) { return p.getWriteCountTotal(); } // TODO remove this method when removing the page store // (the MVStore doesn't support it) return 0; } @Override public long getFileWriteCount() { if (!database.isPersistent()) { return 0; } PageStore p = database.getPageStore(); if (p != null) { return p.getWriteCount(); } return database.getStore().getMvStore().getFileStore().getReadCount(); } @Override public long getFileReadCount() { if (!database.isPersistent()) { return 0; } PageStore p = database.getPageStore(); if (p != null) { return p.getReadCount(); } return database.getStore().getMvStore().getFileStore().getReadCount(); } @Override public long getFileSize() { if (!database.isPersistent()) { return 0; } PageStore p = database.getPageStore(); if (p != null) { return p.getPageCount() * p.getPageSize() / 1024; } return database.getStore().getMvStore().getFileStore().size(); } @Override public int getCacheSizeMax() { if (!database.isPersistent()) { return 0; } PageStore p = database.getPageStore(); if (p != null) { return p.getCache().getMaxMemory(); } return database.getStore().getMvStore().getCacheSize() * 1024; } @Override public void setCacheSizeMax(int kb) { if (database.isPersistent()) { database.setCacheSize(kb); } } @Override public int getCacheSize() { if (!database.isPersistent()) { return 0; } PageStore p = database.getPageStore(); if (p != null) { return p.getCache().getMemory(); } return database.getStore().getMvStore().getCacheSizeUsed() * 1024; } @Override public String getVersion() { return Constants.getFullVersion(); } @Override public String listSettings() { StringBuilder buff = new StringBuilder(); for (Map.Entry<String, String> e : new TreeMap<>( database.getSettings().getSettings()).entrySet()) { buff.append(e.getKey()).append(" = ").append(e.getValue()).append('\n'); } return buff.toString(); } @Override public String listSessions() { StringBuilder buff = new StringBuilder(); for (Session session : database.getSessions(false)) { buff.append("session id: ").append(session.getId()); buff.append(" user: "). append(session.getUser().getName()). append('\n'); buff.append("connected: "). append(new Timestamp(session.getSessionStart())). append('\n'); Command command = session.getCurrentCommand(); if (command != null) { buff.append("statement: ") .append(command) .append('\n') .append("started: ") .append(session.getCurrentCommandStart().getString()) .append('\n'); } Table[] t = session.getLocks(); if (t.length > 0) { for (Table table : session.getLocks()) { if (table.isLockedExclusivelyBy(session)) { buff.append("write lock on "); } else { buff.append("read lock on "); } buff.append(table.getSchema().getName()). append('.').append(table.getName()). append('\n'); } } buff.append('\n'); } return buff.toString(); } }