What matters is more the maturity of each resource.
Maturity is rated from 0 to 5, where 0 is a draft, and 5 is normative.
Further the realse of FHIR, more mature resources are.
It's plan than R6 will be the first normative release of FHIR, it's even plan to be an ISO standard.
This mean that all resources related to Patient will be normative, and will not change in the future.

I haven't tried it yet on 2021.2, but on 2023.1 you use case is working :

IRISAPP>w ##class(Zpy.Utility).Info()
def
IRISAPP>zn "USER"
USER>w ##class(Zpy.Utility).Info()
def
USER>zw $zv
"IRIS for UNIX (Ubuntu Server LTS for x86-64 Containers) 2023.1 (Build 229U) Fri Apr 14 2023 17:37:52 EDT"

Can you update iris ?

If you can't try to map rPYC global to the USER namespace.

rPYC global actually contains the python code.

Hello Cyril,

I have finished this exercise, I will share my experience on this subject with you:

Have you checked that the snmpd deamon is installed and configured on your docker instance?

By default, it is not installed, so you have to install and configure it.

Example of a dockerfile to install snmpd:

ARG IMAGE=intersystemsdc/iris-community:latest
FROM $IMAGE

WORKDIR /irisdev/app

USER root
RUN apt-get update && apt-get install -y \
    nano \
    snmpd \
    snmp \
    sudo && \
    /bin/echo -e ${ISC_PACKAGE_MGRUSER}\\tALL=\(ALL\)\\tNOPASSWD: ALL >> /etc/sudoers && \
    sudo -u ${ISC_PACKAGE_MGRUSER} sudo echo enabled passwordless sudo-ing for ${ISC_PACKAGE_MGRUSER}

COPY snmpd.conf /etc/snmp/snmpd.conf
USER ${ISC_PACKAGE_MGRUSER}

Example of a snmpd.conf:

###############################################################################
#
# snmpd.conf:
#   An example configuration file for configuring the NET-SNMP agent with Cache.
#
#   This has been used successfully on Red Hat Enterprise Linux and running
#   the snmpd daemon in the foreground with the following command:
#
#   /usr/sbin/snmpd -f -L -x TCP:localhost:705 -c./snmpd.conf
#
#   You may want/need to change some of the information, especially the
#   IP address of the trap receiver of you expect to get traps. I've also seen
#   one case (on AIX) where we had to use  the "-C" option on the snmpd command
#   line, to make sure we were getting the correct snmpd.conf file. 
#
###############################################################################

###########################################################################
# SECTION: System Information Setup
#
#   This section defines some of the information reported in
#   the "system" mib group in the mibII tree.

# syslocation: The [typically physical] location of the system.
#   Note that setting this value here means that when trying to
#   perform an snmp SET operation to the sysLocation.0 variable will make
#   the agent return the "notWritable" error code.  IE, including
#   this token in the snmpd.conf file will disable write access to
#   the variable.
#   arguments:  location_string

syslocation  "System Location"

# syscontact: The contact information for the administrator
#   Note that setting this value here means that when trying to
#   perform an snmp SET operation to the sysContact.0 variable will make
#   the agent return the "notWritable" error code.  IE, including
#   this token in the snmpd.conf file will disable write access to
#   the variable.
#   arguments:  contact_string

syscontact  "Your Name"

# sysservices: The proper value for the sysServices object.
#   arguments:  sysservices_number

sysservices 76

###########################################################################
# SECTION: Agent Operating Mode
#
#   This section defines how the agent will operate when it
#   is running.

# master: Should the agent operate as a master agent or not.
#   Currently, the only supported master agent type for this token
#   is "agentx".
#   
#   arguments: (on|yes|agentx|all|off|no)

master agentx
agentXSocket tcp:localhost:705

###########################################################################
# SECTION: Trap Destinations
#
#   Here we define who the agent will send traps to.

# trapsink: A SNMPv1 trap receiver
#   arguments: host [community] [portnum]

trapsink  localhost public   

###############################################################################
# Access Control
###############################################################################

