Запуск рабочего процесса Sharepoint из другого рабочего процесса

Рассмотрим сценарий, в котором у Вас есть рабочий процесс SharePoint 2013, который создает элемент в другом списке. В этом другом списке у Вас есть другой рабочий процесс SharePoint 2013, который настроен на автоматический запуск при создании элемента. Когда запускается первый рабочий процесс, он добавляет элемент в другой список и успешно завершается. Но рабочий процесс, связанный с другим списком, не запускается.

Если вы посмотрите в ULS, вы увидите следующее сообщение.

  w3wp.exe (0x0948)    0x05A8    SharePoint Server    Workflow Services    al2s8    Medium    Workflow recursion prevention attaching property Microsoft.SharePoint.ActivationProperties.IsEventFromWorkflow to event ItemAdded with value c1df2261-1ce4-60f4-b691-b58e44d387ca    c1df2261-1ce4-60f4-b691-b58e44d387ca

Это происходит из-за того, что обновлениями April/June 2013 CU/updates были внесены изменения предотвращения рекурсии рабочего процесса. Это сделано для того, что бы:

  1. Два рабочих процесса, и оба запускаются при обновлении элементов  в одном и том же списке.
  2. Рабочий процесс обновляет элемент в списке, вызывая бесконечный цикл запуска рабочего процесса.

Это привело к тому, что вышеописанные сценарий не работает.

С выпуском  SharePoint Server 2013 May Cumulative Update 2014 данная проблема была решена, но ее решение заключается в том, что появились новые API REST, которые мы можем вызвать для запуска другого рабочего процесса.

И так, как запустить рабочий процесс из другого рабочего процесса?


У нас есть список List1 и связанный с ним рабочий процесс Workflow1.

Workflow1 может быть настроен на автоматический запуск при добавлении / обновлении элемента или на ручной запуск, или на то и другое, это не имеет значения.

Workflow1 предназначен для создания элемента списка в List2.

Со списком List2 связан рабочий процесс Workflow2.

В Workflow2 должна быть включена опция запуска рабочего процесса вручную. (Разрешить запуск этого рабочего процесса вручную)

Workflow2 просто записывает заголовок элемента списка в список истории рабочего процесса.

Workflow1 и Workflow2 построены на платформе рабочих процессов 2013 года.

Если запустить Workflow1, то он отработает успешно, в List2 будет создан элемент, но Workflow2 не запуститься.

Для того, что бы запустить Workflow2 из Workflow1 воспользуемся вышесказанным исправлением и используем для этого REST API.

Решение получается немного громоздким, но рабочим.

Для начала создадим словарь в котором будет два элемента:

Accept: application/json;odata=verbose

Content-type: application/json;odata=verbose

переменную словаря назовем «ReqHeader»

В параметрах создания элемента в списке List2 создадим новую переменную для вывода результата с именем «NewItemGuid». Тип переменной GUID. Сюда будет записан GUID нашего созданного элемента.

Далее вставляем действие “Вызов веб-службы HTTP”.

Нажимаем “это”(“this”)  и первым делом добавляем переменную содержащую URL нашего сайта вставляем адрес.

Далее добавляем строчку  /_api/web/lists/GetByTitle(‘List2’)/items?$filter=GUID eq, после “eq” вставляем нашу переменную “NewItemGuid” определяющую наш созданный элемент, а “List2” наш список, где запускаем рабочий процесс.

Мы вызываем метод REST GetByTitle, передавая ему заголовок интересующего нас списка (для этого сценария это List2). Затем мы запрашиваем все элементы, отфильтрованные по определенному GUID, который является GUID элемента, который мы только что создали в элементе create в действии списка.

Нажмите OK в диалоге построения строк. Диалоговое окно «Вызов веб-службы HTTP» теперь должно выглядеть следующим образом. Убедитесь, что вы выбрали «HTTP GET» для метода HTTP. И жмем ОК.

Выберите пункт «Свойства» в контекстном меню действия «Вызов веб-службы HTTP».

Установите «RequestHeaders» в переменную заголовка запроса, которую вы создали, и создайте новую переменную словаря типов с именем «RespContent» для «ResponseContent». Жмем ОК.

 

Далее добавляем действие «Получить элемент из словаря». Выбираем гиперссылку «элемент по имени или пути» и в редакторе вводим  d/results(0) .

Нажмите на гиперссылку словаря и выбираем переменную «RespContent» из выпадающего списка. Нажмите на гиперссылку элемента и снова выберите переменную «RespContent» из выпадающего списка.

Теперь добавляем еще одно действие «Получить элемент из словаря». Вводим в «элемент по имени или пути» – Id, в ссылке  «словарь» выбираем переменную  «RespContent»., а гиперссылке элемента в «Вывести в элемент»  создаем новую переменную с именем «NewItemId» типа “Целое число”.

Теперь у нас есть ID (порядкового номера) элемента списка, который мы только что создали. Он нам нужен для передачи его  методу REST StartWorkflowOnListItemBySubscriptionId.

 

Другим параметром, который требуется StartWorkflowOnListItemBySubscriptionId, является SubscriptionId рабочего процесса.

Добавляем действие “Вызов веб-службы HTTP”.

Нажимаем “это”(“this”) , добавляем переменную определяющую корень нашего сайта и дописываем строку /_api/web/lists/GetByTitle(‘List2’).

Устанавливаем туже переменную «ReqHeader» для вызова и «RespContent» для результата.

HTTP метод – HTTP GET.

Следующее действие «Получить элемент из словаря». Запросим d/Id из переменной «RespContent» и вернем результат в новую переменную с именем «List2Guid» типа GUID.

Теперь переменная «List2Guid» имеет GUID списка List2. Нам это нужно, чтобы получить subscriptionId рабочего процесса.

Это мы сделаем вызвав уже доступный REST API с именем /_api/SP.WorkflowServices.WorkflowSubscriptionService.Current/EnumerateSubscriptionByList .

Добавляем еще одно действие “Вызов веб-службы HTTP”. В нем запросим все рабочие процессы списка List2.

В данном случае мы будет использовать HTTP метод – HTTP POST.

Теперь мы должны их результата в переменной «RespContent» выбрать необходимы рабочий процесс.

Если у Вас в списке List2 один рабочий процесс то его ID равен 0, если у Вас их несколько то можно вывести словарь «RespContent» и в нем найти нужный Вам рабочий процесс.

Следующим действием будет «Получить предмет из словаря». Запрашиваем d/results(<ID рабочего процесса>) из «RespContent» и снова сохраняем результат в «RespContent».

Вторым действием мы запрашиваем Id который является SubscriptionId нашего рабочего процесса в списке List2 и сохраняем результат в новой переменной с именем «SubscriptionId» типа GUID.

Теперь зная все параметры мы можем запустить рабочий процесс.

Добавляем последнее действие «Вызов веб-службы HTTP» и вызываем новый метод  /_api/SP.WorkflowServices.WorkflowInstanceService.Current/StartWorkflowOnListItemBySubscriptionId передав переменные SubscriptionId и NewItemId.

Здесь опять используем HTTP метод – HTTP POST

На этом все, теперь выполнив текущий рабочий процесс будет произведен запуск выбранного рабочего процесса в списке List2.

 

Источник