IMSql User Guide


Version 4.2.424.0

1. Introduction to IMSql

Raincode IMSql enbales the rehosting of IMS/DB (IMS Database Manager) and IMS/TM (IMS Transaction Manager) systems on .NET and SQL Server. Mainframe applications compiled for .NET can interact with IMSql in the same manner as they would interact with IMS.

IMSql is non-transformational, which means it keeps the sources (COBOL, PL/I) as-is with the IMS-specific CBLTDLI, PLITDLI, CEETDLI and EXEC DLI calls unaltered. This way, new sources are not introduced, which plays a crucial role in program maintainability.

IMSql leverages SQL Server as a database, transaction processor, and execution platform.

IMSql operates in three modes:

  • Online

  • Batch

  • Load and Unload

1.1. Architecture of IMSql

  • Supports .NET Framework and .NET 6.0

  • Leverages Entity Framework

1.2. IMS support

image002
Figure 1. The architecture of IMS support

COBOL or PL/I programs use an interface to communicate with the database provided by CBLTDLI (COBOL to DLI), PLITDLI (PL/I to DLI), CEETDLI, and EXEC DLI.

CBLTDLI, PLITDLI, CEETDLI, and EXEC DLI also act as routers for database and transaction-related queries.

The database server hosts the data, while the database controller server holds transactions and online messages. These servers are synchronized.

CBLTDLI and PLITDLI identify the query type (thanks to the PCB (Program Communication Block)) and route the traffic based on it. All data-related queries go directly to the database server, whereas transaction-related queries are routed to the Queue Management Service.

The Queue Management Service enqueues all requests coming for the transaction. It accepts and enqueues requests from CBLTDLI/PLITDLI and MFS (Message Format Service).

The Message Format Service works as an adapter enabling third-party applications to connect to the Queue Management Service and eventually to the data controller service to get their transaction-related queries served.

2. IMS/DB

On Mainframes, DBDs (Database Description) and PSBs (Program Specification Block) are compiled to create the database and the program’s description.

On IMSql, DBDs will be used to generate a SQL script that creates the corresponding database on SQL Server and the Entity Framework DbContext. The DbContext will be used to write and execute queries.

PSBs are converted to XML files used by IMS-aware programs to determine which database segments pertain to them.

The IMSql engine (IMSql.Common.dll) is dynamically loaded if needed.

Figure 2 shows a high-level overview of the IMS/DB architecture.

image001
Figure 2. IMS/DB architecture
In Figure 2, blue arrows indicate compilation or transformation, whereas grey arrows indicate execution.

2.1. DB model

DBDs are used to create the underlying database structure. A table is created for each physical segment and contains the following columns:

  • Data: a varbinary column that contains all the segment data. The data is stored in the same format as on the Mainframe, using EBCDIC encoding.

  • Each field declared in the DBD is represented by one column:

    • A persisted computed column contains the field’s raw data (substring of the Data column).

  • RID: an identity column (integer).

  • HID: a varbinary used to order the segment if it doesn’t have a unique sequence. If the segment has a unique sequence, this column is always NULL.

  • PID: the foreign key to the physical parent. This column only exists for child segments.

  • LPID: the foreign key to the logical parent. This column exists only for logical child segments.

Concatenated segments are represented as views. The view contains the same columns as the tables representing a segment, with an additional DPRID column which is the RID of the destination parent. The Data column contains the concatenation of the data of the two segments.

Primary indexes are represented by SQL Server index.

Secondary indexes are represented by tables that are maintained by triggers.

2.2. Compile an IMS/DB program

The program itself needs to be compiled using the COBOL or PL/I compiler. Moreover, the database needs to be created, the DbContext has to be compiled, and the PSB must be translated.

2.2.1. DB and Dbcontext creation

A database creation script and DbContext classes are generated by IMSql.DbGenerator command using the DBD:

IMSql.DbGenerator :DbName=<dbName> :Files=<DBD dir or file> :OutputDir=<outputDir>

where,

<dbName>: the name of the database in which the tables, views, triggers and stored procedures will be created

<DBD dir or file>: the path of the DBD’s to be translated. It can be a file or a directory. If it is a directory, all the .DBD files will be translated.

<outputDir>: The directory containing all the generated files, including:

  • the database creation script (named <dbName>.sql);

  • one .cs file per DBD. This is the DbContext for the DBD;

  • one .csproj file per DBD (this is the project to compile the DbContext; it produces a .NET Standard assembly named <DBD>.dll).

To create the database, execute the SQL script.

To compile the DbContext, we use the .NET SDK dotnet command:

dotnet build <DBD>.csproj -o=<dll directory>

The DLL produced must be placed in the same directory of the program assembly.

2.2.2. PSB translation

Each IMS program requires a PSB. The PSB needs to be translated into an XML file:

