주:

셸 및 Java 코드를 사용하여 프로그래밍 방식으로 Oracle Cloud Infrastructure REST API 관리

소개

Oracle Cloud Infrastructure(OCI)는 클라우드에서 미션 크리티컬 애플리케이션을 호스팅할 수 있는 클라우드 인프라를 고객에게 제공합니다. 또한 OCI는 콘솔 또는 API를 통해 OCI 서비스에 액세스하는 방법을 고객에게 제공합니다. API를 통한 연결을 위해 고객은 Java, Python 또는 Ruby와 같이 선택한 프로그래밍 언어를 기반으로 SDK를 사용할 수 있습니다. 그러나 고객이 SDK를 사용할 수 없고 프로그래밍 언어를 사용할 수 없지만 SDK를 설치할 수 없는 도구, 데이터베이스 또는 타사 애플리케이션에서 직접 API를 통해 연결하려는 경우는 거의 없습니다. REST API의 사용이 편리합니다. 고객은 거의 모든 서비스에 대해 OCI에서 제공하는 REST API를 활용할 수 있으며, 엔드포인트를 업데이트하고 권한 부여 및 인증을 처리하여 도구에서 직접 사용할 수 있습니다.

오늘날 모든 조직은 SDK를 설치 및 관리하지 않고도 애플리케이션에서 REST API의 기능을 활용하고 고객을 위한 혁신적인 솔루션을 생성하고자 합니다.

이 사용지침서에서는 OCI가 전 세계 조직이 OCI를 통해 REST API의 기능을 활용할 수 있도록 지원하는 방법에 대해 설명하고 이해합니다. 이 사용지침서에서는 셸 스크립팅 및 Java 코드를 기반으로 하는 REST API의 예를 보여 줍니다.

목표

필요 조건

작업 1: Oracle Cloud Infrastructure API 키 설정

  1. 서비스 계정 또는 관리 사용자로 OCI 테넌시에 로그인하고 사용자 설정으로 이동합니다.

    사용자 설정 열기

    또는

    OCI IAM 콘솔에서 사용자로 이동합니다. 사용자에게 OCI에서 인프라를 생성하고 업데이트하는 데 필요한 모든 액세스 권한이 있는지 확인하십시오.

  2. 리소스 섹션으로 이동하여 API 키API 키 추가를 누릅니다. 새 퍼블릭 및 프라이빗 키를 다운로드하거나, 퍼블릭 키를 업로드하거나, 퍼블릭 키를 붙여넣으려면 선택합니다.

    API 키 추가

  3. 키를 편리한 위치에 저장하고 다음 페이지에 표시된 대로 구성 파일을 저장합니다. REST API를 사용하여 테넌시에 접속할 때 이 구성 파일 및 프라이빗 키가 필요합니다.

    구성 파일 저장

    참고:

    • OCI 리전 및 테넌시에 접속하려면 동일한 configuration parameters가 필요합니다. 자습서를 자세히 살펴보면 이에 따라 Java 코드 및 셸 스크립트의 매개변수를 대체하게 됩니다.

    • OCI 컴퓨팅 인스턴스에서 OCI 서비스를 호출하기 위해 OCI는 인스턴스 주체를 사용하여 보다 안전한 방법을 제공합니다. 사용자 API 키를 모범 사례로 사용하지 마십시오. 자세한 내용은 인스턴스에서 서비스 호출을 참조하십시오.

