From 51ac5c40d1141e2925e569afb373b29dd2c1a01b Mon Sep 17 00:00:00 2001 From: Recolic K <bensl@microsoft.com> Date: Mon, 16 May 2022 19:08:10 +0800 Subject: [PATCH] bug fix: wrap one-activity workflow with a SEQ --- activity.hpp | 14 ++++++++++++-- workflows/qatar-notify.cc | 2 +- workflows/sendemail.cc | 14 ++++++++++++++ xaml-template.hpp | 2 +- 4 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 workflows/sendemail.cc diff --git a/activity.hpp b/activity.hpp index 9382a2d..470f035 100644 --- a/activity.hpp +++ b/activity.hpp @@ -160,9 +160,10 @@ namespace CIS { bool prevOperationIsSequential = true; rlib::string xamlCode; - // For a long expression A >> B >> C >> D, A is in xamlCode, and [B,C,D] are cached in queuedOnRight to wait for merge. + // If representing a long expression A >> B >> C >> D, A is in xamlCode, and [B,C,D] are cached in queuedOnRight to wait for merge. std::list<rlib::string> queuedOnRight; + // Consumes this and seqNext, and create a new Flow representing the merged Flow. Flow binaryOperation(Flow seqNext, bool thisOperationIsSequential) const { Flow result = *this; result.reduceQueuedIfNecessary(thisOperationIsSequential); @@ -176,6 +177,8 @@ namespace CIS { return result; } + // If we are going to perform a different binary operation, we need to merge xamlCode and queuedOnRight into this.xamlCode, to keep the queue clear. + // If we are going to perform the previous binary operation again, we don't need to reduce the queue, and this function does nothing. void reduceQueuedIfNecessary(bool thisOperationIsSequential) { if(thisOperationIsSequential == prevOperationIsSequential || queuedOnRight.empty()) return; rlib::string resultXaml = prevOperationIsSequential ? templates::SEQ_BEGIN : templates::PAR_BEGIN; @@ -231,7 +234,14 @@ namespace CIS { inline auto Flow::generateXaml(Metadata metadata) const { Flow finalized(*this); - finalized.reduceQueuedIfNecessary(!finalized.prevOperationIsSequential); // Always necessary if queue is not empty. + if(finalized.queuedOnRight.empty()) { + // If the queue is empty, it means there is only one activity in the workflow. + // We must wrap it with a SEQuence, or CIS will fail with internal error. + finalized.xamlCode = templates::SEQ_BEGIN + finalized.xamlCode + templates::SEQ_END; + } else { + // Merge all pending elements into one. + finalized.reduceQueuedIfNecessary(!finalized.prevOperationIsSequential); + } return metadata.generateXamlHead() + dirty_plugins::patchGS(finalized.xamlCode) + metadata.generateXamlTail(); } inline auto Flow::generateXaml(std::string className) const { diff --git a/workflows/qatar-notify.cc b/workflows/qatar-notify.cc index e537945..fc14756 100644 --- a/workflows/qatar-notify.cc +++ b/workflows/qatar-notify.cc @@ -6,6 +6,6 @@ int main() { .addInputSetting("RunAsDaemon", "true") ; - println(to_file("AlarmingDaemonWorkflow.xaml"), flow.generateXaml("Microsoft.Office.FleetAGC.Workflows.AlarmingDaemonWorkflow")); + println(to_file("AlarmingDaemonWorkflow.xaml"), flow.generateXaml("FleetAGC.Workflows.AlarmingDaemonWorkflow")); } diff --git a/workflows/sendemail.cc b/workflows/sendemail.cc new file mode 100644 index 0000000..9dbddb0 --- /dev/null +++ b/workflows/sendemail.cc @@ -0,0 +1,14 @@ +#include <cis-workflow-gen/quick-include.hpp> + +int main() { + Flow flow = + Activity("SendEmail", "FleetAGC.Activities.SendEmailActivity") + .addInputSetting("to", CS(GlobalSettings["to"])) + .addInputSetting("title", CS(GlobalSettings["title"])) + .addInputSetting("content_b64", CS(GlobalSettings["content_b64"])) >> Noop("Noop") + ; + + + println(to_file("SendEmailActivityWorkflow.xaml"), flow.generateXaml("M365AGCBuildout.Workflows.SendEmailActivityWorkflow")); +} + diff --git a/xaml-template.hpp b/xaml-template.hpp index 8417b8d..430475a 100644 --- a/xaml-template.hpp +++ b/xaml-template.hpp @@ -89,7 +89,7 @@ __TEMPLATE_ARG_XtraNamespaces </sco:Collection> <AssemblyReference>System.Xml</AssemblyReference> <AssemblyReference>System.Xml.Linq</AssemblyReference> <AssemblyReference>mscorlib</AssemblyReference> - <AssemblyReference>Microsoft.Office.FleetAGC.Activities</AssemblyReference> + <AssemblyReference>FleetAGC.Activities</AssemblyReference> __TEMPLATE_ARG_XtraAssemblies </sco:Collection> </TextExpression.ReferencesForImplementation> )XAML"; -- GitLab