Oracle Cloud Infrastructureドキュメント

概念

このトピックでは、Oracle Cloud Infrastructure Java SDKを使用する際の主要な概念について説明します。

同期コール

同期呼び出しを行うには、同期クライアントのインスタンスを作成します。 同期クライアントの一般的なパターンは、Exampleという名前のサービスの場合、ExampleServiceという名前のインタフェースがあり、同期クライアントの実装はExampleServiceClientです。 Object Storageクライアントの作成例を次に示します:

AuthenticationDetailsProvider provider = ...;
ObjectStorage clientWithDefaultClientConfig = new ObjectStorageClient(provider);
clientWithDefaultClientConfig.setRegion(Region.US_ASHBURN_1);

ClientConfiguration clientConfig = ...;
ObjectStorage clientWithExplicitClientConfig = new ObjectStorageClient(provider, clientConfig);
clientWithExplicitClientConfig.setRegion(Region.US_ASHBURN_1);

同期呼び出しは、レスポンスが利用可能になるまでブロックされます。 すべてのSDK APIは、APIがコンテンツを戻すかどうかにかかわらず、レスポンス・オブジェクトを返します。 レスポンス・オブジェクトには、通常、少なくとも1つのリクエストIDが含まれています。リクエストIDは、特定のリクエストに関するオラクル・サポートに連絡するときに使用できます。

ObjectStorage client = ...;
GetBucketResponse response = client.getBucket(
    GetBucketRequest.builder().namespaceName("myNamespace").bucketName("myBucket").build());
String requestId = response.getOpcRequestId();
Bucket bucket = response.getBucket();
System.out.println(requestId);
System.out.println(bucket.getName());

非同期コール

非同期呼び出しを行うには、非同期クライアントのインスタンスを作成します。 非同期クライアントの一般的なパターンは、Exampleという名前のサービスの場合、ExampleServiceAsyncという名前のインタフェースがあり、非同期のクライアントの実装はExampleServiceAsyncClientです。 Object Storageクライアントの作成例を次に示します:

AuthenticationDetailsProvider provider = ...;
ObjectStorageAsync clientWithDefaultClientConfig = new ObjectStorageAsyncClient(provider);
clientWithDefaultClientConfig.setRegion(Region.US_ASHBURN_1);
 
ClientConfiguration clientConfig = ...;
ObjectStorageAsync clientWithExplicitClientConfig = new ObjectStorageAsyncClient(provider, clientConfig);
clientWithExplicitClientConfig.setRegion(Region.US_ASHBURN_1);

非同期呼び出しはすぐに戻ります。 コールが正常に完了した後、または失敗した後に呼び出されるAsyncHandlerを提供する必要があります:

ObjectStorageAsync client = ...;
 
AsyncHandler<GetBucketRequest, GetBucketResponse> handler = new AsyncHandler<GetBucketRequest, GetBucketResponse>() {
        @Override
        public void onSuccess(GetBucketRequest request, GetBucketResponse response) {
            String requestId = response.getOpcRequestId();
            Bucket bucket = response.getBucket();
            System.out.println(requestId);
            System.out.println(bucket.getName());
        }

        @Override
        public void onError(GetBucketRequest request, Throwable error) {
            error.printStackTrace();
        }
};
 
Future<GetBucketResponse> future = client.getBucket(
        GetBucketRequest.builder().namespaceName("myNamespace").bucketName("myBucket").build(),
        handler);

Waitersとのポーリング

SDKは、特定のリソースが目的の状態に達するまでコードを待機させるウェイタを提供します。 ウェイタは、ブロッキングまたは非ブロッキング(非同期コールバック付き)の両方の方法で呼び出すことができ、目的のステートに達するかタイムアウトを超えるまで待機します。 Waitersは、そうでなければ使いやすい単一のメソッド呼び出しに書き込む必要のあるポーリング・ロジックを抽象化します。

ウェイタは、サービス・クライアント(client.getWaiters())を介して取得されます。 Get<Resource>Requestと目的のライフサイクル状態の両方がwaiters.for<Resource>メソッドに渡されます。 次に例を示します。

public static Instance waitForInstanceProvisioningToComplete(  ComputeClient computeClient, String instanceId) throws Exception {
        
    ComputeWaiters waiters = computeClient.getWaiters();
    GetInstanceResponse response = waiters.forInstance(
        GetInstanceRequest.builder().instanceId(instanceId).build(),
        Instance.LifecycleState.Running)
    .execute();
        
    return response.getInstance();
}

waiters.for<Resource>メソッドには2つのバージョンがあります:

  • 1つのバージョンでは、デフォルトのポーリング値が使用されます。 次に例を示します。

    waiters.forInstance(GetInstanceRequest, LifecycleState)
  • もう1つのバージョンでは、待つ時間とポーリングの間隔を完全に制御できます。 次に例を示します。

    waiters.forInstance(GetInstanceRequest, LifecycleState, TerminationStrategy, DelayStrategy)

