Configuration Reader

Problem:

  • An application need to read configurations from an external source, for instance a file
  • A configuration file might be changed during an application’s work

Assume that configurations are held in a properties file. Our first task is to read Properties and keep it in one place.

@Singleton
@Startup
public class Config {
   private Properties properties;
   @PostConstruct
   private void init(){
      properties = new Properties();
      try {
         InputStream is = new FileInputStream("...");
         properties.load(is);
      } catch ( IOException e ) {
         throw new RuntimeException(e);
      }
   }
   public Properties getProperties() {
      return properties;
   }
   public Properties getProperty( String key ) {
      return properties.getProperty(key);
   }
}

And excerpt of a client code:

   @EJB private Config config;
   ...
      String dbName = config.getProperty("db.name");
   ...
  • Properties are read only once at application start up
  • Bean is @Startup, thus if the configuration file reading fails then runtime exception is thrown, bean initialization fails and the application deployment fails

Now assume that the configuration file is being changed and the application need to reread it. Modify our Singleton:

@Singleton
@Startup
public class Config {
   private Properties properties;
   @PostConstruct
   @Schedule(hour="*",minute="*/5",persistent=false)
   @Lock(LockType.WRITE)
   private void init(){
      try {
         Properties properties = new Properties();
         InputStream is = new FileInputStream("...");
         properties.load(is);
         this.properties = properties;
      } catch ( IOException e ) {
         throw new RuntimeException(e);
      }
   }
   @Lock(LockType.READ)
   public Properties getProperties() {
      return properties;
   }
   @Lock(LockType.READ)
   public Properties getProperty( String key ) { 
      return properties.getProperty(key); 
   } 
}
  • The configuration file is reread every 5 minutes
  • If the configuration file reading fails and it is not initialization then runtime exception is thrown but bean is not discarded and old properties remains, clients are not affected
  • Locks are added to enhance consistency
  • persistent=false prevents accumulated schedule invocations after a server restart

Usually reading the configuration file is fast. But if communicating with an external source containing configurations is time consuming then Lock(LockType.WRITE) might be consider as a bottleneck. We provide further modifications:

@Singleton 
@Startup 
public class ConfigurationReader {
   @EJB
   private Config config;
   @PostConstruct
   @Schedule(hour="*",minute="*/5",persistent=false)
   private void init(){
      try {
         Properties properties = new Properties();
         InputStream is = new FileInputStream("...");
         properties.load(is);
         config.setProperties(properties);
      } catch ( IOException e ) {
         throw new RuntimeException(e);
      }
   }
}

@Singleton
@Startup
public class Config {
   private Properties properties;
   @Lock(LockType.WRITE)
   public void setProperties( Properties properties ) {
      this.properties = properties;
   }
   @Lock(LockType.READ)
   public Properties getProperties() {
      return properties;
   }
   @Lock(LockType.READ)
   public Properties getProperty( String key ) { 
      return properties.getProperty(key); 
   } 
}
  • Hard word is done in separate Singleton, when it is done then the configurations are updated in main Singleton
Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: