Skip to content

Commit 4293a6e

Browse files
authored
docs(wildcard): Add wildcard priority docs
docs(wildcard): Add wildcard priority docs
2 parents 7a4d7cc + 08195db commit 4293a6e

File tree

3 files changed

+107
-110
lines changed

3 files changed

+107
-110
lines changed

async/async-commons/src/main/java/org/reactivecommons/async/commons/utils/matcher/KeyMatcher.java

Lines changed: 2 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
package org.reactivecommons.async.commons.utils.matcher;
22

3-
import java.util.List;
43
import java.util.Set;
54
import java.util.regex.Pattern;
6-
import java.util.stream.Collectors;
75

86
public class KeyMatcher implements Matcher {
97

@@ -25,43 +23,14 @@ public static String matchMissingKey(Set<String> names, String target) {
2523
.orElse(target);
2624
}
2725

28-
public static void main(String[] args) {
29-
Set<String> names = Set.of(
30-
"*.*.*",
31-
"*.#.*",
32-
"prefix.*.*",
33-
"prefix.*.#",
34-
"*.middle.*",
35-
"*.*.suffix",
36-
"*.middle.#",
37-
"*.middle.suffix",
38-
"#.middle.suffix",
39-
"prefix.*.suffix",
40-
"prefix.#.suffix",
41-
"prefix.middle.*",
42-
"prefix.middle.#",
43-
"prefix.middle.suffix",
44-
"prefix.other.other",
45-
"other.middle.other",
46-
"other.other.suffix",
47-
"other.other.other",
48-
"in.depend.ent");
49-
String target = "any.any.middle.suffix";
50-
List<String> res = names.stream()
51-
.filter(name -> matches(target, name))
52-
.sorted(KeyMatcher::compare)
53-
.collect(Collectors.toList());
54-
System.out.println(res);
55-
}
56-
5726
private static int compare(String firstExpression, String secondExpression) {
5827
String[] firstExpressionArr = getSeparated(firstExpression);
5928
String[] secondExpressionArr = getSeparated(secondExpression);
6029
return compare(secondExpressionArr.length - firstExpressionArr.length, firstExpressionArr, secondExpressionArr, 0);
6130
}
6231

63-
private static int compare(int current, String[] first, String[] second, int idx){
64-
if(idx >= first.length || idx >= second.length){
32+
private static int compare(int current, String[] first, String[] second, int idx) {
33+
if (idx >= first.length || idx >= second.length) {
6534
return current;
6635
}
6736
if (first[idx].equals(second[idx])) {
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
---
2+
sidebar_position: 10
3+
---
4+
5+
# Wildcards
6+
7+
You may need to listen variable event names that have the same structure, in that case you have the method `handleDynamicEvents` in the `HandlerRegistry`, so you can specify a pattern with '*' wildcard, it does not creates a binding in the broker, but allows that you do it dynamically through a `DynamicRegistry` class.
8+
9+
You can also create binding with '#' wildcard, it is used to listen multiple words, for example `animals.#` will listen to `animals.dog`, `animals.dog.bark`, `animals.cat`, `animals.cat.meow`, etc.
10+
11+
## DynamicRegistry API
12+
13+
```java
14+
public interface DynamicRegistry {
15+
16+
Mono<Void> startListeningEvent(String eventName);
17+
18+
Mono<Void> stopListeningEvent(String eventName);
19+
20+
//... other definitions for queries
21+
22+
}
23+
```
24+
25+
To start listening a new event dynamically at runtime, you should inject and call a method of the DynamicReggistry, for example:
26+
27+
```java
28+
@Component
29+
@AllArgsConstructor
30+
public class DynamicSubscriber {
31+
private final DynamicRegistry registry;
32+
33+
public Mono<Void> listenNewEvent(String eventName) {
34+
return registry.startListeningEvent(eventName);
35+
}
36+
}
37+
```
38+
39+
The conditions for a success dynamic registry functionality are:
40+
41+
- You should handle dynamic events with specific wildcard
42+
43+
```java
44+
@Configuration
45+
public class HandlerRegistryConfiguration {
46+
47+
@Bean
48+
public HandlerRegistry handlerRegistry(EventsHandler events) {
49+
return HandlerRegistry.register()
50+
.handleDynamicEvents("purchase.*", events::handleEventA, Object.class/*change for proper model*/);
51+
}
52+
}
53+
```
54+
55+
- Start a listener dynamically through
56+
57+
```java
58+
registry.startListeningEvent("purchase.cancelled");
59+
```
60+
61+
You also can listen with * wildcard or # wildcard, the * wildcard is for a single word and # wildcard is for multiple words, for example:
62+
63+
`animals.*` will listen to `animals.dog`, `animals.cat`, `animals.bird`, etc.
64+
`animals.#` will listen to `animals.dog`, `animals.dog.bark`, `animals.cat`, `animals.cat.meow`, etc.
65+
66+
```java
67+
@Configuration
68+
public class HandlerRegistryConfiguration {
69+
70+
@Bean
71+
public HandlerRegistry handlerRegistry(EventsHandler events) {
72+
return HandlerRegistry.register()
73+
.listenEvent("animals.*", events::handleEventA, Object.class/*change for proper model*/)
74+
.listenEvent("pets.#.any", events::handleEventA, Object.class/*change for proper model*/);
75+
}
76+
}
77+
```
78+
79+
This last approach is useful when you have a dynamic event name, for example, you can have a `purchase.cancelled` event, but you can also have a `purchase.cancelled.2021` event, so you can listen to all of them with `purchase.*` or `purchase.#` respectively.
80+
81+
## Priorities
82+
83+
The handlers with wildcards have the lowest priority, so if you have a specific handler for an event name, it will be called before the wildcard handler.
84+
85+
The wildcard handler will be called if there is no specific handler for the event name. And the wildcard matches the pattern.
86+
87+
General conditions for handler priority are:
88+
- fixed words has priority over wildcard
89+
- wildcard with * has priority over wildcard with #
90+
- wildcard with # has the lowest priority
91+
92+
The next code will help you to avoid unexpected behaviors, which indicates you the handler that will be called.
93+
```java
94+
public static void main(String[] args) {
95+
Set<String> names = Set.of("prefix.*.*", "prefix.*.#");
96+
String target = "prefix.middle.suffix";
97+
String handler = new KeyMatcher().match(names, target);
98+
System.out.println(handler);
99+
}
100+
```
101+
102+
## Example
103+
104+
You can see a real example at [samples/async/async-receiver-responder](https://github.com/reactive-commons/reactive-commons-java/tree/master/samples/async/async-receiver-responder)

docs/docs/reactive-commons/6-handling-domain-events.md

Lines changed: 1 addition & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -60,80 +60,4 @@ public class EventsHandler {
6060
return Mono.empty();
6161
}
6262
}
63-
```
64-
65-
### Wildcards
66-
67-
You may need to listen variable event names that have the same structure, in that case you have the method `handleDynamicEvents` in the `HandlerRegistry`, so you can specfy a pattern with '*' wildcard, it does not creates a binding in the broker, but allows that you do it dynamically through a `DynamicRegistry` class.
68-
69-
#### DynamicRegistry API
70-
71-
```java
72-
public interface DynamicRegistry {
73-
74-
Mono<Void> startListeningEvent(String eventName);
75-
76-
Mono<Void> stopListeningEvent(String eventName);
77-
78-
//... other definitions for queries
79-
80-
}
81-
```
82-
83-
To start listening a new event dynamically at runtime, you should inject and call a method of the DynamicReggistry, for example:
84-
85-
```java
86-
@Component
87-
@AllArgsConstructor
88-
public class DynamicSubscriber {
89-
private final DynamicRegistry registry;
90-
91-
public Mono<Void> listenNewEvent(String eventName) {
92-
return registry.startListeningEvent(eventName);
93-
}
94-
}
95-
```
96-
97-
The conditions for a success dynamic registry functionality are:
98-
99-
- You should handle dynamic events with specific wildcard
100-
101-
```java
102-
@Configuration
103-
public class HandlerRegistryConfiguration {
104-
105-
@Bean
106-
public HandlerRegistry handlerRegistry(EventsHandler events) {
107-
return HandlerRegistry.register()
108-
.handleDynamicEvents("purchase.*", events::handleEventA, Object.class/*change for proper model*/);
109-
}
110-
}
111-
```
112-
113-
- Start a listener dynamically through
114-
115-
```java
116-
registry.startListeningEvent("purchase.cancelled");
117-
```
118-
119-
You also can listen with * wildcard or # wildcard, the * wildcard is for a single word and # wildcard is for multiple words, for example:
120-
121-
`animals.*` will listen to `animals.dog`, `animals.cat`, `animals.bird`, etc.
122-
`animals.#` will listen to `animals.dog`, `animals.dog.bark`, `animals.cat`, `animals.cat.meow`, etc.
123-
124-
```java
125-
@Configuration
126-
public class HandlerRegistryConfiguration {
127-
128-
@Bean
129-
public HandlerRegistry handlerRegistry(EventsHandler events) {
130-
return HandlerRegistry.register()
131-
.listenEvent("animals.*", events::handleEventA, Object.class/*change for proper model*/)
132-
.listenEvent("pets.#.any", events::handleEventA, Object.class/*change for proper model*/);
133-
}
134-
}
135-
```
136-
137-
## Example
138-
139-
You can see a real example at [samples/async/async-receiver-responder](https://github.com/reactive-commons/reactive-commons-java/tree/master/samples/async/async-receiver-responder)
63+
```

0 commit comments

Comments
 (0)