001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019 package org.apache.hadoop.conf; 020 021 import org.apache.commons.logging.*; 022 023 import java.util.Collection; 024 025 /** 026 * Utility base class for implementing the Reconfigurable interface. 027 * 028 * Subclasses should override reconfigurePropertyImpl to change individual 029 * properties and getReconfigurableProperties to get all properties that 030 * can be changed at run time. 031 */ 032 public abstract class ReconfigurableBase 033 extends Configured implements Reconfigurable { 034 035 private static final Log LOG = 036 LogFactory.getLog(ReconfigurableBase.class); 037 038 /** 039 * Construct a ReconfigurableBase. 040 */ 041 public ReconfigurableBase() { 042 super(new Configuration()); 043 } 044 045 /** 046 * Construct a ReconfigurableBase with the {@link Configuration} 047 * conf. 048 */ 049 public ReconfigurableBase(Configuration conf) { 050 super((conf == null) ? new Configuration() : conf); 051 } 052 053 /** 054 * {@inheritDoc} 055 * 056 * This method makes the change to this objects {@link Configuration} 057 * and calls reconfigurePropertyImpl to update internal data structures. 058 * This method cannot be overridden, subclasses should instead override 059 * reconfigureProperty. 060 */ 061 @Override 062 public final String reconfigureProperty(String property, String newVal) 063 throws ReconfigurationException { 064 if (isPropertyReconfigurable(property)) { 065 LOG.info("changing property " + property + " to " + newVal); 066 String oldVal; 067 synchronized(getConf()) { 068 oldVal = getConf().get(property); 069 reconfigurePropertyImpl(property, newVal); 070 if (newVal != null) { 071 getConf().set(property, newVal); 072 } else { 073 getConf().unset(property); 074 } 075 } 076 return oldVal; 077 } else { 078 throw new ReconfigurationException(property, newVal, 079 getConf().get(property)); 080 } 081 } 082 083 /** 084 * {@inheritDoc} 085 * 086 * Subclasses must override this. 087 */ 088 @Override 089 public abstract Collection<String> getReconfigurableProperties(); 090 091 092 /** 093 * {@inheritDoc} 094 * 095 * Subclasses may wish to override this with a more efficient implementation. 096 */ 097 @Override 098 public boolean isPropertyReconfigurable(String property) { 099 return getReconfigurableProperties().contains(property); 100 } 101 102 /** 103 * Change a configuration property. 104 * 105 * Subclasses must override this. This method applies the change to 106 * all internal data structures derived from the configuration property 107 * that is being changed. If this object owns other Reconfigurable objects 108 * reconfigureProperty should be called recursively to make sure that 109 * to make sure that the configuration of these objects is updated. 110 */ 111 protected abstract void reconfigurePropertyImpl(String property, String newVal) 112 throws ReconfigurationException; 113 114 }