269 lines
16 KiB
Plaintext
269 lines
16 KiB
Plaintext
#Область ОбработчикиHTTPСервиса
|
|
|
|
Функция Health(Запрос) Экспорт
|
|
Возврат ОтветJSON(BridgeHealth());
|
|
КонецФункции
|
|
|
|
Функция MetadataSnapshot(Запрос) Экспорт
|
|
Контекст = ПрочитатьКонтекст(Запрос);
|
|
Если Не Авторизован(Запрос, Контекст) Тогда
|
|
Возврат ОтветОшибка(401, "Unauthorized");
|
|
КонецЕсли;
|
|
Возврат ОтветJSON(BridgeMetadataSnapshot());
|
|
КонецФункции
|
|
|
|
Функция Query(Запрос) Экспорт
|
|
Контекст = ПрочитатьКонтекст(Запрос);
|
|
Если Не Авторизован(Запрос, Контекст) Тогда
|
|
Возврат ОтветОшибка(401, "Unauthorized");
|
|
КонецЕсли;
|
|
Возврат ОтветJSON(BridgeExecuteQuery(
|
|
ПолучитьПоле(Контекст, "payload", Новый Структура),
|
|
ПолучитьПоле(Контекст, "dry_run", Истина),
|
|
ПолучитьПоле(Контекст, "allow_mutation", Ложь)));
|
|
КонецФункции
|
|
|
|
Функция DataRead(Запрос) Экспорт
|
|
Контекст = ПрочитатьКонтекст(Запрос);
|
|
Если Не Авторизован(Запрос, Контекст) Тогда
|
|
Возврат ОтветОшибка(401, "Unauthorized");
|
|
КонецЕсли;
|
|
Возврат ОтветJSON(BridgeReadData(ПолучитьПоле(Контекст, "payload", Новый Структура)));
|
|
КонецФункции
|
|
|
|
Функция DataWrite(Запрос) Экспорт
|
|
Контекст = ПрочитатьКонтекст(Запрос);
|
|
Если Не Авторизован(Запрос, Контекст) Тогда
|
|
Возврат ОтветОшибка(401, "Unauthorized");
|
|
КонецЕсли;
|
|
Возврат ОтветJSON(BridgeWriteData(
|
|
ПолучитьПоле(Контекст, "payload", Новый Структура),
|
|
ПолучитьПоле(Контекст, "dry_run", Истина),
|
|
ПолучитьПоле(Контекст, "allow_mutation", Ложь)));
|
|
КонецФункции
|
|
|
|
Функция MetadataApply(Запрос) Экспорт
|
|
Контекст = ПрочитатьКонтекст(Запрос);
|
|
Если Не Авторизован(Запрос, Контекст) Тогда
|
|
Возврат ОтветОшибка(401, "Unauthorized");
|
|
КонецЕсли;
|
|
Возврат ОтветJSON(BridgeMetadataApply(
|
|
ПолучитьПоле(Контекст, "payload", Новый Структура),
|
|
ПолучитьПоле(Контекст, "dry_run", Истина)));
|
|
КонецФункции
|
|
|
|
#КонецОбласти
|
|
|
|
#Область ЛогикаSFERA
|
|
|
|
Функция BridgeHealth()
|
|
Результат = Новый Структура;
|
|
Результат.Вставить("status", "ok");
|
|
Результат.Вставить("extension", "SFERA");
|
|
Результат.Вставить("version", "0.1.0");
|
|
Результат.Вставить("timestamp", ТекущаяДата());
|
|
Результат.Вставить("mutation_supported", Истина);
|
|
Результат.Вставить("metadata_apply_supported", Ложь);
|
|
Возврат Результат;
|
|
КонецФункции
|
|
|
|
Функция BridgeMetadataSnapshot()
|
|
Коллекции = Новый Массив;
|
|
ДобавитьКоллекциюМетаданных(Коллекции, "Справочники", Метаданные.Справочники);
|
|
ДобавитьКоллекциюМетаданных(Коллекции, "Документы", Метаданные.Документы);
|
|
ДобавитьКоллекциюМетаданных(Коллекции, "Перечисления", Метаданные.Перечисления);
|
|
ДобавитьКоллекциюМетаданных(Коллекции, "Отчеты", Метаданные.Отчеты);
|
|
ДобавитьКоллекциюМетаданных(Коллекции, "Обработки", Метаданные.Обработки);
|
|
ДобавитьКоллекциюМетаданных(Коллекции, "ПланыОбмена", Метаданные.ПланыОбмена);
|
|
ДобавитьКоллекциюМетаданных(Коллекции, "ПланыВидовХарактеристик", Метаданные.ПланыВидовХарактеристик);
|
|
ДобавитьКоллекциюМетаданных(Коллекции, "ПланыСчетов", Метаданные.ПланыСчетов);
|
|
ДобавитьКоллекциюМетаданных(Коллекции, "ПланыВидовРасчета", Метаданные.ПланыВидовРасчета);
|
|
ДобавитьКоллекциюМетаданных(Коллекции, "РегистрыСведений", Метаданные.РегистрыСведений);
|
|
ДобавитьКоллекциюМетаданных(Коллекции, "РегистрыНакопления", Метаданные.РегистрыНакопления);
|
|
ДобавитьКоллекциюМетаданных(Коллекции, "РегистрыБухгалтерии", Метаданные.РегистрыБухгалтерии);
|
|
ДобавитьКоллекциюМетаданных(Коллекции, "РегистрыРасчета", Метаданные.РегистрыРасчета);
|
|
ДобавитьКоллекциюМетаданных(Коллекции, "БизнесПроцессы", Метаданные.БизнесПроцессы);
|
|
ДобавитьКоллекциюМетаданных(Коллекции, "Задачи", Метаданные.Задачи);
|
|
ДобавитьКоллекциюМетаданных(Коллекции, "ОбщиеМодули", Метаданные.ОбщиеМодули);
|
|
ДобавитьКоллекциюМетаданных(Коллекции, "Роли", Метаданные.Роли);
|
|
ДобавитьКоллекциюМетаданных(Коллекции, "Подсистемы", Метаданные.Подсистемы);
|
|
ДобавитьКоллекциюМетаданных(Коллекции, "HTTPСервисы", Метаданные.HTTPСервисы);
|
|
ДобавитьКоллекциюМетаданных(Коллекции, "WebСервисы", Метаданные.WebСервисы);
|
|
Результат = Новый Структура;
|
|
Результат.Вставить("status", "ok");
|
|
Результат.Вставить("collections", Коллекции);
|
|
Возврат Результат;
|
|
КонецФункции
|
|
|
|
Функция BridgeExecuteQuery(Параметры, DryRun, AllowMutation)
|
|
ТекстЗапроса = Строка(ПолучитьПоле(Параметры, "query", ""));
|
|
Если ПустаяСтрока(ТекстЗапроса) Тогда
|
|
Возврат ОшибкаSFERA("query is required");
|
|
КонецЕсли;
|
|
Если ЗапросОпасный(ТекстЗапроса) И Не AllowMutation Тогда
|
|
Возврат ОшибкаSFERA("Mutation query is blocked. Set allow_mutation=true and disable dry_run.");
|
|
КонецЕсли;
|
|
Если DryRun Тогда
|
|
Результат = Новый Структура;
|
|
Результат.Вставить("status", "dry_run");
|
|
Результат.Вставить("query", ТекстЗапроса);
|
|
Результат.Вставить("mutation_detected", ЗапросОпасный(ТекстЗапроса));
|
|
Возврат Результат;
|
|
КонецЕсли;
|
|
Запрос = Новый Запрос(ТекстЗапроса);
|
|
ПараметрыЗапроса = ПолучитьПоле(Параметры, "parameters", Неопределено);
|
|
Если ТипЗнч(ПараметрыЗапроса) = Тип("Структура") Тогда
|
|
Для Каждого Параметр Из ПараметрыЗапроса Цикл
|
|
Запрос.УстановитьПараметр(Параметр.Ключ, Параметр.Значение);
|
|
КонецЦикла;
|
|
КонецЕсли;
|
|
Таблица = Запрос.Выполнить().Выгрузить();
|
|
Строки = Новый Массив;
|
|
Для Каждого СтрокаТаблицы Из Таблица Цикл
|
|
Строки.Добавить(СтрокаТаблицыВСтруктуру(СтрокаТаблицы, Таблица.Колонки));
|
|
Если Строки.Количество() >= 1000 Тогда
|
|
Прервать;
|
|
КонецЕсли;
|
|
КонецЦикла;
|
|
Результат = Новый Структура;
|
|
Результат.Вставить("status", "ok");
|
|
Результат.Вставить("rows", Строки);
|
|
Результат.Вставить("limit", 1000);
|
|
Возврат Результат;
|
|
КонецФункции
|
|
|
|
Функция BridgeReadData(Параметры)
|
|
Если ЗначениеЗаполнено(ПолучитьПоле(Параметры, "query", "")) Тогда
|
|
Возврат BridgeExecuteQuery(Параметры, Ложь, Ложь);
|
|
КонецЕсли;
|
|
Возврат ОшибкаSFERA("For generic data read use query with SELECT text.");
|
|
КонецФункции
|
|
|
|
Функция BridgeWriteData(Параметры, DryRun, AllowMutation)
|
|
Если Не AllowMutation Тогда
|
|
Возврат ОшибкаSFERA("Write operation is blocked.");
|
|
КонецЕсли;
|
|
Если DryRun Тогда
|
|
Результат = Новый Структура;
|
|
Результат.Вставить("status", "dry_run");
|
|
Результат.Вставить("message", "Write request accepted for preview only.");
|
|
Результат.Вставить("payload", Параметры);
|
|
Возврат Результат;
|
|
КонецЕсли;
|
|
Возврат ОшибкаSFERA("Generic write adapter is intentionally not enabled yet. Implement object-specific handlers first.");
|
|
КонецФункции
|
|
|
|
Функция BridgeMetadataApply(Параметры, DryRun)
|
|
Результат = Новый Структура;
|
|
Результат.Вставить("status", "planned");
|
|
Результат.Вставить("message", "Changing configuration structure is performed by SFERA Windows Agent through Designer and .cfe update, not by runtime HTTP.");
|
|
Результат.Вставить("dry_run", DryRun);
|
|
Результат.Вставить("payload", Параметры);
|
|
Возврат Результат;
|
|
КонецФункции
|
|
|
|
#КонецОбласти
|
|
|
|
#Область СлужебныеПроцедурыИФункции
|
|
|
|
Функция ПрочитатьКонтекст(Запрос)
|
|
Тело = Запрос.ПолучитьТелоКакСтроку();
|
|
Если ПустаяСтрока(Тело) Тогда
|
|
Возврат Новый Структура;
|
|
КонецЕсли;
|
|
Чтение = Новый ЧтениеJSON;
|
|
Чтение.УстановитьСтроку(Тело);
|
|
Возврат ПрочитатьJSON(Чтение);
|
|
КонецФункции
|
|
|
|
Функция Авторизован(Запрос, Контекст)
|
|
// Основная авторизация выполняется публикацией 1С/IIS. Токен SFERA включается после настройки секрета.
|
|
ОжидаемыйТокен = "";
|
|
Если ПустаяСтрока(ОжидаемыйТокен) Тогда
|
|
Возврат Истина;
|
|
КонецЕсли;
|
|
Возврат Запрос.Заголовки.Получить("X-SFERA-Token") = ОжидаемыйТокен;
|
|
КонецФункции
|
|
|
|
Функция ОтветJSON(Данные, КодСостояния = 200)
|
|
Запись = Новый ЗаписьJSON;
|
|
Запись.УстановитьСтроку();
|
|
ЗаписатьJSON(Запись, Данные);
|
|
Тело = Запись.Закрыть();
|
|
Ответ = Новый HTTPСервисОтвет(КодСостояния);
|
|
Ответ.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
|
|
Ответ.УстановитьТелоИзСтроки(Тело, КодировкаТекста.UTF8);
|
|
Возврат Ответ;
|
|
КонецФункции
|
|
|
|
Функция ОтветОшибка(КодСостояния, Сообщение)
|
|
Данные = Новый Структура;
|
|
Данные.Вставить("status", "error");
|
|
Данные.Вставить("message", Сообщение);
|
|
Возврат ОтветJSON(Данные, КодСостояния);
|
|
КонецФункции
|
|
|
|
Функция ПолучитьПоле(СтруктураИсточник, ИмяПоля, ЗначениеПоУмолчанию = Неопределено)
|
|
Если ТипЗнч(СтруктураИсточник) = Тип("Структура") И СтруктураИсточник.Свойство(ИмяПоля) Тогда
|
|
Возврат СтруктураИсточник[ИмяПоля];
|
|
КонецЕсли;
|
|
Возврат ЗначениеПоУмолчанию;
|
|
КонецФункции
|
|
|
|
Процедура ДобавитьКоллекциюМетаданных(Коллекции, ИмяКоллекции, КоллекцияМетаданных)
|
|
Объекты = Новый Массив;
|
|
Для Каждого ОбъектМетаданных Из КоллекцияМетаданных Цикл
|
|
Описание = Новый Структура;
|
|
Описание.Вставить("name", ОбъектМетаданных.Имя);
|
|
Описание.Вставить("synonym", ОбъектМетаданных.Синоним);
|
|
Описание.Вставить("full_name", ИмяКоллекции + "." + ОбъектМетаданных.Имя);
|
|
Объекты.Добавить(Описание);
|
|
КонецЦикла;
|
|
Коллекция = Новый Структура;
|
|
Коллекция.Вставить("name", ИмяКоллекции);
|
|
Коллекция.Вставить("count", Объекты.Количество());
|
|
Коллекция.Вставить("objects", Объекты);
|
|
Коллекции.Добавить(Коллекция);
|
|
КонецПроцедуры
|
|
|
|
Функция ЗапросОпасный(ТекстЗапроса)
|
|
Текст = НРег(ТекстЗапроса);
|
|
Возврат Найти(Текст, "вставить") > 0
|
|
Или Найти(Текст, "изменить") > 0
|
|
Или Найти(Текст, "удалить") > 0
|
|
Или Найти(Текст, "поместить") > 0
|
|
Или Найти(Текст, "создать") > 0;
|
|
КонецФункции
|
|
|
|
Функция СтрокаТаблицыВСтруктуру(СтрокаТаблицы, Колонки)
|
|
Результат = Новый Структура;
|
|
Для Каждого Колонка Из Колонки Цикл
|
|
Результат.Вставить(Колонка.Имя, ЗначениеДляJSON(СтрокаТаблицы[Колонка.Имя]));
|
|
КонецЦикла;
|
|
Возврат Результат;
|
|
КонецФункции
|
|
|
|
Функция ЗначениеДляJSON(Значение)
|
|
Если Значение = Неопределено Или Значение = Null Тогда
|
|
Возврат Неопределено;
|
|
КонецЕсли;
|
|
Если ТипЗнч(Значение) = Тип("Строка")
|
|
Или ТипЗнч(Значение) = Тип("Число")
|
|
Или ТипЗнч(Значение) = Тип("Булево") Тогда
|
|
Возврат Значение;
|
|
КонецЕсли;
|
|
Если ТипЗнч(Значение) = Тип("Дата") Тогда
|
|
Возврат Формат(Значение, "ДФ=yyyy-MM-ddTHH:mm:ss");
|
|
КонецЕсли;
|
|
Возврат Строка(Значение);
|
|
КонецФункции
|
|
|
|
Функция ОшибкаSFERA(Сообщение)
|
|
Результат = Новый Структура;
|
|
Результат.Вставить("status", "error");
|
|
Результат.Вставить("message", Сообщение);
|
|
Возврат Результат;
|
|
КонецФункции
|
|
|
|
#КонецОбласти
|