Azure Service Bus - SubscriptionClient.AcceptMessageSession() vs. SubscriptionClient.BeginAcceptMessageSession() - azure

In the Azure Service Bus namespace, there is a SubscriptionClient type, with a method to initiate a MessageSession in this manner:-
MessageSession session = subscriptionClient.AcceptMessageSession(...);
This is the synchronous version, and it returns a MessageSession. The library also provides an asynchronous version, BeginAcceptMessageSession(). This one is tripping me up, because it invokes a callback, passing in an IAsyncResult and whatever state object you wish to pass. In my case, I am passing the SubscriptionClient instance, so that I can invoke EndAcceptMessageSession() on the SubscriptionClient. BeginAcceptMessageSession() has a return type of void.
How can I access the MessageSession that is accepted via BeginAcceptMessageSession()? All I get back in the callback's result parameter is my SubscriptionClient instance, which I need in order to terminate the BeginAcceptMessageSession() via EndAcceptMessageSession().
The MessageSession reference is nowhere to be found. The documentation is no help in this regard. Searching on Google only reveals a scant 3 pages of search results, most of which is simply the online description of the method itself from MSDN. I looked in AsyncManager.Parameters and it is also empty.
Does anyone know how BeginAcceptMessageSession() is supposed to be invoked so that I can get a reference to the MessageSession thus created?

You should invoke the method like this:
Call the begin method with a method that accepts the IAsyncResult and the SubscriptionClient.
In the other method (AcceptDone in this case), call EndAcceptMessageSession with the IAsyncResult to get the MessageSession
What you see here is an standard implementation of the Asynchronous Programming Model.
private static void Do()
{
SubscriptionClient client = ...
client.BeginAcceptMessageSession(AcceptDone, client);
}
public static void AcceptDone(IAsyncResult result)
{
var subscriptionClient = result.AsyncState as SubscriptionClient;
if (subscriptionClient == null)
{
Console.WriteLine("Async Subscriber got no data.");
return;
}
var session = subscriptionClient.EndAcceptMessageSession(result);
...
subscriptionClient.Close();
}

Related

external service result mutates state of aggregate

My problem is that I don't know how to handle external calls that mutates the state but also needs validation before executing them
Here is my command handler
public async Task<IAggregateRoot> ExecuteAsync(Command command)
{
var sandbox = await _aggregateStore.GetByIdAsync<Sandbox>(command.SandboxId);
var response = await _azureService.CreateRedisInstance(sandbox.Id);
if (response.IsSuccess)
{
sandbox.CreateRedisDetails(response);
return sandbox;
}
sandbox.FailSetup(response.Errors.Select(e => e.Message));
return sandbox;
}
The problem here is that the sandbox aggregate needs to be in correct state before calling external service and I cannot satisfy both. My only idea here is to create separate method CanCreateRedisInstance that checks if aggregate state is valid and only then calls external service. What I don't like is that I introduce validation methods
public async Task<IAggregateRoot> ExecuteAsync(Command command)
{
var sandbox = await _aggregateStore.GetByIdAsync<Sandbox>(command.SandboxId);
if(!sandbox.CanCreateRedisInstance())
{
throw new ValidationExcetpion("something");
}
var response = await _azureService.CreateRedisInstance(sandbox.Id);
if (response.IsSuccess)
{
sandbox.CreateRedisDetails(response);
return sandbox;
}
sandbox.FailSetup(response.Errors.Select(e => e.Message));
return sandbox;
}
The other approach I thought of is to make whole process more cqrs-ish.
public async Task<IAggregateRoot> ExecuteAsync(Command command)
{
var sandbox = await _aggregateStore.GetByIdAsync<Sandbox>(command.SandboxId);
sandbox.ScheduleRedisInstanceCreation();
}
public void ScheduleRedisInstanceCreation()
{
if(RedisInstanceDetails != null)
{
throw new ValidationException("something")
}
RedisInstanceDetails = RedisInstanceDetails.Scheduled(some arguments);
AddEvent(new RedisInstanceCreationScheduled(some arguments));
}
The RedisInstanceCreationScheduled event is sent to queue and picked by event handler
which will call external service and based on result will create other events
public async Task ExecuteAsync(RedisInstanceCreationScheduled event)
{
var sandbox = await _aggregateStore.GetByIdAsync<Sandbox>(command.SandboxId);
var response = await _azureService.CreateRedisInstance(sandbox.Id);
if (response.IsSuccess)
{
sandbox.CreateRedisDetails(response);
return sandbox;
}
sandbox.FailSetup(response.Errors.Select(e => e.Message));
_aggregateStore.Save(sandbox);
}
However this approach add some extra complexity and I am not quite sure if event handler should modify aggregate.
Both approaches are possible.
Why no validation should stay in the Handler? When you change something in the domain, the domain object makes also a validation about the action, and deny it if it's not possible. Here you just need to interact with an external service to verify it.
The external service is just an interface in the domain layer, that you're going to implement with a concrete class into the infrastructure layer. Hence you will not have a directly binding with azure, but a service, let's say CloudService, that in it's implementation uses Azure. This allows you to build domain related exceptions that are thrown by classes that stay in the infrastructure layer.
Also the CQRS approach is valid. But you have to take care when you use it.
You can, for example, start a saga where you ask to the external service to create the instance (CreateRedisInstance), then, according to the event that you get (success or failure) you proceed with the next handler. But you really have to take care about middle situations: what should be done to handle failures between the 2 actions? You need also a rollback of the first action if the second one ends with a failure.
Said this, I would go with the first one if there're no really need to handle a complex process. Moreover, it looks that is all related to the same domain (no infra-domain actions are required), hence there're no real need to augment the complexity with a saga where every success/fail status should be correctly handled.

