Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added File Management related activities #6411

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion Elsa.sln
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docker", "docker", "{986E54
docker\ElsaServer.Dockerfile = docker\ElsaServer.Dockerfile
docker\ElsaServerAndStudio.Dockerfile = docker\ElsaServerAndStudio.Dockerfile
docker\ElsaStudio.Dockerfile = docker\ElsaStudio.Dockerfile
docker\otel-collector-config.yaml = docker\otel-collector-config.yaml
docker\init-db-postgres.sh = docker\init-db-postgres.sh
docker\otel-collector-config.yaml = docker\otel-collector-config.yaml
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Elasticsearch", "src\modules\Elsa.Elasticsearch\Elsa.Elasticsearch.csproj", "{3246883E-2FA7-4B4A-BDC5-99039A2869BC}"
Expand Down Expand Up @@ -403,6 +403,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "oracle-setup", "oracle-setu
docker\oracle-setup\setup.sql = docker\oracle-setup\setup.sql
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.FileManagement", "src\modules\Elsa.FileManagement\Elsa.FileManagement.csproj", "{8C2469AA-7104-458C-B789-F4BF4AFA3417}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -859,6 +861,10 @@ Global
{A51F9683-DA9F-45E7-82DE-1E261ACD6D68}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A51F9683-DA9F-45E7-82DE-1E261ACD6D68}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A51F9683-DA9F-45E7-82DE-1E261ACD6D68}.Release|Any CPU.Build.0 = Release|Any CPU
{8C2469AA-7104-458C-B789-F4BF4AFA3417}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8C2469AA-7104-458C-B789-F4BF4AFA3417}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8C2469AA-7104-458C-B789-F4BF4AFA3417}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8C2469AA-7104-458C-B789-F4BF4AFA3417}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -1011,6 +1017,7 @@ Global
{FA5E857F-B173-4B5D-8049-B817A210DEF5} = {A0DC5F8E-5D7F-4E8A-A5DF-B1FC31F7336E}
{A51F9683-DA9F-45E7-82DE-1E261ACD6D68} = {A0DC5F8E-5D7F-4E8A-A5DF-B1FC31F7336E}
{66E2E2CF-967F-4564-89E8-F46FA973C99B} = {986E5482-0482-448C-B9E4-EC67A9474B85}
{8C2469AA-7104-458C-B789-F4BF4AFA3417} = {B818988E-639C-4E6E-85C1-B231BCAD9DAB}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D4B5CEAA-7D70-4FCB-A68E-B03FBE5E0E5E}
Expand Down
51 changes: 30 additions & 21 deletions src/apps/Elsa.ServerAndStudio.Web/Elsa.ServerAndStudio.Web.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,41 +15,50 @@
<ProjectReference Include="..\..\modules\Elsa.Agents.Persistence.EntityFrameworkCore.SqlServer\Elsa.Agents.Persistence.EntityFrameworkCore.SqlServer.csproj" />
<ProjectReference Include="..\..\modules\Elsa.EntityFrameworkCore.PostgreSql\Elsa.EntityFrameworkCore.PostgreSql.csproj" />
<ProjectReference Include="..\..\modules\Elsa.EntityFrameworkCore.SqlServer\Elsa.EntityFrameworkCore.SqlServer.csproj" />
<ProjectReference Include="..\..\modules\Elsa.FileManagement\Elsa.FileManagement.csproj" />
<ProjectReference Include="..\..\modules\Elsa.FileStorage\Elsa.FileStorage.csproj" />
<ProjectReference Include="..\..\modules\Elsa.JavaScript.Libraries\Elsa.JavaScript.Libraries.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Quartz.EntityFrameworkCore.PostgreSql\Elsa.Quartz.EntityFrameworkCore.PostgreSql.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Quartz.EntityFrameworkCore.SqlServer\Elsa.Quartz.EntityFrameworkCore.SqlServer.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Retention\Elsa.Retention.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Scheduling\Elsa.Scheduling.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Secrets.Persistence.EntityFrameworkCore.PostgreSql\Elsa.Secrets.Persistence.EntityFrameworkCore.PostgreSql.csproj" />
<ProjectReference Include="..\..\modules\Elsa\Elsa.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.Sql.MySql\Elsa.Sql.MySql.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Sql.PostgreSql\Elsa.Sql.PostgreSql.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Sql.Sqlite\Elsa.Sql.Sqlite.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Sql.SqlServer\Elsa.Sql.SqlServer.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Sql\Elsa.Sql.csproj" />
<ProjectReference Include="..\..\modules\Elsa\Elsa.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Caching.Distributed.MassTransit\Elsa.Caching.Distributed.MassTransit.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Caching.Distributed\Elsa.Caching.Distributed.csproj" />
<ProjectReference Include="..\..\modules\Elsa.CSharp\Elsa.CSharp.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.Email\Elsa.Email.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.CSharp\Elsa.CSharp.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Email\Elsa.Email.csproj" />
<ProjectReference Include="..\..\modules\Elsa.EntityFrameworkCore.MySql\Elsa.EntityFrameworkCore.MySql.csproj" Condition=" '$(TargetFramework)' != 'net9.0' " />
<ProjectReference Include="..\..\modules\Elsa.EntityFrameworkCore.Sqlite\Elsa.EntityFrameworkCore.Sqlite.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.Hangfire\Elsa.Hangfire.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.Http\Elsa.Http.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.Identity\Elsa.Identity.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.Liquid\Elsa.Liquid.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.EntityFrameworkCore\Elsa.EntityFrameworkCore.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.MassTransit.AzureServiceBus\Elsa.MassTransit.AzureServiceBus.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.MassTransit.RabbitMq\Elsa.MassTransit.RabbitMq.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.MassTransit\Elsa.MassTransit.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.EntityFrameworkCore.Sqlite\Elsa.EntityFrameworkCore.Sqlite.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Hangfire\Elsa.Hangfire.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Http\Elsa.Http.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Identity\Elsa.Identity.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Liquid\Elsa.Liquid.csproj" />
<ProjectReference Include="..\..\modules\Elsa.EntityFrameworkCore\Elsa.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\modules\Elsa.MassTransit.AzureServiceBus\Elsa.MassTransit.AzureServiceBus.csproj" />
<ProjectReference Include="..\..\modules\Elsa.MassTransit.RabbitMq\Elsa.MassTransit.RabbitMq.csproj" />
<ProjectReference Include="..\..\modules\Elsa.MassTransit\Elsa.MassTransit.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Workflows.Runtime.ProtoActor\Elsa.Workflows.Runtime.ProtoActor.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Python\Elsa.Python.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.Quartz\Elsa.Quartz.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.Webhooks\Elsa.Webhooks.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.Workflows.Api\Elsa.Workflows.Api.csproj"/>
<ProjectReference Include="..\ElsaStudioWebAssembly\ElsaStudioWebAssembly.csproj"/>
<ProjectReference Include="..\..\modules\Elsa.Python\Elsa.Python.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Quartz\Elsa.Quartz.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Webhooks\Elsa.Webhooks.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Workflows.Api\Elsa.Workflows.Api.csproj" />
<ProjectReference Include="..\ElsaStudioWebAssembly\ElsaStudioWebAssembly.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server"/>
<PackageReference Include="Proto.Persistence.Sqlite"/>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" />
<PackageReference Include="Proto.Persistence.Sqlite" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Elsa.Studio"/>
<PackageReference Include="Elsa.Studio.Login.BlazorWasm"/>
<PackageReference Include="Elsa.Studio" />
<PackageReference Include="Elsa.Studio.Login.BlazorWasm" />
</ItemGroup>

