ADN Open CIS
Сообщество программистов Autodesk в СНГ

22/02/2018

Хранение данных в Amazon DynamoDB (.NET)

 

Есть частый вопрос: мое приложение должно хранить данные для моих моделей Viewer, каким образом это можно сделать? А это приводит к следующему вопросу: как обеспечить надлежащие права доступа?

На основании этого нам нужно: индексировать базу данных с тем же идентификатором, который используется для Forge: URN; и проверить, имеет ли вызывающий объект доступ к нему через тот же access token. Ниже приведены основные требования. Мы можем думать о дополнительных требованиях, таких как: мы часто не используем его, поэтому зачем ему все время работать? Хорошо, это плюс, на самом деле, но оправдывает нашу архитектуру.

Для этого образца давайте использовать Amazon DynamoDB для хранения наших данных. Почему? База данных является no-SQL - она соответствует нашей потребности в системе на основе индексов, которая может хранить данные любого типа (совместимая с JSON). На самом деле это огромный плюс, поскольку база данных SQL будет ограничена предопределенным типом данных или потребуется огромное поле для случайного текста. И если ваше приложение попадает в бесплатный уровень, это даже лучше, так как предоставляется 200 миллионов запросов. Подробнее здесь. И последнее, но не менее важное: DynamoDB управляется, поэтому нам не нужно беспокоиться о его масштабировании.

Далее, вычисления также могут быть по запросу с технологией AWS Lambda. Без-серверные вычисления сейчас переживают всплеск, и легко понять, почему: это автоматическое масштабирование вычислительной мощности по требованию и они дешевое. Бесплатный уровень включает 1 миллион вызовов с 400 ГБ-сек. 

Давайте посмотрим на архитектуру: наше клиентское приложение на JavaScript выполняет Viewer. В какой-то момент нужно будет прочитать (GET) или написать (POST/PUT) данные. Он вызывает нашу Лямбду-функцию, передающую токен доступа и URN, теперь лямбда-функция при помощи Forge проверит, имеет токен доступа доступ к URN, если да, то прочитает/запишет данные из/в DynamoDB. Как и любая лямбда-функция, она остается активной ("hot") в течение нескольких минут, a через некоторое время она освобождается. Бесплатно, если она не используется.

Если вы уже знаете AWS Lambda и Amazon DynamoDB, здесь нет ничего нового, кроме как проверить разрешения Forge, ведь так? Вот это сюрприз: такой конечной точки нет! Но мы можем просто вызвать случайную защищенную конечную точку для нее, верно? Следующий.NET-код демонстрирует идею. Обратите внимание, что оно наследуется от Controller, как способ использования во всех наших контроллерах WebAPI. И в комментариях вы заметите, что я провел некоторое тестирование с другими конечными точками, и metadata кажется здесь самым быстрым.

Код - JavaScript: [Выделить]
  1. public class Security : Controller
  2. {
  3.   private static readonly HttpClient client = new HttpClient();
  4.   private const string KEY = "Authorization";
  5.  
  6.   protected async Task<bool> IsAuthorized(string urn)
  7.   {
  8.     // Требуется авторизация
  9.     if (!base.Request.Headers.ContainsKey(KEY))
  10.     {
  11.       base.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
  12.       return false;
  13.     }
  14.  
  15.     // используем Autodesk Forge для получения разрешений ...
  16.     client.DefaultRequestHeaders.Remove(KEY);
  17.     client.DefaultRequestHeaders.Add(KEY, base.Request.Headers[KEY][0]);
  18.  
  19.     // теперь нам нужно вызвать одну конечную точку Forge, чтобы проверить наши учетные данные
  20.     // конечные точки metadata кажутся самыми быстрыми!
  21.     // https://developer.autodesk.com/en/docs/model-derivative/v2/reference/http/urn-metadata-GET/
  22.     //
  23.     // к слову, также проверили manifest, но это требует больше времени отклика
  24.     // https://developer.autodesk.com/en/docs/model-derivative/v2/reference/http/urn-manifest-GET/
  25.  
  26.     // Запрос только заголовка кажется на несколько миллисекунд быстрее, поэтому давайте использовать его
  27.     HttpRequestMessage req = new HttpRequestMessage();
  28.     req.RequestUri = new System.Uri(
  29.       string.Format("https://developer.api.autodesk.com/modelderivative/v2/designdata/{0}/metadata", urn));
  30.     req.Method = new HttpMethod("GET");
  31.     HttpResponseMessage res = await client.SendAsync(req, HttpCompletionOption.ResponseHeadersRead);
  32.  
  33.     // на несколько миллисекунд медленнее...
  34.     // HttpResponseMessage response = await client.GetAsync(
  35.     //   string.Format("https://developer.api.autodesk.com/modelderivative/v2/designdata/{0}/metadata", urn));
  36.  
  37.     if (res.StatusCode != HttpStatusCode.OK)
  38.     {
  39.       base.Response.StatusCode = (int)res.StatusCode;
  40.       return false;
  41.     }
  42.  
  43.     // хорошей дороги!
  44.     return true;
  45.   }
  46. }

Наконец, нам нужны конечные точки POST и PUT для сохранения данных и GET для возврата данных. Она должна быть общей и принимать любой вход JSON. Ниже представлен типичный формат ввода и вывода.

Код - HTML: [Выделить]
  1. {
  2.     "urn":"dXJuOmFkc2WXlUUXNPd1E",
  3.     "data": {"key": "любой правильный json"}
  4. }

И какова производительность? В этом случае самая длинная задача - вызов конечной точки Forge для проверки разрешений. В общем, при тестировании с доступной памятью 256 Мб, требуется в среднем 500 мс, но может занять до нескольких секунд. Это должно попасть в бесплатный уровень с 1 миллионом вызовов. Поскольку процедура выполняет 1 или 2 вызова DynamoDB, она должна легко попасть в 200 миллионов вызовов до 25 единиц чтения/записи. Но не верьте мне на слово, пожалуйста, ознакомьтесь с ценой услуг AWS! :-)

Готовы к полному примеру? Проверьте это на этом Github репозитории!

Источник: https://forge.autodesk.com/blog/storing-data-amazon-dynamodb-net

 

Автор перевода: Дмитрий Емельянов

Обсуждение: http://adn-cis.org/forum/index.php?topic=

Опубликовано 22.02.2018