|
| 1 | +# RabbitMQ `MessageBroker` for MATLAB Production Server |
| 2 | + |
| 3 | +## Architecture |
| 4 | +`MessageBroker`, is essentially a RabbitMQ (AMQP) Consumer which can receive |
| 5 | +messages from a RabbitMQ Server which it then passes along as input to a |
| 6 | +function deployed ot MATLAB Production Server. The MATLAB function is assumed to |
| 7 | +have exactly one input which is the message as character array. |
| 8 | + |
| 9 | +```mermaid |
| 10 | +flowchart |
| 11 | + client(Message Producer) -- publish message --> server[(RabbitMQ Server)]-- deliver message --> MessageBroker[MessageBroker] --"call with message as input"--> mps(MATLAB Production Server) |
| 12 | + MessageBroker -. subscribe .-> server |
| 13 | +``` |
| 14 | + |
| 15 | +As RabbitMQ supports various protocols (AMQP as native protocol but also MQTT |
| 16 | +and STOMP as plugins), the Message Producer can be any client supporting any of |
| 17 | +those protocols. |
| 18 | + |
| 19 | +## Message Datatype |
| 20 | +RabbitMQ messages _in general_ are simply raw bytes, this package implicitly |
| 21 | +assumes however that all messages are UTF-8 encoded strings. Consider encoding |
| 22 | +your messages in JSON format if "more complex" data structures need to be |
| 23 | +represented in the messages. On the MATLAB end the `jsondecode` function can be |
| 24 | +used to parse the JSON string into a MATLAB structure. |
| 25 | + |
| 26 | +## Dataflow |
| 27 | +A full workflow with this package could look like the following: |
| 28 | + |
| 29 | +```mermaid |
| 30 | +sequenceDiagram |
| 31 | + autonumber |
| 32 | + participant MessageSender |
| 33 | + participant RabbitMQ Server |
| 34 | + participant MessageBroker |
| 35 | + participant MATLAB Production Server |
| 36 | + note over MessageSender,MATLAB Production Server: MessageBroker Startup |
| 37 | + MessageBroker-->>RabbitMQ Server: subscribes |
| 38 | + note over MessageSender,MATLAB Production Server: For each message/request sent by MessageSender |
| 39 | + opt |
| 40 | + MessageSender-->>RabbitMQ Server: binds |
| 41 | + end |
| 42 | + MessageSender->>RabbitMQ Server: message |
| 43 | + RabbitMQ Server->>+MessageBroker: message |
| 44 | + MessageBroker->>+MATLAB Production Server: message |
| 45 | + opt |
| 46 | + MATLAB Production Server->>-RabbitMQ Server: reply |
| 47 | + deactivate MessageBroker |
| 48 | + RabbitMQ Server->>MessageSender: reply |
| 49 | + end |
| 50 | +``` |
| 51 | + |
| 52 | +1. Upon startup `MessageBroker` connects to the configured RabbitMQ Server and |
| 53 | + subscribes to the specified `queue` on the specified `exchange` with |
| 54 | + specified `routingkey`. |
| 55 | + |
| 56 | +2. If a MessageSender expects a reply of the function deployed to MATLAB |
| 57 | + Production Server through RabbitMQ, it first subscribes to the RabbitMQ |
| 58 | + server as well, if using the same `queue` on the same `exchange` make sure to |
| 59 | + use a different `routingkey` (to avoid infinite loops where the response |
| 60 | + would trigger another MATLAB Production Server call). |
| 61 | + |
| 62 | +3. The MessageSender (this can literally be the `MessageSender` example client |
| 63 | + included in this package or any other RabbitMQ Client) sends a message with a |
| 64 | + `routingkey` to a `queue` on the RabbitMQ Server. |
| 65 | + |
| 66 | +4. If the `queue` and `routingkey` match the ones `MessageBroker` has subscribed |
| 67 | + to, the RabbitMQ Server delivers to message to `MessageBroker`. |
| 68 | + |
| 69 | +5. `MessageBroker` uses MATLAB Production Server Java client to call the |
| 70 | + specified `function` in the specified `archive` with the message as input. |
| 71 | + MATLAB Production Server will then process this request. If the package is |
| 72 | + used to simply trigger a function call without outputs the flow ends here. |
| 73 | + |
| 74 | +6. If the MATLAB code needs to return an output to the client, the MATLAB code |
| 75 | + can use `rabbitmq.Producer` to send a message with the `routingkey` the |
| 76 | + client is bound to, to the RabbitMQ Server. |
| 77 | + |
| 78 | + > Note: this bypasses `MessageBroker`. `MessageBroker` does not do anything |
| 79 | + > with the "MATLAB style output" of the function deployed to MATLAB |
| 80 | + > Production Server. The MATLAB code deployed to MATLAB Production Server |
| 81 | + > has to explicitly use `rabbitmq.Producer` in the MATLAB code if a reply is |
| 82 | + > to be send over RabbitMQ. |
| 83 | +
|
| 84 | +7. If the `routingkey`, `queue` and `exchange` match the one the client has |
| 85 | + subscribed to, the RabbitMQ server will deliver the reply to the client. |
| 86 | + |
| 87 | +## Installation |
| 88 | +### Building the Java package |
| 89 | +Refer to the [Getting Started Section in |
| 90 | +README.md](../README.md#build-rabbitmq-matlab-java-client-package) for |
| 91 | +instructions on building the required JAR-file. |
| 92 | + |
| 93 | +### Further configuration and testing the setup |
| 94 | + |
| 95 | +1. Before continuing it is good to verify that the RabbitMQ Server is up and |
| 96 | +running correctly and can be accessed, for example by accessing the Web Admin |
| 97 | +console which typically runs on port 15672, so for a local server check |
| 98 | +http://localhost:15672/. |
| 99 | + |
| 100 | + > Please see the [RabbitMQ Authentication, Authorization, Access Control |
| 101 | + > documentation](https://www.rabbitmq.com/access-control.html) on how to |
| 102 | + > configure credentials for remote access, TLS support, authentication, etc. |
| 103 | + |
| 104 | +2. For an initial test, MATLAB Compiler SDK's MATLAB Production Server testing |
| 105 | + interface can be used rather than an actual MATLAB Production Server |
| 106 | + instance running compiled CTF archives: |
| 107 | + |
| 108 | + 1. In MATLAB start the `Production Server Compiler` App. |
| 109 | + 2. Enter `demo` as archive name. |
| 110 | + 3. Add `Software/MATLAB/examples/MPSreceive.m` as exported function. |
| 111 | + 4. Click `Test Client`. |
| 112 | + 5. Click `Start` to start the test server. |
| 113 | + |
| 114 | +3. Open `Software/Java/RabbitMQClient/src/main/resources/mps.yaml` and update |
| 115 | +the options to match your configuration. |
| 116 | + |
| 117 | + ```yaml |
| 118 | + # MATLAB Production Server connection properties |
| 119 | + mps: |
| 120 | + protocol: http # Protocol used by the MPS Instance |
| 121 | + host: localhost # Hostname or IP of the MPS Instance |
| 122 | + port: 9910 # Port the MPS Instance runs on |
| 123 | + archive: demo # Name of the CTF containing the function which |
| 124 | + # is to be called on MPS when a message received |
| 125 | + function: MPSreceive # Function inside the archive which is to be called |
| 126 | + timeoutms: 120000 # Timeout on the request to MATLAB Production Server |
| 127 | + # MessageBroker will log an error if the request |
| 128 | + # to MATLAB Production Server did not complete within |
| 129 | + # this time |
| 130 | + |
| 131 | + # Messaging connection and routing properties |
| 132 | + messageQueue: |
| 133 | + queueName: RabbitMQ # Name of the Queue on RabbitMQ Server |
| 134 | + host: localhost # Hostname or IP of the RabbitMQ Server |
| 135 | + port: 5672 # Port the RabbitMQ Server runs on |
| 136 | + virtualhost: / # RabbitMQ Virtual Host |
| 137 | + credentials: |
| 138 | + username: guest # RabbitMQ username |
| 139 | + password: guest # RabbitMQ password |
| 140 | + exchange: amq.topic # Exchange to work with on RabbitMQ |
| 141 | + routingkey: test-topic # Routing key to subscribe to |
| 142 | + ``` |
| 143 | + |
| 144 | + If indeed working with the MATLAB Compiler SDK MATLAB Production Server testing |
| 145 | + interface on your local machine configured as described in step 4, the `MATLAB |
| 146 | + Production Server connection properties` settings should be correct already. |
| 147 | + |
| 148 | +4. To verify it is possible to successfully send a message to the RabbitMQ |
| 149 | +Server using this configuration, the `MessageSender` application can be used. It |
| 150 | +can be started using `MessageSenderStartup.bat` on Windows or using mvn on any |
| 151 | +system: |
| 152 | + |
| 153 | + ``` |
| 154 | + mvn exec:java -Dexec.mainClass=com.mathworks.messaging.MessageSender -Dexec.args="src/main/resources/mps.yaml" |
| 155 | + ``` |
| 156 | + |
| 157 | + In the client enter a message and routingkey, then in the RabbitMQ Admin Web Console |
| 158 | + verify that indeed a message was received on the configured `queue`. (Ctrl+C can be |
| 159 | + used to stop the application). |
| 160 | + |
| 161 | +5. To complete the workflow, start `MessageBroker` by running |
| 162 | +`MessageBrokerStartup.bat` on Windows or alternatively run it using mvn: |
| 163 | + |
| 164 | + ``` |
| 165 | + mvn exec:java -Dexec.mainClass=com.mathworks.messaging.MessageBroker -Dexec.args="src/main/resources/mps.yaml" |
| 166 | + ``` |
| 167 | + |
| 168 | + This will receive messages from the message queue and then forward these to MATLAB |
| 169 | + Production Server to invoke the designated MATLAB `function`. The consumer will keep |
| 170 | + running, waiting for messages (Use Ctrl+C to stop the application). |
| 171 | + |
| 172 | +6. Now when using `MessageSender` to send a message with the correct |
| 173 | + `routingkey` it should be received by `MessageBroker` which should then call |
| 174 | + the MATLAB Production Server (test) server. If indeed working with the test |
| 175 | + server inside MATLAB, the message should be displayed in the MATLAB Command |
| 176 | + Window. |
| 177 | + |
| 178 | +[//]: # (Copyright 2022 The MathWorks, Inc.) |
0 commit comments