작업 2: REST API를 사용하여 OCI Object Storage에서 바이너리 파일을 업로드하거나 배치하는 셸 스크립트 생성 및 실행

  1. 파일 시스템으로 이동하여 셸 파일을 만듭니다. 이 예에서는 이름이 PUT_OBJECT_REST_API.sh인 파일입니다.

  2. 원하는 편집기로 파일을 열고 다음 코드를 셸 파일에 붙여 넣습니다.

    • 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. 이제 셸 파일에 붙여 넣은 모든 코드가 있습니다. 필요한 값을 업데이트하고 기능을 이해합니다.

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

    이 모든 값은 OCI 테넌시와의 보안 연결을 담당합니다. 구성 파일에서 이러한 값을 가져옵니다.

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

    이는 rest_apihost 끝점이며 각 서비스에 대해 변경되므로 요구사항에 따라 준비합니다. 여기에 표시된 예는 애슈번 지역용 OCI 오브젝트 스토리지 서비스의 끝점입니다.

    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"
    

    여기서는 콘텐츠 유형 및 기타 필수 매개변수와 함께 REST API에 대한 헤더를 생성했습니다. 여기서는 사후 호출에 대한 method_type, datehost headers에 대한 정의가 있습니다. 자세한 헤더 세트가 필요합니다.

    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" ...
    

    마지막으로 서명 문자열을 생성한 다음 curl을 사용하여 REST API를 호출합니다. OCI에 서명하려면 API 호출이 필요하며, 이것이 바로 여기서 API 호출을 수행하는 이유입니다.

  4. 구성에 따라 값을 업데이트한 후 셸 스크립트를 실행하면 스크립트가 제대로 실행되고 파일이 OCI Object Storage로 푸시됩니다.

    참고:

    • 셸 파일 권한을 755로 변경하거나 직접 관리하여 실행 가능하도록 업데이트했는지 확인합니다.

    • 마찬가지로 powerhell을 사용하여 Windows에서도이 작업을 수행하거나 Ubuntu와 같은 WSL (Windows Subsystem for Linux)을 설치하여 Windows에서 동일한 스크립트를 사용하여 Windows의 Ubuntu WSL에서 실행할 수 있습니다. 자세한 내용은 Windows Subsystem for Linux을 참조하십시오.

작업 3: REST API를 사용하여 OCI Object Storage에서 바이너리 파일을 업로드하거나 배치하는 Java 코드 생성 및 실행

  1. 파일 시스템으로 이동하여 Java 파일을 생성합니다. 이 예에서는 이름이 PUT_OBJECT_REST_API.java인 파일입니다.

  2. 원하는 편집기로 파일을 열고 다음 코드를 셸 파일에 붙여 넣습니다.

    • 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. 이제 java 파일에 붙여 넣은 모든 코드가 있습니다. 필요한 값을 업데이트하고 기능을 이해하도록 하겠습니다.

    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
    

    이 모든 값은 OCI 테넌시와의 보안 연결을 담당합니다. 구성 파일에서 이러한 값을 가져옵니다.

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

    이는 rest_api 및 호스트 끝점이며 각 서비스에 대해 변경되므로 요구사항에 따라 준비합니다. 여기에 표시된 예는 애슈번 지역용 OCI 오브젝트 스토리지 서비스의 끝점입니다.

    private static HttpRequest buildRequest
    

    콘텐츠 유형 및 기타 필수 매개변수와 함께 REST API에 대한 헤더를 생성했습니다. 여기서는 사후 호출에 대한 method_type, 날짜 및 호스트 헤더에 대한 정의가 있으며 자세한 헤더 세트가 필요합니다.

    private static String signRequest
    

    마지막으로 서명 문자열을 생성한 다음 REST API를 호출합니다. OCI에 서명하려면 API 호출이 필요하며, 그래서 여기서 API 호출을 수행합니다.

  4. 구성에 따라 값을 업데이트한 후 java 코드를 실행하면 스크립트가 제대로 실행되고 파일이 OCI Object Storage로 푸시됩니다.

    주: 코드에 필요한 모든 필수 패키지가 포함된 Java가 설치되어 있는지 확인하십시오.

확인

추가 학습 자원

docs.oracle.com/learn에서 다른 실습을 탐색하거나 Oracle Learning YouTube 채널에서 더 많은 무료 학습 콘텐츠에 액세스하세요. 또한 Oracle Learning Explorer가 되려면 education.oracle.com/learning-explorer을 방문하십시오.

제품 설명서는 Oracle Help Center를 참조하십시오.