Hi Unai,

What you’re trying to do—triggering a process based on a database insert—is a common pattern. However, using a SQL trigger to directly start a production or business process isn’t recommended in IRIS.

SQL triggers execute within the database transaction, and invoking interoperability logic from there can lead to locking issues, transaction rollbacks, and performance concerns.

The typical and safest approach is to use an EnsLib.SQL.InboundAdapter to poll the table for new records. For example, you can:

Add a flag column (e.g., Processed = 0)

Configure the adapter with a query like:

SELECT * FROM YourTable WHERE Processed = 0
After processing, update the record to mark it as processed

This keeps your database operations and interoperability processing cleanly separated, and it aligns with standard IRIS patterns.

If you need near real-time behavior, you can tune the polling interval to be very short.

Hope that helps point you in the right direction.

Hi Scott,

What you’re running into is less about FHIR or DTL and more about how IRIS handles response routing via message headers and session context.

A couple key points that should help:


1. Don’t route the response through the Rule Engine

The Rule Engine is intended for request routing, not for sending responses back. If you send your FHIR response there, it won’t automatically know how to get back to the original caller.


2. Use the built-in request/response pattern

If your Business Process is calling out to another operation (your external FHIR repo), the easiest and most reliable approach is:

Set tSC = ..SendRequestSync("Your.FHIR.Operation", pRequest, .tResponse)
Set pResponse = tResponse
Quit $$$OK

This preserves the session and ensures IRIS automatically routes the response back to the original Source Config Name.


3. You don’t need matching message types

It’s perfectly fine that your response is an HS.FHIR.DTL.vR4.Model.Resource.* type that differs from the request. IRIS does not require the message classes to match—only that the response is returned within the same session context.


4. If you go off-pattern, you must manage headers

If you’re not using SendRequestSync (e.g., async or custom flows), then you’ll need to explicitly preserve things like:

  • SessionId
  • SourceConfigName
  • TargetConfigName

Otherwise IRIS won’t know where to send the response.


Bottom line

You shouldn’t need to explicitly “send it back” to the Source Config. Just return the response from your Business Process (pResponse), and IRIS will take care of the routing.


Hope that helps—this is a common stumbling point when first working with BP response flows.

Hi Scott,

What you’re running into is less about FHIR or DTL and more about how IRIS handles response routing via message headers and session context.

A couple key points that should help:


1. Don’t route the response through the Rule Engine

The Rule Engine is intended for request routing, not for sending responses back. If you send your FHIR response there, it won’t automatically know how to get back to the original caller.


2. Use the built-in request/response pattern

If your Business Process is calling out to another operation (your external FHIR repo), the easiest and most reliable approach is:

Set tSC = ..SendRequestSync("Your.FHIR.Operation", pRequest, .tResponse)
Set pResponse = tResponse
Quit $$$OK

This preserves the session and ensures IRIS automatically routes the response back to the original Source Config Name.


3. You don’t need matching message types

It’s perfectly fine that your response is an HS.FHIR.DTL.vR4.Model.Resource.* type that differs from the request. IRIS does not require the message classes to match—only that the response is returned within the same session context.


4. If you go off-pattern, you must manage headers

If you’re not using SendRequestSync (e.g., async or custom flows), then you’ll need to explicitly preserve things like:

  • SessionId
  • SourceConfigName
  • TargetConfigName

Otherwise IRIS won’t know where to send the response.


Bottom line

You shouldn’t need to explicitly “send it back” to the Source Config. Just return the response from your Business Process (pResponse), and IRIS will take care of the routing.


Hope that helps—this is a common stumbling point when first working with BP response flows

Hi Scott,

What you’re running into is less about FHIR or DTL and more about how IRIS handles response routing via message headers and session context.

A couple key points that should help:


1. Don’t route the response through the Rule Engine

The Rule Engine is intended for request routing, not for sending responses back. If you send your FHIR response there, it won’t automatically know how to get back to the original caller.


2. Use the built-in request/response pattern

If your Business Process is calling out to another operation (your external FHIR repo), the easiest and most reliable approach is:

Set tSC = ..SendRequestSync("Your.FHIR.Operation", pRequest, .tResponse)
Set pResponse = tResponse
Quit $$$OK

This preserves the session and ensures IRIS automatically routes the response back to the original Source Config Name.


3. You don’t need matching message types

