All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.amazonaws.regions.RegionMetadataParser Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2013-2015 Amazon Technologies, Inc. 
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at:
 * 
 *    http://aws.amazon.com/apache2.0
 *
 * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 
 * OR CONDITIONS OF ANY KIND, either express or implied. See the 
 * License for the specific language governing permissions and 
 * limitations under the License. 
 */
package com.amazonaws.regions;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


/**
 * Parses a region metadata file to pull out information about the
 * available regions, names, IDs, and what service endpoints are available
 * in each region.
 */
public class RegionMetadataParser {

    private static final String REGION_TAG = "Region";
    private static final String REGION_ID_TAG = "Name";
    private static final String DOMAIN_TAG = "Domain";
    private static final String ENDPOINT_TAG = "Endpoint";
    private static final String SERVICE_TAG = "ServiceName";
    private static final String HTTP_TAG = "Http";
    private static final String HTTPS_TAG = "Https";
    private static final String HOSTNAME_TAG = "Hostname";

    /**
     * Parses the specified input stream and returns a {@code RegionMetadata}
     * object.
     *
     * @param input the input stream to parse
     * @return the parsed region metadata
     * @throws IOException on error
     */
    public static RegionMetadata parse(final InputStream input)
            throws IOException {

        return new RegionMetadata(internalParse(input, false));
    }

    /**
     * @deprecated since this object is stateless
     */
    @Deprecated
    public RegionMetadataParser() {
    }
    
    /**
     * Parses the specified input stream and returns a list of the regions
     * declared in it. By default, verification on the region endpoints is
     * disabled.
     * 
     * @param input
     *            The stream containing the region metadata to parse.
     * 
     * @return The list of parsed regions.
     * @deprecated in favor of {@link #parse(InputStream)}
     */
    @Deprecated
    public List parseRegionMetadata(InputStream input)
            throws IOException {

        return internalParse(input, false);
    }

    /**
     * Parses the specified input stream and optionally verifies that all of
     * the endpoints end in ".amazonaws.com". This method is deprecated, since
     * not all valid AWS endpoints end in ".amazonaws.com" any more.
     * 
     * @param input
     *            The stream containing the region metadata to parse.
     * @param endpointVerification
     *            Whether to verify each region endpoint
     * 
     * @return The list of parsed regions.
     * @deprecated in favor of {@link #parse(InputStream)}
     */
    @Deprecated
    public List parseRegionMetadata(final InputStream input,
                                            final boolean endpointVerification)
            throws IOException {

        return internalParse(input, endpointVerification);
    }

    private static List internalParse(
            final InputStream input,
            final boolean endpointVerification) throws IOException {

        Document document;
        try {

            DocumentBuilderFactory factory =
                DocumentBuilderFactory.newInstance();

            DocumentBuilder documentBuilder = factory.newDocumentBuilder();
            document = documentBuilder.parse(input);

        } catch (IOException exception) {
            throw exception;
        } catch (Exception exception) {
            throw new IOException("Unable to parse region metadata file: "
                                  + exception.getMessage(),
                                  exception);
        } finally {
            try {
                input.close();
            } catch (IOException exception) {
            }
        }
        
        NodeList regionNodes = document.getElementsByTagName(REGION_TAG);
        List regions = new ArrayList();
        for (int i = 0; i < regionNodes.getLength(); i++) {
            Node node = regionNodes.item(i);
            if (node.getNodeType() == Node.ELEMENT_NODE) {
                Element element = (Element)node;
                regions.add(parseRegionElement(element, endpointVerification));
            }
        }
        
        return regions;
    }

    private static Region parseRegionElement(
            final Element regionElement,
            final boolean endpointVerification) {

        String name = getChildElementValue(REGION_ID_TAG, regionElement);
        String domain = getChildElementValue(DOMAIN_TAG, regionElement);

        Region region = new Region(name, domain);

        NodeList endpointNodes =
            regionElement.getElementsByTagName(ENDPOINT_TAG);

        for (int i = 0; i < endpointNodes.getLength(); i++) {
            addRegionEndpoint(region,
                              (Element) endpointNodes.item(i),
                              endpointVerification);
        }

        return region;
    }
    
    private static void addRegionEndpoint(
            final Region region,
            final Element endpointElement,
            final boolean endpointVerification) {

        String serviceName = getChildElementValue(SERVICE_TAG, endpointElement);
        String hostname = getChildElementValue(HOSTNAME_TAG, endpointElement);
        String http = getChildElementValue(HTTP_TAG, endpointElement);
        String https = getChildElementValue(HTTPS_TAG, endpointElement);

        if ( endpointVerification && !verifyLegacyEndpoint(hostname) ) {
            throw new IllegalStateException("Invalid service endpoint ("
                                            + hostname + ") is detected.");
        }

        region.getServiceEndpoints().put(serviceName, hostname);
        region.getHttpSupport().put(serviceName, "true".equals(http));
        region.getHttpsSupport().put(serviceName, "true".equals(https));
    }

    private static String getChildElementValue(
            final String tagName,
            final Element element) {

        Node tagNode = element.getElementsByTagName(tagName).item(0);
        if ( tagNode == null )
            return null;
        NodeList nodes= tagNode.getChildNodes();
        Node node = (Node)nodes.item(0); 
     
        return node.getNodeValue();    
    }

    /**
     * Returns whether the provided endpoint is a "valid" AWS service endpoint
     * ending in ".amazonaws.com".
     */
    private static boolean verifyLegacyEndpoint(String endpoint) {
        return endpoint.endsWith(".amazonaws.com");
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy