<!-- 
RSS generated by JIRA (1001.0.0-SNAPSHOT#100246-sha1:7a5c50119eb0633d306e14180817ddef5e80c75d) at Thu Feb 08 23:10:41 UTC 2024

It is possible to restrict the fields that are returned in this document by specifying the 'field' parameter in your request.
For example, to request only the issue key and summary add field=key&field=summary to the URL of your request.
-->
<rss version="0.92" >
<channel>
    <title>FOLIO Jira</title>
    <link>https://folio-org.atlassian.net</link>
    <description>This file is an XML representation of an issue</description>
    <language>en-us</language>    <build-info>
        <version>1001.0.0-SNAPSHOT</version>
        <build-number>100246</build-number>
        <build-date>07-02-2024</build-date>
    </build-info>

<item>
            <title>[FOLIO-1081] High-level design of FOLIO workflow engine</title>
                <link>https://folio-org.atlassian.net/browse/FOLIO-1081</link>
                <project id="10290" key="FOLIO">FOLIO</project>
                    <description>&lt;p&gt;Ongoing discussions.&lt;/p&gt;

&lt;p&gt;I created this issue mostly so I can file hours on it.&lt;/p&gt;</description>
                <environment></environment>
        <key id="80608">FOLIO-1081</key>
            <summary>High-level design of FOLIO workflow engine</summary>
                <type id="10003" iconUrl="https://folio-org.atlassian.net/rest/api/2/universal_avatar/view/type/issuetype/avatar/10318?size=medium">Task</type>
                                            <priority id="10002" iconUrl="https://dev.folio.org/assets/jira-priority/jira-p3.svg">P3</priority>
                        <status id="6" iconUrl="https://folio-org.atlassian.net/images/icons/statuses/closed.png" description="The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.">Closed</status>
                    <statusCategory id="3" key="done" colorName="green"/>
                                    <resolution id="10003">Done</resolution>
                                                        <assignee accountid="5bffed52a1b46046f530c8f7">Mike Taylor</assignee>
                                                                <reporter accountid="5bffed52a1b46046f530c8f7">Mike Taylor</reporter>
                                    <labels>
                    </labels>
                <created>Thu, 22 Feb 2018 13:07:57 +0000</created>
                <updated>Mon, 12 Nov 2018 14:24:08 +0000</updated>
                            <resolved>Mon, 1 Oct 2018 14:40:34 +0000</resolved>
                                                                        <due></due>
                            <votes>0</votes>
                                    <watches>4</watches>
                                                    <timespent seconds="93600">3 days, 2 hours</timespent>
                                <comments>
                                                            <comment id="189732" author="712020:32bb56ac-50e7-4787-b4af-ed3089d9401c" created="Sun, 25 Feb 2018 09:17:02 +0000"  >&lt;p&gt;An additional option would be to use the REST endpoint as an event key and the payload (json) as the event data.&lt;/p&gt;

&lt;p&gt;The event key would be comprised of the VERB + TENANT + RESPONSE-STATUS + RELATIVE-URL-ENDPOINT (calling this REST++ for short)&lt;br/&gt;
The data associated with the event key would be the data returned when this event is called&lt;/p&gt;

&lt;p&gt;We have all the event keys defined in the RAML files along with payload (response) examples.&lt;/p&gt;

&lt;p&gt;A workflow that is interested in a REST++ event, registers on Okapi or a dedicated mod-proxy / mod-workflow-proxy listens for these REST++ events. &lt;br/&gt;
When a registered event occurs (response time, not at request time of course) - this event is sent to the workflow that registered on this event&lt;/p&gt;

&lt;p&gt;This would look something like this:&lt;/p&gt;

&lt;p&gt;Made up workflow:&lt;/p&gt;

&lt;p&gt;Automatic: Scan loans in loans table&lt;br/&gt;
Automatic: If loan due date is in the past mark as overdue&lt;br/&gt;
Automatic: Calculate fine and update DB&lt;br/&gt;
Automatic: Send email to users&lt;br/&gt;
Automatic: If due date is more than 2 weeks ago send notification to librarian&lt;br/&gt;
Manual: Librarian looks at notifications in UI and confirms they are handling or not&lt;br/&gt;
	1. the REST++ event comes in &lt;br/&gt;
	2. if the REST++ event is met (lets say status:200, tenant:a , verb: put, endpoint: abc) forward event + payload to the workflow that registered &lt;br/&gt;
	3. The step in the workflow handling this event will parse the json and see if the librarian indicated that they are handling or not (on vacation...)&lt;br/&gt;
	4. and decide to either continue with the workflow or stop with error, etc...&lt;/p&gt;

&lt;p&gt;	Note that this doesnt have to be an event coming from the UI, it can come from anything triggering a REST++ which should be everything&lt;/p&gt;

&lt;p&gt;As for implementing the workflow itself. Spring&apos;s state machine implementation seems like a very good choice for this - see attachments 	&lt;/p&gt;</comment>
                                                            <comment id="189734" author="712020:32bb56ac-50e7-4787-b4af-ed3089d9401c" created="Sun, 25 Feb 2018 09:39:46 +0000"  >&lt;p&gt;attached is a an example of Spring&apos;s state machine impl - i left out additional classes but can create a repo with them if needed&lt;/p&gt;

&lt;p&gt;some highlights:&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;simple chaining of a workflow&lt;/li&gt;
	&lt;li&gt;guards to validate data per state&lt;/li&gt;
	&lt;li&gt;run actions before, after a state completes, during a transition between states&lt;/li&gt;
	&lt;li&gt;forking into multiple paths&lt;/li&gt;
	&lt;li&gt;decisions based on output of an action to decide which path to continue in&lt;/li&gt;
	&lt;li&gt;joining of diverged paths back into a single flow&lt;/li&gt;
	&lt;li&gt;error handler so that if there is an error during a state you get to handle&lt;/li&gt;
	&lt;li&gt;listeners on anything in the workflow&lt;/li&gt;
	&lt;li&gt;dynamically put together a workflow&lt;/li&gt;
	&lt;li&gt;define multiple states - you can have a single workflow that has two initial states that join up at one point ...&lt;/li&gt;
	&lt;li&gt;etc... (a bunch of other things)&lt;/li&gt;
	&lt;li&gt;needs to run in an executedBlocking in vertx but all calls within that can be async&lt;/li&gt;
&lt;/ul&gt;
</comment>
                                                            <comment id="189736" author="5bffed52a1b46046f530c8f7" created="Tue, 17 Apr 2018 12:14:09 +0000"  >&lt;p&gt;See also: &lt;a href=&quot;https://jira.indexdata.com/browse/INTFOLIO-12&quot; class=&quot;external-link&quot; rel=&quot;nofollow noreferrer&quot;&gt;https://jira.indexdata.com/browse/INTFOLIO-12&lt;/a&gt;&lt;/p&gt;</comment>
                                                            <comment id="189738" author="5bffed52a1b46046f530c8f7" created="Mon, 1 Oct 2018 14:40:26 +0000"  >&lt;p&gt;I guess this stream of work reached its conclusion long ago, with the creation of &lt;a href=&quot;https://github.com/indexdata/mod-workflow/blob/master/doc/folio-workflow-engine.md&quot; class=&quot;external-link&quot; rel=&quot;nofollow noreferrer&quot;&gt;https://github.com/indexdata/mod-workflow/blob/master/doc/folio-workflow-engine.md&lt;/a&gt; and related documents.&lt;/p&gt;</comment>
                    </comments>
                <issuelinks>
                            <issuelinktype id="10000">
                    <name>Blocks</name>
                                                                <inwardlinks description="is blocked by">
                                        <issuelink>
            <issuekey id="79560">FOLIO-1042</issuekey>
        </issuelink>
                            </inwardlinks>
                                    </issuelinktype>
                    </issuelinks>
                <attachments>
                            <attachment id="64026" name="WorkflowEngine.java" size="4240" author="712020:32bb56ac-50e7-4787-b4af-ed3089d9401c" created="Sun, 25 Feb 2018 09:38:39 +0000"/>
                    </attachments>
                <subtasks>
                    </subtasks>
                <customfields>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                <customfield id="customfield_10000" key="com.atlassian.jira.plugins.jira-development-integration-plugin:devsummarycf">
                        <customfieldname>Development</customfieldname>
                        <customfieldvalues>
                            
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    <customfield id="customfield_10019" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>0|hzyb7j:</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    <customfield id="customfield_10020" key="com.pyxis.greenhopper.jira:gh-sprint">
                        <customfieldname>Sprint</customfieldname>
                        <customfieldvalues>
                            
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        <customfield id="customfield_10024" key="com.atlassian.jira.ext.charting:firstresponsedate">
                        <customfieldname>[CHART] Date of First Response</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>Sun, 25 Feb 2018 09:17:02 +0000</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_10025" key="com.atlassian.jira.ext.charting:timeinstatus">
                        <customfieldname>[CHART] Time in Status</customfieldname>
                        <customfieldvalues>
                            
                        </customfieldvalues>
                    </customfield>
                                    </customfields>
    </item>
</channel>
</rss>