Рубрики
Без рубрики

Axios / Get Faceoff: Загрузка файла в Worksdocs Amazon с помощью предварительно подписанного URL Amazon S3

Обзор Если вы используете Amazon Workdocs в качестве управляющего Cloud на основе контента A … Помечено с AWS, JavaScript, производительностью.

Обзор

Если вы используете Amazon Workdocs Как ваша управляемая облачная система управления контентом и/или системой хранения, и если вы планируете автоматизировать такие задачи, как интегрировать ее с другими системами хранения документов/контента, то вам, должно быть, надо наступит в случае использования файла. После некоторой автоматизации вы должны быть в состоянии сделать это в масштабе. В будущем пост я поделился подробной справочной архитектурой о том, как создать такую интегральную систему.

Следующие разделы демонстрируют различные аспекты приложения, начиная с настройки простого приложения Node.js. Тем не менее, есть некоторые предпосылки

Инициализировать проект NPM

Я использовал следующие команды для инициализации нового проекта NPM

➜ mkdir workdocs-sample && cd workdocs-sample
➜ npm init
➜ npm install aws-sdk axios form-data got
➜ touch index.js

После инициализации мою структуру папки выглядит так:

➜  workdocs-sample ls
da-quiz-storage-result.pdf 
index.js                   
node_modules               
package-lock.json          
package.json               
yarn.lock

Инициализировать клиент Workdocs

Настройка AWS учетных данных в index.js Отказ Для получения дополнительной информации читать Лучшие практики для использования учетных данных AWS в вашей среде разработки

const AWS = require("aws-sdk");
const credentials = new AWS.SharedIniFileCredentials({ profile: "default" });
AWS.config.credentials = credentials;

В дополнение к этому вам понадобятся следующие объявления

const got = require("got");
const fs = require("fs");
const FormData = require("form-data");
const workdocs = new AWS.WorkDocs();

Наконец, инициализируйте клиента Workdocs

const workdocs = new AWS.WorkDocs();

Шаги для загрузки файла

Чтобы загрузить файл в папку Workdocs, вам нужно следующее:

  • идентификатор папки для загрузки
    • Чтобы получить идентификатор корневой папки, вам нужно позвонить в Оформление API.
    • Если вы создали новые папки в корне, то вам нужно позвонить ConsingEfolderContents с идентификатором корневой папки
  • Позвоните engilecumentversionupload С идентификатором папки, имя файла и, необязательно, тип контента. Он возвращает предварительно подписанную загрузку Amazon S3 URL, идентификатор документа и идентификатор версии среди прочего
  • использовать получил Чтобы загрузить файл на возвращенные uploadurl.
  • Позвоните UpdatedocumentVersion С идентификатором документа, ID версии и установить Версистстатус к Активный

Получить идентификатор корневой папки

У каждого пользователя есть корневая папка, которая может содержать одного или нескольких детей – ничего необычного, просто обычная структура вложенной папки. Корневая папка имеет идентификатор, который может использоваться для создания папок внутри него. Используя Оформление Вызов API, мы получим идентификатор корневой папки для пользователя, определенного по Запрос параметр. Вы можете посмотреть на Организация Из ваших Amazon Workdocs AWS Console.

const describeUsers = async () => {
  const user = await workdocs
    .describeUsers({
      OrganizationId: "d-92672xxxxx", // your WorkDocs organization Id
      Query: "sahays", // name of an existing WorkDocs user
    })
    .promise();
  return user;
};

Инициализировать загрузку

Следующий код использует engilecumentversionupload Инициировать процесс загрузки файла. API требует Ронталлерид Чтобы загрузить файл, а Имя . Возвращает DECUSTOMIDID Для документа версид Для первой версии документа Uploadurl содержащий предварительно подписанный URL Amazon S3 и GightedHeaders содержащий Content-Type и X-AMZ-Server-Side-шифрование Тип шифрования.

const initUpload = async ({ folderId, filename }) => {
  try {
    console.log("initUpload");
    const contentType = "application/octet-stream";
    const initResult = await workdocs
      .initiateDocumentVersionUpload({
        ParentFolderId: folderId,
        Name: filename,
        ContentType: contentType,
        ContentCreatedTimestamp: new Date(),
        ContentModifiedTimestamp: new Date(),
      })
      .promise();
    const documentId = initResult.Metadata.Id;
    const versionId = initResult.Metadata.LatestVersionMetadata.Id;
    const { UploadUrl, SignedHeaders } = initResult.UploadMetadata;
    console.log("initUpload complete");
    return {
      documentId,
      versionId,
      uploadUrl: UploadUrl,
      signedHeaders: SignedHeaders,
    };
  } catch (e) {
    console.log("failed initUpload", e);
    throw e;
  }
};

Заголовок выглядит как следующее:

headers: {
    'Content-Type': 'application/octet-stream',
    'x-amz-server-side-encryption': 'AES256'
  }

Загрузить файл, используя получил

