ConnectMessage

ConnectMessage

A ConnectMessage is the internal message format that ConnectPlaza uses to send messages between the various components.

As a common user, you don’t need any technical knowledge of this format. But developers of services and/or advanced users should have some knowledge of the ConnectMessage format to understand the properties of the ConnectMessage and possible uses of ConnectMessages.

The ConnectMessage is a straight forward message format, consisting of properties and one or more ConnectMessageParts. The properties contain name/value pairs concerning, for instance, messageID, timestamp and correlationID. 

The common properties that are used in every ConnectMessage, are the unique connectmessageID and the connectmessageTimestamp.

In addition to these common properties, a developer can create and use his own properties.

ConnectMessagePart

A ConnectMessagePart contains a message of a certain type. These types include:

  • TextPart -> containing a printable character String
  • DocumentPart -> containing a parseable XML Document
  • Bytes -> containing a byte stream or byte array
  • File -> containing a File reference
  • Object -> containing a Serializable Java Object

Every MessagePart consists of a set of properties (particular to the message part and separate from the parent Message) and a payload containing data of the aforementioned types. These properties include an ID and index. Any MessagePart can be retrieved from its parent message through either the index or the name.

All components use ConnectMessages which, by default, stores the message contents in a (Connect)MessagePart under the name “msgprt0”.

A developer can store a message in a MessagePart with another name, simply by using the attribute MessagePart (MessagePart-In or MessagePart-Out) in the components. This makes it possible to have multiple MessageParts within one ConnectMessage. This can be important when there are more services in a flow that want to make use of the original contents, that was received by the consumer. The resulting message will be stored in another MessagePart (for instance “msgprt1”). This way, the original message will not be overwritten. 

MessagePart ALL

When the MessagePart-In is configured as ALL, developers will have access to all parts of the ConnectMessage at once. The invoke method of that service will receive not only the type of the MessagePart with ID ‘msgprt0’, but the entire ConnectMessage. This may be useful when using services that require the entire message including all parts to operate.

For example, the Mapforce Service supports multiple input documents that are delivered in separate message parts. Also the Webservice Outbound Gateway supports multipart messages based on this principle.

When accessing messages you can have more than one message part. As you use some parts of the object, most of the time you will use msgprt0, i.e. message part 0. Normally msgprt0 will contain the message you are working on if you do not specify another message part.

MessagePart ALL-XML

A special message part you can use is ALL-XML. This will convert the total message into an XML message. This is a way to also show the header information. The headers of the message will be wrapped into the XML message, the payloads of each message part will be part of the message as a CDATA component of the XML.

For example, suppose we create a simple File Pickup -> File Drop flow. In the File Dropper we set the MessagePart attribute to ALL-XML:

After building and deploying we pickup the file below.

<?xml version="1.0" encoding="UTF-8"?>
<results xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="file:///E:/data/connectplaza/output/notfound.log.xsd">
	<instance>
		<host>server1</host>
		<service>service1</service>
	</instance>
	<instance>
		<host>server1</host>
		<service>service1.Export-info-direct</service>
	</instance>
	<instance>
		<host>server1</host>
		<service>service1.ErrorMailDiscard</service>
	</instance>
	<instance>
		<host>server1</host>
		<service>service1.FTP_Export</service>
	</instance>
	<instance>
		<host>server1</host>
		<service>service1.OrderImport</service>
	</instance>
	<instance>
		<host>server1</host>
		<service>service1.Export</service>
	</instance>
	<instance>
		<host>server1</host>
		<service>service1.Export-direct</service>
	</instance>
	<instance>
		<host>server1</host>
		<service>service1.Export-info</service>
	</instance>
	<instance>
		<host>server1</host>
		<service>service1.FTP_Import</service>
	</instance>
	<instance>
		<host>server2</host>
		<service>service-threads-no-go</service>
	</instance>
	<instance>
		<host>server2</host>
		<service>service-44553</service>
	</instance>
	<instance>
		<host>server2</host>
		<service>service-ccxxx</service>
	</instance>
	<instance>
		<host>server2</host>
		<service>check-all-threads</service>
	</instance>
	<instance>
		<host>server2</host>
		<service>ThreatPoola</service>
	</instance>
	<instance>
		<host>server3</host>
		<service>check-all-files</service>
	</instance>
	<instance>
		<host>server3</host>
		<service>analyzeBackendAdapter.analyzeBackendChannel</service>
	</instance>
	<instance>
		<host>server34</host>
		<service>MYSQL: Packing Order Confirmed</service>
	</instance>
	<instance>
		<host>undefined</host>
		<service>undefined</service>
	</instance>
</results>

The exported XML file will now look like this:

