I-Pascal v1.09 – an open source Object Pascal IDE plugin for IntelliJ IDEA

I-Pascal is a free IDE plugin for IntelliJ IDEA, which supports integration with Delphi and Free Pascal compilers. I-Pascal features include code completion, quick fixes, used units usage check, and refactoring. The plugin is compatible with IntelliJ IDEA Community Edition and Ultimate Edition from version 13.xx. I-Pascal v1.09 is the first version available with source code on Github.

Home page: http://www.siberika.com/siberika/ipascal.htm

Release notes: http://www.siberika.com/siberika/whatsnew.htm

Source code: https://github.com/casteng/i-pascal

 

Daraja Framework: commercial license

Daraja Framework is a HTTP service framework for Free Pascal and Delphi 2009 and newer.

Its source code is dual licensed under the GNU Affero General Public License Version 3 and a commercial license, which removes the requirements of the AGPL license. When the annual subscription is terminated, the license is still valid for unlimited time. Termination of the subscription only ends additional services such as the free (basic) support.

The commercial license also covers the RESTful extension of the framework. If you have any further questions about the commercial license for Daraja Framework, please contact Habarisoft.

daraja_logo_landscape_2016_3

Consume a JMS ObjectMessage with Habari Client for ActiveMQ

As a follow-up to the previous article about MapMessage exchange with Apache ActiveMQ, here is an example for an ObjectMessage, sent from a Java JMS client and consumed from a Delphi application.

Java (producer side)

The Java code creates a java.util.Properties instance, fills it with example data,, and sends it to the destination queue as a ObjectMessage. (Note that the class of the transferred must be serializable and must be in the ActiveMQ class path)

Destination dest = session.createQueue("Habari.ObjectMessage");
MessageProducer producer = session.createProducer(dest);

Properties l = new Properties();
l.put("date", new Date());
l.put("info", "hello world!");
msg.setObject(l);

producer.send(msg);

When this code completes, the JMS ObjectMessage instance will wait in the message broker queue for a consumer.

Delphi / Free Pascal (consumer side)

We want to receive the ObjectMessage as XML, so the header is:

transformation=jms-object-xml

Now the broker knows which serialization our client understands. ActiveMQ sends the ObjectMessage to our STOMP client as XML. The java.util.Properties instance contains a list of key-value pairs, which we have filled with two entries on the Java side. The first entry is a String (“hello world!”), stored under the key “info”, the second a java.util.Date instance stored under “date”. The client received this XML payload:

<properties>
  <property name="info" value="hello world!"/>
  <property name="date" value="Mon Jan 09 17:22:18 CET 2017"/>
</properties>

The Delphi / Free Pascal example client receives the message and uses a custom message transformer to convert the incoming XML:

function TDemoObjectTransformer.Decode(const SerializedObject: 
  RawByteString): TObject;
var
  XmlDoc: IXMLDocument;
  Entry: IXMLNode;
  Key, Value: string;
begin
  XmlDoc := LoadXMLData(SerializedObject);

  Entry := XmlDoc.DocumentElement.ChildNodes[1];
  Key := Entry.GetAttribute('name');
  Value := Entry.GetAttribute('value');

  Result := TExampleClass.Create(Key, Value);
end;

Note that the source code is a proof of concept, using experimental features of the Habari Client library. Also note that transferring objects with ObjectMessage also does have its disadvantages.

About Habari Client for ActiveMQ

Habari Client library for ActiveMQ is available from Habarisoft.habari_logo_2016

 

 

 

Habari Client for RabbitMQ performance test with CloudAMQP “Little Lemur”

CloudAMQP is a service which provides managed RabbitMQ servers in the cloud. For developers, it offers a free plan, called “Little Lemur”. Clients can connect using various protocols: AMQP, AMQPS, HTTPS, STOMP and MQTT. Dedicated plans do also have support for WEB-STOMP.

STOMP client test application

The demo download of the Habari Client for RabbitMQ library for Delphi and Free Pascal contains a STOMP based performance test application. Configuration for CloudAMQP server instances is simple. The CloudAMQ web admin console displays the server name and user credentials on the “Details” page. Click on the Broker address edit field in the test application to open the connection configuration dialog.

The test application will start producer and consumer threads, which send and receive the selected number of messages with a payload of the chosen size. The receiver threads will retry if any messages have not been received.

Test run result

new-bitmap-image

