77
88namespace Ecotone \Modelling \Config \Routing ;
99
10+ use Ecotone \Messaging \Handler \Type ;
11+ use Ecotone \Messaging \Handler \TypeDescriptor ;
12+ use Ecotone \Modelling \Attribute \NamedEvent ;
1013use function array_map ;
1114use function array_unique ;
1215
@@ -49,19 +52,15 @@ public function getRoutesFromAnnotatedFinding(AnnotatedFinding $registration, In
4952 return [$ routingKey ];
5053 }
5154
52- $ interfaceToCall = $ interfaceToCallRegistry -> getFor ( $ registration -> getClassName () , $ registration-> getMethodName () );
53- if ($ interfaceToCall -> hasNoParameters () ) {
55+ $ type = $ this -> getFirstParameterType ( $ interfaceToCallRegistry , $ registration );
56+ if (! $ type ) {
5457 return [];
55- }
56- $ type = $ interfaceToCall ->getFirstParameter ()->getTypeDescriptor ();
57- if ($ type ->isUnionType ()) {
58+ } else {
5859 $ routes = [];
5960 foreach ($ type ->getUnionTypes () as $ unionType ) {
6061 $ routes [] = (string ) $ unionType ;
6162 }
6263 return $ routes ;
63- } else {
64- return [(string ) $ type ];
6564 }
6665 }
6766
@@ -76,9 +75,36 @@ public function addRoutesFromAnnotatedFinding(AnnotatedFinding $registration, In
7675 $ routes = $ this ->getRoutesFromAnnotatedFinding ($ registration , $ interfaceToCallRegistry );
7776 $ priority = PriorityBasedOnType::fromAnnotatedFinding ($ registration );
7877
79- $ routingEvent = new RoutingEvent ($ registration , $ destinationChannel , $ routes , $ priority ->getPriorityArray ());
78+ $ routingEvent = new RoutingEvent ($ this , $ registration , $ destinationChannel , $ routes , $ priority ->getPriorityArray ());
79+
80+ $ this ->dispatchRoutingEvent ($ routingEvent );
81+
82+ if ($ routingEvent ->isCanceled ()) {
83+ return null ; // event is canceled, no routing
84+ }
85+ $ destinationChannel = $ routingEvent ->getDestinationChannel ();
86+ $ priority = $ routingEvent ->getPriority ();
87+
88+ foreach ($ routingEvent ->getRoutingKeys () as $ routingKey ) {
89+ $ this ->addRoute ($ routingKey , $ destinationChannel , $ priority );
90+ }
91+
92+ // add object alias if the routing key is a class and has a NamedEvent annotation
93+ $ type = $ this ->getFirstParameterType ($ interfaceToCallRegistry , $ registration );
94+ if ($ type ) {
95+ foreach ($ type ->getUnionTypes () as $ unionType ) {
96+ $ className = (string ) $ unionType ;
97+ if (class_exists ($ className )) {
98+ $ classDefinition = $ interfaceToCallRegistry ->getClassDefinitionFor (TypeDescriptor::create ($ className ));
99+ if ($ classDefinition ->hasClassAnnotation (TypeDescriptor::create (NamedEvent::class))) {
100+ $ namedEvent = $ classDefinition ->getSingleClassAnnotation (TypeDescriptor::create (NamedEvent::class));
101+ $ this ->addObjectAlias ($ className , $ namedEvent ->getName ());
102+ }
103+ }
104+ }
105+ }
80106
81- return $ this -> dispatchRoutingEvent ( $ routingEvent ) ;
107+ return $ destinationChannel ;
82108 }
83109
84110 /**
@@ -166,6 +192,9 @@ public function addNamedRoute(string $routeName, string $channel, int|array $pri
166192 public function addObjectAlias (string $ class , string $ routingKey ): void
167193 {
168194 if (isset ($ this ->classToNameAliases [$ class ])) {
195+ if ($ this ->classToNameAliases [$ class ] === $ routingKey ) {
196+ return ; // already registered
197+ }
169198 throw ConfigurationException::create ("Class $ class already has an alias registered: " . $ this ->classToNameAliases [$ class ]);
170199 }
171200 if (isset ($ this ->nameToClassAliases [$ routingKey ])) {
@@ -243,6 +272,11 @@ public function compile(): Definition
243272 ]);
244273 }
245274
275+ public function getMessagingConfiguration (): ?Configuration
276+ {
277+ return $ this ->messagingConfiguration ;
278+ }
279+
246280 private function channelName (string $ channel ): string
247281 {
248282 if (isset ($ this ->channelsName [$ channel ])) {
@@ -263,25 +297,22 @@ private function uniqueRoutedChannels(array $routes): array
263297 /**
264298 * @return ?string the destination channel name or null if the event is canceled
265299 */
266- private function dispatchRoutingEvent (RoutingEvent $ routingEvent ): ? string
300+ private function dispatchRoutingEvent (RoutingEvent $ routingEvent ): void
267301 {
268302 foreach ($ this ->routingEventHandlers as $ routingEventHandler ) {
269- $ routingEventHandler ->handleRoutingEvent ($ routingEvent , $ this ->messagingConfiguration );
270- if ($ routingEvent ->isCanceled ()) {
271- return null ;
272- }
273- if ($ routingEvent ->isPropagationStopped ()) {
274- break ;
303+ $ routingEventHandler ->handleRoutingEvent ($ routingEvent );
304+ if ($ routingEvent ->isCanceled () || $ routingEvent ->isPropagationStopped ()) {
305+ return ;
275306 }
276307 }
308+ }
277309
278- $ destinationChannel = $ routingEvent -> getDestinationChannel ();
279- $ priority = $ routingEvent -> getPriority ();
280-
281- foreach ($ routingEvent -> getRoutingKeys () as $ routingKey ) {
282- $ this -> addRoute ( $ routingKey , $ destinationChannel , $ priority ) ;
310+ private function getFirstParameterType ( InterfaceToCallRegistry $ interfaceToCallRegistry , AnnotatedFinding $ registration ): ? Type
311+ {
312+ $ interfaceToCall = $ interfaceToCallRegistry -> getFor ( $ registration -> getClassName (), $ registration -> getMethodName ());
313+ if ($ interfaceToCall -> hasNoParameters () ) {
314+ return null ;
283315 }
284-
285- return $ destinationChannel ;
316+ return $ interfaceToCall ->getFirstParameter ()->getTypeDescriptor ();
286317 }
287318}
0 commit comments