На прошлой неделе прошла конференция Alfresco DevCon, в которой мы участвовали. Пока Alfresco обрабатывает и публикует презентации и видео с конференции, мы расскажем, как она прошла.
Немного истории:
В 2010 и 2011м годах компания Alfresco проводила конференцию Alfresco DevCon, и это было место встречи всех заметных разработчиков на Alfresco.
В 2012 и 2013м годах Alfresco решила, что устраивать конференцию только для технарей - не комильфо, DevCon стал Саммитом, появились бизнес-пользователи и непонятные доклады, конференция перестала нравиться людям, в итоге в 2014м ее прикрыли.
Поняв, что Alfresco не собирается решать вопрос "где бы разработчикам встретиться и поделиться мыслями о жизни", в 2016м и 2017м сообщество Alfresco в лице Ордена Пчелы устроило конференцию BeeCon самостоятельно. BeeCon был хорош, собирал по 200 человек, но устраивать конференцию самостоятельно без вендора все-таки сложно с точки зрения логистики и поиска спонсоров. Alfresco присылала 10-20 человек, но многие инженеры не приезжали, так как "у них спринты, сроки горят" итд. В таком состоянии сообщество пришло к 2018му.
Увидев успех BeeCon, Alfresco решила все же не оставаться в стороне и попробовать возродить DevCon. Повод: Alfresco - это платформа, а что за платформа без разработчиков, так что нужна конференция, где этих разработчиков можно растить. И вот в этом январе прошел DevCon, организованный компанией Alfresco.
Закончим с историей конференций и посмотрим, что интересного было на DevCon 2018.
Alfresco сумела собрать более 270 человек, привезла всех своих инженеров, кого сумела оторвать от работы, и это приятно. Есть вопросы о том, почему что-то в Alfresco работает так, а не иначе, - на DevCon можно получить ответ.
Томас ДеМео рассказал, чего ожидать от Alfresco в ближайшем будущем. Alfresco 6.0.a (Early Access) вроде как была выложена на тестирование еще в ноябре 2017го, но сборка не выглядела как новый большой релиз. Исходя из презентации, настоящий релиз Alfresco 6.0 случится этой весной. Конечно, в нем все будет сломано, написанные ранее модули, как всегда, сломаются, этого никто не скрывает. Уже боимся. Работающий 6.0.x выйдет осенью. Совместимость со старыми модулями вряд ли поправят, но новые возможности правда заработают.
Что ожидать от этого релиза с точки зрения функциональных возможностей? Alfresco переходит на микросервисную архитектуру. Управление пользователями и их правами должно быть выделено из ядра Alfresco и стать независимым компонентом, который будет работать как с Alfresco Content Services (aka Alfresco Community/One), так и с Alfresco Process Service (aka Activiti). Новый рекомендованный способ построения своих расширений Alfresco - использовать REST API и подписываться на события (Events) репозитория. Добро пожаловать в стиль конфигурирования JIRA. :)
С одной стороны хорошо, что Alfresco готова рискнуть и поменять свою архитектуру, придуманную еще в 2005м, следуя модным тенденциями. С другой стороны мы будем скучать по возможности встроить свои расширения глубоко в ядро Alfresco и исправить их косяки архитектуры и кода самостоятельно через Java API. Мы любили Alfresco именно за ее расширяемость и открытость, от которой они теперь пытаются уйти.
Доклад, который нам очень понравился (и не только нам, он взял одну из двух наград "Лучший доклад конференции") - презентация Michael Suzuki на тему аналитики в Alfresco. Alfresco делала много забегов на построения своего решения по аналитике данных, хранимых в репозитории, но ни одно так и не взлетело. Michael показал, как получить все нужные для аналитики данные из SOLR, используя SQL запросы, и построить графики и отчеты при помощи Apache Zeppelin. Это выглядит оптимальным решением, когда готового красивого решения по аналитике компания предложить не может.
Что насчет нас?
В этом году только один человек из нашей команды поехал на конференцию - @aviriel. Все-таки с прошлой конференции (BeeCon 2017) прошло всего 9 месяцев, и все разработчики были слишком заняты завершением проектов. Оксана представила технический доклад на тему "Overcomming common knowledge: 100k nodes in a single folder" (презентация на английском) и получила вторую из двух наград за лучший доклад конференции. Все-таки Alfresco не права, говоря, что больше двух тысяч записей в одной папке хранить нельзя, и мы нашли рабочий способ преодоления этого ограничения в репозитории. Сто тысяч записей у нас загружаются за 1,5 секунды. Похоже, многих людей интересует этот вопрос, раз уж на доклад пришло 75 человек несмотря на вечер последнего дня конференции. Мы записали в ролик несколько скриншотов нашего решения, которые вы можете посмотреть, пока Alfresco не опубликовала видеозапись доклада:
К этому радостному событию (конференция и доклад) приурочен выпуск нового компонента Alvex - Alvex Registers, который во многом похож на реестры документов, которые были в старом Alvex для Alfresco 4, но они не были мигрированы на Alfresco 5. Новые реестры пока содержат не все возможности старого компонента, зато написаны на новом Aikau взамен старого YUI2, и поддерживают хранение до 1 млн. записей в одном реестре. Компонент пока в разработке и не стабилен, не все кнопки работают, и мы в ближайшее время выпустим стабильный релиз, как только все исправим и допишем.
Спасибо всем, кто приехал на конференцию, кто пришел на наш доклад, мы были рады видеть вас. Надеемся увидеть в следующем году и тех, кто не смог добраться в этот раз.
Спасибо за фотографии Francesco Corti, Angel Borroy и другим участникам сообщества.
Если вы хотите ознакомиться с более детальным разбором конференции, можете прочитать запись в блоге keensoft, но на на английском языке.
Выполнение произвольных Java-классов через API в Alfresco
Если вы пишете код под Alfresco, и более того вы пишете его на Java, то вы знаете, сколько времени уходит на перезагрузки Alfresco при разработке и тестировании нового функционала. Наверняка вы знаете, что такое Alfresco JavaScript Console, и страдаете оттого, что чего-то подобного нет для выполнения кода, написанного на Java.
Мы не волшебники, и мы не можем быстро, аккуратно и за бесплатно написать средство для Java, аналогичное JavaScript Console, но мы можем отчасти облегчить вашу жизнь.
Познакомьтесь с нашим новым расширением Alfresco Java Code Executor. Он позволяет удаленно запускать произвольный Java-класс. AJCE - это по сути просто вебскрипт, который получает от вас Java byte-code, загружает его и выполняет.
Настройка сроков исполнения задач в Alvex без программирования
Встречайте новый компонент Alvex - Рабочий календарь! Он позволяет назначать сроки исполнения задач в бизнес-процессах с учетом выходных дней и праздников. Кроме того теперь можно настроить сроки исполнения для всех задач в консоли администрирования, не привлекая к этому разработчика!
Основные возможности этого компонента:
Разработчикам бизнес-процессов больше не нужно задавать сроки исполнения в листенерах при рисовании схемы процесса. Вам не нужно устанавливать новые версии бизнес-процессов после каждой правки сроков и думать, что же делать с уже запущенными процессами, которые от этого не поменяются. Вы можете настраивать сроки исполнения в консоли администрирования Alfresco Share даже для уже запущенных процессов (правда только для тех задач, которые еще не назначены).
Сроки исполнения рассчитываются с учетом выходных дней и праздников. Если вы решите дать 2 дня "на исполнение этой задачи", и пользователю задача будет назначена в четверг, то крайний срок исполнения этой задачи наступит во вторник следующей недели (пятница + 2 выходных + понедельник).
Замечание: Если в процессе пользователь вручную задает срок исполнения для этой задачи в соответствующем поле на форме, то значение, заданное пользователем, будет приоритетнее стандартного срока, заданного администратором в консоли администрирования.
Этот компонент можно настраивать. По умолчанию в расчетах срока используется календарь выходных и праздников Российской Федерации на 2017-2019 годы. Вы можете загрузить файл csv с другим календарем и следовать этой инструкции для его подключения.
На прошлой неделе мы участвовали в конференции BeeCon 2017 - Alfresco Developer Conference. Это главное мероприятие компании Alfresco, где разработчики делятся планами, отвечают на вопросы и общаются с членами сообщества. Что ж, будем первыми, кто напишет, что там было, на русском.
Обновление для разработчиков: Alfresco SDK 3.0
В прошлом году разработчики Alfresco объявляли, что новое SDK почти готово. И вот год спустя они его все-таки выпустили! Из основных новых возможностей:
Поддержка JAR (не только AMP)
Поддерживает Alfresco 4.2-5.2
Простое обновление Alfresco и самого SDK в проекте
Загрузка кода "на лету" (hot-reloading)
Порядка 40 параметров сборки (<enablePlatform />, <enableShare />, <enableSolr/>, <enableMySQL /> и другие)
Умеет втягивать сторонние зависимости в проект (как AMP, так и JAR)
Activiti 6
Вокруг Activiti 5 выросла Activiti 6. Это отдельный продукт, новые функции которого зачастую доступны только при покупке платной версии. Когда хоть какие-то из озвученных фич появятся в Alfresco (и появятся ли) - остается загадкой. Презентация про новую Activiti: ссылка.
SOLR 6 в Alfresco 5.2
В Alfresco 5.2 наконец появилась новая версия SOLR. Что это значит?
Шардинг при большом объеме контента
Индексирование нескольких версий документа
Отпечатки (fingerprint) документов для быстрого поиска
Подсветка найденного при поиске в Alfresco Share
Настройка SOLR через консоль администрирования Alfresco
Судьба Alfresco Share и появление ADF
Все доклады Alfresco про пользовательские интерфейсы и их судьбу описываются одним твитом небезызвестного в сообществе человека по имени Axel Faust:
На конференции не было ни одного доклада про Alfresco Share и Aikau. Ответ на прямой вопрос о судьбе Share - см. выше. Alfresco не может совсем отказаться от Share, потому что на ней работает Records Management, сертифицированный по стандартам DOD, но руководство Alfresco ясно дало понять, что развиваться этот интерфейс особо не будет. Alfresco делает ставку на Alfresco Developer Framework, отнюдь не готовое решение, но фреймворк, позволяющий написать нужный UI на Angular 2. Без доработок умеет показывать список документов и задач. Презентация про ADF с конференции: ссылка.
В общем на правах итога можем сказать, что Alvex нам надо с Share переносить на что-нибудь другое.
Несмотря на эти зачастую неутешительные новости, конференция была чудесной. 180 человек из 28 стран мира встретились, чтобы обсудить насущные вопросы. Как сказал Jeff Potts, это была конференция трёх R: Re-connect, Re-charge, Re-commit.
Члены нашей команды представили три презентации (вы можете посмотреть их на сайте конференции), мы были одним из основных спонсоров и организаторов конференции. Нам даже вручили награду, как лучшему партнеру Order of the Bee. А теперь впереди еще один год работы с технологиями Alfresco до следующей возможности подзарядиться энергией у сообщества.
Как вы знаете, в прошлом году мы были спонсором и активно участвовали в организации конференции BeeCon 2016. Не прошло и года, как мы рады представить вам BeeCon 2017, который в этом году пройдет 25-28 апреля в Сарагосе, Испания. Эта конференция для людей, работающих с Alfresco, которую организует сообщество при поддержке компании Alfresco Software Inc.
Если вы участвовали в прошлогодней конференции в Бельгии, то нам не нужно объяснять, зачем ехать в этом году в Испанию. Если же нет, но вы приезжали раньше на Alfresco DevCon или Summit, то знайте, что на BeeCon качество докладов - то же, а иногда и выше, а людей, с которыми интересно пообщаться, стало даже больше. Если вы вообще раньше никогда не участвовали в конференциях по Alfresco, то вот несколько причин, чтобы начать:
Что хорошего ждет участников BeeCon?
Встреча с экспертами мира Alfresco, многие из которых разрабатывают платформу, которую вы используете.
Общение с другими специалистами по Alfresco. С ними можно обсудить ваши идеи, проекты и вопросы. Вы научитесь чему-то новому сами, и может научите чему-то новому других.
Рассказы о том, как другие решают свои задачи на Alfresco, как избежать ошибок и правильно построить систему на базе Alfresco.
Интересные доклады, споры и обсуждения с докладчиками предложенных тем (а может вы и сами решите представить доклад, заявки на которые начнут принимать уже на этой неделе).
Знакомство с сотрудниками и разработчиками Alfresco. Эти полезные связи можно продолжить, общаясь с людьми по почте, на форумах или в IRC после конференции.
Как мы уже сказали раньше, организацией BeeCon занимается сообщество Alfresco в лице Ордена Пчелы. Конференция предназначена для экспертов Alfresco, разработчиков, инженеров, партнеров, консультанов и пользователей. На конференции не будет докладов о том, зачем покупать платную версию Alfresco One, сколько она стоит, и как классно крупнейший партнер Alfresco внедрил непонятно что в далекой Америке. Конференция рассчитана на техническую аудиторию, и доклады будут технические и по делу, хотя что-то для себя найдет как новичок, так и умудренный жизнью разработчик Alfresco.
Если решитесь приехать на BeeCon, предупреждаем, что участие опасно для людей, страдающих следующими заболеваниями:
Людей, которые считают, что они единственные, кто делает правильные и красивые вещи. На BeeCon их разум может сильно пострадать, когда они увидят множество других участников, делающих потрясающие вещи!
Людей, которые верят, что освоенную тайную магию нужно хранить в секрете, и это сделает их умнее и выше остальных. Такие люди будут в шоке от того, как все делятся идеями, навыками, советами, кодом друг с другом.
Но такие люди все же могут приехать на BeeCon для прохождения терапии и излечиться от своих недугов.
Если вы все еще не уверены, что стоит ехать на BeeCon, пишите нам письма, звоните, а также приходите на http://chat.alfresco.com и http://community.alfresco.com потренировать свой английский и побеседовать с выдающимися представителями сообщества Alfresco.
До встречи в Сарагосе!
P.S. Да, встречи сообщества Alfresco в Москве в этом году опять не будет. Зачем она, если можно встретиться в Испании?
Не прошло и полутора лет с момента объявления начала миграции Alvex на Alfresco 5, как мы готовы анонсировать Alvex 3.0. Это еще не выпуск новой стабильной версии, но все компоненты мигрированы на Alfresco 5.1 и готовы к тестированию, а может и использованию.
Как это теперь работает?
Независимые компоненты
Как и обещали, мы разделили единое решение Alvex не несколько компонентов. Хорошая новость — мы уже добавили в Alvex несколько новых небольших компонентов. Плохая новость — не все компоненты пережили миграцию. Мы решили сильно переработать часть Alvex, поэтому сейчас в новом Alvex нет реестров документов и сайтов заседаний.
Сейчас на Github есть следующие репозитории, относящиеся к Alvex:
Utils — общие конфигурационные файлы, шаблоны FTL и код, который обеспечивает взаимодействие между компонентами Alvex.
Orgchart — оргструктура с подразделениями, ролями, руководителями в Alfresco Share.
Manager dashboard tasks — страницы и дашлеты для руководителей, заданных в оргструктуре, позволяют следить за процессом выполнения задач подчиненных и бизнес-процессами, запущенными подчиненными
Uploader позволяет загружать новые файлы в Alfresco с формы задач или редактирования свойств объекта.
Workflow permissions — управление правами доступа к файлам, обрабатывающимся в рамках бизнес-процесса, правами пользователей на запуск бизнес-процессов определенных видов.
Project management — новый тип сайтов с документами и задачами проекта; расширение возможностей бизнес-процессов — связи между процессами, обсуждения задач, новые страницы задач и процессов.
Datagrid заменяет стандартный datagrid Alfresco и добавляет новые возможности: авто-сгенерированный поиск по таблице, настраиваемые колонки и другие.
Masterdata позволяет использовать списки данных Alfresco и внешние справочники в качестве списка допустимых значений в текстовых полях.
Custom workflows — бизнес-процессы "Поставить задачу", "Отправить документ на согласование" и "Рассылка документов".
Inform policy информирует создателя, редакторов и всех других пользователей, связанных с документом, об изменении файла.
Infavorites document association добавляет документы и файлы, отмеченные пользователем как Избранные, в ассоциации пользователя. При использовании компонента Inform Policy информирует пользователей об изменениях этих файлов.
Middle Name добавляет в API и на все стандартные страницы отчество пользователя, так как Alfresco по умолчанию поддерживает только имя и фамилию.
Для получения сразу нескольких компонентов и скачивания уже готовых сборок Alvex используйте https://github.com/ITDSystems/alvex. В этом же репозитории создан README с подробным описанием, как собирать и работать с новым Alvex.
Важно: Компоненты не стали полностью независимыми. Нужно устанавливать Utils вместе с любым другим компонентом Alvex. Некоторые компоненты зависят сразу от нескольких других и требуют их установку. Например, Custom Workflows зависят от Uploader и Orgchart.
Как это устроено?
SDK
Мы мигрировали на Alfresco SDK 2.2. Так что теперь структура папок и файлов в компонентах будет привычнее для тех, кто уже разрабатывал что-то своё на Alfresco 5. Но SDK 2.2 поддерживает только сборку в формате AMP, а мы по-прежнему любим JAR, так что SDK не совсем стандартный, чтобы поддерживать и AMP, и JAR.
Несмотря на возможность сборки Alvex и в AMP, и в JAR, мы рекомендуем использовать JAR. Для сборки компонента достаточно склонировать репозиторий и собрать пакеты для alfresco и для share. Для тех, кто хочет собрать сразу несколько компонентов, есть возможность собрать архив ZIP с JAR выбранных компонентов, а также всеми зависимостями, которые должны быть установлены. Подробнее о сборке Alvex — в README этого репозитория.
Travis CI
Теперь мы используем Travis для проверки на работоспособность всех изменений в репозиториях. Он собирает компонент и выполняет integration-test, чтобы увидеть, запускается ли Alfresco после внесенных изменений. В README репозиториев с компонентами можно увидеть текущий статус компонента, выполнились ли тесты Travis. Мы стараемся сделать так, чтобы они всегда проходили.
Nexus
Теперь у нас есть Nexus. Если вам нужна конкретная версия любого компонента, вы можете скачать ее здесь. Сборки добавляются в Nexus автоматически при каждом обновлении репозитория, если тесты Travis CI завершились успешно.
Итого, сейчас есть несколько способов использовать компоненты Alvex:
скачать JAR из Nexus, установить их в Alfresco;
склонировать репозиторий и собрать компонент из исходников;
использовать компонент как зависимость в pom.xml;
собрать ZIP только с нужными компонентами Alvex;
скачать все компоненты единым архивом из Nexus.
Поддержка разных версий Alfresco
Сейчас все компоненты работают на Alfresco 5.1.x и 5.2.b. Ветка master всех репозиториев гарантированно работает только на последней версии Alfresco, для поддержки старых версий будут создаваться тэги и отдельные ветки.
Что насчет Alvex Enterprise?
Теперь мы не разделяем Alvex Community и Alvex Enterprise. Будут стабильные сборки (релизы) Alvex, которые мы поддерживаем, как поддерживали Alvex Enterprise. Но все исходные коды открыты, вы можете их скачать, изменить и использовать неподдерживаемую свою собственную версию, как это было с Alvex Community. Мы уже открыли все возможности и компоненты кроме Board Collaboration и Document Registers. Board Collaboration и Document Registers будут сильно переработаны на Aikau и новой версии Activiti, после чего мы их тоже откроем.
Если вам нужны новые функциональные возможности, которых нет в Alvex, есть два пути, как их получить:
Присоединиться к к процессу разработки. Создайте Github Issue для найденного бага или с описанием новой возможности, которую вы хотели бы видеть в будущих версиях Alvex. Исправьте баг или реализуйте новую возможность и пришлите нам Pull Request, если вы хорошо знакомы с Alfresco. Помогите с переводом Alvex на другие языки, которые вы знаете в проекте на CrowdIn. Мы будем рады вашему участию! Наши друзья Douglas C. R. Paes из Бразилии, Younes Regaieg из Франции и Torsten Werner из Германии участвовали в миграции Alvex на Alfresco 5.1. Присоединяйтесь и вы.
Стать нашим заказчиком. Если нужно получить новую возможность в Alvex быстро, нужно решить какую-то специфичную для вашей организации задачу, реализация которой должна остаться закрытой, или вы ищете что-то новое, что совсем не укладывается в Alvex, свяжитесь с нашими специалистами, чтобы обсудить как это можно сделать.
Новый модуль для Alfresco 5.1: Alfresco Inform Policy Extension
Пока все ждут релиза нового Alvex для Alfresco 5, мы решили порадовать вас на Новый год небольшим адд-оном для Alfresco, который, мы надеемся, скрасит ожидание. :)
Новый модуль Alfresco Inform Policy позволяет информировать пользователей об обновлении документов, с которыми они работают. Пользователь получает уведомления по электронной почте, когда кто-нибудь загружает новую версию документа, если:
этот пользователь создал этот документ
этот пользователь изменял этот документ раньше
этот пользователь указан в атрибутах этого документа в каком-нибудь ассоциации (например, исполнитель или адресат)
Модуль живёт на Github: https://github.com/ITDSystems/alfresco-inform-policy-extension-repo. Текущую версию 0.7 для Alfresco 5.0-5.1 можно скачать здесь.
Как использовать?
Установите модуль в Alfresco в виде пакета AMP.
Убедитесь, что вы настроили сервис отправки сообщений электронной почты OutboundSMTP в Alfresco. Модуль не будет работать, если mail.from.enabled выставлен в false или не устрановлен!
Укажите следующие настройки в alfresco-global.properties:
Настройка почты
documentchangeinform.mail.from (String) - от какого адреса следуюет отправлять сообщения
documentchangeinform.mail.subject (String) - тема сообщения
documentchangeinform.lasteditor (boolean) - включить отправку уведомления пользователю, который последний правил документ
documentchangeinform.associated (boolean) - включить отправку уведомления всем пользователям, указанным в ассоциациях документа
documentchangeinform.editors (boolean) - включить отправку уведомления всем пользователям, редактировавшим документ ранее
Запустите Alfresco.
Шаблон сообщения можно найти в папке Data Dictionary/Email Templates/Document Change Notification/ в репозитории Alfresco после запуска. Вы можете поменять шаблон, если это нужно.
Это всё. Пользователи теперь будут получать уведомления при создании новой версии документа.
Предыдущая запись серии: 10. Создание документов в реестре из процесса
На этот раз пример не привязан к процессу, который мы рассматривали все прошлые записи. Рассмотрим пример listener-а, который может использоваться на этапе завершения задачи в любом другом процессе. Главное, что нужно поменять прежде, чем использовать его, это ссылку на шаблон документа и названия переменных, используемых в шаблонах, так как у вас они скорее всего будут другими.
В этом примере мы рассматриваем генерацию счета по шаблону. Ожидается, что на форме задачи есть заполненных поля "Компания", "Номер счета" и "Сумма счета". Конечно, какие-то данные можно брать не из задачи, а заполнять по каким-то правилам в JavaScript. Используемый шаблон:
Listener, в котором мы генерируем документ и прикрепляем его к пакету документов процесса:
Часто возникает необходимость создать документ в реестре из бизнес-процесса. Например, согласованный в процессе договор должен добавиться в реестр договоров, как в нашем примере.
Наиболее простой и универсальный способ создания документов в реестре из процесса - запустить связанный процесс "Зарегистрировать документы". Из плюсов этого метода: можно зарегистрировать документ в любом реестре любого сайта, к которому пользователь имеет доступ, а также этот метод не требует никакой разработки. Из минусов: все поля карточки придётся заполнять вручную.
Для того, чтобы поля заполнялись автоматически, придётся написать listener, который будет создавать документ на нужном этапе бизнес-процесса. Об этом пути мы и поговорим в этой записи.
Для создания документа нужна следующая информация:
Имя сайта, на котором будет производиться регистрация документа
Можно указать имя сайта "жестко" в listener:
А можно дать пользователю возможность выбрать сайт из выпадающего списка. Для этого нужно добавить текстовое свойство в тип задачи:
И отрисовать его на форме задачи, используя контрол из Alvex:
Тогда в listener мы будем выбирать сайт в соответствии со значением переменной atw20:office:
Единственная сложность - нужно аккуратно следить, чтобы у всех пользователей, которые будут завершать эту задачу, были права на добавление документов в реестры хотя бы одного сайта, а то список доступных сайтов будет пустым, и пользователь не может завершить задачу.
Реестр на сайте
Следующим этапом нужно выбрать реестр, в который будет добавляться документ. Если количество реестров на сайте постоянно, и новых не будет, то можно обратиться к реестру по номеру в списке. Главное - найти правильный номер реестра, в этом поможет JavaScript Console:
Можно найти реестр по его имени, но тут нужно быть аккуратным с API на поиск, так как они менялись между версиями Alfresco 4.2 и 5.0. В таком случае выбор реестра будет выполнен примерно так:
А можно написать свой контрол, который будет выводить пользователю выпадающий список существующих реестров, как это было со списком сайтов. В текущей версии Alvex такого стандартного контрола нет, так что придётся создать его самостоятельно.
Новый документ в реестре
Теперь можно создавать документ и заполнять поля карточки. В зависимости от типа документа и полей на форме задачи можно заполнять разные поля. Здесь мы заполняем карточку договора типа alvexdt:agreement:
Следующая запись серии: 11. Генерация документов docx из процесса
Предыдущая запись серии: 8. Работа с оргструктурой в процессе
Обычно бизнес-процесс в Alfresco - это не только последовательность задач, которые пользователи завершают, нажимая на кнопку "Выполнено", но и множество автоматически выполняемых действий. Например, добавление атрибута "Исполнитель" в карточке документа или генерация нового документа по шаблону. Для этого используются listener-ы. Они же используются для подсчета числа согласовавших договор, чтобы завершить цикл согласования, и передачи перемененных между задачами процесса.
Здесь мы рассмотрим простейшие типы listener-ов, написанные на JavaScript. В принципе, можно писать их и на Java.
Доступные переменные
Начнём с отдалённой темы доступных переменных. У процесса есть набор переменных (далее, scope), который доступен в любой момент выполнения процесса. К таким переменным относятся срок исполнения процесса (не задачи!), приоритет процесса, а также любые другие переменные, которые мы создадим и будем использовать в рамках процесса.
Свой scope переменных есть и у каждой задачи в рамках процесса. Сюда относятся исполнитель, срок исполнения задачи, название задачи и все другие свойства, которые мы описываем в типе задачи в модели процесса. Переменные задачи "видны" только в рамках этой задачи с момента её создания (накоторые из переменных могут быть пустыми) и до момента её завершения. Они не удаляются при завершении задачи, мы можем посмотреть их в истории процесса, но обращаться к ним из следующей задачи мы уже не сможем. Чтобы переменные были нам доступны и далее, нужно на этапе завершения задачи перенести их в scope переменных процесса.
А теперь к listener-ам. Они бывают двух типов:
Execution Listener
Task Listener
Execution Listener
Execution Listener выполняется в процессе ВНЕ пользовательских задач. Такой listener можно "повесить" на 3 стадии в процессе:
Старт процесса
Переход между задачами (стрелочки)
Завершение процесса
Пример в нашем процессе можно найти на этапе запуска процесса:
При заполнении формы запуска процесса инициатор указал список согласователей в переменной bpm_assignees. В первой строке listener-а мы записали число согласователей в переменную atw20_reviewerCount, чтобы в дальнейшем считать, все ли согласовали документ. Во второй строке в переменную atw20_approveCount мы записали, что на данный момент документ никем не согласован (мы же только запускаем процесс). В третьей строке мы завели переменную atw20_comments_global, в которой будут храниться все комментарии согласователей. Далее мы записали в переменные процесса инициатора (atw20_initiator) и перенесли в переменные процесса имя контрагента из поля на форме, которое заполнил инициатор - atw20_contractor. Из этого примера можно понять, как записывать и получать переменные из scope переменных процесса.
Записывать согласователей и комментарии в переменные, созданные выше, мы будем в рамках задач, и об этом позже. Еще одно действие, проводимое в рамках процесса, - это обнуление переменных при переходе на новый круг согласования. Это действие "висит" на переходе между задачами и выглядит так:
Для создания нового listener-а выбираем на схеме этап, на который будем "вешать" listener, переходим на вкладку "Listeners", выбираем тип действие, на которое будет срабатывать listener:
Task Listener
Task Listener-ы выполняются в рамках задачи. Такой listener можно "повесить" на 3 стадии в любой задаче:
Создание задачи
Назначение задачи
Выполнение задачи
Часто выполняемая операция при создании задачи - задание срока исполнения и приоритета. Можно скопировать срок исполнения из переменных процесса, тогда они будут совпадать:
А можно рассчитать дату другим способом, например, "сегодня + 7 дней":
Пример listener-а на завершении задачи:
Что здесь происходит? Сначала мы проверяем, согласовал ли пользователь документ. Результат согласования записан в переменную atw20_reviewOutcome в соответствии с нашей моделью. Чтобы достать значение переменной из задачи, воспользуемся функцией task.getVariableLocal(переменная). У нас уже была создана переменная для подсчета числа согласовавших, она хранится в процессе, поэтому мы обращаемся к ней просто atw20_approveCount. А вот чтобы записать в неё новое значение, используем функцию execution.setVariable(переменная, новое значение). По аналогии, но уже со всеми прелестями использования javascript допишем комментарий пользователя в переменную, в которой хранятся все комментарии. В результате в переменную добляется блок, например, ",{Иван Иванов|Согласовано|комментарий}". Созданием из этих данных красивой таблицы будет заниматься контрол, используемый для отображения комментариев на стороне Share.
Число согласовавших в дальнейшем будет обрабатывать ветвление при завершении цикла согласования. Там в условиях перехода мы укажем ${atw20_approveCount}.
Более сложная задача - создание нового документа из задачи или запись значения какого-либо атрибута в свойства всех приложенных файлов. Первое мы рассмотрим на следующей неделе, а сейчас попробуем разобраться с приложенными файлами.
Обновление свойств приложенных файлов
Пример изменения названия всех файлов, приложенных к задаче:
Например, если файл имеет название "Документ", то после того, как сработает listener, он будет называться "Документ (в обработке)".
Когда вы пишете свои listener-ы, нужно быть предельно аккуратным, чтобы сделать всё так, как ожидает пользователь. Например, при обновлении имени файла, нужно не забывать, что файлов у вас может быть много, что в какой-то момент имя файла может стать "Документ (в обработке) (в обработке) (в обработке)", если вы повесите listener на неправильный этап задачи (например, на запуск задачи типа multi-instance, а не на завершение предыдущей задачи, которая была точно одна), а еще не забывайте, что система откажется менять свойства заблокированных файлов.
В остальном "язык" написания listener-ов совпадает с языком написания вебскриптов. Так что отлаживать скрипты можно в JavaScript Console.
Следующая запись серии: 10. Создание документов в реестре из процесса
Предыдущая запись серии: 7. Задачи типа multi-instance
Использование окна "Выбор из оргструктуры" при выборе исполнителя
Чтобы заменить стандартный диалог выбора пользователя Alfresco на диалог выбора из оргструктуры, который позволит не только искать человека по имени, но и выбирать его по роли из нужного подразделения, достаточно указать правильный элемент ввода в конфигурации Share для ассоциации с пользователем:
Назначение по ролям
Для использования автоматического выбора исполнителя по роли пользователя добавьте в контекст на стороне репозитория дополнительный bean:
Из принципиального в этой настройке есть два момента:
В качестве parent указывается bean alvex-orgchart-delegations-manager, который собственно отвечает за работу с оргструктурой.
В разделе matches присутствуют task-assign-change:.*@PROCESS_ID, task-done:.*@PROCESS_ID и process-start@PROCESS_ID, где PROCESS_ID - id нашего бизнес-процесса. Этот набор обеспечивает срабатывание триггеров на все необходимые события - старт процесса, назначение задачи, переназначение задачи.
Для назначения задачи по роли нужно в процессе указать в поле задания исполнителя нужную роль в формате Подразделение::Роль. При этом в качестве подразделения можно использовать специальные служебные переменные: {0} - текущее подразделение, {-1} - подразделение на один уровень выше по структуре и т.д.
При этом разрешение ролей работает рекурсивно - если роль не найдена в текущем подразделении, поиск будет продолжен "вверх" по оргструктуре до совпадения.
Например, на рисунке ниже и в нашем процессе показано назначение задачи на генерального директора (роль CEO) текущего подразделения (служебная переменная {0}). Так как, скорее всего, генеральный директор - один, и он находится в верхнем подразделении оргструктуры, то система будет рекурсивно искать его до самого верха.
Делегирование, замещение и функция "Нет на работе"
После того, как к процессу подключена работа с оргструктурой, возможности замещения на время отсутствия становятся для него автоматически доступны. Настройка замещения показана на рисунке ниже. Можно указать заместителя по умолчанию и отдельных заместителей по разным ролям.
После того, как замещения настроены, новые задачи в рамках бизнес-процесса будут автоматически поступать заместителю. Уже назначенные задачи лучше либо завершить, либо переназначить правильным людям вручную.
Предыдущая запись серии: 6. Работа с документами в процессе
Если процесс устроен так, что в какой-то момент требуется выполнить параллельно несколько разных задач, можно указать это в схеме процесса. Для этого используется Parallel Gateway, никакой отдельной настройки самого ветвления и выполняемых параллельно задач не требуется.
Более частой и несколько более сложной в реализации является другая ситуация - одну и ту же задачу должны выполнить независимо несколько человек. Простой пример - мы не знаем заранее, сколько согласователей должно быть у конкретного проекта, так как это зависит от большого количества факторов. Поэтому требуется возможность выбрать произвольное количество согласователей при старте процесса, задача согласования должна придти к ним всем, одобрить проект должны все. Если хотя бы один согласователь против - проект отправляется на доработку.
Чтобы реализовать это, в модели бизнес-процесса требуется просто использовать аспект bpm:assignees вместо bpm:assignee. Это означает, что исполнителей у задачи может быть как один, так и несколько. Изменения настроек Share тоже просты - нужно вместо bpm:assignee использовать bpm:assignees на всех формах.
Схема процесса требует несколько большей доработки.
Требуется указать, что задача согласования теперь является Multi Instance
В настройках Multi Instance задачи нужно указать два параметра -- какой атрибут содержит массив, в котором перечислены все исполнители задачи (в нашем случае это bpm:assignees), и имя для обращения к каждому отдельному элементу этого массива уже при работе с конкретной копией задачи (в данном случае это reviewer).
В настройках исполнителя задачи теперь необходимо использовать имя отдельного элемента, как оно было задано на прошлом шаге.
Условия переходов также требуется доработать, дописав несколько триггеров. Так как мы хотим реализовать сценарий, в котором для одобрения проекта требуется согласие всех согласователей, то логика будет следующая:
В начале процесса (триггер take на переход от старта процесса к первой задаче) запоминаем, сколько всего согласователей назначено. Это число сохраняем в переменной atw20_reviewerCount). Кроме этого заводим счетчик, в котором будет значение, сколько человек уже согласовало проект (переменная atw20_approveCount).
В конце этапа согласования (триггер на событие complete) учитываем голос согласователя, обновляем переменную atw20_approveCount.
Дорабатываем условия переходов. Теперь проект согласован, если все согласователи его одобрили, и не согласован в любом другом случае.
Также нужно не забыть обнулить счетчик количества одобривших проект при повторной отправке проекта на согласование. Иначе можно получить очень неожиданные ситуации. Этот триггер можно разместить в разных местах схемы процесса. Например, можно поставить его непосредственно на переход (событие take). Вид триггера прост - он просто обнуляет переменную-счетчик.
Следующая запись серии: 8. Работа с оргструктурой в процессе
Если в стандартной Alfresco инициатор прикладывает к задаче файл из домашней директории или из библиотеки документов сайта, к которому другие участники процесса не имеет доступа, то исполнитель увидит задачу без приложенных файлов. При использовании Alvex Uploader также инициатор процесса обычно загружает новые файлы со своего компьютера, которые по умолчанию попадают в его домашнюю директорию. Alfresco в таком случае предполагает, что права на каждый файл выдаются явно. Если права исполнителю не были выданы, то и показывать ему файлы не следует.
Это на первый взгляд логично. Но крайне неудобно. Если вы отправите по процессу несколько файлов, но забудете выдать права на часть из них, то исполнитель увидит не все материалы, которые ему хотели прислать. Это может привести к очень неприятным недоразумениям.
Ставить искусственные ограничения практически бессмыслено, поэтому Alvex позволяет автоматически выдавать всем участникам процесса права на чтение всех прикрепленных файлов. Для этого в контекст на стороне репозитория надо добавить всего один служебный bean:
Из принципиального в этой настройке есть два момента:
В качестве parent указывается bean alvex-custom-workflows-permission-manager, который собственно отвечает за выдачу прав.
В разделе match присутствуют task-assign-after-change:.*@PROCESS_ID, task-done:.*@PROCESS_ID и process-start@PROCESS_ID, где PROCESS_ID - id нашего бизнес-процесса. Этот набор обеспечивает срабатывание триггеров на все необходимые события - старт процесса, назначение задачи, переназначение задачи.
Данная конфигурация приведет к тому, что все пользователи, которым будут назначены какие-либо задачи в рамках бизнес-процесса, получат права на чтение всех прикрепленных файлов. Иногда этого недостаточно, и требуется выдать пользователям права не только на чтение, но и на изменение файлов. В этом случае в настройках bean-а добавляется еще одна секция:
Поле filePermission задает набор прав, которые получат пользователи. Варианты значения этого поля:
Задание одной из стандартных ролей, определенных в Alfresco: CONSUMER, CONTRIBUTOR, EDITOR, COORDINATOR.
Короткая форма записи: read или просто ro - исполнителям будут выданы права на чтение файлов (соответствует роли CONSUMER), read-write или просто rw - исполнителям будут выданы права на чтение и запись файлов (соответствует роли EDITOR).
Иногда также может потребоваться выдавать права на файлы не всегда, а только для определенных стадий процесса. В этом случае указывается не только id процесса PROCESS_ID, но и id задачи в рамках процесса TASK_ID. Конфигурация принимает следующий вид:
Доступ к пакету документов
Еще один неприятный момент при работе с процессом - файлы прикрепляются к процессу изначально, и после его запуска никто с ними сделать ничего не может. Хотя было бы логично, что согласователь может приложить что-то - версию с правками или список замечаний. На этапе доработки и повторной отправки документа на согласование, вероятно, уместно дать возможность полностью изменить состав документов - не только загрузить новые, но и убрать лишние.
Эти полномочия относятся не к прикрепленным файлам (можно ли их читать и редактировать), а к пакету документов как целому (можно ли в него добавлять новые файлы и удалять существующие). Поэтому для работы с ними есть два специальные полномочия. Полномочия настраиваются для задач процесса в модели и являются по сути "флажками" вида "можно/нельзя". По умолчанию "флажки" выключены, поэтому чтобы их изменить нужно вписать новые значения (разрешающие соответственные операции) в секцию overrides соответственной задачи.
Первое полномочие позволяет добавлять новые файлы к процессу и настраивается следующим образом:
Второе полномочие позволяет удалять прикрепленные ранее файлы:
Если необходимо выдать оба полномочия, то в секцию overrides соответственной задачи нужно добавить оба блока одновременно.
Блокировка документов на время согласования
А что же делать, когда несколько человек должны согласовать текущую верcию договора? Исходя из стандартного поведения системы, любой пользователь, имеющий права на редактирование файла, может изменить документ после того, как его согласовал первый сотрудник, но до того, как его согласует второй. Решение одно - блокировать файл (или запись реестра), чтобы никто не мог его изменить, пока все не согласуют (или не отклонят) документ.
Alvex позволяет блокировать документ на старте задачи согласования, и разблокировать его, например, при возврате документа на доработку или при завершении процесса. Для этого в контекст на стороне репозитория надо добавить два служебных bean:
Первый bean включает блокировку при старте задачи согласования:
Второй bean разблокирует все документы в пакете процесса при старте задачи доработки документа и при успешном завершении согласования (старте задачи регистрации документа в нашем процессе):
В итоге, у нас получается довольно длинный и сложный файл контекста на стороне репозитория (и немного файла с описанием типов задач), но он позволяет выдавать всем участникам процесса именно те права на документы, которые нужно. Пример файла контекста из нашего демо-процесса: https://github.com/ITDSystems/alvex-courses-extras/blob/master/2015-09-02/custom-workflow/tutorial-workflow-repo/src/main/amp/config/alfresco/extension/alvex-tutorial-workflow-context.xml.
Следующая запись серии: 7. Задачи типа multi-instance
При отклонении документа согласующими процесс обычно не завершается, а уходит на доработку и новый круг согласования. Для создания таких "кругов", на которые документ может уходить бесконечное число раз, используются циклы.
Для зацикливания процесса попробуем просто дорисовать переход от этапа после согласования к этапу начала согласования:
Или так:
Интуитивно кажется, что этого достаточно, и все в этот момент должно заработать. Внимательный читатель, который прочитал все прошлые записи серии, в этот момент ожидает подвоха - наверняка потребуется что-нибудь писать в какие-нибудь еще файлы.
Но на этот раз интуиция права - больше менять действительно ничего не надо. Так как для всех задач остаются прежними и модели, и настройки Share, то можно править только схему процесса, переставляя этапы и переходы между ними.
Следующая запись серии: 6. Работа с документами в процессе
Предыдущая запись серии: 3. Структура и файлы процесса
Ветвления бывают двух типов:
Parallel Gateways позволяют создавать независимые ветки процесса, которые в дальнейшем будут объединены. Например, две задачи в рамках одного процесса могут выполняться в одно и тоже время независимо друг от друга.
Exclusive Gateways позволяют создавать взаимоисключающие ветки. Например, когда пользователь, рассматривая документ, выбирает Согласовать или Отклонить, то в зависимости от его выбора, процесс должен идти по одной из двух разных веток.
Parallel Gateways
Parallel Gateways отвечают за создание нескольких параллельных веток из одной исходной и за объединение этих веток обратно в одну.
Существует два вида Parallel Gateways:
fork: в Gateway входит одна ветка, выходит - несколько.
join: в Gateway входят несколько веток, выходит - одна. Прежде чем объединить ветки, Gateway дожидается, когда все задачи во входящих ветках дойдут до него.
Parallel Gateway может быть одновременно и fork, и join, когда в него входит несколько веток, и несколько выходит. В этом случае Gateway сначала дожидается выполнения всех задач во входящих ветках, а после этого одновременно создаёт новые ветки в нужном числе.
Отличием Parallel Gateway от других типов ветвлений является то, что для создания веток не требуется выполнение условий. Если в Parallel Gateway пытаться заложить условия, то они будут проигнорированы системой. Все ветки, выходящие из Gateway, имеют одинаковый приоритет.
Пример использования Parallel Gateway для параллельного согласования документа двумя группами пользователей:
Exclusive Gateways
Exclusive Gateway позволяет пользователю, выполняя задачу, делать выбор, например принимать или отклонять документ. В Exclusive Gateway заложены условия перехода к каждой ветке. Условия обрабатываются в том порядке, в котором они описаны в XML. После выполнения первого условия проверка прекращается, и процесс следует ветке, условие для которой выполнено, игнорируя остальные ветки, условия для которых не были рассмотрены.
Обработка условий в Exclusive Gateway в Activiti отличается от обработки условий, принятой в BPMN 2.0. Обычно, если выполняются условия для перехода к нескольких веткам, то эти ветки выполняются параллельно. В Activiti же в таком случае будет выбрана только одна ветка, первая из числа тех, у которых выполнилось условие.
Если ни одно из условий не было выполнено, то бизнес-процесс не может быть продолжен, и пользователю на экран будет выведена ошибка.
Применение на практике
В нашем процессе используется ветвление только типа Exclusive. Посмотрим, как это работает.
Когда мы согласуем документ с несколькими пользователями, нам нужно посчитать, скольким была поставлена задача согласования, и сколько человек одобрили документ. Этот случай чуть сложнее, чем переход по одной из веток в зависимости от значения какого-то статичного свойства процесса. Из-за этого нам придётся познакомиться вкратце с блоком Listeners раньше, чем через 4-5 записей.
Инициатор выбирает пользователей, которым отправится задача согласования в переменную, названную в типе задачи bpm:assignees. Нам требуется при запуске процесса посчитать, сколько человек выбрал инициатор. Для этого во вкладке Listeners мы создаем листенер, срабатывающий при запуске бизнес-процесса: Этот скрипт создаёт переменную atw20:reviewerCount, доступную всем задачам в рамках процесса, и записывает в неё число пользователей, которые получат задачу "Согласовать документ". Вторая создаваемся переменная - atw20:approveCount - число пользователей, одобривших документ. При запуске процесса такое число равно нулю.
На форме задачи пользователь должен видеть несколько кнопок с доступными действиями (согласовать или отклонить документ). Для этого наш тип задачи "Согласовать" должен быть унаследован от стандартного типа bpm:activitiOutcomeTask. В этом типе мы создаем новое текстовое поле, на которое должно быть наложено ограничение по числу допустимых значений. Каждое допустимое значение - действие, доступное пользователю. И последним этапом мы заменяем стандартное свойство bpm:outcomePropertyName нашим свойством, чтобы пользователь видел поле не выпадающим списком, а именно кнопками. Если суммировать все, изложенное в этом пункте, то тип задачи получается таким: Не забывайте создавать конфигурацию Share для всех типов задач.
Для подсчёта числа одобривших документ повесим листенер на завершение задачи согласования, который проверяет при завершении задачи значение переменной atw20:reviewOutcome и, если пользователь одобрил документ, то прибавлял этот голос к общей сумме голосов:
Не забудем, что число согласовавших документ должно обнулиться, когда мы отправляем документ на новый круг согласования. Для этого создадим листенер, который будет при переходе процесса между задачами "Доработать" и "Согласовать" обнулять переменную.
Последним этапом нужно перейти по нужной ветке на этапе ветвления. Для этого не нужно ничего настраивать в самом узле (Gateway), но нужно указать условия переходов на стрелках, которые из него выходят. Для того, чтобы документ уходил на доработку, если хотя бы один из согласователей его не одобрил, мы используем следующее условие:
На второй стрелке можно не задавать условия, но нужно перед установкой процесса в систему открыть схему в обычном текстовом редакторе и проверить, что переход с условием стоит выше по тексту, чем переход без условия.
Предыдущая запись серии: 2. Пример нестандарного бизнес-процесса в Alvex
В качестве примера бизнес-процесса будем использовать процесс согласования проекта.
Структура типа бизнес-процесса
На первый взгляд было бы логично ожидать, что каждый бизнес-процесс - это некоторый отдельный файл, в котором описана последовательность задач. Но в реальности все несколько сложнее. Для полного описания бизнес-процесса требуется следующее:
Схема процесса - этапы процесса, переходы между ними, при необходимости триггеры, вызывающие те или иные автоматические действия при переходах между этапами.
Модель процесса - атрибуты процесса и его отдельных задач, какие переменные существуют в рамках процесса и кому они доступны.
Конфигурация форм для всех задач процесса - что именно и как именно показывать пользователю на экране при работе с конкретной задачей процесса.
Пакеты локализации, если процесс должен поддерживать многоязычный интерфейс. В простейшем случае одного языка пакеты локализации могут отсутствовать.
Файлы контекста - служебные файлы, описывающие инициализацию всех компонентов и ресурсов процесса.
Структура каталогов проекта
Чтобы собрать все файлы процесса в одном месте и не запутаться, создадим заранее структуру, которая позволит это сделать в дальнейшем.
Каталог Tutorial Workflow Repo (или любое другое название для базового каталога, в котором будет находиться конфигурация репозитория) содержит часть конфигурации, которая должна быть загружена в Alfresco Repository (бэк-энд системы). При работе с среде разработки Eclipse лучше создать отдельный проект, в котором будет располагаться содержимое этого каталога. Здесь будут находиться схема бизнес-процесса, его модель задач и локализация. Все расширения репозитория, в том числе бизнес-процессы, принято располагать в каталоге src/main/amp/config/alfresco/extension.
Каталог Tutorial Workflow Share содержит часть конфигурации, которая должна быть загружена в Alfresco Share (фронт-энд системы, веб-интерфейс). Опять-таки в Eclipse это должен быть отдельный проект. Здесь будут располагаться настройки пользовательского интерфейса и их локализация. Все расширения Share, в том числе настройки бизнес-процессов, принято располагать в каталоге src/main/amp/config/alfresco/web-extension.
Файл alvex-tutorial-workflow.bpmn20.xml в Tutorial Workflow Repo/src/main/amp/config/alfresco/extension/workflows - схема бизнес-процесса в формате BPMN2.0.
Файл alvex-tutorial-workflow-task-model.xml в Tutorial Workflow Repo/src/main/amp/config/alfresco/extension/models - модель процесса.
Пакеты локализации модели процесса должны лежать в файлах *.properties в Tutorial Workflow Repo/src/main/amp/config/alfresco/extension/messages.
Файл alvex-tutorial-workflow-context.xml в Tutorial Workflow Repo/src/main/amp/config/alfresco/extension - контекст, описывающий инициализацию схемы, модели и пакетов локализации на стороне репозитория.
Файл alvex-tutorial-workflow-config.xml в Tutorial Workflow Share/src/main/amp/config/alfresco/web-extension - настройка пользовательского интерфейса для бизнес-процесса.
Файлы *.properties в Tutorial Workflow Share/src/main/amp/config/alfresco/web-extension/messages - пакеты локализации пользовательского интерфейса на соответственные языки.
Файл alvex-tutorial-workflow-context.xml в Tutorial Workflow Share/src/main/amp/config/alfresco/web-extension - контекст, описывающий инициализацию форм веб-интерфейса и пакетов локализации на стороне Share.
Файлы pom.xml и module.properties, а также каталоги tomcat относятся к процессу сборки amp-пакетов.
Бизнес-процесс, который будет описываться в этой записи дальше, выложен на Github. Вы можете скопировать оттуда структуру и файлы.
Схема процесса
Описать схему процесса можно графически в Activiti Modeler. Блок процесса в файле описания имеет два атрибута:
id является обязательным атрибутом и должен содержать уникальное значение в рамках системы. Именно по нему Alfresco различает типы бизнес-процессов, загруженных в систему.
name не является обязательным атрибутом. Он используется только для отображения понятного пользователю названия бизнес-процесса в интерфейсе.
Процесс начинается со StartEvent и заканчивается элементом EndEvent. Все задачи между этими двумя событиями будут иметь тип UserTask. Другие типы задач использовать можно, но Alfresco их не всегда и не полностью поддерживает.
В свойствах StartEvent и задач указываем тип задачи (форму), которую будет видеть и заполнять инициатор процесса. Это делается в строке "Form key" в секции "Main config" элемента. Типы задач будут создаваться в отдельном файле.
В настройках задач процесса нужно указать исполнителя. Здесь можно использовать текстовое имя пользователя (например, admin) или указать, что исполнитель будет выбираться пользователем при запуске или на предыдущих этапах процесса. Например, строка ${bpm_assignee.properties.userName} значит, что имя исполнителя берётся из переменной bpm:assignee, которую заполняет инициатор на форме запуска процесса. О переменных подробнее поговорим в разделе описания задач.
Сохраним созданную схему. Проверьте, что Eclipse сохранил её в формате bpmn20.xml, а если нет, то переименуйте файл, иначе Alfresco не распознает в нём схему нового бизнес-процесса.
Описание типов задач
В модели бизнес-процесса указывается, какие поля в принципе есть у задачи, а при настройке форм задается какие поля показать пользователю и как именно.
В этой записи мы не будем детально рассматривать, что такое модели и типы контента, как описываются свойства и ассоциации. Об этом можно почитать на OSSPortal и в нашем блоге. Здесь же мы рассмотрим, как применять знания по разработке своих моделей контента и типов реестров к задачам.
Alfresco содержит один файл со описанием стандартных типов задач в рамках бизнес-процессов - bpmModel.xml. От этих типов наследуются все остальные задачи любых процессов. Например, в моделях alvex-custom-workflows-task-model.xml, alvex-documents-dispatching-task-model.xml и alvex-parallel-review-task-model.xml из состава Alvex описано много задач для соответствующих типовых процессов из состава Alvex. Все эти задачи унаследованы от типов, описанных в bpmModel.xml.
К стандартным задачам относятся следующие типы:
bpm:Task - обобщенный тип, содержит базовые атрибуты задачи: id, описание, дата создания, дата завершения, срок исполнения, статус, приоритет и на кого она назначена. От bpm:Task наследуются все остальные типы. Сам по себе bpm:Task не используется.
bpm:workflowTask - основной тип задач в "линейных" бизнес-процессах. Добавляет к свойствам bpm:Task атрибуты для работы с прикрепленными файлами.
bpm:activitiOutcomeTask - специфичный тип задачи, обычно используемый перед ветвлениями в процессах, когда пользователь должен сделать явный выбор (например, "Одобрить" или "Отклонить").
bpm:startTask - специфичный тип, используемый для первой задачи процесса. Использование этого типа позволяет установить ряд атрибутов для процесса как целого - описание, приоритет, срок исполнения.
При создании процессов вы можете либо переиспользовать стандартные типы задач с их наборами атрибутов, либо создавать свои типы, наследуя их от стандартных и, при необходимости, добавляя собственные атрибуты.
Для каждого типа задачи создается конфигурация интерфейса Share. Конфигурация Share определяет то, как будет выглядеть пользовательский интерфейс при отображении информации о задаче. Если конфигурация отсутствует, то пользователю будут показаны все атрибуты задачи в произвольном порядке.
При запуске экземпляра бизнес-процесса в системе, атрибуты его задач хранятся в репозитории. Полный список атрибутов каждой задачи можно посмотреть в Activiti Workflow Console:
Для нашего процесса создается модель задач процесса в следующем виде:
Модель описывает пять задач, унаследованных от стандартных задач Alfresco. Существует два варианта, как добавить атрибуты к задачам:
Добавить нужные атрибуты к каждой задаче процесса по отдельности. В этом случае они видны в рамках каждой задачи по отдельности, но между задачами не передаются.
Добавить блок атрибутов (аспект) к процессу в целом, после чего подключить его для нужных задач. В этом случае атрибуты применены именно к процессу как целому и передаются между задачами в его рамках.
Чтобы добавить аспект к процессу потребуется:
Добавить новый аспект в модель. В модели аспекты должны идти после задач (раздел aspects следует за разделом types) (см. строки 165-212).
Добавить созданный аспект к задачам процесса (см. строки 15-20 и далее во всех типах)
Для того, чтобы инициатор мог выбрать исполнителя, нам нужно прикрепить к форме запуска процесса стандартный аспект, содержащий свойство bpm:assignees. Если бы согласователь был 1, то мы бы использовали свойство bpm:assignee. В таком случае на схеме процесса в качестве исполнителя мы указываем bpm_assignee.properties.userName ("bpm_assignee" - объект-пользователь, "bpm_assignee.properties.userName" - имя пользователя в виде строки текста).
К полю Контрагент подключен справочник (строка 198) с названием Contractors. Справочник создается в консоли администрирования, это может быть либо список данных в Alfresco, либо внешний справочник в формате XML/JSON. В качестве примера можно использовать справочник http://www.alvexsoftware.com/files/contacts_sample_ru.json. Вы можете назвать справочик по-другому, в таком случае для корректной работы бизнес-процесса нужно указать в строке 198 новое название.
Поместите модель в отдельном файле alvex-tutorial-workflows-task-model.xml в каталоге Tutorial Workflow Repo/src/main/amp/config/alfresco/extension.
Настройка форм задач
Конфигурация Share описывает то, как показывать пользователям поля, описанные в типах задач. Описанную конфигурацию можно разместить в отдельном файле alvex-tutorial-workflows-config.xml в директории Toturial Workflow Share/src/main/amp/config/alfresco/web-extension. Полный вид настройки для нашего процесса приведен ниже.
Файл настройки содержит несколько разделов config.
Первый раздел содержит атрибуты evaluator="string-compare" condition="activiti$alvex-tutorial-workflow". Это означает, что он используется при запуске новой задачи с использованием движка activiti и id типа бизнес-процесса alvex-tutorial-workflow.
Остальные разделы содержат атрибуты evaluator="task-type" condition="atw20:TASK_NAME", где TASK_NAME - это название типа задачи. Это означает, что они относятся к формам для задач данных видов.
Порядок описания форм стандартно для всех объектов Alfresco. Описание всех тегов, стандартных контролов можно найти в http://ru.blog.itdhq.com/post/70277827209/2013-12-17-create-new-registry-type#share.
Локализация процесса
Для стандартных типов задач Alfresco, их свойств и ассоциаций используется стандартная локализация. Там, где требуются нестандартные строки, можно вписывать нужный текст напрямую в label. Такой подход не изящен, но в целом работает до тех пор, пока нам требуется только один язык. Если нужно поддерживать более одного языка - это становится уже неприемлемо.
В такой ситуации требуется создать собственные пакеты локализации. Локализации подлежат следующие компоненты:
Модели - процесс, задачи в рамках процесса, все их атрибуты.
Отдельные надписи в интерфейсе пользователя, такие как названия разделов форм.
Для локализации моделей требуется создать пакеты локализации на соответствующие языки. Пример состава пакета русской локализации:
Первые две строки отвечают за локализацию названия и описания процесса. Строки 3-12 - локализация названий задач в рамках процесса. Строка 13 - локализация свойства в аспекте контрагента. Строки 15-20 - локализация Constraint, который задает доступные действия для согласователя. Строки 22-27 - локализация надписей в таблице истории бизнес-процесса. Пакет локализации позволяет разным пользователям видеть названия этих элементов на своих родных языках.
Для локализации произвольных надписей в интерфейсе пользователя требуется также сначала подготовить пакеты локализации.:
Для нормальной работы локализации во всех операционных системах и браузерах требуется не-ASCII символы сконвертировать в ASCII. Для этого можно использовать утилиту native2ascii.
Инициализация процесса на стороне Alfresco
Для того, чтобы Alfresco считала все файлы процесса, созданные ранее, нужно сообщить Alfresco об их существовании.
При инициализации модуля на стороне Alfresco загружаются необходимые ресурсы в соответствии с тем, что описано для него в файле контекста. Если ресурсы присутствуют в системе, но не описаны в файле контекста, то они загружены не будут.
В ходе старта сервера Alfresco сканирует все файлы, названия которых заканчиваются на *-context.xml, и выполняет описанные в них сценарии инициализации.
Рассмотрим сценарии инициализации всех ресурсов бизнес-процесса на стороне как Alfresco Repository, так и Alfresco Share.
Контекст для Alfresco Repository:
Данный файл создает несколько bean-ов. Сейчас мы рассмотрим только первый из них (alvex-tutorial-workflow-wd), который непосредственно загружает ресурсы бизнес-процесса. Остальные bean-ы выполняют служебные операции, которые не являются обязательными и к которым мы вернемся позднее.
У bean-а есть идентификатор (id) и родительский bean (parent). id может быть любым, но должен быть уникальным в рамках системы. Именно по id bean-ы адресуются друг к другу. В качестве parent для bean-а alvex-tutorial-workflow-wd указан workflowDeployer - это означает, что создаваемый bean наследует свойства обобщенного bean-а, который может загружать новые бизнес-процессы.
Внутри bean-а содержится несколько разделов property. Именно в них описано все то, что bean должен загрузить:
Первый раздел имеет атрибут name="workflowDefinitions". В данном разделе описано, какую схему бизнес-процесса загружать. Параметры при загрузке следующие:
engineId - какой движок бизнес-процессов использовать, Activiti или jBPM.
location - путь к файлу со схемой процесса.
mimetype - формат, в котором хранится схема процесса.
redeploy - нужно ли обновлять схему процесса, если она уже была загружена ранее. Если параметр выставлен в true, то схема обновится, при этом в репозитории Alfresco будет создана новая ее версия. Рекомендуется выставлять redeploy в true в ходе разработки процесса, чтобы схема обновлялась всегда. При передаче в промышленную эксплуатацию рекомендуется установить redeploy в false, так как иначе при каждом рестарте сервера будет создаваться новая версия схемы процесса, полностью идентичная старой.
Второй раздел имеет атрибут name="models". В данном разделе описано, где располагаются модели задач процесса. В качестве параметра в этом разделе указан путь к файлу модели.
Третий раздел имеет атрибут name="labels". В данном разделе описано, где располагаются пакеты локализации. Последний элемент пути - имя пакета локализации без расширения. То есть если имя пакета alvex-tutorial-workflow, то будут загружены все файлы локализации, имена которых имеют вид alvex-tutorial-workflow_*.properties.
Контекст для Alfresco Share:
Данный файл создает два bean-а, оба они будут нам необходимы:
Первый bean имеет id alvex-tutorial-workflow-rd, и для него указан Java-класс org.springframework.extensions.surf.util.ResourceBundleBootstrapComponent. Данный bean загружает файлы локализации на стороне Share. В нем имеется единственный раздел с атрибутом name="resourceBundles". Синтаксис полностью аналогичен загрузке локализации для Repository, которая описана выше, кроме того можно использовать . вместо / для разделения каталогов.
Второй bean имеет id alvex-tutorial-workflow-cd, и для него указан Java-класс org.springframework.extensions.config.ConfigBootstrap. В данном bean-е имеется единственный раздел с атрибутом name="configs". Этот bean загружает конфигурацию для Alfresco Share из отдельного файла alfresco/web-extension/alvex-tutorial-workflow-config.xml, который указан в параметрах.
Предыдущая запись серии: 1. Немного о понятиях и терминологии бизнес-процессов Alfresco
Все файлы бизнес-процесса выложены на Github. Здесь описано содержимое всех файлов и каталогов. А в этой записи мы посмотрим, из каких задач состоит процесс и как его установить в систему.
Процесс состоит из пяти этапов:
Инициатор процесса ставит задачу выбранным пользователям из оргстурктуры согласовать проект документа. К задаче прикладывается файл, в поле "Контрагент" из списка выбирается имя контрагента, к которому относится документ.
Согласователи читают документ. На время согласования документ заблокирован и не может быть изменён. При наличии правок согласователи указывают их в поле "Комментарий" или прикладывают к задаче новый документ с правками.
Если хотя бы один согласователь не одобрил документ, он возвращается инициатору на доработку. Инициатор видит все комментарии, новые приложенные файлы. Инициатор вносит правки в исходный документ и отправляет его на повторное согласование.
Если все согласователи одобрили документ, инициатор получает уведомление об успешном завершении согласования и выбирает сайт с реестрами, на котором нужно зарегистрировать документ в реестре "Договоры". Когда пользователь нажимает кнопку "Зарегистрировать", документ автоматически добавляется в реестр, ему присваивается номер, заполняются поля "Дата регистрации", "Контрагент", "Подписант" (исполнитель следующей задачи), прикрепляются файлы из задачи.
После регистрации документ отправляется пользователю с ролью "CEO" (или его заместителю) на подписание. Этот этап подразумевает выполнение задач вне системы (распечатать, подписать итп), так как интеграцию с ЭЦП мы в этом процессе не делаем. После выполнения задач "оффлайн", пользователь завершает задачу. У документа в реестре меняется статус на "Подписанный", проставляется дата подписания.
Для того, чтобы процесс заработал, требуется:
Alfresco 4.2.4 / 4.2.f с установленным Alvex Enterprise 2.1.3. В идеале Alvex должен быть установлен в виде AMP-пакетов.
Созданная оргструктура, в которой есть пользователь с ролью "CEO" (латиницей, можно другую, но тогда нужно немного обновить процесс). Инициатор процесса должен быть в оргструктуре (не службеные пользователи).
К системе должен быть подключен справочник с названием "Contractors". Например, можно подключить внешний справочник http://www.alvexsoftware.com/files/contacts_sample_ru.json, используя поле "Компания" как отображаемое пользователю.
Сайт с созданным реестром типа "Договоры" (alvexdt:agreement), у пользователя с ролью CEO" и у пользователя, который регистрирует документ в реестре, должны быть права на запись в реестр.
Сборка процесса
Скачиваем исходники процесса с Github. Это можно сделать через Git или загрузив папку в формате ZIP.
Чтобы увидеть схему процесса и собрать проект, импортируем проект в Eclipse:
Выбираем в меню Файл -> Import -> Existing Projects into Workspace -> Имя проекта Tutorial Workflow Repo. В качестве местонахождения проекта указываем папку tutorial-workflow-repo загруженного с Github проекта. Повторяем операцию, создавая проект Tutorial Workflow Share, местонахождение проекта - папка tutorial-workflow-share.
Чтобы собрать проект создаём конфигурацию сборки в Eclipse:
В меню Run -> Run Configurations выбираем систему сборки Maven и нажимаем New launch configuration.
Указываем название и базовый каталог проекта Tutorial Workflow Repo. В качестве цели (Goals) указываем package.
Сохраняем конфигурацию. Пробуем нажать Run. Если у вас установлено несколько пакетов Java или требуются еще какие-то дополнительные настройки, выполните их. Обычно больше никаких настроек не требуется.
Аналогично создаем конфигурацию для сборки проекта Tutorial Workflow Share.
Запускаем созданные конфигурации, используя зелёную кнопку на верхней панеле Eclipse.
Альтернативный вариант - открыть в терминале каталог tutorial-workflow-repo и набрать команду "mvn package". Если у вас установлен maven, то проект соберётся. Повторить для tutorial-workflow-share.
// Поздравляем, теперь вы знаете, как собирать проекты, написанные для Alfresco Maven SDK 2. Сейчас мы переводим все компоненты Alvex на такую структуру, и Alvex для Alfresco 5 будет собираться примерно также.
Установка процесса в систему
Для установки собранных пакетов в Alfresco скопируйте файл alfresco-tutorial-workflow-repo.amp из каталога target в проекте Turorial Workflow Repo в каталог amps в домашней папке Alfresco. Например, если Alfresco установлена в каталог /opt/alfresco-4.2.x, то скопируйте файл в /opt/alfresco-4.2.x/amps.
Аналогично, alfresco-tutorial-workflow-share.amp из каталога target в проекте Turorial Workflow Share скопируйте в amps_share.
// Будьте осторожны, все настройки, сделанные вами в каталогах tomcat/webapps/alfresco и tomcat/webapps/share, и все дополнительные пакеты, которые вы устанавливали в формате JAR, будут удалены. Если Alvex был установлен в формате JAR-файлов, положите пакеты Alvex в формате AMP вместе с устанавливаемым бизнес-процессом. Все свои настройки лучше вынести в каталог tomcat/shared/classes/alfresco, чтобы они пережили такие операции в дальнейшем.
Установите amp-пакеты, используя команду bin/apply_amps.sh, которая находится в той же домашней папке Alfresco.
Перезапустите Alfresco.
Разрешите пользователям запускать новый процесс в секции "Доступные процессы" в консоли администрирования.
Следующая запись серии: 3. Структура и файлы процесса