IMSql.Psb -OutputDirectory=<outputDir> <psb file>

where,

<psb file>: a PSB file

<outputDir>: the output directory where the XML file will be written.

The translated PSB must be in the same directory as the DbContext and program assembly.

2.3. Run an IMS/DB program

2.3.1. Batch program

An IMS batch program is executed through a JCL using the DFSRRCOO utility:

//G1      EXEC PGM=DFSRRC00,REGION=512K,
//            PARM='DBB,DLRSTAT,DLRSTAT,,,,,,,,,,,,,,,,,,

DFSRRCOO takes 21 parameters as mentioned below:

1 Program type: Accepted Value: BMP, DLI, DBB

2 Program name to be executed

3 PSB name

4 In Area: Not supported

5 Out Area: Not supported

6 Option (sub-parameters are OPT SPIE TEST DIRCA): Not supported

7 PRLD: Not supported

8 STIMER: Not supported

9 CheckPointID: for Restart

10 PARDLI: Not supported

11 CPUTIME: Not supported

12 NBA: Not supported

13 OBA: Not supported

14 IMSID: The name of the plan used to connect to the database. For more details, refer to Map PLAN Name to Actual Connection String.

15 AGN: Not supported

16 SSM: Not supported

17 PREINIT: Not supported

18 ALTID: Not supported

19 APARM: Not supported

20 LOCKMAX: Not supported

21 DEBUG: Parameter added by Raincode for debugging. For more details, refer to Debugging

Typically, a batch program is invoked using a PROC. For example, IMSBATCH

// EXEC PROC=IMSBATCH,MBR=<prg name>,PSB=<psb name>,IMSID=<plan name>,

where,

<prg name>: the name of the program (COBOL or PL/I)

<psb name>: the name of the PSB. The PSB should be compiled as a xml file. For more details, refer to IMSql.Psb. The XML file should be in the same directory as the program

<plan name>: the name of the plan used to connect to the database. For more details, refer to Map PLAN Name to Actual Connection String.

Data prefetch

To improve the access performance, IMSql can prefetch data in a buffer. By default, the cache size is 10. The size can be modified using the rclrun IMSqlCacheSize parameter.

2.3.2. Online Program

Refer to IMS/TM.

3. IMS/TM

The IMS/TM (IMS Transaction Manager) functionality is provided using SQL Server queues and messages.

The IMSql.Mfs utility translates the MFS files into XML files.

3.1. Configure IMSql/TM

3.1.1. Create IMSql/TM database

The transaction manager is implemented using SQL Server queues and messages. IMSql.DbGenerator is used to generate the database creation scripts:

IMSql.DbGenerator :Online=true :Data=false :OnlineDbName=<TM db name> :OutputDir=<OutputDir>

where

<TM db name>: the name of the configuration database. Most tools expect the name of the IMS/DB database with the suffix _config.

<OutputDir>: the directory containing the generated scripts

IMSql.DbGenerator produces two SQL scripts:

<TM db name>_ServiceBroker.sql: script to create the queues, services, and contracts.

<TM db name>_Tables.sql: script to create the tables for the administration of the online environment.

3.1.2. Configuring region

The configuration is done through the Raincode console.

Follow the following steps to create a region:

  • In the region tab, click on the ADD ENTRY and give the region’s name, the system to which it is associated and the different encodings (usually, they are all EBCDIC).

configregion
Figure 3. Create a region
  • Create the list of programs using the programs tab. Only list the programs that are associated with a transaction.

listofprograms
Figure 4. Create a program
  • Create the list of transactions using the mapping tab. For each transaction, give its region, name, program, PSB and the size of the scratch pad area (SPA) if necessary.

listoftransaction
Figure 5. Create a transaction

3.1.3. Customize logon screen

By default, the login screen is quite simple (see figure The default logon screen). It is possible to customize the logon screen by using a .mfs file. The .mfs file should respect the following constraints:

  • The output message should be named "LOGONSCR" (LOGONSCR MSG TYPE=OUTPUT …​.)

  • The output message should contain one field of length 40 (MFLD MSG, LTH=40). This field contains an error message if the login fails.

  • The input message should contain two fields of any length. The first is the user id, and the second is the password.

The .mfs file should be compiled (with IMSql.Mfs), and the output files should be put in the bin directory for ordinary mfs. An example of such a .mfs file can be found in %RCDIR%\samples\net6.0\IMSql\logon.mfs

loginscreen
Figure 6. The default logon screen

3.2. Launch IMSql/TM servers

IMSql/TM is divided into two servers:

IMSql.ProcessingServer: IMSql Processing Server

IMSql.ProcessingServer :ConnectionString=<connectionString> :RegionId=<region>

IMSql.TerminalServer: IMSql 3270 TCP Terminal Server

