MTOM (cache) server example availability

Primary tabs

SOAP, XML, Caché

Forgive my possible intrusion.  

I am not currently involved (yet) in any Intersystems deployment and/or development.
However I was triggered by an piece of (Intersystems) documentation residing under the Intersystems website discussing options  regarding 
Using MTOM for Attachments.  (https://cedocs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?K...
)
I this article there is the following sentence: 

By default, a Caché web service behaves as follows:
  • If it receives a request in an MTOM package, the web service sends the response as an MTOM package.
    Also, the IsMTOM property of the web service instance is set to 1.
  • If it receives a request not in an MTOM package, the web service sends the response not in an MTOM package.
I would be very interested in an example server(service)  implementation  in fact a sort of helloworld but with a single base64binary field which I can invoke (soapui) supplying either a MTOM attachement or a base64 encode string. 
A standalone server just echoing what is received is fine and would prove what I have been arguing for a long time .
Hopefully it is feasible including any required software (trial versions are fine).
I run both win 10 and ubuntu 18.04  
Please make my day
 
Thanks
 
Peter  
 

 

Replies

Hi Peter,

A very simple example:

/// Wrapper object
Class br.cjs.MtomObject Extends (%RegisteredObject, %XML.Adaptor)
{ 
Property BinaryData As %GlobalBinaryStream; 

/// Create a instance of br.cjs.MtomObject and populate the property BinaryData with th SVG logo of InterSystems Developer Community
ClassMethod GetLogo() As br.cjs.MtomObject
{
#Dim mtom As br.cjs.MtomObject = ##Class(br.cjs.MtomObject).%New()
#Dim logo As %Stream.TmpBinary = ##Class(%Stream.TmpBinary).%New()
//
b
Do logo.Write("<?xml version='1.0' encoding='utf-8'?>")
Do logo.Write("<!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->")
Do logo.Write("<svg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px'")
Do logo.Write(" viewBox='0 0 181.9 45' style='enable-background:new 0 0 181.9 45;' xml:space='preserve'>")
Do logo.Write("<style type='text/css'>")
Do logo.Write(" .st0{fill:#27318A;}")
Do logo.Write(" .st1{fill:#27318B;}")
Do logo.Write(" .st2{fill:#00A99D;}")
Do logo.Write("</style>")
Do logo.Write("<g>")
Do logo.Write(" <path class='st0' d='M28.4,26.2h-3.8V5.7h3.8V26.2z'/>")
Do logo.Write(" <path class='st0' d='M43.7,26.2h-3.8v-8.6c0-2-1.4-2.9-2.8-2.9c-1.4,0-2.8,0.9-2.8,2.9v8.6h-3.8V11.5h3.8v1.3")
Do logo.Write(" c0.7-1,2.1-1.7,3.5-1.7c3,0,5.9,2.1,5.9,6.4C43.7,17.5,43.7,26.2,43.7,26.2z'/>")
Do logo.Write(" <path class='st0' d='M53.2,22.8v3.4h-3.6c-2.6,0-3.8-1.4-3.8-3.8v-7.6v-3.4V8.1h3.8v3.3h3.6v3.4h-3.6v6.8c0,0.7,0.2,1.2,1.1,1.2")
Do logo.Write(" C50.7,22.8,53.2,22.8,53.2,22.8z'/>")
Do logo.Write(" <path class='st0' d='M58.1,19.8L58.1,19.8c0,1.8,1,3,2.8,3c1.3,0,2.2-0.6,2.6-1.6h3.8c-0.6,3.1-2.8,5-6.4,5c-4.2,0-6.6-2.7-6.6-6.8")
Do logo.Write(" v-1.9c0-4.1,2.3-6.8,6.6-6.8c4.2,0,6.6,2.7,6.6,6.8v2.3C67.5,19.8,58.1,19.8,58.1,19.8z M58.1,16.7L58.1,16.7h5.6l0,0")
Do logo.Write(" c-0.1-1.5-1.1-2.5-2.8-2.5C59.3,14.2,58.3,15.2,58.1,16.7z'/>")
Do logo.Write(" <path class='st0' d='M73.4,26.2h-3.8V11.5h3.8v1.6c0.4-1,1.7-1.9,3.4-1.9H78v3.7h-1.8c-1.4,0-2.8,0.9-2.8,2.9")
Do logo.Write(" C73.4,17.8,73.4,26.2,73.4,26.2z'/>")
Do logo.Write(" <path class='st0' d='M79.8,19.6h3.9c0.2,1.7,1.5,2.8,3.5,2.8c1.7,0,2.9-0.6,2.9-2c0-1.1-0.7-1.7-2.1-2.1l-3.4-0.9")
Do logo.Write(" c-3.1-0.8-4.6-3-4.6-5.9c0-4,3.1-5.8,6.6-5.8c4,0,6.5,2.3,6.9,5.7h-3.9c-0.3-1.3-1.7-1.9-3-1.9c-1.6,0-2.7,0.6-2.7,2")
Do logo.Write(" c0,1.2,0.9,1.7,2,2l3.3,0.9c3.1,0.8,4.7,2.7,4.7,6.1c0,3.6-2.3,5.8-6.7,5.8C82.8,26.2,80,23.6,79.8,19.6z'/>")
Do logo.Write(" <path class='st0' d='M103,27.5c-0.8,2.2-1,3.9-3.7,3.9h-2.8V28h1.6c0.7,0,0.9-0.3,1-0.7l0.4-1.2l-5.3-14.7h4l3.3,9.4l3.3-9.4h4")
Do logo.Write(" L103,27.5z'/>")
Do logo.Write(" <path class='st0' d='M108.5,21.2h3.8c0.2,1.1,1.5,1.7,2.7,1.7c0.7,0,1.9-0.2,1.9-1.1c0-0.6-0.4-0.9-1.3-1.1l-3.1-0.7")
Do logo.Write(" c-1.6-0.4-3.6-1.6-3.6-4.5s2.6-4.5,5.6-4.5s5.5,1.4,5.7,4.8h-3.9c-0.2-0.9-1-1.4-2-1.4c-1.1,0-1.7,0.4-1.7,1.1")
Do logo.Write(" c0,0.6,0.5,0.9,1.1,1.1l3.3,0.7c1.6,0.4,3.6,1.5,3.6,4.5c0,3.3-2.7,4.5-5.7,4.5C111.8,26.2,108.6,24.6,108.5,21.2z'/>")
Do logo.Write(" <path class='st0' d='M134.6,19.8L134.6,19.8c0,1.8,1,3,2.8,3c1.3,0,2.2-0.6,2.6-1.6h3.8c-0.6,3.1-2.8,5-6.4,5")
Do logo.Write(" c-4.2,0-6.6-2.7-6.6-6.8v-1.9c0-4.1,2.3-6.8,6.6-6.8c4.2,0,6.6,2.7,6.6,6.8v2.3C144,19.8,134.6,19.8,134.6,19.8z M134.6,16.7")
Do logo.Write(" L134.6,16.7h5.6l0,0c-0.1-1.5-1.1-2.5-2.8-2.5S134.8,15.2,134.6,16.7z'/>")
Do logo.Write(" <path class='st0' d='M159.1,26.2h-3.8v-8.6c0-2-1.4-2.9-2.7-2.9s-2.7,0.9-2.7,2.9v8.6h-3.8V11.5h3.8v1.2c0.7-1,2.1-1.6,3.3-1.6")
Do logo.Write(" c1.5,0,2.9,0.6,4,1.9c1.1-1.3,2.6-1.9,4.6-1.9c3.7,0,6.5,2.1,6.5,6.4v8.7h-3.8v-8.6c0-2-1.4-2.9-2.7-2.9s-2.7,0.9-2.7,2.9")
Do logo.Write(" L159.1,26.2L159.1,26.2z'/>")
Do logo.Write(" <path class='st0' d='M169.7,21.2h3.8c0.2,1.1,1.5,1.7,2.7,1.7c0.7,0,1.9-0.2,1.9-1.1c0-0.6-0.4-0.9-1.3-1.1l-3.1-0.7")
Do logo.Write(" c-1.6-0.4-3.6-1.6-3.6-4.5s2.6-4.5,5.6-4.5s5.5,1.4,5.7,4.8h-3.9c-0.2-0.9-1-1.4-2-1.4c-1.1,0-1.7,0.4-1.7,1.1")
Do logo.Write(" c0,0.6,0.5,0.9,1.1,1.1l3.3,0.7c1.6,0.4,3.6,1.5,3.6,4.5c0,3.3-2.7,4.5-5.7,4.5C173.1,26.2,169.9,24.6,169.7,21.2z'/>")
Do logo.Write(" <path class='st0' d='M129.2,22.8v3.4h-3.6c-2.6,0-3.8-1.4-3.8-3.8v-7.6v-3.4V8.1h3.8v3.3h3.6v3.4h-3.6v6.8c0,0.7,0.2,1.2,1.1,1.2")
Do logo.Write(" C126.7,22.8,129.2,22.8,129.2,22.8z'/>")
Do logo.Write("</g>")
Do logo.Write("<g>")
Do logo.Write(" <polygon class='st1' points='5.6,6.3 0,3.5 0,39.3 11.3,45 11.3,38.7 5.6,35.9 '/>")
Do logo.Write(" <polygon class='st2' points='11.3,38.7 16.9,41.5 16.9,5.7 5.6,0 5.6,6.3 11.3,9.1 '/>")
Do logo.Write("</g>")
Do logo.Write("<g>")
Do logo.Write(" <path class='st0' d='M24.3,41v-8h3c1.9,0,3,1.2,3,3v2.1c0,1.8-1.1,3-3,3H24.3z M28.9,36c0-0.9-0.7-1.4-1.5-1.4h-1.5v5h1.5")
Do logo.Write(" c0.8,0,1.5-0.5,1.5-1.4V36z'/>")
Do logo.Write(" <path class='st0' d='M32.9,38.6L32.9,38.6c0,0.7,0.4,1.2,1.1,1.2c0.5,0,0.9-0.3,1-0.7h1.5c-0.2,1.2-1.1,2-2.6,2")
Do logo.Write(" c-1.7,0-2.6-1.1-2.6-2.7v-0.8c0-1.6,0.9-2.7,2.6-2.7c1.7,0,2.6,1.1,2.6,2.7v0.9H32.9z M32.9,37.3L32.9,37.3l2.2,0v0")
Do logo.Write(" c0-0.6-0.4-1-1.1-1C33.4,36.3,33,36.7,32.9,37.3z'/>")
Do logo.Write(" <path class='st0' d='M41.3,35.1h1.6L40.8,41h-1.6l-2.1-5.9h1.6l1.3,3.8L41.3,35.1z'/>")
Do logo.Write(" <path class='st0' d='M44.8,38.6L44.8,38.6c0,0.7,0.4,1.2,1.1,1.2c0.5,0,0.9-0.3,1-0.7h1.5c-0.2,1.2-1.1,2-2.6,2")
Do logo.Write(" c-1.7,0-2.6-1.1-2.6-2.7v-0.8c0-1.6,0.9-2.7,2.6-2.7c1.7,0,2.6,1.1,2.6,2.7v0.9H44.8z M44.8,37.3L44.8,37.3l2.2,0v0")
Do logo.Write(" c0-0.6-0.4-1-1.1-1C45.3,36.3,44.9,36.7,44.8,37.3z'/>")
Do logo.Write(" <path class='st0' d='M52,39.7V41h-0.7c-1.1,0-1.5-0.6-1.5-1.5V33h1.5v6.2c0,0.3,0.1,0.5,0.4,0.5H52z'/>")
Do logo.Write(" <path class='st0' d='M52.8,37.7c0-1.6,0.9-2.7,2.6-2.7c1.7,0,2.6,1.1,2.6,2.7v0.8c0,1.6-0.9,2.7-2.6,2.7c-1.7,0-2.6-1.1-2.6-2.7")
Do logo.Write(" V37.7z M56.5,37.5c0-0.7-0.4-1.2-1.1-1.2c-0.7,0-1.1,0.5-1.1,1.2v1.1c0,0.7,0.4,1.2,1.1,1.2c0.7,0,1.1-0.5,1.1-1.2V37.5z'/>")
Do logo.Write(" <path class='st0' d='M60.8,43.2h-1.5v-8h1.5v0.5c0.3-0.4,0.9-0.7,1.4-0.7c1.2,0,2.4,0.8,2.4,2.6v1.1c0,1.7-1.2,2.6-2.4,2.6")
Do logo.Write(" c-0.5,0-1.1-0.3-1.4-0.7V43.2z M63,37.6c0-0.8-0.6-1.1-1.1-1.1s-1.1,0.3-1.1,1.1v0.9c0,0.8,0.6,1.1,1.1,1.1s1.1-0.3,1.1-1.1V37.6z'")
Do logo.Write(" />")
Do logo.Write(" <path class='st0' d='M67.1,38.6L67.1,38.6c0,0.7,0.4,1.2,1.1,1.2c0.5,0,0.9-0.3,1-0.7h1.5c-0.2,1.2-1.1,2-2.6,2")
Do logo.Write(" c-1.7,0-2.6-1.1-2.6-2.7v-0.8c0-1.6,0.9-2.7,2.6-2.7c1.7,0,2.6,1.1,2.6,2.7v0.9H67.1z M67.1,37.3L67.1,37.3l2.2,0v0")
Do logo.Write(" c0-0.6-0.4-1-1.1-1C67.5,36.3,67.1,36.7,67.1,37.3z'/>")
Do logo.Write(" <path class='st0' d='M73.5,41H72v-5.9h1.5v0.6c0.2-0.4,0.7-0.7,1.4-0.7h0.5v1.5h-0.7c-0.6,0-1.1,0.3-1.1,1.1V41z'/>")
Do logo.Write(" <path class='st0' d='M84.4,38.4c-0.1,1.7-1.2,2.8-3,2.8c-1.9,0-3-1.2-3-3v-2.3c0-1.8,1.1-3,3-3c1.9,0,3,1.1,3,2.8h-1.5")
Do logo.Write(" c-0.1-0.8-0.7-1.3-1.5-1.3c-0.8,0-1.5,0.5-1.5,1.4v2.3c0,0.9,0.7,1.4,1.5,1.4c0.8,0,1.4-0.4,1.5-1.3H84.4z'/>")
Do logo.Write(" <path class='st0' d='M85.3,37.7c0-1.6,0.9-2.7,2.6-2.7c1.7,0,2.6,1.1,2.6,2.7v0.8c0,1.6-0.9,2.7-2.6,2.7c-1.7,0-2.6-1.1-2.6-2.7")
Do logo.Write(" V37.7z M89.1,37.5c0-0.7-0.4-1.2-1.1-1.2c-0.7,0-1.1,0.5-1.1,1.2v1.1c0,0.7,0.4,1.2,1.1,1.2c0.7,0,1.1-0.5,1.1-1.2V37.5z'/>")
Do logo.Write(" <path class='st0' d='M97,41h-1.5v-3.4c0-0.8-0.6-1.1-1.1-1.1c-0.5,0-1.1,0.4-1.1,1.1V41h-1.5v-5.9h1.5v0.5c0.3-0.4,0.8-0.7,1.3-0.7")
Do logo.Write(" c0.6,0,1.2,0.2,1.6,0.8c0.4-0.5,1-0.8,1.8-0.8c1.5,0,2.6,0.8,2.6,2.6V41h-1.5v-3.4c0-0.8-0.5-1.1-1.1-1.1c-0.5,0-1.1,0.4-1.1,1.1")
Do logo.Write(" V41z'/>")
Do logo.Write(" <path class='st0' d='M107.2,41h-1.5v-3.4c0-0.8-0.6-1.1-1.1-1.1c-0.5,0-1.1,0.4-1.1,1.1V41H102v-5.9h1.5v0.5")
Do logo.Write(" c0.3-0.4,0.8-0.7,1.3-0.7c0.6,0,1.2,0.2,1.6,0.8c0.4-0.5,1-0.8,1.8-0.8c1.5,0,2.6,0.8,2.6,2.6V41h-1.5v-3.4c0-0.8-0.5-1.1-1.1-1.1")
Do logo.Write(" c-0.5,0-1.1,0.4-1.1,1.1V41z'/>")
Do logo.Write(" <path class='st0' d='M115.8,38.5v-3.4h1.5V41h-1.5v-0.6c-0.3,0.4-0.7,0.8-1.4,0.8c-1.1,0-2.3-0.8-2.3-2.6v-3.5h1.5v3.4")
Do logo.Write(" c0,0.8,0.5,1.1,1.1,1.1C115.3,39.7,115.8,39.3,115.8,38.5z'/>")
Do logo.Write(" <path class='st0' d='M124,41h-1.5v-3.4c0-0.8-0.5-1.1-1.1-1.1s-1.1,0.3-1.1,1.1V41h-1.5v-5.9h1.5v0.5c0.3-0.4,0.9-0.7,1.4-0.7")
Do logo.Write(" c1.2,0,2.4,0.8,2.4,2.6V41z'/>")
Do logo.Write(" <path class='st0' d='M126.8,34.4h-1.5V33h1.5V34.4z M126.8,41h-1.5v-5.9h1.5V41z'/>")
Do logo.Write(" <path class='st0' d='M131.4,39.7V41h-1.5c-1.1,0-1.5-0.6-1.5-1.5v-3h-0.8v-1.4h0.8v-1.3h1.5v1.3h1.5v1.4h-1.5v2.7")
Do logo.Write(" c0,0.3,0.1,0.5,0.4,0.5H131.4z'/>")
Do logo.Write(" <path class='st0' d='M135.1,41.6c-0.3,0.9-0.4,1.5-1.5,1.5h-1.1v-1.4h0.6c0.3,0,0.4-0.1,0.4-0.3l0.2-0.5l-2.1-5.9h1.6l1.3,3.8")
Do logo.Write(" l1.3-3.8h1.6L135.1,41.6z'/>")
Do logo.Write("</g>")
Do logo.Write("</svg>")
//
Do mtom.BinaryData.CopyFrom(logo)
//
Return mtom
} 
}

