Utilisation du client Java JetS3t avec Amazon S3

Utilisation du client Java JetS3t avec Amazon S3

1. Vue d'ensemble

Dans ce tutoriel, nous allons utiliser la bibliothèqueJetS3t avecAmazon S3.

En termes simples, nous allons créer des buckets, y écrire des données, les lire, les copier, puis les répertorier et les supprimer.

2. Configuration du JetS3t

2.1. Dépendance Maven

Tout d'abord, nous devons ajouter la bibliothèque NATS etApache HttpClient à nospom.xml:


    org.lucee
    jets3t
    0.9.4.0006L


    org.apache.httpcomponents
    httpclient
    4.5.5

Maven Central a leslatest version of the JetS3t library et leslatest version of HttpClient. La source de JetS3t peut être trouvéehere.

Nous allons utiliserApache Commons Codec pour l'un de nos tests, nous allons donc l'ajouter à notrepom.xml too:


    org.lucee
    commons-codec
    1.10.L001

Maven Central a la dernière versionhere.

2.2. Clés Amazon AWS

We’ll need AWS Access Keys to connect to the S3 storage service. Un compte gratuit peut être crééhere.

Une fois que nous avons un compte, nous devons créer un ensemble desecurity keys.Il y a de la documentation sur les utilisateurs et les clés d'accès disponibleshere.

JetS3 n'utilisant pas la journalisation Apache Commons, nous l'utilisons donc également lorsque nous voulons imprimer des informations sur ce que nous faisons.

3. Connexion à un stockage simple

Maintenant que nous avons une clé d'accès AWS et une clé secrète, nous pouvons nous connecter au stockage S3.

3.1. Connexion à AWS

Tout d'abord, nous créons les informations d'identification AWS, puis nous les utilisons pour vous connecter au service:

AWSCredentials awsCredentials
  = new AWSCredentials("access key", "secret key");
s3Service = new RestS3Service(awsCredentials);

RestS3Serviceis our connection to Amazon S3.Il utiliseHttpClientpour communiquer avec S3 via REST.

3.2. Vérification de la connexion

Nous pouvons vérifier que nous nous sommes bien connectés au service en répertoriant les buckets:

S3Bucket[] myBuckets = s3Service.listAllBuckets();

Selon que nous avons créé ou non des buckets auparavant, le tableau peut être vide, mais si l'opération ne lève pas d'exception, nous avons une connexion valide.

4. Gestion des godets

Avec une connexion à Amazon S3, nous pouvons créer des compartiments pour stocker nos données. S3 est un système de stockage d'objets. Les données sont téléchargées en tant qu'objets et stockées dans des compartiments.

Étant donné que tous les compartiments S3 partagent le même espace de noms global, chacun doit avoir un nom unique.

4.1. Création d'un compartiment

Essayons de créer un nom de bucket "mybucket":

S3Bucket bucket = s3Service.createBucket("mybucket");

Cela échoue avec une exception:

org.jets3t.service.S3ServiceException: Service Error Message.
  -- ResponseCode: 409, ResponseStatus: Conflict, XML Error Message:
  
  BucketAlreadyExists The requested bucket name is not available.
  The bucket namespace is shared by all users of the system.
  Please select a different name and try again.
  mybucket 07BE34FF3113ECCF
at org.jets3t.service.S3Service.createBucket(S3Service.java:1586)

Le nom «mybucket» est, de manière prévisible, déjà pris. Pour le reste du didacticiel, nous inventerons nos noms.

Réessayons avec un autre nom:

S3Bucket bucket = s3Service.createBucket("myuniquename");
log.info(bucket);

Avec un nom unique, l'appel aboutit et nous voyons des informations sur notre compartiment:

[INFO] JetS3tClient - S3Bucket
[name=myuniquename,location=US,creationDate=Sat Mar 31 16:47:47 EDT 2018,owner=null]

4.2. Supprimer un bucket

Supprimer un bucket est aussi simple que de le créer, sauf pour une chose; buckets must be empty before they can be removed!

s3Service.deleteBucket("myuniquename");

Cela lève une exception pour un compartiment qui n'est pas vide.

4.3. Spécification de la région du compartiment

Buckets can be created in a specific data center.Pour JetS3t, la valeur par défaut est la Virginie du Nord aux États-Unis, ou «us-east-1».

Nous pouvons remplacer ceci en spécifiant une région différente:

S3Bucket euBucket
  = s3Service.createBucket("eu-bucket", S3Bucket.LOCATION_EUROPE);
S3Bucket usWestBucket = s3Service
  .createBucket("us-west-bucket", S3Bucket.LOCATION_US_WEST);
S3Bucket asiaPacificBucket = s3Service
  .createBucket("asia-pacific-bucket", S3Bucket.LOCATION_ASIA_PACIFIC);

JetS3t a une longue liste de régions définies comme constantes.

5. Télécharger, télécharger et supprimer des données

Une fois que nous avons un seau, nous pouvons y ajouter des objets. Les seaux sont conçus pour durer longtemps et il n'y a aucune limite stricte quant à la taille ou au nombre d'objets qu'un seau peut contenir.

Les données sont téléchargées vers S3 en créantS3Objects.We can upload data a from an InputStream,but JetS3t also provides convenience methods for Stringsand*Files*.

5.1. StringDonnées

Jetons d'abord un coup d'œil àStrings:

S3Object stringObject = new S3Object("object name", "string object");
s3Service.putObject("myuniquebucket", stringObject);

Similaire aux buckets, les objets ont des noms,however, object names only live inside their buckets, so we don’t have to worry about them being globally unique.

Nous créons l'objet en passant un nom et les données au constructeur. Ensuite, nous le stockons avecputObject.

Lorsque nous utilisons cette méthode pour stockerStringswith JetS3t, elle définit le type de contenu correct pour nous.

Interrogeons S3 pour obtenir des informations sur notre objet et examinons le type de contenu:

StorageObject objectDetailsOnly
  = s3Service.getObjectDetails("myuniquebucket", "my string");
log.info("Content type: " + objectDetailsOnly.getContentType() + " length: "
  + objectDetailsOnly.getContentLength());

ObjectDetailsOnly()récupère les métadonnées des objets sans les télécharger. Lorsque nous enregistrons le type de contenu, nous voyons:

[INFO] JetS3tClient - Content type: text/plain; charset=utf-8 length: 9

JetS3t a identifié les données en tant que texte et défini la longueur pour nous.

Téléchargeons les données et comparons-les à celles que nous avons importées:

S3Object downloadObject =
  s3Service.getObject("myuniquebucket, "string object");
String downloadString = new BufferedReader(new InputStreamReader(
  object.getDataInputStream())).lines().collect(Collectors.joining("\n"));

assertTrue("string object".equals(downloadString));

Les données sont récupérées dans le mêmeS3Objectwe utilisé pour les télécharger, avec les octets disponibles dans unDataInputStream.

5.2. Données de fichier

Le processus de téléchargement des fichiers est similaire à celui deStrings:

File file = new File("src/test/resources/test.jpg");
S3Object fileObject = new S3Object(file);
s3Service.putObject("myuniquebucket", fileObject);

LorsqueS3Objects est passé unFile, ils tirent leur nom du nom de base des fichiers qu'ils contiennent:

[INFO] JetS3tClient - File object name is test.jpg

JetS3t takes the File and uploads it for us.Il tentera de charger unmime.types file à partir du chemin de classe et l'utilisera pour identifier le type de fichier et le type de contenu envoyé de manière appropriée.

Si nous récupérons les informations d'objet de notre téléchargement de fichier et obtenons le type de contenu, nous voyons:

[INFO] JetS3tClient - Content type:application/octet-stream

Téléchargeons notre fichier dans un nouveau et comparons le contenu:

String getFileMD5(String filename) throws IOException {
    try (FileInputStream fis = new FileInputStream(new File(filename))) {
        return DigestUtils.md5Hex(fis);
    }
}

S3Object fileObject = s3Service.getObject("myuniquebucket", "test.jpg");
File newFile = new File("/tmp/newtest.jpg");
Files.copy(fileObject.getDataInputStream(), newFile.toPath(),
  StandardCopyOption.REPLACE_EXISTING);
String origMD5 = getFileMD5("src/test/resources/test.jpg");
String newMD5 = getFileMD5("src/test/resources/newtest.jpg");
assertTrue(origMD5.equals(newMD5));

Similaire àStringswe a téléchargé l'objet et a utilisé lesDataInputStream pour créer un nouveau fichier. Ensuite, nous avons calculé un hachage MD5 pour les deux fichiers et les avons comparés.

5.3. Streaming de données

Lorsque nous téléversons des objets autres queStringsouFiles,we, nous avons un peu plus de travail à faire:

ArrayList numbers = new ArrayList<>();
// adding elements to the ArrayList

ByteArrayOutputStream bytes = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(bytes);
objectOutputStream.writeObject(numbers);

ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes.toByteArray());

