go to post Marc Mundt · Jun 13, 2019 The resulting XML files can be imported again using %System.OBJ.Load().If you prefer GOF format you can use %Global.Export() instead, however it doesn't accept wildcards so you would need to first put together a list of which globals you want to export.For automation you can execute these methods from your own custom class or routine. If you want to schedule it to run automatically, you can create your custom class as a %SYS.Task.Definition and schedule it to run using Task Manager.You're correct -- you can't restore specific globals from an Online Backup (.cbk) file.
go to post Marc Mundt · Jun 13, 2019 Have a look at %System.OBJ.Export():https://irisdocs.intersystems.com/irisforhealth20192/csp/documatic/%25CSP.Documatic.cls TESTING>s itm="*.GBL" TESTING>s file="C:\Projects\export_mm.xml" TESTING>d $System.OBJ.Export(.itm,.file,,.errors) Having said that, since this is just for backups you might also consider just using the standard Online Backup utility which will backup all globals in the selected database(s) into a file: https://irisdocs.intersystems.com/irisforhealth20192/csp/docbook/DocBook.UI.Page.cls?KEY=GCDI_backup#GCDI_backup_methods_online
go to post Marc Mundt · Jun 6, 2019 Or it looks like I was handling the zero issue manually: if $L(tHexByte)=1 s tHexByte="0"_tHexByte
go to post Marc Mundt · Jun 6, 2019 Here's a (very simple) working example of uploading to an AWS S3 bucket. I used essentially the same approach that Cliff originally used to generate the hex. I didn't experience the same problem, but I may have just been lucky and not had any zeroes in the value I'm converting. <?xml version="1.0" encoding="UTF-8"?> <Export generator="Cache" version="25" zv="Cache for Windows (x86-64) 2017.2.1 (Build 801_3U)" ts="2018-10-04 08:14:32"> <Class name="Demo.Cloud.Storage.Util"> <Super>%RegisteredObject</Super> <TimeChanged>64925,29407.276303</TimeChanged> <TimeCreated>64924,56047.115234</TimeCreated> <Method name="TestS3Upload"> <ClassMethod>1</ClassMethod> <Implementation><![CDATA[ set tAccessKeyId="[Shh... it's a secret]" set tSecretAccessKey="[Shh... it's a secret]" set tAWSRegion="us-east-1" set tAWSService="s3" set tHost="s3.us-east-1.amazonaws.com" set tPort="443" set tBucket="MyBucket12345" set tContentType="text/plain; charset=UTF-8" set tSSLConfig="AWS" set tUseHTTPS=1 set tContentStream=##class(%Stream.TmpCharacter).%New() do tContentStream.Write("this is some test content oh yeah!") do tContentStream.Rewind() set tHorolog=$h set tDateKey=$System.Encryption.HMACSHA(256,$ZD(tHorolog,8),"AWS4"_tSecretAccessKey) set tDateRegionKey=$System.Encryption.HMACSHA(256,tAWSRegion,tDateKey) set tDateRegionServiceKey=$System.Encryption.HMACSHA(256,tAWSService,tDateRegionKey) set tSigningKey=$System.Encryption.HMACSHA(256,"aws4_request",tDateRegionServiceKey) set tHashedPayload=..BytesToHex($System.Encryption.SHAHashStream(256,tContentStream,.tSC)) set tTmpTime=$ZDT(tHorolog,2,7) set tHeaderDate=$ZD(tHorolog,11)_", "_$E(tTmpTime,1,11)_" "_$E(tTmpTime,13,*-1)_" GMT" set tAmzDate=$TR($zdt(tHorolog,8,7),":","") set tKeyName="test_"_tHorolog_".txt" set tCanonicalURI="/"_tBucket_"/"_tKeyName set tCanonicalURI=$zconvert(tCanonicalURI,"O","URL") set tHttpVerb="PUT" set tCanonicalHeaders="content-length:"_tContentStream.Size_$c(10)_"content-type:"_tContentType_$c(10)_"host:"_tHost_$c(10)_"x-amz-content-sha256:"_tHashedPayload_$c(10)_"x-amz-date:"_tAmzDate_$c(10) set tSignedHeaders="content-length;content-type;host;x-amz-content-sha256;x-amz-date" set tCanonicalRequest=tHttpVerb_$c(10)_tCanonicalURI_$c(10,10)_tCanonicalHeaders_$c(10)_tSignedHeaders_$c(10)_tHashedPayload set tStringToSign="AWS4-HMAC-SHA256"_$c(10)_$TR($zdt(tHorolog,8,7),":","")_$c(10)_$zd(tHorolog,8)_"/"_tAWSRegion_"/"_tAWSService_"/aws4_request"_$c(10)_..BytesToHex($System.Encryption.SHAHash(256,tCanonicalRequest)) set tSignature=..BytesToHex($System.Encryption.HMACSHA(256,tStringToSign,tSigningKey)) set tAuthHeader="AWS4-HMAC-SHA256 Credential="_tAccessKeyId_"/"_$zd(tHorolog,8)_"/"_tAWSRegion_"/"_tAWSService_"/aws4_request,SignedHeaders="_tSignedHeaders_",Signature="_tSignature set tHReq=##class(%Net.HttpRequest).%New() set tHReq.Server=tHost set tHReq.Port=tPort set tHReq.SSLConfiguration=tSSLConfig set tHReq.Https=tUseHTTPS do tHReq.SetHeader("Authorization",tAuthHeader) do tHReq.SetHeader("Content-Type","text/plain") do tHReq.SetHeader("Content-Length",tContentStream.Size) do tHReq.SetHeader("Host",tHost) do tHReq.SetHeader("x-amz-content-sha256",tHashedPayload) do tHReq.SetHeader("x-amz-date",tAmzDate) do tHReq.EntityBody.CopyFrom(tContentStream) //do tHReq.OutputHeaders() s tSC=tHReq.Put(tCanonicalURI) do $System.OBJ.DisplayError(tSC) write "Status Code:",tHReq.HttpResponse.StatusCode,! //Do tHReq.HttpResponse.OutputToDevice() if $isobject(tHReq.HttpResponse.Data) { s ^zresp=tHReq.HttpResponse.Data.Read(1000000) } else { s ^zresp=tHReq.HttpResponse.Data } ]]></Implementation> </Method> <Method name="BytesList"> <ClassMethod>1</ClassMethod> <FormalSpec>pBytes:%String</FormalSpec> <ReturnType>%String</ReturnType> <Implementation><![CDATA[ s l=$LISTFROMSTRING(pBytes," ") f i=1:1:$LL(l) s st=$G(st)_$CHAR($ZHEX($LISTGET(l,i))) return st ]]></Implementation> </Method> <Method name="BytesToHex"> <ClassMethod>1</ClassMethod> <FormalSpec>pBytes:%String</FormalSpec> <ReturnType>%String</ReturnType> <Implementation><![CDATA[ set tHex="" for i=1:1:$L(pBytes) { set tHexByte=$ZHEX($ASCII($E(pBytes,i))) if $L(tHexByte)=1 s tHexByte="0"_tHexByte set tHex=tHex_tHexByte } return $ZCONVERT(tHex,"L") ]]></Implementation> </Method> </Class> </Export>
go to post Marc Mundt · Apr 12, 2019 Yes, you can loop through items in your source document and generate one HL7 message for each. In this case the looping would be done in a business process (BPL), and you would call the transformation once for each outbound HL7 message.
go to post Marc Mundt · Apr 10, 2019 Have you tried setting "DefCharEncoding" to UTF-8 in the settings for EnsLib.HL7.Operation.HTTPOperation?Here are the details from the popup-help. Especially note the highlighted line. Using "!UTF-8" will cause the operation to ignore what's in MSH:18 and always use UTF-8. Default Character Encoding to use when reading or writing HL7 messages. If MSH field 18 (Character Set) is empty, this encoding will be used. Choices you can use for this setting include: Native: Use the default character encoding of the installed locale of the IRIS server. latin1: The ISO Latin1 8-bit encoding. This is the default. ISO-8859-1: The ISO Latin1 8-bit encoding. UTF-8: The Unicode 8-bit encoding. Unicode: The Unicode 16-bit encoding (Little-Endian). UnicodeBig: The Unicode 16-bit encoding (Big-Endian). Any other NLS definitions installed on this IRIS server. @<ttable>: <ttable> means a raw InterSystems character translation table name. A prefix of '@' means to use the named table. Putting ! before the encoding name will force the use of the named encoding and will ignore any value found in MSH:18.
go to post Marc Mundt · Apr 10, 2019 Hi Joseph,I developed something like this for a POC last year. It includes wizards to generate Business Services and Business Operations and related message objects based on a source query or stored procedure.It's not currently in a state where I can share it, but I'm planning to eventually clean it up and post it on Open Exchange. I'll let you know when I do.-Marc
go to post Marc Mundt · Feb 19, 2019 What about setting "Reply Code Actions" to "E=D" and enabling "Alert on Error"?From the reply code actions help text:"D - Disable the Process, log an error and restore the original incoming message to the front of the Process's queue."
go to post Marc Mundt · Jan 25, 2019 For current versions, the approach I've seen customers use is to create a business operation using the HL7 or XML outbound file adapter. In Message Viewer you can then "resend" the messages you want to the new business operation.I'm happy to say that we've added a way to download multiple messages directly from Message Viewer. This hasn't been released yet but will be soon. For more details on this and other upcoming features, have a look at this presentation.
go to post Marc Mundt · Jan 22, 2019 Hi Guillaume,Here's some rough code showing how to use executeParametersBatch. I put this together from a few other working examples I had but I haven't tested this actual code and it may have bugs.As always, this is provided as sample code only and is not meant for production use :)-Marc set pSQLStatement="INSERT INTO Test.Table (Field1,Field2) VALUES (?,?)" // JDBCGwy is an instance of the JDBC Gateway object. EnsLib.SQL.OutboundAdapter instantiates this automatically and stores a reference to it in ..%Connection.%JGProxy // Prepare the SQL statement set pHS=JDBCGwy.prepareStatement(ConnHandle,pSQLStatement) // executeParametersBatch expects tArgs to be a $LIST, with the following format: // ParamCount, ParamSets, Type1, Param1, Type2, Param2, Type3, Param3, Type11,Param11… TypeNN,ParamNN // // ParamCount is the number of parameters the query expects (in this example 2) // ParamSets is the number of rows we will be inserting in this batch // Type1, Type2, ..., TypeN is an integer indicating the JDBC data type for the corresponding Param value (e.g. Param1, Param2, ..., ParamN) // Param1, Param2, ..., ParamN is the value for the query parameter set $LIST(tArgs,1)=2 // The query has two parameters ("?") in it set $LIST(tArgs,2)=3 // We will insert 3 rows in this batch // Row 1 ------------------------------------------------------------- // Set the value for the first column (Field1VarChar) set $LIST(tArgs,3)=12 // The JDBC data type for varchar is 12 set $LIST(tArgs,4)="String value 1" // Value for column Field1VarChar // Set the value for the second column (Field2Integer) set $LIST(tArgs,5)=4 // The JDBC data type for integer is 4 set $LIST(tArgs,6)=7 // Value for column Field2Integer // Row 2 ------------------------------------------------------------- // Set the value for the first column (Field1VarChar) set $LIST(tArgs,7)=12 // The JDBC data type for varchar is 12 set $LIST(tArgs,8)="String value 2" // Value for column Field1VarChar // Set the value for the second column (Field2Integer) set $LIST(tArgs,9)=4 // The JDBC data type for integer is 4 set $LIST(tArgs,10)=123 // Value for column Field2Integer // Row 3 ------------------------------------------------------------- // Set the value for the first column (Field1VarChar) set $LIST(tArgs,11)=12 // The JDBC data type for varchar is 12 set $LIST(tArgs,12)="String value 3" // Value for column Field1VarChar // Set the value for the second column (Field2Integer) set $LIST(tArgs,13)=4 // The JDBC data type for integer is 4 set $LIST(tArgs,14)=54 // Value for column Field2Integer // Perform the batch insert // tResultCodes is a $LIST of integers indicating success/failure for each row in the batch set tResultCodes=JDBCGwy.executeParametersBatch(pHS,tArgs)
go to post Marc Mundt · Jan 15, 2019 You can stop a business process completely (along with all other components) by stopping the production:https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY...To only stop a specific business process, you can disable that specific component:https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY...You can also view the status of and manage individual jobs that are doing processing for the business process:https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY...
go to post Marc Mundt · Jan 7, 2019 In the case of moving from AIX to Windows, you're not just changing the OS but also changing the platform (IBM Power to Intel).As Dmitry said, there's no relation to the OS but there is an important issue when changing platforms: endianness. AIX on Power is big-endian while Windows/Linux/etc. on Intel are little-endian.The upshot is: when moving a cache.dat from AIX to Windows you'll need to run an included utility to convert it from big-endian to little-endian.
go to post Marc Mundt · Nov 9, 2018 CAPTION values won't be added to the URL automatically. The result of the sample code you posted would be:https://npiregistry.cms.hhs.gov/api?q=NPI-1CAPTION is generally used to set the label text for a property when displaying it in a user interface. It's used extensively in Zen:https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY...
go to post Marc Mundt · Nov 9, 2018 This came up in an earlier post:https://community.intersystems.com/post/fromjson-doesnt-support-stream-p...I believe this will be addressed in a future release.
go to post Marc Mundt · Nov 9, 2018 You can do this with the $CLASSMETHOD function in ObjectScript:https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY... ClassMethod someMethod(className As %String) { set classObject = $CLASSMETHOD(className,"%New") ... }
go to post Marc Mundt · Nov 2, 2018 This won't help you in the short term, but upcoming versions will include a nice feature to export messages from the message search page. For more details, have a look at this presentation from this year's InterSystems Global Summit.https://learning.intersystems.com/course/view.php?id=1015For the short term, most people use the suggestion from @Julian Matthews of adding a new file out business operation and resending the messages to it.
go to post Marc Mundt · Oct 24, 2018 Joao, just wanted to check with you... did it work after adding quotation marks?
go to post Marc Mundt · Oct 18, 2018 I'm assuming that the source message includes the email address in PID:13.4 and that your DTL is set to "copy" mode?If so, you can add a "set" action to set the value of PID:13.4 to an empty string ("").
go to post Marc Mundt · Oct 16, 2018 Some business operations that use EnsLib.File.OutboundAdapter will pull the value for %f from a property in the request object. This would allow you to set that property in a DTL before sending it to the business operation.But, it looks like you're using EnsLib.XML.Object.Operation.FileOperation, which doesn't do this. It uses the class name of the inbound object as the value for %f.To create a filename programmatically with EnsLib.XML.Object.Operation.FileOperation, you can create a custom class that extends EnsLib.XML.Object.Operation.FileOperation and override the OnMessage() method. The relevant line in the standard OnMessage method is this. You can replace this with your custom logic: // Create output filename using the class name of the persistent class as the base. Set tFilename=..Adapter.CreateFilename($classname(pRequest),..Filename)