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.
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.
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 :
- Réglez la variable d'environnement
OCI_SDK_DEFAULT_RETRY_ENABLED
àfalse
pour désactiver les nouvelles tentatives par défaut globalement. -
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);
-
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
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.
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.
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 :
- Réglez la variable d'environnement
OCI_SDK_DEFAULT_CIRCUITBREAKER_ENABLED
àfalse
. - 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
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 :
OCI_REALM_SPECIFIC_SERVICE_ENDPOINT_TEMPLATE_ENABLED
à true
. 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
.
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.
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.
AuthenticationDetailsProvider provider =
new ConfigFileAuthenticationDetailsProvider(configurationFilePath, profile);
IdentityClient client = IdentityClient.builder()
.endpoint("https://identity.ca-toronto-1.oraclecloud.com")
.build(provider);
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.
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
.