Note:

Gestione las API de REST de Oracle Cloud Infrastructure mediante programación, con shell y código Java

Introducción

Oracle Cloud Infrastructure (OCI) proporciona infraestructura en la nube a los clientes para alojar sus aplicaciones esenciales en la nube. OCI también proporciona al cliente las formas de acceder a los servicios de OCI a través de la consola o mediante API. Para conectarse a través de API, el cliente puede utilizar SDK basados en el lenguaje de programación de su elección, como Java, Python o Ruby. Pero son pocos los casos en los que el cliente no puede utilizar SDK y no puede utilizar ningún lenguaje de programación, sino que desea conectarse a través de API directamente desde una herramienta, base de datos o aplicación de terceros donde no pueden instalar SDK. Aquí viene el uso de API de REST es útil. Los clientes pueden aprovechar las API de REST proporcionadas por OCI para casi todos los servicios y utilizarlas en sus herramientas directamente actualizando los puntos finales y cuidando la autorización y la autenticación.

Hoy en día, todas las organizaciones desean aprovechar la potencia de las API de REST en sus aplicaciones y crear una oferta innovadora para sus clientes sin necesidad de instalar y gestionar ningún SDK.

En este tutorial, analizaremos y comprenderemos cómo OCI puede ayudar a las organizaciones de todo el mundo a aprovechar el poder de las API de REST con OCI. En este tutorial, mostraremos un ejemplo de API de REST basadas en scripts de shell y código Java.

Objetivos

Requisitos

Tarea 1: Configuración de claves de API de Oracle Cloud Infrastructure

  1. Conéctese al arrendamiento de OCI con la cuenta de servicio o el usuario administrador y vaya a la configuración de usuario.

    Abrir configuración de usuario

    O bien:

    Vaya al usuario desde la consola de OCI IAM. Asegúrese de que el usuario tiene todo el acceso necesario para crear y actualizar la infraestructura en OCI.

  2. Vaya a la sección Recursos, haga clic en Claves de API y Agregar clave de API. Seleccione esta opción para descargar las nuevas claves públicas y privadas, cargar la clave pública o pegar la clave pública.

    Agregar clave de API

  3. Guarde las claves en una ubicación conveniente y guarde el archivo de configuración como se muestra en la siguiente página. Necesitará este archivo de configuración y esta clave privada al conectarse a su arrendamiento mediante las API de REST.

    Guardar archivo de configuración

    Nota:

    • Necesitará el mismo configuration parameters para conectarse a su región y arrendamiento de OCI. Sustituirá los parámetros en los scripts de shell y código Java según corresponda a medida que profundicemos en el tutorial.

    • Para llamar a los servicios de OCI desde instancias de OCI Compute, OCI proporciona una forma más segura mediante principales de instancia. Evite utilizar claves de API de usuario como mejores prácticas. Para obtener más información, consulte Llamada a servicios desde una instancia.

