Can my policy behavior change based on data in the execute? - circuit-breaker

I am using the Circuit Breaker Policy for database access. I have a multi-tenant structure with identical databases that store data for different clients. My application could hit any of the tenants. If one database is down the others may not be. If I open the breaker I want to only open it for that tenant.
I created identical polices for each tenant and store them in a Dictionary with the tenant name as the key. When making a database call, I retrieve the matching policy from the dictionary and execute it.
I am fairly sure this works but I am wondering if it's too convoluted. Perhaps Polly already as a way to do this. Is there a way to bind the policy behavior to a data value for the tenant?
Any advice?

The design stated in the question is correct for the requirement: maintain a separate circuit-breaker policy instance per downstream system you want to treat as having distinct health status.
Polly does not offer a circuit-breaker which maintains a big internal dictionary of health states per some key.
Polly does offer a PolicyRegistry; this is fundamentally a key-policy dictionary similar to described in the question.
If the circuit-breaker Policy is required to be used mid-PolicyWrap, and is the only thing in the PolicyWrap that needs to vary per-tenant, you can use a 'policy selector' within the PolicyWrap to select or manufacture an appropriate policy at runtime.
The example code in the link above:
public class AsyncPolicySelector<TResult> : AsyncPolicy<TResult>
{
private readonly Func<Context, IAsyncPolicy<TResult>> policySelector;
public static AsyncPolicySelector<TResult> Create(Func<Context, IAsyncPolicy<TResult>> policySelector)
{
return new AsyncPolicySelector<TResult>(policySelector);
}
private AsyncPolicySelector(Func<Context, IAsyncPolicy<TResult>> policySelector)
{
this.policySelector = policySelector;
}
protected override Task<TResult> ImplementationAsync(Func<Context, CancellationToken, Task<TResult>> action, Context context, CancellationToken cancellationToken, bool continueOnCapturedContext)
{
return policySelector(context).ExecuteAsync(action, context, cancellationToken, continueOnCapturedContext);
}
}
creates you a custom AsyncPolicySelector<TResult> policy using a Func<Context, IAsyncPolicy<TResult>> policySelector which can select-a-previous or manufacture afresh (when needed) a policy.
Polly Context has dictionary semantics so you could set the tenant-id on Context prior to execution.
Context context = new Context();
context["TenantId"] = /* tenant id from somewhere */
// (you must execute through the PolicyWrap then with an overload passing in this context)
And use a Func<Context, IAsyncPolicy<TResult>> policySelector to retrieve the circuit-breaker by context["TenantId"] from your dictionary or PolicyRegistry; or manufacture a new circuit-breaker for that tenant if there was not already one.

Related

DDD: Where to raise "created" domain event

