mirror of
https://github.com/bitwarden/server
synced 2025-12-16 00:03:54 +00:00
Reformat
This commit is contained in:
@@ -1,9 +1,6 @@
|
|||||||
namespace Bit.SeederApi.Services;
|
namespace Bit.SeederApi.Services;
|
||||||
|
|
||||||
public class RecipeNotFoundException : Exception
|
public class RecipeNotFoundException(string recipe) : Exception($"Recipe '{recipe}' not found");
|
||||||
{
|
|
||||||
public RecipeNotFoundException(string message) : base(message) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class RecipeExecutionException : Exception
|
public class RecipeExecutionException : Exception
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,82 +19,17 @@ public class RecipeService : IRecipeService
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Find the recipe class
|
var recipeType = LoadRecipeType(templateName);
|
||||||
var recipeTypeName = $"Bit.Seeder.Recipes.{templateName}";
|
var seedMethod = GetSeedMethod(recipeType, templateName);
|
||||||
var recipeType = Assembly.Load("Seeder")
|
var recipeInstance = Activator.CreateInstance(recipeType, _databaseContext)!;
|
||||||
.GetTypes()
|
|
||||||
.FirstOrDefault(t => t.FullName == recipeTypeName);
|
|
||||||
|
|
||||||
if (recipeType == null)
|
var methodArguments = ParseMethodArguments(seedMethod, arguments);
|
||||||
{
|
|
||||||
throw new RecipeNotFoundException($"Recipe '{templateName}' not found");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Instantiate the recipe with DatabaseContext
|
|
||||||
var recipeInstance = Activator.CreateInstance(recipeType, _databaseContext);
|
|
||||||
if (recipeInstance == null)
|
|
||||||
{
|
|
||||||
throw new RecipeExecutionException("Failed to instantiate recipe");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the Seed method
|
|
||||||
var seedMethod = recipeType.GetMethod("Seed");
|
|
||||||
if (seedMethod == null)
|
|
||||||
{
|
|
||||||
throw new RecipeExecutionException($"Seed method not found in recipe '{templateName}'");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse arguments and match to method parameters
|
|
||||||
var parameters = seedMethod.GetParameters();
|
|
||||||
var methodArguments = new object?[parameters.Length];
|
|
||||||
|
|
||||||
if (arguments == null && parameters.Length > 0)
|
|
||||||
{
|
|
||||||
throw new RecipeExecutionException("Arguments are required for this recipe");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < parameters.Length; i++)
|
|
||||||
{
|
|
||||||
var parameter = parameters[i];
|
|
||||||
var parameterName = parameter.Name!;
|
|
||||||
|
|
||||||
if (arguments?.TryGetProperty(parameterName, out JsonElement value) == true)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
methodArguments[i] = JsonSerializer.Deserialize(value.GetRawText(), parameter.ParameterType);
|
|
||||||
}
|
|
||||||
catch (JsonException ex)
|
|
||||||
{
|
|
||||||
throw new RecipeExecutionException(
|
|
||||||
$"Failed to deserialize parameter '{parameterName}': {ex.Message}", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!parameter.HasDefaultValue)
|
|
||||||
{
|
|
||||||
throw new RecipeExecutionException($"Missing required parameter: {parameterName}");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
methodArguments[i] = parameter.DefaultValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Invoke the Seed method
|
|
||||||
var result = seedMethod.Invoke(recipeInstance, methodArguments);
|
var result = seedMethod.Invoke(recipeInstance, methodArguments);
|
||||||
_logger.LogInformation("Successfully executed recipe: {TemplateName}", templateName);
|
|
||||||
|
|
||||||
|
_logger.LogInformation("Successfully executed recipe: {TemplateName}", templateName);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
catch (RecipeNotFoundException)
|
catch (Exception ex) when (ex is not RecipeNotFoundException and not RecipeExecutionException)
|
||||||
{
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
catch (RecipeExecutionException)
|
|
||||||
{
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
{
|
||||||
_logger.LogError(ex, "Unexpected error executing recipe: {TemplateName}", templateName);
|
_logger.LogError(ex, "Unexpected error executing recipe: {TemplateName}", templateName);
|
||||||
throw new RecipeExecutionException(
|
throw new RecipeExecutionException(
|
||||||
@@ -102,4 +37,61 @@ public class RecipeService : IRecipeService
|
|||||||
ex.InnerException ?? ex);
|
ex.InnerException ?? ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Type LoadRecipeType(string templateName)
|
||||||
|
{
|
||||||
|
var recipeTypeName = $"Bit.Seeder.Recipes.{templateName}";
|
||||||
|
var recipeType = Assembly.Load("Seeder")
|
||||||
|
.GetTypes()
|
||||||
|
.FirstOrDefault(t => t.FullName == recipeTypeName);
|
||||||
|
|
||||||
|
return recipeType ?? throw new RecipeNotFoundException(templateName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MethodInfo GetSeedMethod(Type recipeType, string templateName)
|
||||||
|
{
|
||||||
|
var seedMethod = recipeType.GetMethod("Seed");
|
||||||
|
return seedMethod ?? throw new RecipeExecutionException($"Seed method not found in recipe '{templateName}'");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static object?[] ParseMethodArguments(MethodInfo seedMethod, JsonElement? arguments)
|
||||||
|
{
|
||||||
|
var parameters = seedMethod.GetParameters();
|
||||||
|
|
||||||
|
if (arguments == null && parameters.Length > 0)
|
||||||
|
{
|
||||||
|
throw new RecipeExecutionException("Arguments are required for this recipe");
|
||||||
|
}
|
||||||
|
|
||||||
|
var methodArguments = new object?[parameters.Length];
|
||||||
|
|
||||||
|
for (var i = 0; i < parameters.Length; i++)
|
||||||
|
{
|
||||||
|
var parameter = parameters[i];
|
||||||
|
var parameterName = parameter.Name!;
|
||||||
|
|
||||||
|
if (arguments?.TryGetProperty(parameterName, out var value) == true)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
methodArguments[i] = JsonSerializer.Deserialize(value.GetRawText(), parameter.ParameterType);
|
||||||
|
}
|
||||||
|
catch (JsonException ex)
|
||||||
|
{
|
||||||
|
throw new RecipeExecutionException(
|
||||||
|
$"Failed to deserialize parameter '{parameterName}': {ex.Message}", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!parameter.HasDefaultValue)
|
||||||
|
{
|
||||||
|
throw new RecipeExecutionException($"Missing required parameter: {parameterName}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
methodArguments[i] = parameter.DefaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return methodArguments;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user