go to post Sean Connelly · May 18, 2017 Hi Shobha,It always helps to provide a detailed explanation of your technical problems in order to receive back the best response you are looking for. Or from another perspective the more time you put into your question, the more time you are likely to receive back from community members giving their time to help others.The error that you are getting is because you have tried to compile the %SOAP.WebClient class. This is an internal class to Caché and should not be included in your compilation step. If you try to compile it you will get the permission warning that you have received.What we need to understand is why you are trying to compile this class, or the steps that have lead you to trigger a compilation on this class. We can then figure out where things are going wrong and hopefully steer you in the right direction.In terms of your more broader questions..."I am using SOAP Wizard to create Web client and Services , I want my Ensemble Production to accept the SOAP message and pass it to the Operation. Please let us know how it can be achieved."Again, it would help to have some background in order to know how to best help you. Are you new to both SOAP and Ensemble? Has the documentation helped that we pointed you towards a couple of days ago? What is the overall project goal. For instance, do you need to create a SOAP service from scratch, or are you linking up existing SOAP services?Sean.
go to post Sean Connelly · May 16, 2017 Images are fine for me.Looks like they are hosted on a google drive, perhaps your behind an http proxy that blocks that domain?
go to post Sean Connelly · May 16, 2017 https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY...
go to post Sean Connelly · May 12, 2017 > What is your definition of a few k? Each line is about 25000 KB.Do you mean 25,000 characters (25K)?> Previous comment recommended processing the file as a single message stream. That ended up slowing the message viewer so much for these large messages that that it is impossible to view the message at all.You can override the content display method on your Ens.Request class so that it doesn't display the entire message. You can replace this with a small summary about the file, size, no of records etc.Creating 500,000 Ensemble messages is going to generate a lot of IO that you probably don't need.I would still recommend processing them as one file.
go to post Sean Connelly · May 12, 2017 Please see previous comment to same question...https://community.intersystems.com/post/multi-threading-improve-performanceYou previously mentioned your file contains 500,000 records. How big are the records?If each record is just a few k in size then reading and writing each record from the file to a global will take under 5 minutes.In which case you have a serious bottleneck going on such as a poor referential integrity check. If this is not indexed or tuned then you will have some serious IO thrashing going on, and no matter how many cores you throw at the problem, you will not get any overall performance gains.
go to post Sean Connelly · May 12, 2017 I would hope none of this information is being dumped on a live server, dev server only.
go to post Sean Connelly · May 12, 2017 Hi Amir,It's the same for both %CSP.Page and %CSP.REST.Whilst the %CSP.REST does override the page method, this does not seem to affect the CONVERTINPUTSTREAM parameter.Looking at the code I suspect that the %request.Content stream is created deeper into the CSP gateway.I tested to be sure...Class Foo.Resty Extends %CSP.REST{Parameter CONVERTINPUTSTREAM = 1;XData UrlMap{<Routes> <Route Url="/echo" Method="POST" Call="Echo" Cors="false" /></Routes>}ClassMethod Echo(){ set data=%request.Content.Read(32000) set ^foo2=data write ^foo2 Quit $$$OK}} With CONVERTINPUTSTREAM set to 1 I sent{"test":"Hello áéíóúçÁÉÍÓÚ World"]}and it returned{"test":"Hello áéíóúçÁÉÍÓÚ World"]}and the storage looks fine as well>zzdump ^foo2 0000: 7B 22 74 65 73 74 22 3A 22 48 65 6C 6C 6F 20 E1 {"test":"Hello á0010: E9 ED F3 FA E7 C1 C9 CD D3 DA 20 57 6F 72 6C 64 éíóúçÁÉÍÓÚ World0020: 22 5D 7D "]}As before, if I fail to set the content type in my JavaScript request object then the conversion does not happen.Sean.
go to post Sean Connelly · May 12, 2017 yep, typing to fast again, good job we have the human lint tool at hand :)
go to post Sean Connelly · May 12, 2017 OK, something a little more sophisticated, I've bashed out a class method that should do this for you... ClassMethod ObjectToArray(pObject, Output pArray){ kill pArray if '$IsObject(pObject) Quit "" set rs=##class(%ResultSet).%New("%DynamicQuery:SQL") set sc=rs.Prepare("select Name, RuntimeType, Type from %Dictionary.CompiledProperty where parent=? and NOT Name [ '%'") set sc=rs.Execute(pObject.%ClassName(1)) while rs.Next() { set property=rs.Data("Name") try { set pArray(property)=$PROPERTY(pObject,rs.Data("Name")) } catch duff { } } if pObject.%ClassName(1)="%CSP.Request" Merge pArray("CgiEnvs")=pObject.CgiEnvs Merge pArray("Cookies")=pObject.Cookies} Just call it for each object you wanted converted to an array, merge that into a global or dump it out to pre tags as before, e.g. write "<h2>Request</h2><pre>" do ..ObjectToArray(%request,.array) zw array write "</pre><br><h2>Session</h2><pre>" do ..ObjectToArray(%session,.array) zw array write "</pre><br><h2>Response</h2><pre>" do ..ObjectToArray(%response,.array) zw array write "</pre>" Quit $$$OK And you should get this... Request array("AppData")=$lb("",8224,0,"","/csp/healthshare/","Ensemble Management Portal",1,"","",0,1,"","","/csp/healthshare/r","R","","H:\intersystems\CSP\healthshare\r",1,"%Ens_Portal","",2,"",900,2,2,"",3600,0,1,1,"%ISCMgtPortal",1,"","") array("AppMatch")="/csp/healthshare/r/" array("Application")="/csp/healthshare/r/" array("CSPGatewayRequest")=1 array("CgiEnvs","COMSPEC")="E:\WINDOWS\system32\cmd.exe" array("CgiEnvs","CONTENT_LENGTH")=0 array("CgiEnvs","CONTEXT_DOCUMENT_ROOT")="H:/InterSystems/CSP/" array("CgiEnvs","CONTEXT_PREFIX")="/csp/" array("CgiEnvs","CSP_ORIGINAL_FILE")="" array("CgiEnvs","ComSpec")="E:\WINDOWS\system32\cmd.exe" array("CgiEnvs","DOCUMENT_ROOT")="H:/InterSystems/CSP" array("CgiEnvs","GATEWAY_INTERFACE")="CGI/1.1" array("CgiEnvs","HTTP_ACCEPT")="text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" array("CgiEnvs","HTTP_ACCEPT_ENCODING")="gzip, deflate, sdch, br" array("CgiEnvs","HTTP_ACCEPT_LANGUAGE")="en-US,en;q=0.8" array("CgiEnvs","HTTP_CONNECTION")="keep-alive" array("CgiEnvs","HTTP_COOKIE")="CSPSESSIONID-SP-13333-UP-csp-healthshare-=000000010000nKXcB0rA4r0000Z7RqCT1zYzo6RsrYydAinQ--; CacheBrowserId=zN0TSZMio2VoHmBqhiKm1A--; state-B3B82FCB-2C53-4D41-8B47-CC389A5C7606=SYSEXP%3A1; Username=sean; CSPWSERVERID=fce6d9ad0b3878fbbaef4ad2ad576c9e14c732d1" array("CgiEnvs","HTTP_HOST")="localhost:13333" array("CgiEnvs","HTTP_UPGRADE_INSECURE_REQUESTS")=1 array("CgiEnvs","HTTP_USER_AGENT")="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36" array("CgiEnvs","PATH")="E:\ProgramData\Oracle\Java\javapath;E:\Program Files (x86)\Intel\iCLS Client\;E:\Program Files\Intel\iCLS Client\;E:\WINDOWS\system32;E:\WINDOWS;E:\WINDOWS\System32\Wbem;E:\WINDOWS\System32\WindowsPowerShell\v1.0\;E:\Program Files\Intel\Intel(R) Management Engine Components\DAL;E:\Program Files\Intel\Intel(R) Management Engine Components\IPT;E:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;E:\Program Files (x86)\Intel\Intel(R) Management Engine Components\IPT;E:\Program Files (x86)\QuickTime\QTSystem\;E:\Program Files (x86)\Git\cmd;E:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;E:\WINDOWS\system32;E:\WINDOWS;E:\WINDOWS\System32\Wbem;E:\WINDOWS\System32\WindowsPowerShell\v1.0\;E:\Program Files (x86)\Pandoc\;E:\Program Files (x86)\Microsoft SQL Server\Client SDK\ODBC\130\Tools\Binn\;E:\Program Files (x86)\Microsoft SQL Server\130\Tools\Binn\;E:\Program Files (x86)\Microsoft SQL Server\130\DTS\Binn\;E:\Program Files (x86)\Microsoft SQL Server\130\Tools\Binn\ManagementStudio\;E:\Program Files (x86)\Skype\Phone\;E:\Program Files\Microsoft SQL Server\Client SDK\ODBC\110\Tools\Binn\;E:\Program Files (x86)\Microsoft SQL Server\120\Tools\Binn\;E:\Program Files\Microsoft SQL Server\120\Tools\Binn\;E:\Program Files\Microsoft SQL Server\120\DTS\Binn\;E:\Program Files\nodejs\;E:\WINDOWS\system32\config\systemprofile\AppData\Local\Microsoft\WindowsApps" array("CgiEnvs","PATHEXT")=".COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC" array("CgiEnvs","PATH_TRANSLATED")="H:/InterSystems/CSP/csp/healthshare/r/Foo.Session.cls" array("CgiEnvs","QUERY_STRING")="" array("CgiEnvs","REMOTE_ADDR")="::1" array("CgiEnvs","REMOTE_PORT")=53822 array("CgiEnvs","REQUEST_METHOD")="GET" array("CgiEnvs","REQUEST_SCHEME")="http" array("CgiEnvs","REQUEST_URI")="/csp/healthshare/r/Foo.Session.cls" array("CgiEnvs","SCRIPT_FILENAME")="H:/InterSystems/CSP/healthshare/r/Foo.Session.cls" array("CgiEnvs","SCRIPT_NAME")="/csp/healthshare/r/Foo.Session.cls" array("CgiEnvs","SERVER_ADDR")="::1" array("CgiEnvs","SERVER_ADMIN")="[no address given]" array("CgiEnvs","SERVER_NAME")="localhost" array("CgiEnvs","SERVER_PORT")=13333 array("CgiEnvs","SERVER_PORT_SECURE")=0 array("CgiEnvs","SERVER_PROTOCOL")="HTTP/1.1" array("CgiEnvs","SERVER_SIGNATURE")="" array("CgiEnvs","SERVER_SOFTWARE")="Apache Cache_Server_Pages-Apache_Module/2014.1.1.702.0-1401.1419b" array("CgiEnvs","SystemRoot")="E:\WINDOWS" array("CgiEnvs","WINDIR")="E:\WINDOWS" array("CgiEnvs","windir")="E:\WINDOWS" array("CharSet")="utf-8" array("Content")="" array("ContentType")="" array("Cookies","CSPWSERVERID",1)="fce6d9ad0b3878fbbaef4ad2ad576c9e14c732d1" array("Cookies","CacheBrowserId",1)="zN0TSZMio2VoHmBqhiKm1A--" array("Cookies","Username",1)="sean" array("Cookies","state-B3B82FCB-2C53-4D41-8B47-CC389A5C7606",1)="SYSEXP%3A1" array("GatewayApplication")="/csp" array("GatewayBuild")="661.1401.1419b" array("GatewayConnectionName")="LOCAL" array("GatewayError")="" array("GatewayFunctions")=7 array("GatewayInstanceName")="alien:13333" array("GatewayNewId")=0 array("GatewaySessionCookie")="CSPSESSIONID-SP-13333-UP-csp-healthshare-" array("GatewayTimeout")=60 array("Method")="GET" array("PageName")="Foo.Session.cls" array("Protocol")="HTTP/1.1" array("RequestId")="2E98" array("Secure")=0 array("URL")="/csp/healthshare/r/Foo.Session.cls" array("URLPrefix")="" array("UserAgent")="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36" Session array("AppTimeout")=900 array("Application")="/csp/healthshare/r/" array("ApplicationLicenses")="" array("BrowserName")="Safari" array("BrowserPlatform")="Windows" array("BrowserVersion")=537.36 array("ByIdGroups")=$lb("%iscmgtportal:zN0TSZMio2VoHmBqhiKm1A--") array("CSPSessionCookie")="000000010000nKXcB0rA4r0000Z7RqCT1zYzo6RsrYydAinQ--" array("CookiePath")="/csp/healthshare/" array("CreateTime")="2017-05-12 13:51:19" array("Debug")=0 array("EndSession")=0 array("ErrorPage")="" array("EventClass")="" array("GetNewId")=0 array("GroupId")="%iscmgtportal:zN0TSZMio2VoHmBqhiKm1A--" array("HttpAuthorization")="" array("KeepAlive")=1 array("Key")="è$½Wò"_$c(31)_"qÎ3ñ3fy"_$c(132,30,3) array("Language")="en-us" array("LastModified")="2017-05-12 14:06:57" array("LicenseId")="sean@127.0.0.1" array("LogoutCleanup")=0 array("MessageNumber")=2 array("Namespace")="R" array("NewSession")=0 array("OldTimeout")=5565507717 array("Preserve")=0 array("ProcessId")="" array("RunNamespace")="" array("SOAPRequestCount")=0 array("SecureSessionCookie")=0 array("SecurityContext")=$lb("sean","%All","%All",32,-559038737) array("SessionId")="nKXcB0rA4r" array("StickyLogin")="" array("UseSessionCookie")=2 array("UserAgent")="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36" array("Username")="sean" array("nosave")=0 Response array("CharSet")="utf-8" array("ContentLength")="" array("ContentType")="text/html" array("CookiePath")="/csp/healthshare/" array("Domain")="" array("Expires")="Thu, 29 Oct 1998 17:04:19 GMT" array("GzipOutput")="" array("HTTPVersion")="" array("HeaderCharSet")="" array("InProgress")=1 array("Language")="en-us" array("NoCharSetConvert")=0 array("OutputSessionToken")=1 array("Redirect")="" array("ServerSideRedirect")="" array("Status")="200 OK" array("Timeout")="" array("TraceDump")=0 array("UseASPredirect")=0 array("UseHttpOnly")=1 array("VaryByParam")=""
go to post Sean Connelly · May 12, 2017 I have something that can be adapted. It will need to handle $LB.
go to post Sean Connelly · May 12, 2017 Here is an uber simple approach...write "<h2>Request</h1><pre>"zw %requestwrite "</pre><br><h2>Session</h1><pre>"zw %sessionwrite "</pre><br><h2>Response</h1><pre>"zw %responsewrite "</pre>"
go to post Sean Connelly · May 12, 2017 There is no command like utility that I know of to do this.Classes are compiled down to routines and there is a command line utility for listing these...Do ^%RDWhilst there is no utility, you can write your own that queries the %Dictionary.CompiledClass, e.g. in SQL you can do...select * from %Dictionary.CompiledClassThere is also a quick and dirty way to list from that storage class using the following from the command line...set cn="" for set cn=$order(^oddCOM(cn)) q:cn="" if $e(cn,1)'="%",$e(cn,1,3)'="Ens",$e(cn,1,2)'="HS" write !,cn*Its a one liner but it's wrapping on the comments (cut and paste it into terminal as one line).Its a bit of a hack, but it should work. I have put a filter in so that it does not list system classes that I can think of, you might want to tinker with this to fit your needs. Remember to honor the spaces (there are two after the for and two after the quit).WARNINGYou mentioned that you have created three classes in the %SYS namespace.Be careful doing this as you can lose your code doing an upgrade.If you want to have common code that is accessible from all of your other namespaces then it is better to create a common namespace and then map that namespace to the others.Sean
go to post Sean Connelly · May 12, 2017 Thanks Evgeny,As its config data its a shame to have it converted to Base64 and then wrapped up in XML.Would be nice to see it as JSON in clear text so that it display nicely on GitHub.Guess this might not work for certain types of binary data, but should work in this instance.
go to post Sean Connelly · May 12, 2017 Hi Amir,CONVERTINPUTSTREAM looks to be a new parameter in 2016 and I have only just been looking at it myself this morning. The documentation is a little thin so I am just going on observations. Anyone, please correct me if I am getting any of this wrong.First, my understanding is that Cache is using Unicode internally. If you look at your $ZVERSION you will see a U in the build number which I believe indicates you installed Cache in the default Unicode mode.Prior to 2016. The %CSP.Content will receive a UTF-8 JSON stream as binary and will consume the raw UTF-8 content without doing any translation on it.As an example an "á" character will be sent in UTF-8 as hex C3A1. Internally this character should be stored as hex E1. Since there is no conversion the raw binary is stored as C3A1. When this character is written back out to a CSP device it will assume its Unicode and translate it to UTF-8. C3 becomes C383 and A1 becomes C2A1 which looks like á as UTF-8 symbols.We can do a simple echo test to prove some of this, this is a pre 2016 CSP page...Class Foo.Hex Extends %CSP.Page{ClassMethod OnPage() As %Status [ ServerOnly = 1 ]{ set data=%request.Content.Read(32000) set ^foo=data write ^foo Quit $$$OK}}I'm using Postman to send the following JSON string...{"test":"Hello áéíóúçÁÉÍÓÚ World"}And it echos back{"test":"Hello áéÃóúçÃÃÃÃà World"}And here is a dump of what has been stored in ^foo> zzdump ^foo 0000: 7B 22 74 65 73 74 22 3A 22 48 65 6C 6C 6F 20 C3 {"test":"Hello Ã0010: A1 C3 A9 C3 AD C3 B3 C3 BA C3 A7 C3 81 C3 89 C3 ¡Ã©ÃóúçÃ.Ã.Ã0020: 8D C3 93 C3 9A 20 57 6F 72 6C 64 22 7D .Ã.Ã. World"}As we can see the JSON string was stored exactly as it was sent. The letter á was sent as hex C3A1 and is being stored as C3A1. The dump displays these in Unicode as á and on output to CSP its converted to the UTF-8 equivalents of those symbols.Let's change the CSP page to convert the inbound UTF-8 string into Unicode...Class Foo.Hex Extends %CSP.Page{ClassMethod OnPage() As %Status [ ServerOnly = 1 ]{ set data=%request.Content.Read(32000) set ^foo=$ZCONVERT(data,"I","UTF8") write ^foo Quit $$$OK}}Now when I send{"test":"Hello áéíóúçÁÉÍÓÚ World"}I get back{"test":"Hello áéíóúçÁÉÍÓÚ World"}and in the database I have...zzdump ^foo 0000: 7B 22 74 65 73 74 22 3A 22 48 65 6C 6C 6F 20 E1 {"test":"Hello á0010: E9 ED F3 FA E7 C1 C9 CD D3 DA 20 57 6F 72 6C 64 éíóúçÁÉÍÓÚ World0020: 22 7D "}We can fix the inbound with $ZCONVERT. Note that we didn't need to fix the outbound, it was just auto converted for us. Danny mentioned needing to convert the outbound so I am guessing there is a scenario where this auto conversion is not happening. Would be interesting to understand that more. I'm guessing we need to be careful to not double convert a string if its being done automatically.On to 2016.First a test with CONVERTINPUTSTREAM set to 0Class Foo.Hex Extends %CSP.Page{Parameter CONVERTINPUTSTREAM = 0;ClassMethod OnPage() As %Status [ ServerOnly = 1 ]{ set data=%request.Content.Read(32000) set ^foo=data write ^foo Quit $$$OK}}I post{"test":"Hello áéíóúçÁÉÍÓÚ World"}and get back{"test":"Hello áéÃóúçÃÃÃÃà World"}which reflects what we have seen before and what you are experiencing.Now setting CONVERTINPUTSTREAM to 1 Class Foo.Hex Extends %CSP.Page{Parameter CONVERTINPUTSTREAM = 1;ClassMethod OnPage() As %Status [ ServerOnly = 1 ]{ set data=%request.Content.Read(32000) set ^foo=data write ^foo Quit $$$OK}}I send{"test":"Hello áéíóúçÁÉÍÓÚ World"}and get back{"test":"Hello áéíóúçÁÉÍÓÚ World"}and the database contains the correctly encoded data...zzdump ^foo 0000: 7B 22 74 65 73 74 22 3A 22 48 65 6C 6C 6F 20 E1 {"test":"Hello á0010: E9 ED F3 FA E7 C1 C9 CD D3 DA 20 57 6F 72 6C 64 éíóúçÁÉÍÓÚ World0020: 22 7D "} So it looks like setting CONVERTINPUTSTREAM to 1 negates needing to $ZCONVERT the inbound stream.Except this doesn't seem to be happing for you.I decided to try some more tests from Postman. I removed the sending content type such that it would be sent as raw text. This time I send{"test":"Hello áéíóúçÁÉÍÓÚ World"}and I get back{"test":"Hello áéÃóúçÃÃÃÃà World"}and the database containszzdump ^foo 0000: 7B 22 74 65 73 74 22 3A 22 48 65 6C 6C 6F 20 C3 {"test":"Hello Ã0010: A1 C3 A9 C3 AD C3 B3 C3 BA C3 A7 C3 81 C3 89 C3 ¡Ã©ÃóúçÃ.Ã.Ã0020: 8D C3 93 C3 9A 20 57 6F 72 6C 64 22 7D .Ã.Ã. World"}So my observations are that setting CONVERTINPUTSTREAM to 1 requires the request to include some kind of clue as to the contents encoding. This would make sense as we could be sending raw binary to one method and UTF-8 to another.So, in order to fix your problem you might want to look at your JavaScript code that sends the data.This is what I normally do in pure JavaScript...var request = new XMLHttpRequest();request.setRequestHeader('Content-Type', 'application/json; charset=utf-8');or JQuery...$.ajax({ contentType: 'application/json; charset=utf-8',});Would be nice to see some more documentation on CONVERTINPUTSTREAM so that we can be sure of this behaviour. I tried looking at its implementation but its hidden from view.Hope that helps a bit.Sean.
go to post Sean Connelly · May 10, 2017 (thanks John)I'm now looking at how to implement this with JavaScript files.In my JavaScript I will have lines of code like this...popToast("danger","Unable to open document");Since $$$Text can't be used in this context I wonder what else other developers are doing. I could fetch the JavaScript via a CSP page and replace the strings, but that feels kludgy.My initial thoughts would be to create a $$$Text JavaScript function for continuity and use it in a similar way...popToast("danger",$$$Text("MyApp","Unable to open document"));The localisation file would be loaded on application start (or when the language is changed), something along the lines of.../csp/myapp/localisation.cls?domain=MyApp&lang=defaultSpin the global out into JSON..."MyApp" : { "en" : { "1243066710" : "Hello World" }}$$$Text would be something like...var $$$Text = function(domain,phrase) { var hash = someHashFunction(phrase) // ?? return locals[domain][defaultLanguage][hash]}The next question is, what hashing algorithm is Cache using to create the hash?I will need to replicate that in JavaScript, or come up with some other hash approach.I've also noticed that the samples does not use this hash, instead it uses a man made key, but using that key with $$$Text in COS just creates a hash which seems odd. Any explanations for that?
go to post Sean Connelly · May 10, 2017 This is what I have found out so far, it wasn't clear in the documentation.Snippets of strings (labels, phrases, sentences etc) are held in the global ^CacheMsg keyed on domain, language and some kind of hash of the string, e.g.^CacheMsg("Foo","en",1243066710)="Hello World"^CacheMsg("Foo","ru",1243066710)="Привет мир"If I use $$$Text this way...write $$$Text("Hello World","Foo","ru")Then it compiles down to...write $get(^CacheMsg("Foo","ru","1243066710"),"Hello World")I assume therefore that I can dynamically control the language by doing something along the lines of...write $$$Text("Hello World","Foo",%Session.Language)where I set the language in the session object after the users selection.Alternatively I can use $$$Text with just the first two parameters (no language specified) and it will compile to...write $get(^CacheMsg("Foo",$s($mvv(58)="":"en",1:$mvv(58)),"1243066710"),"Hello World")Where the language will either be set by the value of $mvv(58) or if null defaults to English.I assume $mvv(58) is set by the system when its installed? But can't find any information on that at the moment.The documentation talks about using an XML file to manage the languages, which seems a bit kludgy. I guess mainly to give to an interpretor to edit. I assume then that the Caché Localisation Manager just works off the ^CacheMsg global and not the XML files, and would be a better way to manage the localisations.In terms of deployment I guess the best solution would be to just include all of the languages as a global export and have it imported with the main body of the code.
go to post Sean Connelly · May 10, 2017 These articles by Brendan Bannon might help...https://community.intersystems.com/user/21/posts
go to post Sean Connelly · May 8, 2017 As a side thought. If all you want is an image in the PDF file and no text then you might also want to take a look at...http://www.imagemagick.org/script/index.phpwhich is another battle tested library.I have used it for image to image but not image to PDF so can't confirm how good it is.
go to post Sean Connelly · May 8, 2017 Hi Randy,I've been around the block on this problem.There is no simple native solution. I have tried to create a native COS to PDF generator but its a much bigger problem than time affords.I know you are asking for a solution that does not include creating a web page, BUT, with exception of going to some other document type (e.g. DOC to PDF) you really have no other easy choice.However, there is a better way than Zen reports to implement this (IMHO). I use wkhtmltopdf...https://wkhtmltopdf.org/It's an executable that takes the name of an HTML file and produces a PDF file. You can also control headers, page numbers etc with it. It's rock solid and really easy to use.Essentially...1. Create a simple HTML string with an img tag and save it to a file.2. Call out to wkhtmltopdf using $ZF passing in the name of the filesDone.If you want to be clever and not save the image to a linked file then you can take its base64 directly from the HL7 message and embed it into the img tag, e.g.<img src="data:image/png;base64,iVBORw0KGgo...">I have wkhtmltopdf running at numerous hospitals turning out upwards of 10,000 letters a day, rock solid, no problems.Hope that helps.Sean.