- Index
- » Saddle Forum
- » Development
- » Development News
Development News
Development News
Here we like to inform you about the current development activities for Saddle and introduce you new ideas concerning architecture, technics and features that we intend to implement.
You are free to post comments and contribute your ideas.
Feb-03-11 14:59:17
Re: Development News
Current status:
Since Saddle went public last December, many improvements have been added. A lot of bugs have been squashed and many subtle improvements have been added that make Saddle smother and allow are more fluent and intuitive work with this tool. Here we have to send a big "Thank You" to all the users, who provided numereous bug reports and improvement ideas. We really appreciate that!
Besides the bug fixing and smaller improvements, also new features have been added like the support for Mule 3.1 and the different Mule Enterprise Editions (we had our focus only on the Community Edition before..) or the support for fixed length message parsing and generation to name a view.
Finally, the first tutorial has been created that introduces you to the work with Saddle and also to some of its advanced features. Further tutorials will follow.
We are currently preparing a new release version of Saddle and updating the documentation to reflect all changes.
After this release, we plan some larger changes in the Saddle architecture and its message handling layer that will lead to an even more flexible and convenient system.
I will elaborate on that in a follow-up post within the next days.
Besides this thread, you can always follow the current state of the development in "realtime" on our Trac system at SourceForge and by checking up the nightly builds, you will find in the download section.
Re: Development News
Message Mapping Enhancements
Today we would like to inform you about our new Message Mapper GUI.
In former builds of Saddle the message mappings where one single, large Java file, not easy to manage and probably way to much code if you only wanted to try this feature with some simple example.
Now the GUI has been rewritten, so that Saddle's automatically generated methods and the user's own code can be completely separated.
By default new mappings now open in a simple mode, only showing a small Java class with one method to implement. You can put your business logic inside this method, add custom methods and handle your messages as you need it.
If you, for whatever reason need direct access to the Saddle mapping basics or just want to have a look at what we are doing here, simply click the big black "X" in the toolbar to enable the expert mode. It will show the base class to your mapping in a second "tab". Everything from receiving the messages to triggering some channels and sending something out to mule will be automatically handled by Saddle in this second class. Also all of its methods are accessible in your code.
Another thought for the future is updatability of a custom mapping. If the user has his own Java file the basis can easily be updated by replacing one Java file if bugs are found or the base logic changes.
These changes should simplify your work with Saddle mappings and probably bring some more attention to the Saddle way of handling data.
If you find some bugs in our generated base class please let us know, so that we are able to include the fixes into later releases.
As always please report any bugs you encounter and we will try to fix them as soon as possible.
Best regards,
The Saddle development team
Re: Development News
Say Goodbye to DOM!
So far, Saddle was using DOM (Document Object Model) for parsing data into the Saddle Message Templates and accessing the parsed data. This approach worked fine but came with some major drawbacks:
Performance
DOM is great for the purpose it has been designed but for representing a message structure particular requirement have to be met. DOM does not provide the possibility to store direct references to other Nodes within a Node object. Next, the DOM sturcture maintains a lot of elements that are not required for representing a message structure. Finally, for each instance of a message structure, the XML template has to be parsed to a DOM tree, which is very expensive as there is no fast clone function.
Flexibility
Different data types cannot be stored in their native format but have to be converted to strings. This is especially problematic for the treatment of binary data as it has to be encoded (e.g. Base64). Also, all nodes at a certain level of a branch are siblings. There is no differentiation between instances of the same Node and real siblings (=other nodes at the same level). Attributes cannot be shared between instances of the same Node, even if they are identical.
Usability
As the actual Node objects cannot be altered without changing the DOM library, all operations on them have to addressed by using an external API. Furthermore, this API was not consistent.
Footprint
for each instance of a message field, several objects are created, which results in a significant memory occupation.
The new Saddle Message Layer is a custom implementation with a sgnificantly higher performance, lower footprint and higher flexibility and usability:
A message template is now only parsed once into a Message Factory instance. Each time a transformer or a Mapping needs an empty instance, simply the produce() method of the MessageFactory is called, which clones the Structure that had been created from the message template.
Field attributes are identical for each instance of the same field and also for fields of different message instances. Thus, they are only created once and simply referenced by each field or instance, they decribe. That lowers the footprint and increases processing speed at the same time.
Each field comes now with a set of functions for accessing and modifying its content that can be called directly. In the past, this calls had to be made from the external API.
E.g. a call for getting the path of the parent of a certain field looked with the old Message Layer like:
Code:
getMessageInstance().getPath(getMessageInstance().getParent(currentField));
With the new Message Layer this call would be simply:
Code:
currentField.getParent().getPath();
This approach is more comfortable to use and helped us to obtain much cleaner and easier understanding code for our integration projects.
All concerned components like custom transformers, connectors, and the Message Mapper Module have been adapted to the new Message Layer.
What will you have to change?
If you are using the Saddle Message Layer, you have to adapt the calls to the API in your mappings to the new format. But this should be straight forward and easy to accomplish as the function names remained mainly the same.
The new Message Layer will be one of the features of the v0.8 release of Saddle. You can already test it by downloading the latest nightly build.
Feel free to post any comments, questions, or remarks.
The Saddle Development Team
Re: Development News
Easy Database Support for Saddle!
Great news: Saddle is now able to connect to databases directly inside your mapping logic. You may now read and write data to your database from within the business logic of your mappings. Saddle allows this by using the same triggering infrastructure like when triggering files from the filesystem. The request method will block and return as soon as the results of the select are available.
As you can see in example shown in the following picture, this allows you to start your mapping with some input data and later request some additional data from the database. Once the requestMessage() call returns, the results will be available at the channel and you can directly continue working with it. After working with all the data you might want to send some data out into another database. This can also be done without interrupting your logic by simply using the sendMessage() method as if you were sending some file to the file system. At the end you can do some more work and then return the final results of the mapping, for example as a file. The data for the statements as well as the statement results are as usual easily and well structured accessible via the Saddle message templates.
You will not have to worry about any synchronization issues or listeners and can concentrate on your business logic alone. The described features do not bypass the Mule configuration logic. This means everything is flexible and configurable instead of being hard coded in the business logic of a service component.
All these features will be present in Saddle version 0.8 and are already present in the current nightly builds. We will also build some tutorial(s), explaining the new functionality in more detail.
Re: Development News
Release of Saddle v0.8 is immediate
We are currently debugging Saddle v0.8. You can follow the debugging by viewing the status of the bug reports in the Saddle bug tracker.
You can help us with that by downloading the latest nightly build in the download section and reporting any bugs you encounter.
Documentation and the tutorial have already been updated to the new version. Right after the release further tutorials will be created explaining the new project structure as well as advanced features like database-handling or HL7 support.
You can find information about the new features of the upcoming version in the blog and also in the previous posts.
The next features that will be implemented is the support for flows and an overhaul of the Saddle monitoring functionality.
We will provide you more details about that in subsequent posts.
Re: Development News
Too fast for Mule?
We currently have a problem we would like to share with you.
We have the following workflow:
It's configuration looks like this:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<mule xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tool http://www.springframework.org/schema/tool/spring-tool-3.0.xsd
http://cxf.apache.org/core http://cxf.apache.org/core/core.xsd
http://cxf.apache.org/configuration/beans http://cxf.apache.org/configuration/beans/cxf-beans.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/3.1/mule.xsd
http://www.mulesoft.org/schema/mule/file http://www.mulesoft.org/schema/mule/file/3.1/mule-file.xsd
http://www.mulesoft.org/schema/mule/hl7 http://www.mulesoft.org/schema/mule/hl7/3.1/mule-hl7.xsd
http://www.mulesoft.org/schema/mule/management http://www.mulesoft.org/schema/mule/management/3.1/mule-management.xsd
http://www.mulesoft.org/schema/mule/tcp http://www.mulesoft.org/schema/mule/tcp/3.1/mule-tcp.xsd
http://www.mulesoft.org/schema/mule/vm http://www.mulesoft.org/schema/mule/vm/3.1/mule-vm.xsd
/schemas/saddle/saddleMule310Components/0.8 /schemas/saddle/saddleMule310Components/0.8/mule-saddle.xsd" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tcp="http://www.mulesoft.org/schema/mule/tcp" xmlns:vm="http://www.mulesoft.org/schema/mule/vm" xmlns:spring="http://www.springframework.org/schema/beans" xmlns:management="http://www.mulesoft.org/schema/mule/management" xmlns:hl7="http://www.mulesoft.org/schema/mule/hl7" xmlns:file="http://www.mulesoft.org/schema/mule/file" xmlns:saddle="/schemas/saddle/saddleMule310Components/0.8">
<model name="model">
<service name="CreateAckService">
<inbound>
<?WDPosition x="15" y="75" id="10221955" linkedTo="185223"?>
<hl7:inbound-endpoint name="ADTin" transformer-refs="AdtToMessage" responseTransformer-refs="MessageToAck" host="localhost" port="12345" exchange-pattern="request-response" responseTimeout="60000"/>
</inbound>
<?WDPosition x="289" y="65" id="14729515" linkedTo="32447140 7408716"?>
<component>
<prototype-object class="CreateAckService">
<property key="responsePath" value="vm://Component_1ReplyQueue"/>
<property key="endpointForADT_in" value="ADTin"/>
</prototype-object>
</component>
<outbound>
<?WDPosition x="451" y="65" id="32447140" linkedTo="788126"?>
<pass-through-router>
<?WDPosition x="806" y="65" id="18077060" linkedTo=""?>
<file:outbound-endpoint name="ArchiveHL7" transformer-refs="MessageToMixedstring" path="/home/matthias/testcase/out1" outputPattern="Appointment_#[function:count].xml"/>
</pass-through-router>
</outbound>
<async-reply>
<vm:inbound-endpoint name="Component_1ReplyEndpoint" path="Component_1ReplyQueue" exchange-pattern="one-way"/>
<single-async-reply-router/>
</async-reply>
</service>
</model>
<?WDPosition x="146" y="15" id="185223" linkedTo="14729515"?>
<saddle:mixedstring-to-message-transformer name="AdtToMessage" templatePath="ADT_A01"/>
<?WDPosition x="614" y="65" id="788126" linkedTo="18077060"?>
<saddle:message-to-mixedstring-transformer name="MessageToMixedstring"/>
<?WDPosition x="145" y="125" id="7408716" linkedTo="10221955"?>
<saddle:message-to-mixedstring-transformer name="MessageToAck"/>
<management:jmx-default-config/>
</mule>
And we try to send a response from inside the mapping by using the sendResponse() method which eventually uses context.dispatchEvent().
We recognized that the reply will not be delivered as it was unexpected. Mule displays the following log message:
Code:
org.mule.service.processor.ServiceAsyncRequestReplyRequestor: Unexpected message with id c9768d2f-d48a-11e0-8fb3-1d864b142e87 received. This message will be discarded.
Although the displayed correlation ID is the unique ID of the incoming message.
If we now slow down the transformer a bit (using Thread.sleep() to wait some milliseconds) and place it in the VM endpoint of the async reply router instead of using it as a response transformer we see that the reply arrives.
After some debugging we found out, that mule only stores the unique ID of the message awaiting a response after the service component has returned. This is too late for our approach as the reply should be sent while the component is still doing some work.
The last time we tested this and saw it working our transformers and message library have been much slower than they are now and it seems that they were just slow enough.
Now we've got another problem: we are apparently too fast for mule.
Probably we use Mule in a way that it is not supposed to be used, probably we found a bug here that should be reported and fixed.
We will try to report the issue to mule directly as we are really out of ideas of what we did wrong and will try to keep you informed here.
If you have any Idea on how we can solve our problem please let us know.
Best regards,
The Saddle Team
Edit: I just posted this into mule's forums. Let's hope this helps.
Sep-02-11 10:40:15
Re: Development News
Mule 3.2
We just added support for Mule 3.2 in the nightly builds. It should normally do the same than for 3.1 and there is still no support for new Mule 3 features like flows (but these will come as a next step after the release of Saddle 0.8)
So if you wanted to give Saddle a try but definitely wanted to use the latest Mule version it would be great if you could try it out now and give us some feedback in this forum.
There are also some new features like the possibility to define custom properties on endpoints or object factories and access to embedded scripts in scripting components and transformers.
Best regards,
The Saddle Team
Re: Development News
Bidirectional Communication & HL7
you might remember the issue we had with assigning a correlation id to a unique id, which has been explained a few posts above. The cause is that the unique ID of a message is only remembered when it left a service. Mule checks for the existence of a unique message id that is identical to the the corelation-id of the message sent to the response router. As the original message has not left the service at this point of time, no match is found. From our point of view this seems like an architectural bug of Mule as it prevents the access to a reply router of the same service.
Not wanting to modify the underlying logic to guarantee compatibility with all vanilla Mule versions, we decided to bypass this issue by using a pass-through service that is set before the actual service that has to send information back to an inbound channel.
This results in a slightly higher complexity of the resulting mule configuration file but is encapsulated in the GUI by the introduction of a new configuration element called ReplyComponent:
The ReplyComponent allows the creation of bidirectional configurations like the following, which are needed for e.g. HL7 communication:
Depending on the content of the retrived message, the service sends back an ACK to the sender and continues with the processing of the received message.
An inbound message is modified and sent to an outbound system. The response of the outbound system is also modified and sent back to the inbound system. In both examples, the external systems are connected via TCP/IP and the same connection is used for sending and receiving.
If you want to send data to an inbound channel from within a service, a simple function call in your mapping logic will do the job:
sendAsyncResponse(<ACKNOWLEDGEMENT MESSAGE>, <RECEIVED MESSAGE>);
The later nightly builds of Saddle (available in the download section) contain support for this. Tutorials describing how to implement these scenarios will be released with Saddle v0.8
Complete template libraries for all versions of HL7 v2.x, an acknowledgement-based protocol that is widely used in the healthcare sector, are now publicly available in the download section. The libraries contain predefined templates for all message types of the respective HL7 version. Please use these with the latest nightly builds.
Best regards,
The Saddle Team
Re: Development News
Flow development
After releasing Saddle 0.8 we instantly started to work on flow support. While doing this we recognized, that our current approach of building the configuration files would lead to very complicated and hard to maintain class structures.
This is why we are currently overhauling the way our configurations are built.
To determine what has to be done if one element is linked to another one Saddle uses a set of strategy classes that are associated to each category of elements (for example inbound endpoints or components) as normally all elements of one type behave in the same way. For a short overview on the design pattern see its page on Wikipedia.
However the old way of fixed allocation of one strategy to a certain type of object became more and more complicated to handle as we extended Saddle's functionality for example with the Reply Service in the component section. This lead us to thinking about a more flexible and easier to configure approach.
As we realized that our strategies would get even more complicated if we added flow support to them we started thinking about a better approach and came to the idea of a more flexible way of defining the palette and what has to be done for which element.
Our solution for these problems was to allow the configuration of the palette using an XML file for each Mule version. This would allow us to assign elements to categories that all use a default strategy, but also allow the definition of elements that needed a special strategy instead of the default one.
The XML approach gives everyone the possibility to tailor the palette to their needs. Categories can be reordered, renamed and new ones can easily be added.
As you can see in the image above the different strategies that are needed are now hierarchically organized. There are two abstract base classes, one for flow handling strategies and one for service handling strategies.
All strategy implementations are derived from these two classes, depending on whether they will handle services or flows. The abstract classes provide default functionality that is used through all Strategies and additional helper mtehods for specific types of elements have been placed into helper classes to prevent a code duplication there (see EndpointHelper and FilterHelper).
Some mule versions differ in the handling of configurations, for example mule 3.1 and onwards allow multiple outbound endpoints in an exception strategy. Such extra handling can now easily be implemented by deriving a new strategy class for mule 3.1 and add handling code for multiple outbound endpoints there whithout having to touch the existing classes. The new class will then be set in the XML file of the palette and will now be used automatically.
Saddle will determine whether to use a defined service or flow strategy based on the currently open workflow and the elements that should be linked.
This allows us to keep the old service support as the flow support starts to grow, without the one influencing the other.
We already started writing some strategies to support flows in Saddle and will continue to work on them for the next weeks. If you want to keep track of our progress feel free to try the latest nightly builds that will continuously be enhanced with more flow support. If you do this please keep in mind that the nightly builds are potentially unstable and might mess up your configuration files, so be sure to always keep a backup of your files.
Best regards,
The Saddle Team
- Index
- » Saddle Forum
- » Development
- » Development News
Board Info
- Board Stats:
- Total Topics:
- 49
- Total Polls:
- 0
- Total Posts:
- 329
- Total Posts Today:
- 2
- User Info:
- Total Users:
- 472
- Newest User:
- Anam
- Members Online:
- 1
- Guests Online:
- 5
- Most Active Users:
- mkutscheid, Ortwin, aartik, javega, tokoma1, lahvenai, gvsg_immo, matiuslim
- Online:
- mkutscheid
Forum Legend:
- Topic
- New
- Locked
- Sticky
- Active
- New/Active
- New/Locked
- New Sticky
- Locked/Active
- Active/Sticky
- Sticky/Locked
- Sticky/Active/Locked