With small payload sizes, the transfer rate reaches several hundred messages per second. It drops to around 100 messages per second and less with payloads of 500 bytes. (CloudAMQ shared plan instances are vhosts located on a shared server where other users actions might affect the performance of the whole server.)

While these message rates are much lower than those in a local network, they are still good enough for evaluation of messaging applications which need to run in the Internet.

 

About Habari Client libraries

habari_logo_2016Habari Client libraries enable Object Pascal applications to take advantage of message broker / message queue technology – which is distributed, loosely coupled, reliable and asynchronous – to build integrated systems, using peer-to-peer and publish-subscribe communication models

 

 

 

 

Consume ActiveMQ JMS MapMessages from Delphi

One outstanding feature of the popular Apache ActiveMQ message broker is its rich message conversion capability, which allows cross-platform/cross-language exchange by serialization of JMS object and map messages to XML or JSON. Non-Java clients do not have to support the native ActiveMQ wire protocol. Instead, they can use a simple protocol such as STOMP.

Java (producer side)

Here is a small example for a Java client application which sends a MapMessage to the ActiveMQ message broker. The code sets four key-value pairs of a MapMessage instance, and sends it to the destination queue:

ConnectionFactory f = new ActiveMQConnectionFactory();
Connection conn = f.createConnection("user", "password");
Session session = conn.createSession(false, AUTO_ACKNOWLEDGE);
Destination dest = session.createQueue("Habari.MapMessage");
conn.start();

MessageProducer producer = session.createProducer(dest);
MapMessage msg = session.createMapMessage();

msg.setString("hello", "world");
msg.setInt("int", 42);
msg.setBoolean("false", false);
msg.setBoolean("true", true);

producer.send(msg);

conn.close();

When this code completes, the JMS MapMessage instance will wait in the message broker queue for a consumer. At this point, it is neither XML nor JSON encoded. It is stored in the internal broker native format of ActiveMQ.

Delphi / Free Pascal (consumer side)

As explained above, the MapMessage waits in the message broker, but is not serialized to XML or JSON. If we need a serialized message, our client must tell this the ActiveMQ broker when it creates a consumer for the queue. It does so by including a special header in the STOMP subscription frame. We want to receive the MapMessage as XML, so the header is:

transformation=jms-map-xml

Now the broker knows which serialization our client understands. ActiveMQ sends the MapMessage to our STOMP client as XML.


<map>
  <entry>
    <string>false</string>
    <boolean>false</boolean>
  </entry>
  <entry>
    <string>true</string>
    <boolean>true</boolean>
  </entry>
  <entry>
    <string>hello</string>
    <string>world</string>
  </entry>
  <entry>
    <string>int</string>
    <int>42</int>
  </entry>
</map>

Our Delphi / Free Pascal example client receives the message and display its key/value pairs:

procedure ReceiveAsXML(Transformer: IMessageTransformer);
const
  DEST_NAME = 'Habari.MapMessage';
  DEST_PARAMS = '?transformation=jms-map-xml';
var
  Connection: IConnection;
  Session: ISession;
  Consumer: IMessageConsumer;
  Destination: IQueue;
  MapMessage: IMapMessage;
  MapNames: PMStrings;
  I: Integer;
  Key: string;
begin
  Connection := TBTConnection.MakeConnection;
  try
    try
      SetTransformer(Connection, Transformer);

      Connection.Start;
      Session := Connection.CreateSession(amAutoAcknowledge);
      Destination := Session.CreateQueue(DEST_NAME+DEST_PARAMS);
      Consumer := Session.CreateConsumer(Destination);

      WriteLn('Waiting for messages ...');

      MapMessage := Consumer.Receive as IMapMessage;

      if Assigned(MapMessage) then
      begin
        MapNames := MapMessage.GetMapNames;
        for I := 0 to Length(MapNames) - 1 do
        begin
          Key := MapNames[I];
          WriteLn(Key + '=' + MapMessage.GetString(Key));
        end;
      end;

      Connection.Stop;

    except
      on E: Exception do
        WriteLn(E.Message);
    end;
  finally
    Connection.Close;
  end;

  WriteLn('Press any key');
  ReadLn;
end;

Conclusion

This proof-of-concept example code shows how ActiveMQ message broker integration with non-Java clients may be implemented with no changes to existing code. ActiveMQ is able to deliver a JMS MapMessage to a STOMP client in a cross-platform format, so that Delphi and Free Pascal clients may consume them.