IMSql.TerminalServer :ConnectionString=<connectionString> :RegionId=<region>
By default, the terminal server is listening to port 32023. So, your terminal emulator must connect to port 32023.

3.3. Alternate PCB

The alternate PCB can have both transaction code names (NAME=) and logical terminal names (LTERM=) as an output message destination. While the mainframe makes distinctions between transactions and terminals, this distinction is not required for IMSql. In IMSql, both message destinations are simply programs, leading to a more uniform treatment of both.

Implementation of these destinations is as follows:

  • NAME= destinations are normal IMS/TM programs as on the mainframe, with their associated PSB files.

  • LTERM= destinations are also normal IMS/TM programs as if they were NAME= destinations. The only difference is that these do not have a PSB file.

To specify whether a program is a message destination for a logical terminal name or a transaction-code name, the mappings tab in the Raincode Console contains an Lterm flag. If it is set to true, the program is considered mapped to a logical terminal; if it is set to false, the program is considered mapped to a transaction code.

Writing a C# program as a destination for an alternate PCB message is possible. The program masquerades as a COBOL program, and by performing calls to CBLTDLI, it interacts with IMS/TM as normal. This, in effect, allows a logical terminal to be implemented in C#.

4. Utilities

IMSql provides several utilities:

  • IMSql.Load: A data load utility that reads IMS Unload files and loads them in SQL DB

  • IMSql.Unload: A data unload utility that reads the SQL Server database and generates an UNLOAD file used by IMS.

  • IMSql.DbGenerator: SQL Server script generator from DBD files

  • IMSql.TerminalServer: IMSql/TM 3270 Terminal Server

  • IMSql.ProcessingServer: IMSql/TM Processing Server

4.1. IMSql.Load

IMSql.Load import data from a flat file to the SQL Server database. The flat file’s format is produced by the DFSRRC00/ULU, DFSURGO0 standard utilities (for more detail, refer to the section Unload data from the Mainframe).

IMSql.Load use two different techniques to import the data into the database:

  • Insert: uses sql insert to insert the data into the database. This technique is used if the parameter -ConnectionString is used.

  • bcp: This version doesn’t explicitly load the data into the database but creates the files (data and format) that can be used by bcp to load the data into the database. IMSql.LoadSegment.ps1 is an example of a script to load the data using bcp. This technique is used if the parameter -BcpOutputFolder is used.

The insert version is the easiest to use because it directly inserts the data into the database, but it’s much slower (20 times) than the bcp one.

4.1.1. Load with insert

IMSql.Load -DbdFile=path_to_dbd_file -UnloadFile=path_to_data_file -ConnectionString="connection_string"

Where

  • path_to_dbd_file: the path to the DBD

  • path_to_data_file: the data file extracted from the mainframe that needs to be loaded

  • connection_string: the connection string to the database

4.1.2. Load with bcp

In bcp mode, it didn’t load the data but prepared them to be loaded by the SQL Server bcp command. The data file will be split into one file per table. For each table, a format file (.fmt) file is created that specifies the format argument used by the bcp command. It also produces a file, IMSqlLoad_seg.csv, that list the tables in which data should be loaded.

When the data have been processed, they need to be loaded in the database using bcp. When data have been loaded, foreign keys representing logical links should be updated, and the secondary indexes should be rebuilt.

Two stored procedures should be executed to do this: <DBD_name>_UPDATE_LPID and <DBD_name>_REGENERATE_SECONDARY_INDEX.

IMSql.Load -DbdFile=path_to_dbd_file -UnloadFile=path_to_data_file -BcpOutputFolder=path_to_ouputdir

Where

  • path_to_dbd_file: the path to the DBD

  • path_to_data_file: the data file extracted from the mainframe that needs to be loaded

  • path_to_outputdir: the output dir

bcp should take as parameters, in addition to connection parameters:

  • -E: Specifies that identity value or values in the imported data file are to be used for the identity column (RID column).

  • -h "CHECK_CONSTRAINTS": Specifies that all constraints on the target table or view must be checked during the bulk-import operation. Without the CHECK_CONSTRAINTS hint, any CHECK and FOREIGN KEY constraints are ignored, and after the operation, the constraint on the table is marked as not-trusted.

To check that all the foreign keys are trusted, execute the following query:

SELECT
FK.name [constraint_name]
,T.name [referencing_table_name]
,TabC.name [referencing_column_name]
,RefT.name [referenced_table_name]
,RefC.name [referenced_column_name]
,FK.delete_referential_action_desc delete_referential_action_desc
,FK.update_referential_action_desc update_referential_action_desc
,FK.is_disabled
,FK.is_not_trusted,
concat('ALTER TABLE ', t.name, '  WITH CHECK check  CONSTRAINT ' , fk.name) [query_to_trust]
FROM   sys.foreign_keys AS FK
   INNER JOIN sys.foreign_key_columns FKC
     ON FK.object_id = FKC.constraint_object_id
   INNER JOIN sys.tables AS T
     ON T.object_id = FK.parent_object_id
   INNER JOIN sys.columns AS TabC
     ON TabC.column_id = FKC.constraint_column_id
     AND TabC.object_id = FKC.parent_object_id
   INNER JOIN sys.tables AS RefT
     ON RefT.object_id = FK.referenced_object_id
   INNER JOIN sys.columns AS RefC
     ON RefC.column_id = FKC.referenced_column_id
     AND RefC.object_id = FKC.referenced_object_id

The column is_not_trusted should be equal to 0. If not, you should execute the query of the [query_to_trust] column to mark the Foreign Key (FK) as trusted. For each DBD, there is a stored procedure (<DBD name>_TRUST_FK) that tries to mark all the FK of the DBD as trusted.

When the data are loaded using bcp, the foreign keys representing the logical parent links are not correctly set, and the secondary indexes are not updated because the triggers are not activated. For each DBD, there are two stored procedures to update them:

  • <DBD name>_UPDATE_LPID: update the logical parent FK of the DBD

  • <DBD name>_REGENERATE_SECONDARY_INDEX: regenerate the secondary index of the DBD

A sample script ($env:RCDIR\scripts\IMSql\IMSql.LoadSegments.ps1) is provided. This script calls IMSql.Load for each DBD, bcp for each table and finally, for each DBD, execute the stored procedures to update the logical links, foreign keys, and secondary indexes. Before using this script, you should personalize it by changing the value of some variables:

  • $srcDir: the root directory of DBD and data files

  • $wrkDir: directory where temporary files will be created

  • $bcpOptions: options used by bcp (connection and database name)

  • $sqlcmd: options used by sqlcmd (connection and database name)

  • $todo: list of DBD to be loaded in a CSV format: <name of the DBD>,<DBD path relatif to $srcDir>,<data file relatif to $srcDir>

4.1.3. Command-line options of IMSql.Load

Configuration
Table 1. Command-line options of IMSql.Load
Command-line option Default value Description

BcpOutputFolder

Path to place the files for bcp.

ConnectionString

SQL Database connection string to connect.

DbContextDir

Directory where the DbContext dll’s are.

DBDFile

Path to the IMS DBD file.

DBDName

Name of the DBD.

UnloadFile

Path to save the content of the UNLOADED data.

This argument is mandatory.

Miscellaneous
Command-line option Default value Description

DotNetConfigFile

An additional app.config file.

Help

Display the help message. This is a boolean value.

LogLevel

WARNING

Values can be any of the following:

  • SILENT

  • ERROR

  • WARNING

  • INFO

  • DEBUG

  • TRACE

  • PROGRAM_OUTPUT

  • DIAGNOSTIC

Version

Display version information. This is a boolean value.

4.2. Unload data from the Mainframe

To unload data from the Mainframe, DFSRRC00 must be executed with the DFSURGU0 HD Reorganization Unload utility:

//ULU     EXEC PGM=DFSRRC00,PARM='ULU,DFSURGU0,DI21PART'

When the data are unloaded from IMS, they must be transferred from the Mainframe to the target platform as a binary file.

Below is a sample JCL to unload the data of the DI21PART DBD to a file called DR01.IMS.UDI21PAR.

//DR01DI21 JOB ACTINFO1,
// 'PGMRNAME',
// CLASS=A,
// MSGCLASS=A,MSGLEVEL=(1,1),
// NOTIFY=&SYSUID,
// REGION=64M
//*
//*JOBPARM PROCLIB=PROC01
//IMS1010 JCLLIB ORDER=(IMS1010.PROCLIB)
//* SCRATCH DATA SETS
//*
//SCRATCH EXEC PGM=IDCAMS,DYNAMNBR=200
//SYSPRINT DD SYSOUT=*
//SYSIN    DD *
  DELETE DR01.IMS.UDI21PAR -
         NONVSAM SCRATCH
//*
//* ALLOCATE DATA SETS
//*
//ALLOCATE EXEC PGM=IDCAMS,DYNAMNBR=200
//SYSPRINT DD SYSOUT=*
//SYSIN    DD *
  ALLOCATE -
      DSNAME('DR01.IMS.UDI21PAR') -
      FILE(UNLOAD1)               -
      RECFM(V B)                  -
      DSORG(PS)                   -
      NEW CATALOG                 -
      SPACE(1) CYLINDERS         -
      VOL(RC0001)              -
      UNIT(SYSDA)
