Интеграция с LRS
1. Загрузка цифрового следа с использованием API к LRS
1.1. Общая инструкция интеграции к LRS
Шаги интеграции ОО с LRS платформы:
- Запросить доступ к тестовому хранилищу LRS.
Если вы работаете с нами по нескольким проектам, для каждого проекта нужно отдельное хранилище. Правила выдачи прав доступа описаны ниже. - Протестировать передачу в LRS полного пакета стейтментов по одному пользователю. Подробно описан ниже.
Процесс тестирования двухсторонний, с участием технических специалистов Платформы 2035 и провайдера. - Запросить доступ к хранилищу LRS на промышленном контуре.
После получения доступа вы сможете загружать ЦС на промышленном контуре.
Обратите внимание! Для работы необходимо на заключительном этапе получить доступ именно к продуктовому контуру.
Неприятная ошибка, - продолжить слать рабочие цифровые следы в тестовый контур, их придется повторно послать в промышленный контур.
1.2. Доступ к тестовому хранилищу LRS (тестовый контур)
Направьте заявку на выдачу токена письмом на электронную почту apps@2035.university:
- Тема: Доступ к тестовому External LRS, Название проекта, Название организации.
- Текст: Просим выдать логин, пароль и basic auth токен к External LRS.
- Для какого контура: Тестовый.
- Организация (юридическое наименование, как в договоре).
- Название проекта, в рамках которого проходит интеграция.
- ID организации на Платформе (в ЛК Каталога).
В течение 3 дней заявка будет обработана, и вы получите письмо с информацией, необходимой для доступа.
Сразу после этого вы можете приступать к тестированию передачи ЦС.
Обратите внимание!!!
Отсутствие части информации в заявке влияет на скорость (замедляет) на работу по ней!
1.3 Тестирование авторизации LRS (тестовый контур)
В Университете 2035 используется LRS (Learning Record Store, хранилище учебных активностей) под названием «Learning Locker».
Документация на английском языке тут: http://docs.learninglocker.net/welcome/.
Интеграция с LRS Университета 2035 заключается в 2-х аспектах:
- Настройка инструмента оправки запросов к RESTful API на стороне LRS.
- Отправка фактов (цифрового следа) в LRS;
- Получение фактов (цифрового следа) из LRS.
- Настройка шаблонов отправки сообщений (xAPI) для каждого фиксируемого факта.
Перед началом подключения к API LRS вы получили параметры доступа к нему, которые должны выглядеть так:
- xAPI Endpoint: https://lrs-external.u2035test.ru/data/xAPI/statements
- Basic: ZmZjZGY4ZTkwwwMyOTc1ZTI5OWUzMDVjYzY5NWI5MmJhZTQyNTFmMTpiNzk3MDIzNWQ5MWVlNTdhMzgyYTc1ZWVlZDgyNWNlODczMmFiYjli
- Key: ffcdf8e906c2975e299e305cc695b92bdd4251f1
- Secret: b7970235d91ee57a382a75dddd825ce8732abb9b
Пояснения к параметрам:
- Первый параметр для всех организаций одинаковый – это адрес API тестового стенда LRS Университета 2035.
- Второй, третий и четвертый – индивидуальные для каждого хранилища для каждой организации (на стороне LRS для организации может быть настроено несколько хранилищ).
Приведены измененные параметры только для того, чтобы был пример, как они должны выглядеть. - Используется либо 2-й, либо и 3-й и 4-й параметры, они являются взаимозаменяемыми. 3-й и 4-й указываются в полях логин и пароль некоторых инструментов отправки REST-запросов, 2-й тоже самое только в base64-кодировке и используется в параметре Authorization заголовка запроса.
Ниже по тексту будут представлены в качестве примеров скриншоты из бесплатного инструмента работы с REST API Postman.
Обратите внимание!!!
Для проверки работоспособности вы можете использовать проект в postman, в котором собраны необходимые шаблоны для интеграции
https://www.postman.com/unti2035/cs-kb/overview
В частности для проверки работоспособности полученных ключей авторизации используйте шаблон «Проверка связи».
1.4 Настройка параметров и проверка связи
Необходимо в средстве/механизме оправки REST запросов указать Адрес API (первый параметр выше + /statements).
Параметры заголовка – параметры авторизации (2 или 3,4 параметры указанные выше).
Обязательные параметры:
<button>
Key </button> |
<button>
Value </button> |
---|---|
X-Experience-API-Version |
1.0.3 |
content-type |
application/json |
Для проверки связи выполните следующие действия:
- Отправить запрос «Get» с указанными на предыдущем этапе данными. В ответ должен вернуться статус 200 (ОК).
- Если данные, указанные на предыдущем шаге, неверны, то в ответ на отправленный запрос отобразится статус ошибки:
- не найден API, если адрес URL указан неправильно;
- 404 Not Found, если к адресу не добавили /statements;
- 400 Bad Request, если не указаны заголовки или указаны не верно (X-Experience-API-Version обязателен для любых запросов, content-type для Get не обязателен);
- 401 Unauthorized, если неправильно указали параметры авторизации.
- Вторым запросом для проверки подключения к LRS отправить запрос «POST» с ранее указанными параметрами и простым сообщением в теле запроса: {"Test":"тест"}. В ответ на такой запрос должен быть получен статус 400 Bad Request телом ответа:
{<code> </<span class="speller-hint" data-toggle="popover" data-hint="3" data-original-title="" title="">code</span>> "<span class="speller-hint" data-toggle="popover" data-hint="4" data-original-title="" title="">errorId</span>": "aa9c8065-6884-48ac-adfd-b283f49e14ad", "warnings": [ "Missing required value in 'statements.0.actor'", "Missing required value in 'statements.0.verb'", "Missing required value in 'statements.0.object'", "Unknown keys (Test) set in 'statements.0'" ] }
Обратите внимание! Метод уже не GET, а POST
Данный ответ означает, что запрос был отправлен в LRS, но его структура не соответствует структуре xAPI, предполагающий обязательные элементы, описывающие факт: actor, verb и object.
Получение указанного ответа означает, что настройка и тестирование вашего средства/механизма отправки запросов в LRS завершено и нужно переходить к формированию корректных сообщений о фактах обучения в формате xAPI.
В дальнейшем вы можете, например, попробовать разные шаблоны из проекта Postman, чтобы познакомиться со структуру xapi и удостовериться в их работоспособности.
1.5. Доступ в промышленный контур LRS
Получение доступов на промышленный контур LRS аналогичен получению доступа к тестовому хранилищу.
Направьте заявку на выдачу токена письмом на электронную почту apps@2035.university:
- Тема: Доступ к продуктовому External LRS, Название проекта, Название организации.
- Текст: Просим выдать логин, пароль и basic auth токен к External LRS.
- Для какого контура: Промышленный.
- Организация (юридическое наименование, как в договоре).
- Название проекта, в рамках которого проходит интеграция.
- ID организации на Платформе (в ЛК Каталога).
- Для подтверждения того, что вы успешно загрузили ЦС на тестовом контуре, вам нужно также отправить результаты загрузки, указав id стейтмента, который вы получили в ответ на отправку ЦС в LRS.
Обратите внимание!!!
Отсутствие части информации в заявке влияет на скорость (замедляет) принятия по ней решения
В течение 3 дней заявка будет обработана, и вы получите письмо с логином, паролем и секретным ключом.
2. Интеграция с S3. Работа с файлами
Для отправки артефактов используется объектное хранилище CLOUD4Y. Объектное хранилище построено на платформе компании Cloudian и поддерживает протокол доступа Amazon S3 API. В объектном хранилище данные хранятся без иерархии (каждый объект расположен в пуле данных на одном уровне). Доступ к данным возможен через API.
Алгоритм взаимодействия следующий:
- По запросу на доступ к LRS мы также выдаем доступ к хранилищу s3, который мы используем (если его нет - запросите отдельно на apps@2035.university, указав организацию и проект). Вам будет предоставлен логин и пароль. Их необходимо использовать для авторизации в личном кабинете по ссылке.
После авторизации, откройте меню пользователя:
и используйте access key и s3 endpoint для автоматизированной загрузки файлов на s3 хранилище
- Подключаетесь и работаете с ним по стандартному протоколу Amazon S3 API (описание https://docs.aws.amazon.com/en_us/AmazonS3/latest/API/Welcome.html?roistat_visit=3788849).
- В ЦС в стейтменте xAPI передается ссылка на файл в этом сервисе.
В стейтменте xAPI нужно заполнить массив объектов в statement.attachments. В каждом объекте заполняется набор полей, ссылка на объект в s3 пишется в fileUrl:
usageType: string
display:
ru-RU: string
description:
ru-RU: string
contentType: string
length: int
sha2: string
fileUrl: string
Например,
{
"_id" : "5e8c87aea84de709ec69af48" ,
"<<span class="speller-hint" data-toggle="popover" data-hint="7" data-original-title="" title="">span</span> class="<span class="speller-hint" data-toggle="popover" data-hint="8" data-original-title="" title="">speller</span>-hint" data-toggle="popover" data-hint="7" data-original-title="" title=""><span class="speller-hint" data-toggle="popover" data-hint="9" data-original-title="" title="">hasGeneratedId</span></span>" : false ,
"organisation" : "5e8afe645384a609880b7557" ,
"lrs_id" : "5e8afe7e5384a609880b755b" ,
"client" : "5e8afe7e5384a609880b755c" ,
"person" : {
"_id" : "5e8c87aee79b7e09a0c51a7e" ,
"display" : "Василий Пупкин123"
},
"active" : true ,
"voided" : false ,
"timestamp" : "2019-11-01 09:34:00" ,
"stored" : "2020-04-07 14:01:18" ,
"hash" : "b84db5bc2ff0e487f528c9873e8f1deb41ee59fb" ,
"agents" : [
"<a href="https://id.2035.university/">https://id.2035.university</a>|1672721"
],
"<<span class="speller-hint" data-toggle="popover" data-hint="10" data-original-title="" title="">span</span> class="<span class="speller-hint" data-toggle="popover" data-hint="11" data-original-title="" title="">speller</span>-hint" data-toggle="popover" data-hint="8" data-original-title="" title="">relatedAgents</span>" : [
"<a href="https://id.2035.university/">https://id.2035.university</a>|1672721" ,
"<a href="https://id.2035.university/">https://id.2035.university</a>|54272" ,
"<a href="https://id.2035.university/">https://id.2035.university</a>|646378" ,
"mailto:takem08@gmail.com"
],
"registrations" : [],
"verbs" : [
"<a href="http://adlnet.gov/xapi/verbs/experienced">http://adlnet.gov/xapi/verbs/experienced</a>"
],
"activities" : [
"<a href="https://hackathon_cv.2035.university/task_12/coding_1456">https://hackathon_cv.2035.university/task_12/coding_1456</a>"
],
"<<span class="speller-hint" data-toggle="popover" data-hint="12" data-original-title="" title="">span</span> class="<span class="speller-hint" data-toggle="popover" data-hint="13" data-original-title="" title="">speller</span>-hint" data-toggle="popover" data-hint="9" data-original-title="" title=""><span class="speller-hint" data-toggle="popover" data-hint="14" data-original-title="" title="">relatedActivities</span></span>" : [
"<a href="https://hackathon_cv.2035.university/task_12/coding_1456">https://hackathon_cv.2035.university/task_12/coding_1456</a>" ,
"<a href="https://hackathon_cv.2035.university/">https://hackathon_cv.2035.university</a>" ,
"<a href="https://hackathon_cv.2035.university/task_12">https://hackathon_cv.2035.university/task_12</a>"
],
"statement" : {
"timestamp" : "2019-11-01T12:34:00+03:00" ,
"id" : "137ca18f-97f6-4477-981a-696fb41c6b65" ,
"authority" : {
"<<span class="speller-hint" data-toggle="popover" data-hint="15" data-original-title="" title="">span</span> class="<span class="speller-hint" data-toggle="popover" data-hint="16" data-original-title="" title="">speller</span>-hint" data-toggle="popover" data-hint="10" data-original-title="" title=""><span class="speller-hint" data-toggle="popover" data-hint="17" data-original-title="" title="">objectType</span></span>" : "Agent" ,
"name" : "3" ,
"mbox" : "mailto:takem08@gmail.com"
},
"actor" : {
"account" : {
"name" : "1672721" ,
"<<<span class="speller-hint" data-toggle="popover" data-hint="7" data-original-title="" title="">span</span> class="<span class="speller-hint" data-toggle="popover" data-hint="8" data-original-title="" title="">speller</span>-hint" data-toggle="popover" data-hint="18" data-original-title="" title="">span</span> class="<span class="<span class="speller-hint" data-toggle="popover" data-hint="9" data-original-title="" title="">speller</span>-hint" data-toggle="popover" data-hint="19" data-original-title="" title="">speller</span>-hint" data-toggle="popover" data-hint="11" data-original-title="" title=""><span class="speller-hint" data-toggle="popover" data-hint="20" data-original-title="" title="">homePage</span></span>" : "<a href="https://id.2035.university/">https://id.2035.university</a>"
},
"name" : "Василий Пупкин133" ,
"<<span class="speller-hint" data-toggle="popover" data-hint="21" data-original-title="" title="">span</span> class="<span class="speller-hint" data-toggle="popover" data-hint="22" data-original-title="" title="">speller</span>-hint" data-toggle="popover" data-hint="12" data-original-title="" title=""><span class="speller-hint" data-toggle="popover" data-hint="23" data-original-title="" title="">objectType</span></span>" : "Agent"
},
"verb" : {
"id" : "<a href="http://adlnet.gov/xapi/verbs/experienced">http://adlnet.gov/xapi/verbs/experienced</a>" ,
"display" : {
"en-US" : "experienced"
}
},
"object" : {
"id" : "<a href="https://hackathon_cv.2035.university/task_12/coding_1456">https://hackathon_cv.2035.university/task_12/coding_1456</a>" ,
"definition" : {
"name" : {
"ru-RU" : "Написание кода"
},
"description" : {
"ru-RU" : "Создание и отладка программного кода"
},
"type" : "<a href="https://id.2035.university/xapi/activities/coding">https://id.2035.university/xapi/activities/coding</a>" ,
"extensions" : {
"<a href="https://id/">https://id</a>&46;2035&46;university/xapi/extension/tool" : [
"OpenCV"
],
"<a href="https://id/">https://id</a>&46;2035&46;university/xapi/extension/programming-language" : "C" ,
"<a href="https://id/">https://id</a>&46;2035&46;university/xapi/extension/dataset" : "10000 фото автомобилей на снежной трассе" ,
"<a href="https://id/">https://id</a>&46;2035&46;university/xapi/extension/domain" : "компьютерное зрение и компьютерное распознавание изображений" ,
"<a href="https://id/">https://id</a>&46;2035&46;university/xapi/extension/objective" : "Создать систему распознавания номеров автомобилей в ветреную и снежную погоду"
}
},
"<<span class="speller-hint" data-toggle="popover" data-hint="24" data-original-title="" title="">span</span> class="<span class="speller-hint" data-toggle="popover" data-hint="25" data-original-title="" title="">speller</span>-hint" data-toggle="popover" data-hint="13" data-original-title="" title=""><span class="speller-hint" data-toggle="popover" data-hint="26" data-original-title="" title="">objectType</span></span>" : "Activity"
},
"result" : {
"success" : true ,
"completion" : true ,
"duration" : "PT2H44M" ,
"extensions" : {
"<a href="https://id/">https://id</a>&46;2035&46;university/xapi/extension/competences_text" : [
"Программирование на языке C" ,
"Быстрое вхождение в новые контексты" ,
"Командная работа"
],
"<a href="https://id/">https://id</a>&46;2035&46;university/xapi/extension/competences" : [
"<a href="https://id.2035.university/xapi/extension/competences/set/CDO/programming">https://id.2035.university/xapi/extension/competences/set/CDO/programming</a>" ,
"<a href="https://id.2035.university/xapi/extension/competences/set/softskills/team_work">https://id.2035.university/xapi/extension/competences/set/softskills/team_work</a>"
]
}
},
"context" : {
"team" : {
"name" : "Орлы" ,
"member" : [
{
"name" : "Илья Ильич Репин" ,
"account" : {
"name" : "54272" ,
"<<<span class="speller-hint" data-toggle="popover" data-hint="10" data-original-title="" title="">span</span> class="<span class="speller-hint" data-toggle="popover" data-hint="11" data-original-title="" title="">speller</span>-hint" data-toggle="popover" data-hint="27" data-original-title="" title="">span</span> class="<span class="<span class="speller-hint" data-toggle="popover" data-hint="12" data-original-title="" title="">speller</span>-hint" data-toggle="popover" data-hint="28" data-original-title="" title="">speller</span>-hint" data-toggle="popover" data-hint="14" data-original-title="" title=""><span class="speller-hint" data-toggle="popover" data-hint="29" data-original-title="" title="">homePage</span></span>" : "<a href="https://id.2035.university/">https://id.2035.university</a>"
},
"<<span class="speller-hint" data-toggle="popover" data-hint="30" data-original-title="" title="">span</span> class="<span class="speller-hint" data-toggle="popover" data-hint="31" data-original-title="" title="">speller</span>-hint" data-toggle="popover" data-hint="15" data-original-title="" title=""><span class="speller-hint" data-toggle="popover" data-hint="32" data-original-title="" title="">objectType</span></span>" : "Agent"
},
{
"name" : "Алиса Селезнева" ,
"account" : {
"name" : "646378" ,
"<<<span class="speller-hint" data-toggle="popover" data-hint="13" data-original-title="" title="">span</span> class="<span class="speller-hint" data-toggle="popover" data-hint="14" data-original-title="" title="">speller</span>-hint" data-toggle="popover" data-hint="33" data-original-title="" title="">span</span> class="<span class="<span class="speller-hint" data-toggle="popover" data-hint="15" data-original-title="" title="">speller</span>-hint" data-toggle="popover" data-hint="34" data-original-title="" title="">speller</span>-hint" data-toggle="popover" data-hint="16" data-original-title="" title=""><span class="speller-hint" data-toggle="popover" data-hint="35" data-original-title="" title="">homePage</span></span>" : "<a href="https://id.2035.university/">https://id.2035.university</a>"
},
"<<span class="speller-hint" data-toggle="popover" data-hint="36" data-original-title="" title="">span</span> class="<span class="speller-hint" data-toggle="popover" data-hint="37" data-original-title="" title="">speller</span>-hint" data-toggle="popover" data-hint="17" data-original-title="" title=""><span class="speller-hint" data-toggle="popover" data-hint="38" data-original-title="" title="">objectType</span></span>" : "Agent"
}
],
"objectType" : "Group"
},
"<<span class="speller-hint" data-toggle="popover" data-hint="39" data-original-title="" title="">span</span> class="<span class="speller-hint" data-toggle="popover" data-hint="40" data-original-title="" title="">speller</span>-hint" data-toggle="popover" data-hint="18" data-original-title="" title=""><span class="speller-hint" data-toggle="popover" data-hint="41" data-original-title="" title="">contextActivities</span></span>" : {
"parent" : [
{
"definition" : {
"name" : {
"ru-RU" : "Хакатон по CV"
},
"description" : {
"ru-RU" : "Хакатон по компьютерному зрению и распознаванию изображений"
}
},
"id" : "<a href="https://hackathon_cv.2035.university/">https://hackathon_cv.2035.university</a>" ,
"<<span class="speller-hint" data-toggle="popover" data-hint="42" data-original-title="" title="">span</span> class="<span class="speller-hint" data-toggle="popover" data-hint="43" data-original-title="" title="">speller</span>-hint" data-toggle="popover" data-hint="19" data-original-title="" title=""><span class="speller-hint" data-toggle="popover" data-hint="44" data-original-title="" title="">objectType</span></span>" : "Activity"
},
{
"definition" : {
"name" : {
"ru-RU" : "Задача 12"
},
"description" : {
"ru-RU" : "Задача распознавания номеров автомобиля в ветреную и снежную погоду"
}
},
"id" : "<a href="https://hackathon_cv.2035.university/task_12">https://hackathon_cv.2035.university/task_12</a>" ,
"<<span class="speller-hint" data-toggle="popover" data-hint="45" data-original-title="" title="">span</span> class="<span class="speller-hint" data-toggle="popover" data-hint="46" data-original-title="" title="">speller</span>-hint" data-toggle="popover" data-hint="20" data-original-title="" title=""><span class="speller-hint" data-toggle="popover" data-hint="47" data-original-title="" title="">objectType</span></span>" : "Activity"
}
]
},
"extensions" : {
"<a href="http://id/">http://id</a>&46;tincanapi&46;com/extension/observer" : {
"name" : "Алексей Фиксиков" ,
"account" : {
"name" : "575838" ,
"<<<span class="speller-hint" data-toggle="popover" data-hint="16" data-original-title="" title="">span</span> class="<span class="speller-hint" data-toggle="popover" data-hint="17" data-original-title="" title="">speller</span>-hint" data-toggle="popover" data-hint="48" data-original-title="" title="">span</span> class="<span class="<span class="speller-hint" data-toggle="popover" data-hint="18" data-original-title="" title="">speller</span>-hint" data-toggle="popover" data-hint="49" data-original-title="" title="">speller</span>-hint" data-toggle="popover" data-hint="21" data-original-title="" title=""><span class="speller-hint" data-toggle="popover" data-hint="50" data-original-title="" title="">homePage</span></span>" : "<a href="https://id.2035.university/">https://id.2035.university</a>"
},
"<<span class="speller-hint" data-toggle="popover" data-hint="51" data-original-title="" title="">span</span> class="<span class="speller-hint" data-toggle="popover" data-hint="52" data-original-title="" title="">speller</span>-hint" data-toggle="popover" data-hint="22" data-original-title="" title=""><span class="speller-hint" data-toggle="popover" data-hint="53" data-original-title="" title="">objectType</span></span>" : "Agent"
},
"<a href="https://id/">https://id</a>&46;2035&46;university/xapi/extension/actor-role" : "Full stack программист"
}
},
"attachments" : [
{
"usageType" : "<a href="http://id.tincanapi.com/attachment/supporting_media">http://id.tincanapi.com/attachment/supporting_media</a>" ,
"display" : {
"ru-RU" : "Программный код"
},
"description" : {
"ru-RU" : "Программный код для распознавания изображений в рамках датасета"
},
"contentType" : "text/plain" ,
"length" : 4681,
"sha2" : "" ,
"<<<span class="speller-hint" data-toggle="popover" data-hint="19" data-original-title="" title="">span</span> class="<span class="speller-hint" data-toggle="popover" data-hint="20" data-original-title="" title="">speller</span>-hint" data-toggle="popover" data-hint="54" data-original-title="" title="">span</span> class="<span class="<span class="speller-hint" data-toggle="popover" data-hint="21" data-original-title="" title="">speller</span>-hint" data-toggle="popover" data-hint="55" data-original-title="" title="">speller</span>-hint" data-toggle="popover" data-hint="23" data-original-title="" title=""><span class="speller-hint" data-toggle="popover" data-hint="56" data-original-title="" title="">fileUrl</span></span>" : "<a href="https://github.com/user/pupkin/cars/cv.c">https://github.com/user/pupkin/cars/cv.c</a>"
}
],
"stored" : "2020-04-07T14:01:18.306Z" ,
"version" : "1.0.0"
},
"metadata" : {
"<<span class="speller-hint" data-toggle="popover" data-hint="24" data-original-title="" title="">a</span> href="https://<span class="speller-hint" data-toggle="popover" data-hint="25" data-original-title="" title="">learninglocker</span>/">https://<span class="speller-hint" data-toggle="popover" data-hint="26" data-original-title="" title="">learninglocker</span></a>&46;net/result-duration" : {
"seconds" : 9840
}
},
"<<span class="speller-hint" data-toggle="popover" data-hint="57" data-original-title="" title="">span</span> class="<span class="speller-hint" data-toggle="popover" data-hint="58" data-original-title="" title="">speller</span>-hint" data-toggle="popover" data-hint="27" data-original-title="" title=""><span class="speller-hint" data-toggle="popover" data-hint="59" data-original-title="" title="">processingQueues</span></span>" : [],
"personaIdentifier" : "5e8c87ae02648851e13a6029" ,
"<<span class="speller-hint" data-toggle="popover" data-hint="60" data-original-title="" title="">span</span> class="<span class="speller-hint" data-toggle="popover" data-hint="61" data-original-title="" title="">speller</span>-hint" data-toggle="popover" data-hint="28" data-original-title="" title="">completedQueues</span>" : [
"STATEMENT_FORWARDING_QUEUE" ,
"STATEMENT_PERSON_QUEUE" ,
"<span class="speller-hint" data-toggle="popover" data-hint="29" data-original-title="" title="">STATEMENT</span>_<span class="speller-hint" data-toggle="popover" data-hint="30" data-original-title="" title="">QUERYBUILDERCACHE</span>_QUEUE"
],
"__v" : 1,
"<<span class="speller-hint" data-toggle="popover" data-hint="62" data-original-title="" title="">span</span> class="<span class="speller-hint" data-toggle="popover" data-hint="63" data-original-title="" title="">speller</span>-hint" data-toggle="popover" data-hint="31" data-original-title="" title="">completedForwardingQueue</span>" : [],
"<<span class="speller-hint" data-toggle="popover" data-hint="64" data-original-title="" title="">span</span> class="<span class="speller-hint" data-toggle="popover" data-hint="65" data-original-title="" title="">speller</span>-hint" data-toggle="popover" data-hint="32" data-original-title="" title="">deadForwardingQueue</span>" : [],
"<<span class="speller-hint" data-toggle="popover" data-hint="66" data-original-title="" title="">span</span> class="<span class="speller-hint" data-toggle="popover" data-hint="67" data-original-title="" title="">speller</span>-hint" data-toggle="popover" data-hint="33" data-original-title="" title="">failedForwardingLog</span>" : [],
"<<span class="speller-hint" data-toggle="popover" data-hint="68" data-original-title="" title="">span</span> class="<span class="speller-hint" data-toggle="popover" data-hint="69" data-original-title="" title="">speller</span>-hint" data-toggle="popover" data-hint="34" data-original-title="" title="">pendingForwardingQueue</span>" : []
}
|