About Habari Client for ActiveMQ

The Habari Client library includes example implementations of XML message transformers based on various XML and JSON parsers, including the default IXMLDocument based parser. Note that the example implementations in the shipping versions only support properties of string type for sending and receiving. Support for receiving boolean and integer values is planned for the next release.

Habari Client library for ActiveMQ is available from Habarisoft.habari_logo_2016

 

 

 

Sending messages to a RabbitMQ auto-delete queue

The RabbitMQ STOMP plugin supports advanced queue features, which can be defined in the management interface but also from clients when the queue is created. No matter how these features have been declared, RabbitMQ requires that the client specifies the same feature settings anytime when this queue is used.

Example 1: auto-delete

Creation of an auto-delete queue

If the queue does not exist yet, it may be created dynamically by subscribing

ClientCallbackQueue := Session.CreateQueue('Callback?auto-delete=true');

Consumer := Session.CreateConsumer(ClientCallbackQueue);

The admin interface will show that the auto-delete feature is enabled.

Sending a message to the auto-delete queue

Sending a message to this queue requires to specify that the auto-delete feature is enabled:

Msg := Session.CreateTextMessage;

Msg.SetStringProperty('auto-delete', 'true');

Producer.Send(Msg);

Example 2: x-max-priority

Creation of the queue

If the queue does not exist yet, it may be created dynamically by subscribing

PriorityQueue := Session.CreateQueue('Priority?x-max-priority=20');

Consumer := Session.CreateConsumer(PriorityQueue);

The admin interface will show that the maximum priority is 20.

Sending a message to the queue

Sending a message to this queue requires to specify that the maximum priority is 20:

Msg := Session.CreateTextMessage;

Msg.SetIntProperty('x-max-priority', 20);

Producer.Send(Msg);

Hint: check the broker log

If your STOMP client code works with special destination features and does not work as expected, always check the RabbitMQ broker log file. On Windows, you may find it in %APPDATA%\RabbitMQ\log. On Unix, it is located in ${install_prefix}/var/log/rabbitmq (File Locations documentation).

For example, this error message appears if a STOMP client tries to use a exclusive queue from a second connection:

STOMP error frame sent:
Message: resource_locked
Detail: "RESOURCE_LOCKED - cannot obtain exclusive access to locked queue 'QueueTest' in vhost '/'\n"

Note

All code examples use the Habari Client for RabbitMQ STOMP library for Delphi and Free Pascal.

habari_logo_2016Habari Client libraries enable Object Pascal applications to take advantage of message broker / message queue technology – which is distributed, loosely coupled, reliable and asynchronous – to build integrated systems, using peer-to-peer and publish-subscribe communication models.

ScroogeXHTML for the Java™ platform 6.2.0 – fast RTF to HTML5 and XHTML conversion

Habarisoft released version 6.2.0 of its RTF to HTML5 and XHTML converter library, ScroogeXHTML for the Java™ platform. The new version resolves 3 bugs and introduces 3 enhancements and new features, including support for table row height and text format changes within hyperlinks.

You can evaluate the new release with the online converter demo, which displays the configuration property values of the converter, and allows to modify many of them.

scrooge_portrait_logo_2016

 

“Tiny RTF Viewer” 2.5 using ScroogeXHTML RTF to HTML5 converter

Habarisoft released Tiny RTF Viewer 2.5 for Android. This small viewer app converts RTF documents (which can be stored locally or accessed by choosing a hyperlink in a web browser) to HTML5, and displays them in the internal web browser.
Google play

For the internal conversion from Rich Text Format (RTF) to HTML5, the app uses the ScroogeXHTML library from Habarisoft. More information and an on-line demo of the converter library are available at https://www.scroogexhtml.com/

scrooge_portrait_logo_2016

Android is a trademark of Google Inc. ♦ Google Play is a trademark of Google Inc.

 

ScroogeXHTML for the Java™ platform 6.1.0 – fast RTF to HTML5 and XHTML conversion

Habarisoft released version 6.1.0 of its RTF to HTML5 and XHTML converter library, ScroogeXHTML for the Java™ platform. The new version resolves 2 bugs and introduces 4 enhancements and new features, including support for table row height and text format changes within hyperlinks.

You can evaluate the new release with the online converter demo, which displays the configuration property values of the converter, and allows to modify many of them.

scrooge_portrait_logo_2016