スレッド・モデル

クライアントは、初期化されるとスレッド・セーフになります。 エンドポイントを設定した後は、クライアントを複数のスレッドで安全に使用し、その上で同時にメソッドをコールできます。

クライアントは、複数のリクエスト(同時スレッド全体、または1つのスレッド内)で再利用できます。 環境リソースが制約されていない場合、クライアントがスコープ外になる直前に閉じることのみをお薦めします。

ノート

この保証は、デフォルトのJAX-RS実装であるジャージにのみ適用されます。
代替実装を使用する場合は、スレッドの安全性を自分で管理する必要があります。 詳細は、「独自のJAX-RS実装の使用」を参照してください。

ラージ・オブジェクトのアップロード

Object Storageサービスは、ラージ・オブジェクトを分割して大規模オブジェクトのアップロードを容易にするマルチパート・アップロードをサポートします。 Java SDKは、高度なユースケースのraw multipartアップロード操作、およびmultipartアップロードAPIを使用するより高いレベルのアップロード・クラスをサポートしています。 「マルチパート・アップロードの管理」は、マルチパート・アップロード操作に使用されるAPIへのリンクを提供します。 より高いレベルのマルチパート・アップロードは、UploadManagerを使用して実装されます。: ラージ・オブジェクトをパーツに分割し、パーツを並行してアップロードしてから、そのパーツをストレージ内の単一のオブジェクトとして再結合します。

UploadObjectの例は、UploadManagerを使用してオブジェクトを自動的に分割してアップロードする方法を示し、Object Storageサービスとのやりとりを簡単にします。

Rawリクエスト

Rawリクエストは便利であり、必要な場合もあります。 典型的な使用例は: 独自のHTTPクライアントを使用する場合、代替エンドポイントへのOCI認証リクエストの作成、およびSDKで現在サポートされていないOCI APIへのリクエストの作成。 Java SDKは、非標準リクエストに対してRequestSignerインスタンスを作成するために使用できるDefaultRequestSignerクラスを公開しています。

GitHubの「Rawリクエスト」の例は、以下の方法を示しています:

  • 認証プロバイダを作成して署名者をリクエスト
  • リクエストを認証するためにHTTPクライアント(この例ではJersey)と統合

エンドポイントの設定

