And one moment I use API and we have API-Key authentication.
public class AssessmentJobsService : DomainService, IAssessmentJobsService
{
#region Fields
private readonly IAssessmentDetailRepository _assessmentDetailRepository;
private readonly IMediaRepository _mediaRepository;
private readonly IBlobManager _blobManager;
private readonly IAssessmentRepository _assessmentRepository;
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="AssessmentJobsService" /> class.
/// </summary>
/// <param name="assessmentDetailRepository">The assessment repository.</param>
/// <param name="mediaRepository">The media repository.</param>
/// <param name="blobManager">The blob manager.</param>
public AssessmentJobsService(
IAssessmentDetailRepository assessmentDetailRepository,
IMediaRepository mediaRepository,
IBlobManager blobManager,
IAssessmentRepository assessmentRepository)
{
_assessmentDetailRepository = assessmentDetailRepository;
_mediaRepository = mediaRepository;
_blobManager = blobManager;
_assessmentRepository = assessmentRepository;
}
#endregion
/// <inheritdoc/>
public void SheduleAssessmentCleanup(long assessmentId)
{
BackgroundJob.Schedule(() => CleanUpAssessment(assessmentId), TimeSpan.FromSeconds(30));
}
public void SheduleEmptyAssessmentCleanup(long assessmentId)
{
BackgroundJob.Schedule(() => CleanUpEmptyAssessment(assessmentId), TimeSpan.FromHours(4));
}
/// <inheritdoc/>
public void SheduleMediaCleanup(long mediaId)
{
BackgroundJob.Schedule(() => CleanUpMedia(mediaId), TimeSpan.FromHours(4));
}
/// <inheritdoc/>
public async Task StartTrackingJob(long assessmentDetailId, bool isOneStepProcess)
{
// Create a Hangfire job to finish the job if not all methods are called within 5 minutes
var jobId = BackgroundJob.Schedule(() => CheckProcessVideoTracking(assessmentDetailId, isOneStepProcess), TimeSpan.FromMinutes(3));
var assessementDetails = await _assessmentDetailRepository.GetAsync(assessmentDetailId);
assessementDetails.JobId = jobId;
// Sets default status
assessementDetails.ProcessVideoTrackStatus = (int)ProcessVideoTrackingStatus.InProgress;
assessementDetails.ProcessVideoTrackStatusValue = ProcessVideoTrackingStatus.InProgress.ToString();
await _assessmentDetailRepository.UpdateAsync(assessementDetails, true);
}
/// <inheritdoc/>
//[AutomaticRetry(Attempts = 5, DelaysInSeconds = new[] { 300, 600, 900, 1800, 3600 })]
[AutomaticRetry(Attempts = 5, DelaysInSeconds = new[] { 60, 60, 60 })]
public async Task CheckProcessVideoTracking(long assessmentDetailId, bool isOneStepProcess)
{
var assessmentDetails = await _assessmentDetailRepository.GetAsync(assessmentDetailId)
?? throw new Exception($"Job failed. Assessment details were not found");
var status = (ProcessVideoTrackingStatus)assessmentDetails.ProcessVideoTrackStatus;
if ((isOneStepProcess && status == ProcessVideoTrackingStatus.ProcessData) ||
(!isOneStepProcess && status == (ProcessVideoTrackingStatus.ProcessData | ProcessVideoTrackingStatus.Report | ProcessVideoTrackingStatus.Overlay)))
{
return;
}
throw new Exception($"Job failed. Status {status}");
}
/// <inheritdoc/>
public async Task CleanUpMedia(long mediaId)
{
var mediaIsInUse = await _mediaRepository.CheckMediaWithAssessmentDetails(mediaId);
if (!mediaIsInUse)
{
var media = await _mediaRepository.FindAsync(mediaId);
if(media == null)
{
return;
}
await _mediaRepository.DeleteAsync(mediaId);
await _blobManager.DeleteBlob(media?.MediaUrl, media?.FileName);
}
}
/// <inheritdoc/>
public async Task CleanUpMediaMedBridge()
{
try
{
// Get details from assessment where externalAssessmentId != null
var mediaIds = await _assessmentDetailRepository.GetListMediaIdAndCleanDetailsMedbridgeAsync();
if (mediaIds != null)
{
var mediaQueryable = await _mediaRepository.GetQueryableAsync();
var medias = mediaQueryable.Where(m => mediaIds.Contains(m.Id)).ToList();
if (medias == null)
{
return;
}
await _mediaRepository.DeleteManyAsync(mediaIds, true);
foreach (var media in medias)
{
await _blobManager.DeleteBlob(media?.MediaUrl, media?.FileName);
}
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
/// <inheritdoc/>
public async Task CleanUpAssessment(long assessmentId)
{
var details = await _assessmentDetailRepository.GetListAsync(x => x.AssessmentId == assessmentId);
var mediaIds = details.Select(x => x.MediaId).ToList();
await _assessmentDetailRepository.DeleteManyAsync(details);
var medias = await _mediaRepository.GetListAsync(x => mediaIds.Contains(x.Id));
await _mediaRepository.DeleteManyAsync(medias);
foreach (var media in medias)
{
await _blobManager.DeleteBlob(media.MediaUrl, media.FileName);
}
}
public async Task CleanUpEmptyAssessment(long assessmentId)
{
if (!await _assessmentDetailRepository.CheckAssessmentWithAssessmentDetails(assessmentId))
{
var assessment = await _assessmentRepository.FindAsync(assessmentId);
if (assessment != null)
{
await _assessmentRepository.DeleteAsync(assessment);
}
}
}
}
and in HttpHostModule
private void ConfigureHangfire(ServiceConfigurationContext context, IConfiguration configuration)
{
context.Services.AddHangfire(config =>
{
GlobalConfiguration.Configuration.UsePostgreSqlStorage(configuration.GetConnectionString("Default"));
});
}
Is it enough for stack trace. Or we need to add this code and we will have more information?
13:40:27 INF] Executed endpoint 'Health checks' [13:40:27 INF] Event dropped by processor CustomSentryProcessor [13:40:27 INF] Request finished HTTP/1.1 GET http://10.244.6.75:80/health-status - - - 200 - application/json 4.1482ms [13:40:27 INF] Executed endpoint 'Health checks' [13:40:27 INF] Event dropped by processor CustomSentryProcessor [13:40:27 INF] Request finished HTTP/1.1 GET http://10.244.6.75:80/health-status - - - 200 - application/json 3.0396ms [13:40:27 ERR] ---------- RemoteServiceErrorInfo ---------- { "code": null, "message": "An internal error occurred during your request!", "details": null, "data": {}, "validationErrors": null }
[13:40:27 ERR] Undefined feature: risk
Volo.Abp.AbpException: Undefined feature: risk
at Volo.Abp.Features.FeatureDefinitionManager.GetAsync(String name)
at Volo.Abp.FeatureManagement.FeatureManager.GetOrNullInternalAsync(String name, String providerName, String providerKey, Boolean fallback)
at Volo.Abp.FeatureManagement.FeatureManager.GetOrNullWithProviderAsync(String name, String providerName, String providerKey, Boolean fallback)
at Volo.Abp.FeatureManagement.FeatureAppService.GetAsync(String providerName, String providerKey)
at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo)
at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue1.ProceedAsync() at Volo.Abp.Authorization.AuthorizationInterceptor.InterceptAsync(IAbpMethodInvocation invocation) at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter
1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func3 proceed) at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo) at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue
1.ProceedAsync()
at Volo.Abp.GlobalFeatures.GlobalFeatureInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func
3 proceed)
at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo)
at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue1.ProceedAsync() at Volo.Abp.Auditing.AuditingInterceptor.ProceedByLoggingAsync(IAbpMethodInvocation invocation, AbpAuditingOptions options, IAuditingHelper auditingHelper, IAuditLogScope auditLogScope) at Volo.Abp.Auditing.AuditingInterceptor.InterceptAsync(IAbpMethodInvocation invocation) at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter
1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func3 proceed) at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo) at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue
1.ProceedAsync()
at Volo.Abp.Validation.ValidationInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func
3 proceed)
at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo)
at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue1.ProceedAsync() at Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation) at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter
1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func3 proceed) at lambda_method3149(Closure, Object) at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask
1 actionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|26_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
[13:40:27 INF] Executing ObjectResult, writing value of type 'Volo.Abp.Http.RemoteServiceErrorResponse'.
[13:40:27 INF] Executed action Volo.Abp.FeatureManagement.FeaturesController.GetAsync (Volo.Abp.FeatureManagement.HttpApi) in 251.6018ms
[13:40:27 INF] Executed endpoint 'Volo.Abp.FeatureManagement.FeaturesController.GetAsync (Volo.Abp.FeatureManagement.HttpApi)'
[13:40:27 INF] Envelope queued up: 'd86a37c4329848568ba1fa8efc199355'
[13:40:27 INF] Request finished HTTP/1.1 GET http://api-dev.3motionai.com/api/feature-management/features?providerName=T - - - 500 - application/json;+charset=utf-8 274.8530ms
[13:40:27 INF] Envelope 'd86a37c4329848568ba1fa8efc199355' successfully sent.
[13:40:34 INF] Start processing HTTP request GET http://3m-backend-api-webhost-dev2-55cd8c9cd4-qkxzs/health-status
[13:40:34 INF] Sending HTTP request GET http://3m-backend-api-webhost-dev2-55cd8c9cd4-qkxzs/health-status
[13:40:34 INF] Request starting HTTP/1.1 GET http://3m-backend-api-webhost-dev2-55cd8c9cd4-qkxzs/health-status - -
[13:40:34 INF] Started transaction with span ID 'f1cd941c0dff465c' and trace ID '86a44028d26f496a91756b61b7026d02'.
[13:40:34 INF] Executing endpoint 'Health checks'
[13:40:34 INF] Executed endpoint 'Health checks'
[13:40:34 INF] Received HTTP response headers after 3.8044ms - 200
[13:40:34 INF] End processing HTTP request after 3.9389ms - 200
[13:40:34 INF] Event dropped by processor CustomSentryProcessor
[13:40:34 INF] Request finished HTTP/1.1 GET http://3m-backend-api-webhost-dev2-55cd8c9cd4-qkxzs/health-status - - - 200 - application/json 3.7909ms
[13:40:42 INF] Request starting HTTP/1.1 GET http://10.244.6.75:80/health-status - -
[13:40:42 INF] Request starting HTTP/1.1 GET http://10.244.6.75:80/health-status - -
[13:40:42 INF] Sentry trace header is null. Creating new Sentry Propagation Context.
[13:40:42 INF] Sentry trace header is null. Creating new Sentry Propagation Context.
[13:40:42 INF] Started transaction with span ID 'e3d7716683cd4290' and trace ID '46a9a0a8ae604a9fa92fa0bda97e34b8'.
[13:40:42 INF] Started transaction with span ID '57415cff88434c49' and trace ID '92d5b63d8cbe40d79d0872310c55d61e'.
[13:40:42 INF] Executing endpoint 'Health checks'
I can send You stackTrace
[13:39:47 INF] Request starting HTTP/1.1 GET http://api-dev.3motionai.com/api/app/assessment-types/movements - -
[13:39:47 INF] Sentry trace header is null. Creating new Sentry Propagation Context.
[13:39:47 INF] Started transaction with span ID '3407bb84c47c4acd' and trace ID '18271856ff714539a8b97737c3b2da46'.
[13:39:47 INF] Executing endpoint '_3M.AssessmentTypes.AssessmentTypesAppService.GetMovements (_3M.Application)'
[13:39:47 INF] Route matched with {action = "GetMovements", controller = "AssessmentTypes", area = "", page = ""}. Executing controller action with signature System.Threading.Tasks.Task1[System.Collections.Generic.List
1[_3M.AssessmentTypes.AssessmentTypeDto]] GetMovements() on controller _3M.AssessmentTypes.AssessmentTypesAppService (_3M.Application).
[13:39:48 ERR] ---------- RemoteServiceErrorInfo ----------
{
"code": null,
"message": "An internal error occurred during your request!",
"details": null,
"data": {},
"validationErrors": null
}
[13:39:48 ERR] Undefined feature: Sports
Volo.Abp.AbpException: Undefined feature: Sports
at Volo.Abp.Features.FeatureDefinitionManager.GetAsync(String name)
at Volo.Abp.Features.FeatureChecker.GetOrNullAsync(String name)
at Volo.Abp.Features.FeatureCheckerBase.IsEnabledAsync(String name)
at _3M.AssessmentTypes.AssessmentTypesAppService.GetListAssessmentTypesWithCheckedFeatures(List1 asmtypes) in /azp/_work/1/s/src/_3M.Application/AssessmentTypes/AssessmentTypesAppService.cs:line 80 at _3M.AssessmentTypes.AssessmentTypesAppService.GetMovements() in /azp/_work/1/s/src/_3M.Application/AssessmentTypes/AssessmentTypesAppService.cs:line 58 at lambda_method2576(Closure, Object) at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask
1 actionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|26_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
[13:39:48 INF] Executing ObjectResult, writing value of type 'Volo.Abp.Http.RemoteServiceErrorResponse'.
[13:39:48 INF] Executed action _3M.AssessmentTypes.AssessmentTypesAppService.GetMovements (_3M.Application) in 450.3411ms
[13:39:48 INF] Executed endpoint '_3M.AssessmentTypes.AssessmentTypesAppService.GetMovements (_3M.Application)'
[13:39:48 INF] Enve
This part x => await _featureChecker.IsEnabledAsync(x.Code) will not work it needs WhenAll but this works with repository and I had some problems with WhenAll and asynchronous calls to db.
My public class AssessmentFeatureDefinitionProvider : FeatureDefinitionProvider { private readonly IAssessmentTypeRepository _assessmentTypeRepository; private const string FeatureNameForSingleMovements = "Tasks"; private const string FeatureNameForProtocols = "Protocols";
public AssessmentFeatureDefinitionProvider(IAssessmentTypeRepository assessmentTypeRepository)
{
_assessmentTypeRepository = assessmentTypeRepository;
}
public override async void Define(IFeatureDefinitionContext context)
{
var tasksGroup = context.AddGroup(FeatureNameForSingleMovements);
var protocolGroup = context.AddGroup(FeatureNameForProtocols);
await DefineFeaturesForAssessmentType(tasksGroup, AssessmentTypeNames.Movement);
await DefineFeaturesForAssessmentType(protocolGroup, AssessmentTypeNames.Protocol);
}
private async Task DefineFeaturesForAssessmentType(FeatureGroupDefinition contextGroup, AssessmentTypeNames assessmentTypeName)
{
var assessmentTypes = await _assessmentTypeRepository.GetAssessmentTypes(assessmentTypeName);
foreach (var assessmentType in assessmentTypes)
{
var feature = contextGroup.AddFeature(assessmentType.Code, defaultValue: "true", displayName: L($"DisplayName:AssessmentType.{assessmentType.Code}"));
var movements = assessmentType.AssessmentTypeMovements.Select(x => x.AssessmentMovement).ToList();
foreach (var movement in movements)
{
feature.CreateChild(movement.Code, defaultValue: "true", displayName: L($"DisplayName:AssessmentMovement.{movement.Code}"));
}
}
}
private static LocalizableString L(string name)
{
return LocalizableString.Create<_3MFeatureResource>(name);
}
}
And is it ok that I have FeatureDefinitionProvider in the domain project
I will try. But what about get features it fell down two. And can You answer me can feature has a name with white spaces?
this what method get features return and next time it will be 200