Concepts

Cette rubrique explique certains des concepts clés relatifs à l'utilisation de la trousse SDK Oracle Cloud Infrastructure pour Java.

Cette rubrique explique certains des concepts clés relatifs à l'utilisation de la trousse SDK Oracle Cloud Infrastructure pour Java.

Appels synchrones

Pour effectuer des appels synchrones, créez une instance du client synchrone. Selon le modèle général pour les clients synchrones : pour un service nommé Example, il y aura une interface nommée ExampleService et la mise en oeuvre du client synchrone sera appelée ExampleServiceClient. Voici un exemple de création d'un client de stockage d'objets :

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);

Les appels synchrones sont bloqués jusqu'à ce que la réponse soit disponible. Toutes les API de trousse SDK retournent un objet de réponse (que l'API renvoie du contenu ou non). L'objet de réponse contient généralement au moins un ID demande que vous pouvez utiliser lors de la communication avec le soutien technique d'Oracle pour obtenir de l'aide sur une demande particulière.

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());

Appels asynchrones

Pour effectuer des appels asynchrones, créez une instance du client asynchrone. Selon le modèle général pour les clients asynchrones : pour un service nommé Example, il y aura une interface nommée ExampleServiceAsync et la mise en oeuvre du client asynchrone sera appelée ExampleServiceAsyncClient. Voici un exemple de création d'un client de stockage d'objets :

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);

Les appels asynchrones sont retournés immédiatement. Vous devez fournir un AsyncHandler qui sera appelé une fois l'appel réussi ou en échec :

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);

Scrutation avec des processus en attente

La trousse SDK offre des processus d'attente qui permettent à votre code d'attendre qu'une ressource spécifique atteigne l'état souhaité. Un processus en attente peut être appelé à la fois de manière bloquante ou non bloquante (avec rappel asynchrone), et attendra jusqu'à ce que l'état souhaité soit atteint ou qu'une temporisation soit dépassée. Les processus en attente convertissent la logique de scrutation (que vous auriez à écrire autrement) en un appel de méthode unique facile à utiliser.

Les processus en attente sont obtenus au moyen du client du service (client.getWaiters()). Les deux états Get<Resource>Request et celui du cycle de vie désiré sont transmis à la méthode waiters.for<Resource>. Par exemple :

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();
}

Chaque méthode waiters.for<Resource> comporte deux versions :

  • Une version utilise les valeurs de scrutation par défaut. Par exemple :

    waiters.forInstance(GetInstanceRequest, LifecycleState)
  • L'autre version vous donne un contrôle total sur la durée d'attente et la durée entre les tentatives de scrutation. Par exemple :

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

Modèle de fil

Le client prend l'état thread-safe lorsqu'il est initialisé. Après avoir défini son point d'extrémité, vous pouvez utiliser en toute sécurité un client dans plusieurs fils et méthodes d'appel simultanément.

Vous pouvez réutiliser un client dans plusieurs demandes, tant dans des fils simultanés que dans un seul fil. À moins que les ressources de l'environnement ne soient restreintes, vous devez seulement fermer le client juste avant qu'il ne soit hors de portée.

Note

Cette garantie s'applique uniquement à la mise en oeuvre JAX-RS par défaut, Jersey. Lorsque vous utilisez une autre mise en oeuvre, vous devez gérer la sécurité du fil vous-même. Pour plus d'informations, voir Configuration de la trousse SDK.

Chargement d'objets volumineux

Le service de stockage d'objets prend en charge les chargements en plusieurs parties pour faciliter les chargements d'objets volumineux en fractionnant l'objet volumineux en parties. La trousse SDK pour Java prend en charge les opérations de chargement en plusieurs parties brutes pour des cas d'utilisation avancés, ainsi qu'une classe de chargement de niveau supérieur utilisant les API de chargement en plusieurs parties. L'utilisation de chargements en plusieurs parties fournit des liens aux API utilisées pour les opérations de chargement en plusieurs parties. Les chargements en plusieurs parties de niveau supérieur sont mis en oeuvre à l'aide d'UploadManager qui fractionne un objet volumineux en plusieurs parties pour vous, charge les parties en parallèle, puis recombine et valide les parties en un seul objet dans le stockage.