サービス・エンドポイントは、2つの方法のいずれかで設定できます。

  • サービス・インスタンス上でsetEndpoint()を呼び出します。 これにより、完全なホスト名を指定できます(たとえば、https://www.example.com)。
  • サービス・インスタンス上でsetRegion()を呼び出します。 これは、指定されたリージョンのサービスに適したホスト名を選択します。 ただし、設定したリージョンでサービスがサポートされていない場合、Java SDKはエラーを返します。

サービス・インスタンスは、異なるリージョンとの通信には使用できません。 異なるリージョンに依頼する必要がある場合は、複数のサービス・インスタンスを登録します。

前方互換性と列挙

列挙に基づく条件ロジックがある場合は、互換性を維持するためにコードがUnknownEnumValueケースを処理するようにしてください。 一部のレスポンス・フィールドは列挙型ですが、将来、個々のサービスはそのフィールドの既存の列挙ではない値を返します。 この可能性に対処するために、enum型のすべてのレスポンス・フィールドには、UnknownEnumValueという追加の値があります。 サービスがSDKのバージョンで認識されない値を返した場合、レスポンス・フィールドはこの値に設定されます。

新規リージョン・サポート

新しいリージョンのアナウンスメントの前にリリースされたSDKのバージョンを使用している場合は、回避策を使用して到達できます。

regionは、ローカライズされた地理的領域です。 リージョンの詳細およびリージョンを識別する方法は、「リージョンと可用性ドメイン」を参照してください。

realmは、エンティティを共有するリージョンの集合です。 レルムを識別するには、ネットワーク・アドレスの末尾にあるドメイン名を参照します。 たとえば、xyz.abc.123.oraclecloud.comのレルムはoraclecloud.comです。

ノート

次のコード・サンプルについては、リージョンに適切なエンドポイントを指定してください。

oraclecloud.comレルム

oraclecloud.comレルム内のリージョンの場合、SDKバージョンの「リージョン」列挙にすでに定義されているものを渡す場合と同じように、新しいリージョン名を渡すことはできません。

Java SDK 1.2.34以降を使用する場合、次のいずれかのメソッドで新しいリージョン名を文字列として渡すことができます:

  • 以前に作成したクライアントのリージョンを設定するには:

    client.setRegion("ca-toronto-1");
  • 新しいクライアントを作成するときにリージョンを設定するには、次のステップを実行します:

    Identity identityClient = IdentityClient.builder()
            .region("ca-toronto-1")
            .build(provider);

インスタンス・プリンシパルを介して認証する場合、次のコードを使用してfederationEndpointを設定できます。 このメソッドは、すべてのバージョンのSDKで動作します。

InstancePrincipalsAuthenticationDetailsProvider provider = InstancePrincipalsAuthenticationDetailsProvider.builder()
        .federationEndpoint("https://auth.ca-toronto-1.oraclecloud.com/v1/x509")
        .build();

その他のレルム

oraclecloud.com以外のレルムのリージョンの場合、次の回避策を使用して、古いバージョンのSDKを持つ新しいリージョンに到達できます。

エンドポイントを指定するには:

AuthenticationDetailsProvider provider =
        new ConfigFileAuthenticationDetailsProvider(configurationFilePath, profile);

IdentityClient client = IdentityClient.builder()
        .endpoint("https://identity.ca-toronto-1.oraclecloud.com")
        .build(provider);

インスタンス・プリンシパルを介して認証する場合、エンドポイントとfederationEndpointを次のプロセスで設定できます:

InstancePrincipalsAuthenticationDetailsProvider provider = InstancePrincipalsAuthenticationDetailsProvider.builder()
        .federationEndpoint("https://auth.ca-toronto-1.oraclecloud.com/v1/x509")
        .build();

IdentityClient identityClient = IdentityClient.builder()
        .endpoint("https://identity.ca-toronto-1.oraclecloud.com")
        .build(provider);

ページされたレスポンス

APIによってはページ区切りされた結果セットが戻されるため、追加のアイテムがないか確認し、必要に応じて次のページをフェッチする必要があります。 これは手動で行うことも、イテレータを使用することもできます。

ページの手動フェッチ

レスポンス・オブジェクトには、次のページ・トークンをフェッチするメソッドが含まれています。 トークンがNULLの場合、それ以上のアイテムはありません。 Nullでない場合は、Requestオブジェクトにトークンを設定して、レスポンスの次のページを取得することで、追加リクエストを作成できます。

ノート

APIによっては、追加の結果がない場合でもトークンが戻される場合があります。
また、返されたアイテムがない場合は、必ずチェックして停止してください。

次の例は、Object Storage APIから返されたページ・トークンの処理方法を示しています。

ObjectStorage client = ...;
 
ListBucketsRequest.Builder builder =
    ListBucketsRequest.builder().namespaceName(namespace);
String nextPageToken = null;
do {
    builder.page(nextPageToken);
    ListBucketsResponse listResponse = client.listBuckets(builder.build());
    List<Bucket> buckets = listResponse.getItems();
    // handle buckets
    nextPageToken = listResponse.getOpcNextPage();
} while (nextPageToken != null);

イテレータの使用

ページ・トークンを手動で操作するかわりに、イテレータを使用できます。 各サービス・クライアントは、Paginatorオブジェクトを返すgetPaginators()メソッドを公開します。 このオブジェクトには、Iterable型のオブジェクトを返すメソッドが含まれます。 iterableを使用するための2つのアプローチをサポートしています:

  • レスポンス・イテレータ: リスト操作によって返されるResponseオブジェクトを反復処理できます。 これらはResponseIteratorsと呼ばれ、メソッドには"ResponseIterator"というサフィクスが付きます(例:listUsersResponseIterator)。
    Iterable<ListUsersResponse> responseIterator = identityClient.getPaginators().listUsersResponseIterator(request);
    for (ListUsersResponse response : responseIterator) {
        for (User user : response.getItems()) {
            System.out.println(user);
        }
    }
  • レコード・イテレータ: リストされているリソース/レコードを反復処理できます。 これらはRecordIteratorと呼ばれ、メソッドには"RecordIterator"というサフィクスが付きます(例:listUsersRecordIterator)。
    Iterable<User> recordIterator = identityClient.getPaginators().listUsersRecordIterator(request)
    for (User user : recordIterator) {
        System.out.println(user);
    }

例外処理

例外を処理する際に、その例外の原因となったHTTPリクエストに関する詳細(ステータス・コードやタイムアウトなど)を取得できます。 getOpcRequestIdメソッドを使用することで、BmcExceptionを処理する際にリクエストIDを取得することもできます。

この例は、BmcExceptionを処理し、リクエストIDを出力するtry-catchブロックを示しています。

ObjectStorage client = ...;
try {
    GetBucketResponse response = client.getBucket(
	        GetBucketRequest.builder().namespaceName("myNamespace").bucketName("myBucket").build());
    String requestId = response.getOpcRequestId();
    System.out.println(requestId);
} catch (BmcException e) {
    String requestId = e.getOpcRequestId();
    System.out.println(requestId);
    e.printStackTrace();
}

Java SDKの例外は、ランタイム例外です(未選択)。したがって、メソッド・シグネチャには表示されません。 すべてのAPIはBmcExceptionをスローすることができます。