Observação:

Gerenciar APIs REST do Oracle Cloud Infrastructure de Forma Programática usando Shell e Código Java

Introdução

A Oracle Cloud Infrastructure (OCI) fornece infraestrutura de nuvem aos clientes para hospedar seus aplicativos de missão crítica na nuvem. A OCI também fornece ao cliente as maneiras de acessar os serviços da OCI por meio da console ou de APIs. Para estabelecer conexão por meio de APIs, o cliente pode usar SDKs com base na linguagem de programação de sua escolha, como Java, Python ou Ruby. Mas são poucos os casos em que o cliente não pode usar o SDK e não pode usar nenhuma linguagem de programação, mas deseja se conectar por meio de APIs diretamente de uma ferramenta, banco de dados ou aplicativo de terceiros em que não pode instalar o SDK. Aqui vem o uso de APIs REST à mão. Os clientes podem aproveitar as APIs REST fornecidas pela OCI para quase todos os serviços e usá-las em suas ferramentas diretamente, apenas atualizando os pontos finais e cuidando da autorização e autenticação.

Atualmente, todas as organizações querem aproveitar o poder das APIs REST em seus aplicativos e criar uma oferta inovadora para seus clientes sem a necessidade de instalar e gerenciar qualquer SDK.

Neste tutorial, discutiremos e entenderemos como a OCI pode ajudar as organizações em todo o mundo a aproveitar o poder das APIs REST com a OCI. Neste tutorial, demonstraremos um exemplo de APIs REST com base em scripts de shell e código Java.

Objetivos

Pré-requisitos

Tarefa 1: Configurar Chaves de API do Oracle Cloud Infrastructure

  1. Faça log-in na tenancy do OCI com a conta de serviço ou o usuário administrador e vá para as Definições do usuário.

    Abrir Definições do Usuário

    Ou

    Vá para o usuário na console do OCI IAM. Certifique-se de que o usuário tenha todo o acesso necessário para criar e atualizar a infraestrutura no OCI.

  2. Vá para a seção Recursos, clique em Chaves de API e Adicionar Chave de API. Selecione para fazer download das novas chaves pública e privada, fazer upload da chave pública ou colar a chave pública.

    Adicionar Chave de API

  3. Salve as chaves em um local conveniente e salve o arquivo de configuração conforme mostrado na página a seguir. Você precisará desse arquivo de configuração e da chave privada ao estabelecer conexão com sua tenancy usando APIs REST.

    Salvar Arquivo de Configuração

    Observação:

    • Você precisará do mesmo configuration parameters para estabelecer conexão com sua região e tenancy do OCI. Você substituirá os parâmetros no código Java e nos scripts shell de acordo à medida que nos aprofundarmos no tutorial.

    • Para chamar serviços do OCI por meio de instâncias do OCI Compute, o OCI fornece uma maneira mais segura de usar controladores de instâncias. Evite usar chaves de API do usuário como melhores práticas. Para obter mais informações, consulte Chamando os Serviços em uma Instância.

Tarefa 2: Criar e Executar Script de Shell para Fazer Upload ou Colocar um Arquivo Binário do OCI Object Storage usando APIs REST

  1. Vá para o sistema de arquivos e crie um arquivo de shell. Para este exemplo, arquivo nomeado como PUT_OBJECT_REST_API.sh.

  2. Abra o arquivo com sua escolha de editor e cole o código a seguir no arquivo 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. Agora temos todo o código colado no arquivo shell, vamos trabalhar na atualização dos valores necessários e entender sua funcionalidade.

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

    Todos esses valores são responsáveis por estabelecer uma conexão segura com sua tenancy do OCI. Obtenha esses valores no arquivo de configuração.

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

    Esse é o ponto final rest_api e host, prepare-o de acordo com seu requisito, pois isso será alterado para cada serviço. O exemplo mostrado aqui é o ponto final do OCI Object Storage Service para a região 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"
    

    Aqui criamos os cabeçalhos da API REST, juntamente com o tipo de conteúdo e outros parâmetros obrigatórios. Observe que aqui temos definições para method_type, data e cabeçalhos de host, pois para pós-chamada precisamos de um conjunto de cabeçalhos detalhado.

    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 fim, estamos criando a string de assinatura e, em seguida, fazendo a chamada da API REST usando curl. Observe que o OCI precisa que as chamadas de API sejam assinadas e é por isso que estamos fazendo isso aqui.

  4. Depois de atualizar os valores de acordo com sua configuração, execute o script shell, você deverá ver o script executando tudo de bom e o arquivo será enviado ao OCI Object Storage.

    Observação:

    • Certifique-se de ter atualizado a permissão do arquivo shell para executável, alterando-o para 755 ou gerenciá-lo você mesmo.

    • Você também pode fazer isso no Windows usando powerhell, ou usar o mesmo script no Windows instalando um WSL (Windows Subsystem for Linux) como o Ubuntu e executá-lo a partir do Ubuntu WSL no Windows. Para obter mais informações, consulte Subsistema do Windows para Linux.

Tarefa 3: Criar e Executar Código Java para Fazer Upload ou Colocar um Arquivo Binário do OCI Object Storage usando APIs REST

  1. Vá para o sistema de arquivos e crie um arquivo java. Para este exemplo, arquivo nomeado como PUT_OBJECT_REST_API.java.

  2. Abra o arquivo com sua escolha de editor e cole o código a seguir no arquivo 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. Agora temos todo o código colado no arquivo java, vamos trabalhar na atualização dos valores necessários e entender sua funcionalidade.

    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 esses valores são responsáveis por estabelecer uma conexão segura com sua tenancy do OCI. Obtenha esses valores no arquivo de configuração.

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

    Este é o ponto final rest_api e do host, prepare-o de acordo com seu requisito, pois isso será alterado para cada serviço. O exemplo mostrado aqui é o ponto final do OCI Object Storage Service para a região ashburn.

    private static HttpRequest buildRequest
    

    Criamos os cabeçalhos da API REST juntamente com o tipo de conteúdo e outros parâmetros obrigatórios. Observe que aqui temos definições para method_type, data e cabeçalhos do host, pois para chamada posterior precisamos de um conjunto de cabeçalhos detalhado.

    private static String signRequest
    

    Por fim, estamos criando a string de assinatura e, em seguida, fazendo a chamada da API REST. Observe que o OCI precisa que as chamadas de API sejam assinadas e é por isso que estamos fazendo isso aqui.

  4. Depois de atualizar os valores de acordo com sua configuração, execute o código java, você deverá ver o script executando tudo de bom e o arquivo será enviado ao OCI Object Storage.

    Observação: certifique-se de ter o Java instalado com todos os pacotes necessários, conforme necessário para o código.

Agradecimentos

Mais Recursos de Aprendizagem

Explore outros laboratórios em docs.oracle.com/learn ou acesse mais conteúdo de aprendizado gratuito no canal Oracle Learning YouTube. Além disso, visite education.oracle.com/learning-explorer para se tornar um Oracle Learning Explorer.

Para obter a documentação do produto, visite o Oracle Help Center.