[codex] Resolve build warnings (#7458)
* Resolve build warnings * Address Greptile review feedback * Remove dead metadata null guard * Preserve tenant-agnostic workflow activities
This commit is contained in:
parent
ec43976e30
commit
27ae1fae64
|
|
@ -6,7 +6,9 @@ using Microsoft.Extensions.DependencyInjection;
|
|||
|
||||
namespace Elsa.Common.ShellFeatures;
|
||||
|
||||
[ShellFeature("DefaultFormatters")]
|
||||
[ShellFeature(
|
||||
"DefaultFormatters",
|
||||
Description = "Registers default serializers and type converters")]
|
||||
public class DefaultFormattersFeature : IShellFeature
|
||||
{
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
|
|
@ -14,4 +16,4 @@ public class DefaultFormattersFeature : IShellFeature
|
|||
TypeDescriptor.AddAttributes(typeof(Type), new TypeConverterAttribute(typeof(TypeTypeConverter)));
|
||||
services.AddSingleton<IFormatter, JsonFormatter>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,9 @@ using Microsoft.Extensions.DependencyInjection;
|
|||
|
||||
namespace Elsa.Common.ShellFeatures;
|
||||
|
||||
[ShellFeature("Multitenancy")]
|
||||
[ShellFeature(
|
||||
"Multitenancy",
|
||||
Description = "Provides tenant resolution, tenant scopes, and tenant lifecycle services")]
|
||||
public class MultitenancyFeature : IShellFeature
|
||||
{
|
||||
private readonly Func<IServiceProvider, ITenantsProvider> _tenantsProviderFactory = sp => sp.GetRequiredService<DefaultTenantsProvider>();
|
||||
|
|
@ -42,4 +44,4 @@ public class MultitenancyFeature : IShellFeature
|
|||
.AddTransient<IDrainHandler, ActivateShellTenants>()
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@ using Microsoft.Extensions.DependencyInjection;
|
|||
namespace Elsa.Common.ShellFeatures;
|
||||
|
||||
[UsedImplicitly]
|
||||
[ShellFeature("StringCompression")]
|
||||
[ShellFeature(
|
||||
"StringCompression",
|
||||
Description = "Registers string compression codecs")]
|
||||
public class StringCompressionFeature : IShellFeature
|
||||
{
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
|
|
@ -18,4 +20,4 @@ public class StringCompressionFeature : IShellFeature
|
|||
.AddSingleton<ICompressionCodec, GZip>()
|
||||
.AddSingleton<ICompressionCodec, Zstd>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using Elsa.Dsl.ElsaScript.Ast;
|
||||
using Elsa.Dsl.ElsaScript.Contracts;
|
||||
using Elsa.Dsl.ElsaScript.Helpers;
|
||||
|
|
@ -114,7 +115,7 @@ public class ElsaScriptCompiler(IActivityRegistryLookupService activityRegistryL
|
|||
metadata.TryGetValue(key, out var value) ? ConvertValue<T>(value, default) : default;
|
||||
|
||||
private T GetMetadataValueOrDefault<T>(Dictionary<string, object> metadata, string key, T defaultValue) =>
|
||||
metadata.TryGetValue(key, out var value) ? ConvertValue(value, defaultValue) : defaultValue;
|
||||
metadata.TryGetValue(key, out var value) ? ConvertValue(value, defaultValue) ?? defaultValue : defaultValue;
|
||||
|
||||
private static T? ConvertValue<T>(object value, T? defaultValue)
|
||||
{
|
||||
|
|
@ -477,6 +478,7 @@ public class ElsaScriptCompiler(IActivityRegistryLookupService activityRegistryL
|
|||
throw new NotSupportedException($"Expression type {exprNode.GetType().Name} is not supported as Expression");
|
||||
}
|
||||
|
||||
[UnconditionalSuppressMessage("Trimming", "IL2060:Call to MakeGenericMethod can not be statically analyzed", Justification = "ElsaScript activity input types are discovered from runtime activity descriptors and must be bound dynamically.")]
|
||||
private object CompileExpression(ExpressionNode exprNode, Type targetType)
|
||||
{
|
||||
// Check if targetType is already Input<T>
|
||||
|
|
@ -598,4 +600,4 @@ public class ElsaScriptCompiler(IActivityRegistryLookupService activityRegistryL
|
|||
|
||||
private static string MapLanguageName(string dslLanguage) =>
|
||||
LanguageMappings.TryGetValue(dslLanguage, out var mapped) ? mapped : dslLanguage;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -454,7 +454,7 @@ public class ElsaScriptParser : IElsaScriptParser
|
|||
|
||||
var workflowWithoutMetadata = workflowKeyword
|
||||
.And(identifier)
|
||||
.Then(x => (WorkflowId: x.Item2.ToString(), Metadata: (IReadOnlyList<(string Name, object Value)>?)null));
|
||||
.Then(x => (WorkflowId: x.Item2.ToString(), Metadata: (IReadOnlyList<(string Name, object Value)>)[]));
|
||||
|
||||
var workflowHeader = workflowWithMetadata.Or(workflowWithoutMetadata);
|
||||
|
||||
|
|
@ -466,12 +466,9 @@ public class ElsaScriptParser : IElsaScriptParser
|
|||
var bodyElements = x.Item2;
|
||||
|
||||
var metadataDict = new Dictionary<string, object>();
|
||||
if (header.Metadata != null)
|
||||
foreach (var entry in header.Metadata)
|
||||
{
|
||||
foreach (var entry in header.Metadata)
|
||||
{
|
||||
metadataDict[entry.Name] = entry.Value;
|
||||
}
|
||||
metadataDict[entry.Name] = entry.Value;
|
||||
}
|
||||
|
||||
// Separate use statements from regular statements in body
|
||||
|
|
|
|||
|
|
@ -30,10 +30,10 @@ internal class ActivityOutputFunctionsDefinitionProvider(IActivityRegistryLookup
|
|||
definitions.AddRange(from output in activityDescriptor.Outputs.Where(x => x.Name.IsValidVariableName())
|
||||
select output.Name.Pascalize()
|
||||
into outputPascalName
|
||||
let activityNamePascalName = activity.Name.Pascalize()
|
||||
let activityNamePascalName = activity.Name!.Pascalize()
|
||||
select CreateFunctionDefinition(builder => builder.Name($"get{outputPascalName}From{activityNamePascalName}").ReturnType("any")));
|
||||
}
|
||||
|
||||
return definitions;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ using Microsoft.Extensions.DependencyInjection;
|
|||
|
||||
namespace Elsa.Resilience.ShellFeatures;
|
||||
|
||||
[ShellFeature]
|
||||
[ShellFeature(Description = "Provides workflow resilience strategies and retry attempt tracking")]
|
||||
public class ResilienceFeature : IFastEndpointsShellFeature
|
||||
{
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
|
|
@ -44,4 +44,4 @@ public class ResilienceFeature : IFastEndpointsShellFeature
|
|||
.AddSingleton<ITransientExceptionStrategy, DefaultTransientExceptionStrategy>()
|
||||
.AddSingleton<ITransientExceptionDetector, TransientExceptionDetector>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -472,7 +472,7 @@ public static class ExpressionExecutionContextExtensions
|
|||
{
|
||||
var activity = activityWithOutput.Activity;
|
||||
var activityDescriptor = activityWithOutput.ActivityDescriptor;
|
||||
var activityIdentifier = useActivityName ? activity.Name : activity.Id;
|
||||
var activityIdentifier = useActivityName ? activity.Name! : activity.Id;
|
||||
var activityIdPascalName = activityIdentifier.Pascalize();
|
||||
|
||||
foreach (var output in activityDescriptor.Outputs)
|
||||
|
|
@ -568,4 +568,4 @@ public static class ExpressionExecutionContextExtensions
|
|||
enumerable
|
||||
])!;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@ using Microsoft.Extensions.DependencyInjection;
|
|||
|
||||
namespace Elsa.Workflows.ShellFeatures;
|
||||
|
||||
[ShellFeature("CommitStrategies")]
|
||||
[ShellFeature(
|
||||
"CommitStrategies",
|
||||
Description = "Registers workflow commit strategies")]
|
||||
public class CommitStrategiesFeature : IShellFeature
|
||||
{
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
|
|
@ -14,4 +16,4 @@ public class CommitStrategiesFeature : IShellFeature
|
|||
services.AddSingleton<ICommitStrategyRegistry, DefaultCommitStrategyRegistry>();
|
||||
services.AddStartupTask<PopulateCommitStrategyRegistry>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,9 @@ using Microsoft.Extensions.DependencyInjection;
|
|||
|
||||
namespace Elsa.Workflows.ShellFeatures;
|
||||
|
||||
[ShellFeature(DependsOn =
|
||||
[ShellFeature(
|
||||
Description = "Provides core workflow execution, activity execution, and workflow serialization services",
|
||||
DependsOn =
|
||||
[
|
||||
"SystemClock",
|
||||
"Expressions",
|
||||
|
|
@ -177,4 +179,4 @@ public class WorkflowsFeature : IShellFeature
|
|||
// Overridable services
|
||||
services.AddScoped<ICommitStateHandler, NoopCommitStateHandler>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,8 +9,23 @@ namespace Elsa.Workflows.Management.Activities.WorkflowDefinitionActivity;
|
|||
/// <summary>
|
||||
/// Provides activity descriptors based on <see cref="WorkflowDefinition"/>s stored in the database.
|
||||
/// </summary>
|
||||
public class WorkflowDefinitionActivityProvider(IWorkflowDefinitionStore store, WorkflowDefinitionActivityDescriptorFactory workflowDefinitionActivityDescriptorFactory, ITenantAccessor tenantAccessor) : IActivityProvider
|
||||
public class WorkflowDefinitionActivityProvider : IActivityProvider
|
||||
{
|
||||
private readonly IWorkflowDefinitionStore _store;
|
||||
private readonly WorkflowDefinitionActivityDescriptorFactory _workflowDefinitionActivityDescriptorFactory;
|
||||
private readonly ITenantAccessor? _tenantAccessor;
|
||||
|
||||
public WorkflowDefinitionActivityProvider(IWorkflowDefinitionStore store, WorkflowDefinitionActivityDescriptorFactory workflowDefinitionActivityDescriptorFactory)
|
||||
{
|
||||
_store = store;
|
||||
_workflowDefinitionActivityDescriptorFactory = workflowDefinitionActivityDescriptorFactory;
|
||||
}
|
||||
|
||||
public WorkflowDefinitionActivityProvider(IWorkflowDefinitionStore store, WorkflowDefinitionActivityDescriptorFactory workflowDefinitionActivityDescriptorFactory, ITenantAccessor tenantAccessor) : this(store, workflowDefinitionActivityDescriptorFactory)
|
||||
{
|
||||
_tenantAccessor = tenantAccessor;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async ValueTask<IEnumerable<ActivityDescriptor>> GetDescriptorsAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
|
|
@ -20,7 +35,14 @@ public class WorkflowDefinitionActivityProvider(IWorkflowDefinitionStore store,
|
|||
VersionOptions = VersionOptions.All
|
||||
};
|
||||
|
||||
var definitions = (await store.FindManyAsync(filter, cancellationToken)).ToList();
|
||||
var definitions = (await _store.FindManyAsync(filter, cancellationToken)).ToList();
|
||||
|
||||
if (_tenantAccessor != null)
|
||||
{
|
||||
var currentTenantId = _tenantAccessor.TenantId;
|
||||
definitions = definitions.Where(x => x.TenantId == Tenant.AgnosticTenantId || x.TenantId.NormalizeTenantId() == currentTenantId).ToList();
|
||||
}
|
||||
|
||||
return CreateDescriptors(definitions).ToList();
|
||||
}
|
||||
|
||||
|
|
@ -34,6 +56,6 @@ public class WorkflowDefinitionActivityProvider(IWorkflowDefinitionStore store,
|
|||
var latestPublishedVersion = allDefinitions
|
||||
.Where(x => x.DefinitionId == definition.DefinitionId && x.IsPublished)
|
||||
.MaxBy(x => x.Version);
|
||||
return workflowDefinitionActivityDescriptorFactory.CreateDescriptor(definition, latestPublishedVersion);
|
||||
return _workflowDefinitionActivityDescriptorFactory.CreateDescriptor(definition, latestPublishedVersion);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ public class MultitenancyTests(App app) : AppComponentTest(app)
|
|||
public void DefaultTenant_ShouldUseEmptyStringAsId()
|
||||
{
|
||||
// Assert
|
||||
Assert.Equal(string.Empty, Tenant.DefaultTenantId);
|
||||
Assert.Empty(Tenant.DefaultTenantId);
|
||||
Assert.Equal(Tenant.DefaultTenantId, Tenant.Default.Id);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ public class ReloadWorkflowTests : AppComponentTest
|
|||
// Set up the initial workflow version.
|
||||
_testWorkflowProvider.MaterializedWorkflows = [workflowV1];
|
||||
await _workflowDefinitionsReloader.ReloadWorkflowDefinitionsAsync();
|
||||
var activityTypeName = workflowV1.Workflow.Name.Pascalize();
|
||||
var activityTypeName = workflowV1.Workflow.Name!.Pascalize();
|
||||
var activityV1 = _activityRegistry.Find(activityTypeName);
|
||||
Assert.Equal(1, activityV1!.Version);
|
||||
|
||||
|
|
@ -151,4 +151,4 @@ public class ReloadWorkflowTests : AppComponentTest
|
|||
workflow.Name = definitionId;
|
||||
return new(workflow, _testWorkflowProvider.Name, TestWorkflowMaterializer.MaterializerName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,9 @@ public class ExceptionExtensionsTests
|
|||
[InlineData(typeof(ThreadAbortException))]
|
||||
public void FatalExceptions(Type exceptionType)
|
||||
{
|
||||
#pragma warning disable SYSLIB0050 // FormatterServices is needed to instantiate fatal exception types without throwing them.
|
||||
var ex = (Exception)System.Runtime.Serialization.FormatterServices.GetUninitializedObject(exceptionType);
|
||||
#pragma warning restore SYSLIB0050
|
||||
Assert.True(ex.IsFatal());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -514,10 +514,10 @@ public class CachingWorkflowDefinitionServiceTests
|
|||
.Returns(async callInfo => await callInfo.Arg<Func<ICacheEntry, Task<WorkflowGraphFindResult>>>()(Substitute.For<ICacheEntry>()));
|
||||
|
||||
_cache.FindOrCreateAsync<WorkflowDefinition>(Arg.Any<object>(), Arg.Any<Func<ICacheEntry, Task<WorkflowDefinition>>>())
|
||||
.Returns(async callInfo => await callInfo.Arg<Func<ICacheEntry, Task<WorkflowDefinition>>>()(Substitute.For<ICacheEntry>()));
|
||||
.Returns(async callInfo => (WorkflowDefinition?)await callInfo.Arg<Func<ICacheEntry, Task<WorkflowDefinition>>>()(Substitute.For<ICacheEntry>()));
|
||||
|
||||
_cache.FindOrCreateAsync<WorkflowGraph>(Arg.Any<object>(), Arg.Any<Func<ICacheEntry, Task<WorkflowGraph>>>())
|
||||
.Returns(async callInfo => await callInfo.Arg<Func<ICacheEntry, Task<WorkflowGraph>>>()(Substitute.For<ICacheEntry>()));
|
||||
.Returns(async callInfo => (WorkflowGraph?)await callInfo.Arg<Func<ICacheEntry, Task<WorkflowGraph>>>()(Substitute.For<ICacheEntry>()));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
Loading…
Reference in a new issue