# As shipped, the snmpd demon will only respond to queries on the
# system mib group until this file is replaced or modified for
# security purposes.  Examples are shown below about how to increase the
# level of access.
#
# By far, the most common question I get about the agent is "why won't
# it work?", when really it should be "how do I configure the agent to
# allow me to access it?"
#
# By default, the agent responds to the "public" community for read
# only access, if run out of the box without any configuration file in 
# place.  The following examples show you other ways of configuring
# the agent so that you can change the community names, and give
# yourself write access to the mib tree as well.
#
# For more information, read the FAQ as well as the snmpd.conf(5)
# manual page.
#
####
# First, map the community name "public" into a "security name"

#       sec.name  source          community
com2sec notConfigUser  default       public

####
# Second, map the security name into a group name:

#       groupName      securityModel securityName
group   notConfigGroup v1           notConfigUser
group   notConfigGroup v2c           notConfigUser

####
# Third, create a view for us to let the group have rights to:

# Make at least  snmpwalk -v 1 localhost -c public system fast again.
#       name           incl/excl     subtree         mask(optional)
# access to 'internet' subtree
view    systemview    included   .1.3.6.1

# access to Cache MIBs Caché and Ensemble
view    systemview    included   .1.3.6.1.4.1.16563.1
view    systemview    included   .1.3.6.1.4.1.16563.2
####
# Finally, grant the group read-only access to the systemview view.

#       group          context sec.model sec.level prefix read   write  notif
access  notConfigGroup ""      any       noauth    exact  systemview none none

From this neat article : https://community.intersystems.com/post/intersystems-data-platforms-and-...

Then, you have to start the snmpd deamon:

sudo service snmpd start

On iris, you have to configure the snmp agent:

%SYS> w $$start^SNMP()

With all these steps, you should be able to retrieve information via snmp.

snmpwalk -m ALL -v 2c -c public localhost .iso.3.6.1.4.1.16563.4.1.1.1.5.4.73.82.73.83

Result :

iso.3.6.1.4.1.16563.4.1.1.1.5.4.73.82.73.83 = STRING: "IRIS for UNIX (Ubuntu Server LTS for x86-64 Containers) 2023.1 (Build 229U) Fri Apr 14 2023 17:37:52 EDT"

Now that the snmpd service is running and functional as well as the snmp agent.

I encourage you to have a look at OpenTelemetry, it's a new standard for monitoring and tracing.

https://opentelemetry.io/

And our implementation of OpenTelemetry for IRIS :

https://docs.intersystems.com/iris20233/csp/docbook/Doc.View.cls?KEY=GCM...

Great article :)

It brings back memories of a project where we built a state machine: https://developer.mozilla.org/fr/docs/Glossary/State_machine

Back then, message queues didn't exist, and neither did your tutorial ;) it would have helped us a lot.

Think about completing it with an example applied to websockets, I have the impression that it lends itself well to this.

Hi, FHIR Profile Validation will be support with IRIS 2023.3.

https://community.intersystems.com/post/intersystems-announces-its-secon...

Highlights

There are several exciting new features in this release, such as support to base HL7® FHIR® version R5, and the integration with the IBM FHIR® Validator. There are also runtime performance improvements for ObjectScript.  Note that these features are expected, but nor assured to appear in the final release. 

Mean while, you can use community edition of Profile Validation :

Hi, FHIR Profile Validation will be support with IRIS 2023.3.

https://community.intersystems.com/post/intersystems-announces-its-secon...

Highlights

There are several exciting new features in this release, such as support to base HL7® FHIR® version R5, and the integration with the IBM FHIR® Validator. There are also runtime performance improvements for ObjectScript.  Note that these features are expected, but nor assured to appear in the final release. 

Mean while, you can use community edition of Profile Validation :

Hi,

I can't reproduce your error. I'm missing some information.

What I have done so far is :

  • adding the missing imports
  • adding the missing class DFrameRequest
    • i suppose it is a dataclass with a field named dframe of type pd.DataFrame
    • i suppose it is a subclass of Message
  • i have added a main function to run the code
    • i'm not sure of the format of the dataframe and the data in it
from dataclasses import dataclass
import pandas as pd
from grongier.pex import BusinessOperation,Message
from sqlalchemy import create_engine, types

@dataclass
class DFrameRequest(Message):
    dframe: pd.DataFrame

