Compartir a través de


Introducción a las solicitudes HTTP de Conexiones híbridas de Relay en Java

En esta guía de inicio rápido, creará aplicaciones de remitente y receptor de Java que envían y reciben mensajes mediante el protocolo HTTP. Las aplicaciones usan la característica Conexiones híbridas de Azure Relay. Para información acerca de Azure Relay en general, consulte Azure Relay.

En esta guía de inicio rápido, realizará los siguientes pasos:

  1. Creación de un espacio de nombres de Relay mediante Azure Portal.
  2. Creación de una conexión híbrida en dicho espacio de nombres mediante Azure Portal.
  3. Escritura de una aplicación de consola de servidor (de escucha) para recibir mensajes.
  4. Escritura de una aplicación de consola de cliente (remitente) para enviar mensajes.
  5. Ejecución de aplicaciones.

Requisitos previos

Creación de un espacio de nombres mediante Azure Portal

  1. Inicie sesión en Azure Portal.

  2. Seleccione Todos los servicios en el menú de la izquierda. Seleccione Integración, busque Retransmisiones, mueva el mouse sobre Retransmisiones y, a continuación, seleccione Crear.

    Captura de pantalla en la que se muestra la selección del botón Retransmisiones -> Crear.

  3. En la página Crear espacio de nombres, siga estos pasos:

    1. Elija la suscripción de Azure en la que se va a crear el espacio de nombres.

    2. En Grupo de recursos, elija un grupo de recursos existente en el que se colocará el espacio de nombres o cree uno.

    3. Escriba un nombre para el espacio de nombres de Retransmisión.

    4. Seleccione la región donde se debe hospedar el espacio de nombres.

    5. En la parte inferior de la página, seleccione Revisar y crear.

      Captura de pantalla en la que se muestra la página Crear un espacio de nombres.

    6. En la página Revisar y crear, seleccione Crear.

    7. Al cabo de unos minutos, verá la página Retransmisión del espacio de nombres.

      Captura de pantalla en la que se muestra la página principal del espacio de nombres de Retransmisión.