<ConnectMessage>
<props>
<prop name="connectmessageTimestamp" value="1490364316104"/>
<prop name="connectmessageID" value="f84e5af0-c39a-4c2c-ae63-cc43dcaba30a"/>
<prop name="file_name" value="notfound.log.xml"/>
</props>
<parts>
<part id="msgprt0" index="0" type="TEXT">
<props>
</props>
<content><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<results xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="file:///E:/data/connectplaza/output/notfound.log.xsd">
	<instance>
		<host>server1</host>
		<service>service1</service>
	</instance>
	<instance>
		<host>server1</host>
		<service>service1.Export-info-direct</service>
	</instance>
	<instance>
		<host>server1</host>
		<service>service1.ErrorMailDiscard</service>
	</instance>
	<instance>
		<host>server1</host>
		<service>service1.FTP_Export</service>
	</instance>
	<instance>
		<host>server1</host>
		<service>service1.OrderImport</service>
	</instance>
	<instance>
		<host>server1</host>
		<service>service1.Export</service>
	</instance>
	<instance>
		<host>server1</host>
		<service>service1.Export-direct</service>
	</instance>
	<instance>
		<host>server1</host>
		<service>service1.Export-info</service>
	</instance>
	<instance>
		<host>server1</host>
		<service>service1.FTP_Import</service>
	</instance>
	<instance>
		<host>server2</host>
		<service>service-threads-no-go</service>
	</instance>
	<instance>
		<host>server2</host>
		<service>service-44553</service>
	</instance>
	<instance>
		<host>server2</host>
		<service>service-ccxxx</service>
	</instance>
	<instance>
		<host>server2</host>
		<service>check-all-threads</service>
	</instance>
	<instance>
		<host>server2</host>
		<service>ThreatPoola</service>
	</instance>
	<instance>
		<host>server3</host>
		<service>check-all-files</service>
	</instance>
	<instance>
		<host>server3</host>
		<service>analyzeBackendAdapter.analyzeBackendChannel</service>
	</instance>
	<instance>
		<host>server34</host>
		<service>MYSQL: Packing Order Confirmed</service>
	</instance>
	<instance>
		<host>undefined</host>
		<service>undefined</service>
	</instance>
</results>]]></content>
</part>
</parts>
</ConnectMessage>

ConnectMessage Header

The header of a ConnectMessage contains all the properties of the message. The most common is the property file_name, which has the original file name of a read file.  The common properties that are used in every ConnectMessage, are the unique connectmessageID and the connectmessageTimestamp.

You can read the properties with Javascript or if you create messages with ALL-XML.

Byte Order Markers

When processing messages it is possible that you get a parsing error. When looking into your XML file, nothing seems to be wrong.

Caused by: com.altova.SourceInstanceUnavailableException: cannot parse input stream.
                at com.altova.xml.XmlTreeOperations.loadDocument(XmlTreeOperations.java:71)
                at com.altova.xml.XmlTreeOperations.loadDocument(XmlTreeOperations.java:39)
                at com.mapforce.MappingMapToweborder.run(MappingMapToweborder.java:898)
                ... 81 common frames omitted
Caused by: org.xml.sax.SAXParseException: Content is not allowed in prolog.
                at org.apache.xerces.parsers.DOMParser.parse(Unknown Source)
                at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source)
                at com.altova.xml.XmlTreeOperations.loadDocument(XmlTreeOperations.java:66)
                ... 83 common frames omitted

When saving the message in notepad, the message suddenly checks out and there are no problems...

When you get inexplicable messages like this, your XML file probably has a BOM. A BOM or Byte Order Marker is a special marker added at the very beginning of a Unicode file encoded in UTF-8, UTF-16 or UTF-32. It is used to indicate whether the file uses the big-endian or little-endian byte order. The BOM is mandatory for UTF-16 and UTF-32, but it is optional for UTF-8.

The problem with a BOM is, that it is not visible in an ASCII editor, but you can detect it in a HEX editor.

The byte order mark is likely to be one of these byte sequences:

UTF-8 BOM   : ef bb bf 
UTF-16BE BOM: fe ff 
UTF-16LE BOM: ff fe 
UTF-32BE BOM: 00 00 fe ff 
UTF-32LE BOM: ff fe 00 00

Parsing XML documents with a Byte Order Marker may cause problems as the parser tries to interpret the BOM as characters. However, you can remove the BOM by using the Encoding Converter Service, converting the message from, for instance, UTF-8 to UTF-8, specifying to Remove the BOM. This will remove the BOM from the payload.

Keep in mind that some applications require a BOM.

Binary-text limitation cap

Since version 4.0.0 we have included a limitation on the number of characters that will be printed when performing a getStringContent() operation on a Messagepart of type Bytes also known as the ConnectMessagePartByteArrayImpl. This part contains the binary data of the messagepart stored in a byte-array. The contents of this byte array should be retrieved using the getContent() method.

Whenever performing the toString() or getStringContent() methods the size of the string representation of the internal byte array will automatically be capped to 1024 characters.

This number can be overridden by adding a System property to the ConnectPlaza Agent: connectMessage.payloadCap

This can be done in the connectplaza-jvm-process.properties configuration file by adding the following line:

connectplaza.process.jvm.arg.cap = -DconnectMessage.payloadCap=1048576

This line will set the maximum number of characters to 1048576.