L'exemple UploadObject montre comment utiliser UploadManager pour fractionner automatiquement un objet en plusieurs parties afin de simplifier les interactions avec le service de stockage d'objets.

Nouvelles tentatives

À partir de la version 2.10.0, la trousse SDK pour Java est configurée par défaut pour retenter certaines opérations de trousse SDK qui échouent. La trousse SDK vous permet de spécifier la stratégie à utiliser pour le mode de traitement des nouvelles tentatives, notamment le nombre de nouvelles tentatives, la condition selon laquelle la trousse SDK doit retenter une opération et le moment auquel arrêter les nouvelles tentatives. Vous pouvez définir ces paramètres au niveau du client et au niveau de la demande individuelle.

Pour savoir pour quelles opérations de service les nouvelles tentatives sont activées par défaut, consultez la description des opérations de service de la trousse SDK.

Note

Les nouvelles tentatives ne sont pas prises en charge actuellement pour les clients asynchrones.

Par défaut, la trousse SDK retente les opérations avec les codes de statut de réponse HTTP 409 (avec un code d'erreur IncorrectState), 429, 500, 502, 503, 504, les erreurs de temporisation (temporisations de connexion HTTP et de lecture, par exemple), les erreurs de connexion de demande, les exceptions de demande et les exceptions de disjoncteur.

La configuration par défaut la plus courante et la liste des erreurs qui peuvent faire l'objet de nouvelles tentatives sont visibles dans Github.

Désactivation des nouvelles tentatives par défaut

Pour désactiver la fonction de nouvelles tentatives par défaut, vous pouvez effectuer l'une des opérations suivantes :

  1. Réglez la variable d'environnement OCI_SDK_DEFAULT_RETRY_ENABLED à false pour désactiver les nouvelles tentatives par défaut globalement.
  2. Remplacez les nouvelles tentatives par défaut pour une instance client spécifique. Cet exemple montre comment remplacer les nouvelles tentatives par défaut pour objectStorageClient :

    ClientConfiguration clientConfiguration =
            ClientConfiguration.builder()
                    .retryConfiguration(RetryConfiguration.builder().terminationStrategy(new MaxAttemptsTerminationStrategy(1))
                            .build())
                    .build();
    ObjectStorage objectStorageClient = ObjectStorageClient.builder().configuration(clientConfiguration).build(provider);
    
  3. Remplacez les nouvelles tentatives par défaut pour une instance de demande spécifique. Cet exemple illustre le remplacement des nouvelles tentatives pour putObjectRequest :

    PutObjectRequest putObjectRequest =
            PutObjectRequest.builder()
                    .putObjectBody(stream)
                    .bucketName(bucketName)
                    .objectName(objectName)
                    .namespaceName(namespace)
                    .retryConfiguration(RetryConfiguration.builder().terminationStrategy(new MaxAttemptsTerminationStrategy(1)).build())
                    .build();

Priorité du comportement des nouvelles tentatives

  • Toute configuration définie explicitement au niveau de la demande remplace la configuration au niveau du client ou la configuration globale et la configuration au moyen de la variable d'environnement, pour cette instance de demande spécifique.
  • Toute configuration définie explicitement au niveau du client remplace la configuration globale et la configuration au moyen de la variable d'environnement, pour cette instance de client particulière.

Stratégies de traitement des nouvelles tentatives

Vous pouvez spécifier la stratégie à utiliser pour le traitement des nouvelles tentatives, notamment le nombre de nouvelles tentatives, la condition selon laquelle la trousse SDK doit retenter une opération et le moment auquel arrêter les nouvelles tentatives. Vous pouvez définir ces paramètres au niveau du client et au niveau de la demande individuelle.
Note

La configuration par défaut la plus courante et la liste des erreurs qui peuvent faire l'objet de nouvelles tentatives sont visibles sur Github.

Stratégie de délai

Le paramètre delayStrategy détermine la durée d'attente entre chaque appel de nouvelle tentative. Deux options sont disponibles pour ce paramètre :

  • FixedTimeDelayStrategy (milliseconds) - Le délai avant chaque nouvelle tentative est spécifié en nombre de millisecondes.
  • ExponentialBackoffDelayStrategy (milliseconds) - Le délai pour les nouvelles tentatives suivantes augmente d'un facteur exponentiel de 2 jusqu'à ce qu'il atteigne le délai maximal défini (en millisecondes), avec une valeur de base d'une milliseconde.

La stratégie de délai par défaut est réglée à ExponentialBackoffDelayStrategy avec une valeur de gigue comprise entre 0 et 1 000 millisecondes et un temps d'attente maximal entre les appels de 30 secondes.

Condition de nouvelle tentative

retryCondition définit une fonction avec un argument d'erreur qui retourne un booléen indiquant s'il faut réessayer ou non. L'opération sera retentée si cette fonction retourne true.

Stratégie d'arrêt

Le paramètre terminationStrategy définit quand mettre fin aux nouvelles tentatives. Ce paramètre prend en charge les options suivantes :

  • MaxTimeTerminationStrategy (milliseconds) - Définit la durée totale en millisecondes pour la nouvelle tentative.
  • MaxAttemptsTerminationStrategy (attempts) - Définit le nombre total de nouvelles tentatives.

La stratégie d'arrêt par défaut pour la trousse SDK d'OCI est MaxAttemptsTerminationStrategy = 8.

Exemples de nouvelles tentatives

Java

Cet exemple montre comment configurer et utiliser les nouvelles tentatives avec la trousse SDK pour Java :

/**
 * Copyright (c) 2016, 2021, Oracle and/or its affiliates.  All rights reserved.
 * This software is dual-licensed to you under the Universal Permissive License (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl or Apache License 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose either license.
 */
import com.oracle.bmc.ClientConfiguration;
import com.oracle.bmc.ConfigFileReader;
import com.oracle.bmc.auth.AuthenticationDetailsProvider;
import com.oracle.bmc.auth.ConfigFileAuthenticationDetailsProvider;
import com.oracle.bmc.identity.Identity;
import com.oracle.bmc.identity.IdentityClient;
import com.oracle.bmc.identity.requests.ListRegionsRequest;
import com.oracle.bmc.identity.responses.ListRegionsResponse;
import com.oracle.bmc.retrier.Retriers;
import com.oracle.bmc.retrier.RetryConfiguration;
import com.oracle.bmc.waiter.FixedTimeDelayStrategy;
import com.oracle.bmc.waiter.MaxAttemptsTerminationStrategy;

/**
 * This example demonstrates how to use the SDK retries.
 *
 * Retry configuration may be set at
 * a) the SDK level (using {@link Retriers#setDefaultRetryConfiguration(RetryConfiguration)}
 * b) the client level (using {@link ClientConfiguration}
 * c) the request level (using {@link com.oracle.bmc.requests.BmcRequest#setRetryConfiguration(RetryConfiguration)}
 */
public class RetryExample {
    public static void main(String[] args) throws Exception {
        String configurationFilePath = "~/.oci/config";
        String profile = "DEFAULT";

        // Configuring the AuthenticationDetailsProvider. It's assuming there is a default OCI config file
        // "~/.oci/config", and a profile in that config with the name "DEFAULT". Make changes to the following
        // line if needed and use ConfigFileReader.parse(configurationFilePath, profile);

        final ConfigFileReader.ConfigFile configFile = ConfigFileReader.parseDefault();

        final AuthenticationDetailsProvider provider =
                new ConfigFileAuthenticationDetailsProvider(configFile);

        // Set the default retry strategy for all operations to set retry attempts to 3
        Retriers.setDefaultRetryConfiguration(
                RetryConfiguration.builder()
                        .terminationStrategy(new MaxAttemptsTerminationStrategy(3))
                        .build());

        // Override the default retry strategy for the identity client and update retry attempts to 4
        final Identity identityClient =
                new IdentityClient(
                        provider,
                        ClientConfiguration.builder()
                                .retryConfiguration(
                                        RetryConfiguration.builder()
                                                .terminationStrategy(
                                                        new MaxAttemptsTerminationStrategy(4))
                                                .build())
                                .build());

        // Override the client's retry strategy for the list regions request and wait for 5ms between retrying
        final ListRegionsRequest listRegionsRequest =
                ListRegionsRequest.builder()
                        .retryConfiguration(
                                RetryConfiguration.builder()
                                        .terminationStrategy(new MaxAttemptsTerminationStrategy(2))
                                        .delayStrategy(new FixedTimeDelayStrategy(5L))
                                        .build())
                        .build();
        final ListRegionsResponse listRegionsResponse =
                identityClient.listRegions(listRegionsRequest);

        System.out.println(listRegionsResponse.getItems());
    }
}

Disjoncteurs

À partir de la version 2.10.0, la trousse SDK pour Java fournit la prise en charge par défaut des disjoncteurs pour les clients de service pour lesquels les disjoncteurs de trousse SDK par défaut sont activés. Les disjoncteurs permettent d'éviter que le client submerge le service en bloquant l'envoi des demandes à celui-ci après qu'un certain seuil d'échec a été atteint.

Note

Les disjoncteurs par défaut ne sont pas pris en charge actuellement pour les clients asynchrones.

Pour les disjoncteurs par défaut, toutes les erreurs pour lesquelles une nouvelle tentative est possible sont traitées comme des défaillances. Pour identifier les clients de service pour lesquels les disjoncteurs sont activés, consultez la description des clients dans la trousse SDK.

Note

La configuration par défaut des disjoncteurs peut être consultée sur Github.

Configuration du disjoncteur

Les paramètres suivants définissent un disjoncteur :

  • Seuil de taux d'échec - L'état du disjoncteur passe de CLOSED à OPEN lorsque le taux d'échec est égal ou supérieur à ce seuil. Par exemple, lorsque plus de 50 % des appels enregistrés ont échoué, le disjoncteur s'ouvre.
  • Temporisation de réinitialisation - Délai après lequel un disjoncteur ouvert tente d'exécuter une demande.
  • Exceptions d'échec - Liste des exceptions qui sont considérées comme des échecs pour le disjoncteur.
  • Seuil de nombre minimal d'appels/volume - Nombre minimal d'appels requis (par période de fenêtre glissante) avant que le disjoncteur puisse calculer le taux d'erreur.

Configuration des disjoncteurs par défaut

La configuration des disjoncteurs par défaut est la suivante :

  • Seuil de taux d'échec : 80 %. Lorsque 80 % des demandes calculées pour une période de 120 secondes ont échoué, le disjoncteur fermé s'ouvre.
  • Seuil de nombre minimal d'appels/volume : 10, pour la période de 120 secondes définie ci-dessus.
  • Temporisation de réinitialisation : Le disjoncteur attend 30 secondes avant de régler l'interrupteur à l'état halfOpen et de retenter l'action.
  • Exceptions d'échec : Les défaillances du circuit sont enregistrées uniquement pour les exceptions réexécutables ou transitoires. Les codes de réponse HTTP 409 (avec IncorrectState), 429, 500, 502, 503 et 504, les temporisations de demande HTTP et autres, les erreurs et exceptions de connexion de demande sont considérés comme des défaillances qui déclenchent un disjoncteur.

Désactivation du disjoncteur par défaut

Pour désactiver la fonction de disjoncteur par défaut, vous pouvez effectuer l'une des opérations suivantes :

  1. Réglez la variable d'environnement OCI_SDK_DEFAULT_CIRCUITBREAKER_ENABLED à false.
  2. Modifiez la configuration du disjoncteur par défaut pour une instance de client. L'exemple suivant montre comment effectuer cette opération avec une instance IdentityClient :
    ClientConfiguration clientConfiguration =
            ClientConfiguration.builder().circuitBreakerConfiguration(CircuitBreakerUtils.getNoCircuitBreakerConfiguration()).build();
     
            // Create Clients using above ClientConfiguration
            IdentityClient identityClient = new IdentityClient(provider, clientConfiguration);

Priorité du comportement du disjoncteur

Toute configuration de disjoncteur que vous définissez explicitement au niveau du client remplace la configuration globale par défaut et le remplacement au niveau de l'environnement pour ce client.

Pour plus d'informations sur les disjoncteurs et leur configuration par défaut, voir cet exemple sur Github.

Demandes brutes

Les demandes brutes sont utiles et, dans certains cas, nécessaires. Cas d'utilisation courants : Lors de l'utilisation de votre propre client HTTP, qui soumet une demande OCI authentifiée à un autre point d'extrémité, et qui soumet une demande à une API OCI qui n'est pas prise en charge actuellement dans la trousse SDK. La trousse SDK pour Java présente la classe DefaultRequestSigner que vous pouvez utiliser pour créer une instance RequestSigner pour les demandes non standard.

L'exemple de demande brute sur GitHub montre comment :

  • Créer un fournisseur d'authentification et un signataire de demande
  • Intégrer à un client HTTP (Jersey dans cet exemple) pour authentifier les demandes

Définition des points d'extrémité

Les points d'extrémité de service peuvent être définis de trois façons.

  • Appelez setEndpoint() sur l'instance de service. Vous pouvez ainsi spécifier un nom d'hôte complet (par exemple, https://www.example.com).
  • Appelez setRegion() sur l'instance de service. Cela sélectionne le nom d'hôte approprié pour le service dans la région indiquée. Toutefois, si le service n'est pas pris en charge dans la région que vous définissez, la trousse SDK pour Java retourne une erreur.
  • Transmettez la région dans le fichier de configuration. Pour plus d'informations, voir Fichier de configuration des trousses SDK et de l'interface de ligne de commande.

Notez qu'une instance de service ne peut pas être utilisée pour communiquer avec différentes régions. Si vous devez faire des demandes à différentes régions, créez plusieurs instances de service.

Points d'extrémité dédiés

Les endpoints dédiés sont les modèles de endpoint définis par le service pour un domaine spécifique au niveau client. La trousse SDK Java pour OCI vous permet d'activer l'utilisation de la fonction de modèles de point d'extrémité propres au domaine au niveau de l'application et du client. Cette fonction est désactivée par défaut.
Note

La valeur définie au niveau du client a priorité sur la valeur définie au niveau de l'application.

Activer les modèles de point d'extrémité propres au domaine au niveau de l'application :

Pour activer la fonction de modèles de point d'extrémité propres au domaine au niveau de l'application, réglez la variable d'environnement OCI_REALM_SPECIFIC_SERVICE_ENDPOINT_TEMPLATE_ENABLED à true.
Note

La valeur booléenne n'est pas sensible à la casse.

Activer les modèles de point d'extrémité propres au domaine au niveau de l'application :

Pour activer la fonction de modèles de point d'extrémité propres au domaine au niveau client, définissez l'indicateur dans le code comme indiqué :

Pour la trousse SDK OCI pour Java :

ObjectStorage client = ObjectStorageClient.builder().build(provider);
client.useRealmSpecificEndpointTemplate(true);

Pour un exemple complet, voir UseRealmSpecificEndpointsExample sur Github.

Pour la trousse SDK OCI pour Java existante :

ObjectStorage client = new ObjectStorageClient(provider);
client.useRealmSpecificEndpointTemplate(true);

Pour un exemple complet, voir UseRealmSpecificEndpointsExample sur GitHub.

Compatibilité ascendante et énumérations

Si vous avez une logique conditionnelle basée sur une énumération, veillez à ce que le code traite le cas UnknownEnumValue pour garantir la compatibilité ascendante. Certains champs de réponse sont de type énumération, mais, dans le futur, des services individuels pourraient retourner des valeurs qui ne seraient pas couvertes par des énumérations existantes pour ce champ. Pour répondre à cette possibilité, chaque champ de réponse de type énumération a une valeur supplémentaire nommée UnknownEnumValue. Si un service retourne une valeur qui n'est pas reconnue par votre version de trousse SDK, le champ de réponse sera réglé à cette valeur.

Prise en charge de la nouvelle région

Si vous utilisez une version de trousse SDK antérieure à l'annonce d'une nouvelle région, vous pouvez utiliser une solution de rechange pour l'atteindre.

Une région est une zone géographique localisée. Pour plus d'informations sur les régions et comment les identifier, voir Régions et domaines de disponibilité.

Un domaine est un jeu de régions qui partagent des entités. Vous pouvez identifier votre domaine en consultant son nom à la fin de l'adresse réseau. Par exemple, le domaine pour xyz.abc.123.oraclecloud.com est oraclecloud.com.

Vous devez d'abord appeler Region.register pour enregistrer la nouvelle région, puis vous pouvez définir la région en utilisant le fichier de configuration ou en appelant la méthode setRegion.

Note

Lorsqu'une région est enregistrée, le point d'extrémité de fédération n'est plus nécessaire lors de l'utilisation des principaux d'instance. Pour obtenir un exemple, voir https://github.com/oracle/oci-java-sdk/blob/master/bmc-examples/src/main/java/NewRegionAndRealmSupportWithoutSDKUpdate.java.

domaine oraclecloud.com

Pour les régions du domaine oraclecloud.com, vous pouvez transmettre de nouveaux noms de région, comme vous transmettriez des noms déjà définis dans l'énumération Région de votre version de trousse SDK.

Note

Pour les exemples de code suivants, veillez à fournir les points d'extrémité appropriés pour votre région.

Si vous utilisez la version 1.2.34 ou une version ultérieure de la trousse SDK pour Java, vous pouvez transmettre le nom de la nouvelle région en tant que chaîne à l'aide d'une des méthodes suivantes :

  • Pour définir la région d'un client créé précédemment :

    client.setRegion("ca-toronto-1");
  • Pour définir une région lors de la création d'un client :

    Identity identityClient = IdentityClient.builder()
            .region("ca-toronto-1")
            .build(provider); 
  • Vous pouvez également transmettre la région dans le fichier de configuration. Pour plus d'informations, voir Fichier de configuration des trousses SDK et de l'interface de ligne de commande.

Autres domaines

Pour les régions des domaines autres que oraclecloud.com, vous pouvez utiliser les solutions suivantes pour atteindre de nouvelles régions avec des versions antérieures de la trousse SDK.

Pour indiquer le point d'extrémité :
AuthenticationDetailsProvider provider =
        new ConfigFileAuthenticationDetailsProvider(configurationFilePath, profile);

IdentityClient client = IdentityClient.builder()
        .endpoint("https://identity.ca-toronto-1.oraclecloud.com")
        .build(provider);
Si vous vous authentifiez au moyen des principaux d'instance, vous pouvez définir le point d'extrémité et federationEndpoint au moyen du processus suivant :
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);

Réponses paginées

Certaines API retournent des jeux de résultats paginés; vous devez donc vérifier les éléments supplémentaires et, si nécessaire, extraire la page suivante. Vous pouvez le faire manuellement ou utiliser un itérateur.

Extraction manuelle des pages

Les objets de réponse contiennent une méthode pour extraire le jeton de page suivante. Si le jeton est nul, il n'y a plus d'élément. S'il n'est pas nul, vous pouvez créer une demande supplémentaire en définissant le jeton de l'objet Request pour obtenir la page suivante des réponses.

Note

Certaines API peuvent retourner un jeton même s'il n'y a pas de résultats supplémentaires. Vérifiez également si des éléments ont été retournés et arrêtez s'il n'y en a pas.

Cet exemple montre comment traiter les jetons de page retournés par l'API Stockage d'objets :

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);