Tarea 2: Creación y ejecución de un script de shell para cargar o colocar un archivo binario desde OCI Object Storage mediante API de REST

  1. Vaya al sistema de archivos y cree un archivo de shell. Para este ejemplo, archivo denominado PUT_OBJECT_REST_API.sh.

  2. Abra el archivo con el editor que desee y pegue el siguiente código en el archivo de shell.

    • PUT_OBJECT_REST_API.sh:

      #!/bin/bash
      
      ########################## Fill these in with your values ##########################
      #OCID of the tenancy calls are being made in to
      tenancy_ocid="ocid1.tenancy.oc1..aaaaaaaackopa"
      
      # namespace of the tenancy
      namespace="ocitenancyname"
      
      # OCID of the user making the rest call
      user_ocid="ocid1.user.oc1..aaaaaaaafelqsoffcjh"
      
      # path to the private PEM format key for this user
      privateKeyPath="/home/lovelesh/.oci/oci_api_key.pem"
      
      # fingerprint of the private key for this user
      fingerprint="72:d4:6c:f8:89"
      
      #bucket name for uplaod/ put
      bucket="ocibucketname"
      
      #file name for upload/ put
      object="test_pdf.pdf"
      
      # The REST api you want to call, with any required paramters.
      rest_api="/n/$namespace/b/$bucket/o/$object"
      
      # The host you want to make the call against
      host="objectstorage.us-ashburn-1.oraclecloud.com"
      
      # the file containing the data you want to POST to the rest endpoint
      body="/home/lovelesh/.oci/test_pdf.pdf"
      ####################################################################################
      
      # extra headers required for a POST/PUT request
      method="put"
      content_type="application/octet-stream"
      body_arg=(--data-binary @${body})
      content_sha256="$(openssl dgst -binary -sha256 < $body | openssl enc -e -base64)";
      content_sha256_header="x-content-sha256: $content_sha256"
      content_length="$(wc -c < $body | xargs)";
      content_length_header="content-length: $content_length"
      headers="(request-target) date host"
      # add on the extra fields required for a POST/PUT
      headers=$headers" x-content-sha256 content-type content-length"
      content_type_header="content-type: $content_type";
      
      date=`date -u "+%a, %d %h %Y %H:%M:%S GMT"`
      date_header="date: $date"
      host_header="host: $host"
      request_target="(request-target): $method $rest_api"
      
      # note the order of items. The order in the signing_string matches the order in the headers, including the extra POST fields
      signing_string="$request_target\n$date_header\n$host_header"
      # add on the extra fields required for a POST/PUT
      signing_string="$signing_string\n$content_sha256_header\n$content_type_header\n$content_length_header"
      
      
      
      signature=`printf '%b' "$signing_string" | openssl dgst -sha256 -sign $privateKeyPath | openssl enc -e -base64 | tr -d '\n'`
      
      set -x
      curl -v -X $(echo $method | tr [:lower:] [:upper:]) --data-binary "@$body" -sS https://$host$rest_api -H "date: $date" -H "x-content-sha256: $content_sha256" -H "content-type: $content_type" -H "content-length: $content_length" -H "Authorization: Signature version=\"1\",keyId=\"$tenancy_ocid/$user_ocid/$fingerprint\",algorithm=\"rsa-sha256\",headers=\"$headers\",signature=\"$signature\""
      
  3. Ahora tenemos todo el código pegado en el archivo shell, vamos a trabajar en la actualización de los valores necesarios y entender su funcionalidad.

    tenancy_ocid="ocid1.tenancy.oc1..aaaaaaaackopa"
    ...
    fingerprint="72:d4:6c:f8:89"
    

    Todos estos valores son responsables de establecer una conexión segura con su arrendamiento de OCI. Obtenga estos valores del archivo de configuración.

    rest_api="/n/$namespace/b/$bucket/o/$object"
    host="objectstorage.us-ashburn-1.oraclecloud.com"
    

    Este es el punto final rest_api y host, prepárelo según sus necesidades, ya que esto cambiará para todos y cada uno de los servicios. El ejemplo que se muestra aquí es el punto final para el servicio OCI Object Storage para la región de ashburn.

    headers=$headers" x-content-sha256 content-type content-length"
    content_type_header="content-type: $content_type";
    date=`date -u "+%a, %d %h %Y %H:%M:%S GMT"`
    date_header="date: $date"
    host_header="host: $host"
    request_target="(request-target): $method $rest_api"
    

    Aquí hemos creado las cabeceras para la API de REST junto con el tipo de contenido y otros parámetros necesarios. Tenga en cuenta que aquí tenemos definiciones para method_type, fecha y cabeceras de host, ya que para la llamada posterior necesitamos un juego de cabeceras detallado.

    signing_string="$signing_string\n$content_sha256_header\n$content_type_header\n$content_length_header"
    curl -v -X $(echo $method | tr [:lower:] [:upper:]) --data-binary "@$body" ...
    

    Por último, estamos creando la cadena de firma y, a continuación, realizando la llamada a la API de REST mediante curl. Tenga en cuenta que OCI necesita que se firmen las llamadas de API, y por eso lo estamos haciendo aquí.

  4. Después de actualizar los valores según la configuración, ejecute el script de shell, debe ver que el script se ejecuta correctamente y el archivo se transfiere a OCI Object Storage.

    Nota:

    • Asegúrese de haber actualizado el permiso de archivo de shell a ejecutable cambiando a 755 o gestionarlo usted mismo.

    • También puedes hacer esto en Windows usando powerhell, o usar el mismo script en Windows instalando un WSL (Subsistema Windows para Linux) como Ubuntu y ejecutarlo desde Ubuntu WSL en Windows. Para obtener más información, consulte Windows Subsystem for Linux.