class FileOperationEmbedded(BusinessOperation):
    tablename = None
    engine = None

    def on_init(self):
        if not hasattr(self, "dsnIris"):
            self.dnsIris = 'iris+emb:///'
        if not hasattr(self, "schema"):
            self.schema = 'Toto'

        self.engine = create_engine(self.dnsIris)
        return None

    def on_message(self, request:DFrameRequest):
        df = pd.DataFrame(request.dframe.col)

        for row in request.dframe.col:
            df = pd.DataFrame.from_dict(row, orient='index').T.reset_index(drop=True)
            try:
                df.to_sql(name=self.tablename, con=self.engine, if_exists='append', index=False, schema=self.schema,
                          dtype={'id': types.INTEGER, 'col_type': types.VARCHAR(50), 'col_center': types.VARCHAR(50),
                                 'col_name': types.VARCHAR(50), 'col_issue_name': types.VARCHAR(50),
                                 'col_model': types.VARCHAR(50), 'col_treatment': types.VARCHAR(50),
                                 'source': types.VARCHAR(50), 'filename': types.VARCHAR(100), 'created_at': types.TIMESTAMP})
            except Exception as e:
                self.log_info(f"Une erreur s'est produite : {e}")

        return None

if __name__ == '__main__':
    # create a new instance of the business operation
    bo = FileOperationEmbedded()
    # initialize the business operation
    bo.on_init()

    # create a new message
    msg = DFrameRequest(pd.DataFrame())
    msg.dframe.col = [
            {'id': 1, 'col_type': 'type1', 'col_center': 'center1', 'col_name': 'name1', 'col_issue_name': 'issue1',
             'col_model': 'model1', 'col_treatment': 'treatment1', 'source': 'source1', 'filename': 'file1',
             'created_at': '2021-10-01 00:00:00'},
            {'id': 2, 'col_type': 'type2', 'col_center': 'center2', 'col_name': 'name2', 'col_issue_name': 'issue2',
             'col_model': 'model2', 'col_treatment': 'treatment2', 'source': 'source2', 'filename': 'file2',
             'created_at': '2021-10-02 00:00:00'}
        ]

    # send the message to the business operation
    bo.on_message(msg)
    print("Done")

Then, from your code I can see the following issues :

  • you are using the same variable name for the dataframe and the list of rows
  • the variable self.tablename is not initialized
  • the name FileOperationEmbedded it's maybe not the best name for your class as it is not a file operation
  • why are you using a for loop to iterate over the rows of the dataframe ?

I have modified your code to fix these issues :

from dataclasses import dataclass
import pandas as pd
from grongier.pex import BusinessOperation,Message
from sqlalchemy import create_engine, types

@dataclass
class DFrameRequest(Message):
    dframe: pd.DataFrame

class IrisSqlAlchmyEmbedded(BusinessOperation):
    tablename = None
    engine = None

    def on_init(self):
        if not hasattr(self, "dsnIris"):
            self.dnsIris = 'iris+emb:///'
        if not hasattr(self, "schema"):
            self.schema = 'Toto'
        if not hasattr(self, "tablename") or self.tablename is None:
            self.tablename = 'mytable'

        self.engine = create_engine(self.dnsIris)
        return None

    def on_message(self, request:DFrameRequest):

        try:
            request.dframe.to_sql(name=self.tablename, con=self.engine, if_exists='append', index=False, schema=self.schema,
                      dtype={'id': types.INTEGER, 'col_type': types.VARCHAR(50), 'col_center': types.VARCHAR(50),
                             'col_name': types.VARCHAR(50), 'col_issue_name': types.VARCHAR(50),
                             'col_model': types.VARCHAR(50), 'col_treatment': types.VARCHAR(50),
                             'source': types.VARCHAR(50), 'filename': types.VARCHAR(100), 'created_at': types.TIMESTAMP})
        except Exception as e:
            print(f"Une erreur s'est produite : {e}")

        return None

