· Feb 19, 2016 12m read

Deploying Applications in InterSystems Cache with %Installer

Suppose you have developed your own app with InterSystems technologies stack and now want to perform multiple deployments on the customers' side. During the development process you've composed a detailed installation guide for your application, because you need to not only import classes, but also fine-tune the environment according to your needs.
To address this specific task, InterSystems has created a special tool called %Installer. Read on to find out how to use it.


Using this tool, you can define the installation manifest, which describes the desired Caché configuration instead of the installation steps. You need only to describe what you want, and Caché will automatically generate the necessary code to modify the environment for you. Therefore, you should distribute only the manifest itself, while all the installation code will be generated for the specific Caché server at compile time.

To define a manifest, create a new XData block with detailed description of the target configuration and then implement a method to generate Caché ObjectScript  code for this XData block (this code is always the same). Once the manifest is ready, you can access it from a terminal or Caché ObjectScript code or  automatically during Caché installation. The manifest must be executed in the %SYS namespace. Manifests can handle both system parameters (superport, OS, mgr directory, etc.) and arbitrary user-supplied parameters. In general, each installation class must meet the following requirements:

  • Contain a link to
  • Contain an XData block with the Caché server configuration
  • The block can be have any valid name
  • Add [XMLNamespace = INSTALLER] after the block's name if you want to see prompts from Studio
  • The root item (there must only be  one) is called <Manifest> and comprises all other items
  • You also need to implement the setup() method which will generate the necessary program code for the XData block.

Installer basics

You can execute an installation manifest in several ways:

  • In the %SYS namespace using a terminal or from a Caché ObjectScript code
do ##class(MyPackage.MyInstaller).setup()
  • Automatically during the installation of Caché. To do this, export the installer's class into DefaultInstallerClass.xml stored in the folder with Caché installation package (i.e. where setup_cache.exe or cinstall are stored). During Caché installation, this class will be imported into the %SYS namespace and executed via the setup() method.


Let's consider a simple example. Create the class called App.Installer containing an installer that will generate a new namespace with the user-defined name, create default web app and import code into this new namespace:

Include %occInclude
Class App.Installer {

/// You can see generated method in zsetup+1^App.Installer.1
XData Install [ XMLNamespace = INSTALLER ]
    <If Condition='(##class(Config.Namespaces).Exists("${Namespace}")=0)'>
        <Log Text="Creating namespace ${Namespace}" Level="0"/>
        <Namespace Name="${Namespace}" Create="yes" Code="${Namespace}" Ensemble="0" Data="${Namespace}">
                <Database Name="${Namespace}" Dir="${MGRDIR}${Namespace}" Create="yes"/>
        <Log Text="End Creating namespace ${Namespace}" Level="0"/>

    <Role Name="AppRole" Description="Role to access and use the App" Resources="%DB_CACHESYS:RW,%Admin_Secure:U" />

    <Namespace Name="${Namespace}" Create="no">
        <CSPApplication Url="/csp/${Namespace}" Directory="${CSPDIR}${Namespace}" AuthenticationMethods="64" IsNamespaceDefault="true" Grant="AppRole" />
        <IfDef Var="SourceDir">
            <Log Text="SourceDir defined - offline install from ${SourceDir}" Level="0"/>
            <Import File="${SourceDir}"/>

///Entry point method, you need to call
/// At class compile time it generate Caché ObjectScript code from the manifest
/// After that you can run this installer from a terminal:
/// Set pVars("Namespace")="NewNamespace"
/// Set pVars("SourceDir")="C:\temp\distr\"
/// Do ##class(App.Installer).setup(.pVars)
ClassMethod setup(ByRef pVars, pLogLevel As %Integer = 0, pInstaller As %Installer.Installer) As %Status [ CodeMode = objectgenerator, Internal ]
     Quit ##class(%Installer.Manifest).%Generate(%compiledclass, %code, "Install")

In this example, installer performs the following actions:

  • Checks if a namespace with the same name as the value of Namespace variable exists (for clarity let's specify that the Namespace variable is set to NewNamespace)
  • If not, then logs that a new namespace called NewNamespace will be created
  • Defines a new namespace:
    • Name is NewNamespace
    • Creates a new namespace
    • Routines database is NewNamespace
    • Do not enable Ensemble
    • Globals database is NewNamespace
  • Creates a new database
    • Name is NewNamespace;
    • Creates it in the mgr/NewNamespace folder (note that the MGRDIR variable is available by default)
  • Creation of the namespace is completed and logged
  • Creates new role: AppRole (with resources %DB_CACHESYS:RW and %Admin_Secure:U)
  • Default web application /csp/NewNamespace is created (it also grants AppRole automatically)
  • If SourceDir variable is defined then imports all files from there into NewNamespace

To run this installer in a terminal, execute the following commands:

Set pVars("Namespace")="NewNamespace"
Set pVars("SourceDir")="C:\temp\distr\"
Do ##class(App.Installer).setup(.pVars)

During execution terminal displays relevant information:

2016-02-17 19:26:17 0 App.Installer: Installation starting at 2016-02-17 19:26:17, LogLevel=0
2016-02-17 19:26:17 0 : Creating namespace NewNamespace
2016-02-17 19:26:17 0 : End Creating namespace NewNamespace
2016-02-17 19:26:17 0 : SourceDir defined - offline install from C:\temp\distr\
2016-02-17 19:26:18 0 App.Installer: Installation succeeded at 2016-02-17 19:26:18
2016-02-17 19:26:18 0 %Installer: Elapsed time .545148s

To receive even more information about what is going on specify LogLevel (from 0 (default) to 3 (raw); higher number = more information).

Do ##class(App.Installer).setup(.pVars, 3)

Now let's talk about what can be done in installer manifest.

Availible nodes

A manifest is composed of the following items:


Parent node

Attributes (default values)



Invoke, Error

Value – value of an argument

Passes an argument into a method called via Invoke or Error



Package – a package to be mapped
From – name of the source database used for mapping

Creates a class mapping from a database to the namespace which contains this Configuration item



Class – names of classes for compilation
Flags – compilation flags (ck)
IgnoreErrors – ignore errors (0)

Compilers classes. Calls $System.OBJ.Compile(Class, Flags)




Used for creating namespaces and databases. Closing tag activates mappings and updates the CPF file



Src — source class
Target — target class
Replace — remove the source class (0)

Copies or moves the source class definition to the target one



Src — source directory
Target — target directory
IgnoreErrors — ignore errors (0)

Copies a directory



Src — source file
Target — target file
IgnoreErrors — ignore errors (0)

Copies a file



Name – name of the access credentials
Username – user name
Password – user password
Overwrite – overwrite if the account already exists

Creates or overrides the access credentials



AuthenticationMethods – enabled authentication methods
AutoCompile – automatic compilation (in CSP settings)
CSPZENEnabled – the CSP/ZEN flag
ChangePasswordPage – path to change password page
CookiePath – session cookie path
CustomErrorPage – path to custom error page
DefaultSuperclass – default superclass
DefaultTimeout – session timeout
Description – description
Directory – path to CSP files
EventClass – event class name
Grant – list of roles assigned upon logging into the system
GroupById – group by Id property
InboundWebServicesEnabled – inbound web services flag
IsNamespaceDefault – Namespace Default Application flag
LockCSPName – Lock CSP Name flag
LoginClass – path to login page
PackageName – package name property
PermittedClasses – permitted classes propert
Recurse – recurce flag (serve subdirectories) (0)
Resource – resource required to access web app
ServeFiles – service files property
ServeFilesTimeout – time, in seconds, of how long to cache static files.
TwoFactorEnabled – two-step authentication
Url – name of the web application
UseSessionCookie – use cookies for the session

Creates or modifies a web application. For details, refer to documentation and the Security.Applications class



BlockSize – block size in bytes of the database
ClusterMountMode – mount the database as a part of the cluster
Collation – sorting order
Create – whether to create a new database (yes/no/overwrite (yes))
Dir – directory
Encrypted – encrypt database
EncryptionKeyID – ID of the encryption key
ExpansionSize – size in MB to expand by
InitialSize – initial size
MaximumSize – maximum size
MountAtStartup – mount upon launch
MountRequired – specifies that the database MUST be successfully mounted at startup.
Name – database name
PublicPermissions – public permissions
Resource – resource
StreamLocation – directory where the streams associated with this database go.

Creates or modifies a database. For details, refer to documentation, the Config.Databases and SYS.Database classes



Name – variable name
Value – variable value
Dir – variable value (if this is a path to a folder/file)

Sets the variable value (if it is not set yet)


Manifest, Namespace

Will be executed when the if statement is false



Status – error code
Source – source of the error

Throws an exception. Note that ${} and #{} syntax is not available



Index – variable name
Values – list of values for the variable

Collection-controlled loop



Global – global name
From – name of the database for mapping

Collation – sorting order (Caché Standard)

Maps a global


Manifest, Namespace

Condition – a conditional statement

Conditional if statement


Manifest, Namespace

Var – variable name

Conditional if statement used when the variable is already set


Manifest, Namespace

Var – variable name

Conditional if statement used when the variable is not set yet



File – file/folder for import
Flags — compilation flags (ck)
IgnoreErrors — ignore errors (0)
Recurse – import recursively (0)

Imports files. Calls:
$System.OBJ.ImportDir(File,,Flags,,Recurse) and $System.OBJ.Load(File, Flags)



Class – class name
Method – method name
CheckStatus – check the returned status
Return – write the result into a variable

Makes a call to a method of a class with various arguments and returns the execution results



Name – path to the CSP page
Dir – folder with CSP pages
Flags — compilation flags (ck)
IgnoreErrors — ignore errors (0)

Loads CSP file using $System.CSP.LoadPage(Name, Flags) and $System.CSP.LoadPageDir(Dir, Flags)



Level – logging level from 0 (minimum) up to 3 (detailed)
Text – string up to 32,000 characters in length

Adds a message to a log when the logging level is greater or equal to the "level" attribute



Root item. The only one root item in a manifest; contains all other items



Name – name of the namespace
Create – whether to create a new namespace (yes/no/overwrite (yes))
Code – database for program code
Data – database
Ensemble – enable Ensemble for the namespace
All other attributes are applicable to the Ensemble web applications

Defines the installer's scope



Name – production name
AutoStart – automatic launch of the production

Configures the Ensemble production



Name – resource name
Description – resource description
Permission – public permissions

Creates or modifies a resource.



Name – name of the role
Description – role description (can't contain commas)
Resources – resourcesgiven to role, represented as "MyResource:RW,MyResource1:RWU"

RolesGranted – whether to grant the corresponding roles

Creates a new role



Routines – routine name
Type – routines type (MAC, INT, INC, OBJ or ALL)
From – source database

Creates a new mapping for routines



Item – configurable item
Target – parameter type: Item, Host, Adapter
Setting – parameter name
Value – parameter value

Configures an item in the Ensemble production Makes a call to the Ens.Production:ApplySettings method



Name – of the Config package
Value – attribute value

Sets the values for attributes of the Config package (using the Modify method)



Username – user name
PasswordVar – variable containing the password
Roles – list of user's roles
Fullname – full name
Namespace – startup namespace
Routine – starting routine
ExpirationDate – date after which the user will be deactivated
ChangePassword – change the password upon next login into the system
Enabled – whether the user is activated

Creates or modifies a user.



Name — variable name
Value – variable value

Assigns a value to the variable


User-supplied variables

Some attributes can contain expressions (strings) that are expanded when the manifest is executed. There are three types of expressions that can be expanded, as follows:

  • ${<Variable_name>} – value of the variable (user-defined or environment variable; see below) is calculated during the execution of the manifest;
  • ${#<Parameter_name>} – will be replaced with the value of the specified parameter from the installer's class during compilation;
  • #{<Caché_ObjectScript_code>} — the value of the specified Caché ObjectScript statement will be calculated during the execution of the manifest. Make sure to put quotation marks as required.

Parameter values are defined during compilation and therefore can be a part of a variable or Caché ObjectScript statement. Since variables are interpreted before the Caché ObjectScript code, you can use them in Caché ObjectScript statements, e.g: #{$ZCVT("${NAMESPACE}","L")}.

System variables

The following variables are always available:



Sample value


(Available only when the installer is run) Directory from which the installation (setup_cache.exe or cinstall) is running.



(Available only when the installer is run) Indicates whether this is a new installation or an upgrade. This variable is either  0 (new installation) or 1  (upgrade).

0 (installation)
1 (update)





Path to the CPF file



Name of the instance



Number of CPU cores



The CSP directory



Name of the web server



Port of the web server



Directory where Caché is installed



Management directory (mgr)



Operating system



Port of the Caché superserver



Name of the platform



Version of Caché



Sometimes it may be hard to understand what values can be assigned as node attributes' values. To figure this out, check the generated int code for the setup method. In most cases, the main call is made to the tInstaller.<ElementName> which is an object of the %Installer.Installer class which, in turn, will make direct calls to the system methods. Alternatively, you can check the code of the %Installer.<ElementName> class in which the node attributes are class properties. The program code is generated in the %OnBeforeGenerateCode, %OnGenerateCode and %OnAfterGenerateCode methods.

For debugging purposes, I recommend that you wrap a call to the installer into a transaction. For example, you can use the TSTART/TROLLBACK commands to easily undo all changes made within Caché  (however, external changes, such as creating a new database file, will not be reverted).

Lastly, don't forget to set LogLevel to 3.


The MDX2JSON project provides an installer. To install the project, import the installer.xml file containing the MDX2JSON.Installer class into any namespace. You can perform import either from the SMP or by drag&dropping the file into Studio.
Then run the following command in a terminal:

do ##class(MDX2JSON.Installer).setup()

As a result, Caché will load application files from the GitHub repository and then perform installation in the default MDX2JSON namespace/MDX2JSON database, map the MDX2SJON package to %All and SAMPLES, map the ^MDX2SJON global to %All and SAMPLES  create the REST application called /MDX2JSON, and so on – you will see all these steps in the terminal. For more detailed information on MDX2JSON installer, please refer to the project readme.

Even more examples

Example from the documentation.
The Sample.Installer class in the Samples namespace.
The CacheGitHubCI projects provides an installer.
The SYSMON Dashboards project provides an installer.
The DeepSee Audit project provides an installer.


%Installer is a convenient tool for distributing and deploying applications based on InterSystems Caché and Ensemble.



Discussion (9)4
Log in or sign up to continue

I see.

So I guess I should use EnsLib.HL7.SchemaDocument class but can't find an example of how import/export programatically.

In response to @Evgeny Shvarov I am talking about Custom HL7 Schemas ( in IRIS for Health. Use custom schemas is something very usual and I think that to include this import feature in Installer could be very useful... I'll try to make it works and if I am success I'll post the how-to :-D