Angular2 Event subscription not firing? - events

I have a system with the following structure (three components) :
Grand-Father -> Father -> Children
And a service : Service which has a EventEmitter on it.
On all three components I have the service set as a provider, added it to the constructor and subscribed to the eventemitter:
this.subscription = this._service.eemiter.subscribe(data=> this.init(data));
Problem is, it only gets fired on the component that calls the method from the service which fires the event. My guess is that, by defining them this way each component get a different Service and not the same one, therefore the event is only seen by the component that called the firing method.
What design should I make in order for all three components to be able to subscribe to the same service and actually catch the event?

If you add it to the providers of every component, every component gets its own instance of the service (not shared).
Either add it to bootstrap(AppComponent, [MySharedService]) or to a common parent element.
The parent element with MyService in the providers list is the root scope for the service instance. All children get the same instance (except another component in between also has MyService in the providers list).

Related

Axon Event only picked up by one instance of my service instead of all (fan-out)

We have a Spring micro-service connected to Axon with an #Component and an #EventHandler function on this class. Like this:
#Component
#AllowReplay(false)
class AClass {
#EventHandler
fun on(someEvent: SomeEvent) {
...some handling here
}
}
The Event gets picked up normally and everything works fine but when we run multiple instances of our service only one instance of the service picks up the event. I userstand that this has to do with the way the event processors work (https://docs.axoniq.io/reference-guide/axon-framework/events/event-processors) but I need all instances of the service to pick up the event. How can I configure this?
It pretty much depends on how you are configuring and using it.
So, 'pick up' events, the way you describe, I assume that are events being handled.
In that case, and another assumption here that you are using some sort of Tracking Event Processor (TEP), this is where this logic and responsability is.
In essence, a TEP is responsible for 'tracking' which events it already received to not double react on those.
In your scenario, seems like your apps/instances are sharing the same database (hence sharing the same tokens) and that's why you see it.
About your 'workaround', you are just assigning names to a Processing Group (which can also be done using annotations like this: #ProcessingGroup("processing-group-name-you-want"). If you do not assign a name, the package is the default name used.
Every Processing Groups has a tracking token behind it. In this case, you get multiple tokens and 'react' to the same event multiple times.
For more info about Processing Groups, I recommend this answer.
The answer that works for me, although not the prettiest: Axon 'merges' processors based on package name so multiple instances of a service result in a single processor.
By using unique processing groups you can trick Axon into not 'merging' the different processors into one.
#Autowired
fun configure(configurer: EventProcessingConfigurer) {
configurer.assignProcessingGroup { t: String? -> "${t}_${UUID.randomUUID()}" }
}

Axon How can I add an event listener/interceptor to intercept events before they reach their handlers?

I have a projection class (to build a read model) and I want to add an interceptor for its events in a way that if the id passed in the event leads to a null object (non-existent in my db) then I want to block it, otherwise let it pass.
This way I will escape adding a null checker on EVERY event handler.
#EventHandler
public void onEvent(Event event) {
Entity entity = getEntity(event.getId());
if(entity!=null){ // what I don't want to add on every event handler
dostuff();
}
}
I found that axon provides an interface called EventListener but I'm not sure how to work with it and I'm not sure if this will be intercepting ALL of my events or if I will be able to intercept select events.
There is no mention anywhere for this interface but in the official documentation (with no actual examples or so)
You are right on the part the the Reference Guide still needs some improvements #bleh10 - I can assure you, they're being worked on, the team is just spread out relatively thin.
In absence of the sought after example, I think I can give you some guidance.
What you're looking for is a MessageHandlerInterceptor implementation, specifically for the EventMessage type. As the naming suggests, it intercepts messages prior to being handled, which corresponds perfectly with the question you've posed.
Secondly, you obviously need a place to configure these. Within an Axon application, the technical aspect of delivering events to your #EventHandler annotated methods, is the Event Processor. As such, it is in charge of ensuring the Event Messages flowing through it are intercepted as desired.
Hence, the place to configure your EventMessage MessageHandlerInterceptor, is on the EventProcessor implementation you've chosen. To ensure a given Event Handling Component is set in a specific EventProcessor, you can specify it's Processing Group by annotating the class with the #ProcessingGroup annotation.
From there on, you can easily configure specific properties for your Event Processor by utilizing the EventProcessingConfigurer. More specifically, I'd suggest to use the EventProcessingConfigurer#registerHandlerInterceptor(String, Function<Configuration, MessageHandlerInterceptor<? super EventMessage<?>>>) method for this.
The first String parameter is meant to describe the name of your Processing Group. The second is a Function which receive the Axon Configuration and should output a MessageHandlerInterceptor which can deal with the EventMessage class.
Hope this helps you out!

How to take an action on a deleted Asset in Adobe Experience Manager?

I have a system external to Adobe Experience Manager that I need to make a quick call to whenever an Asset is deleted in AEM. Not being an expert in AEM, my options feel very limited.
I've attempted to create a workflow with a step that can make the appropriate call, and have hooked up a Launcher to listen for a Remove event on any "dam:Asset" type nodes from a certain path in AEM. That means I've got a Java class I've pushed into AEM that extends WorkflowProcess, and is called as part of that workflow.
However, this workflow is not being triggered when I go delete an Asset. If, however, I change the Launcher to listen for a Remove event on "Any Node Type", the workflow is called as I would have expected, however it appears that the asset has already been deleted by the time it hits my process, so the node path provided to my process is already null and void and I'm unable to do anything with it. In any case, I can't leave the Launcher set to fire on "Any Node Type"...
What am I missing? Is there a better way to capture a delete event on an asset? All I need is to be able to gather some information from the deleted node and its children to make this external call. I just need a handle on the Node when a user deletes an Asset...
There are basically 3 ways to do this :
1) Using workflows - The way you are doing it right now. Create a workflow and use a launcher to trigger the workflow. This method has its disadvantages. if there are going to be lot of concurrent events then you should avoid using workflows since each workflow is an independent thread. if there are lot of workflows then you could end up with lot of waiting threads.
2) Using Sling Eventing - This is an eventing mechanism provided by sling. This is a publish-subscribe model Here you subscribe to different topics and you are notified when any event for that topic occurs. There are different topics like "RESOURCE_ADDED", "RESOURCE_REMOVED" etc.
Here is a sample code on how to create a listener which is notified when a resource is removed.
public class AssetRemoved implements EventHandler {
private Logger logger = LoggerFactory.getLogger(AssetRemoved.class);
#Override
public void handleEvent(Event event) {
logger.info("********Node removed");
String[] propertyNames = event.getPropertyNames();
}
}
3) using Lower level JCR API's - This is an eventing mechanism provided by JCR implementations. This is the lowest level of eventing right at the persistence level. As a good pratice, it is always recommended to use higher level API's like sling or the one's provided by Adobe as a general rule.
In JCR eventing mechanism, you create an observation listener which is notified
http://www.day.com/specs/jsr170/javadocs/jcr-1.0/javax/jcr/observation/EventListener.html
There are 6 types of events which can occur :
Node added
Node moved
Node removed
Prop­erty added
Prop­erty removed
Prop­erty changed
Your Event listener is notified for all the events and you have to filter based on which type you want to listen(unlike Sling eventing).
You can create an Event listener like the below sample code :
Public class SampleEventListener implements EventListener{
pubic void onEvent(EventIterator events){
//filter the type of event type & do your stuff here:
}
}
For your use case I would suggest to use the Sling Eventing(option 2). Until and unless really necessary or you need a really granular access, always stick to higher level API's like sling.