if __name__ == '__main__':
    # create a new instance of the business operation
    bo = IrisSqlAlchmyEmbedded()
    # initialize the business operation
    bo.on_init()

    # create a new message
    msg = DFrameRequest(pd.DataFrame([
            {'id': 1, 'col_type': 'type1', 'col_center': 'center1', 'col_name': 'name1', 'col_issue_name': 'issue1',
             'col_model': 'model1', 'col_treatment': 'treatment1', 'source': 'source1', 'filename': 'file1',
             'created_at': '2021-10-01 00:00:00'},
            {'id': 2, 'col_type': 'type2', 'col_center': 'center2', 'col_name': 'name2', 'col_issue_name': 'issue2',
             'col_model': 'model2', 'col_treatment': 'treatment2', 'source': 'source2', 'filename': 'file2',
             'created_at': '2021-10-02 00:00:00'}
        ]))

    # send the message to the business operation
    bo.on_message(msg)
    print("Done")

It seems that 2022.x have the same capability that 2023.x, I mean by that 2022.x support conditional Update and Create.

Then if you want to update only that is needed to be updated you have to go with JSON Patch :

PATCH https://localhost:4443/fhir/r4/Organization?identifier=HEAD
Accept: application/fhir+json
Content-Type: application/json-patch+json

[
 { 
   "op": "add", 
   "path": "/telecom/0", 
   "value": {
                "system": "phone",
                "value": "some-other-phone"
                }
 }
]

Result :

GET https://localhost:4443/fhir/r4/Organization?identifier=HEAD&_elements=telecom
Accept: application/fhir+json
{
  "resourceType": "Bundle",
  "id": "9962a9aa-668b-11ee-8f79-0242ac160003",
  "type": "searchset",
  "timestamp": "2023-10-09T10:05:38Z",
  "total": 1,
  "link": [
    {
      "relation": "self",
      "url": "https://localhost:4443/fhir/r4/Organization?_elements=telecom&identifier=HEAD"
    }
  ],
  "entry": [
    {
      "fullUrl": "https://localhost:4443/fhir/r4/Organization/1",
      "resource": {
        "resourceType": "Organization",
        "telecom": [
          {
            "system": "phone",
            "value": "some-other-phone"
          },
          {
            "system": "phone",
            "value": "some-other-phone"
          }
        ],
        "meta": {
          "tag": [
            {
              "system": "http://terminology.hl7.org/CodeSystem/v3-ObservationValue",
              "code": "SUBSETTED",
              "display": "Resource content reduced because _elements search parameter"
            }
          ]
        }
      },
      "search": {
        "mode": "match"
      }
    }
  ]
}

Attention JSON patch only work with direct access to the resource, if you need json path in a bundle you have to pass it as a base64 :

{
  "resourceType": "Bundle",
  "type": "transaction",
  "entry": [
    {
      "fullUrl": "Patient/1",
      "resource": {
        "resourceType": "Binary",
        "contentType": "application/json-patch+json",
        "data": "WyB7ICJvcCI6InJlcGxhY2UiLCAicGF0aCI6Ii9hY3RpdmUiLCAidmFsdWUiOmZhbHNlIH0gXQ=="
      },
      "request": {
        "method": "PATCH",
        "url": "Patient/1"
      }
    }
  ]
}

Example of a json path in a bundle for the patient 1 with this patch :