Obtención de las credenciales de administración

  1. En la página Retransmisión, seleccione Directivas de acceso compartido en el menú de la izquierda. `

  2. En la página Directivas de acceso compartido, seleccione RootManageSharedAccessKey.

  3. En Directiva SAS: RootManageSharedAccessKey, haga clic en el botón Copiar situado junto a Cadena de conexión principal. Esta acción copia la cadena de conexión en el Portapapeles para su uso posterior. Pegue este valor en el Bloc de notas o cualquier otra ubicación temporal.

  4. Repita el paso anterior para copiar y pegar el valor de Clave principal en una ubicación temporal para su uso posterior.

    Captura de pantalla en la que se muestra la información de conexión para el espacio de nombres de Retransmisión.

Creación de una conexión híbrida mediante Azure Portal

En la página Relay del espacio de nombres, siga estos pasos para crear una conexión híbrida.

  1. En el menú de la izquierda, en Entidades, seleccione Conexiones híbridas y, después, + Conexión híbrida.

    Captura de pantalla en la que se muestra la página Conexiones híbridas.

  2. En la página Crear conexión híbrida, escriba un nombre para la conexión híbrida y seleccione Crear.

    Captura de pantalla en la que se muestra la página Crear conexión híbrida.

Creación de una aplicación de servidor (agente de escucha)

Para escuchar y recibir mensajes desde Relay, escriba una aplicación de consola en Java.

Creación de una aplicación Java

Si deshabilitó la opción que indica que se requiere la autorización del cliente al crear la retransmisión, puede enviar solicitudes a la dirección URL de conexiones híbridas con un explorador. Para acceder a los puntos de conexión protegidos, debe crear y pasar un token en el encabezado ServiceBusAuthorization, que se muestra aquí.

Esta es una estructura de proyecto Maven sencilla y una clase de Java que muestra el envío de solicitudes a una dirección URL de conexiones híbridas con autorización de cliente mediante la biblioteca de Azure Relay.

Adición del paquete de Relay

Modifique el archivo pom.xml en el paquete de aplicación maven para incluir el paquete de Azure Relay.

<dependency>
    <groupId>com.microsoft.azure</groupId>
    <artifactId>azure-relay</artifactId>
    <version>0.0.6</version>
</dependency>

Ejecute mvn dependency:copy-dependencies -DoutputDirectory=lib en el proyecto mvn para agregar el archivo jar de dependencia en el directorio de biblioteca del proyecto. Importa todas las dependencias del paquete mvn azure-relay. Este paquete proporciona funciones para construir identificadores uniformes de recursos (URI) y tokens de Relay.

Escritura de código para enviar mensajes

  1. Agregue los archivos jar de dependencia al ClassPath del archivo Listener.java.

    javac -cp lib/* src/main/java/com/example/listener/Listener.Java
    
  2. Importe las dependencias en la clase Listener.java.

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.net.URI;
    import java.net.URISyntaxException;
    import java.util.Scanner;
    import com.microsoft.azure.relay.HybridConnectionListener;
    import com.microsoft.azure.relay.RelayConnectionStringBuilder;
    import com.microsoft.azure.relay.RelayedHttpListenerResponse;
    import com.microsoft.azure.relay.TokenProvider;
    
  3. Agregue el siguiente constants a la parte superior del archivo Listener.java a una función java createConnectionString para obtener los detalles de la conexión híbrida.

    public static String createConnectionString(){
        StringBuilder connectionString = new StringBuilder();
        connectionString.append("Endpoint=sb://");
        connectionString.append("{namespace}");
        connectionString.append(".servicebus.windows.net/;SharedAccessKeyName=");
        connectionString.append("{keyrule}");
        connectionString.append(";SharedAccessKey=");
        connectionString.append("{key}");
        connectionString.append(";EntityPath=");
        connectionString.append("{path}");
        return connectionString.toString();
    }
    

    Reemplace los marcadores de posición entre corchetes por los valores que obtuvo al crear la conexión híbrida.

    • namespace: el espacio de nombres de Relay. Asegúrese de utilizar el nombre de espacio de nombres completo; por ejemplo, {namespace}.servicebus.windows.net.
    • path: el nombre de la conexión híbrida.
    • keyrule: nombre de la clave de directivas de acceso compartido, que es RootManageSharedAccessKey de forma predeterminada.
    • nst key: la clave principal del espacio de nombres que guardó anteriormente.
  4. Agregue el siguiente código al archivo Listener.java. La función principal debe tener un aspecto similar al siguiente código:

    public static void main( String[] args ) throws URISyntaxException
    {
        String CONNECTION_STRING_ENV_VARIABLE_NAME = createConnectionString();
        RelayConnectionStringBuilder connectionParams = new RelayConnectionStringBuilder(CONNECTION_STRING_ENV_VARIABLE_NAME);
        TokenProvider tokenProvider = TokenProvider.createSharedAccessSignatureTokenProvider(
                    connectionParams.getSharedAccessKeyName(),
                    connectionParams.getSharedAccessKey());
        HybridConnectionListener listener = new HybridConnectionListener(new URI(connectionParams.getEndpoint().toString() + connectionParams.getEntityPath()), tokenProvider);
    
        // The "context" object encapsulates both the incoming request and the outgoing response
        listener.setRequestHandler((context) -> {
            String receivedText = "";
            if (context.getRequest().getInputStream() != null) {
                try (BufferedReader reader = new BufferedReader(new InputStreamReader(context.getRequest().getInputStream(), "UTF8"))) {
                    StringBuilder builder = new StringBuilder();
                    String inputLine;
                    while ((inputLine = reader.readLine()) != null) {
                        builder.append(inputLine);
                    }
                    receivedText = builder.toString();
                } catch (IOException e) {
                    System.out.println(e.getMessage());
                }
            }
            System.out.println("requestHandler received " + receivedText);
    
            RelayedHttpListenerResponse response = context.getResponse();
            response.setStatusCode(202);
            response.setStatusDescription("OK");
    
            try {
                response.getOutputStream().write(("Echo: " + receivedText).getBytes());
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            // The context MUST be closed for the message to be sent
            response.close();
        });
    
        listener.openAsync().join();
    
        Scanner in = new Scanner(System.in);
        System.out.println("Press ENTER to terminate this program.");
        in.nextLine();
    
        listener.close();
        in.close();
    }
    
    

    Este es el aspecto que debe tener el archivo Listener.java:

    package com.example.listener;
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.net.URI;
    import java.net.URISyntaxException;
    import java.util.Scanner;
    import com.microsoft.azure.relay.HybridConnectionListener;
    import com.microsoft.azure.relay.RelayConnectionStringBuilder;
    import com.microsoft.azure.relay.RelayedHttpListenerResponse;
    import com.microsoft.azure.relay.TokenProvider;
    
     public class Listener
     {
        public static String createConnectionString(){
            StringBuilder connectionString = new StringBuilder();
            connectionString.append("Endpoint=sb://");
            connectionString.append("{namespace}");
            connectionString.append(".servicebus.windows.net/;SharedAccessKeyName=");
            connectionString.append("{keyrule}");
            connectionString.append(";SharedAccessKey=");
            connectionString.append("{key}");
            connectionString.append(";EntityPath=");
            connectionString.append("{path}");
            return connectionString.toString();
        }
    
        public static void main( String[] args ) throws URISyntaxException
        {
            String CONNECTION_STRING_ENV_VARIABLE_NAME = createConnectionString();
            RelayConnectionStringBuilder connectionParams = new RelayConnectionStringBuilder(CONNECTION_STRING_ENV_VARIABLE_NAME);
            TokenProvider tokenProvider = TokenProvider.createSharedAccessSignatureTokenProvider(
                        connectionParams.getSharedAccessKeyName(),
                        connectionParams.getSharedAccessKey());
            HybridConnectionListener listener = new HybridConnectionListener(new URI(connectionParams.getEndpoint().toString() + connectionParams.getEntityPath()), tokenProvider);
    
            // The "context" object encapsulates both the incoming request and the outgoing response
            listener.setRequestHandler((context) -> {
                String receivedText = "";
                if (context.getRequest().getInputStream() != null) {
                    try (BufferedReader reader = new BufferedReader(new InputStreamReader(context.getRequest().getInputStream(), "UTF8"))) {
                        StringBuilder builder = new StringBuilder();
                        String inputLine;
                        while ((inputLine = reader.readLine()) != null) {
                            builder.append(inputLine);
                        }
                        receivedText = builder.toString();
                    } catch (IOException e) {
                        System.out.println(e.getMessage());
                    }
                }
                System.out.println("requestHandler received " + receivedText);
    
                RelayedHttpListenerResponse response = context.getResponse();
                response.setStatusCode(202);
                response.setStatusDescription("OK");
    
                try {
                    response.getOutputStream().write(("Echo: " + receivedText).getBytes());
                } catch (IOException e) {
                    e.printStackTrace();
                }
    
                // The context MUST be closed for the message to be sent
                response.close();
            });
    
            listener.openAsync().join();
    
            Scanner in = new Scanner(System.in);
            System.out.println("Press ENTER to terminate this program.");
            in.nextLine();
    
            listener.close();
            in.close();
        }
    }
    

Creación de una aplicación de cliente (remitente)

Para enviar mensajes a Relay, puede usar cualquier cliente HTTP o escribir una aplicación de consola en Java.

Creación de una aplicación Java

Si deshabilitó la opción que indica que se requiere la autorización del cliente al crear la retransmisión, puede enviar solicitudes a la dirección URL de conexiones híbridas con un explorador. Para acceder a los puntos de conexión protegidos, debe crear y pasar un token en el encabezado ServiceBusAuthorization, que se muestra aquí.

Esta es una estructura de proyecto Maven sencilla y una clase de Java que muestra el envío de solicitudes a una dirección URL de conexiones híbridas con autorización de cliente mediante la biblioteca de Azure Relay.

Adición del paquete de Relay

Modifique el archivo pom.xml en el paquete de aplicación maven para incluir el paquete de Azure Relay.

<dependency>
	<groupId>com.microsoft.azure</groupId>
	<artifactId>azure-relay</artifactId>
	<version>0.0.6</version>
</dependency>

Ejecute mvn dependency:copy-dependencies -DoutputDirectory=lib en el proyecto mvn para agregar el archivo jar de dependencia en el directorio de biblioteca del proyecto. También importa todas las dependencias del paquete mvn azure-relay. Este paquete proporciona funciones para construir identificadores uniformes de recursos (URI) y tokens de Relay.

Escritura de código para enviar mensajes

  1. Agregue los archivos jar de dependencia al ClassPath del archivo Sender.java.

    javac -cp lib/* src/main/java/com/example/sender/Sender.Java
    
  2. Importe las dependencias en la clase Sender.java.

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    import java.net.HttpURLConnection;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.time.Duration;
    import java.util.Scanner;
    import com.microsoft.azure.relay.RelayConnectionStringBuilder;
    import com.microsoft.azure.relay.TokenProvider;
    
  3. Agregue el siguiente constants a la parte superior del archivo Sender.java a una función java createConnectionString para obtener los detalles de la conexión híbrida.

    public static String createConnectionString(){
        StringBuilder connectionString = new StringBuilder();
        connectionString.append("Endpoint=sb://");
        connectionString.append("{namespace}");
        connectionString.append(".servicebus.windows.net/;SharedAccessKeyName=");
        connectionString.append("{keyrule}");
        connectionString.append(";SharedAccessKey=");
        connectionString.append("{key}");
        connectionString.append(";EntityPath=");
        connectionString.append("{path}");
        return connectionString.toString();
    }
    

    Reemplace los marcadores de posición entre corchetes por los valores que obtuvo al crear la conexión híbrida.

    • namespace: el espacio de nombres de Relay. Asegúrese de utilizar el nombre de espacio de nombres completo; por ejemplo, {namespace}.servicebus.windows.net.
    • path: el nombre de la conexión híbrida.
    • keyrule: nombre de la clave de directivas de acceso compartido, que es RootManageSharedAccessKey de forma predeterminada.
    • nst key: la clave principal del espacio de nombres que guardó anteriormente.
  4. Agregue el siguiente código al archivo Sender.java. La función principal debe tener un aspecto similar al siguiente código.

    public static void main(String[] args) throws IOException {
        String CONNECTION_STRING_ENV_VARIABLE_NAME = createConnectionString();
        if (CONNECTION_STRING_ENV_VARIABLE_NAME == null || CONNECTION_STRING_ENV_VARIABLE_NAME.isEmpty()){
            System.err.println("Connection string is null or empty. Please check your createConnectionString method.");
            return;
        }
        RelayConnectionStringBuilder connectionParams = new RelayConnectionStringBuilder(CONNECTION_STRING_ENV_VARIABLE_NAME);
        TokenProvider tokenProvider = TokenProvider.createSharedAccessSignatureTokenProvider(
                connectionParams.getSharedAccessKeyName(), 
                connectionParams.getSharedAccessKey());
        URL url = buildHttpConnectionURL(connectionParams.getEndpoint().toString(), connectionParams.getEntityPath());
        String tokenString = tokenProvider.getTokenAsync(url.toString(), Duration.ofHours(1)).join().getToken();
        Scanner in = new Scanner(System.in);
        while (true) {
            System.out.println("Press ENTER to terminate this program.");
            String message = in.nextLine();
            int value = System.in.read();
            if (value == '\n' || value == '\r') {
                System.out.println("Terminating the program...");
                break;}
            // Starting a HTTP connection to the listener
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            // Sending an HTTP request to the listener
            // To send a message body, use POST
            conn.setRequestMethod((message == null || message.length() == 0) ? "GET" : "POST");
            conn.setRequestProperty("ServiceBusAuthorization", tokenString);
            conn.setDoOutput(true);
            OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream());
            out.write(message, 0, message.length());
            out.flush();
            out.close();
            // Reading the HTTP response
            String inputLine;
            BufferedReader reader = null;
            StringBuilder responseBuilder = new StringBuilder();
            try {
                InputStream inputStream = conn.getInputStream();
                reader = new BufferedReader(new InputStreamReader(inputStream));
                System.out.println("status code: " + conn.getResponseCode());
                while ((inputLine = reader.readLine()) != null) {
                    responseBuilder.append(inputLine);
                }
                System.out.println("received back " + responseBuilder.toString());
            } catch (IOException e) {
                System.out.println("The listener is offline or could not be reached.");
                break;
            } finally {
                if (reader != null) {
                    reader.close();
                }
            }
        }
        in.close();
    }
    
    static URL buildHttpConnectionURL(String endpoint, String entity) throws MalformedURLException {
        StringBuilder urlBuilder = new StringBuilder(endpoint + entity);
    
        // For HTTP connections, the scheme must be https://
        int schemeIndex = urlBuilder.indexOf("://");
        if (schemeIndex < 0) {
            throw new IllegalArgumentException("Invalid scheme from the given endpoint.");
        }
        urlBuilder.replace(0, schemeIndex, "https");
        return new URL(urlBuilder.toString());
    }
    

    Este es el aspecto que debe tener el archivo Sender.java:

    package com.example.sender;
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    import java.net.HttpURLConnection;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.time.Duration;
    import java.util.Scanner;
    import com.microsoft.azure.relay.RelayConnectionStringBuilder;
    import com.microsoft.azure.relay.TokenProvider;
    
    public class Sender
    {
        public static String createConnectionString(){
            StringBuilder connectionString = new StringBuilder();
            connectionString.append("Endpoint=sb://");
            connectionString.append("{namespace}");
            connectionString.append(".servicebus.windows.net/;SharedAccessKeyName=");
            connectionString.append("{keyrule}");
            connectionString.append(";SharedAccessKey=");
            connectionString.append("{key}");
            connectionString.append(";EntityPath=");
            connectionString.append("{path}");
            return connectionString.toString();
            }
        public static void main(String[] args) throws IOException {
            String CONNECTION_STRING_ENV_VARIABLE_NAME = createConnectionString();
            if (CONNECTION_STRING_ENV_VARIABLE_NAME == null || CONNECTION_STRING_ENV_VARIABLE_NAME.isEmpty()){
                System.err.println("Connection string is null or empty. Please check your createConnectionString method.");
                return;
            }
            RelayConnectionStringBuilder connectionParams = new RelayConnectionStringBuilder(CONNECTION_STRING_ENV_VARIABLE_NAME);
            TokenProvider tokenProvider = TokenProvider.createSharedAccessSignatureTokenProvider(
                    connectionParams.getSharedAccessKeyName(), 
                    connectionParams.getSharedAccessKey());
            URL url = buildHttpConnectionURL(connectionParams.getEndpoint().toString(), connectionParams.getEntityPath());
            String tokenString = tokenProvider.getTokenAsync(url.toString(), Duration.ofHours(1)).join().getToken();
            Scanner in = new Scanner(System.in);
            while (true) {
                System.out.println("Press ENTER to terminate this program.");
                String message = in.nextLine();
                int value = System.in.read();
                if (value == '\n' || value == '\r') {
                    System.out.println("Terminating the program...");
                    break;}
                // Starting a HTTP connection to the listener
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                // Sending an HTTP request to the listener
                // To send a message body, use POST
                conn.setRequestMethod((message == null || message.length() == 0) ? "GET" : "POST");
                conn.setRequestProperty("ServiceBusAuthorization", tokenString);
                conn.setDoOutput(true);
                OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream());
                out.write(message, 0, message.length());
                out.flush();
                out.close();
                // Reading the HTTP response
                String inputLine;
                BufferedReader reader = null;
                StringBuilder responseBuilder = new StringBuilder();
                try {
                    InputStream inputStream = conn.getInputStream();
                    reader = new BufferedReader(new InputStreamReader(inputStream));
                    System.out.println("status code: " + conn.getResponseCode());
                    while ((inputLine = reader.readLine()) != null) {
                        responseBuilder.append(inputLine);
                    }
                    System.out.println("received back " + responseBuilder.toString());
                } catch (IOException e) {
                    System.out.println("The listener is offline or could not be reached.");
                    break;
                } finally {
                    if (reader != null) {
                        reader.close();
                    }
                }
            }
            in.close();
        }
    
        static URL buildHttpConnectionURL(String endpoint, String entity) throws MalformedURLException {
            StringBuilder urlBuilder = new StringBuilder(endpoint + entity);
    
            // For HTTP connections, the scheme must be https://
            int schemeIndex = urlBuilder.indexOf("://");
            if (schemeIndex < 0) {
                throw new IllegalArgumentException("Invalid scheme from the given endpoint.");
            }
            urlBuilder.replace(0, schemeIndex, "https");
            return new URL(urlBuilder.toString());
        }
    }
    

Nota:

El código de ejemplo de este artículo usa una cadena de conexión para autenticarse en un espacio de nombres de Azure Relay para simplificar el tutorial. Se recomienda usar la autenticación de Microsoft Entra ID en entornos de producción, en lugar de usar cadenas de conexión o firmas de acceso compartido, lo que puede verse más fácilmente comprometido. Para obtener información detallada y código de ejemplo para usar la autenticación de Id. de Entra de Microsoft, consulte Autenticación de una identidad administrada con Microsoft Entra ID para acceder a recursos de Azure Relay y Autenticar una identidad administrada con el identificador de Microsoft Entra para acceder a los recursos de Azure Relay.

Ejecución de las aplicaciones

  1. Ejecute la aplicación de servidor: desde un símbolo del sistema de Java o un tipo de aplicación java -cp <jar_dependency_path> com.example.listener.Listener.java.
  2. Ejecute la aplicación cliente: desde un símbolo del sistema de Java o un tipo de aplicación java -cp <jar_dependency_path> com.example.sender.Sender.java y escriba texto.
  3. Asegúrese de que la consola de aplicación de servidor genera el texto que escribió en la aplicación de cliente.

Enhorabuena, ha creado una aplicación de conexiones híbridas de extremo a extremo mediante Java.

Pasos siguientes

En esta guía de inicio rápido, ha creado aplicaciones de cliente y servidor de Java que han usado HTTP para enviar y recibir mensajes. La característica Conexiones híbridas de Azure Relay también admite el uso de WebSockets para enviar y recibir mensajes. Para aprender a usar WebSockets con Conexiones híbridas de Azure Relay, consulte la Guía de inicio rápido de WebSockets.

En esta guía de inicio rápido, ha usado Java para crear aplicaciones cliente y servidor. Para aprender a escribir aplicaciones cliente y servidor con .NET Framework, consulte la Guía de inicio rápido de WebSockets para .NET o la Guía de inicio rápido de HTTP para .NET.