Integración Java+Azure utilizando REST

Cuando escuchamos de Azure, inmediatamente se nos viene a la mente el SDK de esta interesante plataforma de Microsoft, sin embargo algunos desarrolladores preferimos invocar a los servicios de Azure directamente desde  su API REST, sin utilizar bibliotecas específicas. En este artículo encontrarás un ejemplo completo de cómo comunicarnos con Azure Blob Storage.


A continuación, se muestra la clase java que se encarga de realizar la comunicación:
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package util;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimeZone;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;

/**
 *
 * @author Rolando
 */
public class Util {

    private static Base64 base64 = new Base64();

    public static void signRequestSK(HttpURLConnection request, String account, String key) throws Exception {
        SimpleDateFormat fmt = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss");
        fmt.setTimeZone(TimeZone.getTimeZone("GMT"));
        String date = fmt.format(Calendar.getInstance().getTime()) + " GMT";

        StringBuilder sb = new StringBuilder();
        sb.append("GET\n"); // method
        sb.append("\n"); // content encoding
        sb.append("\n"); // content language
        sb.append("\n"); // content length
        sb.append("\n"); // md5 (optional)
        sb.append("\n"); // content type
        sb.append("\n"); // legacy date
        sb.append("\n"); // if-modified-since
        sb.append("\n"); // if-match
        sb.append("\n"); // if-none-match
        sb.append("\n"); // if-unmodified-since
        sb.append("\n"); // range
        sb.append("x-ms-date:" + date + "\n"); // headers
        sb.append("x-ms-version:2015-12-11\n");
        sb.append("/" + account + request.getURL().getPath() + "\ncomp:list");
        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(new SecretKeySpec(base64.decode(key), "HmacSHA256"));
        String authKey = new String(base64.encode(mac.doFinal(sb.toString().getBytes("UTF-8"))));
        String auth = "SharedKey " + account + ":" + authKey;
        request.setRequestProperty("x-ms-date", date);
        request.setRequestProperty("x-ms-version", "2015-12-11");
        request.setRequestProperty("Authorization", auth);
        request.setRequestProperty("Accept-Charset", "UTF-8");
        request.setRequestProperty("Accept", "application/atom+xml,application/xml");
        request.setRequestMethod("GET");
    }

    public static void main(String args[]) throws Exception {
        //To use fiddler
        System.setProperty("http.proxyHost", "127.0.0.1");
        System.setProperty("https.proxyHost", "127.0.0.1");
        System.setProperty("http.proxyPort", "8888");
        System.setProperty("https.proxyPort", "8888");
        //--
        //Inputs
        String account = "<Nombre_Cuenta>";
        String key = "<Access_Key>";
        //--
        HttpURLConnection connection = (HttpURLConnection) (new URL("http://" + account + ".blob.core.windows.net/?comp=list")).openConnection();
        signRequestSK(connection, account, key);
        connection.connect();
        StringBuffer text = new StringBuffer();
        InputStreamReader in = new InputStreamReader((InputStream) connection.getContent());
        BufferedReader buff = new BufferedReader(in);
        String line;
        do {
            line = buff.readLine();
            text.append(line + "\n");
        } while (line != null);
        System.out.println(text);
    }
}
Entonces, si utilizamos Fiddler, podremos ver que este sería el Request:
GET http://"<Nombre_Cuenta>".blob.core.windows.net/?comp=list HTTP/1.1
x-ms-date: Wed, 26 Oct 2016 18:35:49 GMT
x-ms-version: 2015-12-11
Authorization: SharedKey "<Nombre_Cuenta>":psyT2FlwpU3BU7/kKqtfi+ZBTuUpEX8bnsZ45O/1rUk=
Accept-Charset: UTF-8
Accept: application/atom+xml,application/xml
User-Agent: Java/1.8.0_92
Host: "<Nombre_Cuenta>".blob.core.windows.net
Connection: keep-alive
Y el response quedaría de la siguiente manera:
<?xml version="1.0" encoding="UTF-8" ?>
<EnumerationResults ServiceEndpoint="http://"<Nombre_Cuenta>".blob.core.windows.net/">
    <Containers>
        <Container>
            <Name>sas</Name>
            <Properties>
                <Last-Modified>Tue, 25 Oct 2016 19:19:46 GMT</Last-Modified>
                <Etag>"0x8D3FD0BE1F7E8D0"</Etag>
                <LeaseStatus>unlocked</LeaseStatus>
                <LeaseState>available</LeaseState>
            </Properties>
        </Container>
    </Containers>
    <NextMarker />
</EnumerationResults>

Comentarios