I struggle to find and implement the best practise for the following problem: where is the best location to raise create domain event (the event that notifies for the creation of an aggregate). For example if we have Order aggregate in our bounded context we would like to notifie all interested parties when order is create. The event could be OrderCreatedEvent.
What I tried in first place is to raise this event in the constructor (I have a collection of domain events in each aggregate). This way it is okay only when we create the order. Because when we would like to do anything with this aggregate in the future we are going to create new instance of it through the constructor. Then OrderCreatedEvent will be raised again but it is not true.
However, I thought it would be okey to raise the event in the application layer but it is an anti-pattern (the domain events should live only in the domain). Maybe to have a method Create that will just add the OrderCreatedEvent to its domain events list and call it in the application layer when order is created is an option.
Interesting fact I found on the internet is that it is an anti-pattern to raise domain events in the contructor which means the last described option (to have Create method) would be the best approach.
I am using Spring Boot for the application and MapStruct for the mapper that maps the database/repository Entity to the domain model aggregate. Also, tried to find a way to create a mapper that is going to skip the contructor of the target class but as all properties of the Order aggregate are private seems impossible.
Usually constructor are used only to make assignations on object's fields. This is not the right place to trigger behaviours, especially when they throw exceptions or have side effects
DDD theorists (from Eric Evans onwards) suggest implementing factories for aggregates creation. A factory method, for example, can invoke aggregate constructor (and wire up the aggregate with child domain objects as well) and also register an event.
Publishing events from the application layer is not an anti-pattern per se. Application services can depend from the domain events publisher, the important thing is that it's not application layer to decide which event to send
To summarize, with a stack like Java Spring Boot and domain events support, your code could look like
public class MyAggregate extends AbstractAggregateRoot {
public static MyAggregate create() {
MyAggregate created = new MyAggregate();
created.registerEvent(new MyAggregateCreated());
return created;
}
}
public class MyApplicationService {
#Autowired private MyAggregateRepository repository;
public void createAnAggregate() {
repository.save(MyAggregate.create());
}
}
notice that event publishing happens automagically after calling repository.save(). The downside here is that, when you use db-generated identifiers, aggregate id is not avaliable in the event payload since it's associated after persisting the aggregate. If i will change the application service code like that:
public class MyApplicationService {
#Autowired private MyAggregateRepository repository;
#Autowired private ApplicationEventPublisher publisher;
public void createAnAggregate() {
repository.save(MyAggregate.create()).domainEvents().forEach(evt -> {
publisher.publish(evt);
});
}
}
Application layer is in charge to decide what to do to fulfill this workflow (create an aggregate, persist it and send some event) but all the steps happen transparently. I can add a new property to the aggregate root, change DBMS or change event contract, this won't change these lines of code. Application layer decides what to do and domain layer decides how to do it. Factories are part of the domain layer, events are a transient part of the aggregate state and the publishing part is transparent from domain standpoint
Check out this question!
Is it safe to publish Domain Event before persisting the Aggregate?.
However, I thought it would be okey to raise the event in the application layer but it is an anti-pattern (the domain events should live only in the domain). - Domain events live in Domain layer, but Application layer references Domain layer and can easily emit domain events.

Update online user-data from outside the session (without reauthentication)

