Observação:
- Este tutorial requer acesso ao Oracle Cloud. Para se inscrever em uma conta gratuita, consulte Conceitos básicos do Oracle Cloud Infrastructure Free Tier.
- Ele usa valores de exemplo para credenciais, tenancy e compartimentos do Oracle Cloud Infrastructure. Ao concluir seu laboratório, substitua esses valores por valores específicos do seu ambiente de nuvem.
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
-
Configure chaves de API do OCI para o usuário com base nas quais APIs REST se conectarão à tenancy do OCI.
-
Crie um caso de uso para fazer download ou upload de um arquivo binário para o OCI Object Storage usando APIs REST.
-
Configure um shell e um aplicativo Java, escreva o código apropriado para chamar e exibir APIs REST do OCI.
Pré-requisitos
-
Acesso ao OCI e às políticas permitidas no Oracle Cloud Infrastructure Identity and Access Management (OCI IAM). O usuário deve ter acesso aos recursos correspondentes que deseja criar ou atualizar usando APIs REST.
-
Conhecimento de scripts de shell e desenvolvimento de aplicativos Java.
-
Compreensão básica da metodologia ágil de desenvolvimento de software.
Tarefa 1: Configurar Chaves de API do Oracle Cloud Infrastructure
-
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.
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.
-
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.
-
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.
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
-
Vá para o sistema de arquivos e crie um arquivo de shell. Para este exemplo, arquivo nomeado como
PUT_OBJECT_REST_API.sh
. -
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\""
-
-
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.
-
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
-
Vá para o sistema de arquivos e crie um arquivo java. Para este exemplo, arquivo nomeado como
PUT_OBJECT_REST_API.java
. -
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); } }
-
-
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.
-
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.
Links Relacionados
Agradecimentos
- Autor - Lovelesh Saxena (Arquiteto Principal de Engenharia de Software)
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.
Manage Oracle Cloud Infrastructure REST APIs Programmatically using Shell and Java Code
G12004-01
July 2024