[ { "op":"replace", "path":"/active", "value":false } ]
{
"entry":
    [
        {
        "request":
            {
            "method": "PUT",
            "url": "Organization?identifier=EFG"
            },
        "resource":
            {
            "active": true,
            "identifier":
                [
                    {
                    "system": "https://fhir.domain.de/identifiers/domain-orgid",
                    "value": "EFG"
                    }
                ],
            "name": "Allgemeine Einrichtung  EFG.",
            "partOf":
                {
                "display": "HEAD",
                "reference": "urn:uuid:87a8f88a-5223-11ee-8c2c-005056b163cd"
                },
            "resourceType": "Organization",
            "telecom":
                [
                    {
                    "system": "phone",
                    "value": "some-phonenr"
                    },
                    {
                    "system": "fax",
                    "value": "some-faxnr"
                    }
                ],
            "type":
                [
                    {
                    "coding":
                        [
                            {
                            "code": "2",
                            "system": "https://fhir.domain.de/CodeSystem/domain-orglevel"
                            },
                            {
                            "code": "KL",
                            "display": "Klinik m. Poliklinik",
                            "system": "https://fhir.domain.de/CodeSystem/domain-orgtype"
                            }
                        ]
                    }
                ]
            }
        },
        {
        "request":
            {
            "method": "PUT",
            "url": "Organization?identifier=AEAP"
            },
        "resource":
            {
            "active": true,
            "identifier":
                [
                    {
                    "system": "https://fhir.domain.de/identifiers/domain-orgid",
                    "value": "AEAP"
                    }
                ],
            "name": "Allgemeine Einrichtung AEAP",
            "partOf":
                {
                "display": "HEAD",
                "reference": "urn:uuid:87a8f88a-5223-11ee-8c2c-005056b163cd"
                },
            "resourceType": "Organization",
            "telecom":
                [
                    {
                    "system": "phone",
                    "value": "some-phonenr"
                    },
                    {
                    "system": "fax",
                    "value": "some-faxnr"
                    }
                ],
            "type":
                [
                    {
                    "coding":
                        [
                            {
                            "code": "2",
                            "system": "https://fhir.domain.de/CodeSystem/domain-orglevel"
                            },
                            {
                            "code": "KL",
                            "display": "Klinik m. Poliklinik",
                            "system": "https://fhir.domain.de/CodeSystem/domain-orgtype"
                            }
                        ]
                    }
                ]
            }
        },
        {
        "fullUrl": "urn:uuid:87a8f88a-5223-11ee-8c2c-005056b163cd",
        "request":
            {
            "method": "PUT",
            "url": "Organization?identifier=HEAD"
            },
        "resource":
            {
            "active": true,
            "address":
                [
                    {
                    "line":
                        [
                        "Some street 2"
                        ],
                    "type": "postal",
                    "use": "work"
                    }
                ],
            "identifier":
                [
                    {
                    "system": "https://fhir.domain.de/identifiers/domain-orgid",
                    "value": "HEAD"
                    }
                ],
            "name": "Some Hospital",
            "partOf":
                {
                "display": "NULL"
                },
            "resourceType": "Organization",
            "telecom":
                [
                    {
                    "system": "phone",
                    "value": "some-phonenr"
                    }
                ],
            "type":
                [
                    {
                    "coding":
                        [
                            {
                            "code": "0",
                            "system": "https://fhir.domain.de/CodeSystem/domain-orglevel"
                            },
                            {
                            "code": "SHOS",
                            "display": "Some Hospital",
                            "system": "https://fhir.domain.de/CodeSystem/domain-orgtype"
                            }
                        ]
                    }
                ]
            }
        }
    ],
"id": "214a4092-eeb9-440d-b645-0ec3b5b30bbe",
"resourceType": "Bundle",
"type": "transaction"
}

Here is your bundle with conditional update instead of conditional create.

Result on IRIS 2023.2 :

First call :

{
  "resourceType": "Bundle",
  "id": "409996a4-644b-11ee-8e3a-0242ac160003",
  "type": "transaction-response",
  "timestamp": "2023-10-06T13:07:35Z",
  "entry": [
    {
      "response": {
        "status": "201",
        "location": "https://localhost:4443/fhir/r4/Organization/2",
        "etag": "W/\"1\"",
        "lastModified": "2023-10-06T13:07:35Z"
      }
    },
    {
      "response": {
        "status": "201",
        "location": "https://localhost:4443/fhir/r4/Organization/3",
        "etag": "W/\"1\"",
        "lastModified": "2023-10-06T13:07:35Z"
      }
    },
    {
      "fullUrl": "urn:uuid:87a8f88a-5223-11ee-8c2c-005056b163cd",
      "response": {
        "status": "201",
        "location": "https://localhost:4443/fhir/r4/Organization/1",
        "etag": "W/\"1\"",
        "lastModified": "2023-10-06T13:07:35Z"
      }
    }
  ]
}

as you can see we have 201 (mean created)

Second call :

{
  "resourceType": "Bundle",
  "id": "ccc5c35a-644b-11ee-8f77-0242ac160003",
  "type": "transaction-response",
  "timestamp": "2023-10-06T13:08:47Z",
  "entry": [
    {
      "response": {
        "status": "200",
        "location": "https://localhost:4443/fhir/r4/Organization/2",
        "etag": "W/\"2\"",
        "lastModified": "2023-10-06T13:08:48Z"
      }
    },
    {
      "response": {
        "status": "200",
        "location": "https://localhost:4443/fhir/r4/Organization/3",
        "etag": "W/\"2\"",
        "lastModified": "2023-10-06T13:08:48Z"
      }
    },
    {
      "fullUrl": "urn:uuid:87a8f88a-5223-11ee-8c2c-005056b163cd",
      "response": {
        "status": "200",
        "location": "https://localhost:4443/fhir/r4/Organization/1",
        "etag": "W/\"2\"",
        "lastModified": "2023-10-06T13:08:47Z"
      }
    }
  ]
}