</Project>
14 changes: 14 additions & 0 deletions src/apps/Elsa.ServerAndStudio.Web/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
using Microsoft.Data.Sqlite;
using Proto.Persistence.Sqlite;
using WebhooksCore.Options;
using Elsa.Retention.Extensions;
using Elsa.Sql.Extensions;

const bool useMassTransit = true;
const bool useProtoActor = true;
Expand Down Expand Up @@ -153,6 +155,18 @@
ef.UseMySql(mySqlConnectionString);
#endif
}))
.UseRetention()
.UseScheduling()
.UseSql()
.UseFileStorage()
.UseHangfire()

.AddActivity<CopyFileOrDirectory>()
.AddActivity<CreateDirectory>()
.AddActivity<DeleteFileOrDirectory>()
.AddActivity<FileOrFolderExists>()
.AddActivity<ReadFileContent>()
.AddActivity<WriteToFile>()
.UseAgentActivities()
.AddActivitiesFrom<Program>()
.AddWorkflowsFrom<Program>();
Expand Down
2 changes: 1 addition & 1 deletion src/apps/Elsa.ServerAndStudio.Web/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
},
"DatabaseProvider": "Sqlite",
"Hosting": {
"BaseUrl": "https://localhost:8080",
"BaseUrl": "https://localhost:5001",
"ApiPrefix": "/elsa/api"
},
"Identity": {
Expand Down
59 changes: 59 additions & 0 deletions src/modules/Elsa.FileManagement/Activities/CopyFileOrDirectory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using Elsa.Extensions;
using Elsa.Workflows;
using Elsa.Workflows.Attributes;
using Elsa.Workflows.Models;

[Activity("File Management", "Copies a file or directory to the specified path.",
Kind = ActivityKind.Action
)]
public class CopyFileOrDirectory : CodeActivity<bool>
{
[Input(Description = "The source path to the file/folder to copy.")]
public Input<string> SourcePath { get; set; } = default!;

[Input(Description = "The destination path to the file/folder to copy.")]
public Input<string> DestinationPath { get; set; } = default!;

[Input(Description = "Whether to overwrite the destination file/folder if it already exists.")]
public Input<bool> OverWrite { get; set; } = default!;

[Input(Description = "Whether to copy the source directory recursively.")]
public Input<bool> Recursive { get; set; } = default!;

protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
{
if (File.Exists(SourcePath.Get(context)))
{
File.Copy(SourcePath.Get(context), DestinationPath.Get(context), OverWrite.Get(context));
Result.Set(context, true);
}
else if (Directory.Exists(SourcePath.Get(context)))
{
if (!Directory.Exists(DestinationPath.Get(context)))
Directory.CreateDirectory(DestinationPath.Get(context));
foreach (var file in Directory.GetFiles(SourcePath.Get(context)))
{
File.Copy(file, Path.Combine(DestinationPath.Get(context), Path.GetFileName(file)), OverWrite.Get(context));
}
if (Recursive.Get(context))
{
var allDirectories = Directory.GetDirectories(SourcePath.Get(context), "*", SearchOption.AllDirectories);
foreach (var directory in allDirectories)
{
var destinationDirectory = Path.Combine(DestinationPath.Get(context), directory.Substring(SourcePath.Get(context).Length + 1));
if (!Directory.Exists(destinationDirectory))
Directory.CreateDirectory(destinationDirectory);
foreach (var file in Directory.GetFiles(directory))
{
File.Copy(file, Path.Combine(destinationDirectory, Path.GetFileName(file)), OverWrite.Get(context));
}
}
}
Result.Set(context, true);
}
else
{
Result.Set(context, false);
}
}
}
26 changes: 26 additions & 0 deletions src/modules/Elsa.FileManagement/Activities/CreateDirectory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Elsa.Extensions;
using Elsa.Workflows;
using Elsa.Workflows.Attributes;
using Elsa.Workflows.Models;

[Activity("File Management", "Creates a directory at the specified path.",
Kind = ActivityKind.Action
)]
public class CreateDirectory : CodeActivity<bool>
{
[Input(Description = "The path to the directory to create.")]
public Input<string> Path { get; set; } = default!;

protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
{
if(Directory.Exists(Path.Get(context)))
{
Result.Set(context, true);
}
else
{
Directory.CreateDirectory(Path.Get(context));
Result.Set(context, true);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using Elsa.Extensions;
using Elsa.Workflows;
using Elsa.Workflows.Attributes;
using Elsa.Workflows.Models;

[Activity("File Management", "Deletes a file or directory at the specified path.",
Kind = ActivityKind.Action
)]
public class DeleteFileOrDirectory : CodeActivity<bool>
{
[Input(Description = "The path to the file/folder to delete.")]
public Input<string> Path { get; set; } = default!;

protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
{
if (File.Exists(Path.Get(context)))
{
File.Delete(Path.Get(context));
Result.Set(context, true);
}
else if (Directory.Exists(Path.Get(context)))
{
Directory.Delete(Path.Get(context), true);
Result.Set(context, true);
}
else
{
Result.Set(context, false);
}
}
}
19 changes: 19 additions & 0 deletions src/modules/Elsa.FileManagement/Activities/FileOrFolderExists.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Elsa.Extensions;
using Elsa.Workflows;
using Elsa.Workflows.Attributes;
using Elsa.Workflows.Models;

[Activity("File Management", "Checks if a file or folder exists at the specified path.",
Kind = ActivityKind.Action
)]
public class FileOrFolderExists : CodeActivity<bool>
{
[Input(Description = "The path to the file/folder to check.")]
public Input<string> Path { get; set; } = default!;

protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
{
var exists = File.Exists(Path.Get(context)) || Directory.Exists(Path.Get(context));
Result.Set(context, exists);
}
}
26 changes: 26 additions & 0 deletions src/modules/Elsa.FileManagement/Activities/ReadFileContent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Elsa.Extensions;
using Elsa.Workflows;
using Elsa.Workflows.Attributes;
using Elsa.Workflows.Models;

[Activity("File Management", "Reads the content of a file.",
Kind = ActivityKind.Action
)]
public class ReadFileContent : CodeActivity<string>
{
[Input(Description = "The path to the file to read.")]
public Input<string> Path { get; set; } = default!;

protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
{
if (File.Exists(Path.Get(context)))
{
var content = File.ReadAllText(Path.Get(context));
Result.Set(context, content);
}
else
{
Result.Set(context, "");
}
}
}
22 changes: 22 additions & 0 deletions src/modules/Elsa.FileManagement/Activities/WriteToFile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Elsa.Extensions;
using Elsa.Workflows;
using Elsa.Workflows.Attributes;
using Elsa.Workflows.Models;

[Activity("File Management", "Write the content to the file.",
Kind = ActivityKind.Action
)]
public class WriteToFile : CodeActivity<bool>
{
[Input(Description = "The path to the file to write.")]
public Input<string> Path { get; set; } = default!;

[Input(Description = "The content to write to the file.")]
public string Content { get; set; } = default!;

protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
{
File.WriteAllText(Path.Get(context), Content);
Result.Set(context, true);
}
}
23 changes: 23 additions & 0 deletions src/modules/Elsa.FileManagement/Elsa.FileManagement.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<Description>
Provides activities to save and load files to and from a confogurable storage provider.
</Description>
<PackageTags>elsa module activities storage</PackageTags>
</PropertyGroup>

<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="FluentStorage" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Elsa.Workflows.Core\Elsa.Workflows.Core.csproj" />
<ProjectReference Include="..\Elsa.Workflows.Management\Elsa.Workflows.Management.csproj" />
</ItemGroup>

</Project>
3 changes: 3 additions & 0 deletions src/modules/Elsa.FileManagement/FodyWeavers.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait />
</Weavers>