How to use Reactor to dispatch events to multiple consumers and to filter events based on event data?

I'm evaluating Reactor (https://github.com/reactor/reactor) if it would be suitable for creating an event dispatching framework inside my Spring / enterprise application.
First, consider a scenario in which you have an interface A and concrete event classes B, C, and so on. I want to dispatch concrete events to multiple consumers i.e. observers. Those are registered to a global Reactor instance during bean post processing. However, you can register them dynamically. In most cases there is one producer sending events to multiple consumers at high rate.
I have used Selectors, namely, the ClassSelector to dispatch the correct event types to the correct consumers. This seems to work nicely.
Reactor reactor = ...
B event = ...
Consumer<Event<B>> consumer = ...
// Registration is used to cancel the subscription later
Registration<?> registration = reactor.on(T(event.getClass()), consumer);
To notify, use the type of the event as a key
B event = ...
reactor.notify(event.getClass(), Event.wrap(event));
However, I'm wondering if this is the suggested way to dispatch events efficiently?
Secondly, I was wondering that is it possible to filter events based on the event data? If I understand correctly, Selectors are only for inspecting the key. I'm not referring to event headers here but to the domain specific object properties. I was wondering of using Streams and Stream.filter(Predicate<T> p) for this but is it also possible to filter using Reactor and Selectors? Of course I could write a delegating consumer that inspects the data and delegates it to registered consumers if needed.
There is a helper object called Selectors that helps to create the various kinds of built-in Selector implementations. There you can see references to the PredicateSelector. The PredicateSelector is very useful as it allows you complete control over the matching of the notification key. It can be a Spring #Bean, an anonymous inner class, a lambda, or anything else conforming to the simple Predicate interface.
Optionally, if you have the JsonPath library in your classpath, then you can use the JsonPathSelector to match based on JsonPath queries.
In either of these cases you don't need to have a separate object for a key if the important data is actually the domain object itself. Just notify on the object and pass the Event<Object> as the second parameter.
MyPojo p = service.next();
reactor.notify(p, Event.wrap(p));