we can see 200 mean ok/updated.

Get all organization :

{
  "resourceType": "Bundle",
  "id": "56ccfcb4-644a-11ee-8f78-0242ac160003",
  "type": "searchset",
  "timestamp": "2023-10-06T13:09:50Z",
  "total": 3,
  "link": [
    {
      "relation": "self",
      "url": "https://localhost:4443/fhir/r4/Organization"
    }
  ],
  "entry": [
    {
      "fullUrl": "https://localhost:4443/fhir/r4/Organization/1",
      "resource": {
        "active": true,
        "address": [
          {
            "line": [
              "Some street 2"
            ],
            "type": "postal",
            "use": "work"
          }
        ],
        "identifier": [
          {
            "system": "https://fhir.domain.de/identifiers/domain-orgid",
            "value": "HEAD"
          }
        ],
        "name": "Some Hospital",
        "partOf": {
          "display": "NULL"
        },
        "resourceType": "Organization",
        "telecom": [
          {
            "system": "phone",
            "value": "some-phonenr"
          }
        ],
        "type": [
          {
            "coding": [
              {
                "code": "0",
                "system": "https://fhir.domain.de/CodeSystem/domain-orglevel"
              },
              {
                "code": "SHOS",
                "display": "Some Hospital",
                "system": "https://fhir.domain.de/CodeSystem/domain-orgtype"
              }
            ]
          }
        ],
        "id": "1",
        "meta": {
          "lastUpdated": "2023-10-06T13:08:47Z",
          "versionId": "2"
        }
      },
      "search": {
        "mode": "match"
      }
    },
    {
      "fullUrl": "https://localhost:4443/fhir/r4/Organization/2",
      "resource": {
        "active": true,
        "identifier": [
          {
            "system": "https://fhir.domain.de/identifiers/domain-orgid",
            "value": "EFG"
          }
        ],
        "name": "Allgemeine Einrichtung  EFG.",
        "partOf": {
          "display": "HEAD",
          "reference": "Organization/1"
        },
        "resourceType": "Organization",
        "telecom": [
          {
            "system": "phone",
            "value": "some-phonenr"
          },
          {
            "system": "fax",
            "value": "some-faxnr"
          }
        ],
        "type": [
          {
            "coding": [
              {
                "code": "2",
                "system": "https://fhir.domain.de/CodeSystem/domain-orglevel"
              },
              {
                "code": "KL",
                "display": "Klinik m. Poliklinik",
                "system": "https://fhir.domain.de/CodeSystem/domain-orgtype"
              }
            ]
          }
        ],
        "id": "2",
        "meta": {
          "lastUpdated": "2023-10-06T13:08:48Z",
          "versionId": "2"
        }
      },
      "search": {
        "mode": "match"
      }
    },
    {
      "fullUrl": "https://localhost:4443/fhir/r4/Organization/3",
      "resource": {
        "active": true,
        "identifier": [
          {
            "system": "https://fhir.domain.de/identifiers/domain-orgid",
            "value": "AEAP"
          }
        ],
        "name": "Allgemeine Einrichtung AEAP",
        "partOf": {
          "display": "HEAD",
          "reference": "Organization/1"
        },
        "resourceType": "Organization",
        "telecom": [
          {
            "system": "phone",
            "value": "some-phonenr"
          },
          {
            "system": "fax",
            "value": "some-faxnr"
          }
        ],
        "type": [
          {
            "coding": [
              {
                "code": "2",
                "system": "https://fhir.domain.de/CodeSystem/domain-orglevel"
              },
              {
                "code": "KL",
                "display": "Klinik m. Poliklinik",
                "system": "https://fhir.domain.de/CodeSystem/domain-orgtype"
              }
            ]
          }
        ],
        "id": "3",
        "meta": {
          "lastUpdated": "2023-10-06T13:08:48Z",
          "versionId": "2"
        }
      },
      "search": {
        "mode": "match"
      }
    }
  ]
}

