Commit 1143f69d by Dan Markwat

Updated ServiceInitializer to add ability to load different properties

files (e.g. for testing). Also added a unit test to ensure this functionality is working.
parent f8356cb5
...@@ -26,51 +26,109 @@ import org.slf4j.Logger; ...@@ -26,51 +26,109 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
* Initializer that uses at startup to bring up all the Metadata startup services. * Initializer that uses at startup to bring up all the Metadata startup
* services.
*/ */
public class ServiceInitializer { public class ServiceInitializer {
private static final Logger LOG = LoggerFactory.getLogger(ServiceInitializer.class); private static final Logger LOG = LoggerFactory
private final Services services = Services.get(); .getLogger(ServiceInitializer.class);
private final Services services = Services.get();
public void initialize() throws MetadataException { // default property file name/path
String[] serviceClassNames; private static final String DEFAULT_CONFIG_PATH = "application.properties";
try { // system property referenced by this class to extract user-overriden
PropertiesConfiguration configuration = // properties file
new PropertiesConfiguration("application.properties"); public static final String PROPERTIES_SYS_PROP = "metadata.properties";
serviceClassNames = configuration.getStringArray("application.services");
} catch (ConfigurationException e) {
throw new RuntimeException("unable to get server properties");
}
for (String serviceClassName : serviceClassNames) { // Path to the properties file (must be on the classpath for
serviceClassName = serviceClassName.trim(); // PropertiesConfiguration to work)
if (serviceClassName.isEmpty()) { private final String propertyPath;
continue;
}
Service service = ReflectionUtils.getInstanceByClassName(serviceClassName);
services.register(service);
LOG.info("Initializing service: {}", serviceClassName);
try {
service.start();
} catch (Throwable t) {
LOG.error("Failed to initialize service {}", serviceClassName, t);
throw new MetadataException(t);
}
LOG.info("Service initialized: {}", serviceClassName);
}
}
public void destroy() throws MetadataException { /**
for (Service service : services) { * Default constructor. Use the metadata.properties System property to
LOG.info("Destroying service: {}", service.getClass().getName()); * determine the property file name.
try { */
service.stop(); public ServiceInitializer() {
} catch (Throwable t) { propertyPath = System.getProperty(PROPERTIES_SYS_PROP,
LOG.error("Failed to destroy service {}", service.getClass().getName(), t); DEFAULT_CONFIG_PATH);
throw new MetadataException(t); }
}
LOG.info("Service destroyed: {}", service.getClass().getName()); /**
} * Create a ServiceInitializer, specifying the properties file filename
} * explicitly
*
* @param propPath
* the filename of the properties file with the service
* intializer information
*/
public ServiceInitializer(String propPath) {
propertyPath = propPath;
}
/**
* Get the configuration properties for the ServiceInitializer
*
* @return
* @throws ConfigurationException
*/
public PropertiesConfiguration getConfiguration()
throws ConfigurationException {
return new PropertiesConfiguration(propertyPath);
}
/**
* Initialize the services specified by the application.services property
*
* @throws MetadataException
*/
public void initialize() throws MetadataException {
/*
* TODO - determine whether this service model is the right model;
* Inter-service dependencies can wreak havoc using the current model
*/
String[] serviceClassNames;
LOG.info("Loading services using properties file: {}", propertyPath);
try {
PropertiesConfiguration configuration = getConfiguration();
serviceClassNames = configuration
.getStringArray("application.services");
} catch (ConfigurationException e) {
throw new RuntimeException("unable to get server properties");
}
for (String serviceClassName : serviceClassNames) {
serviceClassName = serviceClassName.trim();
if (serviceClassName.isEmpty()) {
continue;
}
Service service = ReflectionUtils
.getInstanceByClassName(serviceClassName);
services.register(service);
LOG.info("Initializing service: {}", serviceClassName);
try {
service.start();
} catch (Throwable t) {
LOG.error("Failed to initialize service {}", serviceClassName,
t);
throw new MetadataException(t);
}
LOG.info("Service initialized: {}", serviceClassName);
}
}
public void destroy() throws MetadataException {
for (Service service : services) {
LOG.info("Destroying service: {}", service.getClass().getName());
try {
service.stop();
} catch (Throwable t) {
LOG.error("Failed to destroy service {}", service.getClass()
.getName(), t);
throw new MetadataException(t);
}
LOG.info("Service destroyed: {}", service.getClass().getName());
}
}
} }
application.services=org.apache.hadoop.metadata.service.TestService
\ No newline at end of file
package org.apache.hadoop.metadata.service;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/**
* Unit test for the Service Initializer.
*
* Test functionality to allow loading of different property files.
*/
public class ServiceInitializerTest {
private final String propertiesFileName = "test.application.properties";
private ServiceInitializer sinit;
@BeforeClass
public void setUp() throws Exception {
// setup for the test properties file
System.setProperty(ServiceInitializer.PROPERTIES_SYS_PROP,
propertiesFileName);
sinit = new ServiceInitializer();
}
@AfterClass
public void tearDown() throws Exception {
// test destruction of the Services - no exceptions is assumed a success
sinit.destroy();
}
@Test
public void testPropsAreSet() throws Exception {
Assert.assertEquals(
sinit.getConfiguration().getString(
"application.services"),
TestService.NAME);
}
@Test
public void testInitialize() throws Exception {
// test the initialization of the initializer
// no exceptions is assumed a success
sinit.initialize();
}
}
package org.apache.hadoop.metadata.service;
import java.io.IOException;
public class TestService implements Service {
public static final String NAME = TestService.class.getName();
@Override
public String getName() {
return NAME;
}
@Override
public void start() throws Exception {
}
@Override
public void stop() {
}
@Override
public void close() throws IOException {
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment