Bruke JetS3t Java Client med Amazon S3

1. Oversikt

I denne opplæringen bruker vi JetS3t-biblioteket med Amazon S3.

Enkelt sagt, vi lager bøtter, skriver data til dem, leser data tilbake, kopierer dem, og deretter lister opp og sletter dem.

2. JetS3t-oppsett

2.1. Maven avhengighet

Først må vi legge til NATS-biblioteket og Apache HttpClient til vårt pom.xml:

 org.lucee jets3t 0.9.4.0006L org.apache.httpkomponenter httpclient 4.5.5 

Maven Central har den nyeste versjonen av JetS3t-biblioteket og den siste versjonen av HttpClient. Kilden til JetS3t finner du her.

Vi bruker Apache Commons Codec for en av testene våre, så vi legger til det i vårt pom.xml også:

 org.lucee commons-codec 1.10.L001 

Maven Central har den nyeste versjonen her.

2.2. Amazon AWS-nøkler

Vi trenger AWS tilgangstaster for å koble til S3-lagringstjenesten. Her kan du opprette en gratis konto.

Etter at vi har en konto, må vi lage et sett med sikkerhetsnøkler. Det er dokumentasjon om brukere og tilgangsnøkler tilgjengelig her.

JetS3t ved hjelp av Apache Commons-logging, så vi bruker det også når vi vil skrive ut informasjon om hva vi gjør.

3. Koble til en enkel lagring

Nå som vi har en AWS-tilgangsnøkkel og en hemmelig nøkkel, kan vi koble til S3-lagring.

3.1. Koble til AWS

Først oppretter vi AWS-legitimasjon og bruker dem deretter til å koble til tjenesten:

AWSCredentials awsCredentials = nye AWSCredentials ("tilgangsnøkkel", "hemmelig nøkkel"); s3Service = ny RestS3Service (awsCredentials); 

RestS3Serviceer vår forbindelse til Amazon S3.Det bruker HttpClientå kommunisere med S3 over REST.

3.2. Verifiserer tilkobling

Vi kan bekrefte at vi har koblet til tjenesten ved å oppgi bøtter:

S3Bucket [] myBuckets = s3Service.listAllBuckets (); 

Avhengig av om vi har opprettet skuffer før eller ikke, kan matrisen være tom, men hvis operasjonen ikke gir unntak, har vi en gyldig forbindelse.

4. Skuffestyring

Med en forbindelse til Amazon S3, kan vi lage bøtter for å holde dataene våre. S3 er et objektlagringssystem. Data lastes opp som objekter og lagres i bøtter.

Siden alle S3-skuffene har samme globale navneområde, må hver og en ha et unikt navn.

4.1. Å lage en bøtte

La oss prøve å lage et bøttenavn “mybucket“:

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

Dette mislykkes med unntak:

org.jets3t.service.S3ServiceException: Tjenestefeilmelding. - Svarskode: 409, Svarstatus: Konflikt, XML-feilmelding: BucketAlreadyExists Det valgte bøttenavnet er ikke tilgjengelig. Bucket-navneområdet deles av alle brukere av systemet. Velg et annet navn og prøv igjen. mybucket 07BE34FF3113ECCF på org.jets3t.service.S3Service.createBucket (S3Service.java:1586)

Navnet "mybucketEr, forutsigbart, allerede tatt. For resten av opplæringen lager vi navnene våre.

La oss prøve igjen med et annet navn:

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

Med et unikt navn lykkes samtalen, og vi ser informasjon om bøtta vår:

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

4.2. Slette en bøtte

Det er like enkelt å slette en bøtte som å lage den, bortsett fra én ting; bøtter må være tomme før de kan fjernes!

s3Service.deleteBucket ("myuniquename"); 

Dette vil gi et unntak for en bøtte som ikke er tom.

4.3. Spesifisering av Bucket Region

Skuffer kan opprettes i et bestemt datasenter.For JetS3t er standard Nord-Virginia i USA, eller "us-east-1."

Vi kan overstyre dette ved å spesifisere en annen region:

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 har en omfattende liste over regioner definert som konstanter.

5. Last opp, last ned og slett data

Når vi har en bøtte, kan vi legge til gjenstander i den. Skuffer er ment å være holdbare, og det er ingen hard grense for størrelsen eller antall gjenstander en bøtte kan inneholde.

Data lastes opp til S3 ved å opprette S3Objects.Vi kan laste opp data a fra en InputStream,men JetS3t gir også praktiske metoder for Strengerog Filer.

5.1. StringData

La oss ta en titt på Strengerførst:

S3Object stringObject = ny S3Object ("objektnavn", "strengobjekt"); s3Service.putObject ("myuniquebucket", stringObject); 

I likhet med bøtter har objekter navn, objektnavn lever imidlertid bare i bøttene sine, så vi trenger ikke å bekymre oss for at de er globalt unike.

Vi oppretter objektet ved å sende et navn og dataene til konstruktøren. Så lagrer vi den med putObject.

Når vi bruker denne metoden til å lagre Strengermed JetS3t setter den riktig innholdstype for oss.

La oss spørre S3 for informasjon om objektet vårt og se på innholdstypen:

StorageObject objectDetailsOnly = s3Service.getObjectDetails ("myuniquebucket", "min streng"); log.info ("Innholdstype:" + objectDetailsOnly.getContentType () + "lengde:" + objectDetailsOnly.getContentLength ()); 

ObjectDetailsOnly ()henter objektets metadata uten å laste den ned. Når vi logger innholdstypen ser vi:

[INFO] JetS3tClient - Innholdstype: tekst / vanlig; charset = utf-8 lengde: 9 

JetS3t identifiserte dataene som tekst og angir lengden for oss.

La oss laste ned dataene og sammenligne dem med det vi lastet opp:

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

Data hentes i det samme S3Objektvi bruker for å laste den opp, med byte tilgjengelig i a DataInputStream.

5.2. Fildata

Prosessen for opplasting av filer ligner på Strenger:

Filfil = ny fil ("src / test / resources / test.jpg"); S3Object fileObject = ny S3Object (fil); s3Service.putObject ("myuniquebucket", fileObject); 

Når S3Objectsblir bestått a Fil de henter navnet sitt fra grunnnavnet på filene de inneholder:

[INFO] JetS3tClient - Filobjektnavnet er test.jpg

JetS3t tar Fil og laster den opp for oss.Den vil prøve å laste inn en mime.types-fil fra klassestien og bruke den til å identifisere filtypen og sendt innholdstype på riktig måte.

Hvis vi henter objektinformasjonen til filopplastingen vår og får innholdstypen vi ser:

[INFO] JetS3tClient - Innholdstype: applikasjon / oktettstrøm

La oss laste ned filen til en ny og sammenligne innholdet:

String getFileMD5 (String filnavn) kaster IOException {try (FileInputStream fis = ny FileInputStream (ny fil (filnavn))) {return DigestUtils.md5Hex (fis); }} S3Object fileObject = s3Service.getObject ("myuniquebucket", "test.jpg"); Fil newFile = ny fil ("/ tmp / newtest.jpg"); Files.copy (fileObject.getDataInputStream (), newFile.toPath (), StandardCopyOption.REPLACE_EXISTING); Streng origMD5 = getFileMD5 ("src / test / resources / test.jpg"); Streng newMD5 = getFileMD5 ("src / test / resources / newtest.jpg"); assertTrue (origMD5.equals (newMD5));

Lik Strengervi lastet ned objektet og brukte DataInputStream for å opprette en ny fil. Deretter beregnet vi en MD5-hash for begge filene og sammenlignet dem.

5.3. Streaming av data

Når vi laster opp andre objekter enn Strengereller Filer,vi har litt mer arbeid å gjøre:

ArrayList tall = ny ArrayList (); // legge til elementer i ArrayList ByteArrayOutputStream bytes = nye ByteArrayOutputStream (); ObjectOutputStream objectOutputStream = ny ObjectOutputStream (byte); objectOutputStream.writeObject (tall); ByteArrayInputStream byteArrayInputStream = ny ByteArrayInputStream (bytes.toByteArray ()); S3Object streamObject = ny S3Object ("stream"); streamObject.setDataInputStream (byteArrayInputStream); streamObject.setContentLength (byteArrayInputStream.available ()); streamObject.setContentType ("binær / oktett-strøm"); s3Service.putObject (BucketName, streamObject); 

Vi må angi innholdstype og lengde før opplasting.

Å hente denne strømmen betyr å reversere prosessen:

S3Object newStreamObject = s3Service.getObject (BucketName, "stream"); ObjectInputStream objectInputStream = ny 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)); 

For forskjellige datatyper kan innholdstypegenskapen brukes til å velge en annen metode for dekoding av objektet.

6. Kopiere, flytte og gi nytt navn til data

6.1. Kopiere gjenstander

Objekter kan kopieres inne i S3, uten å hente dem.

La oss kopiere testfilen vår fra avsnitt 5.2, og verifisere resultatet:

S3Object targetObject = ny S3Object ("testcopy.jpg"); s3Service.copyObject (BucketName, "test.jpg", "myuniquebucket", targetObject, false); S3Object newFileObject = s3Service.getObject ("myuniquebucket", "testcopy.jpg"); Fil newFile = ny fil ("src / test / resources / testcopy.jpg"); Files.copy (newFileObject.getDataInputStream (), newFile.toPath (), REPLACE_EXISTING); Streng origMD5 = getFileMD5 ("src / test / resources / test.jpg"); Streng newMD5 = getFileMD5 ("src / test / resources / testcopy.jpg"); assertTrue (origMD5.equals (newMD5)); 

Vi kan kopiere objekter i samme bøtte, eller mellom to forskjellige.

Hvis det siste argumentet er sant, vil det kopierte objektet motta nye metadata. Ellers beholder det kildobjektets metadata.

Hvis vi vil endre metadataene, kan vi sette flagget til sant:

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

6.2. Objekter i bevegelse

Objekter kan flyttes til en annen S3-bøtte i samme region.En flyttoperasjon er en kopi og deretter en sletteoperasjon.

Hvis kopieringen mislykkes, blir ikke kildeobjektet slettet. Hvis sletteoperasjonen mislykkes, vil objektet fortsatt eksistere i kilden og også på destinasjonsstedet.

Å flytte et objekt ligner på å kopiere det:

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

6.3. Gi nytt navn til objekter

JetS3t har en praktisk metode for å gi nytt navn til objekter. For å endre et objektnavn kaller vi det bare med et nytt S3Objekt:

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

7. Konklusjon

I denne opplæringen brukte vi JetS3t for å koble til Amazon S3. Vi opprettet og slettet bøtter. Så la vi til forskjellige typer data i bøtter og hentet dataene. For å pakke inn ting kopierte vi og flyttet dataene våre.

Kodeeksempler, som alltid, kan du finne på GitHub.