Nota
- Questa esercitazione richiede l'accesso a Oracle Cloud. Per iscriverti a un account gratuito, consulta Inizia a utilizzare Oracle Cloud Infrastructure Free Tier.
- Utilizza valori di esempio per le credenziali, la tenancy e i compartimenti di Oracle Cloud Infrastructure. Al termine del laboratorio, sostituisci questi valori con quelli specifici del tuo ambiente cloud.
Gestisci le API REST di Oracle Cloud Infrastructure a livello di programmazione utilizzando Shell e codice Java
Introduzione
Oracle Cloud Infrastructure (OCI) fornisce ai clienti un'infrastruttura cloud per ospitare le loro applicazioni mission critical nel cloud. OCI offre anche ai clienti i modi per accedere ai servizi OCI tramite la console o tramite le API. Per la connessione tramite le API, i clienti possono utilizzare gli SDK in base al linguaggio di programmazione scelto, ad esempio Java, Python o Ruby. Sono tuttavia pochi i casi in cui il cliente non può utilizzare SDK e non può utilizzare alcun linguaggio di programmazione, ma desidera invece connettersi tramite API direttamente da uno strumento, un database o un'applicazione di terze parti in cui non può installare SDK. Ecco perché l'uso delle API REST è utile. I clienti possono sfruttare le API REST fornite da OCI per quasi tutti i servizi e utilizzarle direttamente nei propri strumenti semplicemente aggiornando gli endpoint e occupandosi dell'autorizzazione e dell'autenticazione.
Oggi, ogni organizzazione vuole sfruttare la potenza delle API REST nelle proprie applicazioni e creare un'offerta innovativa per i propri clienti senza la necessità di installare e gestire alcun SDK.
In questo tutorial, discuteremo e capiremo come OCI può aiutare le organizzazioni di tutto il mondo a sfruttare la potenza delle API REST con OCI. In questa esercitazione verrà illustrato un esempio di API REST basate su script shell e codice Java.
Obiettivi
-
Impostare le chiavi API OCI per l'utente in base alle API REST che si connetteranno alla tenancy OCI.
-
Crea un caso d'uso per scaricare o caricare un file binario in OCI Object Storage utilizzando le API REST.
-
Impostare una shell e un'applicazione Java, scrivere il codice appropriato per chiamare e visualizzare le API REST OCI.
Prerequisiti
-
Accesso a OCI e ai criteri consentiti in Oracle Cloud Infrastructure Identity and Access Management (IAM OCI). L'utente deve avere accesso alle risorse corrispondenti che desidera creare o aggiornare mediante le API REST.
-
Conoscenza di shell scripting e sviluppo di applicazioni Java.
-
Conoscenza di base della metodologia agile di sviluppo del software.
Task 1: impostare le chiavi API di Oracle Cloud Infrastructure
-
Eseguire il login alla tenancy OCI con l'account di servizio o l'utente amministratore e andare alle impostazioni utente.
Oppure
Andare all'utente dalla console IAM OCI. Assicurarsi che l'utente disponga di tutti gli accessi necessari per creare e aggiornare l'infrastruttura su OCI.
-
Passare alla sezione Risorse, fare clic su Chiavi API e su Aggiungi chiave API. Selezionare questa opzione per scaricare le nuove chiavi pubbliche e private, caricare la chiave pubblica o incollare la chiave pubblica.
-
Salvare le chiavi in una posizione comoda e salvare il file di configurazione come mostrato nella pagina seguente. Durante la connessione alla tenancy mediante le API REST, saranno necessari questo file di configurazione e questa chiave privata.
Nota:
-
Per connettersi all'area geografica e alla tenancy OCI, sarà necessario lo stesso
configuration parameters
. Sostituirete i parametri nel codice Java e negli script shell di conseguenza mentre ci immergiamo più a fondo nell'esercitazione. -
Per chiamare i servizi OCI dalle istanze di OCI Compute, OCI offre un modo più sicuro utilizzando i principal delle istanze. Evita di utilizzare le chiavi API degli utenti come best practice. Per ulteriori informazioni, vedere Chiamata di servizi da un'istanza.
-
Task 2: creare ed eseguire uno script shell per caricare o inserire un file binario da OCI Object Storage utilizzando le API REST
-
Passare al file system e creare un file shell. In questo esempio, file denominato
PUT_OBJECT_REST_API.sh
. -
Aprire il file con l'editor scelto e incollare il codice seguente nel file della 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\""
-
-
Ora abbiamo tutto il codice incollato nel file shell, lavoriamo per aggiornare i valori richiesti e capire le loro funzionalità.
tenancy_ocid="ocid1.tenancy.oc1..aaaaaaaackopa" ... fingerprint="72:d4:6c:f8:89"
Tutti questi valori sono responsabili di stabilire una connessione sicura con la tenancy OCI. Recuperare questi valori dal file di configurazione.
rest_api="/n/$namespace/b/$bucket/o/$object" host="objectstorage.us-ashburn-1.oraclecloud.com"
Questo è l'endpoint rest_api e host, prepararlo in base alle proprie esigenze in quanto ciò cambierà per ogni servizio. L'esempio mostrato qui è l'endpoint per il servizio di storage degli oggetti OCI per l'area 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"
Qui abbiamo creato le intestazioni per l'API REST insieme al tipo di contenuto e ad altri parametri obbligatori. Si noti che qui sono disponibili definizioni per method_type, data e intestazione host in quanto per la chiamata successiva è necessario impostare un'intestazione dettagliata.
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" ...
Infine, stiamo creando la stringa di firma, quindi effettuando la chiamata API REST utilizzando curl. Si noti che OCI ha bisogno che le chiamate API siano firmate ed è per questo che lo stiamo facendo qui.
-
Dopo aver aggiornato i valori in base alla configurazione, esegui lo script della shell, dovresti vedere lo script che esegue tutte le operazioni valide e il file viene sottoposto a PUSH nello storage degli oggetti OCI.
Nota:
-
Assicurarsi di aver aggiornato l'autorizzazione di esecuzione del file shell modificandola in 755 o gestirla personalmente.
-
Puoi anche farlo su Windows utilizzando powershell, o utilizzare lo stesso script su Windows installando un WSL (Windows Subsystem for Linux) come Ubuntu ed eseguirlo da Ubuntu WSL su Windows. Per ulteriori informazioni, vedere Sottosistema Windows per Linux.
-
Task 3: creare ed eseguire il codice Java per caricare o inserire un file binario dallo storage degli oggetti OCI utilizzando le API REST
-
Passare al file system e creare un file java. In questo esempio, file denominato
PUT_OBJECT_REST_API.java
. -
Aprire il file con l'editor scelto e incollare il codice seguente nel file della 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); } }
-
-
Ora abbiamo tutto il codice incollato nel file java, lavoriamo per aggiornare i valori richiesti e capire le loro funzionalità.
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
Tutti questi valori sono responsabili di stabilire una connessione sicura con la tenancy OCI. Recuperare questi valori dal file di configurazione.
String targetUri = "https://objectstorage." + region + ".oraclecloud.com/n/" + namespace + "/b/" + bucketName + "/o/" + fileName; HttpRequest request = buildRequest(targetUri, filePath, privateKey);
Si tratta dell'endpoint rest_api e dell'host, prepararlo in base alle proprie esigenze in quanto ciò cambierà per ogni servizio. L'esempio mostrato qui è l'endpoint per il servizio di storage degli oggetti OCI per l'area ashburn.
private static HttpRequest buildRequest
Le intestazioni per l'API REST sono state create insieme al tipo di contenuto e ad altri parametri obbligatori. Si noti che qui abbiamo definizioni per method_type, data e intestazioni host come per la chiamata post abbiamo bisogno di una serie di intestazioni dettagliate.
private static String signRequest
Infine, stiamo creando la stringa di firma e quindi effettuando la chiamata all'API REST. Si noti che OCI ha bisogno che le chiamate API siano firmate ed è per questo che lo stiamo facendo qui.
-
Dopo aver aggiornato i valori in base alla configurazione, esegui il codice java, dovresti vedere lo script che esegue tutte le operazioni valide e il file viene sottoposto a push nello storage degli oggetti OCI.
Nota: assicurarsi di avere installato Java con tutti i package richiesti in base alle esigenze del codice.
Collegamenti correlati
Conferme
- Autore - Lovelesh Saxena (architetto principale di ingegneria del software)
Altre risorse di apprendimento
Esplora altri laboratori su docs.oracle.com/learn o accedi a più contenuti gratuiti sulla formazione su Oracle Learning YouTube channel. Inoltre, visita education.oracle.com/learning-explorer per diventare un Oracle Learning Explorer.
Per la documentazione del prodotto, visita l'Oracle Help Center.
Manage Oracle Cloud Infrastructure REST APIs Programmatically using Shell and Java Code
G12001-01
July 2024