Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.hdds.conf;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.concurrent.TimeUnit;

/**
* Mark field to be configurable from ozone-site.xml.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Config {

/**
* Configuration fragment relative to the prefix defined with @ConfigGroup.
*/
String key();

/**
* Type of configuration. Use AUTO to decide it based on the java type.
*/
ConfigType type() default ConfigType.AUTO;

/**
* If type == TIME the unit should be defined with this attribute.
*/
TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.hdds.conf;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Mark pojo which holds configuration variables.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ConfigGroup {
String prefix();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.hdds.conf;

/**
* Possible type of injected configuration.
* <p>
* AUTO means that the exact type will be identified based on the java type of
* the configuration field.
*/
public enum ConfigType {
AUTO,
STRING,
BOOLEAN,
INT,
LONG,
TIME,
SIZE
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.hdds.conf;

/**
* Exeception to throw in case of a configuration problem.
*/
public class ConfigurationException extends RuntimeException {
public ConfigurationException() {
}

public ConfigurationException(String message) {
super(message);
}

public ConfigurationException(String message, Throwable cause) {
super(message, cause);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
Expand Down Expand Up @@ -61,6 +63,108 @@ public List<Property> readPropertyFromXml(URL url) throws JAXBException {
return config.getProperties();
}

/**
* Create a Configuration object and inject the required configuration values.
*
* @param configurationClass The class where the fields are annotated with
* the configuration.
* @return Initiated java object where the config fields are injected.
*/
public <T> T getObject(Class<T> configurationClass) {

T configuration;

try {
configuration = configurationClass.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new ConfigurationException(
"Configuration class can't be created: " + configurationClass, e);
}
ConfigGroup configGroup =
configurationClass.getAnnotation(ConfigGroup.class);
String prefix = configGroup.prefix();

for (Method setterMethod : configurationClass.getMethods()) {
if (setterMethod.isAnnotationPresent(Config.class)) {

String methodLocation =
configurationClass + "." + setterMethod.getName();

Config configAnnotation = setterMethod.getAnnotation(Config.class);

String key = prefix + "." + configAnnotation.key();

Class<?>[] parameterTypes = setterMethod.getParameterTypes();
if (parameterTypes.length != 1) {
throw new ConfigurationException(
"@Config annotation should be used on simple setter: "
+ methodLocation);
}

ConfigType type = configAnnotation.type();

if (type == ConfigType.AUTO) {
type = detectConfigType(parameterTypes[0], methodLocation);
}

//Note: default value is handled by ozone-default.xml. Here we can
//use any default.
try {
switch (type) {
case STRING:
setterMethod.invoke(configuration, get(key));
break;
case INT:
setterMethod.invoke(configuration,
getInt(key, 0));
break;
case BOOLEAN:
setterMethod.invoke(configuration,
getBoolean(key, false));
break;
case LONG:
setterMethod.invoke(configuration,
getLong(key, 0));
break;
case TIME:
setterMethod.invoke(configuration,
getTimeDuration(key, 0, configAnnotation.timeUnit()));
break;
default:
throw new ConfigurationException(
"Unsupported ConfigType " + type + " on " + methodLocation);
}
} catch (InvocationTargetException | IllegalAccessException e) {
throw new ConfigurationException(
"Can't inject configuration to " + methodLocation, e);
}

}
}
return configuration;

}

private ConfigType detectConfigType(Class<?> parameterType,
String methodLocation) {
ConfigType type;
if (parameterType == String.class) {
type = ConfigType.STRING;
} else if (parameterType == Integer.class || parameterType == int.class) {
type = ConfigType.INT;
} else if (parameterType == Long.class || parameterType == long.class) {
type = ConfigType.LONG;
} else if (parameterType == Boolean.class
|| parameterType == boolean.class) {
type = ConfigType.BOOLEAN;
} else {
throw new ConfigurationException(
"Unsupported configuration type " + parameterType + " in "
+ methodLocation);
}
return type;
}

/**
* Class to marshall/un-marshall configuration from xml files.
*/
Expand Down Expand Up @@ -145,7 +249,7 @@ public String toString() {
}

@Override
public int hashCode(){
public int hashCode() {
return this.getName().hashCode();
}

Expand All @@ -169,6 +273,7 @@ public static void activate() {
* does not override values of properties
* if there is no tag present in the configs of
* newly added resources.
*
* @param tag
* @return Properties that belong to the tag
*/
Expand All @@ -181,7 +286,7 @@ public Properties getAllPropertiesByTag(String tag) {
Properties props = new Properties();
Enumeration properties = propertiesByTag.propertyNames();
while (properties.hasMoreElements()) {
Object propertyName = properties.nextElement();
Object propertyName = properties.nextElement();
// get the current value of the property
Object value = updatedProps.getProperty(propertyName.toString());
if (value != null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.hdds.conf;

import java.util.concurrent.TimeUnit;

/**
* Example configuration to test the configuration injection.
*/
@ConfigGroup(prefix = "ozone.scm.client")
public class SimpleConfiguration {

private String clientAddress;

private String bindHost;

private boolean enabled;

private int port = 1234;

private long waitTime = 1;

@Config(key = "address")
public void setClientAddress(String clientAddress) {
this.clientAddress = clientAddress;
}

@Config(key = "bind.host")
public void setBindHost(String bindHost) {
this.bindHost = bindHost;
}

@Config(key = "enabled")
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}

@Config(key = "port")
public void setPort(int port) {
this.port = port;
}

@Config(key = "wait", type = ConfigType.TIME, timeUnit =
TimeUnit.SECONDS)
public void setWaitTime(long waitTime) {
this.waitTime = waitTime;
}

public String getClientAddress() {
return clientAddress;
}

public String getBindHost() {
return bindHost;
}

public boolean isEnabled() {
return enabled;
}

public int getPort() {
return port;
}

public long getWaitTime() {
return waitTime;
}
}
Loading