Fixed Indexer SwaggerUI, Added worker & call management endpoints to Indexer, restructuring to improve project separation
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -15,3 +15,5 @@ src/Indexer/obj
|
|||||||
src/Indexer/Scripts/__pycache__
|
src/Indexer/Scripts/__pycache__
|
||||||
src/Indexer/logs
|
src/Indexer/logs
|
||||||
src/Server/logs
|
src/Server/logs
|
||||||
|
src/Shared/bin
|
||||||
|
src/Shared/obj
|
||||||
@@ -7,7 +7,7 @@ using System.Text.Json;
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using System.Reflection.Metadata.Ecma335;
|
using System.Reflection.Metadata.Ecma335;
|
||||||
using Server.Models;
|
using Shared.Models;
|
||||||
|
|
||||||
namespace Client;
|
namespace Client;
|
||||||
|
|
||||||
@@ -86,7 +86,7 @@ public class Client
|
|||||||
return await GetUrlAndProcessJson<EntityQueryResults>(url);
|
return await GetUrlAndProcessJson<EntityQueryResults>(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<EntityIndexResult> EntityIndexAsync(List<Server.JSONEntity> jsonEntity)
|
public async Task<EntityIndexResult> EntityIndexAsync(List<JSONEntity> jsonEntity)
|
||||||
{
|
{
|
||||||
return await EntityIndexAsync(JsonSerializer.Serialize(jsonEntity));
|
return await EntityIndexAsync(JsonSerializer.Serialize(jsonEntity));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Server\Server.csproj" />
|
<ProjectReference Include="..\Shared\Shared.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
|||||||
122
src/Indexer/Controllers/CallsController.cs
Normal file
122
src/Indexer/Controllers/CallsController.cs
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
using ElmahCore;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Indexer.Models;
|
||||||
|
|
||||||
|
namespace Indexer.Controllers;
|
||||||
|
|
||||||
|
[ApiController]
|
||||||
|
[Route("[controller]")]
|
||||||
|
public class CallsController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly ILogger<WorkerController> _logger;
|
||||||
|
private readonly IConfiguration _config;
|
||||||
|
private readonly IConfigurationRoot _configurationRoot;
|
||||||
|
private readonly WorkerCollection _workerCollection;
|
||||||
|
|
||||||
|
public CallsController(ILogger<WorkerController> logger, IConfiguration config, IConfigurationRoot configurationRoot, WorkerCollection workerCollection)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
_config = config;
|
||||||
|
_configurationRoot = configurationRoot;
|
||||||
|
_workerCollection = workerCollection;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("List")]
|
||||||
|
public ActionResult<CallListResults> List(string name)
|
||||||
|
{
|
||||||
|
bool success = true;
|
||||||
|
List<CallListResult> calls = [];
|
||||||
|
var configWorkerSection = _config.GetSection("EmbeddingsearchIndexer:Worker");
|
||||||
|
_workerCollection.Workers.TryGetValue(name, out Worker? worker);
|
||||||
|
if (worker is null)
|
||||||
|
{
|
||||||
|
success = false;
|
||||||
|
_logger.LogError("No worker found under the name {name}.", [name]);
|
||||||
|
HttpContext.RaiseError(new Exception($"No worker found under the name {name}"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (ICall call in worker.Calls)
|
||||||
|
{
|
||||||
|
CallListResult callListResult = new()
|
||||||
|
{
|
||||||
|
CallConfig = call.CallConfig,
|
||||||
|
IsRunning = call.IsRunning,
|
||||||
|
LastExecution = call.LastExecution,
|
||||||
|
LastSuccessfulExecution = call.LastSuccessfulExecution,
|
||||||
|
HealthStatus = call.HealthCheck().Status.ToString()
|
||||||
|
};
|
||||||
|
calls.Add(callListResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new CallListResults() { Calls = calls, Success = success };
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("Enable")]
|
||||||
|
public ActionResult<WorkerStartResult> Enable(string name)
|
||||||
|
{
|
||||||
|
_workerCollection.Workers.TryGetValue(name, out Worker? worker);
|
||||||
|
if (worker is null)
|
||||||
|
{
|
||||||
|
_logger.LogError("Unable to start calls in worker {name} - no running worker with this name.", [name]);
|
||||||
|
return new WorkerStartResult { Success = false };
|
||||||
|
}
|
||||||
|
_logger.LogInformation("Starting calls in worker {name}.", [name]);
|
||||||
|
foreach (ICall call in worker.Calls)
|
||||||
|
{
|
||||||
|
call.Start();
|
||||||
|
}
|
||||||
|
_logger.LogInformation("Starting calls in worker {name}.", [name]);
|
||||||
|
return new WorkerStartResult { Success = true };
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("Disable")]
|
||||||
|
public ActionResult<WorkerStopResult> Disable(string name)
|
||||||
|
{
|
||||||
|
_workerCollection.Workers.TryGetValue(name, out Worker? worker);
|
||||||
|
if (worker is null)
|
||||||
|
{
|
||||||
|
_logger.LogError("Unable to stop calls in worker {name} - no running worker with this name.", [name]);
|
||||||
|
return new WorkerStopResult { Success = false };
|
||||||
|
}
|
||||||
|
_logger.LogInformation("Stopping calls in worker {name}.", [name]);
|
||||||
|
foreach (ICall call in worker.Calls)
|
||||||
|
{
|
||||||
|
call.Stop();
|
||||||
|
}
|
||||||
|
_logger.LogInformation("Stopped calls in worker {name}.", [name]);
|
||||||
|
return new WorkerStopResult { Success = true };
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("Reload")]
|
||||||
|
public ActionResult<WorkerReloadConfigResult> Reload()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Reloading configuration");
|
||||||
|
_configurationRoot.Reload();
|
||||||
|
_logger.LogInformation("Reloaded configuration");
|
||||||
|
_logger.LogInformation("Destroying workers");
|
||||||
|
foreach (KeyValuePair<string, Worker> workerKVPair in _workerCollection.Workers)
|
||||||
|
{
|
||||||
|
Worker worker = workerKVPair.Value;
|
||||||
|
foreach (ICall call in worker.Calls)
|
||||||
|
{
|
||||||
|
call.Stop();
|
||||||
|
}
|
||||||
|
_workerCollection.Workers.Remove(workerKVPair.Key);
|
||||||
|
_logger.LogInformation("Destroyed worker {workerKVPair.Key}", [workerKVPair.Key]);
|
||||||
|
}
|
||||||
|
_logger.LogInformation("Destroyed workers");
|
||||||
|
_workerCollection.InitializeWorkers();
|
||||||
|
return new WorkerReloadConfigResult { Success = true };
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError("Exception {ex.Message} happened while trying to reload the worker configuration.", [ex.Message]);
|
||||||
|
HttpContext.RaiseError(ex);
|
||||||
|
return new WorkerReloadConfigResult { Success = false };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
74
src/Indexer/Controllers/WorkerController.cs
Normal file
74
src/Indexer/Controllers/WorkerController.cs
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
using ElmahCore;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Indexer.Models;
|
||||||
|
|
||||||
|
namespace Indexer.Controllers;
|
||||||
|
|
||||||
|
[ApiController]
|
||||||
|
[Route("[controller]")]
|
||||||
|
public class WorkerController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly ILogger<WorkerController> _logger;
|
||||||
|
private readonly IConfiguration _config;
|
||||||
|
private readonly IConfigurationRoot _configurationRoot;
|
||||||
|
private readonly WorkerCollection _workerCollection;
|
||||||
|
|
||||||
|
public WorkerController(ILogger<WorkerController> logger, IConfiguration config, IConfigurationRoot configurationRoot, WorkerCollection workerCollection)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
_config = config;
|
||||||
|
_configurationRoot = configurationRoot;
|
||||||
|
_workerCollection = workerCollection;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("List")]
|
||||||
|
public ActionResult<WorkerListResults> List() // List the workers (and perhaps current execution status, maybe also health status and retry count?)
|
||||||
|
{
|
||||||
|
bool success = true;
|
||||||
|
List<WorkerListResult> workerListResultList = [];
|
||||||
|
try
|
||||||
|
{
|
||||||
|
foreach (KeyValuePair<string, Worker> workerKVPair in _workerCollection.Workers)
|
||||||
|
{
|
||||||
|
Worker worker = workerKVPair.Value;
|
||||||
|
WorkerListResult workerListResult = new()
|
||||||
|
{
|
||||||
|
Name = worker.Name,
|
||||||
|
Script = worker.Config.Script,
|
||||||
|
HealthStatus = worker.HealthCheck().Status.ToString()
|
||||||
|
};
|
||||||
|
workerListResultList.Add(workerListResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
success = false;
|
||||||
|
_logger.LogError("Unable to list workers due to exception: {ex.Message}", [ex.Message]);
|
||||||
|
HttpContext.RaiseError(ex);
|
||||||
|
}
|
||||||
|
WorkerListResults workerListResults = new()
|
||||||
|
{
|
||||||
|
Workers = workerListResultList,
|
||||||
|
Success = success
|
||||||
|
};
|
||||||
|
return workerListResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("TriggerUpdate")]
|
||||||
|
public ActionResult<WorkerTriggerUpdateResult> TriggerUpdate(string name)
|
||||||
|
{
|
||||||
|
_workerCollection.Workers.TryGetValue(name, out Worker? worker);
|
||||||
|
if (worker is null)
|
||||||
|
{
|
||||||
|
_logger.LogError("Unable to trigger worker {name} - no running worker with this name.", [name]);
|
||||||
|
return new WorkerTriggerUpdateResult { Success = false };
|
||||||
|
}
|
||||||
|
_logger.LogInformation("triggering worker {name}.", [name]);
|
||||||
|
ManualTriggerCallbackInfos callbackInfos = new();
|
||||||
|
worker.Scriptable.Update(callbackInfos);
|
||||||
|
_logger.LogInformation("triggered worker {name}.", [name]);
|
||||||
|
return new WorkerTriggerUpdateResult { Success = true };
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
<PackageReference Include="Pythonnet" Version="3.0.5" />
|
<PackageReference Include="Pythonnet" Version="3.0.5" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Server\Server.csproj" />
|
|
||||||
<ProjectReference Include="..\Client\Client.csproj" />
|
<ProjectReference Include="..\Client\Client.csproj" />
|
||||||
|
<ProjectReference Include="..\Shared\Shared.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -17,8 +17,9 @@ public class WorkerHealthCheck : IHealthCheck
|
|||||||
bool hasDegraded = false;
|
bool hasDegraded = false;
|
||||||
bool hasUnhealthy = false;
|
bool hasUnhealthy = false;
|
||||||
Dictionary<string, HealthStatus> degradedWorkerList = [];
|
Dictionary<string, HealthStatus> degradedWorkerList = [];
|
||||||
foreach (Worker worker in _workerCollection.Workers)
|
foreach (KeyValuePair<string, Worker> workerKVPair in _workerCollection.Workers)
|
||||||
{
|
{
|
||||||
|
Worker worker = workerKVPair.Value;
|
||||||
HealthCheckResult workerHealth = worker.HealthCheck();
|
HealthCheckResult workerHealth = worker.HealthCheck();
|
||||||
hasDegraded |= workerHealth.Status == HealthStatus.Degraded;
|
hasDegraded |= workerHealth.Status == HealthStatus.Degraded;
|
||||||
hasUnhealthy |= workerHealth.Status == HealthStatus.Unhealthy;
|
hasUnhealthy |= workerHealth.Status == HealthStatus.Unhealthy;
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ public interface IScriptable
|
|||||||
ILogger _logger { get; set; }
|
ILogger _logger { get; set; }
|
||||||
void Init();
|
void Init();
|
||||||
void Update(ICallbackInfos callbackInfos);
|
void Update(ICallbackInfos callbackInfos);
|
||||||
|
void Stop();
|
||||||
|
|
||||||
bool IsScript(string filePath);
|
bool IsScript(string filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,12 +10,14 @@ public class PythonScriptable : IScriptable
|
|||||||
public PyModule scope;
|
public PyModule scope;
|
||||||
public dynamic sys;
|
public dynamic sys;
|
||||||
public string source;
|
public string source;
|
||||||
|
public bool SourceLoaded { get; set; }
|
||||||
public ScriptUpdateInfo UpdateInfo { get; set; }
|
public ScriptUpdateInfo UpdateInfo { get; set; }
|
||||||
public ILogger _logger { get; set; }
|
public ILogger _logger { get; set; }
|
||||||
public PythonScriptable(ScriptToolSet toolSet, ILogger logger)
|
public PythonScriptable(ScriptToolSet toolSet, ILogger logger)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
Runtime.PythonDLL = @"libpython3.12.so";
|
SourceLoaded = false;
|
||||||
|
Runtime.PythonDLL ??= @"libpython3.12.so";
|
||||||
if (!PythonEngine.IsInitialized)
|
if (!PythonEngine.IsInitialized)
|
||||||
{
|
{
|
||||||
PythonEngine.Initialize();
|
PythonEngine.Initialize();
|
||||||
@@ -39,36 +41,22 @@ public class PythonScriptable : IScriptable
|
|||||||
|
|
||||||
public void Init()
|
public void Init()
|
||||||
{
|
{
|
||||||
int retryCounter = 0;
|
ExecFunction("init");
|
||||||
retry:
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using (Py.GIL())
|
|
||||||
{
|
|
||||||
pyToolSet = ToolSet.ToPython();
|
|
||||||
scope.Set("toolset", pyToolSet);
|
|
||||||
scope.Exec(source);
|
|
||||||
scope.Exec("init(toolset)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
UpdateInfo = new() { DateTime = DateTime.Now, Successful = false, Exception = ex };
|
|
||||||
if (retryCounter < 3)
|
|
||||||
{
|
|
||||||
_logger.LogWarning("Unable to init the scriptable - retrying", [ToolSet.filePath, ex]);
|
|
||||||
retryCounter++;
|
|
||||||
goto retry;
|
|
||||||
}
|
|
||||||
_logger.LogError("Unable to init the scriptable", [ToolSet.filePath, ex]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
UpdateInfo = new() { DateTime = DateTime.Now, Successful = true };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update(ICallbackInfos callbackInfos)
|
public void Update(ICallbackInfos callbackInfos)
|
||||||
{
|
{
|
||||||
int retryCounter = 0;
|
ExecFunction("update");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Stop()
|
||||||
|
{
|
||||||
|
ExecFunction("stop");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ExecFunction(string name, ICallbackInfos? callbackInfos = null)
|
||||||
|
{
|
||||||
|
int retryCounter = 0;
|
||||||
retry:
|
retry:
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -77,7 +65,12 @@ public class PythonScriptable : IScriptable
|
|||||||
pyToolSet = ToolSet.ToPython();
|
pyToolSet = ToolSet.ToPython();
|
||||||
pyToolSet.SetAttr("callbackInfos", callbackInfos.ToPython());
|
pyToolSet.SetAttr("callbackInfos", callbackInfos.ToPython());
|
||||||
scope.Set("toolset", pyToolSet);
|
scope.Set("toolset", pyToolSet);
|
||||||
scope.Exec("update(toolset)");
|
if (!SourceLoaded)
|
||||||
|
{
|
||||||
|
scope.Exec(source);
|
||||||
|
SourceLoaded = true;
|
||||||
|
}
|
||||||
|
scope.Exec($"{name}(toolset)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -85,12 +78,11 @@ public class PythonScriptable : IScriptable
|
|||||||
UpdateInfo = new() { DateTime = DateTime.Now, Successful = false, Exception = ex };
|
UpdateInfo = new() { DateTime = DateTime.Now, Successful = false, Exception = ex };
|
||||||
if (retryCounter < 3)
|
if (retryCounter < 3)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("Execution of script failed to an exception - retrying", [ToolSet.filePath, ex]);
|
_logger.LogWarning("Execution of {name} function in script {Toolset.filePath} failed to an exception {ex.Message}", [name, ToolSet.filePath, ex.Message]);
|
||||||
retryCounter++;
|
retryCounter++;
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
_logger.LogError("Execution of script failed to an exception", [ToolSet.filePath, ex]);
|
_logger.LogError("Execution of {name} function in script {Toolset.filePath} failed to an exception {ex.Message}", [name, ToolSet.filePath, ex.Message]);
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
UpdateInfo = new() { DateTime = DateTime.Now, Successful = true };
|
UpdateInfo = new() { DateTime = DateTime.Now, Successful = true };
|
||||||
}
|
}
|
||||||
@@ -128,6 +120,8 @@ public class IntervalCallbackInfos : ICallbackInfos
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class ManualTriggerCallbackInfos : ICallbackInfos {}
|
||||||
|
|
||||||
public struct ScriptUpdateInfo
|
public struct ScriptUpdateInfo
|
||||||
{
|
{
|
||||||
public DateTime DateTime { get; set; }
|
public DateTime DateTime { get; set; }
|
||||||
|
|||||||
@@ -1,15 +1,125 @@
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using Microsoft.Extensions.Diagnostics.HealthChecks;
|
using Microsoft.Extensions.Diagnostics.HealthChecks;
|
||||||
|
using Indexer.Exceptions;
|
||||||
|
|
||||||
namespace Indexer.Models;
|
namespace Indexer.Models;
|
||||||
|
|
||||||
public class WorkerCollection
|
public class WorkerCollection
|
||||||
{
|
{
|
||||||
public List<Worker> Workers;
|
public Dictionary<string, Worker> Workers;
|
||||||
public List<Type> types;
|
public List<Type> types;
|
||||||
public WorkerCollection()
|
private readonly ILogger _logger;
|
||||||
|
private readonly IConfiguration _configuration;
|
||||||
|
private readonly Client.Client client;
|
||||||
|
|
||||||
|
public WorkerCollection(ILogger<WorkerCollection> logger, IConfiguration configuration, Client.Client client)
|
||||||
{
|
{
|
||||||
Workers = [];
|
Workers = [];
|
||||||
types = [typeof(PythonScriptable)];
|
types = [typeof(PythonScriptable)];
|
||||||
|
_logger = logger;
|
||||||
|
_configuration = configuration;
|
||||||
|
this.client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void InitializeWorkers()
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Initializing workers");
|
||||||
|
// Load and configure all workers
|
||||||
|
var sectionMain = _configuration.GetSection("EmbeddingsearchIndexer");
|
||||||
|
if (!sectionMain.Exists())
|
||||||
|
{
|
||||||
|
_logger.LogCritical("Unable to load section \"EmbeddingsearchIndexer\"");
|
||||||
|
throw new IndexerConfigurationException("Unable to load section \"EmbeddingsearchIndexer\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
WorkerCollectionConfig? sectionWorker = (WorkerCollectionConfig?)sectionMain.Get(typeof(WorkerCollectionConfig)); //GetValue<WorkerCollectionConfig>("Worker");
|
||||||
|
if (sectionWorker is not null)
|
||||||
|
{
|
||||||
|
foreach (WorkerConfig workerConfig in sectionWorker.Worker)
|
||||||
|
{
|
||||||
|
ScriptToolSet toolSet = new(workerConfig.Script, client);
|
||||||
|
InitializeWorker(toolSet, workerConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.LogCritical("Unable to load section \"Worker\"");
|
||||||
|
throw new IndexerConfigurationException("Unable to load section \"Worker\"");
|
||||||
|
}
|
||||||
|
_logger.LogInformation("Initialized workers");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void InitializeWorker(ScriptToolSet toolSet, WorkerConfig workerConfig)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Initializing worker: {Name}", workerConfig.Name);
|
||||||
|
Worker worker = new(workerConfig.Name, workerConfig, GetScriptable(toolSet));
|
||||||
|
Workers[workerConfig.Name] = worker;
|
||||||
|
foreach (CallConfig callConfig in workerConfig.Calls)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Initializing call of type: {Type}", callConfig.Type);
|
||||||
|
|
||||||
|
switch (callConfig.Type)
|
||||||
|
{
|
||||||
|
case "interval":
|
||||||
|
if (callConfig.Interval is null)
|
||||||
|
{
|
||||||
|
_logger.LogError("Interval not set for a Call in Worker \"{Name}\"", workerConfig.Name);
|
||||||
|
throw new IndexerConfigurationException($"Interval not set for a Call in Worker \"{workerConfig.Name}\"");
|
||||||
|
}
|
||||||
|
var timer = new System.Timers.Timer((double)callConfig.Interval);
|
||||||
|
timer.AutoReset = true;
|
||||||
|
timer.Enabled = true;
|
||||||
|
DateTime now = DateTime.Now;
|
||||||
|
IntervalCall call = new(timer, worker.Scriptable, _logger, callConfig)
|
||||||
|
{
|
||||||
|
LastExecution = now,
|
||||||
|
LastSuccessfulExecution = now
|
||||||
|
};
|
||||||
|
timer.Elapsed += (sender, e) =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
call.LastExecution = DateTime.Now;
|
||||||
|
worker.Scriptable.Update(new IntervalCallbackInfos() { sender = sender, e = e });
|
||||||
|
call.LastSuccessfulExecution = DateTime.Now;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError("Exception occurred in a Call of Worker \"{name}\": \"{ex}\"", worker.Name, ex.Message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
worker.Calls.Add(call);
|
||||||
|
break;
|
||||||
|
case "schedule": // TODO implement scheduled tasks using Quartz
|
||||||
|
throw new NotImplementedException("schedule not implemented yet");
|
||||||
|
case "fileupdate":
|
||||||
|
if (callConfig.Path is null)
|
||||||
|
{
|
||||||
|
_logger.LogError("Path not set for a Call in Worker \"{Name}\"", workerConfig.Name);
|
||||||
|
throw new IndexerConfigurationException($"Path not set for a Call in Worker \"{workerConfig.Name}\"");
|
||||||
|
}
|
||||||
|
throw new NotImplementedException("fileupdate not implemented yet");
|
||||||
|
//break;
|
||||||
|
default:
|
||||||
|
throw new IndexerConfigurationException($"Unknown Type specified for a Call in Worker \"{workerConfig.Name}\"");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IScriptable GetScriptable(ScriptToolSet toolSet)
|
||||||
|
{
|
||||||
|
string fileName = toolSet.filePath;
|
||||||
|
foreach (Type type in types)
|
||||||
|
{
|
||||||
|
IScriptable? instance = (IScriptable?)Activator.CreateInstance(type, [toolSet, _logger]);
|
||||||
|
if (instance is not null && instance.IsScript(fileName))
|
||||||
|
{
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_logger.LogError("Unable to determine the script's language: \"{fileName}\"", fileName);
|
||||||
|
|
||||||
|
throw new UnknownScriptLanguageException(fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,6 +186,12 @@ public class CallConfig
|
|||||||
public interface ICall
|
public interface ICall
|
||||||
{
|
{
|
||||||
public HealthCheckResult HealthCheck();
|
public HealthCheckResult HealthCheck();
|
||||||
|
public void Start();
|
||||||
|
public void Stop();
|
||||||
|
public bool IsRunning { get; set; }
|
||||||
|
public CallConfig CallConfig { get; set; }
|
||||||
|
public DateTime? LastExecution { get; set; }
|
||||||
|
public DateTime? LastSuccessfulExecution { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class IntervalCall : ICall
|
public class IntervalCall : ICall
|
||||||
@@ -83,11 +199,31 @@ public class IntervalCall : ICall
|
|||||||
public System.Timers.Timer Timer;
|
public System.Timers.Timer Timer;
|
||||||
public IScriptable Scriptable;
|
public IScriptable Scriptable;
|
||||||
public ILogger _logger;
|
public ILogger _logger;
|
||||||
public IntervalCall(System.Timers.Timer timer, IScriptable scriptable, ILogger logger)
|
public bool IsRunning { get; set; }
|
||||||
|
public CallConfig CallConfig { get; set; }
|
||||||
|
public DateTime? LastExecution { get; set; }
|
||||||
|
public DateTime? LastSuccessfulExecution { get; set; }
|
||||||
|
|
||||||
|
public IntervalCall(System.Timers.Timer timer, IScriptable scriptable, ILogger logger, CallConfig callConfig)
|
||||||
{
|
{
|
||||||
Timer = timer;
|
Timer = timer;
|
||||||
Scriptable = scriptable;
|
Scriptable = scriptable;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
CallConfig = callConfig;
|
||||||
|
IsRunning = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
Timer.Start();
|
||||||
|
IsRunning = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Stop()
|
||||||
|
{
|
||||||
|
Scriptable.Stop();
|
||||||
|
Timer.Stop();
|
||||||
|
IsRunning = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HealthCheckResult HealthCheck()
|
public HealthCheckResult HealthCheck()
|
||||||
@@ -113,6 +249,24 @@ public class IntervalCall : ICall
|
|||||||
|
|
||||||
public class ScheduleCall : ICall
|
public class ScheduleCall : ICall
|
||||||
{
|
{
|
||||||
|
public bool IsRunning { get; set; }
|
||||||
|
public CallConfig CallConfig { get; set; }
|
||||||
|
public DateTime? LastExecution { get; set; }
|
||||||
|
public DateTime? LastSuccessfulExecution { get; set; }
|
||||||
|
|
||||||
|
public ScheduleCall(CallConfig callConfig)
|
||||||
|
{
|
||||||
|
CallConfig = callConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Stop()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public HealthCheckResult HealthCheck()
|
public HealthCheckResult HealthCheck()
|
||||||
{
|
{
|
||||||
return HealthCheckResult.Unhealthy(); // Not implemented yet
|
return HealthCheckResult.Unhealthy(); // Not implemented yet
|
||||||
@@ -121,6 +275,24 @@ public class ScheduleCall : ICall
|
|||||||
|
|
||||||
public class FileUpdateCall : ICall
|
public class FileUpdateCall : ICall
|
||||||
{
|
{
|
||||||
|
public bool IsRunning { get; set; }
|
||||||
|
public CallConfig CallConfig { get; set; }
|
||||||
|
public DateTime? LastExecution { get; set; }
|
||||||
|
public DateTime? LastSuccessfulExecution { get; set; }
|
||||||
|
|
||||||
|
public FileUpdateCall(CallConfig callConfig)
|
||||||
|
{
|
||||||
|
CallConfig = callConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Stop()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public HealthCheckResult HealthCheck()
|
public HealthCheckResult HealthCheck()
|
||||||
{
|
{
|
||||||
return HealthCheckResult.Unhealthy(); // Not implemented yet
|
return HealthCheckResult.Unhealthy(); // Not implemented yet
|
||||||
|
|||||||
68
src/Indexer/Models/WorkerResults.cs
Normal file
68
src/Indexer/Models/WorkerResults.cs
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using Microsoft.Extensions.Diagnostics.HealthChecks;
|
||||||
|
|
||||||
|
namespace Indexer.Models;
|
||||||
|
|
||||||
|
public class WorkerListResults
|
||||||
|
{
|
||||||
|
[JsonPropertyName("WorkerList")]
|
||||||
|
public required List<WorkerListResult> Workers { get; set; }
|
||||||
|
[JsonPropertyName("Success")]
|
||||||
|
public required bool Success { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class WorkerListResult
|
||||||
|
{
|
||||||
|
[JsonPropertyName("Name")]
|
||||||
|
public required string Name { get; set; }
|
||||||
|
[JsonPropertyName("Script")]
|
||||||
|
public required string Script { get; set; }
|
||||||
|
[JsonPropertyName("HealthStatus")]
|
||||||
|
public required string HealthStatus { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CallListResults
|
||||||
|
{
|
||||||
|
[JsonPropertyName("Calls")]
|
||||||
|
public required List<CallListResult> Calls { get; set; }
|
||||||
|
[JsonPropertyName("Success")]
|
||||||
|
public required bool Success { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CallListResult
|
||||||
|
{
|
||||||
|
[JsonPropertyName("CallConfig")]
|
||||||
|
public required CallConfig CallConfig { get; set; }
|
||||||
|
[JsonPropertyName("IsRunning")]
|
||||||
|
public required bool IsRunning { get; set; }
|
||||||
|
[JsonPropertyName("LastExecution")]
|
||||||
|
public required DateTime? LastExecution { get; set; }
|
||||||
|
[JsonPropertyName("LastSuccessfulExecution")]
|
||||||
|
public required DateTime? LastSuccessfulExecution { get; set; }
|
||||||
|
[JsonPropertyName("HealthStatus")]
|
||||||
|
public required string HealthStatus { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class WorkerStopResult
|
||||||
|
{
|
||||||
|
[JsonPropertyName("Success")]
|
||||||
|
public required bool Success { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class WorkerStartResult
|
||||||
|
{
|
||||||
|
[JsonPropertyName("Success")]
|
||||||
|
public required bool Success { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class WorkerTriggerUpdateResult
|
||||||
|
{
|
||||||
|
[JsonPropertyName("Success")]
|
||||||
|
public required bool Success { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class WorkerReloadConfigResult
|
||||||
|
{
|
||||||
|
[JsonPropertyName("Success")]
|
||||||
|
public required bool Success { get; set; }
|
||||||
|
}
|
||||||
@@ -3,7 +3,6 @@ using Indexer.Models;
|
|||||||
using Indexer.Services;
|
using Indexer.Services;
|
||||||
using ElmahCore;
|
using ElmahCore;
|
||||||
using ElmahCore.Mvc;
|
using ElmahCore.Mvc;
|
||||||
using Server;
|
|
||||||
using ElmahCore.Mvc.Logger;
|
using ElmahCore.Mvc.Logger;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
@@ -20,12 +19,12 @@ Log.Logger = new LoggerConfiguration()
|
|||||||
.CreateLogger();
|
.CreateLogger();
|
||||||
builder.Logging.AddSerilog();
|
builder.Logging.AddSerilog();
|
||||||
builder.Services.AddHttpContextAccessor();
|
builder.Services.AddHttpContextAccessor();
|
||||||
|
builder.Services.AddSingleton<IConfigurationRoot>(builder.Configuration);
|
||||||
builder.Services.AddSingleton<Client.Client>();
|
builder.Services.AddSingleton<Client.Client>();
|
||||||
builder.Services.AddSingleton<WorkerCollection>();
|
builder.Services.AddSingleton<WorkerCollection>();
|
||||||
builder.Services.AddHostedService<IndexerService>();
|
builder.Services.AddHostedService<IndexerService>();
|
||||||
builder.Services.AddHealthChecks()
|
builder.Services.AddHealthChecks()
|
||||||
.AddCheck<WorkerHealthCheck>("WorkerHealthCheck");
|
.AddCheck<WorkerHealthCheck>("WorkerHealthCheck");
|
||||||
|
|
||||||
builder.Services.AddElmah<XmlFileErrorLog>(Options =>
|
builder.Services.AddElmah<XmlFileErrorLog>(Options =>
|
||||||
{
|
{
|
||||||
Options.LogPath = builder.Configuration.GetValue<string>("EmbeddingsearchIndexer:Elmah:LogFolder") ?? "~/logs";
|
Options.LogPath = builder.Configuration.GetValue<string>("EmbeddingsearchIndexer:Elmah:LogFolder") ?? "~/logs";
|
||||||
@@ -67,9 +66,11 @@ if (app.Environment.IsDevelopment())
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
app.UseMiddleware<ApiKeyMiddleware>();
|
app.UseMiddleware<Shared.ApiKeyMiddleware>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// app.UseHttpsRedirection();
|
// app.UseHttpsRedirection();
|
||||||
|
|
||||||
|
app.MapControllers();
|
||||||
|
|
||||||
app.Run();
|
app.Run();
|
||||||
|
|||||||
@@ -6,103 +6,18 @@ namespace Indexer.Services;
|
|||||||
|
|
||||||
public class IndexerService : IHostedService
|
public class IndexerService : IHostedService
|
||||||
{
|
{
|
||||||
private readonly WorkerCollection workerCollection;
|
public WorkerCollection workerCollection;
|
||||||
private readonly IConfiguration _config;
|
|
||||||
private readonly Client.Client client;
|
|
||||||
public ILogger<IndexerService> _logger;
|
public ILogger<IndexerService> _logger;
|
||||||
|
|
||||||
public IndexerService(WorkerCollection workerCollection, IConfiguration configuration, Client.Client client, ILogger<IndexerService> logger, IHttpContextAccessor httpContextAccessor)
|
public IndexerService(WorkerCollection workerCollection, Client.Client client, ILogger<IndexerService> logger)
|
||||||
{
|
{
|
||||||
this._config = configuration;
|
|
||||||
this.client = client;
|
|
||||||
this.workerCollection = workerCollection;
|
this.workerCollection = workerCollection;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_logger.LogInformation("Initializing IndexerService");
|
_logger.LogInformation("Initializing IndexerService");
|
||||||
// Load and configure all workers
|
workerCollection.InitializeWorkers();
|
||||||
var sectionMain = _config.GetSection("EmbeddingsearchIndexer");
|
_logger.LogInformation("Initialized IndexerService");
|
||||||
if (!sectionMain.Exists())
|
|
||||||
{
|
|
||||||
_logger.LogCritical("Unable to load section \"EmbeddingsearchIndexer\"");
|
|
||||||
throw new IndexerConfigurationException("Unable to load section \"EmbeddingsearchIndexer\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
WorkerCollectionConfig? sectionWorker = (WorkerCollectionConfig?)sectionMain.Get(typeof(WorkerCollectionConfig)); //GetValue<WorkerCollectionConfig>("Worker");
|
|
||||||
if (sectionWorker is not null)
|
|
||||||
{
|
|
||||||
foreach (WorkerConfig workerConfig in sectionWorker.Worker)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("Initializing worker: {Name}", workerConfig.Name);
|
|
||||||
ScriptToolSet toolSet = new(workerConfig.Script, client);
|
|
||||||
Worker worker = new(workerConfig.Name, workerConfig, GetScriptable(toolSet));
|
|
||||||
workerCollection.Workers.Add(worker);
|
|
||||||
foreach (CallConfig callConfig in workerConfig.Calls)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("Initializing call of type: {Type}", callConfig.Type);
|
|
||||||
|
|
||||||
switch (callConfig.Type)
|
|
||||||
{
|
|
||||||
case "interval":
|
|
||||||
if (callConfig.Interval is null)
|
|
||||||
{
|
|
||||||
_logger.LogError("Interval not set for a Call in Worker \"{Name}\"", workerConfig.Name);
|
|
||||||
throw new IndexerConfigurationException($"Interval not set for a Call in Worker \"{workerConfig.Name}\"");
|
|
||||||
}
|
|
||||||
var timer = new System.Timers.Timer((double)callConfig.Interval);
|
|
||||||
timer.Elapsed += (sender, e) =>
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
worker.Scriptable.Update(new IntervalCallbackInfos() { sender = sender, e = e });
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError("Exception occurred in a Call of Worker \"{name}\": \"{ex}\"", worker.Name, ex.Message);
|
|
||||||
httpContextAccessor.HttpContext.RaiseError(ex);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
timer.AutoReset = true;
|
|
||||||
timer.Enabled = true;
|
|
||||||
IntervalCall call = new(timer, worker.Scriptable, _logger);
|
|
||||||
worker.Calls.Add(call);
|
|
||||||
break;
|
|
||||||
case "schedule": // TODO implement scheduled tasks using Quartz
|
|
||||||
throw new NotImplementedException("schedule not implemented yet");
|
|
||||||
case "fileupdate":
|
|
||||||
if (callConfig.Path is null)
|
|
||||||
{
|
|
||||||
_logger.LogError("Path not set for a Call in Worker \"{Name}\"", workerConfig.Name);
|
|
||||||
throw new IndexerConfigurationException($"Path not set for a Call in Worker \"{workerConfig.Name}\"");
|
|
||||||
}
|
|
||||||
throw new NotImplementedException("fileupdate not implemented yet");
|
|
||||||
//break;
|
|
||||||
default:
|
|
||||||
throw new IndexerConfigurationException($"Unknown Type specified for a Call in Worker \"{workerConfig.Name}\"");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_logger.LogCritical("Unable to load section \"Worker\"");
|
|
||||||
throw new IndexerConfigurationException("Unable to load section \"Worker\"");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IScriptable GetScriptable(ScriptToolSet toolSet)
|
|
||||||
{
|
|
||||||
string fileName = toolSet.filePath;
|
|
||||||
foreach (Type type in workerCollection.types)
|
|
||||||
{
|
|
||||||
IScriptable? instance = (IScriptable?)Activator.CreateInstance(type, [toolSet, _logger]);
|
|
||||||
if (instance is not null && instance.IsScript(fileName))
|
|
||||||
{
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_logger.LogError("Unable to determine the script's language: \"{fileName}\"", fileName);
|
|
||||||
|
|
||||||
throw new UnknownScriptLanguageException(fileName);
|
|
||||||
}
|
|
||||||
public Task StartAsync(CancellationToken cancellationToken)
|
public Task StartAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
/*foreach (Worker worker in workerCollection.Workers)
|
/*foreach (Worker worker in workerCollection.Workers)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
{ "Name": "File", "Args": { "path": "logs/log.txt", "rollingInterval": "Day", "retainedFileCountLimit": 7 } }
|
{ "Name": "File", "Args": { "path": "logs/log.txt", "rollingInterval": "Day", "retainedFileCountLimit": 7 } }
|
||||||
],
|
],
|
||||||
"Properties": {
|
"Properties": {
|
||||||
"Application": "Indexer"
|
"Application": "Embeddingsearch.Indexer"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"EmbeddingsearchIndexer": {
|
"EmbeddingsearchIndexer": {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ using Newtonsoft.Json;
|
|||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using Server.Exceptions;
|
using Server.Exceptions;
|
||||||
|
|
||||||
namespace server;
|
namespace Server;
|
||||||
|
|
||||||
public class AIProvider
|
public class AIProvider
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Nodes;
|
using System.Text.Json.Nodes;
|
||||||
using Server.Models;
|
using Shared.Models;
|
||||||
|
using Server.Helper;
|
||||||
namespace Server.Controllers;
|
namespace Server.Controllers;
|
||||||
|
|
||||||
[ApiController]
|
[ApiController]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using ElmahCore;
|
using ElmahCore;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Server.Models;
|
using Shared.Models;
|
||||||
|
|
||||||
namespace Server.Controllers;
|
namespace Server.Controllers;
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ using System.Threading.Tasks;
|
|||||||
using Microsoft.Extensions.AI;
|
using Microsoft.Extensions.AI;
|
||||||
using OllamaSharp;
|
using OllamaSharp;
|
||||||
using OllamaSharp.Models;
|
using OllamaSharp.Models;
|
||||||
using server;
|
|
||||||
|
|
||||||
namespace Server;
|
namespace Server;
|
||||||
|
|
||||||
|
|||||||
@@ -2,11 +2,9 @@ using System.Collections.Concurrent;
|
|||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using MySql.Data.MySqlClient;
|
using Shared.Models;
|
||||||
using OllamaSharp;
|
|
||||||
using server;
|
|
||||||
|
|
||||||
namespace Server;
|
namespace Server.Helper;
|
||||||
|
|
||||||
public static class SearchdomainHelper
|
public static class SearchdomainHelper
|
||||||
{
|
{
|
||||||
@@ -85,7 +83,7 @@ public static class SearchdomainHelper
|
|||||||
int? preexistingEntityID = DatabaseHelper.GetEntityID(helper, jsonEntity.Name, jsonEntity.Searchdomain);
|
int? preexistingEntityID = DatabaseHelper.GetEntityID(helper, jsonEntity.Name, jsonEntity.Searchdomain);
|
||||||
if (preexistingEntityID is not null)
|
if (preexistingEntityID is not null)
|
||||||
{
|
{
|
||||||
lock (helper.connection)
|
lock (helper.connection) // TODO change this to helper and do A/B tests (i.e. before/after)
|
||||||
{
|
{
|
||||||
Dictionary<string, dynamic> parameters = new()
|
Dictionary<string, dynamic> parameters = new()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using ElmahCore;
|
using ElmahCore;
|
||||||
using ElmahCore.Mvc;
|
using ElmahCore.Mvc;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
using server;
|
|
||||||
using Server;
|
using Server;
|
||||||
using Server.HealthChecks;
|
using Server.HealthChecks;
|
||||||
|
|
||||||
@@ -72,7 +71,7 @@ if (IsDevelopment || useSwagger)
|
|||||||
}
|
}
|
||||||
if (UseMiddleware == true && !IsDevelopment)
|
if (UseMiddleware == true && !IsDevelopment)
|
||||||
{
|
{
|
||||||
app.UseMiddleware<ApiKeyMiddleware>();
|
app.UseMiddleware<Shared.ApiKeyMiddleware>();
|
||||||
}
|
}
|
||||||
|
|
||||||
app.UseAuthorization();
|
app.UseAuthorization();
|
||||||
|
|||||||
@@ -17,11 +17,10 @@ using Mysqlx.Resultset;
|
|||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Numerics.Tensors;
|
using System.Numerics.Tensors;
|
||||||
using Server;
|
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using server;
|
using Server.Helper;
|
||||||
|
|
||||||
namespace Server;
|
namespace Server;
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ using OllamaSharp;
|
|||||||
using Microsoft.IdentityModel.Tokens;
|
using Microsoft.IdentityModel.Tokens;
|
||||||
using Server.Exceptions;
|
using Server.Exceptions;
|
||||||
using Server.Migrations;
|
using Server.Migrations;
|
||||||
using server;
|
|
||||||
|
|
||||||
namespace Server;
|
namespace Server;
|
||||||
|
|
||||||
|
|||||||
@@ -22,4 +22,8 @@
|
|||||||
<PackageReference Include="System.Data.Sqlite" Version="1.0.119" />
|
<PackageReference Include="System.Data.Sqlite" Version="1.0.119" />
|
||||||
<PackageReference Include="System.Numerics.Tensors" Version="9.0.3" />
|
<PackageReference Include="System.Numerics.Tensors" Version="9.0.3" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Shared\Shared.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
{ "Name": "File", "Args": { "path": "logs/log.txt", "rollingInterval": "Day", "retainedFileCountLimit": 7 } }
|
{ "Name": "File", "Args": { "path": "logs/log.txt", "rollingInterval": "Day", "retainedFileCountLimit": 7 } }
|
||||||
],
|
],
|
||||||
"Properties": {
|
"Properties": {
|
||||||
"Application": "Indexer"
|
"Application": "Embeddingsearch.Server"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"EmbeddingsearchIndexer": {
|
"EmbeddingsearchIndexer": {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.Primitives;
|
using Microsoft.Extensions.Primitives;
|
||||||
|
|
||||||
namespace Server;
|
namespace Shared;
|
||||||
|
|
||||||
public class ApiKeyMiddleware
|
public class ApiKeyMiddleware
|
||||||
{
|
{
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Server.Models;
|
namespace Shared.Models;
|
||||||
|
|
||||||
|
|
||||||
public class EntityQueryResults
|
public class EntityQueryResults
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace Server;
|
namespace Shared.Models;
|
||||||
|
|
||||||
public class JSONEntity
|
public class JSONEntity
|
||||||
{
|
{
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Server.Models;
|
namespace Shared.Models;
|
||||||
|
|
||||||
public class SearchdomainListResults
|
public class SearchdomainListResults
|
||||||
{
|
{
|
||||||
11
src/Shared/Shared.csproj
Normal file
11
src/Shared/Shared.csproj
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="ElmahCore" Version="2.1.2" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
@@ -9,6 +9,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Indexer", "Indexer\Indexer.
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Client", "Client\Client.csproj", "{4232CA30-ABC0-4EB9-A796-5E217719DD88}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Client", "Client\Client.csproj", "{4232CA30-ABC0-4EB9-A796-5E217719DD88}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shared", "Shared\Shared.csproj", "{DD8D64EC-86E9-407E-ADC7-AC3F8F9E6A7F}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -30,5 +32,9 @@ Global
|
|||||||
{4232CA30-ABC0-4EB9-A796-5E217719DD88}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{4232CA30-ABC0-4EB9-A796-5E217719DD88}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{4232CA30-ABC0-4EB9-A796-5E217719DD88}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{4232CA30-ABC0-4EB9-A796-5E217719DD88}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{4232CA30-ABC0-4EB9-A796-5E217719DD88}.Release|Any CPU.Build.0 = Release|Any CPU
|
{4232CA30-ABC0-4EB9-A796-5E217719DD88}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{DD8D64EC-86E9-407E-ADC7-AC3F8F9E6A7F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{DD8D64EC-86E9-407E-ADC7-AC3F8F9E6A7F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{DD8D64EC-86E9-407E-ADC7-AC3F8F9E6A7F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{DD8D64EC-86E9-407E-ADC7-AC3F8F9E6A7F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|||||||
Reference in New Issue
Block a user