IMessageService messages not getting handled

We’re publishing messages to RabbitMQ but they hang in the outq instead of being processed by our handler.

.net core app running ServiceStack 6.*

Can someone cast their eyes over this and tell me where I’m going wrong?

Configure.Mq.cs

public class ConfigureMq : IHostingStartup
{
    public void Configure(IWebHostBuilder builder) => builder
        .ConfigureServices((context, services) =>
        {
            services.AddSingleton<IMessageService>(c =>
                new RabbitMqServer(context.Configuration.GetConnectionString("RabbitMq") ?? "localhost:5672")
                {
                    // DisablePublishingToOutq = true
                }
            );
        })
        .ConfigureAppHost(afterAppHostInit: appHost =>
        {
            var mqServer = appHost.Resolve<IMessageService>();

            mqServer.RegisterHandler<UpdateSearchIndexMappingForActivityType>(appHost.ExecuteMessage);

            mqServer.RegisterHandler<UpdateSearchIndexMappingResponse>(appHost.ExecuteMessage);

            mqServer.Start();
        });
}

MessageDTOs

[Route("/search/indexing/activityType", "POST")]
public class UpdateSearchIndexMappingForActivityType : IHasBearerToken, IPost, IReturn<UpdateSearchIndexMappingResponse>
{
    public int Id { get; set; }
    public int SystemId { get; set; }
    public int From { get; set; }
    public int To { get; set; }

    public string BearerToken { get; set; }
    public ResponseStatus ResponseStatus { get; set; }
}

public class UpdateSearchIndexMappingResponse
{
    public ResponseStatus ResponseStatus { get; set; }
}

MessageHandler Service

public class LookupSearchIndexingServices : Service, IPost<UpdateSearchIndexMappingForActivityType>
{
    public static ILog Log = LogManager.GetLogger(typeof(LookupSearchIndexingServices));

    [Authenticate]
    public object Post(UpdateSearchIndexMappingForActivityType request)
    {
        if (Log.IsDebugEnabled)
            Log.Debug($"In LookupSearchIndexingServices: UpdateSearchIndexMappingForActivityType({request.Id})");

        return new UpdateSearchIndexMappingResponse();
    }

    public void Post(UpdateSearchIndexMappingResponse request)
    {
        Log.Info("Search Index has successfully remapped");
    }
}

Like I say, the message then just collect in the outq…
image

Here’s the Message Workflow, the .outq isn’t a queue that processes messages, it’s a topic other RabbitMQ clients can subscribe to, to get notified when messages are completed, i.e. it’s not part of the message workflow.

Yeah I’ve read the workflow and was expecting the UpdateSearchIndexMappingResponse.Inq to have message in it.

Breakpoints in the handlers never get hit and the Log.Debug / Log.Info lines never execute.

Ok, it looks like you don’t want them to be published to the .outq but want them published to the UpdateSearchIndexMappingResponse.inq so they are processed. Not sure why it’s not being published to the response .inq, perhaps the new profiling support we’ve added in v6.1.1 on MyGet will provide some insight at /admin-ui/profiling otherwise I’d recommend debugging the MessageHandler class to find out why it’s not being published to the Response.inq:

I’ve found that removing the [Authenticate] attribute from the MessageHandler fixes the problem but the BearerToken is being set correctly before the message is published and I can see the value on the messages sat in the Outq

    try
    {
        message.BearerToken = Request.GetSessionId();
        PublishMessage(message);
    }

Can’t tell from here without a local repro, does it return an Authenticated Session inside the service impl?

var session = base.SessionAs<AuthUserSession>();

No, it returns an unauthenticated session…

Wait, this needs to be a Bearer Token Auth like a JWT or an API key, not a session id.

message.BearerToken = Request.GetSessionId();

I thought that but copied this from the docs : https://docs.servicestack.net/messaging#embedding-auth-info-in-mq-request-dto

How do I get the bearerToken before publishing?

yeah that’s wrong, the session id goes in IHasSessionId, JWT/API Key Bearer tokens is populated in IHasBearerToken, will update.

1 Like

Switching to IHasSessionId and Setting message.SessionId = Request.GetSessionId() doesn’t work.

Have tried using Request.GetBearerToken() with no joy

I guess there’s something else I’m missing

Are you authenticating with JWT? Can’t authenticate otherwise.

Does the same SessionId from the authenticated user populating the MQ Request DTO make it to the Service? Does Request.GetSessionId() in MQ return the same Id?

If it’s returning the same id, can you retrieve the session manually from cache client with:

var sessionKey = SessionFeature.GetSessionKey(sessionId);
Request.GetCacheClient().Get<IAuthSession>(sessionKey)

Yes, authenticating with jwt and using JWT cookies.

The SessionId’s match from Publish session to MessageHandler session but I can’t get the IAuthSession…

(note the local variable values top-left)

Does it match the Authenticated Users Session Id which was used to populate the SessionId?, i.e. who published the message?

Nope…

So that’s the issue, the same SessionId needs to be sent with the Request DTO.

OK thanks, so why is Request.GetSession() returning a different id?

If you’re using JWT, you’re not using server sessions, so you should be populating the Bearer Token instead:

message.BearerToken = Request.GetJwtToken();
1 Like

Ah, thanks - was looking for the method to get the token.

1 Like

I guess it’s working now…

Now to find a way to provide a secure ssl cert for use during dev…