It’s perfectly fine that your response is an HS.FHIR.DTL.vR4.Model.Resource.* type that differs from the request. IRIS does not require the message classes to match—only that the response is returned within the same session context.


4. If you go off-pattern, you must manage headers

If you’re not using SendRequestSync (e.g., async or custom flows), then you’ll need to explicitly preserve things like:

  • SessionId
  • SourceConfigName
  • TargetConfigName

Otherwise IRIS won’t know where to send the response.


Bottom line

You shouldn’t need to explicitly “send it back” to the Source Config. Just return the response from your Business Process (pResponse), and IRIS will take care of the routing.


Hope that helps—this is a common stumbling point when first working with BP response flows.

Hi Scott,

What you’re running into is less about FHIR or DTL and more about how IRIS handles response routing via message headers and session context.

A couple key points that should help:

1. Don’t route the response through the Rule Engine

The Rule Engine is intended for request routing, not for sending responses back. If you send your FHIR response there, it won’t automatically know how to get back to the original caller.

2. Use the built-in request/response pattern

If your Business Process is calling out to another operation (your external FHIR repo), the easiest and most reliable approach is:

Set tSC = ..SendRequestSync("Your.FHIR.Operation", pRequest, .tResponse)
Set pResponse = tResponse
Quit $$$OK

This preserves the session and ensures IRIS automatically routes the response back to the original Source Config Name.

3. You don’t need matching message types

It’s perfectly fine that your response is an HS.FHIR.DTL.vR4.Model.Resource.* type that differs from the request. IRIS does not require the message classes to match—only that the response is returned within the same session context.

4. If you go off-pattern, you must manage headers

If you’re not using SendRequestSync (e.g., async or custom flows), then you’ll need to explicitly preserve things like:

SessionId
SourceConfigName
TargetConfigName

Otherwise IRIS won’t know where to send the response.

Bottom line

You shouldn’t need to explicitly “send it back” to the Source Config. Just return the response from your Business Process (pResponse), and IRIS will take care of the routing.

Hope that helps—this is a common stumbling point when first working with BP response flows.

Hi

If I had to guess I would say that in iis you have an app defined /test that is tied to the web gateway.


In your example that doesn’t work you are redirecting to a path /mobile/…


I would guess you might not have an app defined under your /mobile path that is tied to the web gateway

Hello Yone,

Thank you for raising this question. While the HealthShare / InterSystems Management Portal does not currently provide a built-in dark mode option, there are a few approaches that can make the interface easier on the eyes. The available options depend somewhat on the browser and device you are using.

Option 1 — Browser Extensions (Desktop Chrome / Edge / Firefox)

On desktop browsers, the most effective workaround is to use an extension that forces a dark theme on websites.

One commonly used extension is Dark Reader, which dynamically converts page styles to a dark theme and usually works reasonably well with the Management Portal.

Steps for Chrome on desktop:

  1. Open the Chrome Web Store
  2. Install the Dark Reader extension
  3. After installation, click the Dark Reader icon near the address bar
  4. Toggle it on while viewing the Management Portal

Dark Reader also allows adjustments to brightness, contrast, and sepia levels, which can help reduce eye strain.

Option 2 — Chrome on iPhone

Chrome on iOS unfortunately does not support browser extensions, so extensions such as Dark Reader cannot be used within Chrome on an iPhone or iPad.

For iPhone users, the options are limited to:

  • Enabling system dark mode (Settings → Display & Brightness → Dark)
  • Using Accessibility features like Smart Invert (Settings → Accessibility → Display & Text Size → Smart Invert)

These can help somewhat but typically will not fully convert the Management Portal interface.

Option 3 — Safari on iPhone (Recommended Mobile Solution)

Safari on iOS does support browser extensions, so you can use Dark Reader there.

Steps:

  1. Install Dark Reader from the App Store
  2. Go to Settings → Safari → Extensions
  3. Enable Dark Reader
  4. Open the HealthShare Management Portal in Safari

Once enabled, Safari will apply the dark theme to the portal pages.

Option 4 — Custom CSS Overrides

Some users also experiment with browser tools or extensions (such as Stylus) to apply custom CSS that forces darker backgrounds. However, this approach is not officially supported and may break with portal updates.

Future Support

At the moment I’m not aware of any native dark mode support in the Management Portal itself. Accessibility improvements like this would be a great candidate for an enhancement request through the InterSystems Ideas Portal.

