3
\$\begingroup\$

I should initialize the startup variables before serving the requests. Few of my variables could be initialized from a local property file (say init.properties) and few would get initialized from a URL, say (/getProperties).

  1. I should be able to serve requests from my engine only when all my variables gets initialised (both from a local property file and from a remote URL call).

  2. The first request should fail when there is some exception while loading the property file (or) when the remote HTTP call fails and it should be able to retry on consecutive calls.

Here is how I have done the initialisation part:

public class EngineUtils {

    private static boolean isEnginePropertiesInitialised = false;
    private static long keepAliveTime = -1;
    private static String serverIp;
    private static int port;
    private static String mode;
    private static String moduleName;
    private static String moduleURL;
    private static String remoteModuleURL;
    private static int moduleType = -1;
    private static String token = null;

    /**
    And this list goes on..
    **/


    public static synchronised void initEngineProperties() {    //Made this synchronised to make sure that only one thread is allowed to initialise at a time
            if(remoteModuleURL == null) {        //Checking this to make sure the properties are initialised already
                initEngineProps();
                initModuleURL();
                initConnectingServerIpPort();
            }
    }

    public static int initModuleType() {
        /**
        The moduleName used here is initialised from **initEngineProps** and this should have executed before it is initialising
        the module type. I’m just maintaining the order now while writing code consciously but not sure some one else who 
        read my code understands this order. Is commenting the only way in these situations?
        **/
        if(moduleName.equals(“ABC”)) return 1;
        else if(moduleName.equals(“CDE”)) return 2;
        else if(moduleName.equals(“MNO”)) return 3;
    }
    public static int getModuleType() {
        if(moduleType == -1) {
            initModuleType();
        } 
    }
    private static void populateProperties(JSONObject props) throws Exception {
        mode = props.optString(“mode”);
        serverIp = props.optString(“ip”);
        port = props.optString(“port”);
        moduleURL = props.optString(“module_url”);
    }
    public static void loadPropertiesFromLocalFile() throws Exception {
        Properties prop = new Properties();
        String filepath = “path_to_properties_file/abc.properties”;
        InputStream in = new FileInputStream(filepath);
        prop.load(in);

        token = props.getProperty(“token”);
    }
    public static void initEngineProps() throws Exception {
        if(isEnginePropertiesInitialised) return;    //To avoid reinitialising the properties again
        loadPropertiesFromLocalFile();

        /**
        This XYZ module has to be initialised only after loading the token value from local property file
        Someone else who is reading or looking at this code for the first time may not recognise this.
        How could I avoid this?
        **/

        initXYZModule(token);

        int moduleType = getModuleType();

        if(moduleType == 1) {
            /**
                1.Do some other stuff
                2.Make http request to request uri - this would respond with json object - during success call
                3.When there is some network failure (or) server is not reachable this method 
                **getHttpResponse** throws exception
            **/
            populateProperties(getHttpResponse(“from_uri_0”));   
        } else if(moduleType == 2) {
             populateProperties(getHttpResponse(“from_uri_1”));   
        } else if(moduleType == 3) {
              populateProperties(getHttpResponse(“from_uri_2”));   
        }
    }

    /**
    This method is required everywhere else in the project and the 
    value has to be initialised before it gets served
    **/

    public static void getToken() {
        if(!isEnginePropertiesInitialised) 
            initEngineProperties();
        return token;
    }
    public static void initModuleURL() {
        //Do some stuff here
    }
    public static void initConnectingServerIpPort() {
        //Do some stuff here
    }
  }

After writing this I find it too clumsy to read and it is not easily understandable and I get confused when I try to change some snippet over here. Can someone suggest a better design for the following case so that my code looks easily understandable to everyone?

\$\endgroup\$
2
  • \$\begingroup\$ It might be worth to check AtomicBoolean and CountDownLatch to see how these could help you. \$\endgroup\$
    – Thomas
    Jan 16 '18 at 19:56
  • \$\begingroup\$ use a static initializer? \$\endgroup\$
    – slowy
    Jan 17 '18 at 10:20
3
\$\begingroup\$

Ohh...
you do not need to convert a property to integer then again. Generaly, if you have if-else or switches statement like that and checking if something is initialized, etc, your design is wrong.

private static Properies props;
static{
props.put("ABC","from_uri_0”);
props.put("CDE","from_uri_1");
//...
    }

And call just props.get("ABC").
Further, if you would do some actions depending of some key, you could use functional features like:

private static Map<String,Function> funcs;// then static init

Then instead of if-else or switch:

thisFunc = funcs.get(string);
thisFunc.action(do stuff);// of whatever the syntax is

Then to import props from Json i would do

private static String[] fromJson 
= new String []{“mode”, "ip", "url"};// so you can modify the list in one place

 private static void populateProperties(JSONObject jo)
for(String str: fromJson ){
props.put(str,jo.optString((str);
}

Then, you do not need have a boolean value if something is initialized, its just bad code. Instead, the exception must be thrown

    public static void initEngineProps() throws IOException {
    loadPropertiesFromLocalFile();// throws IOException  since it is reads some file
    }
    public static void getToken(){

    return token;// token must be there if no exception had been thrown

}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.