Hangfire Recurring Job not firing OnPerformed method from JobFilter - hangfire

I'm developing a custom JobFilter for my application but It seems that the method from a recurring job is not hitting the OnPerformed method (IServerFilter). When I create a background job manually this works just fine. Does someone knows how to monitor if a job (all types) is complete?
public class CustomJobAttribute : JobFilterAttribute, IClientFilter, IServerFilter
{
public void OnCreating(CreatingContext filterContext)
{
}
public void OnCreated(CreatedContext filterContext)
{
}
public void OnPerforming(PerformingContext filterContext)
{
}
public void OnPerformed(PerformedContext filterContext)
{
}
}

Related

How do I execute something on Test Suite Setup/Teardown?

is there such thing as a Test Suite Setup/Teardown in Karate API?
Basically, I want to do something before everything starts and after everything is finished.
If you are using Java / JUnit as the entry point this is quite simple, just add lines of code before / after.
Also refer this answer: https://stackoverflow.com/a/59080128/143475 - the ExecutionHook (which still does require you to write Java code) has beforeAll() and afterAll() callbacks.
In practice it is probably simplest to use a callSingle() in your karate-config.js and do a pre-cleanup.
Fixed via below code.
<...truncated imports...>
#KarateOptions()
public class TestRunner {
#Test
public void testParallel() {
Results results = Runner.path("classpath:THISCLASS").hook(new ExecHook()).parallel(1);
generateReport(results.getReportDir());
assertTrue(results.getErrorMessages(), results.getFailCount() == 0);
}
}
class ExecHook implements ExecutionHook {
#Override
public void afterAll(Results results) {
System.out.println("DO SOMETHING HERE");
}
#Override
public boolean beforeScenario(Scenario scenario, ScenarioContext context) {
return true;
}
#Override
public void afterScenario(ScenarioResult result, ScenarioContext context) {
}
#Override
public boolean beforeFeature(Feature feature, ExecutionContext context) {
return true;
}
#Override
public void afterFeature(FeatureResult result, ExecutionContext context) {
}
#Override
public void beforeAll(Results results) {
}
#Override
public boolean beforeStep(Step step, ScenarioContext context) {
return true;
}
#Override
public void afterStep(StepResult result, ScenarioContext context) {
}
#Override
public String getPerfEventName(HttpRequestBuilder req, ScenarioContext context) {
return null;
}
#Override
public void reportPerfEvent(PerfEvent event) {
}
}
Just one question, is there a way to to take off the #Overrides for the methods I'm not using?

inject Database Context into Custom Attribute .NET Core