Hopefully one of the browser-based options can help reduce eye strain when working in the portal.

Best regards.

Yes — you’re correct to think about that edge case.

If you read the stream in fixed-size chunks (e.g., Read(32000)), a simple tChunk[pNeedle search can miss matches where the target string spans the boundary between two reads. For example, "HITL" could appear as "HI" at the end of one chunk and "TL" at the beginning of the next.

A common solution is to keep a small overlap buffer from the end of the previous chunk and prepend it to the next chunk before searching. The overlap only needs to be ($Length(pNeedle)-1) characters.

The general pattern looks like this:

  1. Read the next chunk from the stream
  2. Prepend the trailing characters from the previous iteration
  3. Search the combined buffer
  4. Preserve the last (needle length - 1) characters as the next overlap
  5. Continue until a match is found or the stream ends
  6. Rewind the stream before returning so downstream components can still read it

Here’s an example implementation

Class MyApp.Rule.Functions Extends Ens.Rule.FunctionSet
{
ClassMethod StreamContains(
   pMsg As EnsLib.HTTP.GenericMessage,
   pNeedle As %String = "HITL"
   ) As %Boolean
{
   Set tSC = $$$OK
   Set tFound = 0
   Set tTail = ""
   Set tChunkLen = 32000
   Set tNeedleLen = $Length(pNeedle)
   Set tStream = pMsg.Stream
   If '$IsObject(tStream) Quit 0
   If pNeedle="" Quit 0
   Do tStream.Rewind()
   While ('tStream.AtEnd) && ('tFound) {
       Set tChunk = tStream.Read(tChunkLen,.tSC)
       Quit:$$$ISERR(tSC)
       Set tData = tTail _ tChunk
       If tData[pNeedle {
           Set tFound = 1
           Quit
       }
       If tNeedleLen>1 {
           Set tTail = $Extract(tData,*-(tNeedleLen-2),*)
       } Else {
           Set tTail = ""
       }
   }
   Do tStream.Rewind()
   Quit tFound
}
}

Then your routing rule condition can simply call the function:

MyApp.Rule.Functions.StreamContains(Document,"HITL")

This keeps the routing rule readable while safely inspecting the stream without consuming it.

Jenna Makin · Jan 9, 2023 go to post

Are you looking to count nodes that have data?   Will your global always be sequencially and numerically subscripted like your example?

Jenna Makin · Jul 25, 2020 go to post

Hi Ken

In ObjectScript an abstract class simply means that you can not instantiate it.   You MUST subclass it and instantiate the subclass.

The concept you understand is supported in Objectscript but it requires that you declare the method itself as abstract.

The two (abstract class keyword and abstract method keyword) work independently of each other.

Does this explain what you are seeing better?

Jenna Makin · Apr 15, 2020 go to post

Hi Yakov

First, I wouldn't implement this kind of logic in a business service.  I would have a business service that immediately passes a message to a business operation and then perform these functions there (or possibly in business operations).   Services should not be long-running which building and querying a staging table seems like it might take some time.

Jenna Makin · Mar 31, 2020 go to post

My stream definition is

Property Streams As list Of %CSP.CharacterStream;
 

I used the %CSP.CharacterStream because that is what was being created in the %request object and I figured it would be simpler to just add that stream to my collection.  

I understand why this would be stored in CacheStream as it it created by the CSP engine.   I think my solution is to use a %Stream.Character and actually copy the contents from the %CSP.CharacterStream rather than storing itself.

Jenna Makin · Mar 26, 2020 go to post

I think I may have it.  Basically I. Base64.encoding the file on the client side and will need to decide it on the server.  

I need to do a little more testing and debugging in the morning and will post the solution.

Jenna Makin · Mar 26, 2020 go to post

No.    There is another page that is the target of the HTTPRequest POST which takes the file data passed in request and stores the file into the database.   Problem is that the binary files aren't  received properly

Jenna Makin · Feb 13, 2020 go to post

If it is desirable to have the customized setting heading with distinct separate words (like in the HL7FTPService) in the production configuration view then the global CacheMsg should be updated in the related namespace (e.g. Ensemble) where the production will be running as it is shown below for the RemoteArchivePath:

  Ensemble>set ^CacheMsg("EnsColumns","en","RemoteArchivePath")="Remote Archive Path"

After that change the RemoteArchivePath setting name is shown in the view as ‘Remote Archive Path’.

Jenna Makin · Feb 6, 2020 go to post

I must not have had enough coffee today because it looks right to me.

:)

Jenna Makin · Feb 6, 2020 go to post

Interesting.   I did get this to work but don't believe it's calling the %iFind.Utils:Highlight method.   The reason I say this is that the method has extra parameters that don't correspond to the SQL %Fimd.Highlight SQL function.

Jenna Makin · Feb 6, 2020 go to post

Eduard,

I had seen that in the docs and have tried various flavors of it.  I am using embedded SQL in a classmethod here to do my search.   Here's the method

ClassMethod Search(pSessionId As %String, pSearchString As %String) As %Stream.GlobalCharacter
{
    set tTags="<span style='background-color:yellow;'>"
    &sql(
    SELECT %iFind.Highlight(Text , :pSearchString , '' , :tTags) into :results 
    FROM SSA_OCR.TempSearchable)
    quit results
}

When I try to use this, I get:

SSA>s rs=##class(SSA.OCR.TempSearchable).Search(20, "Cough")
 
 quit results }
 ^