//*
//*********************************************************************
//* FUNCTION: UNLOAD DATA BASE - MIGRATE = YES
//*********************************************************************
//*
//ULU     EXEC  PGM=DFSRRC00,PARM='ULU,DFSURGU0,DI21PART'
//STEPLIB  DD DSNAME=IMS1010.SDFSRESL,DISP=SHR
//DFSRESLB DD DSNAME=IMS1010.SDFSRESL,DISP=SHR
//IMS      DD DSN=IMS1010.DBDLIB,DISP=SHR
//         DD DSN=IMS1010.PSBLIB,DISP=SHR
//SYSPRINT DD SYSOUT=*
//RECON1   DD DSNAME=IMS1010.RECON1,DISP=SHR
//RECON2   DD DSNAME=IMS1010.RECON2,DISP=SHR
//SYSUDUMP DD SYSOUT=*
//DFSURGU1 DD DSNAME=DR01.IMS.UDI21PAR,DISP=OLD
//DI21PART DD DSNAME=IMS1010.DI21PART,DISP=SHR
//DI21PARO DD DSNAME=IMS1010.DI21PARO,DISP=SHR
//DFSVSAMP DD *
VSRBF=4096,5
VSRBF=2048,5
VSRBF=512,5
IOBF=(2048,5)
//*
//SYSIN    DD *
MIGRATE=YES
/*
//DFSCTL   DD *
SBPARM ACTIV=COND
/*

When the file (DR01.IMS.UDI21PAR in this example) is created, it should be uploaded from the Mainframe using FTP. Pay attention; this is a binary file with variable-length records. So it must be transferred in binary mode with the record length in front of each record.

ftp mainframe.mycompany.com
ftp> binary
200 Representation type is Image
ftp> literal site RDW
200 SITE command was accepted
ftp> get DR01.IMS.UDI21PAR

4.3. Command-line options of IMSql.Unload

4.3.1. Configuration

Table 2. Command-line options of IMSql.Unload
Command-line option Default value Description

ConnectionString

SQL Database connection string to connect.

DbContextDir

Directory where the DbContext dll’s are.

DBDFile

Path to the DBD file to get the segment information.

DBDName

Name of the DBD.

Plan

Plan name used to get SQL Database connection string to connect.

UnloadFile

Path to save the content of the UNLOADED data.

This argument is mandatory.

4.3.2. Miscellaneous

Command-line option Default value Description

DotNetConfigFile

An additional app.config file.

Help

Display the help message. This is a boolean value.

LogLevel

WARNING

Values can be any of the following:

  • SILENT

  • ERROR

  • WARNING

  • INFO

  • DEBUG

  • TRACE

  • PROGRAM_OUTPUT

  • DIAGNOSTIC

Version

Display version information. This is a boolean value.

4.4. Command line options of IMSql.DbGenerator

4.4.1. Miscellaneous

Table 3. Command line options of IMSql.DbGenerator
Command-line option Default value Description

ConsoleLog

False

The DbContext generated displays the queries in the console. This is a boolean value.

Data

True

Generates outputs for the IMSql DB database. This is a boolean value.

DbName

IMSql

The name of the IMSql DB database in the output scripts.

DebugLog

False

The DbContext generated displays the queries in the debug console. This is a boolean value.

DotNetConfigFile

An additional app.config file.

Encoding

Encoding of the DBD files.

Files

The input dbd files for generating the database scripts.

GenerateDisplayColumn

The generated table contains computed columns representing the ASCII representation of the raw fields. This is a boolean value.

Help

Display the help message. This is a boolean value.

LogLevel

WARNING

Values can be any of the following:

  • SILENT

  • ERROR

  • WARNING

  • INFO

  • DEBUG

  • TRACE

  • PROGRAM_OUTPUT

  • DIAGNOSTIC

Online

False

Generates outputs for the IMSql TM database. This is a boolean value.

OnlineDbName

IMSql_Config

The name of the IMSql TM configuration database in the output scripts.

OutputDir

./imsoutput

The output folder.

RepoConnectString

The repository connection string. See also the DBDriver option.

RepoDriver

Sets the connection string to use for the repository persistence system as an ODBC connection string if ODBC persistence is used or as a physical file name if SQLITE is used instead. See also the DBConnectString option. Values can be any of the following:. Values can be any of the following:

  • ODBC

  • Sqlite

ScanOnly

False

Parse and scan the DBD, but do not produce any code (.sql or .cs). This is useful for checking DBD syntax for compatibility. This is a boolean value.

Version

Display version information. This is a boolean value.

4.5. Command line options of IMSql.TerminalServer

4.5.1. Miscellaneous

Table 4. Command line options of IMSql.TerminalServer
Command-line option Default value Description

ConnectionListener

2

The maximum length of the pending connections queue for the terminals.

ConnectionString

The IMSql Configuration Database connection string.

This argument is mandatory.

DotNetConfigFile

An additional app.config file.

Help

Display the help message. This is a boolean value.

LogLevel

WARNING

Values can be any of the following:

  • SILENT

  • ERROR

  • WARNING

  • INFO

  • DEBUG

  • TRACE

  • PROGRAM_OUTPUT

  • DIAGNOSTIC

Port

32023

The TCP port for Tn3270 connections.

Queue

The queue listen by this terminal server. By default the queue is named "{System name}_{Region name}_{Machine name}".

RegionId

Default

The IMS RegionId to bind to the terminal server.

Version

Display version information. This is a boolean value.

4.5.2. Plugin

Command-line option Default value Description

Plugin

Loads plugin-providing assembly.

PluginPath

Path where plugins (and other assemblies) are searched.

4.6. Command line options of IMSql.ProcessingServer

4.6.1. Miscellaneous

Table 5. Command line options of IMSql.ProcessingServer
Command-line option Default value Description

CatalogConfiguration

Path to the configuration file for the catalog.

ConnectionString

The IMSql Configuration Online connection string.

This argument is mandatory.

DbConnectionString

The IMSql Configuration Database connection string.

DotNetConfigFile

An additional app.config file.

Help

Display the help message. This is a boolean value.

LogLevel

WARNING

Values can be any of the following:

  • SILENT

  • ERROR

  • WARNING

  • INFO

  • DEBUG

  • TRACE

  • PROGRAM_OUTPUT

  • DIAGNOSTIC

Queue

The queue listen by this processing server. By default the queue is named "IMS_PROC_{region name}". If the queue doesn’t exist, it’s create.

RclrunArgs

The args passed to rclrun.

RegionId

Default

The IMS RegionId to bind to the processing server.

SqlServer

Connect to SQL Server to access "DB2" data with the given connection string.

Version

Display version information. This is a boolean value.

4.6.2. Plugin

Command-line option Default value Description

Plugin

Loads plugin-providing assembly.

PluginPath

Path where plugins (and other assemblies) are searched.

5. Parser Utilities

Parser utilities are:

  • IMSql.Dbd: Utility to parse DBD files to generate XML representations.

  • IMSql.Mfs: Utility to parse MFS files to generate XML representations.

  • IMSql.Psb: Utility to parse PSB files to generate XML representations.

5.1. Command line options of IMSql.Dbd

5.1.1. Miscellaneous

Table 6. Command line options of IMSql.Dbd
Command-line option Default value Description

DotNetConfigFile

An additional app.config file.

Help

Display the help message. This is a boolean value.

InputEncoding

windows-1252

The encoding of the DBD Files.

LogLevel

WARNING

Values can be any of the following:

  • SILENT

  • ERROR

  • WARNING

  • INFO

  • DEBUG

  • TRACE

  • PROGRAM_OUTPUT

  • DIAGNOSTIC

MergeDB

Name of the database used for merging all the DBD files.

OutputDirectory

The directory will contain the generated XML files.

SqlDatabase

The sql database to upload the files to.

TabWidth

4

The number of spaces by which a tab character will be replaced when found in the DBD file.

Version

Display version information. This is a boolean value.

5.2. Command line options of IMSql.Mfs

5.2.1. Miscellaneous

Table 7. Command line options of IMSql.Mfs
Command-line option Default value Description

DotNetConfigFile

An additional app.config file.

Help

Display the help message. This is a boolean value.

IncludeDirectories

Directories that will contain the include/copybook files.

InputEncoding

windows-1252

The encoding of the MFS Files.

LogLevel

WARNING

Values can be any of the following:

  • SILENT

  • ERROR

  • WARNING

  • INFO

  • DEBUG

  • TRACE

  • PROGRAM_OUTPUT

  • DIAGNOSTIC

OutputDirectory

The directory will contain the generated XML files.

SqlDatabase

The sql database to upload the files to.

TabWidth

4

The number of spaces by which a tab character will be replaced when found in the MFS file.

Version

Display version information. This is a boolean value.

5.3. Command line options of IMSql.Psb

5.3.1. Miscellaneous

Table 8. Command line options of IMSql.Psb
Command-line option Default value Description

DotNetConfigFile

An additional app.config file.

Help

Display the help message. This is a boolean value.

InputEncoding

windows-1252

The encoding of the PSB Files.

LogLevel

WARNING

Values can be any of the following:

  • SILENT

  • ERROR

  • WARNING

  • INFO

  • DEBUG

  • TRACE

  • PROGRAM_OUTPUT

  • DIAGNOSTIC

OutputDirectory

The directory will contain the generated XML files.

RepoConnectString

The repository connection string. See also the DBDriver option.

RepoDriver

Sets the connection string to use for the repository persistence system as an ODBC connection string if ODBC persistence is used or as a physical file name if SQLITE is used instead. See also the DBConnectString option. Values can be any of the following:. Values can be any of the following:

  • ODBC

  • Sqlite

ScanOnly

False

Parse and scan the PSB, but do not produce any code (.xml). This is useful for checking PSB syntax for compatibility. This is a boolean value.

SqlDatabase

The sql database to upload the files to.

TabWidth

4

The number of spaces by which a tab character will be replaced when found in the PSB file.

Version

Display version information. This is a boolean value.

6. Plugin

6.1. Security plugin

When you connect from a terminal emulator, you will be prompted to provide a login and password.

The terminal server uses this plugin to check the user login and the processing server to check if a transaction can be executed.

The plugin instance is located at: RainCode.IMSql.Common.Security.SecurityManager.SecurityManagerPlugin

It should provide a method that receives a string as an input parameter and returns an ISecurityPlugin instance.

6.1.1. Security plugin API

The ISecurityPlugin interface provides methods allowing security in the IMSql.

public interface ISecurityPlugin
{
    string CheckLogin(string username, string password);

    bool CheckTransaction(string transCode, string securityString);
}
  • CheckLogin: that validates the login and password. This method returns a string called the security string. If the security string is empty, the user/password is wrong. If the security string starts with #ERROR#, it means that there is an error during the password validation (the error message is after the second #). Otherwise, the user/password is validated.

  • CheckTransaction: This method, based on the transaction code and the security string, checks if the user is allowed to execute the transaction.

6.2. Dummy plugin

This implementation checks if the user is RC (with any password) and allows the execution of all the transactions.

Plugin Implementation

using RainCode.Core.Logging;
using RainCode.Core.Plugin;
using RainCode.IMSql.Common.Security;
using System;

[assembly: PluginProvider(typeof(RainCode.IMSql.Security.DummySecurity), nameof(RainCode.IMSql.Security.DummySecurity.Register))]

namespace RainCode.IMSql.Security
{
    public class DummySecurity: ISecurityPlugin
    {
        private static LogSource LogSource = new LogSource("DummySecurity");

        public static void Register()
        {
            Logger.LogInfo(LogSource, "Registering DummySecurity");
            RainCode.IMSql.Common.Security.SecurityManager.SecurityManagerPlugin.Provide(10, TryBuild);
        }

        /// <summary>
        /// Initialize the plugin. Returns a pointer to a instance of "DummySecurity".
        /// </summary>
        /// <param name="cfg">not used in this implementation </param>
        /// <returns></returns>
        public static ISecurityPlugin TryBuild(string cfg)
        {
            return new DummySecurity(cfg);
        }

        public DummySecurity(string cfg)
        {

        }

        /// <summary>
        /// Validate the user/password.
        /// If the "securityString"
        ///  * is empty or null, the user name ('userId') or the password ('password') is wrong.
        ///  * starts with "#ERROR#", it's an error message.
        ///  * Otherwise the security string is associated with the session and contains data necessary
        ///      to check if the current user is allowed to execute a given transaction.
        /// </summary>
        /// <param name="user">The user id</param>
        /// <param name="password">The password</param>
        /// <returns>In this example, "ok" if 'user' = "RC", error otherwise</returns>
        public string CheckLogin(string user, string password)
        {
            // Here check if the user/password are correct
            Logger.LogInfo(LogSource, $"CheckLogin {user}");
            if (user.Equals("RC", StringComparison.OrdinalIgnoreCase))
            {
                return "ok";
            } else
            {
                return $"#ERROR#Use RC user";
            }
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="transCode">the transaction code</param>
        /// <param name="securityString">the security string</param>
        /// <returns>In this example, always return true</returns>
        public bool CheckTransaction(string transCode, string securityString)
        {
            // Here check if the current user can execute the transaction 'transCode' based on 'securityString'
            Logger.LogInfo(LogSource, $"CheckTransaction {transCode} / { securityString}");
            return (securityString.Equals("ok", StringComparison.OrdinalIgnoreCase));
        }
    }
}

6.3. Active Directory plugin

This implementation uses Active Directory.

The configuration string is read from the configuration database (select [VALUE] from [REGION_OPTION] where [REGION_NAME] = the current region and [NAME] = 'security_config').

The configuration string contains four parameters separated by a ;:

  • the address of the server - for example, corp.phidani.be

  • the domain name - for example, OU=Phidani Users, DC=corp, DC=phidani, DC=be

  • the domain in which the user must be validated - for ex, CORP

  • CSV file containing couples transaction;group. Where transaction is the name of a transaction and group a group name allowed to execute a transaction

CheckLogin checks the user/password using the Active directory. CheckTransaction checks if at least one user group (listed in securityString separated by a ,) is contained in the CSV file.

7. Debugging

7.1. Debugging a Batch Program

To debug a batch program, add a parameter in your JCL.

  • Compile the program with the -Debug option. (cobrc -Debug)

  • Add DEBUG=TRUE as the 21st parameter of DFSRRCOO

//G1      EXEC PGM=DFSRRC00,REGION=512K,
//            PARM='DBB,DLRSTAT,DLRSTAT,,,,,,,,,,,,,,,,,,DEBUG=TRUE'
  • Submit the JOB

Submit -FILE=`EXTRACT-STAT.JCL`
  • A debug window will pop up in a few seconds. Select the Visual Studio from the list.

jitdebugger
Figure 7. Just in time debugger

7.2. Debugging an Online Program

To debug an online program, attach the debugger to the processing server.

  • Compile the program with the -Debug option. (cobrc -Debug)

  • Start the processing server (IMSql.ProcessingServer)

  • Select Debug→Attach to Process…​ (Ctrl+Alt+P) to attach a process.

attachtoprocess
Figure 8. Attach to Process
  • A window will appear, select IMSql.ProcessingServer and set a breakpoint in the program.

Processingserver
Figure 9. Attach to Process

7.3. Logging

Log messages will be displayed differently depending on the log level.

If the log level is set to INFO, a message is displayed at the end of the IMS query giving the execution time in milliseconds.

[2023-10-13 12:16:31.538] [10] [INFO] [APPDLI]: IMS Call end: GU with 4 parameters: 447

The following messages are displayed if the log level is set to TRACE.

[2023-10-13 12:16:31.090] [10] [TRACE] [APPDLI]: IMS Call [2023-10-13 12:16:31.091] [10] [TRACE] [APPDLI]: IMS Call : GU with 4 parameters.

The above message displays the function and the number of parameters.

[2023-10-13 12:16:31.092] [10] [TRACE] [APPDLI]: IMS Call for 4340. [2023-10-13 12:16:31.093] [10] [TRACE] [APPDLI]: IMS Call for 4340 on DB.

The above message displays the PCB id and the type.

[2023-10-13 12:16:31.532] [10] [TRACE] [IMS.ResultRowCache]: Init cache from reader: 1

The above message displays the number of lines prefetched in the cache.

[2023-10-13 12:16:31.533] [10] [TRACE] [IMS.ResultRowCache]: The current element is 0

The above message displays the element number read in the cache (zero based).

[2023-10-13 12:16:31.534] [10] [TRACE] [APPDLI]: IMS call status: Blanks

The above message displays the query status code.

If the log level is set to DIAGNOSTIC, the SSA used, and the SQL query is displayed.

[2023-10-13 12:16:31.094] [10] [DIAGNOSTIC] [IMS.Ssa]: Ssa: DEALER(DLRNO EQ DDDD00003)
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (6ms) [Parameters=[], CommandType='Text', CommandTimeout='600']
SELECT TOP(10) N'DEALER' AS [Type], 0 AS [Level], [d].[RID], -1 AS [PID], SUBSTRING([d].[Data], 0 + 1, 10000) AS [Data], [d].[DLRNO] AS [Key], SUBSTRING([d].[DLRNO], 0 + 1, 10) AS [CKey], N'$' + CONVERT(VARCHAR(11), [d].[RID]) AS [CRid], (0x01 + 0x00) + 0x AS [CHid], [d].[HID], N'' AS [QueryType], CAST(1 AS bit) AS [HasChild]

FROM [DEALERDB_DEALER] AS [d]

WHERE [d].[DLRNO] = 0xC4C4C4C4F0F0F0F0F340

ORDER BY [d].[DLRNO]

8. Database Connection

There can be two connection strings to IMS. The first is the connection to the data database, and the second is the connection to the online database that manages the queues.

8.1. IMS Batch

The plan to be used to retrieve the connection string is the 14th parameter of DFSRRC00. This plan is used to search for a connection string to connect to the database. If a plan with the same name suffixed by _config is found, this plan is used to connect to the online database.

If no such plan is found, the connection string to the database is used to connect to the online database by adding _config to the database name.

If a batch program also needs to access the DB2 database. The connection string to the DB2 database is given as two environment variables named RC_DB_CONNECTION and RC_DB_TYPE.

8.2. IMS Online

Terminal server

The terminal server has only one connection string to the online database. The -ConnectionString option.

Processing server

The processing server needs two connection strings, one to the database and one to the online database.

-ConnectionString option is used to give the connection string to the online database. This option is mandatory.

-DbConnectionString option is used to give the connection string to the database. This option is optional.

If not present, the connection string to the online database is used by removing the _config prefix from the database name.

If an online program also needs to access DB2 database. The DB2 connection string should be given using the -SqlServer option.

For example:

-SqlServer="Server=tcp:10.0.0.10,1433;Initial Catalog=MY_DB;Persist Security Info=False;User ID=ME;Password=mypwd;MultipleActiveResultSets=True;Encrypt=True;TrustServerCertificate=False;

Appendix A: Useful information

This appendix includes some additional useful information concerning IMSql.

A.2. List of Figures