| At line 6 changed 1 line. |
| In the course of working on tooling for Fuji we will eventually come (well, in fact we're already there) to the necessity of implementing some sort of message tracing functionality. This should satisfy four major tasks that the user will be able to perform from the tooling: |
| In the course of working on tooling for Fuji we will eventually come (well, in fact we're already there) to the necessity of implementing some sort of message tracing functionality. It should satisfy several major tasks that the user will be able to perform from the tooling (__note__: the changes described below are intended to provide the required infrastructure, not the complete "feature" providing support for these tasks. The latter is expected to be developed separately by the tooling engineers, or any third party): |
| At line 11 added 1 line. |
| * "Audit". The tooling application might want to record the messages as they flow through the system, providing a facility for a later retrieval. I would be beneficial to be able to reconstruct not only the path of a single message, but also the messages that are somehow related to the message in question. E.g. messages that resulted from this message having been processed by a certain component, or vice versa, messages that served as the "input" for the current one. |
| At line 12 changed 1 line. |
| A checkpoint is a certain location on the message flow that we consider to be interesting to inspect from the message state standpoint. Currently the checkpoints are located around each service present in the message flow, i.e. right after the message left the service and entered the NMR and right before the message leaves the NME and enters the service. Additionally we account for "raw" messages, that is, binding components (where applicable) have additional checkpoints: right after the binding received a message from the outside world (in binding-specific format) and right before the binding is about to send out a message to the OW (again in binding-specific format). A good example of these would be a an incoming or outgoing HTTP/SOAP request, contents of the file read by the file binding, JDBC result set of a database query, etc. |
| A checkpoint is a certain location on the message flow that we consider to be interesting to inspect from the message state standpoint. The standard checkpoints are located around each service present in the message flow, i.e. right after the message left the service and entered the NMR and right before the message leaves the NMR and enters the service. Additionally we account for "raw" messages, that is, binding components (where applicable) have additional checkpoints: right after the binding received a message from the outside world (in binding-specific format) and right before the binding is about to send out a message to the OW (again in binding-specific format). A good example of these would be a an incoming or outgoing HTTP/SOAP request, contents of the file read by the file binding, JDBC result set of a database query, etc. |
| Non-standard checkpoints are provided by the participating services and are component-type specific. E.g. a File BC (if equipped with an encoder) might want to provide access to the message as it was read from the filesystem, then as it was processed by an encoder and transformed into XML, etc. |
| At line 26 changed 1 line. |
| * There should be a way to "catch" faults and errors, as they appear, |
| ** receive events about messages only at specific checkpoints to be able to monitor, for example, only the encoding step, |
| ** receive event only about specific types of messages: normal or fault, this would allow building some sort of maintenance solutions, allowing to "fix" faults as they occur and direct the fixed messages further along wire. |
| * There should be a way to "catch" faults and errors, as they appear. Additionally there should be an option to "fix" faults (see above). |
| At line 40 changed 1 line. |
| * Provides the functionality which enabled the tooling applications to |
| * Provides the functionality which enables the tooling applications to |
| At line 54 changed 1 line. |
| void attachListener(MessagesListener listener, MessagesFilter filter); |
| void attachListener( |
| MessagesListener listener, |
| MessagesFilter filter); |
| At line 63 changed 1 line. |
| void removeListener(MessagesListener listener); |
| void removeListener( |
| MessagesListener listener); |
| At line 71 changed 1 line. |
| * injected before the service, or after it. |
| * injected before the service, after it, or at some service-specific |
| * checkpoint. |
| At line 83 added 1 line. |
| * @param type type of the message which will be injected. |
| At line 85 added 3 lines. |
| * @param relations identifiers of the messages that are related to the |
| * current one. The keys in this map are relation types, the list in |
| * the map value lists the message identifiers. |
| At line 82 changed 1 line. |
| void sendMessage(QName service, MessageLocation location, Object message); |
| void sendMessage( |
| QName service, |
| String location, |
| String type, |
| Object message, |
| Map<String, List<String>> relations); |
| /** |
| * Standard checkpoint, identifying the location right before a message |
| * leaves the NMR and enters the service. |
| */ |
| public static final String INBOUND = "inbound"; // NOI18N |
| /** |
| * Standard checkpoint, identifying the location right after a message |
| * left the service and entered the NMR. |
| */ |
| public static final String OUTBOUND = "outbound"; // NOI18N |
| /** |
| * Standard message type, indicating that the message is a normal one. |
| */ |
| public static final String NORMAL = "normal"; // NOI18N |
| /** |
| * Standard message type, indicating that the message is a fault. |
| */ |
| public static final String FAULT = "fault"; // NOI18N |
| At line 90 changed 9 lines. |
| /** |
| * Invoked by the runtime when an event occurs, that is accepted by the |
| * filter which was supplied at listener attach time. |
| * |
| * @param service service that generated the event. |
| * @param location message location relative to the service. |
| * @param message the message object. |
| */ |
| void onMessage(QName service, MessageLocation location, Object message); |
| /** |
| * Invoked by the runtime when an event occurs, that is accepted by the |
| * filter which was supplied at listener attach time. |
| * |
| * @param service service that generated the event. |
| * @param location message location relative to the service. |
| * @param type type of the message. |
| * @param message the message object. |
| * @param relations identifiers of the messages that are related to the |
| * current one. The keys in this map are relation types, the list in |
| * the map value lists the message identifiers. |
| */ |
| void onMessage( |
| QName service, |
| String location, |
| String type, |
| Object message, |
| Map<String, List<String>> relations); |
| At line 161 added 1 line. |
| * @param type type of the message. |
| At line 163 added 3 lines. |
| * @param relations identifiers of the messages that are related to the |
| * current one. The keys in this map are relation types, the list in |
| * the map value lists the message identifiers. |
| At line 117 changed 1 line. |
| boolean accept(QName service, MessageLocation location, Object message); |
| boolean accept( |
| QName service, |
| String location, |
| String type, |
| Object message, |
| Map<String, List<String>> relations); |
| At line 119 removed 16 lines. |
| /** |
| * Possible location of a message with regard to a service unit. So far |
| * only two locations are possible: right before the service and right |
| * after it. |
| */ |
| public enum MessageLocation { |
| /** |
| * The message is about to leave the NMR and enter the service code. |
| */ |
| INBOUND, |
| /** |
| * The message has just left the service code and entered the NMR. |
| */ |
| OUTBOUND |
| } |
| At line 137 changed 1 line. |
| The API oriented towards the components is mucho sumple. It could be a single method in the {{MessagingService}}, or in a separate class: |
| The API oriented towards the components is very simple. It could be a single method in the {{MessagingService}}, or in a separate class: |
| At line 186 added 1 line. |
| * @param type type of the message. |
| At line 188 added 3 lines. |
| * @param relations identifiers of the messages that are related to the |
| * current one. The keys in this map are relation types, the list in |
| * the map value lists the message identifiers. |
| At line 147 changed 1 line. |
| void notifyListeners(QName service, MessageLocation location, Object message); |
| void notifyListeners( |
| QName service, |
| MessageLocation location, |
| String type, |
| Object message, |
| Map<String, List<String>> relations); |
| At line 160 changed 1 line. |
| !! Things to consider in the future |
| * Debugging of the component code itself. For the components whose "code" is exposed (e.g. BPEL, JRuby) it would be nice to be able to debug this code as well, thus introducing another action alongside with "Step by Message": "Step Into". We'd need a more or less common API for that as well, if we ever decide to pursue this direction. It is already partially possible with the service-specific checkpoints, but the overall API is too message-centric to be useful enough for this task. However, given that the message object is defined quite generically, it should be possible to pass in the internal service execution context. |
| At line 162 removed 2 lines. |
| * Debugging of the component code itself. For the components whose "code" is exposed (e.g. BPEL, JRuby) it would be nice to be able to debug this code as well, thus introducing another action alongside with "Step by Message": "Step Into". We'd need a more or less common API for that as well, if we ever decide to pursue this direction. |