How to mock Transport.send() method in this method using MockitoJUnitRunner?

I want to write the testcase for the given method. But there exist a static Transport.sendEmail method.
How can I mock this method using MockitoJunitRunner.
public void sendEmail(final String message, final String contentType) {
final Session session = Session.getDefaultInstance(PROPERTIES, null);
final Multipart mpart = new MimeMultipart();
final MimeBodyPart body = new MimeBodyPart();
try {
body.setContent(message, contentType);
mpart.addBodyPart(body);
Transport.send(createMessage(session, mpart));
LOGGER.info("Email Notification Sent Successfully");
} catch (MessagingException | UnsupportedEncodingException e) {
LOGGER.error("Was not able to send mail", e);
}
So:
Transport.send(createMessage(session, mpart));
that static call means: you can't "control" it using Mockito. Plain and simple. If that call just "passes" in your unit test environment, well, then you can test it, but not verify that the call really took place. Worse, if that call throws some exception in the unit test setup, then heck, what could you do?
Options:
turn to PowerMock(ito) or JMockit, as they allow you to gain control
recommended: improve your design to be easy-to-test
That last idea comes in various flavors:
For example, you could create a minimal interface EmailSenderService that offers a void send(Message whatever) method. Next: you create one implementation of that interface that simply invokes that static method. Now your code that actually has to send that message ... simply gets passed in an instance of EmailSenderService. And within your unit tests, you can now #Mock that interface, and you gain control over it.
Alternatively, you simply deprecate that static method (maybe the whole class), and you design a new "real" EmailSenderService that doesn't rely on static methods.

Servicestack Exception Handling: Passing a Status That Came From Web

Let's say I have multiple services. One service is calling another service to get something. That service also gets some information from a third party vendor. Let's say the third party vendor returned a Too Many Requests message with 429 status code. The method that calls the third party vendor is used by lots of other methods and can be called directly via GET Request or within another Http Request.
When I detect the 429 status code, I was throwing a custom exception (let's say TooManyRequestsException) and using the Mapper to send the code to the requester.
Config.MapExceptionToStatusCode.Add(typeof(TooManyRequestsException),429);
It works if the method is called directly. But obviously I forgot the fact that this method was called by many other methods inside the service and all other methods are wrapping this exception with generic System.Exception objects with custom messages inside their catch blocks.
What other options do I have other than changing all the methods that wrap the exception with System.Exception? I tried to go over http://docs.servicestack.net/error-handling but couldn't really find a way that would help me, or couldn't make sense of it.
I recommend looking at Overriding OnExceptionTypeFilter in your AppHost which will let you apply custom logic to inspect the Exception and customize the ResponseStatus returned:
public override void OnExceptionTypeFilter(
Exception ex, ResponseStatus responseStatus)
{
var argEx = ex as ArgumentException;
var isValidationSummaryEx = argEx is ValidationException;
if (argEx != null && !isValidationSummaryEx && argEx.ParamName != null)
{
var paramMsgIndex = argEx.Message.LastIndexOf("Parameter name:");
var errorMsg = paramMsgIndex > 0
? argEx.Message.Substring(0, paramMsgIndex)
: argEx.Message;
responseStatus.Errors.Add(new ResponseError
{
ErrorCode = ex.GetType().Name,
FieldName = argEx.ParamName,
Message = errorMsg,
});
}
}

How to Nak a ServiceStack RabbitMQ message within the RegisterHandler?

I'd like to be able to requeue a message from within my Service Endpoint that has been wired up through the RegisterHandler method of RabbitMQ Server. e.g.
mqServer.RegisterHandler<OutboundILeadPhone>(m =>
{
var db = container.Resolve<IFrontEndRepository>();
db.SaveMessage(m as Message);
return ServiceController.ExecuteMessage(m);
}, noOfThreads: 1);
or here.
public object Post(OutboundILeadPhone request)
{
throw new OutBoundAgentNotFoundException(); // added after mythz posted his first response
}
I don't see any examples how this is accomplished, so I'm starting to believe that it may not be possible with the ServiceStack abstraction. On the other hand, this looks promising.
Thank you, Stephen
Update
Throwing an exception in the Service does nak it, but then the message is sent to the OutboundILeadPhone.dlq which is normal ServiceStack behavior. Guess what I'm looking for is a way for the message to stay in the OutboundILeadPhone.inq queue.
Throwing an exception in your Service will automatically Nak the message. This default exception handling behavior can also be overridden with RabbitMqServer's RegisterHandler API that takes an Exception callback, i.e:
void RegisterHandler<T>(
Func<IMessage<T>, object> processMessageFn,
Action<IMessage<T>, Exception> processExceptionEx);
void RegisterHandler<T>(
Func<IMessage<T>, object> processMessageFn,
Action<IMessage<T>, Exception> processExceptionEx,
int noOfThreads)

How to Dispose an InMemory Cached result in ServiceStack

I have a service in my ServiceStack API to handle image results, by implementing IStreamWriter WriteTo(stream). Works great.
To optimize the processing I am adding support for the InMemory Cache, with a TimeSpan to expire the results. My concern is related to IDispose. Prior to cache implementation I was using IDispose to dispose the result object and its image after returning, but with inmemory cache it cannot implement IDispose, otherwise the data will be wiped before it is refetched from cache.
Question is how, or where, to implement the disposal of the cached results? Will the cache dispose the items on expiration? If so, how to implement Dispose only for calls from cache manager, but not from http handler.
public class ImageResult : IDisposable, IStreamWriter, IHasOptions
{
private readonly Image image;
public void WriteTo(Stream responseStream)
{
image.Save(responseStream, imgFormat);
}
public void Dispose()
{
// if we dispose here, will be disposed after the first result is returned
// want the image to be disposed on cache expiration
//if (this.image != null)
// this.image.Dispose();
}
}
public class ImageService : AssetService
{
public object Get(ImageRequest request)
{
var cacheKey = ServiceStack.Common.UrnId.Create<ImageRequest>(request.id);
if (Cache.Get<ImageResult>(cacheKey) == null)
{
Cache.Set<ImageResult>(cacheKey, GetImage(request), TimeSpan.FromMinutes(1));
}
return Cache.Get<ImageResult>(cacheKey);
}
[...]
}
From a quick look at ServiceStack's InMemoryCache you can see there's no event or callback to hook into for cache entry expiration. Consider using System.Runtime.Caching.MemoryCache which gives you similar caching capabilities, plus specifically you can use a change monitor for callback on expiration and/or removal.
Another alternative: create your own from SS's cache source code to provide you with a callback.
Once you have a callback in place, you could call Dispose() from there - but as you said you don't want the ImageResult to be disposable, instead allow access to its Image property and dispose that from the expiration callback yourself. You could wrap a class around .net's image to allow for unit testing (avoid having to use a real image object in tests).
EDIT: actually.. see below(*), this would create a mess.
On another note, I would make some slight changes to your Get() method. The last call to Cache.Get() is superfluous. Even though you're using an in-memory cache you'd still want to minimize access to it as it's potentially slower than it may seem (needs to use locks to synchronize in-memory access from multiple threads).
var imageResult = Cache.Get<ImageResult>(cacheKey);
if (imageResult == null)
{
imageResult = GetImage(request);
Cache.Set<ImageResult>(cacheKey, imageResult, TimeSpan.FromMinutes(1));
}
return imageResult;
(*) Just realized you could have a request getting the ImageResult from the cache, and then an instance later, before it writes anything to the target (response) stream, it expires and gets disposed. Nasty. Instead, let .net handle this for you: instead of making ImageResult implement IDisposable, create a destructor in which you dispose the internal Image object. This will work with SS's in memory cache:
~ImageResult()
{
image.Dispose();
}

Resources