Wiki source code of crashcourse-messaging-asynchronous-routing
Hide last authors
| author | version | line-number | content |
|---|---|---|---|
| |
1.1 | 1 | {{html wiki="true"}} |
| 2 | <div class="ez-academy"> | ||
| 3 | <div class="ez-academy_body"> | ||
| 4 | |||
| 5 | <div class="doc"> | ||
| 6 | |||
| 7 | |||
| 8 | |||
| 9 | = Asynchronous Routing = | ||
| 10 | |||
| 11 | In this microlearning, we will explain the basics of asynchronous routing that plays a vital role in the distribution of messages within the five-layer model of messaging. | ||
| 12 | |||
| 13 | Should you have any questions, please contact academy@emagiz.com. | ||
| 14 | |||
| 15 | * Last update: February 25th, 2021 | ||
| 16 | * Required reading time: 7 minutes | ||
| 17 | |||
| 18 | == 1. Prerequisites == | ||
| 19 | |||
| 20 | * Basic knowledge of the eMagiz platform | ||
| 21 | |||
| 22 | == 2. Key concepts == | ||
| 23 | |||
| 24 | This microlearning centers around asynchronous routing for messaging flows in eMagiz. | ||
| 25 | By asynchronous routing we mean: The process that routes messages that it receives to the correct outbound queue based on some metadata. | ||
| 26 | |||
| 27 | The asynchronous routing has three relevant parts: | ||
| 28 | |||
| 29 | * All asynchronous onramps send their data to the routing | ||
| 30 | * Based on a decision made within the routing the message is routed to one or more offramp queues | ||
| 31 | * Each offramp queue will receive data based on the decision unless you add another filter before the messages are sent to the offramp queue | ||
| 32 | |||
| 33 | |||
| 34 | |||
| 35 | == 3. Asynchronous routing == | ||
| 36 | |||
| 37 | Asynchronous routing plays a crucial role in the distribution of messages it receives to one or more offramps. | ||
| 38 | |||
| 39 | The asynchronous routing has three relevant parts: | ||
| 40 | |||
| 41 | * All asynchronous onramps send their data to the routing | ||
| 42 | * Based on a decision made within the routing the message is routed to one or more offramp queues | ||
| 43 | * Each offramp queue will receive data based on the decision unless you add another filter before the messages are sent to the offramp queue | ||
| 44 | |||
| 45 | === 3.1 Make a decision === | ||
| 46 | |||
| 47 | In asynchronous routing, you can build your decision model on which the routing needs to make the decision. | ||
| 48 | |||
| 49 | The best practice for setting up your asynchronous routing process is to use one SpEL expression that determines to which offramp queues a messages needs to be routed. | ||
| 50 | The SpEL expression looks as follows: | ||
| 51 | |||
| 52 | headers.{technicalnameofproject}\_targetSystem.split(',').![#this.trim()+#root.headers.{technicalnameofproject}_messageType] | ||
| 53 | |||
| 54 | This SpEL expression does the following things: | ||
| 55 | |||
| 56 | 1. It looks for the header called {technicalnameofproject}\_targetSystem and will split each entry based on the separator (a comma) | ||
| 57 | 2. It will trim the result of this split and combine it the value in the header called {technicalnameofproject}\_messageType | ||
| 58 | 3. For every unique combination it will search to a pre-configured list to see to which channel the message should be sent | ||
| 59 | |||
| 60 | In the standard router component this will look as follows: | ||
| 61 | |||
| 62 | <p align="center">[[image:crashcourse-messaging-asynchronous-routing--routing-decision.png||]]</p> | ||
| 63 | |||
| 64 | In this simple case, we only have one channel as a result because all routings start simple. | ||
| 65 | The moment you add new offramps to your project you need to add the new entry(s) to this list. | ||
| 66 | Doing so is easy when you are in Start Editing Mode. Simply open the router component and select the button New Mapping | ||
| 67 | |||
| 68 | <p align="center">[[image:crashcourse-messaging-asynchronous-routing--new-value-mapping.png||]]</p> | ||
| 69 | |||
| 70 | In here you fill in the correct unique combination of a target system and the message type and select the channel you want to route the message to. | ||
| 71 | When you are satisfied you can press Save and the new entry will be registered in eMagiz. | ||
| 72 | |||
| 73 | Don't forget to make a new version and deploy it to actualize your changes. | ||
| 74 | |||
| 75 | === 3.2 Control output === | ||
| 76 | |||
| 77 | As the asynchronous plays a role in routing messages between all asynchronous flows in a | ||
| 78 | the messaging solution you can imagine that making changes does not need to happen lightly. | ||
| 79 | The other aspect is that when multiple projects are being built at the same time the asynchronous routing | ||
| 80 | will house a multitude of changes that need to go to Acceptance or Production at the same time. | ||
| 81 | |||
| 82 | One control mechanism we consider a best practice to guard yourself against those risks is to add a filter | ||
| 83 | before data is placed on the offramp queue. | ||
| 84 | By doing this consistently you can control when a specific offramp can receive data on any environment. | ||
| 85 | In other words, when a certain system is not ready yet to receive data on Acceptance or Production but is ready on Test | ||
| 86 | you can control this behavior with this solution. | ||
| 87 | |||
| 88 | Below you see how this will look on flow level. | ||
| 89 | |||
| 90 | <p align="center">[[image:crashcourse-messaging-asynchronous-routing--filter-construction.png||]]</p> | ||
| 91 | |||
| 92 | When we zoom in on the filter component we see a simple SpEL expression that checks the value of a certain property. | ||
| 93 | When the value of the property is true the message can pass. If the value of the property is any other value the message will be halted. | ||
| 94 | The best practice would be to work with false to get clarity on what the intended use of the property value is. | ||
| 95 | |||
| 96 | <p align="center">[[image:crashcourse-messaging-asynchronous-routing--filter-configuration.png||]]</p> | ||
| 97 | |||
| 98 | === 3.4 Step by step guide === | ||
| 99 | |||
| 100 | Furthermore, as a best practice, we give you a short guide that you can add to your asynchronous routing as annotations | ||
| 101 | to ensure that you always know what you need to do to make this a reality. | ||
| 102 | |||
| 103 | Steps to follow when adding an integration to the routing Part I: | ||
| 104 | |||
| 105 | 1. Add a header in the onramp named {technicalnameofproject}\_targetSystem (if this is not done yet) | ||
| 106 | 2. Fill this header with a value that should be defined as a property (naming convention = systemname.messagetype.targetsystems) | ||
| 107 | 3. This property should be created in Test, Accp, and Prod and filled with all target systems for a certain message type (notation = systemname1,systemname2,systemname3) | ||
| 108 | 4. In the routing a standard router should be used as the first building block after receiving the input. | ||
| 109 | |||
| 110 | Part II | ||
| 111 | |||
| 112 | 5. In this standard router a SpelExpression has to be defined **once** that concatenates the following headers: {technicalnameofproject}\_targetSystem and {technicalnameofproject}\_messageType. | ||
| 113 | 6. For every unique combination there is a value that should be specified alongside the channel on which to put the message (this should be a channel that ultimately leads to the correct offramp queue) | ||
| 114 | 7. For every channel that leads to a JMS outbound channel adapter a filter needs to be added to make sure that each output option can be turned on or off easily. | ||
| 115 | This to prevent that messages are sent to a system that does not expect them then | ||
| 116 | 8 This filter should look like this: '${routing.monitor.detorem.enabled}' == 'true'. | ||
| 117 | The naming convention of said property is routing.targetsystem.messagetype.enabled. | ||
| 118 | |||
| 119 | === 3.5 The result === | ||
| 120 | |||
| 121 | The result of setting up your asynchronous routing in this manner | ||
| 122 | is that you have one single point of entry, one single piece of decision logic, and a way to control the output per specific output channel. | ||
| 123 | |||
| 124 | <p align="center">[[image:crashcourse-messaging-asynchronous-routing--simple-asynchronous-routing-example.png||]]</p> | ||
| 125 | |||
| 126 | ===== Practice ===== | ||
| 127 | |||
| 128 | == 4. Assignment == | ||
| 129 | |||
| 130 | Build your asynchronous routing based on the best practice for one of the offramps that are available within your (Academy) project. | ||
| 131 | This assignment can be completed with the help of your (Academy) project you have created/used in the previous assignment. | ||
| 132 | |||
| 133 | == 5. Key takeaways == | ||
| 134 | |||
| 135 | * Use one component that decides to route messages to certain channels | ||
| 136 | * Control the output with a filter to prevent data to be sent to a queue too early | ||
| 137 | * Use the annotations to write down the step by step guide within your asynchronous routing | ||
| 138 | |||
| 139 | |||
| 140 | |||
| 141 | == 6. Suggested Additional Readings == | ||
| 142 | |||
| 143 | If you are interested in this topic and want more information on it please read the help text provided by eMagiz. | ||
| 144 | |||
| 145 | == 7. Silent demonstration video == | ||
| 146 | |||
| 147 | This video demonstrates how you could have handled the assignment and gives you some context on what you have just learned. | ||
| 148 | |||
| 149 | <iframe width="1280" height="720" src="../../vid/microlearning/crashcourse-messaging-asynchronous-routing.mp4" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> | ||
| 150 | |||
| 151 | </div> | ||
| 152 | </div> | ||
| 153 | </div> | ||
| 154 | |||
| 155 | {{/html}} |