Domanda

i am designing a web service in java where i need to do a sort of AB testing with requests in java.

Basically I'm looking for ways to easily configure parameters which will be dynamically loaded by a request handler to determine the code path based on config values.

for example, let's say i need to get some data either from an external web service or from local DB. i want to have a way to configure parameters(criteria in this context) so that it would determine whether to go fetch data from external web service or from local DB.

if i go with a key-value pair config system above example might produce something like this.

locale=us
percentage=30
browser=firefox

which would mean that i would be fetching data from local DB for 30% of requests from US users whose user-agent is firefox. and i would like this config system to be dynamic so that server does not need to be restarted.

sorry about very high level description but any insights/leads would be appreciated. if this is a topic that is beaten to death in the past, please kindly let me know the links.

È stato utile?

Soluzione

I've used this in the past. It is the most common way in java to achieve what you are asking using java.util.Properties:

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

/**
* Class that loads settings from config.properties
* @author Brant Unger
*
*/
public class Settings 
{
public static boolean DEBUG = false; 

/**
 * Load settings from config.properties
 */
public static void load()
{
    try
    {
        Properties appSettings = new Properties();
        FileInputStream fis = new FileInputStream("config.properties"); //put config properties file to buffer
        appSettings.load(fis); //load config.properties file

                   //This is where you add your config variables:
                   DEBUG = Boolean.parseBoolean((String)appSettings.get("DEBUG"));

        fis.close();
        if(DEBUG) System.out.println("Settings file successfuly loaded");

    }
    catch(IOException e)
    {
        System.out.println("Could not load settings file.");
        System.out.println(e.getMessage());
    }
}

}

Then in your main class you can do:

Settings.load(); //Load settings

Then you can check the values of those variables in every other class like:

if (Settings.DEBUG) System.out.println("The debug value is true");

Altri suggerimenti

I'm not sure if it helps you, but i usually put config data in some editable file:

file params.ini

vertices 3
n_poly 80
mutation_rate 0.0001f
photo_interval_sec 60
target_file monalisa.jpeg
randomize_start true
min_alpha 20
max_alpha 90

I use this class to load it:

import java.io.*;
import java.util.HashMap;
import java.util.Scanner;

public class Params 
{
 static int VERTICES = 0;
 static int N_POLY = 0;
 static float MUTATION_RATE = 0.0f;
 static int PHOTO_INTERVAL_SEC = 0;
 static String TARGET_FILE;
 static boolean RANDOMIZE_START = false;
 static int MIN_ALPHA = 0;
 static int MAX_ALPHA = 0;
 
 public Params() 
 { 
  Scanner scanner = new Scanner(this.getClass().getResourceAsStream("params.ini")); 
  HashMap<String, String> map = new HashMap<String, String>();
  
  while (scanner.hasNext()) 
  {
   map.put(scanner.next(), scanner.next());
  }
  
  TARGET_FILE = map.get("target_file");
  VERTICES = Integer.parseInt(map.get("vertices"));
  N_POLY = Integer.parseInt(map.get("n_poly"));    
  MUTATION_RATE = Float.parseFloat(map.get("mutation_rate"));
  PHOTO_INTERVAL_SEC = Integer.parseInt(map.get("photo_interval_sec"));
  RANDOMIZE_START = Boolean.parseBoolean(map.get("randomize_start"));
  MIN_ALPHA = Integer.parseInt(map.get("min_alpha"));
  MAX_ALPHA = Integer.parseInt(map.get("max_alpha"));
 }
 
}

Then just load and read:

// call this to load/reload the file
new Params();

// then just read
int vertices = Params.VERTICES;    

Hope it helps!

I've just released an open source solution to this using .yml files, which can be loaded into POJOs, thus creating a nicer solution than a map of properties. In addition, the solution interpolates system properties and environment variables into placeholders:

url: ${database.url}
password: ${database.password}
concurrency: 12

This can be loaded into a Map or better still a Java POJO.

See https://github.com/webcompere/lightweight-config

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top