Search code examples
javaenumshostnameinetaddress

How to efficiently return the string basis on current datacenter?


We have machine hostname as -

dbx111.dc1.host.com
dbx112.dc2.host.com
dcx113.dc3.host.com

dcx115.dev.host.com

Here dc1, dc2, dc3 and dev are our datacenter and we will be having only four datacenter as of now. And also it might be possible that machine hostname can have more dots in between separated by another domain in future.

Now I need to find out which datacenter my current machine is in as I will be running below code on the actual machine.

And also I have two flows as of now one is USERFLOW and other is DEVICEFLOW.

public enum FlowTypeEnum {
    USERFLOW, DEVICEFLOW
}

Problem Statement:-

  • If my machine is in DC1 and flow type is USERFLOW then I need to return /test/datacenter/dc1 but if flow type is DEVICEFLOW then I need to return /testdevice/datacenter/dc1
  • But if my machine is in DC2 and flow type is USERFLOW then I need to return /test/datacenter/dc2 but if flow type is DEVICEFLOW then I need to return /testdevice/datacenter/dc2.
  • And if my machine is in DC3 and flow type is USERFLOW then I need to return /test/datacenter/dc3 but if flow type is DEVICEFLOW then I need to return /testdevice/datacenter/dc3.
  • But if my machine datacenter is in DEV, and flow type is USERFLOW then I need to return "/test/datacenter/dc1" but if flow type is DEVICEFLOW then I need to return /testdevice/datacenter/dc1.

I have my below code which works fine but it doesn't use FlowTypeEnum at all. How do I pass typeEnum value from Java main to DatacenterEnum class and return string as shown in the above algorithm -

Below is my TestsingEnum class -

public class TestingEnum {

    public static void main(String[] args) {
        // FlowTypeEnum typeEnum = FlowTypeEnum.USERFLOW;
        // how to pass this typeEnum value to DatacenterEnum class with the current setup I have
        // and return basis on above algorithm

        System.out.println(DatacenterEnum.LOCAL_POOK);
    }
}

And below is my DatacenterEnum class -

public enum DatacenterEnum {
    DEV, DC1, DC2, DC3;

    private static final Random random = new Random();

    public static String forCode(int code) {
        return (code >= 0 && code < values().length) ? values()[code].name() : null;
    }

    private static final DatacenterEnum ourlocation = compareLocation();

    private static DatacenterEnum compareLocation() {
        String currenthost = getHostNameOfServer();

        if (currenthost != null) {
            if (isDevMachine(currenthost)) {
                return DC1;
            }

            for (DatacenterEnum dc : values()) {
                String namepart = "." + dc.name().toLowerCase() + ".";
                if (currenthost.indexOf(namepart) >= 0) {
                    return dc;
                }
            }
        }
    }

    private String toLocalPook() {
        if (this == DEV) {
            return "/test/datacenter/dc1";
        }

        return "/test/datacenter/" + name().toLowerCase();
    }

    public static final String LOCAL_POOK = ourlocation.toLocalPook();

    private static final String getHostNameOfServer() {
        try {
            return InetAddress.getLocalHost().getCanonicalHostName().toLowerCase();
        } catch (UnknownHostException e) {
            // log an exception
        }

        return null;
    }

    private static boolean isDevMachine(String hostName) {
        return hostName.indexOf("." + DEV.name().toLowerCase() + ".") >= 0;
    }
}

The only difference between USERFLOW and DEVICEFLOW is - For USERFLOW, I need to use /test and for DEVICEFLOW, I need to use /testdevice and other things are same.


Solution

  • Why don't you pass the flow type to the toLocalPook method:

    enum Flow {
        USERFLOW , DEVICEFLOW 
    }
    private String toLocalPook(Flow f) {
        String prefix = "";
        if (f.equals(Flow.DEVICEFLOW)) {
            prefix = "/testdevice";
        } else if (f.equals(Flow.USERFLOW)) {
            prefix = "/test";
        }
        if (this == DEV) {
            return prefix + "/datacenter/dc1";
        }
    
        return prefix + "/datacenter/" + name().toLowerCase();
    }
    

    If you do this you would have to change the way you call toLocalPook... LOCAL_POOK can not be final static:

    class OtherClass {
        public static void main(String[] args) {
            String LOCAL_POOK = DatacenterEnum.getOurlocation().toLocalPook(
                    Flow.USERFLOW);
            System.out.println(LOCAL_POOK);
        }
    
    }
    

    here's the full enum

        public enum DatacenterEnum {
        DEV, DC1, DC2, DC3;
    
    
        public static DatacenterEnum getOurlocation() {
            return ourlocation;
        }
    
        private static final Random random = new Random();
    
        public static String forCode(int code) {
            return (code >= 0 && code < values().length) ? values()[code].name() : null;
        }
    
        private static final DatacenterEnum ourlocation = compareLocation();
    
        private static DatacenterEnum compareLocation() {
            String currenthost = getHostNameOfServer();
    
            if (currenthost != null) {
                if (isDevMachine(currenthost)) {
                    return DC1;
                }
    
                for (DatacenterEnum dc : values()) {
                    String namepart = "." + dc.name().toLowerCase() + ".";
                    if (currenthost.indexOf(namepart) >= 0) {
                        return dc;
                    }
                }
            }
            return null;
        }
    
        enum Flow {
            USERFLOW , DEVICEFLOW 
        }
        public String toLocalPook(Flow f) {
            String prefix = "";
            if (f.equals(Flow.DEVICEFLOW)) {
                prefix = "/testdevice";
            } else if (f.equals(Flow.USERFLOW)) {
                prefix = "/test";
            }
            if (this == DEV) {
                return prefix + "/datacenter/dc1";
            }
    
            return prefix + "/datacenter/" + name().toLowerCase();
        }
    
    
        private static final String getHostNameOfServer() {
            try {
                return InetAddress.getLocalHost().getCanonicalHostName().toLowerCase();
            } catch (UnknownHostException e) {
                // log an exception
            }
    
            return null;
        }
    
        private static boolean isDevMachine(String hostName) {
            return hostName.indexOf("." + DEV.name().toLowerCase() + ".") >= 0;
        }
    
    }