what is the difference between event listerners and subscribers in symfony2 [duplicate]

I'm working in the Symfony2 framework and wondering when would one use a Doctrine subscriber versus a listener. Doctrine's documentation for listeners is very clear, however subscribers are rather glossed over. Symfony's cookbook entry is similar.
From my point of view, there is only one major difference:
The Listener is signed up specifying the events on which it listens.
The Subscriber has a method telling the dispatcher what events it is listening to
This might not seem like a big difference, but if you think about it, there are some cases when you want to use one over the other:
You can assign one listener to many dispatchers with different events, as they are set at registration time. You only need to make sure every method is in place in the listener
You can change the events a subscriber is registered for at runtime and even after registering the subscriber by changing the return value of getSubscribedEvents (Think about a time where you listen to a very noisy event and you only want to execute something one time)
There might be other differences I'm not aware of though!
Don't know whether it is done accidentally or intentionally.. But subscribers have higher priority that listeners - https://github.com/symfony/symfony/blob/master/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPass.php#L73-L98
From doctrine side, it doesn't care what it is (listener or subscriber), eventually both are registered as listeners - https://github.com/doctrine/common/blob/master/lib/Doctrine/Common/EventManager.php#L137-L140
This is what I spotted.
You should use event subscriber when you want to deal with multiple events in one class, for example in this symfony2 doc page article, one may notice that event listener can only manage one event, but lets say you want to deal with several events for one entity, prePersist, preUpdate, postPersist etc... if you use event listener you would have to code several event listener, one for each event, but if you go with event subscriber you just have to code one class the event susbcriber, look that with the event subscriber you can manage more than one event in one class, well thats the way i use it, i preffer to code focused in what the model business need, one example of this may be went you want to handle several lifecycle events globaly only for a group of your entities, to do that you can code a parent class and defined those global methods in it, then make your entities inherit that class and later in your event susbcriber you subscribe every event you want, prePersist, preUpdate, postPersist etc... and then ask for that parent class and execute those global methods.
Another important thing: Doctrine EventSubscribers do not allow you to set a priority.
Read more on this issue here
Both allow you to execute something on a particular event pre / post persist etc.
However listeners only allow you to execute behaviours encapsulated within your Entity. So an example might be updating a "date_edited" timestamp.
If you need to move outside the context of your Entity, then you'll need a subscriber. A good example might be for calling an external API, or if you need to use / inspect data not directly related to your Entity.
Here is what the doc is saying about that in 4.1.
As this is globally applied to events, I suppose it's also valid for Doctrine (not 100% sure).
Listeners or Subscribers
Listeners and subscribers can be used in the same application indistinctly. The decision to use either of them is usually a matter
of personal taste. However, there are some minor advantages for each
of them:
Subscribers are easier to reuse because the knowledge of the events is kept in the class rather than in the service definition.
This is
the reason why Symfony uses subscribers internally;
Listeners are more flexible because bundles can enable or disable each of them conditionally depending on some configuration value.
http://symfony.com/doc/master/event_dispatcher.html#listeners-or-subscribers
From the documentation :
The most common way to listen to an event is to register an event
listener with the dispatcher. This listener can listen to one or more
events and is notified each time those events are dispatched.
Another way to listen to events is via an event subscriber. An event
subscriber is a PHP class that's able to tell the dispatcher exactly
which events it should subscribe to. It implements the
EventSubscriberInterface interface, which requires a single static
method called getSubscribedEvents().
See the example here :
https://symfony.com/doc/3.3/components/event_dispatcher.html

Resources