As you can see "partOf" are referencing internal id of HEAD.

TIP :

To quickly test on a fresh server, you can wipe data like this (only do it on dev server, your laptop, never in production !!! )

Set appKey = "/fhir/r4"
Set strategy = ##class(HS.FHIRServer.API.InteractionsStrategy).GetStrategyForEndpoint(appKey)
Set options("deleteDataOnly") = 1
Do strategy.Delete(.options)

Hi Roy,

I can't tell about the "seed: path" but how to play with the Web Gateway sidecar you can follow this example :

https://community.intersystems.com/post/local-k8s-deployment-fhir-server

TL; DR :

In your topology definition :

## deploy webgateway (web server) nodes
    webgateway:
      image: k3d-registry.localhost:5000/intersystems/webgateway:2023.1.1.380.0-linux-amd64
      type: apache
      replicas: 1
      applicationPaths:
        - /csp/sys
        - /fhir/r4
      alternativeServers: LoadBalancing
      loginSecret:
        name: iris-webgateway-secret 

The iris-webgateway-secret :

kubectl create secret generic iris-webgateway-secret --from-literal='username=CSPSystem' --from-literal='password=SYS'

The config file for iris :

[Actions]
ModifyService:Name=%Service_CallIn,Enabled=1,AutheEnabled=16
ModifyUser:Name=SuperUser,ChangePassword=0,PasswordHash=a31d24aecc0bfe560a7e45bd913ad27c667dc25a75cbfd358c451bb595b6bd52bd25c82cafaa23ca1dd30b3b4947d12d3bb0ffb2a717df29912b743a281f97c1,0a4c463a2fa1e7542b61aa48800091ab688eb0a14bebf536638f411f5454c9343b9aa6402b4694f0a89b624407a5f43f0a38fc35216bb18aab7dc41ef9f056b1,10000,SHA512
ModifyUser:Name=CSPSystem,ChangePassword=0,PasswordHash=a31d24aecc0bfe560a7e45bd913ad27c667dc25a75cbfd358c451bb595b6bd52bd25c82cafaa23ca1dd30b3b4947d12d3bb0ffb2a717df29912b743a281f97c1,0a4c463a2fa1e7542b61aa48800091ab688eb0a14bebf536638f411f5454c9343b9aa6402b4694f0a89b624407a5f43f0a38fc35216bb18aab7dc41ef9f056b1,10000,SHA512

To generate PasswordHash :

docker run --rm -it containers.intersystems.com/intersystems/passwordhash:1.1 -algorithm SHA512 -workfactor 10000

Add the configmap for iris :

kubectl create cm iriscluster-config --from-file common.cpf 

the topology of IRIS + Webgateway :

apiVersion: intersystems.com/v1alpha1
kind: IrisCluster
metadata:
  name: sample
spec:

## provide InterSystems IRIS license key if required
#     licenseKeySecret:
#       name: iris-key-secret

## specify files used to customize the configurations of
## InterSystems IRIS nodes, including passwordHash parameter
## to set the default password, securing InterSystems IRIS
  configSource:
    name: iriscluster-config

## topology: defines node types to be deployed; only "data:" is required

  topology:
    data:
      image: k3d-registry.localhost:5000/iris-oauth-fhir-iris:latest


## deploy webgateway (web server) nodes
    webgateway:
      image: k3d-registry.localhost:5000/intersystems/webgateway:2023.1.1.380.0-linux-amd64
      type: apache
      replicas: 1
      applicationPaths:
        - /csp/sys
        - /fhir/r4
      alternativeServers: LoadBalancing
      loginSecret:
        name: iris-webgateway-secret 

I bet that the issue is related to the fact that recently IRIS 2023.2 was released. This version removed this method InstallFoundation from this class HS.HC.Util.Installer. This was a private method and it was not documented. But it was widely used by the community to install FHIR server.

TL;DR :

Change :

  do ##class(HS.HC.Util.Installer).InstallFoundation()

to

  Do ##class(HS.Util.Installer.Foundation).Install(namespace)

cf : https://community.intersystems.com/post/installfoundation-method-missing...