S3Object streamObject = new S3Object("stream");
streamObject.setDataInputStream(byteArrayInputStream);
streamObject.setContentLength(byteArrayInputStream.available());
streamObject.setContentType("binary/octet-stream");

s3Service.putObject(BucketName, streamObject);

Nous devons définir notre type de contenu et sa longueur avant le téléchargement.

Récupérer ce flux signifie inverser le processus:

S3Object newStreamObject = s3Service.getObject(BucketName, "stream");

ObjectInputStream objectInputStream = new ObjectInputStream(
  newStreamObject.getDataInputStream());
ArrayList newNumbers = (ArrayList) objectInputStream
  .readObject();

assertEquals(2, (int) newNumbers.get(0));
assertEquals(3, (int) newNumbers.get(1));
assertEquals(5, (int) newNumbers.get(2));
assertEquals(7, (int) newNumbers.get(3));

Pour différents types de données, la propriété de type de contenu peut être utilisée pour sélectionner une méthode différente de décodage de l'objet.

6. Copie, déplacement et changement de nom des données

6.1. Copie d'objets

Les objets peuvent être copiés dans S3, sans les récupérer.

Copions notre fichier de test de la section 5.2 et vérifions le résultat:

S3Object targetObject = new S3Object("testcopy.jpg");
s3Service.copyObject(
  BucketName, "test.jpg",
  "myuniquebucket", targetObject, false);
S3Object newFileObject = s3Service.getObject(
  "myuniquebucket", "testcopy.jpg");

File newFile = new File("src/test/resources/testcopy.jpg");
Files.copy(
  newFileObject.getDataInputStream(),
  newFile.toPath(),
  REPLACE_EXISTING);
String origMD5 = getFileMD5("src/test/resources/test.jpg");
String newMD5 = getFileMD5("src/test/resources/testcopy.jpg");

assertTrue(origMD5.equals(newMD5));

Nous pouvons copier des objets dans le même compartiment ou entre deux objets différents.

Si le dernier argument est vrai, l'objet copié recevra de nouvelles métadonnées. Sinon, il conservera les métadonnées de l'objet source.

Si nous voulons modifier les métadonnées, nous pouvons définir le drapeau sur true:

targetObject = new S3Object("testcopy.jpg");
targetObject.addMetadata("My_Custom_Field", "Hello, World!");
s3Service.copyObject(
  "myuniquebucket", "test.jpg",
  "myuniquebucket", targetObject, true);

6.2. Objets en mouvement

Objects can be moved to another S3 bucket in the same region.Une opération de déplacement est une opération de copie puis de suppression.

Si l’opération de copie échoue, l’objet source n’est pas supprimé. Si l'opération de suppression échoue, l'objet existera toujours dans la source et également dans l'emplacement de destination.

Déplacer un objet ressemble à le copier:

s3Service.moveObject(
  "myuniquebucket",
  "test.jpg",
  "myotheruniquebucket",
  new S3Object("spidey.jpg"),
  false);

6.3. Renommer des objets

JetS3t has a convenience method for renaming objects. Pour changer le nom d'un objet, nous l'appelons simplement avec un nouveauS3Object:

s3Service.renameObject(
  "myuniquebucket", "test.jpg", new S3Object("spidey.jpg"));

7. Conclusion

Dans ce didacticiel, nous avons utilisé JetS3t pour vous connecter à Amazon S3. Nous avons créé et supprimé des seaux. Nous avons ensuite ajouté différents types de données aux compartiments et récupéré les données. Pour conclure, nous avons copié et déplacé nos données.

Des échantillons de code, comme toujours, peuvent être trouvésover on GitHub.