I'm creating ASP.NET Core 3.1 app, using SPA for front end. So I decided to create custom Authentication & Authorization. So I created custom attributes to give out and verify JWTs.
Lets say it looks like this:
[AttributeUsage(AttributeTargets.Method)]
public class AuthLoginAttribute : Attribute, IAuthorizationFilter
{
public async void OnAuthorization(AuthorizationFilterContext filterContext)
{
//Checking Headers..
using (var EF = new DatabaseContext)
{
user = EF.User.Where(p => (p.Email == username)).FirstOrDefault();
}
filterContext.HttpContext.Response.Headers.Add(
"AccessToken",
AccessToken.CreateAccessToken(user));
}
}
Everything was Okay, but my DatabaseContext, looked like this:
public class DatabaseContext : DbContext
{
public DbSet<User> User { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseMySQL("ConnectionString");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//....
}
}
I wanted to take Connection string from Appsettings.json and maybe use Dependency injection. I
Changed Startup.cs to look like this:
//...
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddDbContext<DatabaseContext>(
options => options.UseMySQL(Configuration["ConnectionStrings:ConnectionString"]));
services.Add(new ServiceDescriptor(
typeof(HMACSHA256_Algo), new HMACSHA256_Algo(Configuration)));
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/build";
});
}
//...
Changed Database Context class to this:
public class DatabaseContext : DbContext
{
public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options) { }
public DbSet<User> User { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
///..
}
}
In Controllers I injected DB context and everything works. It looks like this:
[ApiController]
[Route("API")]
public class APIController : ControllerBase
{
private DatabaseContext EF;
public WeatherForecastController(DatabaseContext ef)
{
EF = ef;
}
[HttpGet]
[Route("/API/GetSomething")]
public async Task<IEnumerable<Something>> GetSomething()
{
using(EF){
//.. this works
}
}
}
But my custom Attribute doesn't work no more. I can't declare new Database context, because it needs DatabaseContextOptions<DatabaseContext> object to declare, so how do I inject DBContext to Attribute as I did to Controller?
This doesn't work:
public class AuthLoginAttribute : Attribute, IAuthorizationFilter
{
private DatabaseContext EF;
public AuthLoginAttribute(DatabaseContext ef)
{
EF = ef;
}
public async void OnAuthorization(AuthorizationFilterContext filterContext)
{
using(EF){
}
}
}
this works with controller, but with attribute complains about there not being constructor with 0 arguments.
What you can do is utilize the RequestServices:
[AttributeUsage(AttributeTargets.Method)]
public class AuthLoginAttribute : Attribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationFilterContext context)
{
var dbContext = context.HttpContext
.RequestServices
.GetService(typeof(DatabaseContext)) as DatabaseContext;
// your code
}
}
If you allow me to add two comments to your code:
Try not to use async void because in the event of an exception you will be very confused what is going on.
There is no need to wrap injected DbContext in a using statement like this using(EF) { .. }. You will dispose it early and this will lead to bugs later in the request. The DI container is managing the lifetime for you, trust it.

JUnit5 afterAll callback fires at the end of each test class and not after all tests

I have 15 JUnit5 classes with tests. When I run them all from maven, the afterAll() is executed 15 times which causes 15 notifications to a Slack Webhook. Is there anything else I need to only send one notification?
public class TestResultsExtensionForJUnit5 implements TestWatcher, AfterAllCallback {
#Override
public void afterAll(ExtensionContext extensionContext) throws Exception {
sendResultToWebHook();
}
#Override
public void testDisabled(ExtensionContext context, Optional<String> reason) {
totalTestDisabled = totalTestDisabled + 1;
}
#Override
public void testSuccessful(ExtensionContext context) {
totalTestPassed = totalTestPassed + 1;
}
#Override
public void testAborted(ExtensionContext context, Throwable cause) {
totalTestAborted = totalTestAborted + 1;
}
#Override
public void testFailed(ExtensionContext context, Throwable cause) {
totalTestFailed = totalTestFailed + 1;
}
}
#ExtendWith(TestResultsExtensionForJUnit5.class)
public class Random1Test {}
The best way is to implement and install a TestExecutionListener from the JUnit Platform, as it is described in the User Guide at https://junit.org/junit5/docs/current/user-guide/#launcher-api-listeners-custom -- override the default testPlanExecutionFinished​(TestPlan testPlan) method with your notifying call. Here, all tests from all engines are finished.

PRISM Xamarin - Working with tabbed pages (IActiveAware)