Utilisation d'un itérateur

Au lieu de traiter manuellement des jetons de page, vous pouvez utiliser un itérateur. Chaque client de service expose une méthode getPaginators() qui retourne un objet Paginator. Cet objet contient des méthodes pour retourner des objets de type itérable. Nous prenons en charge deux approches pour l'utilisation du type itérable :

  • Itérateur de réponse : Vous pouvez effectuer une itération sur les objets Response qui sont retournés par l'opération de liste. Ceux-ci sont référencés en tant que ResponseIterators et leurs méthodes prennent comme suffixe "ResponseIterator", par exemple, listUsersResponseIterator.
    Iterable<ListUsersResponse> responseIterator = identityClient.getPaginators().listUsersResponseIterator(request);
    for (ListUsersResponse response : responseIterator) {
        for (User user : response.getItems()) {
            System.out.println(user);
        }
    }
  • Itérateur d'enregistrement : Vous pouvez effectuer une itération sur les ressources/enregistrements énumérés. Ceux-ci sont référencés en tant que RecordIterator et leurs méthodes prennent comme suffixe "RecordIterator", par exemple, listUsersRecordIterator.
    Iterable<User> recordIterator = identityClient.getPaginators().listUsersRecordIterator(request)
    for (User user : recordIterator) {
        System.out.println(user);
    }