There are several scenarios, where I want to update the user/principal data such that the changes are reflected while the user stays logged in (I do not want to force re-authentication)
From "within" the session this is not a Problem:
#PostMapping("/updateInfo")
fun updateMyData(
#AuthenticationPrincipal user: AppUser,
#Valid #RequestBody newInfo: UpdateDataRequest
): ResponseEntity<TestUserInfo> {
val testInfo = TestUserInfo(user, newInfo)
user.info = testInfo
val updatedUser = users.save(user)
return ResponseEntity.ok(updatedUser.info!!)
}
When I allow the user to for example change the their own data, I can easily access and change the #AuthenticationPrincipal - in successive requests i can observe that the data is updated.
This is different when I need to change the user data from 'outside' the session.
use cases
There are 2 use cases for this:
a). an administrator changes user-data
b). the user confirms his email address
Now a). clearly happens from within another http-session where the principal is a user with some admin privileges.
For b). you might ask, why this doesn't happen within a session: I want a simple one-time confirmation link, i.e. a get request. I cannot assume, that the user is logged in via a session on the device the confirmation link is opened. It wouldn't feel right to me, to do a separate preauthentication provider or something to get the user authenticated - then there will an unnecessary session opened on a browser that is never used again.
So in both cases, when I fetch the user via a JPArepository, update data, and save it back, the change is up to date in the databse - but the logged-in users don't know of that change, because their user data is stored in the http session and doesn't know that it needs to be updated.
Note that I am not using redis/spring-session anything - this is just a plain http session, so from my understanding I can not use FindByIndexNameSessionRepository.
What I have tried
In spring-security issue #3849 it was suggested by rwinch to override SecurityContextRepository - however, there is no further information on how to do that exactly - I tried to understand the interface but couldn't get much further there.
I tried to get through the responses tothe followinf SO post:
How to reload authorities on user update with Spring Security (ignoring answers using redis.)
the most upvoted answer by leo doesn't help, as mentioned in the comments there
Aure77 suggests using SessionRegistry, which I tried to use also following bealdung - but to no avail: I cannot the right session, getallprincipals() is always empty when there is an active session for a logged in user. In case I had the right session I'm still not even sure how to move on from there, as Aure just suggests using expireNow() which forces reauthentication - I want to avoid that.
alexkasko suggests something similar - from his I am thinking that maybe spring boot uses a thread-local securityContextRepository by default, and thats why i have no principals. He the suggests something that i haven'T yet understood - also the answers are quite old (2012) and I don'T feel very secure about trying to understand and apply that
TwiN suggests using a HandlerInterceptor. Hasler Choo suggests a modified version with a hashset that seems to be more close to what i need. As described below - it has its problems though.
HandlerInterceptor based approach
This is the only solution so far that I could successfully implement - but it doesn't seem very flexible. My implementation so far will only cover user-role changes.
Configuration:
#Configuration
class WebMvcConfig : WebMvcConfigurer {
#Autowired
private lateinit var updateUserDataInterceptor : UpdateUserDataInterceptor
override fun addInterceptors(registry: InterceptorRegistry) {
registry.addInterceptor(updateUserDataInterceptor)
}
}
The HandlerInterceptor:
#Component
class UpdateUserDataInterceptor(
#Autowired
private val users: AppUserRepository
) : HandlerInterceptor {
private val usersToUpdate = ConcurrentHashMap.newKeySet<Long>()
fun markUpdate(user: AppUser) = usersToUpdate.add(user.id)
override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean {
val auth = SecurityContextHolder.getContext().authentication
(auth.principal as? AppUser)?.apply {
synchronized(usersToUpdate) {
if (id in usersToUpdate) {
role = users.findById(id).get().role
usersToUpdate.remove(id)
}
}
}
return true
}
}
Instead of just updating the role, what I would rather like, is just replace the entire principle - but the principal is final in the Authentication object.
So whenever a would wnat something else than the role updated, this has to specifically be mentioned here.
Remaining questions:
Are there other solutions than the HandlerInterceptor?
Is there a HandlerInterceptor based solution, that allows me to fully update the principal object
I am not considering single instance applications
1. Three factors in play
How quickly you want the changes reflected ( current session and current request vs current session and next request vs next session)
Do you have to keep the response time minimally affected by using distributed memory or cache?
Do you want to cut the cost (cannot use distributed memory) at the expense of response time?
Now you can you choose one option from first factor. But with second and third factors, you optimise one factor at the expensive of other one. Or you try to find a balance like your attempt to keep a list of affected users in memory and then hit the database for those affected.
( Unfortunately your optimisation to keep list of affected users in UpdateUserDataInterceptor as it is not stored in distributed memory won't work unless it is a single instance application)
2. Now based on my understanding of your question, I am making the following answers to the three factors in play.
current session next request
reduced cost (no distributed memory)
performance hit with database calls
( I will later update my thoughts on other possible paths and possible implementations for those paths)
3. Implementation options for the selected path - next-request-with-db-calls-and-no-distributed-memory
Any component that is part of request filter chain with the ability to call the database can achieve this by updating the SecurityContext. If you do this in the SecurityContextRepository, you are doing it at the earliest opportunity and you may even have the opportunity to restore the SecurityContext with updated principle instead of updating the already created SecurityContext. But any other filter or Interceptor can achieve this too by updating the SecurityContext.
4. Detailed look into each Implementation
SecurityContextRepository Option :
Looking at the HttpSessionSecurityContextRepository, it seems straight forward to extend it.
public class HttpSessionSecurityContextRepository
implements SecurityContextRepository {
.....
public SecurityContext loadContext(HttpRequestResponseHolder reqRespHolder) {
HttpServletRequest request = reqRespHolder.getRequest();
HttpServletResponse response = reqRespHolder.getResponse();
HttpSession httpSession = request.getSession(false);
SecurityContext context = readSecurityContextFromSession(httpSession);
........
//retrieve the user details from db
//and update the principal.
.......
return context;
}
}
SecurityContextHolderStrategy Option
Looking at the ThreadLocalSecurityContextHolderStrategy, it also looks straightforward
final class ThreadLocalSecurityContextHolderStrategy
implements SecurityContextHolderStrategy {
private static final ThreadLocal<SecurityContext> contextHolder = new ThreadLocal<>();
....
public void setContext(SecurityContext context) {
// you can intercept this call here, manipulate the SecurityContext and set it
Assert.notNull(context, "Only non-null SecurityContext instances are permitted");
contextHolder.set(context);
}
.....
}
Another filter or HandlerInterceptor //TODO WILL UPDATE
Note:
You mentioned principal is final in authentication object and you want to replace it. You can achieve this by creating a mutable wrapper of UserDetails, extending your current UserDetailsService and returning that wrapper. Then you can update the principal,
YourWrapper principalWrapper =(YourWrapper) securityContext
.getAuthentication().getPrincipal();
principalWrapper.setPrincipal(updated);

Domain driven design - access modifiers for entities and enforcing validation

I am very new to DDD and reading various discussions on validation (where to put it) on the stackoverflow as well as on the web. I do like the idea of keeping the validations outside the entities and validate them depending upon the context. In our project, we have an entity called MedicalRecord and there are various rules for when one can be created or can be saved. I want to create a service layer, let's say RecordService, that would do some check to make sure if a user can create a medical record before creating one. I also want to create MedicalRecordRepository that would save the medical record. What confuses me is the access modifies on my entity and repository classes. Since both will be public, how can I enforce the client of my application to use the service instead of just creating new medical record (with public constructor) and use the repository to save it? I am using c#. I know DDD is language independent but wondering if someone could provide some thoughts on this.
Thanks.
You must control record creation by making the c'tor non-public and allowing creation only through a factory:
public class MedicalRecord
{
internal MedicalRecord()
{
}
}
public static class MedicalRecordFactory
{
public static MedicalRecord Create(User onBehalfOf)
{
// do logic here
return new MedicalRecord();
}
}
For the internal keyword to be applicable, either both classes must be in the same assembly or the class assembly must allow the factory assembly access with the InternalsVisibleTo attribute.
Edit
If you need to be able to perform validation at any time, you additionally have to encapsulate validation logic in another class (here partially done via an extension method):
public static class MedicalRecordValidator
{
public static bool IsValid(this MedicalRecord medicalRecord, <context>)
{
return IsValid(<context>);
}
public static bool IsValidForCreation(User onBehalfOf)
{
return IsValid(null, onBehalfOf);
}
private static bool IsValid(<context> context, User user = null)
{
// do validation logic here
}
}
then, the factory could do this:
public static MedicalRecord Create(User onBehalfOf)
{
return IsValidForCreation(onBehalfOf) ? new MedicalRecord() : null;
}
and you could also always do this:
if (myMedicalRecord.IsValid(<context>))
{
// ....
Only use your repository to retrieve your entities; not to save them. Saving (persisting) your entities is the responsibility of your unit of work.
You let your service change one or more entities (for instance a MedicalRecord) and track the changes in a unit of work. Before committing the changes in your unit of work, you can validate all entities for validation needs across entities. Then you commit your unit of work (in a single transaction), which will persist all your changes, or none at all.
For clarity, your MedicalRecord should protect its own invariants; such that a client retrieving a MedicalRecord using a repository, calling some methods to modify it and then persisting it using a unit of work, should result in a "valid" system state. If there are situations where this is not the case, then it can be argued that it should not be possible to retrieve a MedicalRecord on its own - it is part of some larger concept.
For creation purposes, using a factory like #Thomas suggests below is a good approach, although I think I'd call it a service (because of the collaboration between entities) instead of a factory. What I like about Thomas' approach is that it does not allow a client to create a MedicalRecord without a User (or other contextual information), without tying the MedicalRecord tightly to the user.

Multi-tenancy with MVC3 and Custom Membership Provider

I have a question regarding Multi-tenancy (with MVC3, EF) and a custom SQL Membership provider.
I have custom User and Roles membership classes created, since I have to include the userId in my application tables along with additional user based attributes. I am now converting this into a multi-tenancy application. We are going for a shared-db, shared-app model. We have a master Tenant table that stores the tenant details (including URL ) and the Tenant_id has been included in every table. And now we're working on the changes to the application itself.
The assumption is that tenants will login using a URL like so: tenantUrl.mybaseURL.com.
I am going to change my custom User Validate methods as per this algorithm:
- User goes to URL to login
- The Account controller logon method calls the Custom validate method passing in user/pwd and the tenantId (which has been looked up from the db using the URL).
- The custom validate method checks if the user/password/tenantId combination are valid.
- If valid, we set the tenant Id in a HttpRequest Object and login the user
- For each db access, we lookup the Request object for the tenandId and use that as a filter.
Edit: This is my TenantContext class, where I will be setting/getting the tenantId
public class TenantContext
{
public static int TenantId
{
set
{
if (!HttpContext.Current.Items.Contains("tenant-code"))
HttpContext.Current.Items.Add("tenant-code", value);
HttpContext.Current.Items["tenant-code"] = value;
}
get {return HttpContext.Current.Items.Contains("tenant-code") ? Convert.ToInt32(HttpContext.Current.Items["tenant-code"]) : -1; }
}
}
The tenantId will be set in the Account Controller Login in the above Context.
Is the above a good way to do this or is there a better way? Anybody see any issues with this I should be aware of?
I have seen an example of the tenantId being stored in AppSettings here Handling data access in multi tenant site. Is this a better way to do it?
Thank You
Your algorithm is perfect and in fact i have been working in this kind of an implementation. I have a suggestion that for you, that you use the custom object to maintain the useridentity across different layers. This will contain the userid, tenantid etc.. as this HttpContext will not be helping you in the case of a WCF service and in the context of a user belonging to a tenant and operating on behalf of another tenant. Hence, it would be a better option to have a UserIdentity object that identifies the user. Also, do send the tenantids to the data access layers and do not infer the tenant id's from the request as it will not be available in all environments.

Which layer should I implement caching of lookup data from database in a DDD application?

I am designing a WCF service using DDD.
I have a domain service layer that calls repository to create domain objects. The repository is implemented using ADO.Net and not an ORM. The data comes from DB using Stored Procs. While creating an object say an Address the SP returns an id for state. The SP will not join address table with the state table. The state is represented by a value object class State that has id, abbr and name properties. The list of state objects can be cached (using system.runtime.caching.memorycache) when the application starts up as it is non-volatile data. In general I have a LookupDataRepository that can retrieve all such lookup data from tables. Now the AddressRepository has to populate the State property of address from the state id.
pseudo code:
class AddressRepository : IAddressRepository
{
Address GetAddressById(int id)
{
// call sp and map from data reader
Address addr = new Address(id);
addr.Line = rdr.GetString(1);
addr.State = // what to do ?, ideally LookupCache.GetState(rdr.GetInt32(2))
}
}
class State
{
public int Id;
public string Abbr;
public string Name;
enum StateId {VIC, NSW, WA, SA};
public static State Victoria = // what to do, ideally LookupCache.GetState(StateId.VIC)
}
// then somewhere in address domain model
if(currentState = State.Victroia)
{
// specific logic for Victoria
}
My question is which layer to put this cache ?. Service, Repository, a separate assembly available across all layers.
Where to put Cache? It depends.
If you're scenario will be that you inject your IAddressRepository into several application services (I believe you call em Domain services) the outcome will be:
Caching at repository level will result in that all services will benefit (Pros).
Caching at repository level will result in that all services must use cache (cons).
Caching at service level will only cache for those clients/service that use that specific service and methods (Pros/Cons?)
If you have your transaction management at service layer, you'll need to be careful when applying caching at repository level. Sometime a read operation may hit cache instead and the transaction cannot verify that the read data you're suppose to conduct write operation on isn't modified.
I would go for caching at Service layer. If feels more natural and gives you more control of where and when you want to cache. Repository level is usually to low grained. Service layer and its methods is more closer to use cases and it's then you know when and what to cache.
I really recommend writing a cache wrapper like
public class CacheManager : ICacheManager
{
public Address Address
{
get { }
set { }
}
}
That holds a static reference to System.Runtime.Caching.MemoryCache.Default.
It makes your Caching type safety and casting is only done inside wrapper. You can also unit test your services with a Mocked ICacheManager injected.
A more advanced approach is to do this with Aspect Oriented Programming and decorators/interceptors. You have tons of good info here at StackOverFlow https://stackoverflow.com/search?q=AOP+caching
In my opinion and from my experience, would caching as a repository result in duplicate code, more complexity to the domain, and all events need to be cached? Since an IRepository interface would be implemented ...
So I opted for an infrastructure service, let's cache only what is needed in our app. It is also available to all other services that wish to consume it.

Resources