Tarea 3: Creación y ejecución de código Java para cargar o colocar un archivo binario desde OCI Object Storage mediante API de REST

  1. Vaya al sistema de archivos y cree un archivo java. Para este ejemplo, archivo denominado PUT_OBJECT_REST_API.java.

  2. Abra el archivo con el editor que desee y pegue el siguiente código en el archivo de shell.

    • PUT_OBJECT_REST_API.java:

      import java.io.IOException;
      import java.net.URI;
      import java.net.http.HttpClient;
      import java.net.http.HttpRequest;
      import java.net.http.HttpResponse;
      import java.nio.file.Files;
      import java.nio.file.Paths;
      import java.security.KeyFactory;
      import java.security.NoSuchAlgorithmException;
      import java.security.PrivateKey;
      import java.security.Signature;
      import java.security.spec.InvalidKeySpecException;
      import java.security.spec.PKCS8EncodedKeySpec;
      import java.time.ZoneOffset;
      import java.time.ZonedDateTime;
      import java.time.format.DateTimeFormatter;
      import java.util.Base64;
      
      // NOTE - Feel free to remove logging as needed. Currently logs the signing string, host, date, and response. 
      
      public class PUT_OBJECT_REST_API {
      
          private static final String apiKeyFilePath = "C:\\Users\\User1\\Folder\\privatekey.pem"
          private static final String tenancyId = "ocid1.tenancy.oc1..aaaaaaaackopa27emaz4uteg4q7"; // OCI Tenancy ID
          private static final String userId = "ocid1.user.oc1..aaaaaaaafelqsoffcjq"; // OCI User ID
          private static final String keyFingerprint = "72:d4:6c:f8:89:74:aa"; // OCI fingerprint
          private static final String region = "us-ashburn-1"; // OCI Region
          private static final String namespace = "ocitenancyname"; // OCI bucket namespace
          private static final String bucketName = "ocibucketname"; // OCI bucket NAME
      
          public static void main(String[] args) {
              try {
                  String filePath = "D:\\file\\location\\test_pdf.pdf"; //args.length > 0 ? args[0] : ""; // File to upload (path)
                  PrivateKey privateKey = loadPrivateKey(apiKeyFilePath);
                  String fileName = Paths.get(filePath).getFileName().toString();
                  String targetUri = "https://objectstorage." + region + ".oraclecloud.com/n/" + namespace + "/b/" + bucketName + "/o/" + fileName;
                  HttpRequest request = buildRequest(targetUri, filePath, privateKey);
                  HttpClient client = HttpClient.newHttpClient();
                  HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
      
                  System.out.println("Response status code: " + response.statusCode());
                  System.out.println("Response body: " + response.body());
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
      
          private static PrivateKey loadPrivateKey(String filePath) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
              String key = new String(Files.readAllBytes(Paths.get(filePath)))
                  .replace("-----BEGIN PRIVATE KEY-----", "")
                  .replace("-----END PRIVATE KEY-----", "")
                  .replaceAll("\\s+", ""); // Remove all whitespace
      
              byte[] decodedKey = Base64.getDecoder().decode(key);
              PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(decodedKey);
              KeyFactory kf = KeyFactory.getInstance("RSA");
              return kf.generatePrivate(spec);
          }
      
          private static HttpRequest buildRequest(String targetUri, String filePath, PrivateKey privateKey) throws Exception {
              String method = "put";
              String path = "/n/" + namespace + "/b/" + bucketName + "/o/" + Paths.get(filePath).getFileName();
              String host = "objectstorage." + region + ".oraclecloud.com";
              String date = DateTimeFormatter.RFC_1123_DATE_TIME.format(ZonedDateTime.now(ZoneOffset.UTC));
              byte[] fileContent = Files.readAllBytes(Paths.get(filePath)); // Read file content as byte array
      
              String signingString = "(request-target): " + method.toLowerCase() + " " + path + "\n" +
                                  "host: " + host + "\n" +
                                  "date: " + date;
              System.out.println("Signing String: \n" + signingString);
      
              String signature = signRequest(privateKey, signingString);
              String authorizationHeader = "Signature version=\"1\",headers=\"(request-target) host date\",keyId=\"" +
                  tenancyId + "/" + userId + "/" + keyFingerprint + "\",algorithm=\"rsa-sha256\",signature=\"" + signature + "\"";
      
              return HttpRequest.newBuilder()
                      .uri(URI.create(targetUri))
                      .header("Content-Type", "application/octet-stream")
                      .header("date", date)
                      .header("Authorization", authorizationHeader)
                      .PUT(HttpRequest.BodyPublishers.ofByteArray(fileContent))
                      .build();
          }
      
          private static String signRequest(PrivateKey privateKey, String dataToSign) throws Exception {
              Signature signatureInstance = Signature.getInstance("SHA256withRSA");
              signatureInstance.initSign(privateKey);
              signatureInstance.update(dataToSign.getBytes());
              byte[] signature = signatureInstance.sign();
              return Base64.getEncoder().encodeToString(signature);
          }
      }
      
  3. Ahora tenemos todo el código pegado en el archivo java, vamos a trabajar en la actualización de los valores necesarios y entender su funcionalidad.

    private static final String apiKeyFilePath = "C:\\Users\\User1\\Folder\\privatekey.pem"
    private static final String tenancyId = "ocid1.tenancy.oc1..aaaaaaaackopa27emaz4uteg4q7"; // OCI Tenancy ID
    private static final String userId = "ocid1.user.oc1..aaaaaaaafelqsoffcjq"; // OCI User ID
    private static final String keyFingerprint = "72:d4:6c:f8:89:74:aa"; // OCI fingerprint
    private static final String region = "us-ashburn-1"; // OCI Region
    private static final String namespace = "ocitenancyname"; // OCI bucket namespace
    private static final String bucketName = "ocibucketname"; // OCI bucket NAME
    

    Todos estos valores son responsables de establecer una conexión segura con su arrendamiento de OCI. Obtenga estos valores del archivo de configuración.

    String targetUri = "https://objectstorage." + region + ".oraclecloud.com/n/" + namespace + "/b/" + bucketName + "/o/" + fileName;
    HttpRequest request = buildRequest(targetUri, filePath, privateKey);
    

    Este es el punto final de host y rest_api. Prepárelo según sus necesidades, ya que cambiará para todos y cada uno de los servicios. El ejemplo que se muestra aquí es el punto final para el servicio OCI Object Storage para la región de ashburn.

    private static HttpRequest buildRequest
    

    Hemos creado las cabeceras para la API de REST junto con el tipo de contenido y otros parámetros necesarios. Tenga en cuenta que aquí tenemos definiciones para method_type, fecha y cabeceras de host, ya que para la llamada posterior necesitamos un juego de cabeceras detallado.

    private static String signRequest
    

    Por último, estamos creando la cadena de firma y, a continuación, realizando la llamada a la API de REST. Tenga en cuenta que OCI necesita que se firmen las llamadas de API, y por eso lo estamos haciendo aquí.

  4. Después de actualizar los valores según la configuración, ejecute el código java, verá que el script se ejecuta correctamente y que el archivo se transfiere a OCI Object Storage.

    Nota: Asegúrese de que tiene Java instalado con todos los paquetes necesarios según lo necesite el código.

Agradecimientos

Más recursos de aprendizaje

Explore otros laboratorios en docs.oracle.com/learn o acceda a más contenido de aprendizaje gratuito en el canal YouTube de Oracle Learning. Además, visite education.oracle.com/learning-explorer para convertirse en Oracle Learning Explorer.

Para obtener documentación sobre el producto, visite Oracle Help Center.