/** * Copyright (c) 2002-2011 "Neo Technology," * Network Engine for Objects in Lund AB [http://neotechnology.com] * * This file is part of Neo4j. * * Neo4j is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.neo4j.management.impl; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.management.AttributeList; import javax.management.AttributeNotFoundException; import javax.management.MBeanAttributeInfo; import javax.management.MBeanException; import javax.management.MBeanInfo; import javax.management.NotCompliantMBeanException; import javax.management.ReflectionException; import org.neo4j.helpers.Service; import org.neo4j.kernel.Config; import org.neo4j.kernel.KernelExtension.KernelData; @Service.Implementation( ManagementBeanProvider.class ) public final class ConfigurationBean extends ManagementBeanProvider { public static final String CONFIGURATION_MBEAN_NAME = "Configuration"; @Description( "Tell Neo4j to use memory mapped buffers for accessing the native storage layer" ) public static final String USE_MEMORY_MAPPED_BUFFERS = Config.USE_MEMORY_MAPPED_BUFFERS; @Description( "Print out the effective Neo4j configuration after startup" ) public static final String DUMP_CONFIGURATION = Config.DUMP_CONFIGURATION; @Description( "Make Neo4j keep the logical transaction logs for being able to backup the database" ) public static final String KEEP_LOGICAL_LOGS = Config.KEEP_LOGICAL_LOGS; @Description( "Enable a remote shell server which shell clients can log in to" ) public static final String ENABLE_REMOTE_SHELL = Config.ENABLE_REMOTE_SHELL; @Description( "<TODO: document this>" ) public static final String BACKUP_SLAVE = Config.BACKUP_SLAVE; @Description( "Only allow read operations from this Neo4j instance" ) public static final String READ_ONLY = Config.READ_ONLY; @Description( "Relative path for where the Neo4j storage directory is located" ) public static final String STORAGE_DIRECTORY = Config.STORAGE_DIRECTORY; @Description( "Use a quick approach for rebuilding the ID generators. " + "This give quicker recovery time, but will limit the ability to reuse the space of deleted entities." ) public static final String REBUILD_IDGENERATORS_FAST = Config.REBUILD_IDGENERATORS_FAST; @Description( "The size to allocate for memory mapping the node store" ) public static final String NODE_STORE_MMAP_SIZE = Config.NODE_STORE_MMAP_SIZE; @Description( "The size to allocate for memory mapping the array property store" ) public static final String ARRAY_PROPERTY_STORE_MMAP_SIZE = Config.ARRAY_PROPERTY_STORE_MMAP_SIZE; @Description( "The size to allocate for memory mapping the store for property key strings" ) public static final String PROPERTY_INDEX_KEY_STORE_MMAP_SIZE = Config.PROPERTY_INDEX_KEY_STORE_MMAP_SIZE; @Description( "The size to allocate for memory mapping the store for property key indexes" ) public static final String PROPERTY_INDEX_STORE_MMAP_SIZE = Config.PROPERTY_INDEX_STORE_MMAP_SIZE; @Description( "The size to allocate for memory mapping the property value store" ) public static final String PROPERTY_STORE_MMAP_SIZE = Config.PROPERTY_STORE_MMAP_SIZE; @Description( "The size to allocate for memory mapping the string property store" ) public static final String STRING_PROPERTY_STORE_MMAP_SIZE = Config.STRING_PROPERTY_STORE_MMAP_SIZE; @Description( "The size to allocate for memory mapping the relationship store" ) public static final String RELATIONSHIP_STORE_MMAP_SIZE = Config.RELATIONSHIP_STORE_MMAP_SIZE; @Description( "Relative path for where the Neo4j logical log is located" ) public static final String LOGICAL_LOG = Config.LOGICAL_LOG; @Description( "Relative path for where the Neo4j storage information file is located" ) public static final String NEO_STORE = Config.NEO_STORE; @Description( "The type of cache to use for nodes and relationships, one of [weak, soft, none]" ) public static final String CACHE_TYPE = Config.CACHE_TYPE; public ConfigurationBean() { super( CONFIGURATION_MBEAN_NAME ); } @Override protected Neo4jMBean createMBean( KernelData kernel ) throws NotCompliantMBeanException { return new ConfigurationImpl( this, kernel ); } @Description( "The configuration parameters used to configure Neo4j" ) private static class ConfigurationImpl extends Neo4jMBean { private static final Map<String, String> parameterDescriptions; static { final Map<String, String> descriptions = new HashMap<String, String>(); for ( final Field field : ConfigurationBean.class.getFields() ) { if ( Modifier.isStatic( field.getModifiers() ) && Modifier.isFinal( field.getModifiers() ) ) { final Description descr = field.getAnnotation( Description.class ); if ( descr == null || field.getType() != String.class ) continue; try { if ( !field.isAccessible() ) field.setAccessible( true ); descriptions.put( (String) field.get( null ), descr.value() ); } catch ( Exception e ) { continue; } } } parameterDescriptions = Collections.unmodifiableMap( descriptions ); } private final Map<Object, Object> config; protected ConfigurationImpl( ManagementBeanProvider provider, KernelData kernel ) throws NotCompliantMBeanException { super( provider, kernel ); this.config = kernel.getConfigParams(); } private static String describeConfigParameter( String param ) { String description = parameterDescriptions.get( param ); return description != null ? description : "Configuration attribute"; } private MBeanAttributeInfo[] keys() { List<MBeanAttributeInfo> keys = new ArrayList<MBeanAttributeInfo>(); for ( Map.Entry<Object, Object> entry : config.entrySet() ) { if ( entry.getKey() instanceof String ) { keys.add( new MBeanAttributeInfo( (String) entry.getKey(), String.class.getName(), describeConfigParameter( (String) entry.getKey() ), true, false, false ) ); } } return keys.toArray( new MBeanAttributeInfo[keys.size()] ); } @Override public Object getAttribute( String attribute ) throws AttributeNotFoundException, MBeanException, ReflectionException { return config.get( attribute ); } @Override public AttributeList getAttributes( String[] attributes ) { AttributeList result = new AttributeList( attributes.length ); for ( String attribute : attributes ) { try { result.add( getAttribute( attribute ) ); } catch ( Exception e ) { throw new RuntimeException( e ); } } return result; } @Override public MBeanInfo getMBeanInfo() { Description description = getClass().getAnnotation( Description.class ); return new MBeanInfo( getClass().getName(), description != null ? description.value() : "Neo4j configuration", keys(), null, null, null ); } } }