Chiffrement côté client

Le chiffrement côté client vous permet de chiffrer les données du côté client avant de les stocker localement ou de les utiliser avec d'autres services Oracle Cloud Infrastructure.

Pour utiliser le chiffrement côté client, vous devez créer une clé de chiffrement principale à l'aide du service de gestion des clés. Cette création peut être effectuée à l'aide des opérations CreateKey ou ImportKey.

La clé de chiffrement principale sert à générer une clé de chiffrement des données pour chiffrer les données utiles. Une copie chiffrée de cette clé de chiffrement des données (chiffrée à l'aide de la clé de chiffrement principale) et d'autres éléments de métadonnées sont inclus dans les données utiles chiffrées retournées par les trousses SDK pour pouvoir être utilisés pour le déchiffrement.

Préalables pour Java

Les fichiers de politique sans limite pour des versions antérieures ne sont requis que pour les mises à jour JDK 8, 7 et 6 antérieures à 8u161, 7u171 et 6u16. Pour ces versions et les versions ultérieures, les fichiers de politique sont inclus mais ne sont pas activés par défaut.

Les versions courantes de JDK ne requièrent pas ces fichiers de politique. Elles sont fournies ici pour être utilisées avec d'anciennes versions de JDK. La version JDK 9 et les versions ultérieures comprennent les fichiers de politiques sans limite et les utilisent par défaut.

Exemples

L'exemple de code suivant montre comment chiffrer une chaîne :


// String encryption example
			
final byte[] plainText = "Hello World".getBytes();
String masterKeyId = "OCID....";
Map<String, String> context = Collections.singletonMap("Example", "value");
 
OciCrypto ociCrypto = new OciCrypto();
KmsMasterKey kmsMasterKey = new KmsMasterKey(authenticationProvider, Region.US_ASHBURN_1.getRegionId(), vaultId, masterKeyId);
KmsMasterKeyProvider kmsMasterKeyProvider = new KmsMasterKeyProvider(kmsMasterKey);
 
//  Encrypt the data and embed the master key ID in the header
final OciCryptoResult encryptResult = ociCrypto.encryptData(kmsMasterKeyProvider, plainText, context);
final byte[] cipherText = encryptResult.getResult();
 
//  Decrypt the data
final OciCryptoResult decryptResult = ociCrypto.decryptData(kmsMasterKeyProvider, cipherText);

L'exemple suivant montre comment chiffrer un flux de fichiers :


// Create Encryption file stream
FileInputStream in = new FileInputStream(srcFile);
OciCrypto ociCrypto = new OciCrypto();
KmsMasterKey kmsMasterKey = new KmsMasterKey(authenticationProvider, Region.US_ASHBURN_1.getRegionId(), vaultId, masterKeyId);
KmsMasterKeyProvider kmsMasterKeyProvider = new KmsMasterKeyProvider(kmsMasterKey);
OciCryptoInputStream encryptingStream = ociCrypto.createEncryptingStream(kmsMasterKeyProvider, in);
 
// Write the encrypted data to file
FileOutputStream out = new FileOutputStream(srcFile + ".encrypted");
IOUtils.copy(encryptingStream, out);
encryptingStream.close();
out.close();
 
// For decryption, no need to pass key info
KmsMasterKeyProvider kmsMasterKeyProvider = new KmsMasterKeyProvider(authenticationProvider);
// Create the Decryption file stream.
in = new FileInputStream(srcFile + ".encrypted");
OciCryptoInputStream decryptingStream = ociCrypto.createDecryptingStream(kmsMasterKeyProvider, in);
 
 
// Return the plaintext data
out = new FileOutputStream(srcFile + ".decrypted");
IOUtils.copy(decryptingStream, out);
decryptingStream.close();
out.close();

Traitement des exceptions

Lors du traitement d'une exception, vous pouvez obtenir plus d'informations sur la demande HTTP qui l'a générée, notamment le code de statut ou la temporisation. Vous pouvez également obtenir l'ID demande lors du traitement d'une exception BmcException à l'aide de la méthode getOpcRequestId.

Cet exemple présente un bloc try-catch qui traite une exception BmcException et imprime l'ID demande.

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();
}

Les exceptions dans la trousse SDK pour Java sont des exceptions d'exécution (non vérifiées). Elles ne s'affichent pas dans les signatures de méthode. Toutes les API peuvent générer un message BmcException.