4
\$\begingroup\$

In our company we have a machine hostname as -

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

Here dc1, dc2, dc3 are our datacenter and we will be having only three datacenter. But it might be possible that they can have more dots in between separated by another domain.

Now I need to find in which datacenter my current machine is in. I will be running below code in some machine as shown above.. And below code will tell me which datacenter my code is running in. But is there any way to modify the below code to make it more efficient? I guess we can write this much better -

String datacenter = getCurrentDatacenter();

private String getCurrentDatacenter(){

    String s_hostName = null;;
    try {
        s_hostName = InetAddress.getLocalHost().getCanonicalHostName();
    } catch (UnknownHostException e) {      
        s_logger.debug(LogLevel.ERROR+"\t"+e.getStackTrace().toString());
    }

    if (s_hostName != null && !s_hostName.isEmpty()){

        s_hostName.toUpperCase();
        if (s_hostName.contains(DatacenterEnum.DC1.name())){
            currentDatacenter = DC1;
        }
        else if (s_hostName.contains(DatacenterEnum.DC2.name())){
            currentDatacenter = DC2;
        }
        else if (s_hostName.contains(DatacenterEnum.DC3.name())){
            currentDatacenter = DC3;
        }
    }

    return currentDatacenter;
}

Below is my ENUM -

public enum DatacenterEnum {
    DC1, DC2, DC3;

    private static final Map<Integer, DatacenterEnum> BY_CODE_MAP = new LinkedHashMap<Integer, DatacenterEnum>();

    static {
    for (DatacenterEnum rae : DatacenterEnum.values()) {
        BY_CODE_MAP.put(rae.ordinal(), rae);
    }
    }

    public static String forCode(int code) {
    return BY_CODE_MAP.get(code).name();
    }
}
\$\endgroup\$

1 Answer 1

4
\$\begingroup\$

There are a few things which I think will simplify your code a lot, and it all centers around your Enum.

Firstly, there is no need in your enum to have the BY_CODE_MAP system. Remove it. You can very efficiently (and with the identical results) use the method:

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

The values() array in an enum will always be indexed in the same order as the ORDINAL of each Enum.

The second thing, is that you should only be calculating the Datacenter location once for each JVM. Having it as a method which is called potentially multiple times, each time interrogating the java.net.* layer for hostnames, is inefficient.

I suggest you add a static initializer method to your Enum that 'knows'.

Consider the following changes to your enum, and replace the logic in your code:

private String getCurrentDatacenter(){
    DatacenterEnum us = DatacenterEnum.getCurrentDatacenter();
    return us == null ? null : us.name();
}

Then, your Enum will look like (I have commented out the code I think is redundant):

import java.net.InetAddress;
import java.net.UnknownHostException;


public enum DatacenterEnum {
    DC1, DC2, DC3;

//    private static final Map<Integer, DatacenterEnum> BY_CODE_MAP = new LinkedHashMap<Integer, DatacenterEnum>();

//    static {
//        for (DatacenterEnum rae : DatacenterEnum.values()) {
//            BY_CODE_MAP.put(rae.ordinal(), rae);
//        }
//    }

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

    private static final DatacenterEnum ourlocation = compareLocation();

    private static DatacenterEnum compareLocation() {
        String ourhost = getHostName();
        for (DatacenterEnum dc : values()) {
            String namepart = "." + dc.name().toLowerCase() + ".";
            if (ourhost.indexOf(namepart) >= 0) {
                return dc;
            }
        }
        return null;
    }

    private static final String getHostName() {
        try {
            return InetAddress.getLocalHost().getCanonicalHostName().toLowerCase();
        } catch (UnknownHostException e) {      
            // s_logger.debug(LogLevel.ERROR+"\t"+e.getStackTrace().toString());
            return "localhost";
        }
    }

    public static DatacenterEnum getCurrentDatacenter() {
        return ourlocation;
    }

    public static void main(String[] args) {
        System.out.println(DatacenterEnum.getCurrentDatacenter());
    }

}

If you ever have additional datacenters, you can simply add a new name to the enum and the rest will work. Also, you can add values that are not the same naming convention... for example, if you add the ENUM "EU1" for your first european datacenter, it will match aaa.eu1.xxx.yyy

\$\endgroup\$
1
  • \$\begingroup\$ Thanks a lot rolfl for helping me out in this question. I also have one more question here. You might be able to help me. \$\endgroup\$
    – david
    Jan 14, 2014 at 1:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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