<UNDEFINED>zSearch+7^SSA.OCR.TempSearchable.1 *results
SSA 2e1>w results
 
W results
^
<UNDEFINED>^SSA.OCR.TempSearchable.1 *results
SSA 2e1>w %objlasterror
0 àŠ=<CLASS DOES NOT EXIST>zApplyTransformation+6^%iFind.Utils.1”SSAŠ*^zApplyTransformation+6^%iFind.Utils.1^15d^zPrepareTransformations+27^%iFind.Filer.Basic.1^1(d^zFileIndex+33^%iFind.Filer.Basic.1^1*d^zFileIndex+8^%iFind.Filer.Semantic.1^1*d^zFileIndex+5^%iFind.Filer.Analytic.1^1"d^zHighlight+17^%iFind.Utils.1^1,e^%0JmCm3l4tudf^SSA.OCR.TempSearchable.1^41e^%0JmBuncommitted+1^SSA.OCR.TempSearchable.1^1(d^zSearch+6^SSA.OCR.TempSearchable.1^1e^^^0
SSA 2e1>d $System.OBJ.DisplayError(%objlasterror)
 
ERROR #5002: ObjectScript error: <CLASS DOES NOT EXIST>zApplyTransformation+6^%iFind.Utils.1
SSA 2e1>

Any thoughts on why this is erroring?

Jenna Makin · Dec 21, 2019 go to post

Ben

Check %SYSTEM.INetInfo.   I think it probably contains a method to serve your purpose 

Jenna Makin · Dec 19, 2019 go to post

The proper way to do this would be

if the %OnNew is going to error you should throw an exception-  If you did this, the thrown exception should be caught by your try/catch block that calls the %New() method.  Then in the catch block you can examine either %objlasterror or perhaps some specific error variable you create for your purposes.

Jenna Makin · Dec 11, 2019 go to post

Hi-

Even in a http POST, url variables are found in %request.Data.  The content stream will contain the body of your post.

Jenna Makin · Nov 23, 2019 go to post

I'm not really familiar with this service but it looks like there's a format problem with some content field.   Maybe Telephone 

Jenna Makin · Nov 15, 2019 go to post

When studio opens a class, routine, or CSP file it takes out a lock.    I've seen cases where if Studio crashes the lock doesn't get removed.

Jenna Makin · Nov 14, 2019 go to post

Task manager seems very appropriate here.

VA is doing some of this with their productions.   Auto disabling services after one execution.

Jenna Makin · Nov 14, 2019 go to post

Install on local workstation and create a connection that points to the cloud server

Jenna Makin · Nov 14, 2019 go to post

If  you want to q global search and replace you can use the %RCHANGE utility from a terminal session.

Jenna Makin · Nov 12, 2019 go to post

I'm going to allow someone more familiar with Docker answer this.   It's clearly a permissions issue biut is it a issue inside or outside the container?   I don't know

Jenna Makin · Nov 12, 2019 go to post

What user is IRIS running a

Do a ps -ef and make sure the user listed for all of the Iris processes has write permissions to the directory.

Do you have anyone that has worked with ISC technology before or Linux?   If not I would suggest perhaps getting someone with a little experience here.