/// WebService
Class br.cjs.MtomServiceSoap Extends %SOAP.WebService
{ 
Method GetLogo() As %GlobalBinaryStream [ WebMethod ]
{
/// Tell to the service that the return of method is a attachment
Set ..MTOMRequired = 1
//
#Dim mtom As br.cjs.MtomObject = ##Class(br.cjs.MtomObject).GetLogo()
//
Return mtom.BinaryData
} /// SERVICENAME - Should be the name of the service for which this is a proxy.
/// Override this parameter in the subclass.
Parameter SERVICENAME = "MtomServiceExample"; /// NAMESPACE - Should be an unique URI
/// Override this parameter in the subclass with the unique namespace URI
/// of your organization.
/// Override this parameter in the subclass.
Parameter NAMESPACE = "br.cjs"; 
}

Hi Christiano,  

   thanks very much for your input at this stage. 
As I indicated I more or less stumbled across this developer community because cache seems to address a debate we are having for quite some time.   So I am not aware of the details regarding this technology. So I have some questions
1. What do I need (software stack) to be able to run the server code you supplied and use SoapUI as a test client against it?

2. The current example seems to have a basically empty request and get an MTOM response back
Aside from actually coding stuff do you see any  fundamental barriers against having a server implementation that - when you send it MTOM it replies with MTOM and when you send it base64 encoded string it also responds with a encoded string (all within one single service/endpoint)?