Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue #34: code to get host name in the cloud from instance metadata #35

Merged
merged 1 commit into from
Oct 7, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
}
}