Wednesday 27 May 2015

How to get AWS EC2 instance metadata from Java

I have recently found that I can access EC2 machine instance metadata using curl.
Which is brilliantly useful.

However, I wanted to get the same data inside my Java applications.
So I build a utility to make it available...

package com.mendeley.weblet.oauth.utility;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.client.apache4.config.DefaultApacheHttpClient4Config;

import java.net.URI;


/**
 * Utility class to access EC2 instance Meta-data
 *
 * @See (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html)
 */
public class EC2Metadata {

    /**
     * Some of the Metadata types
     */
    public enum Type{
        ami_id("ami-id"),
        ami_launch_index("ami-launch-index"),
        ami_manifest_path("ami-manifest-path"),
        block_device_mapping("block-device-mapping/"),
        hostname("hostname"),
        instance_action("instance-action"),
        instance_id("instance-id"),
        instance_type("instance-type"),
        kernel_id("kernel-id"),
        local_hostname("local-hostname"),
        local_ipv4("local-ipv4"),
        mac("mac"),
        network("network/"),
        placement("placement/"),
        public_hostname("public-hostname"),
        public_ipv4("public-ipv4"),
        public_keys("public-keys/"),
        reservation_id("reservation-id"),
        security_groups("security-groups"),
        services("services/");

        private String name;

        private Type(String name){
            this.name = name;
        }
    }


    /**
     * Get metadata using Type enum
     *
     * @param type
     * @param timeout
     * @param defaultValue
     * @return
     */
    public static String retrieveMetadata(Type type, int timeout,String defaultValue) {
        return retrieveMetadata(type.toString(),timeout,defaultValue);
    }

    /**
     * Get metadata by String value
     * Allows further metadata to be retrieved.
     * See AWS documentation for more info.
     *
     * @param type
     * @param timeout
     * @param defaultValue
     * @return
     */
    public static String retrieveMetadata(String type, int timeout,String defaultValue) {
        try{
            URI uri = URI.create("http://169.254.169.254/latest/meta-data/" + type);
            System.out.println(uri.toString());

            ClientConfig config = new DefaultApacheHttpClient4Config();
            config.getProperties().put(ClientConfig.PROPERTY_CONNECT_TIMEOUT,timeout);

            Client client = Client.create(config);
            WebResource webResource = client.resource(uri);

            ClientResponse response = webResource.get(ClientResponse.class);

            String results = response.getEntity(String.class);
            return results;

        }catch(Throwable t){
            return defaultValue;
        }
    }


    public static void main(String[] args) {
        String myEC2Id = retrieveMetadata(Type.instance_id,1000, "null");
        System.out.println("The Instance Id is " + myEC2Id + " .");
    }

}


I will try to get it into Github at some point, until then, please use it as you see fit.
Obviously I take no responsibility for the end of the world as you know it, should it occur.

2 comments: