Открытый пакет интеграций - это бесплатное и с открытым исходным кодом расширение, представляющее из себя набор общих модулей для работы с разнообразными онлайн-сервисами и технологиями
Узнать больше:
Репозиторий на Github | Основная статья на Инфостарт | Документация
S3 хранилища — отличный способ хранения файлов, который, несмотря на небольшой флер загадочности, крайне прост и удобен в повседневном использовании
Сегодня мы рассмотрим практический аспект интеграции с подобными хранилищами в 1С и как максимально просто решить распространенный задачи при работе с ними при помощи методов Открытого пакета интеграций. Но сначала немного теории
Simple Stroage Services
Кратко про S3. Кратко, потому что слово "Simple" в названии не врет и ничего сложного в теоретической части данного хранилища нет:
- S3 это объектное хранилище. Его "объектность" состоит в том, что все хранящиеся там данные представляют из себя, собственно, объекты, состоящие из:
- Данных: самих файлов или информации (например, текста, изображения, видео)
- Метаданных: дополнительной информации о данных (например, даты создания, прав доступа, тегов)
- Уникального идентификатора (ключа): используется для обращения к объекту
- Все объекты хранятся в бакетах. Бакет — это контейнер для хранения объектов и каждый ваш объект находится в бакете. Доступ к бакетам осуществляется по их именам. Эти имена — те же URL у сайтов и, следовательно, уникальны по всему миру. Выглядят вот так:
https://<имя_бакета>.s3.<регион>.amazonaws.com/<ключ_объекта>
- Бакеты размещены по регионам. Это с большего касается оригинального AWS S3: само собой, если вы работаете в своем локальном MinIO (реализация S3 для разворачивания на своих серверах), то никакого распределения там не будет. Однако это очень важная и одна из ключевых особенностей технологии S3, благодаря которой она славится своей устойчивостью и надежностью: если вы пользуетесь услугами какого-то большого серьезного провайдера, то хранящиеся у него данные будут дублироваться по т.н. зонам доступности (Availability Zones) - отдельным дата-центрам в пределах выбранного региона. Т.е. ваши объекты будут доступны, даже если с одним из дата центров что-нибудь приключится
Из основного, что нужно знать для простого использования S3, это все: есть просто бакеты (хранилища) и просто объекты (файлы), хранящиеся там. Вложенных бакетов не бывает (есть т.н. Directory Bucket, которые для удобства мимикрируют, будто бы у них есть подкаталоги, но на самом деле нет), объекты просто лежат в этих бакетах, а бакеты доступны по URL которые, как и URL сайтов, уникальны
Ну, а теперь перейдем к практике.
Начинаем работу
Первое, с чем приходится столкнутся при начале интеграции с S3 - знаменитая AWS4 аутентификация. Это очень большая и долгая тема, и мы на ней останавливаться не будем, так как она уже реализована в библиотеке ОПИ. Все, что вам нужно для начала работы - получить 5 частей учетных данных от своего провайдера S3, а именно:
- Access key
- Secret key
- Region
- URL сервера
- Тип сервиса (по умолчанию - S3)
После того, как эти данные будут у вас, просто укажите их в качестве параметров функции ОсновныеДанные
URL = "storage-155.s3hoster.by";
AccessKey = "BRN5RKJE67...";
SecretKey = "NNhv+i9PrytpT8Tu0C1N...";
Region = "BTC";
ОсновныеДанные = OPI_S3.ПолучитьСтруктуруДанных(URL, AccessKey, SecretKey, Region);
Далее эта структура будет передаваться во все вызываемые методы
Работа с бакетами
Кстати, о методах. Также, как и основных сущностей в S3, видов функций всего два: функции для работы с бакетами и функции для работы с объектами (еще есть возможность просто отправить произвольный запрос, но это не так интересно). Начнем с бакетов
Само собой, в ОПИ доступны все основные операции над бакетами. Например, их можно создавать:
URL = "storage-155.s3hoster.by";
AccessKey = "BRN5RKJE67...";
SecretKey = "NNhv+i9PrytpT8Tu0C1N...";
Region = "BTC";
ОсновныеДанные = OPI_S3.ПолучитьСтруктуруДанных(URL, AccessKey, SecretKey, Region);
// Directory bucket
Наименование = "opi-dirbucket3";
Результат = OPI_S3.СоздатьБакет(Наименование, ОсновныеДанные, Истина);
// General purpose bucket
Наименование = "opi-gpbucket3";
Результат = OPI_S3.СоздатьБакет(Наименование, ОсновныеДанные);
Выше были упомянуты Directory Buckets - те, которые эмулируют вложенные каталоги, наподобие папок обычных файловых систем. Их также можно создавать: достаточно передать Истина в последний параметр функции СоздатьБакет
Что будет результатом выполнения данной операции? Ну, если мы говорим про S3 в целом, то для запросов и ответов в нем используется формат XML, а также активно применяются собственные заголовки для передачи различных метаданных. Но так как XML это не очень удобно, в ОПИ все результаты выполнения функций преобразуются в структуры следующего вида:
{
"status": 200,
"response": {},
"headers": {}
}
JSON формат представлен в статье для удобства - в 1С это настоящие Структуры. Они всегда будут состоять из трех верхних полей: status - код статуса http, respnonse - тело ответа и headers - ключ-значений http-заголовков. Тело ответа в response - то, которое в оригинале XML документ - будет также разобрано в структуру
Это хорошо можно увидеть на нашей следующей функции — ПолучитьСписокБакетов.
Далее я буду опускать повторяющееся создание структуры основных данных. Если вы видите в параметре какой-либо функции ОсновныеДанные — это та же структура из ПолучитьСтруктуруДанных первого примера выше
Вот так можно получить список всех бакетов хранилища:
Результат = OPI_S3.ПолучитьСписокБакетов(ОсновныеДанные);
И результат (опять же: в 1С будет структурой):
{
"status": 200,
"response": {
"ListAllMyBucketsResult": {
"Owner": {
"ID": "02d6176db174dc93cb1b899f7c6078f08654445fe8cf1b6ce98d8855f66bdbf4",
"DisplayName": "minio"
},
"Buckets": {
"Bucket": [
{
"Name": "newbucket2",
"CreationDate": "2024-11-13T18:59:09.139Z"
},
{
"Name": "opi-dirbucket3",
"CreationDate": "2024-11-22T09:34:49.125Z"
},
{
"Name": "opi-gpbucket3",
"CreationDate": "2024-11-22T09:34:49.346Z"
},
{
"Name": "opi-newbucket2",
"CreationDate": "2024-11-14T06:04:12.769Z"
}
]
}
}
},
"headers": {
"Accept-Ranges": "bytes",
"Content-Length": "658",
"Content-Type": "application/xml",
"Date": "Fri, 22 Nov 2024 09:34:49 GMT",
"Server": "MinIO",
"Strict-Transport-Security": "max-age=31536000; includeSubDomains",
"Vary": "Origin,Accept-Encoding",
"X-Amz-Id-2": "e602da57d0c30b8c7034fcfe129917205f80f7bab979408e71da5d1441c85e79",
"X-Amz-Request-Id": "180A40A63D973E0D",
"X-Content-Type-Options": "nosniff",
"X-Xss-Protection": "1; mode=block"
}
}
Также, в случае необходимости, бакет можно и удалить. Для этого в пакете присутствует функция УдалитьБакет:
// Directory bucket
Наименование = "opi-dirbucket3";
Результат = OPI_S3.УдалитьБакет(Наименование, ОсновныеДанные, Истина);
// General purpose bucket
Наименование = "opi-gpbucket3";
Результат = OPI_S3.УдалитьБакет(Наименование, ОсновныеДанные);
Еще в ОПИ есть отдельные методы для настройки тегов, шифрования и версионирования бакетов, но это очень специфические вещи - мы на них останавливаться не будем. В случае необходимости работы с чем-то, из перечисленного выше, вы всегда сможете найти больше информации в онлайн-документации
Работа с объектами
Теперь перейдем к работе непосредственно с объектами бакетов. В первую очередь, необходимо познакомится с функцией ЗагрузитьОбъект, которая позволит помещать информацию в наше хранилище
Наименование = "picture.jpg";
Бакет = "opi-gpbucket3";
Содержимое = "C:\picture.jpg"; // URL, Путь или Двоичные данные
Результат = OPI_S3.ЗагрузитьОбъект(Наименование, Бакет, Содержимое, ОсновныеДанные);
Отдельный плюс S3 хранилищ, который максимально для нас актуален, это возможность загрузки больших файлов частями. Едва ли мы смогли бы загрузить файл размером, скажем, 20 ГБ, одним HTTP-запросом через штатные средства 1С. Но при разделении данных это не составляет проблем
Функция ЗагрузитьОбъект удобна тем, что она универсальна и для больших, и для малых файлов: нам не нужно думать о том, чтобы проверять размер файла и выбирать правильный метод для загрузки
По умолчанию, все файлы свыше 20 МБ считаются большими и загружаются частями, где размер одной части - эти же 20 МБ. Размер можно регулировать при необходимости: для этого в структуру основных данных нужно добавить поле ChunkSize с необходимым значением в байтах (подробнее в документации)
URL = "storage-155.s3hoster.by";
AccessKey = "BRN5RKJE67...";
SecretKey = "NNhv+i9PrytpT8Tu0C1N...";
Region = "BTC";
ОсновныеДанные = OPI_S3.ПолучитьСтруктуруДанных(URL, AccessKey, SecretKey, Region);
ОсновныеДанные.Вставить("ChunkSize", 5242880); // 5 МБ
Введенное значение, как и стандартное, отвечает сразу и за максимальный размер файла для отправки без разделения и за размер одной отправляемой части
Если же вы хотите сами контролировать процесс загрузки с разделением, то в экспорт вынесены также составные части функции ЗагрузитьОбъект: ИнициализироватьЗагрузкуЧастями, ЗагрузитьЧастьОбъекта, ЗавершитьЗагрузкуЧастями, ОтменитьЗагрузкуЧастями
Аналогично работает и скачивание объекта из хранилища при помощи функции ПолучитьОбъект:
ОсновныеДанные.Вставить("ChunkSize", 200000);
Наименование = "picture.jpg";
Бакет = "opi-gpbucket3";
// Получение двоичных данных
Результат = OPI_S3.ПолучитьОбъект(Наименование, Бакет, ОсновныеДанные);
ВременныйФайл = ПолучитьИмяВременногоФайла();
// Сохранение на диск
Результат = OPI_S3.ПолучитьОбъект(Наименование, Бакет, ОсновныеДанные, , , ВременныйФайл);
Еще объекты можно удалять
Результат = OPI_S3.УдалитьОбъект(Наименование, Бакет, ОсновныеДанные);
Копировать
Результат = OPI_S3.КопироватьОбъект(ПутьИсточник, БакетИсточник, ПутьПриемник, БакетПриемник, ОсновныеДанные);
Получать списком
Результат = OPI_S3.ПолучитьСписокОбъектов(Бакет, ОсновныеДанные);
И делать еще много разных специфических операций, вроде тех же, что и у бакетов, настроек тегов и версионирования. Мы же остановимся на еще одной интересной возможности S3 - создании прямых ссылок к объектам
Преподписанные ссылки
Как мы видели ранее, все операции с S3 требуют определенного набора секретных данных для аутентификации. Однако, бывают ситуации, в которых нам необходимо обеспечить загрузку или скачивание объектов хранилища без передачи этих данных во вне или третьим лицам. Это можно сделать при помощи создания т.н. преподписанных (presigned) URL
Presigned URL - это такие ссылки к объектам хранилища, в которых уже заложены авторизационные данные - примерно в том же виде, что и при нормальной настоящей авторизации. Выглядят они примерно вот так:
opi-gpbucket3.storage-155.s3hoster.by/picture.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=BRN5RKJE67YCVDZRRQVI%2F20241128%2FBTC%2Fs3%2Faws4_request&X-Amz-Date=20241128T171930Z&X-Amz-Expires=7200&X-Amz-SignedHeaders=host&X-Amz-Signature=f4e1a933fe344f514e639b01767f42b21ac63e198b9e0ba1bf28580b1c7dc054
Несмотря на наличие, как уже было сказано, авторизационных данных в них, никакой секретной информации достать оттуда нельзя - она преобразована в хэш. Также каждая такая ссылка обязательно имеет время жизни - максимум 604800 секунд (7 дней)
Что касается 1С, то для создания подобных URL в ОПИ есть две функции: ПолучитьСсылкуСкачиванияОбъекта и ПолучитьСсылкуЗагрузкиОбъекта
Наименование = "picture.jpg";
Бакет = "opi-gpbucket3";
URLСкачивания = OPI_S3.ПолучитьСсылкуСкачиванияОбъекта(Наименование, Бакет, ОсновныеДанные, 7200);
URLЗагрузки = OPI_S3.ПолучитьСсылкуЗагрузкиОбъекта(Наименование, Бакет, ОсновныеДанные, 7200);
По первой ссылке объект можно будет скачать GET-запросом, а по второй - загрузить запросом с методом PUT
Подытожим
Мы рассмотрели базовые функции Открытого пакета интеграций для работы с S3 хранилищами, которых будет достаточно для решения большинства задач, возникающих перед 1С разработчиком в процессе работы. Также немного напомню про сам проект ОПИ в целом:
- На данный момент функционал не ограничивается работой с S3, но имеет методы еще для 19 сервисов и технологий, таких как, например, Telegram, Bitrix24, VK, Viber, Google Drive, Yandex Disk, SQLite и др. Полный список поддерживаемых API можно найти в основной статье о проекте
- ОПИ - это не только расширение для 1С, но еще пакет для OneScript и приложение для командной строки. При этом, у всех трех реализаций общий набор методов, а значит вы можете использовать один и тот же функционал там, где вам это будет удобнее. Подробнее про версию для командной строки
- При работе с пакетом вам всегда поможет подробная документация. Там есть как просто описание параметров и возвращаемых значений, так и примеры кода 1С с шаблонами команд вызова для CLI-приложения
Если вам нравится ОПИ, то не забывайте поддерживать его звездочкой на GitHub и плюсом на Инфостарт!
Спасибо за внимание!
Мой GitHub: https://gitub.com/Bayselonarrend OpenYellow: https://openyellow.notion.site Лицензия MIT: https://mit-license.org