I have tab pages implementing different views, but I cannot initialize each of the tabs when navigating.
<TabbedPage.Children>
<tabPages:Page1/>
<tabPages:Page2/>
<tabPages:Page3/>
</TabbedPage.Children>
So what I did was to use IActiveAware as prism documentation suggested to know which tab page is currently active. So I have this class:
public abstract class TabbedChildViewModelBase : BaseViewModel, IActiveAware, INavigationAware, IDestructible
protected bool IsInitalized { get; set; }
private bool _IsActive;
public bool IsActive
{
get
{
return _IsActive;
}
set
{
SetProperty(ref _IsActive, value, RaiseIsActiveChanged);
}
}
public event EventHandler IsActiveChanged;
public virtual void OnNavigatingTo(NavigationParameters parameters)
{
}
protected virtual void RaiseIsActiveChanged()
{
IsActiveChanged?.Invoke(this, EventArgs.Empty);
}
public virtual void Destroy()
{
}
}
So each child view models inherits the child view model base:
public class Page1 : TabbedChildViewModelBase
{
public CurrentSeaServiceViewModel()
{
IsActiveChanged += HandleIsActiveTrue;
IsActiveChanged += HandleIsActiveFalse;
}
private void HandleIsActiveTrue(object sender, EventArgs args)
{
if (IsActive == false)
{
TestLabelOnly = "Test";
}
// Handle Logic Here
}
private void HandleIsActiveFalse(object sender, EventArgs args)
{
if (IsActive == true) return;
// Handle Logic Here
}
public override void Destroy()
{
IsActiveChanged -= HandleIsActiveTrue;
IsActiveChanged -= HandleIsActiveFalse;
}
}
The problem is, the child vm isn't initializing. Is there something needed in order to implement IActiveAware properly nor launching the IsActive property
I still used IActiveAware unfortunately, to make the childtabbedviewmodel work you need to bind the page to its own view model.
So here's what I did:
<TabbedPage.Children>
<views:ChildPage1>
<views:ChildPage1.BindingContext>
<viewModels:ChildPage1ViewModel/>
</views:ChildPage1.BindingContext>
</views:ChildPage1>
<views:ChildPage2>
<views:ChildPage2.BindingContext>
<viewModels:ChildPage2ViewModel/>
</views:ChildPage2.BindingContext>
</views:ChildPage2>
</TabbedPage.Children>
I used the property BindingContext of my views and
using IActiveAware I would also know what tab is currently active. Hope anyone helps this who finds trouble binding the child pages of a tab.

How can I inject multiple repositories in a NServicebus message handler?

I use the following:
public interface IRepository<T>
{
void Add(T entity);
}
public class Repository<T>
{
private readonly ISession session;
public Repository(ISession session)
{
this.session = session;
}
public void Add(T entity)
{
session.Save(entity);
}
}
public class SomeHandler : IHandleMessages<SomeMessage>
{
private readonly IRepository<EntityA> aRepository;
private readonly IRepository<EntityB> bRepository;
public SomeHandler(IRepository<EntityA> aRepository, IRepository<EntityB> bRepository)
{
this.aRepository = aRepository;
this.bRepository = bRepository;
}
public void Handle(SomeMessage message)
{
aRepository.Add(new A(message.Property);
bRepository.Add(new B(message.Property);
}
}
public class MessageEndPoint : IConfigureThisEndpoint, AsA_Server, IWantCustomInitialization
{
public void Init()
{
ObjectFactory.Configure(config =>
{
config.For<ISession>()
.CacheBy(InstanceScope.ThreadLocal)
.TheDefault.Is.ConstructedBy(ctx => ctx.GetInstance<ISessionFactory>().OpenSession());
config.ForRequestedType(typeof(IRepository<>))
.TheDefaultIsConcreteType(typeof(Repository<>));
}
}
My problem with the threadlocal storage is, is that the same session is used during the whole application thread. I discovered this when I saw the first level cache wasn't cleared. What I want is using a new session instance, before each call to IHandleMessages<>.Handle.
How can I do this with structuremap? Do I have to create a message module?
You're right in that the same session is used for all requests to the same thread. This is because NSB doesn't create new threads for each request. The workaround is to add a custom cache mode and have it cleared when message handling is complete.
1.Extend the thread storage lifecycle and hook it up a a message module
public class NServiceBusThreadLocalStorageLifestyle : ThreadLocalStorageLifecycle, IMessageModule
{
public void HandleBeginMessage(){}
public void HandleEndMessage()
{
EjectAll();
}
public void HandleError(){}
}
2.Configure your structuremap as follows:
For<<ISession>>
.LifecycleIs(new NServiceBusThreadLocalStorageLifestyle())
...
Hope this helps!