Object-Oriented Java Adapter of Amazon S3 SDK

The following text is a partial translation of the original English article, performed by ChatGPT (gpt-3.5-turbo) and this Jekyll plugin:

Я являюсь большим поклонником Amazon Web Services (AWS). Я использую их практически во всех своих проектах. Одним из их самых популярных сервисов является Simple Storage Service (S3). Это хранилище для двоичных объектов (файлов) с уникальными именами, доступное через HTTP или RESTful API.

Использование S3 очень просто. Вы создаете “bucket” с уникальным именем, загружаете свой “объект” в bucket через их веб-интерфейс или через RESTful API, а затем снова скачиваете его (через HTTP или API).

Amazon предлагает Java SDK, который обертывает их RESTful API. Однако, этот SDK совсем не объектно-ориентированный. Он является чисто императивным и процедурным - он просто отражает API.

Например, чтобы скачать существующий объект doc.txt из bucket test-1, вам нужно сделать что-то вроде этого:

Как всегда, процедурное программирование имеет свои неизбежные недостатки. Чтобы преодолеть их все, я разработал jcabi-s3, который является небольшим объектно-ориентированным адаптером для Amazon SDK. Вот как можно выполнить ту же задачу чтения объекта с помощью jcabi-s3:

Почему этот подход лучше? Во-первых, есть несколько явных преимуществ.

S3-объект получает свое представление в Java. Это не набор процедур, которые вызываются для получения его свойств (как с AWS SDK). Вместо этого это Java-объект с определенным поведением. Я назвал их “океты” (аналогично “ведрам”), чтобы избежать конфликтов с java.lang.Object.

Окет - это интерфейс, который предоставляет поведение реального объекта AWS S3: чтение, запись, проверка существования. Существует также удобный декоратор Окет.Text, который упрощает работу с двоичными объектами:

Теперь вы можете передать объект в другой класс, вместо того чтобы предоставлять ему ваши учетные данные AWS, имя ведра и имя объекта. Вы просто передаете Java-объект, который инкапсулирует все детали взаимодействия с AWS.

Поскольку jcabi-s3 представляет все сущности в виде интерфейсов, их легко можно расширить с помощью инкапсуляции (шаблон Декоратор).

Например, вы хотите, чтобы ваш код повторял операции чтения объектов S3 несколько раз перед тем, как отказаться и выбросить исключение IOException (кстати, это очень хорошая практика при работе с веб-сервисами). Таким образом, вы хотите, чтобы все операции чтения S3 повторялись несколько раз, если первые попытки не удалось.

Вы определяете новый класс-декоратор, скажем, RetryingOcket, который инкапсулирует исходный Ocket:

Теперь, везде, где ожидается Ocket, вы отправляете экземпляр RetryingOcket, который обертывает ваш исходный объект.

Метод foo.process() не заметит разницы, так как он ожидает тот же интерфейс Ocket.

Кстати, эта функциональность повторной попытки реализована изначально в jcabi-s3 в пакете com.jcabi.s3.retry.

Снова, из-за того, что все сущности в jcabi-s3 являются интерфейсами, их очень легко мокировать. Например, ваш класс ожидает объект S3, считывает его данные и вычисляет хэш MD5 (я использую DigestUtils из commons-codec).

Вот как будет выглядеть простой модульный тест (попробуйте создать модульный тест для класса с использованием AWS SDK, и вы увидите разницу):

Я использую JUnit и Mockito в этом тесте.

Все классы в jcabi-s3 помечены аннотацией @Immutable и являются полностью неизменяемыми.

Библиотека поставляется в виде зависимости JAR в Maven Central (получите ее последние версии в Maven Central).

Как всегда, ваши комментарии и критика приветствуются в виде GitHub issues.

Translated by ChatGPT gpt-3.5-turbo/42 on 2023-11-22 at 09:38

sixnines availability badge   GitHub stars