Skip to content

Commit

Permalink
Issue #34: code to get host name in the cloud from instance metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
sriramkrishnan committed Oct 5, 2013
1 parent 04136b5 commit 1c4b7d9
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 19 deletions.
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ project(':genie-server') {
compile 'com.sun.jersey.contribs:jersey-guice:1.9.1'
compile 'com.netflix.servo:servo-core:0.4.34'
compile 'com.netflix.karyon:karyon-extensions:1.0.22'
compile 'commons-httpclient:commons-httpclient:3.1'

runtime 'org.apache.derby:derby:10.2.2.0'
runtime 'mysql:mysql-connector-java:5.1.16'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,14 @@

package com.netflix.genie.server.util;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.InetAddress;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.methods.GetMethod;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -34,11 +39,17 @@
*/
public final class NetUtil {

private static String publicHostName;
private static String localHostName;
private static String cloudHostName;
private static String dcHostName;

private static Logger logger = LoggerFactory.getLogger(NetUtil.class);

// the instance meta-data uri's for public and private host/ip's
private static final String PUBLIC_HOSTNAME_URI =
"http://169.254.169.254/latest/meta-data/public-hostname";
private static final String LOCAL_IPV4_URI =
"http://169.254.169.254/latest/meta-data/local-ipv4";

private NetUtil() {
// never called
}
Expand All @@ -63,10 +74,10 @@ public static String getArchiveURI(String jobID) {
}

/**
* Return either the public or local dns name, depending on the datacenter.
* Return either the cloud or dc host name, depending on the datacenter.
* If the property netflix.genie.server.host is set, that value will always be returned.
* If the property is not set, then the environment variable EC2_PUBLIC_HOSTNAME will
* be used in the cloud, or InetAddress.getLocalHost() will be used in the DC.
* If the property is not set, then the instance metadata will be used in the cloud,
* or InetAddress.getLocalHost() will be used in the DC.
*
* @return host name
*/
Expand All @@ -84,9 +95,9 @@ public static String getHostName() throws CloudServiceException {
String dc = ConfigurationManager.getConfigInstance().getString(
"netflix.datacenter");
if ((dc != null) && dc.equals("cloud")) {
hostName = getPublicHostName();
hostName = getCloudHostName();
} else {
hostName = getLocalHostName();
hostName = getDCHostName();
}

if ((hostName == null) || (hostName.isEmpty())) {
Expand All @@ -99,38 +110,74 @@ public static String getHostName() throws CloudServiceException {
return hostName;
}

private static String getPublicHostName() throws CloudServiceException {
private static String getCloudHostName() throws CloudServiceException {
logger.debug("called");

if ((publicHostName != null) && (!publicHostName.isEmpty())) {
return publicHostName;
if ((cloudHostName != null) && (!cloudHostName.isEmpty())) {
return cloudHostName;
}

// gets the ec2 public hostname, if available
try {
cloudHostName = httpGet(PUBLIC_HOSTNAME_URI);
} catch (IOException ioe) {
String msg = "Unable to get public hostname from instance metadata";
logger.error(msg, ioe);
throw new CloudServiceException(
HttpURLConnection.HTTP_INTERNAL_ERROR, msg, ioe);
}
if ((cloudHostName == null) || (cloudHostName.isEmpty())) {
try {
cloudHostName = httpGet(LOCAL_IPV4_URI);
} catch (IOException ioe) {
String msg = "Unable to get local IP from instance metadata";
logger.error(msg, ioe);
throw new CloudServiceException(
HttpURLConnection.HTTP_INTERNAL_ERROR, msg, ioe);
}
}
logger.info("cloudHostName=" + cloudHostName);

// gets the ec2 public hostname
publicHostName = System.getenv("EC2_PUBLIC_HOSTNAME");
logger.debug("publicHostName=" + publicHostName);
return cloudHostName;
}

return publicHostName;
/**
* Returns the response from an HTTP GET call if it succeeds, null otherwise.
*
* @param uri The URI to execute the HTTP GET on
* @return response from an HTTP GET call if it succeeds, null otherwise
* @throws IOException if there was an error with the HTTP request
*/
private static String httpGet(String uri) throws IOException {
String response = null;
HttpClient client = new HttpClient();
HttpMethod method = new GetMethod(uri);
client.executeMethod(method);
int status = method.getStatusCode();
if (status == HttpURLConnection.HTTP_OK) {
response = method.getResponseBodyAsString();
}
return response;
}

private static String getLocalHostName() throws CloudServiceException {
private static String getDCHostName() throws CloudServiceException {
logger.debug("called");

if ((localHostName != null) && (!localHostName.isEmpty())) {
return localHostName;
if ((dcHostName != null) && (!dcHostName.isEmpty())) {
return dcHostName;
}

try {
// gets the local instance hostname
InetAddress addr = InetAddress.getLocalHost();
localHostName = addr.getCanonicalHostName();
dcHostName = addr.getCanonicalHostName();
} catch (Exception e) {
String msg = "Unable to get the hostname";
logger.error(msg, e);
throw new CloudServiceException(
HttpURLConnection.HTTP_INTERNAL_ERROR, msg, e);
}

return localHostName;
return dcHostName;
}
}

0 comments on commit 1c4b7d9

Please sign in to comment.