Следующий код использует получил NPM Библиотека Загрузить локальный файл. Обратите внимание, что мы используем Поставить запрос. Файл добавлен к Formdata используя объект потока файлов. Заголовки извлечены из предыдущего вызова engilecumentversionupload используется для установки Поставить Запросить заголовок.

const uploadFile = async ({ filename, signedHeaders, uploadUrl }) => {
  try {
    if (fs.existsSync(filename)) {
      console.log("reading file stream");
      const fileStream = fs.createReadStream(filename);
      console.log("preparing form data");
      const formData = new FormData();
      formData.append(filename, fileStream);
      console.log("uploading to ", uploadUrl);
      const extendParams = {
        headers: signedHeaders,
      };
      console.log("got extendParams", extendParams);
      const client = got.extend(extendParams);
      await client.put(uploadUrl, {
        body: formData,
      });
      console.log("upload complete");
    } else {
      console.log("file doesn't exist");
      throw "file doesn't exist";
    }
  } catch (e) {
    console.error("failed uploadFile", e);
    throw e;
  }
};

Обновить документ версии

Этот важный шаг завершает транзакцию загрузки файла, установив Версистстатус к Активный Который говорит Amazon Workdocs, чтобы отметить просто загруженный файл как самую последнюю/активную версию.

const updateVersion = async ({ documentId, versionId }) => {
  try {
    await workdocs
      .updateDocumentVersion({
        DocumentId: documentId,
        VersionId: versionId,
        VersionStatus: "ACTIVE",
      })
      .promise();
    console.log("document version updated");
  } catch (e) {
    console.log("failed updateVersion", e);
    throw e;
  }
};

Время для этого лица: получил VS Axios

Давайте посмотрим на Axios. вызов сначала.

await axios.put(uploadUrl, formData, {
        headers: signedHeaders
      });

Это приводит к Amazon S3, отклоняющую запрос со следующей ошибкой:


NotImplemented
A header you provided implies functionality that is not implemented
Transfer-Encoding
016D6B18F95E6923QgYnoYEQTZR4jG7wvdLfAe6lcd2Tg+/eAOeHLvtM+CamqyDxZX8p7CV4ZL+Hph7+IOUiFJkayT8=

Сервер возвращает 501: не реализован отклик

response: {
    status: 501,
    statusText: 'Not Implemented',
    headers: {
      'x-amz-request-id': '016D6B18F95E6923',
      'x-amz-id-2': 'QgYnoYEQTZR4jG7wvdLfAe6lcd2Tg+/eAOeHLvtM+CamqyDxZX8p7CV4ZL+Hph7+IOUiFJkayT8=',
      'content-type': 'application/xml',
      'transfer-encoding': 'chunked', // extra header
      date: 'Mon, 18 May 2020 22:00:24 GMT',
      connection: 'close',
      server: 'AmazonS3'
    },...
}

Теперь давайте посмотрим на получил Вызов:

const extendParams = {
  headers: signedHeaders,
};
console.log("got extendParams", extendParams);
const client = got.extend(extendParams);
await client.put(uploadUrl, {
  body: formData,
});

Это приводит к успешному 200.: Хорошо Ответ с тем же входами

Принести все это вместе

Ниже приведена функция точек входа, которая работает в результате запущенного index.js, используя Узел index.js.

const start = async () => {
  try {
    const user = await describeUsers();
    const rootFolderId = user.Users[0].RootFolderId;
    const filename = "da-quiz-storage-result.pdf";
    const {
      documentId,
      versionId,
      uploadUrl,
      signedHeaders,
    } = await initUpload({ folderId: rootFolderId, filename });
    await uploadFile({ filename, signedHeaders, uploadUrl });
    await updateVersion({ documentId, versionId });
  } catch (e) {
    console.error(e);
  }
};

start();

Ну наконец то

После запуска Узел index.js В вашем терминале вы увидите выход, аналогичный следующему:

initUpload
initUpload complete
reading file stream
preparing form data
uploading to  https://gb-us-west-2-prod-doc-source.s3.us-west-2.amazonaws.com/1b45f47aa1c4d1d1c1f0978587e10f1e56ce801824ca5d5fce0565dea6f76baf/1589767973739-0d3c7a46986cfe7d0fd8beec8258628a8b6ca0e9b0f412afafcdaf9c6aa7a00e?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20200518T021253Z&X-Amz-SignedHeaders=content-type%3Bhost%3Bx-amz-server-side-encryption&X-Amz-Expires=900&X-Amz-Credential=AKIAIM5HWZT6CVS2WHIA%2F20200518%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Signature=025e9ed29fe7f8ab85593c51a4a09b396909de47ea1e893148df14e3435ea080
got extendParams {
  headers: {
    'Content-Type': 'application/octet-stream',
    'x-amz-server-side-encryption': 'AES256'
  }
}
upload complete
document version updated

Файл . Da-Quiz-Storage-Recally.pdf сейчас загружен, как показано на этом скриншоте:

Оригинал: “https://dev.to/sahays/axios-got-faceoff-uploading-a-file-to-amazon-workdocs-using-amazon-s3-pre-signed-url-1hfo”