stylesheet classes.xsl which generated that diagram is attached and discussed a little bit.
You might be interested in "graph extraction" from XML data and Depth-First-Search traversal of the extracted graph which was used to generate the "block" hierarchy diagram. Also the simple and nice heuristic which allows
to allocate exactly the vertical space needed for a node in the diagram is interesting -- in "XML speak" instead of "graph speak"
Accessing the Non-XML data is possible by a binary transform action. WTX provides QUOTEDTOTEXT() function, but what I want to show here is a simpler way to do it.
The solution is by simply replacing the "multipart/signed" Content-Type by "multipart/related" with the correct "boundary" setting. because "multipart/related" messages can be processed by DataPower. This Content-Type rewrite technique was also used in swaform tool allowing to process HTTP form data with binary file uploads (multipart/form-data):
a binary transform action with stylesheet Signed2Related.xsl, with input INPUT and output NULL
a results action with input INPUT
a backend URL of http://127.0.0.1:port2
And you will have a
loopback XML service listening on 127.0.0.1:port2
attachment processing set to "Skip"
store:///identity.xsl transform action
XML Manager with Minimum Output Escaping rule in Compile Options policy (for showing German Umlaute unescaped below)
That's all. I tested with MPGW 1st service and 2nd service as MPGW, XML FW or XSL Accelerator successfully (on 3.7.3, 3.8.0 and 4.0.1 firmware).
Here is the output generated by the service:
$ curl --data-binary @Qp.mime http://dp2-l3:8121; echo <?xml version="1.0" encoding="UTF-8"?> <sample>If you believe that truth=beauty, then surely mathematics is the most beautiful branch of philosophy. <umlaute>äöüÄÖÜß</umlaute></sample> $
<?xml version=3D"1.0" encoding=3D"ISO-8859-1"?> <sample>If you believe that truth=3Dbeauty, then surely=20= mathematics is the most beautiful branch of philosophy.=0A= <umlaute>=E4=F6=FC=C4=D6=DC=DF</umlaute>= </sample> ------=_Part_2_12345 Content-Type: application/pkcs7-signature; name=smime.p7s; smime-type=signed-data Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" Content-Description: S/MIME Cryptographic Signature
This should be base64 sign part data. Missing intentionally for qouted-printable demo. ------=_Part_2_12345--
<!-- Allow accessing the decoded (quotable-printable) body-part in chained service with "Skip" attachment processing by "multipart/related" --> <dp:set-http-request-header name="'Content-Type'" value="concat('multipart/related; type="text/xml"; ', 'boundary="',$boundary,'"')" />
The latency values get logged at information level when a DataPower service accesses some real backend (not with skip-backside).
If you do want the entries in loopback case just have a simple pass-thru XML FW on the box as "backend".
The technote describes the 16 values by order of output in the log message.
This does not correspond to the order these values get timestamped during execution of a transaction.
Find below the reordering of technote table according to the real execution order (see <EDIT>...</EDIT> below for a restriction).
The messages in the table have been replaced by WebGUI online help messages (if you click on "Latency: ..." in the log).
In addition I added coloring of the different phases of the transaction:
receive request header
front side processing
transmit to back side
receive header from back side
back side processing
transmit response to front side
You do have access to 3 of the values by read-only service variables:
In addition you may access var://service/time-elapsed (the value used for creation of all 16 latency values, read-only).
request headers read
front side transform begun
front side parsing complete
front side stylesheet ready
front side transform complete
back side connection attempted
(this is when the connection is first tried)
back side connection completed
(or time connection attempt gave up)
request headers sent
entire request transmitted
response headers received
back side transform begun
back side parsing complete
back side stylesheet ready
back side transform complete
response headers sent
A colleague made me aware that this order cannot be guaranteed in case of streaming processing.
(see DataPower XML data processing)
could have been titled "Processing binary data in DataPower stylesheets 1/x". This posting is the second of several postings on processing of binary data in DataPower stylesheets.
Again this is on CDATA as in the postings "CDATA .../x". This time the (customer) problem was as follows:
accept XML input data
do XML threat protection
if no threat, pass input unmodified to backend (preserve any CDATA elements).
While preserving of CDATA might be done with cdata-section-elements of <xsl:output ... /> you have to know which elements you want to have CDATA output for, In case of DataPowwer as generic proxy any element might contain CDATA section or might not contain CDATA sections.
If the service would have XML request type CDATA sections are gone -- therefore we need a Non-XML service.
But XML threat protection does not work in Non-XML service -- therefore we need a second XML service.
Now lets discuss the solution I came up with.
Setup XML-FW with XML request type with its own XML Manager and any specific XML Parser settings. (I did set "XML Element Depth" to 1, service is on port 2060)
Setup XML-FW with Non-XML request type, and these two actions: 1) binary transform action from INPUT to NULL with stylesheet check.xsl 2) results action from INPUT to OUTPUT
This is the binary transform stylesheet check.xsl I used.
The <dp:input-mapping ... /> uses Flat File Descriptor (FFD) store:///pkcs7-convert-input.ffd shipped with DataPower and used by five PKCS7 stylesheets located in store:/// folder. As documented in the FFD itself (see below) it generates structure <object><message>***binary data***</message></object> with a binaryNode as child of <message> element. Find the details on binaryNode in previous posting.
Now the "binary data" (which in this case is XML data, but we want pass it unmodified) needs to be posted to second XML (threat protection) service by <dp:url-open>. Posting binary data with <dp:url-open> is done with data-type="base64". Therefore we just convert the binaryNode data to base64 by dp:binary-encode(/object/message) in <dp:url-open>. We are not interested in the response of the service called but only in its response code, therefore response="responsecode". The result of <dp:url-open> call is stored in variable $reponse. In case the HTTP response code is not equal to 200 we know that something is wrong, and for the service called we know that XML threat protection found a problem. Therefore we abort service execution by <dp:reject>.
So if service execution does not get aborted by <dp:reject> the results action from INPUT to OUTPUT just copies the unmodified INPUT to OUTPUT (preserving any CDATA section). Otherwise (in case of a detected XML threat) the service returns a generic error message to the client.
What we have seen is
how to process binary (Non-XML) input data (resulting in a binaryNode)
how to convert a binaryNode to a base64 encoded string
how to pass "binary" data to dp:url-open() by data-type="base64"
how to process response code of dp:url-open
By the arguments above there cannot be a solution without a side call.
And this is from stylesheet "store:///pkcs7-convert-input.ffd":
... <!-- This FFD converts the input into an XML tree like this:
While embedding stylesheets is part of the spec it is not supported by all browsers. Especially Internet Exploerer 6/7/8 browsers do not support it.
I found a solution on how to enable Internet Explorer browsers for embedded stylesheet processing. The first solution had the drawback that now stylesheet embedding was possible for FF and IE, but the solution broke the ability of the other big5 browsers to process embedded stylesheets although they could process them natively.
To give you an idea of an embedded stylesheet find listing of supportALL.xml (generates the table on the right) below:
<!-- This stylesheet is a modification from this posting: http://www.biglist.com/lists/lists.mulberrytech.com/xsl-list/archives/200010/msg01150.html --> <xsl:stylesheet id="style1" version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- only needed by "Opera Mini"; output method here IS "html" even without explicit declaration, see http://www.w3.org/TR/xslt#output --> <xsl:output method="html"/>
<xsl:key name="b" match="@os" use="."/>
<xsl:template match="/"> <html> <body>
<i>ApplyStylesheetEmbedding.xsl technique</i> works for: <table border="1" cellspacing="0">
<!-- Generate the row of table header cells --> <tr> <th>Browser \ OS</th> <!-- | Generate a header cell for each unique os name | | See Chapter 9 of "Building Oracle XML Applications" from O'Reilly
| for a detailed explanation of how this <xsl:key> based technique works +--> <xsl:for-each select="//@os[generate-id(.)=generate-id(key('b',.))]"> <!-- Sort by the os name (the value of the current @os attribute -->
a "prepend" service making use of special binary data processing behavior mentioned in my previous Blog posting Sending zip archives to DataPower (this just converts Non-XML input data base64string to prepend=base64string)
a normal Non-XML service with a convert-http action to convert this "HTTP-Form" input to XML (convert-http action does not need DataGlue license)
This is just another example for "does not work out-of-the-box on DataPower but can be made working".