Демо-задача
Автономное веб-приложения для учета движения наличных денег:
- Два справочника:
- Кассы (считаем, что кошельки, контрагенты, подотчетники и т.д. – это просто разные кассы)
- Статьи ДДС – для простейшей аналитики
- Один документ: Перемещение денег (куда, откуда, статья, сумма)
- Один отчет: Ведомость по денежным средствам
Приложение должно обеспечивать возможность ввода и редактирования документов как из веб-интерфейса, так и средствами 1С и сохранять работоспособность при недоступности сервера или поломках доступа в Интернет.
Чтобы не усложнять пример, ограничение прав на уровне записей не рассматриваем. Пользователь веб-приложения увидит и сможет изменять документы по всем кассам. В реальных задачах используется фильтрованная репликация, когда документы передаются в браузер с учетом RLS.
Результат
Живое демо доступно по ссылке: https://light.oknosoft.ru/helloworld/
- Движок легко справляется с тысячами одновременных сеансов
- Сервер 1С для обслуживания веб-клиентов не используется
- Публикации SOAP и HTTP сервисов не требуется
Содержание
- Подготовка базы 1С. Готовая dt-шка есть в прикрепленных файлах. Опишу, что именно делалось со стороны конфигуратора
- Подготовка инфраструктуры. Для отладки и публикации, нужны установленный локально NodeJS, а так же серверы CouchDB и Nginx. CouchDB и Nginx могут располагаться как на локальном компьютере, так и удаленно на любом компьютере в Интернет
- Настройка состава метаданных, а так же, синонимов и начальное заполнение, выполняются в режиме 1С:Предприятие
- Подготовка веб-приложения. Структуру каталогов и необходимые файлы развернём в любой удобной папке на локальном компьютере с помощью npm
- Публикация веб-приложения. Рассмотрим необходимые и достаточные шаги для публикации приложения в Интернет
Одно без другого недостаточно информативно.
Шаг №1 CouchDB
Выбору CouchDB для back-end metadata.js предшествовала большая работа. В первую очередь, рассматривался PostgreSQL, ставились эксперименты с MySQL, Couchbase и MongoDB, но я не смог устоять перед уникальными возможностями CouchDB:
- В разработку собственного движка синхронизации данных, я вложил не менее года, но когда увидел математику master-master репликации CouchDB, без сожаления выбросил своё творчество на помойку
- Запас масштабируемости – есть примеры систем на кластере CouchDB с посещаемостью 500 млн. запросов в сутки (до 10000 транзакций в секунду)
- 100% HTTP API – не требуются никаких бинарных драйверов
- Возможность подключить внешний низкоуровневый движок обработки запросов и построения индексов. Например, скрипт на NodeJS.
Прочтите последний пункт еще раз: Metadata использует для хранения данных CouchDB, которая, в свою очередь, может использовать метадату для низкоуровневого построения индексов и агрегатов!!!
С установкой CouchDB проблем не возникнет – готовые образы виртуальных машин Linux для VMDK, OpenStack, Xen, Docker, ProxMox или установочный iso-файл можно взять, например, в turnkeylinux. Исходные тексты и дистрибутивы для всех платформ доступны официальном сайте couchdb.org
После установки, необходимо выполнить два действия:
- Задать пароль администратора
- Указать в секции httpd, слушать все ip-адреса (установить bind_address = 0.0.0.0). По умолчанию, служба CouchDB, слушает только localhost и обратиться к серверу снаружи невозможно
Остальные настройки библиотека интеграции сделает из режима 1С:Предприятие.
Задачи CouchDB при взаимодействии с 1С:
- CouchDB предоставляет 1C-ке http интерфейс для записи и чтения произвольных данных. Повторюсь, в ранних редакциях metadata, предпринимались попытки использовать для этих целей файловую систему или базу SQL. Эти подходы имели проблемы с версионированием и удобством отслеживания и синхронизации изменений. CouchDB чем то похожа на Git, где с версионированием всё хорошо, но Git – это не база данных. Map/reduce индекса на нём не построишь.
Для простоты можно считать, что CouchDB – это такая штука, в которую 1С-ка в любой момент может без блокировок записать любой сериализуемый объект (в CouchDB запись и чтение неблокирующие. 1000 клиентов могут одновременно читать и писать одни и те же данные) - На начальном этапе и при изменении структуры конфигурации, 1С складывает в CouchDB подробное описание своих метаданных. По этому описанию, движкок metadata компилирует javascript-файлы с конструкторами объектов данных, Плюс, создаёт скрипты sql для таблиц в памяти браузера
- Далее, при редактировании в 1С любого объекта, в подписке на событие «при записи», изменения этого объекта отправляются в CouchDB. Происходит подобие «регистрации изменений в плане обмена»
- В фоновых заданиях, 1С-ка запрашивает у CouchDB список объектов, изменённых с момента последней синхронизации, читает и записывает изменённые объекты. При интенсивной работе, фоновые задачи репликации можно запускать в несколько потоков
Шаг №2 Nginx
Nginx используется в нашем проекте по прямому назначению: для отдачи статических файлов, балансировки нагрузки и редиректов http запросов к сервисам. Апологеты Apache или IIS, могут настроить те же функции средствами их любимых серверов, но лично мне, ближе синтаксис nginx.conf. Особенно, после того как в нём поддержаны сценарии javascript. Пример nginx.conf есть в прикрепленных файлах. В большинстве случаев, годятся настройки по умолчанию. Достаточно указать путь к папке с файлами веб-приложения.
В production-окружении, службы CouchDB, Apach и Nginx, обычно размещают на разных физических или виртуальных серверах. Рекомендуется перенаправлять браузеры клиентов с http на https, чтобы пароли и прочие данные веб-приложения передавались исключительно по шифрованному каналу.
Исходные тексты и дистрибутивы для всех платформ доступны официальном сайте nginx.org
Шаг №3 NodeJS
В нашей задаче, Node.js используется только на этапах подготовки и сборки проекта. С его помощью, мы развернём структуру папок и файлов приложения helloworld, а так же, скомпилируем итоговые файлы для публикации в Интернет.
Исходные тексты и дистрибутивы для всех платформ доступны официальном сайте nodejs.org
Шаг №4 IDE
Если у вас уже установлен любимый редактор кода javascript, этот абзац можно пропустить. Для остальных, предлагаю обратить внимание на WebStorm и NetBeans. WebStorm платный, NetBeans не требует денег за подписку. Выбор за вами.
Шаг №5 Файлы проекта
Создадим пустой каталог. Например, c:\www
и перейдём в него в командном интерпретаторе. Предполагается, что nodejs уже установлен.
Выполним команды:
PS C:\users> cd c:\www
PS C:\www> npm install -g metadata-js@0.11.223
Metadata.js будет установлена глобально и зарегистриуется утилита командной строки metadata.
PS C:\www> npm install -g gulp-cli
Установит глобально и зарегистрирует утилиту командной строки менеджера задач gulp
PS C:\www> metadata init
Создаст начальную структуру проекта
PS C:\www> npm install
Установит дополнительные библиотеки (зависимости), необходимые движку metadata.js
Инсталляция потребует некоторого времени. Из Интернета загружается около 200Mb кода.
При установке зависимостей, могут появляться сообщения об ошибках. Обычно, это не мешает работе веб-приложения.
Мы в одном шаге от запуска демо-примера.
Если CouchDB установлен локально, на этом же компьютере, проект можно не пересобирать и сразу открыть файл c:\www\index.html
в браузере Chrome. Должно открыться демо-приложение и ругнуться на отсутствие данных в CouchDB. Их мы подготовим на следующем шаге.
Если CouchDB установлен на другом компьютере в локальной или глобальной сети, необходимо пересобрать проект, предварительно, указав в настройках по умолчанию, строку подключения к серверу. Отредактировать файл настроек package.json
можно любым текстовым редактором. Указываем в параметре config->couchdb
тот же путь, который указан для этого параметра в 1С.
Чтобы перекомпилировать файлы проекта, выполним в командной строке:
PS C:\www> gulp full
Для отладки в файловом режиме, просто открываем c:\www\index.html
в Chrome. Остальные браузеры блокируют исходящие запросы со страниц, открытых по протоколу file:///
.
Чтобы наше приложение заработало в любом браузере локальной сети, достаточно поместить файлы из c:\www\
в папку веб-сервера. Папка не обязана быть корневой. Например, если корень apache или nginx смотрит на c:\www-data\
, можно создать папку c:\www-data\helloworld\
и поместить в неё содержимое нашего проекта. В браузере проект будет доступен по http://localhost/helloworld/
или http://имякомпьютера/helloworld/
. На вебсервер нет необходимости переносить всю структуру проекта.
Достаточно скопировать папку dist
и файлы index.html
, cache.appcache
и manifest.json
.
Вместе со структурой папок, которую мы получили командой metadata init
, в каждой папке был создан файл README.md
, поясняющий назначение папки. Исходные тексты и шаблоны, располагаются в иерархии папки src
. Особый интерес представляют папки внутри src/modifiers
. Там живут модули объектов и менеджеров наших документов и справочников, а так же, общие модули.
В демо-примере задействована единственная подписка на событие – при создании документа «ПеремещениеДенег». Обработчик живёт в файле src\modifiers\documents\doc_cash_moving.js
и выполняет единственное действие: назначает номер новому документу
// Подписываемся на события
$p.doc.cash_moving.on({
/**
* Обработчик при создании документа
*/
after_create: function (attr) {
//Номер документа
return this.new_number_doc();
}
});
Клиентский код про формы в демке отсутствует - используются автоформы.
При необходимости, можно добавить обработчики на событие «при изменении реквизита» и пересчитывать одни поля при изменении других. Например, рассчитывать итог в табличной части или подставлять договор при изменении организации или контрагента.
Есть возможность полностью переопределить любую форму, добавив соответствующий метод в менеджере объекта.
Еще, в папке модификаторов есть несколько служебных модулей (cat_users_acl.js
, cch_predefined_elmnts.js
и cch_properties.js
). Эти файлы – аналог модулей объектов из БСП, реализующих стандартную функциональность.
Шаг №6 конфигурация 1С
Можно взять готовую dt-шку из прикрепленных файлов и добавить в неё объекты прикладной задачи. Для полноты картины, рассмотрим, как делалась эта каркасная dt-шка:
- Создаём пустую конфигурацию, присваиваем ей имя (в нашем случае «МетадатаДемо»), создаём подсистему «МетадатаДемо»
- Т.к. библиотека интеграции использует БСП, производим сравнение-объединение с актуальной версией БСП с постановкой на поддержку
- Включаем возможность внесения изменений в следующие объекты БСП:
- Общие модули «ПодсистемыКонфигурацииПереопределяемый» и «УправлениеСвойствамиПереопределяемый»
- Справочник «ВидыКонтактнойИнформации» – в него добавим предопределенные элементы, чтобы у наших касс появилась закладка с контактной информацией
- Справочник «НаборыДополнительныхРеквизитовИСведений» – в него добавим предопределенные элементы, чтобы у наших касс появились настраиваемые дополнительные реквизиты
- План видов характеристик «ДополнительныеРеквизитыИСведения» - при необходимости расширения состава типов дополнительных реквизитов
- Добавляем общий модуль «ОбновлениеИнформационнойБазыМетадатаДемо» и указываем на него ссылку в модуле «ПодсистемыКонфигурацииПереопределяемый»
Рассмотренные шаги – стандартная процедура подключения БСП. Далее, подключаем библиотеку интеграции (cf-ка есть в прикрепленных файлах)
- Производим сравнение-объединение с библиотекой интеграции с постановкой на поддержку
- Включаем возможность внесения изменений в определяемые типы библиотеки интеграции и БСП – изменим их состав после того, как в конфигурацию будут добавлены наши документы и справочники
- Включаем возможность внесения изменений в общий модуль «ИнтеграцияПереопределяемый» - в нём укажем ссылку на процедуру формирования начального образа данных. Так же, в этом модуле можно переопределить правила сериализации данных, но в демо-примере эта возможность не используется
- Добавляем справочники «ДДС» и «Кассы» и документ «ПеремещениеДенг»
- Добавляем общий модуль «ИнтеграцияМетадатаДемо» и реализуем в нём процедуру НачальноеЗаполнениеФинализация()
Из-за внедренных библиотек БСП и Окнософт:Интеграция, конфигурация получается довольно толстой (400 общих модулей, 70 справочников, 100 регистров и т.д.), но при включенном отборе по подсистемам, объекты демо-задачи помещаются на один экран.
Важную роль при настройке конфигурации имеют определяемые типы библиотеки интеграции:
- ИнтеграцияСсылка – в состав этого типа надо включить все ссылочные метаданные, которые потребуются веб-приложению. Для экономии трафика и памяти браузера, не рекомендуется включать в этот тип неиспользуемые метаданные. С другой стороны, важно не забывать про связанные ссылочные типы. Например, при добавлении справочника «Номенклатура», следует добавить справочники «Виды номенклатуры» и «Номенклатурные группы»
- ИнтеграцияОбъект – включает авторегистрацию изменений. Если предыдущий тип определяет, можно ли в принципе передать в CouchDB некие данные, то текущий, указывает, должны ли изменения передаваться в CouchDB автоматически при записи каждого объекта
- ИнтеграцияНаборЗаписей – аналогично предыдущему, но относится к регистрам сведений и накопления, а не к ссылочным типам
Работа со стороны конфигуратора закончена, дальнейшую настройку будем делать в режиме 1С:Предприятие.
Шаг №7 Связь с CouchDB и начальный образ данных
- Задать адреса сервисов
- Включить CORS
- Настроить базы
- Выгрузить описание метаданных
- Зарегистрировать начальный образ
Запускаем 1С в режиме предприятия и открываем обработку «Интеграция: настройка»
На первой закладке необходимо указать:
- Адрес (url) сервера CouchDB с префиксом баз проекта. В нашем случае, сервер крутится на компьютере с именем
i980
порт5984
и префикс =hw_
. Префиксы позволяют разместить базы нескольких, разных по структуре или одинаковых проектов на одном сервере - Имя и пароль администратора CouchDB – с этими учетными данными, подсистема интеграции 1С будет взаимодействовать с CouchDB
- В табличную часть «Пользователи», необходимо добавить минимум одного пользователя и указать для него пароль и роли на сервере CouchDB. Роли задаются в виде массива строк. Разработчик прикладного решения может при необходимости добавить произвольное число ролей. По умолчанию, в metadata.js используются роли:
- doc_reader – может читать объекты из базы doc
- ram_reader – может читать объекты из базы ram
- doc_editor – может изменять объекты в базе doc, но для него действуют фильтры RLS
- ram_editor – может изменять объекты в базе ram
- doc_full - может изменять объекты в базе doc, RLS на него не распространяется
- Галку «Active» на этапе начальной настройки можно снять. Она включает режим авторегистрации изменений, когда при записи любого объекта в 1С, изменения синхронно передаются в CouchDB
- Галку «Check» на этапе начальной настройки можно снять. Она включает режим обязательного контроля регистрации изменений в CouchDB. Если галки Check и Active взведены, а сервер CouchDB выключен, при попытке записать документ или элемент справочника, включенный в состав обмена, при записи возникнет ошибка – изменения записаны не будут
- Поле «Zone» в демо-примере не используется. С его помощью, библиотека интеграции реализует функциональность, схожую с 1С:Fresh, когда к одной физической базе 1С подключено несколько абонентов (групп пользователей) с полностью изолированными или частично пересекающимися областями данных
- Поле «Since» и кнопка «Прочитать» используются для отладки обратной связи с CouchDB
На второй закладке перечислены объекты метаданных 1С, которые должны быть доступны в веб-приложении. Список заполняется автоматически при первом старте, но разработчик может в любой момент добавить или удалить из этого списка любые классы данных.
Ряд объектов используются ядром metadata.js. Их удаление из состава обмена, испортит работу веб-приложения. Вот этот список:
- Перечисление «ИнтеграцияСостоянияТранспорта»
- Перечисление «ИнтеграцияТипКеширования»
- Перечисление «ИнтеграцияТипСвёртки»
- Справочник «Пользователи»
- Справочник «ИнтеграцияПраваПользователей»
- Справочник «ЗначенияСвойствОбъектов»
- Справочник «ИдентификаторыОбъектовМетаданных»
- Справочник «НаборыДополнительныхРеквизитовИСведений»
- Справочник «Формулы»
- План видов характеристик «ДополнительныеРеквизитыИСведения»
- План видов характеристик «ПредопределенныеЭлементы»
Колонка «Кешировать» указывает, в какой базе CouchDB будут зарегистрированы изменения и способ обработки этих изменений браузером.
Устройство баз в NoSQL отличается от привычного реляционного. Главные особенности: права на чтение и фильтр репликации задаются для базы в целом, а не на конкретный тип объектоав. Metadata.js создаёт для каждого проекта три базы (ram, doc и meta), в которых хранит разные классы объектов.
- ram – рекомендуется для справочников и прочих редко изменяющихся данных. Объекты с типом кеширования ram, загружаются в ОЗУ браузера при старте веб-приложения и доступны в синхронном режиме. Изменения постоянно синхронизируются в одну сторону: из CouchDB в indexedDB и оперативную память браузера
- doc – как правило, используется для документов. Внутри базы doc работает RLS, изменения синхронизируются в обе стороны между CouchDB, 1С и indexedDB браузера
- doc_remote – объекты не кешируются в браузере и доступны только online. Чтение-запись через CouchDB
- meta – используются для больших неразделенных классификаторов. Сюда можно положить классификатор банков или КЛАДР. В отличие от doc_remote, данные не дублируются в разных зонах в режиме разделения данных
- e1cib – Не регистрировать в CouchDB. Этот режим можно рассматривать, как «лёгкий клиент 1С». Потребуется опубликовать rest http сервис библиотеки интеграции. Объекты будут доступны только online через стандартные http интерфейсы 1С.
Разработчику дана свобода при назначении типов кеширования. В экзотических случаях, можно держать документы в памяти, а за справочниками ходить на сервер.
Колонка «Свёртка» в текущей редакции библиотеки интеграции не используется.
Объекты, для которых взведена галка «Скрыть», не видны в автоматически генерируемом интерфейсе веб-приложения, но формы этих объектов полностью доступны через ссылочные реквизиты других объектов. Например, справочник «пользователи» спрятан в общем списке справочников, что не мешает выбрать пользователя в поле «ответственный» документа «перемещение денег».
Колонка «Разрешен IREST» в текущей редакции библиотеки интеграции не используется.
CouchDB может работать в качестве универсальной шины данных, к которой подключены разные ИБ 1С, сканеры, ТСД, АСУ и прочие «не 1С программы». Использование синонимов упрощает интеграцию с разнородными базами.
Указывать синонимы для новых объектов и реквизитов не обязательно. Проблем с русскоязычными названиями не возникает. Разработчик самостоятельно принимает решение, нужны ли синонимы для его задачи. Если принято решение синонимы не использовать, в таблице синонимов необходимо сохранить записи, относящиеся к предопределенным реквизитам и объектам ядра metadata.js (см. список объектов предыдущего абзаца).
Настало время пошевелить CouchDB из 1С.
- Включаем CORS. Рекомендую по возможности не использовать кроссдоменные запросы в production. Всегда можно сделать проксирование через Nginx и перенаправить запросы к разным серверам таким образом, чтобы браузеру казалось, что все серверы располагаются в одном origin. Главная неприятность от CORS – снижение быстродействия из-за использования preflight запросов. Если сайт и сервер расположены в разных доменах, перед тем, как отправить реальный запрос серверу, браузер направляет ему запрос с методом OPTION, на который сервер должен ответить «да, я согласен обрабатывать запросы из чужого домена». Теряем драгоценные миллисекунды на каждом запросе.
С другой стороны, использование CORS упрощает инфраструктуру и реализацию отказоустойчивости. Если основной сервер не отвечает, веб-приложение может самостоятельно отправить запрос на резервный сервер в другом дата-центре.
CORS в CouchDB включается кнопкой «Включить CORS» на закладке «Регистрация». На маленьких экранах, эта кнопка может прятаться внутри кнопки «еще» левой табличной части. - Создаём базы. При нажатии на кнопку «Настроить CouchDB» закладки «Регистрация»
- будут созданы три базы (doc, ram и meta)
- будут созданы пользователи и привязаны к базам
- в базах будут созданы или перезаполнены служебные документы с базовыми настройками
- Выполняем команду «Записать мета». Возвращаемся на закладку «Метаданные» и жмём кнопку. На основании списка метаданных к обмену и с учетом синонимов, будет сформирован и записан в CouchDB, объект описания метаданных
- Выполняем команду «Начальное заполнение». Это подготовительная команда выполняет цикл запросов и заполняет табличную часть ссылками на объекты, из которых будет составлен начальный образ данных. По умолчанию, регистрируются все объекты, включенные в состав обмена. Математику начальной регистрации можно дополнить и переопределить в процедурах «НачальноеЗаполнение» и «НачальноеЗаполнениеФинализация» общего модуля «ИнтеграцияМетадатаДемо».
- Выполняем команду «Зарегистрировать». По этой команде, список ссылок отправляется в CouchDB и начинает синхронизироваться со всеми подключенными веб-клиентами
- Любуемся результатом
В базы hw_*
можно «провалиться» щелчком мыши и изучить содержимое записанных со стороны 1С объектов.
Все необходимые от 1С данные получены – можно переходить к сборке веб-приложения.
Шаг №8 Отчеты
Полностью автоматического формирования отчетов на текущий момент не нет. Доступна форма типового отчета со стандартной разбивкой на поле табличного документа и панель параметров. Данные для отчета можно получать из разных источников. В текущем примере, данные извлекаем из map/reduce индекса CouchDB. Про индексы в NoSQL поговорим в отдельной статье. Сейчас, предлагаю просто открыть в браузере /_utils/database.html?hw_0_doc/_design/doc/_view/cash_moving_date_cashbox#
Это индекс CouchDB, используемый в данном случае, как аналог регистра накопления 1С.
При записи каждого объекта, выполняется код похожий на обработчик проведения. Формируется составной индекс (дата + касса) и рассчитывает промежуточные итоги. Эти итоги используются при построении отчета.
Полный код отчета здесь не дублирую - он доступен в модуле src/modifiers/reports/rep_cash_moving.js
Шаг №9 Публикация в Интернет
Если у вас есть VPS, VDS или dedicated сервер, просто разверните на нём couchdb и nginx и скопируйте файлы проекта в подходящую директорию.
Если выделенного сервера нет, но хочется «пощупать» технологию, есть бесплатные хостинги CouchDB:
- Smileupps. Сервис довольно тормозной, но вполне работоспособный. Для ознакомительных целей годится
- IBM Cloudant, лично не тестировал, но там есть бесплатный тариф, при условии небольшого трафика
При включенном CORS, файлы проекта можно разместить на любом, дешевом или бесплатном хостинге. Никакой нагрузки на http сервер они не создают – это обычные статические файлы небольшого размера.
В CouchDB есть еще одна фича: он может работать http-сервером. То есть, можно построить back-end на голом CouchDB – без Apache и Nginx.
Итоги
Демо-задача решена. Понимаю, что в короткой статье невозможно рассмотреть даже вершину айсберга.
Если тема покажется аудитории интересной - голосуйте за продолжение. Буду по мере сил выкладывать новые материалы.