diff --git a/src/bundles/Elsa.Server.Web/Endpoints/Api1/Get/Endpoint.cs b/src/bundles/Elsa.Server.Web/Endpoints/Api1/Get/Endpoint.cs
deleted file mode 100644
index 5d727bb33..000000000
--- a/src/bundles/Elsa.Server.Web/Endpoints/Api1/Get/Endpoint.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using Elsa.Abstractions;
-using Elsa.Workflows.Activities;
-using Elsa.Workflows.Models;
-using Elsa.Workflows.Runtime.Contracts;
-using Elsa.Workflows.Runtime.Parameters;
-using JetBrains.Annotations;
-
-namespace Elsa.Server.Web.Endpoints.Api1.Get;
-
-///
-/// Returns a message.
-///
-[UsedImplicitly]
-public class Get : ElsaEndpointWithoutRequest
-{
- ///
- public override void Configure()
- {
- Get("/api-1");
- AllowAnonymous();
- }
-
- ///
- public override async Task HandleAsync(CancellationToken ct)
- {
- await Task.Delay(1000, ct);
- var response = new
- {
- Message = "OK"
- };
- await SendOkAsync(response, ct);
- }
-}
\ No newline at end of file
diff --git a/src/bundles/Elsa.Server.Web/Endpoints/DynamicWorkflows/Post/Endpoint.cs b/src/bundles/Elsa.Server.Web/Endpoints/DynamicWorkflows/Post/Endpoint.cs
deleted file mode 100644
index f72fb576e..000000000
--- a/src/bundles/Elsa.Server.Web/Endpoints/DynamicWorkflows/Post/Endpoint.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using Elsa.Abstractions;
-using Elsa.Workflows.Activities;
-using Elsa.Workflows.Models;
-using Elsa.Workflows.Runtime.Contracts;
-using Elsa.Workflows.Runtime.Options;
-using Elsa.Workflows.Runtime.Parameters;
-
-namespace Elsa.Server.Web.Endpoints.DynamicWorkflows.Post;
-
-public class Post(IWorkflowRegistry workflowRegistry, IWorkflowRuntime workflowRuntime) : ElsaEndpointWithoutRequest
-{
- public override void Configure()
- {
- Post("/dynamic-workflows");
- AllowAnonymous();
- }
-
- public override async Task HandleAsync(CancellationToken ct)
- {
- var workflow = new Workflow
- {
- Identity = new WorkflowIdentity("DynamicWorkflow1", 1, "DynamicWorkflow1:v1"),
- Root = new Sequence
- {
- Activities =
- {
- new WriteLine("Step 1"),
- new WriteLine("Step 2"),
- new WriteLine("Step 3")
- }
- }
- };
-
- await workflowRegistry.RegisterAsync(workflow, ct);
- await workflowRuntime.StartWorkflowAsync("DynamicWorkflow1", new StartWorkflowRuntimeParams());
- }
-}
\ No newline at end of file
diff --git a/src/bundles/Elsa.Server.Web/Program.cs b/src/bundles/Elsa.Server.Web/Program.cs
index 9c41549da..c4f259015 100644
--- a/src/bundles/Elsa.Server.Web/Program.cs
+++ b/src/bundles/Elsa.Server.Web/Program.cs
@@ -48,6 +48,7 @@ const bool runEFCoreMigrations = true;
const bool useMemoryStores = false;
const bool useCaching = true;
const bool useReadOnlyMode = false;
+const bool useSignalR = true;
const DistributedCachingTransport distributedCachingTransport = DistributedCachingTransport.MassTransit;
const MassTransitBroker useMassTransitBroker = MassTransitBroker.Memory;
@@ -250,7 +251,6 @@ services
{
api.AddFastEndpointsAssembly();
})
- .UseRealTimeWorkflows()
.UseCSharp(options =>
{
options.AppendScript("string Greet(string name) => $\"Hello {name}!\";");
@@ -322,6 +322,11 @@ services
elsa.UseQuartz(quartz => { quartz.UseSqlite(sqliteConnectionString); });
}
+ if (useSignalR)
+ {
+ elsa.UseRealTimeWorkflows();
+ }
+
if (useMassTransit)
{
elsa.UseMassTransit(massTransit =>
@@ -418,19 +423,18 @@ if (app.Environment.IsDevelopment())
}
// SignalR.
-app.UseWorkflowsSignalRHubs();
+if (useSignalR)
+{
+ app.UseWorkflowsSignalRHubs();
+}
// Run.
app.Run();
-///
/// The main entry point for the application made public for end to end testing.
-///
[UsedImplicitly]
public partial class Program
{
- ///
/// Set by the test runner to configure the module for testing.
- ///
public static Action? ConfigureForTest { get; set; }
-}
+}
\ No newline at end of file
diff --git a/src/clients/Elsa.Api.Client/Resources/WorkflowInstances/Contracts/IWorkflowInstancesApi.cs b/src/clients/Elsa.Api.Client/Resources/WorkflowInstances/Contracts/IWorkflowInstancesApi.cs
index 4a50a368c..a225e57ad 100644
--- a/src/clients/Elsa.Api.Client/Resources/WorkflowInstances/Contracts/IWorkflowInstancesApi.cs
+++ b/src/clients/Elsa.Api.Client/Resources/WorkflowInstances/Contracts/IWorkflowInstancesApi.cs
@@ -1,6 +1,7 @@
using Elsa.Api.Client.Resources.WorkflowDefinitions.Models;
using Elsa.Api.Client.Resources.WorkflowInstances.Models;
using Elsa.Api.Client.Resources.WorkflowInstances.Requests;
+using Elsa.Api.Client.Resources.WorkflowInstances.Responses;
using Elsa.Api.Client.Shared.Models;
using Refit;
@@ -47,14 +48,13 @@ public interface IWorkflowInstancesApi
Task> GetFilteredJournalAsync(string workflowInstanceId, GetFilteredJournalRequest? filter, int? skip = default, int? take = default, CancellationToken cancellationToken = default);
///
- /// Checks if there are updates in the journal for a specific workflow instance.
+ /// Returns the execution state of the specified workflow instance.
///
- /// The ID of the workflow instance for which to check for updates.
- /// The request containing the ID and time from which to check for updates.
+ /// The ID of the workflow instance for which to return its execution state.
/// The cancellation token.
- /// Returns whether updates are available for the journal.
- [Get("/workflow-instances/{workflowInstanceId}/journal/has-updates")]
- Task HasJournalUpdates(string workflowInstanceId, [Query]HasJournalUpdateRequest request, CancellationToken cancellationToken = default);
+ /// Returns a response containing the execution state.
+ [Get("/workflow-instances/{workflowInstanceId}/execution-state")]
+ Task GetExecutionStateAsync(string workflowInstanceId, CancellationToken cancellationToken = default);
///
/// Deletes a workflow instance.
diff --git a/src/clients/Elsa.Api.Client/Resources/WorkflowInstances/Models/HasJournalUpdateRequest.cs b/src/clients/Elsa.Api.Client/Resources/WorkflowInstances/Models/HasJournalUpdateRequest.cs
deleted file mode 100644
index 6efb34477..000000000
--- a/src/clients/Elsa.Api.Client/Resources/WorkflowInstances/Models/HasJournalUpdateRequest.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-namespace Elsa.Api.Client.Resources.WorkflowInstances.Models;
-
-/// A request to update a journal for a workflow instance.
-public class HasJournalUpdateRequest
-{
- /// The unique identifier of a workflow instance.
- public string WorkflowInstanceId { get; set; } = default!;
-
- /// The start date for checking for updates in the workflow instance journal.
- public DateTimeOffset UpdatesSince { get; set; }
-}
\ No newline at end of file
diff --git a/src/clients/Elsa.Api.Client/Resources/WorkflowInstances/Responses/WorkflowInstanceExecutionStateResponse.cs b/src/clients/Elsa.Api.Client/Resources/WorkflowInstances/Responses/WorkflowInstanceExecutionStateResponse.cs
new file mode 100644
index 000000000..e3262e1f8
--- /dev/null
+++ b/src/clients/Elsa.Api.Client/Resources/WorkflowInstances/Responses/WorkflowInstanceExecutionStateResponse.cs
@@ -0,0 +1,6 @@
+using Elsa.Api.Client.Resources.WorkflowInstances.Enums;
+
+namespace Elsa.Api.Client.Resources.WorkflowInstances.Responses;
+
+/// Represents the response containing the last updated timestamp of a workflow instance.
+public record WorkflowInstanceExecutionStateResponse(WorkflowStatus Status, WorkflowSubStatus WorkflowSubStatus, DateTimeOffset UpdatedAt);
\ No newline at end of file
diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowInstances/ExecutionState/Endpoint.cs b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowInstances/ExecutionState/Endpoint.cs
new file mode 100644
index 000000000..96ccc853d
--- /dev/null
+++ b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowInstances/ExecutionState/Endpoint.cs
@@ -0,0 +1,37 @@
+using Elsa.Abstractions;
+using Elsa.Extensions;
+using Elsa.Workflows.Management.Contracts;
+using JetBrains.Annotations;
+
+namespace Elsa.Workflows.Api.Endpoints.WorkflowInstances.ExecutionState;
+
+/// Returns the execution state of the specified workflow instance.
+[PublicAPI]
+internal class ExecutionState(IWorkflowInstanceStore store) : ElsaEndpoint
+{
+ ///
+ public override void Configure()
+ {
+ Get("/workflow-instances/{id}/execution-state");
+ ConfigurePermissions("read:workflow-instances");
+ }
+
+ ///
+ public override async Task HandleAsync(Request request, CancellationToken cancellationToken)
+ {
+ var workflowInstance = await store.FindAsync(request.WorkflowInstanceId, cancellationToken);
+
+ if (workflowInstance == null)
+ {
+ await SendNotFoundAsync(cancellationToken);
+ return;
+ }
+
+ var response = new Response(
+ workflowInstance.Status,
+ workflowInstance.SubStatus,
+ workflowInstance.UpdatedAt);
+
+ await SendOkAsync(response, cancellationToken);
+ }
+}
\ No newline at end of file
diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowInstances/ExecutionState/Models.cs b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowInstances/ExecutionState/Models.cs
new file mode 100644
index 000000000..4a0605239
--- /dev/null
+++ b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowInstances/ExecutionState/Models.cs
@@ -0,0 +1,13 @@
+using FastEndpoints;
+
+namespace Elsa.Workflows.Api.Endpoints.WorkflowInstances.ExecutionState;
+
+/// The request to check the execution state of the workflow instance.
+public class Request
+{
+ /// The unique identifier of a workflow instance.
+ [BindFrom("id")] public string WorkflowInstanceId { get; set; } = default!;
+}
+
+/// Represents the response containing the last updated timestamp of a workflow instance.
+public record Response(WorkflowStatus Status, WorkflowSubStatus SubStatus, DateTimeOffset UpdatedAt);
\ No newline at end of file
diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowInstances/Journal/HasUpdates/Endpoint.cs b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowInstances/Journal/HasUpdates/Endpoint.cs
deleted file mode 100644
index a535e25c9..000000000
--- a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowInstances/Journal/HasUpdates/Endpoint.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-using Elsa.Abstractions;
-using Elsa.Common.Entities;
-using Elsa.Common.Models;
-using Elsa.Workflows.Runtime.Contracts;
-using Elsa.Workflows.Runtime.Filters;
-using Elsa.Workflows.Runtime.OrderDefinitions;
-using JetBrains.Annotations;
-
-namespace Elsa.Workflows.Api.Endpoints.WorkflowInstances.Journal.HasUpdates;
-
-/// Endpoint that checks if there are updates for a workflow instance.
-[PublicAPI]
-internal class HasUpdates(IWorkflowExecutionLogStore store) : ElsaEndpoint
-{
- ///
- public override void Configure()
- {
- Get("/workflow-instances/{id}/journal/has-updates");
- ConfigurePermissions("read:workflow-instances");
- }
-
- ///
- public override async Task ExecuteAsync(Request request, CancellationToken cancellationToken)
- {
- var pageArgs = PageArgs.From(1, 1, 0, 1);
- var filter = new WorkflowExecutionLogRecordFilter { WorkflowInstanceId = request.WorkflowInstanceId };
- var order = new WorkflowExecutionLogRecordOrder(x => x.Sequence, OrderDirection.Descending);
- var pageOfRecords = await store.FindManyAsync(filter, pageArgs, order, cancellationToken);
-
- return pageOfRecords.Items.Any(item => item.Timestamp >= request.UpdatesSince);
- }
-}
\ No newline at end of file
diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowInstances/Journal/HasUpdates/Models.cs b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowInstances/Journal/HasUpdates/Models.cs
deleted file mode 100644
index eefafc6d0..000000000
--- a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowInstances/Journal/HasUpdates/Models.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using FastEndpoints;
-
-namespace Elsa.Workflows.Api.Endpoints.WorkflowInstances.Journal.HasUpdates;
-
-/// The request to check if there are updates for a workflow instance journal.
-public class Request
-{
- /// The unique identifier of a workflow instance.
- [BindFrom("id")] public string WorkflowInstanceId { get; set; } = default!;
-
- /// The start date for checking for updates in the workflow instance journal.
- public DateTimeOffset UpdatesSince { get; set; }
-}
\ No newline at end of file