Carma Developer`s Perspective

advertisement
Enterprise Modernisation
CARMA Developer's Perspective
Anthony Rudd (anthony.rudd@datev.de)
© DATEV eG
August 2009
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
1
CARMA Developer's Perspective
This paper describes the use of the RDz CARMA interface from the developer's perspective using as
example the interface to DATEV's proprietary source management system ("SRCVW" = SouRCe
VerWaltung). It does not describe the tasks that the system programmer must perform to create the
required CARMA environment.
This paper is based on a session presented at an earlier Enterprise Modernisation conference.
Although the methodology described in this paper was tested on WDz Version 6, the procedure is still
generally valid (RDz 7.5).
SRCVW Characteristics:
SRCVW is USS based (administrative data, program source versions).
Each user (department, group, team, etc.) must define a project (and project version, currently, except
for test projects, always 1.0).
Each program version exists as a unique HFS file.
This gives the following 4-level name structure:
<project>/<projectversion>/<programname>/<programversion>
For example:
SED/1.0/SETEST14/1.3
Interfaces (APIs):
SRCVW provides a TSO REXX procedure that routes the request to the appropriate service routine.
Such service routines have both associated TSO REXX procedures and USS REXX procedures.
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
2
Project structure
The following figure illustrates a simple SRCVW project structure with the associated entities
(connection, RAM, instance, member). The green arrow indicates an active connection.
The figure shows that MVSE001 connection has three RAMs: PDS RAM, SCLM RAM and SRCVW
RAM. The first two RAMs are samples supplied with RDz. The customised SRCVW RAM used the
RDz-supplied TEST RAM as basis.
Connection
RAM
Instance
Member
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
3
Alternative project structure
It is also possible to define an alternative project structure that has an additional level 2 (project +
project version). This allows containers to be defined at the next lower level.
Expanding the project level lists the associated programs.
Expanding a program (=container) lists the associated program versions.
Connection
RAM
Instance
Container
Member
Note: Which of these two structures is used is largely a personal preference.
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
4
RAM implementation
Characteristics:
The SRCVW RAM is a C program (RDz also supplies a sample COBOL program that could be
customised).
Customised interfaces (C functions) were written to provide fast access to general SCM services
(read-only) - list "directory" contents, list program, etc.
Standard SCM REXX execs used for "write" services (check out, …).
SRCVW RAM uses a wrapper to invoke these services. The wrapper (a user-written C function)
invokes the REXX interpreter to call the specified SCM service. The SCM services return a result
string that contains the service return code (non-zero return code -> error, the associated error text is
contained in the result string). The wrapper parses this result string to evaluate the result.
Some RAM operations set a custom return value, for example, to explicitly confirm the end of the
associated operation.
Typical CARMA RAM function
A typical CARMA RAM function has the following form:
int checkin(char instanceID[256], char memberID[256], void **params,
void ***customReturn, char error[256]);
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
5
CARMA configuration
The use of CARMA requires that certain host-side configuration settings be made. These are
primarily:



The creation of the CRADEF VSAM file.
The creation of the CRASTRS VSAM file.
The creation of the CARMA “job”.
These are described in more detail later and explained in the CARMA Developer’s Guide (SC297660).
Essentially, these configuration settings have the following purpose. The CRADEF file defines the load
module name of the RAMs, which functions each RAM supports with the associated symbolic
parameters and return values. The CRASTRS file supplies the associated translated text in the
supported codepages for the entries defined in CRADEF. The CARMA job (batch TSO) starts when a
connection to a CARMA repository is made and accepts the requests; the job terminates when a
disconnection is made to the CARMA repository. This job must supply all DD statements required by
the RAM.
The CARMA runtime uses the CRADEF and CRASTRS file content to generate the appropriate
input/output masks.
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
6
Example of a dynamically generated input mask
The following input mask is generated when the Checkout action (action number 13) is invoked.
The CRADEF record for action 13 (Ann013 record) defines three input parameters (003, 004 and 005) and one
return value (000). These have associated CRADEF record definitions Pnn003 … 005 and Tnn000, respectively
(nn is the RAM number, in this case 02).
A02013
003,004,005!000
P02003
P02004
P02005
STRING
STRING
STRING
44
8
32
T02000
STRING
48
N
N
N
The associated CRASTRS records contain the national-language text to be displayed for each of these fields .
EN_US
EN_US
EN_US
00037P02003
00037P02004
00037P02005
DSN
MEM
OPTIONS
EN_US
00037T02000
OK
Dataset name?
Member name?
Options?
Completed successfully
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
7
CARMA RAM function parameters
The parameters passed to and returned from a specific CARMA function depend on the associated
function and on the settings made in CRADEF (for example, the number of parameters and the form
of the associated text).
The following parameters are used by many functions:
<instanceID>
<memberID>
<params>
<customReturn>
<error>
Descriptor
identifies the associated instance
identifies the associated member
pointer to an array of associated parameters
pointer to an array of custom return values set by the function
Note: the actual return values must not be on the stack.
a character string that contains descriptive text for an error
(non-zero function return value)
returned data records
(the number of returned records must be set in a separate field)
With the exception of Descriptor, which is a structure name, variable names are shown.
<params> and <customReturn> for the associated function implementation must be defined in
CRADEF.
The associated <params> and <customReturn> displayed in a mask with the text specified for the
associated function implementation must be defined in CRASTRS.
The Descriptor structure has the following fields
char id[256];
char name[64];
<id> is, in effect, a unique key
<name> is the displayed text.
Memory for returned data
Buffers for returned data must be allocated dynamically (in C, with malloc() ).
The CARMA host client frees the allocated (heap) memory.
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
8
ID structure
The ID must be unique (and not contain any 0x00s!; the presence of 0x00s can cause strange and
unexpected behaviour).
The associated ID is returned for most CARMA functions
-> used to return the appropriate information from the SCM (via program logic (direct, indirect using a
hash table, etc.))
My ID structure:
1<project>, e.g. 1SED
2<project>/<projectversion>, e.g. 2SED/1.0
3<project>/<projectversion>/<program>, e.g. 3SED/1.0/SETEST13
4<project>/<projectversion>/<program>/<programversion>, e.g. 4SED/1.0/SETEST13/1.2
This allows the associated data to be retrieved directly.
Note: It is important to map the logical structure of the SCM to an appropriate ID.
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
9
Actions
The CARMA functions are associated with an action ID. The functions can be customised for the
specific RAM. This customisation is made in the CRADEF (and CRASTRS) VSAM-KSDS files (and
obviously in the programmed RAM).
The following actions are available:
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
80
81
82
83
initRam
terminateRam
getMembers
extractMember
putMember
getAllMemberInfo
getMemberInfo
updateMemberInfo
isMemberContainer
getContainerContents
lock
unlock
checkIn
checkOut
getInstances
reset
performAction (customised actions)
initCarma
terminateCarma
getRAMList
getRAMData
The actual actions (and their parameters and return values) supported by the RAM must be specified
in the CRADEF file.
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
10
Actions (continued)
Although most actions are called implicitly (for example, initRam(), some actions are called
explicitly (checkIn(), checkOut(), lock(), unlock(), custom()) from the instance
context menu.
Other actions can be controlled by the RAM.
For example, isMemberContainer(). The answer Yes (=1) means the
getContainerContents() action will be called when the corresponding entry is expanded.
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
11
Customised action
Customised actions can be defined for a RAM. Each customised action has its own unique ID (its
action ID). Action IDs in the range 100 to 999 are used to define customised actions.
The performAction() function receives control when a customised action is invoked.
The function has four input arguments:
actionID
instanceID
memberID
params
The associated customised action ID
The instance ID
The member ID
The parameters defined for the customised action ID. The parameters are entered in
the displayed prompt.
Extract from the CRADEF file
A02101
A02102
006|000,001
006|000
P02006
STRING
32
T02000
T02001
STRING
STRING
48
16
N
Positions 2-3 specify the associated RAM number; position 1 is the record type.
The associated CRASTRS entries:
EN_US
EN_US
00037A02101
00037A02102
COMPILE
RESET
EN_US
00037P02006
PARM
EN_US
EN_US
00037T02000
00037T02001
OK
RSC
Parameters
Completed successfully
Here positions 9-13 specify the codepage, and 14-16 the record type and RAM number.
These entries specify that RAM 02 (SRCVW) has two customised actions: 101 = COMPILE, 102 =
RESET. Each of these actions has one input parameter (006) and one or two customised return
values, respectively. The input parameter has Parameters as displayed text (the name PARM is not
used).
COMPILE has two customised return values with names OK as and RSC, respectively (the
descriptions, Completed successfully for OK) are not used).
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
12
CRADEF schematic (for the first custom action)
┌─┬───┬─────┬───┬─────┬─┬─────────────┐
│A│0│2│1│0│1│
│0│0│6│|│0│0│0│,│0│0│1│
└┬┴─┬─┴─────┴───┴─────┴┬┴─────────────┘
│ │ └──┬──┘
└──┬──┘│└──────┬──────┘
│ │
│
│
│
│
│ │
│
│
│
└───────►
│ │
│
│
└───────────────►
│ │
│
└───────────────────►
│ │
│
│ │
└─────────────────────────────►
│ │
│ └──────────────────────────────────►
│
└─────────────────────────────────────►
Return value IDs (-> T record)
Delimiter (note: ! in German)
Parameter IDs (-> P records)
Secondary ID (= custom Action ID)
RAM ID
A = Action
Parameter entry
┌─┬───┬─────┬───┬──────┬───┬─┐
│P│0│2│0│0│6│
│STRING│32 │N│
└┬┴─┬─┴─────┴───┴──────┴─┬─┴┬┘
│ │ └──┬──┘
└───┬──┘ │ │
│ │
│
│
│ └───────►
│ │
│
│
│
│ │
│
│
└──────────►
│ │
│
│
│ │
│
└───────────────►
│ │
│
│ │
└──────────────────────────►
│ │
│ └───────────────────────────────►
│
└──────────────────────────────────►
N = not constant
Parameter length
Parameter type
Parameter ID
RAM ID
P = Parameter
The associated CRASTRS entry (for brevity, without prefixed locale (EN_US) and code page (00037) )
┌────────┬──────┬────────────┐
│ P02006 │ PARM │ Parameters │
└───┬────┴──┬───┴─────┬──────┘
│
│
│
│
│
└───────────────► Description
│
└─────────────────────────► Name (not used)
└─────────────────────────────────► Key
The associated display
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
13
Depending on whether COMPILE or RESET is double-clicked, customised actionID 101 or 102,
respectively, will be passed to the processing function.
In this case, COMPILE (customised actionID 101) was selected for member SETEST13.
InstanceID: 2SEA/1.0
memberID: 4SEA/1.0/SETEST13/1.1
With the associated parameter prompt
Here 'alpha' is entered as parameter.
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
14
The first customised return value entry
┌─┬───┬─────┬───┬──────┬───┐
│T│0│2│0│0│0│
│STRING│48 │
└┬┴─┬─┴─────┴───┴──────┴─┬─┘
│ │ └──┬──┘
└───┬──┘ │
│ │
│
│
│
│ │
│
│
└──────────►
│ │
│
└───────────────►
│ │
└──────────────────────────►
│ └───────────────────────────────►
└──────────────────────────────────►
Customised return value maximum length
Parameter type
Parameter ID
RAM ID
P = Parameter
The associated CRASTRS entry (for brevity, without prefixed locale (EN_US) and code page (00037) )
┌────────┬────┬────────────────────────┐
│ T02000 │ OK │ Completed successfully │
└───┬────┴─┬──┴───────────┬────────────┘
│
│
│
│
│
└───────────────► Description (not used)
│
└──────────────────────────────► Name (used in the display)
└─────────────────────────────────────► Key
With the associated return
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
15
The associated user-written performAction() function
int performAction(int actionID, char instanceID[256],
char memberID[256], void** params,
void*** customReturn, char error[256]) {
char *pprocname;
char *ppj;
static char msg1[48];
static char msg2[16];
ppj = params[0]; // pointer to first parameter
switch (actionID) { // process
case 101:
pprocname = "SESVCACT"; // Compile
break;
case 102:
pprocname = "SESVCRES"; // Reset
break;
default:
printf("invalid actionID: %d\n",actionID);
return 107;
}
presult = execREXXProcedure(pprocname,1,ppj);
rc = getRC(presult); // extract return code from result
printf("execREXXProcedure RC:%d\n",rc);
if (rc != 0) {
int n;
memset(error, ' ', 256);
n = MIN(strlen(presult),256);
memcpy(error,presult,n);
return 503;
}
switch (actionID) {
case 101: // compile
memset(msg2, ' ', sizeof(msg2));
memcpy(msg2, "Reason code: 47",15);
*customReturn = malloc(sizeof(void *) * 2);
(*customReturn)[1] = (void *)msg2;
break;
case 102: // reset
*customReturn = malloc(sizeof(void *) * 1);
break;
default:
}
memset(msg1, ' ', sizeof(msg1));
memcpy(msg1, "completed successfully",22);
(*customReturn)[0] = (void *)msg1;
return 0;
}
Note: Because the two custom actions return a different number of return values, to prevent memory
leakage, it is important that the correct amount of memory is allocated for the customReturn vector.
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
16
Action custom parameters
The parameters to be passed to an action are specified in CRADEF (and CRASTRS).
When an action is invoked, the associated mask for the parameter input will be displayed.
Example
If the "Remember the entered values for later" box is ticked, the entered values will be retained for the
associated entry. Some displayed text is generated automatically (based on the associated action),
whereas the text associated with the parameters comes from the CRASTRS file.
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
17
Action function return values
An action can return two values:
 the function direct return value
(0 = success, otherwise error return code (optionally with text in <error>))
 custom return value(s)
The function direct return value must be set.
If custom return values are set, the appropriate entries must be defined in CRADEF (and CRASTRS).
Many functions also return data.
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
18
Action function direct return value
A non-zero function return value indicates failure.
Both predefined return codes (for example, 20 = internal error) and user-defined return codes can be
used (return codes in the range 500-900). User-defined return codes do not need to be defined in any
CARMA control files. Appendix A of the CARMA Developer's Guide lists the predefined return codes.
The error message for a user-defined return code is generated based on the associated action
function, the return code and the supplied text.
Example for setting a non-zero function return value
int checkin(char instanceID[256], char memberID[256], void **params,
void ***customReturn, char error[256]) {
…
memset(error, ' ', 256);
pstr = "CKIN Function not supported";
memcpy(error, pstr, strlen(pstr));
return 507;
}
The associated display
Note: The extended error text is displayed when the mouse is positioned on the error message.
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
19
Action custom return value
Example of the use of a custom return value to indicate the successful processing of an action.
The appropriate heap memory must be allocated to contain the pointer to each custom return value
(the number of custom return values and their respective maximum lengths are specified in the
CRADEF entry from the associated action. In this case, one custom return value is returned.
Heap memory can be allocated dynamically with the malloc() function or statically as global variable
or with the static attribute.
int performAction(int actionID, char instanceID[256],
char memberID[256], void **params,
void ***customReturn, char error[256]) {
…
static char msg[49];
memset(msg, ' ', sizeof(msg)); // clear msg area
memcpy(msg, "Processing completed successfully", 34);
*customReturn = malloc(sizeof(void *) * 1);
(*customReturn)[0] = (void *)msg;
return 0; /* OK */
}
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
20
CARMA RAM job
CRASUBMT (in SCRACLST)
This job is started when the connection to CARMA is made, and terminated on disconnection (at the
remote system level).
Example of a customised CRASUBMT job
PROC 1 PORT
SUBMIT * END($$)
//&SYSUID.1 JOB (accountinginformation),CARMASERV,
// MSGLEVEL=(1,1),MSGCLASS=V,TIME=(,20),CLASS=N,NOTIFY=&SYSUID
//* LICENSED MATERIALS - PROPERTY OF IBM
*//
…
//ALLOC EXEC PGM=IEFBR14
//TEMP
DD UNIT=3390,SPACE=(CYL,(1,1)),LRECL=80,RECFM=FB,DSORG=PS,
//
DSN=&SYSUID..TEMP,
//
BLKSIZE=0,DISP=(MOD,CATLG)
//*
//RUN
EXEC PGM=IKJEFT01,DYNAMNBR=25,REGION=1024K
//STEPLIB DD DSN=CRA.V6.SCRALOAD,DISP=SHR
//
DD DSN=REXX.V1R4.SEAGLPA,DISP=SHR
//CRADEF
DD DSN=CRA.V6.VSAMV.CRADEF,DISP=SHR
//CRAMSG
DD DSN=CRA.V6.VSAMV.CRAMSG,DISP=SHR
//CRASTRS DD DSN=CRA.V6.VSAMV.CRASTRS,DISP=SHR
//CRARAM1 DD DSN=CRA.V6.VSAMV.CRARAM1,DISP=SHR
//CRARAM2 DD DSN=CRA.V6.VSAMV.CRARAM2,DISP=SHR
//ISPPROF DD UNIT=3390,SPACE=(CYL,(2,2,2)),LRECL=80,RECFM=FB,DSORG=PO,
//
BLKSIZE=3120,DISP=(NEW,DELETE)
//SYSUDUMP DD SYSOUT=V
//*
//* DD:TEMP work file required for DATEV SRCVW CARMA interface
//TEMP
DD DSN=&SYSUID..TEMP,DISP=(OLD)
//SYSPROC DD DSN=SYS1.SBPXEXEC,DISP=SHR
//
DD DSN=SYS1.SISPCLIB,DISP=SHR
//
DD DSN=TSSE000.FSET.EXEC,DISP=SHR
//
DD DSN=TSRCVW.SRCVW.DIALOG,DISP=SHR
…
//ISPEXEC DD DSN=SYS1.SISPEXEC,DISP=SHR
//ISPPLIB DD DSN=SYS1.SBPXPENU,DISP=SHR
…
//ISPMLIB DD DSN=SYS1.SBPXMENU,DISP=SHR
…
//ISPSLIB DD DSN=SYS1.SISPSLIB,DISP=SHR
…
//ISPTLIB DD DSN=SYS1.SBPXTENU,DISP=SHR
…
//SYSTSPRT DD SYSOUT=*
//SYSTSIN DD *
ISPSTART +
PGM(CRASERV) PARM(&PORT)
//
$$
EXIT CODE(0)
Italics = DATEV extension to the CRASUBMT job.
Red = CARMA files.
Note: The DLL with the user-written RAM must be contained in one of the libraries specified in the
STEPLIB concatenation.
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
21
CARMA control files
CARMA has several VSAM control files (see CRASUBMT).
The two VSAM control files of direct interest for the RAM programmer are:


CRADEF (language-independent CAF (Custom Action Framework) data)
CRASTRS (language-dependent CAF data)
These files will normally need to be customised for the RAM.
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
22
CRADEF
Language-independent CAF data (one record for each CAF object type: A = action, P = parameter, R
= RAM, T = return value)
A01004
A01010
A01011
A01014
A01100
A01101
A02004
A02013
A02014
A02101
A02102
D02010
P01000
P01001
P01002
P01003
P01004
P01005
P02000
P02001
P02002
P02003
P02004
P02005
P02006
R00000
R01000
R02000
T02000
T02001
001,003!
001,002!
001,002!
000!
001,004,005!
001,004,005!
003,004!
003,004,005!000
000,001,002!
006!000,001
006!000
STRING
STRING
STRING
STRING
STRING
STRING
STRING
STRING
STRING
STRING
STRING
STRING
STRING
1.1
1.0
1.0
STRING
STRING
C
C
C
16
16
16
16
1
1
8
8
8
44
8
32
32
Z/OSV1R41.0
1.0
1.0
Z/OSV1R61.0
48
16
N
N
N
N
N
N
N
N
N
N
N
N
N
CRARPDS
CRARSCLM
RUDDRAM
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
23
CRASTRS
Language-dependent CAF data.
Each CRADEF record has a corresponding CRASTRS record for each language, even when the
CRASTRS record does not contain any text.
EN_US
EN_US
EN_US
EN_US
EN_US
EN_US
EN_US
EN_US
EN_US
EN_US
EN_US
EN_US
EN_US
EN_US
EN_US
EN_US
EN_US
EN_US
EN_US
EN_US
EN_US
EN_US
EN_US
EN_US
EN_US
EN_US
EN_US
EN_US
EN_US
EN_US
EN_US
00037A01004
00037A01010
00037A01011
00037A01014
00037A01100
00037A01101
00037A02004
00037A02009
00037A02013
00037A02014
00037A02101
00037A02102
00037D02010
00037P01000
00037P01001
00037P01002
00037P01003
00037P01004
00037P01005
00037P02000
00037P02001
00037P02002
00037P02003
00037P02004
00037P02005
00037P02006
00037R00000
00037R01000
00037R02000
00037T02000
00037T02001
BUILD
PROMOTE
COMPILE
RESET
PROJECT
PROJDEF
ACCESS
LANGUAGE
SCOPE
MODE
PROJECT
PV
PGM
DSN
MEM
OPTIONS
PARM
PDS RAM
SCLM RAM
SRCVW RAM
OK
RSC
What is the project name?
What is the project definition?
Access?
What is the language?
N
What is the scope?
C
What is the mode?
Project name?
Project version?
Program name?
Dataset name?
Member name?
Options?
Parameters
Allows browsing of PDSs and browsing/modification
Capable of performing all CARMA API actions
My test RAM;
Completed successfully
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
24
Schematic relationship between CRADEF entries (simplified)
A02014
A02101
A02102
P01000
…
P02000
P02001
P02002
P02003
P02004
P02005
R00000
R01000
R02000
T02000
000,001,002!
000!000
000!000
STRING
16
N
STRING
STRING
STRING
STRING
STRING
STRING
1.1
1.0
1.0
STRING
8
8
8
44
8
32
Z/OSV1R41.0
1.0
1.0
Z/OSV1R61.0
2
N
N
N
N
N
N
CRARPDS
CRARSCLM
RUDDRAM
C
C
C
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
25
CRADEF
A RAM definition
┌─┬───┬─────┬───┬───┬─┬────────┬───┬───────┐
│R│0│2│0│0│0│
│1.0│C│Z/OSV1R6│1.0│RUDDRAM│
└┬┴─┬─┴──┬──┴───┴─┬─┴┬┴────┬───┴─┬─┴───┬───┘
│ │
│
│ │
│
│
│
│ │
│
│ │
│
│
└──────►
│ │
│
│ │
│
│
│ │
│
│ │
│
└────────────►
│ │
│
│ │
│
│ │
│
│ │
└──────────────────►
│ │
│
│ │
│ │
│
│ └────────────────────────►
│ │
│
│
│ │
│
└───────────────────────────►
│ │
│
│ │
└────────────────────────────────────►
│ │
│ └─────────────────────────────────────────►
│
└────────────────────────────────────────────►
DLL name
CARMA version
Repository version
Programming language (C,COBOL,PLI)
RAM version
'000'
RAM ID
R = RAM (record type
The associated CRASTRS entry
┌────────┬───────────┬──────────────┐
│R02000 │ SRCVW RAM │ My test RAM; │
└───┬────┴─────┬─────┴──────┬───────┘
│
│
│
│
│
└──────────────► Description
│
│
│
└───────────────────────────► Name (= repository type)
│
└──────────────────────────────────────► Key
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
26
The associated DATEV RAM properties (from the context menu)
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
27
Disabled Action entry
An Action entry is customised to specify the input parameters and return values.
Extract from the CRADEF file.
D02010
Associated CRASTRS entry:
EN_US
00037D02010
CRADEF schematic
┌─┬───┬─────┐
│D│0│2│0│1│0│
└┬┴─┬─┴─────┘
│ │ └──┬──┘
│ │
│
│ │
└──────────────► Action ID to be disabled
│ └───────────────────► RAM ID
└──────────────────────► D = Disable
The associated CRASTRS entry must only be present for completeness, although it does not contain
any text.
The associated action (in this case, 010 = Lock) cannot be invoked for this RAM. The associated
context menu entry will be greyed-out.
Example of context menu with disable action.
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
28
Customised Action entry
An Action entry is customised to specify the input parameters and return values.
Extract from the CRADEF file.
A02013
P02003
P02004
P02005
003,004,005|000
STRING
44
STRING
8
STRING
32
N
N
N
Associated CRASTRS entries:
EN_US
EN_US
EN_US
00037P02003
00037P02004
00037P02005
DSN
MEM
OPTIONS
Dataset name?
Member name?
Options?
CRADEF schematic
┌─┬───┬─────┬───┬─────┬─────┬─────┬─┬─────┐
│A│0│2│0│1│3│
│0│0│3│0│0│4│0│0│5│|│0│0│0│
└┬┴─┬─┴──┬──┴───┴─────┴─────┴─────┴┬┴──┬──┘
│ │
│
└────────┬────────┘│
│
│ │
│
│
│
│
│ │
│
│
│
└───────►
│ │
│
│
└───────────►
│ │
│
└─────────────────────►
│ │
│
│ │
└─────────────────────────────────────►
│ │
│ └──────────────────────────────────────────►
│
└─────────────────────────────────────────────►
Return value ID (-> T record)
Delimiter (note: ! in German)
Parameter IDs (-> P records)
Secondary ID (= Action ID)
RAM ID
A = Action
Parameter entry
┌─┬───┬─────┬───┬──────┬──┬─┐
│P│0│2│0│0│3│
│STRING│44│N│
└┬┴─┬─┴──┬──┴───┴───┬──┴─┬┴┬┘
│ │
│
│
│ │
│ │
│
│
│ └────────►
│ │
│
│
│
│ │
│
│
└──────────►
│ │
│
│
│ │
│
└───────────────►
│ │
│
│ │
└──────────────────────────►
│ │
│ └───────────────────────────────►
│
└──────────────────────────────────►
N = not constant
Parameter length
Parameter type
Parameter ID
RAM ID
P = Parameter
Associated CRASTRS entry (for brevity, without prefixed locale (EN_US) and code page (00037) )
┌────────┬─────────┬───────────────┐
│P02003 │
DSN
│ Dataset name? │
└───┬────┴────┬────┴───────┬───────┘
│
│
│
│
│
└───────────────► Description
│
│
│
└────────────────────────────► Name
│
└──────────────────────────────────────► Key
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
29
The associated parameters prompt:
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
30
Custom return value entry
┌─┬───┬─────┬───┬──────┬────┐
│T│0│2│0│0│0│
│STRING│ 32 │
└┬┴─┬─┴──┬──┴───┴───┬──┴─┬──┘
│ │
│
│
│
│ │
│
│
└─────────►
│ │
│
│
│ │
│
└──────────────►
│ │
│
│ │
└─────────────────────────►
│ │
│ └──────────────────────────────►
│
└─────────────────────────────────►
Maximum length
Return value type
Return value ID
RAM ID
T = Return value
Associated CRASTRS entry
┌────────┬───┬────────────────────────┐
│T02000 │OK │ Completed successfully │
└───┬────┴─┬─┴──────────┬─────────────┘
│
│
│
│
│
└──────────────────► Description
│
│
│
└───────────────────────────────► Name
│
└──────────────────────────────────────► Key
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
31
The associated displayed custom return value mask:
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
32
Difference between a "customised action" and a "custom action"
A "customised action" is a standard action (for example, checkIn) that has user-defined parameters
and return values.
A "custom action" is a new action that is invoked from the Custom entry in the context menu and which
causes the performAction service to be called with the associated custom action ID.
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
33
Wrapper function
Wrapper functions can be used to "wrap" existing services so they can be invoked from a RAM. The
form of the wrapper function depends on the environment in which the existing service runs. Because
the services (APIs, application programming interfaces) provided by SRCVW are REXX execs, the
REXX interpreter must be invoked to perform the service.
The wrapper function described here (execREXXProcedure()) is written as a C function that is
passed the name of the REXX exec to be called. This name is passed to IRXEXEC() (the REXX
interpreter) that invokes the named exec and returns the processing result as function return value.
This wrapper function can be invoked as a C function.
Sample wrapper function
execREXXProcedure(): execute specified REXX procedure
#include
#include
#include
#include
#include
<stdlib.h>
<string.h>
<stdio.h>
<stdarg.h>
"REXX.h" /* REXX control block definitions */
#pragma linkage (OSFUNC,OS)
typedef int OSFUNC();
#define LBUF 1024
/* maximum length of the result buffer */
#define NARG 20
/* maximum number of arguments */
#define SUBROUTINE 0x20000000 /* invoke procedure as subroutine */
EXECBLOCK execblk = {"IRXEXECB",48, 0, "
*pexecblk = &execblk;
","SYSPROC ","
",NULL,0},
EVALBLOCK evalblk = { 0, LBUF/8, 0, 0 }, *pevalblk = &evalblk;
ARGLIST arglist_entry[NARG+1], *parglist = arglist_entry;
/* function prototypes */
#define MIN(x,y) (x < y) ? x : y
char *execREXXProcedure(char *procname, int narg, ... ) {
va_list argptr;
OSFUNC *fptr;
int rc;
int p0 = 0;
static char result[LBUF+1];
int n;
/* execution code */
fptr = (OSFUNC *)fetch("IRXEXEC ");
if (fptr == NULL) {
puts("IRXEXEC fetch error");
return "";
}
memset(execblk.exec_member,' ',8);
n = MIN(strlen(procname),8);
memcpy(execblk.exec_member,procname,n);
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
34
va_start(argptr, narg); /* get first argument */
for (n=0; n < narg; n++) {
char *pc;
pc = va_arg(argptr, char *);
arglist_entry[n].argstring_ptr = pc;
arglist_entry[n].argstring_length = strlen(pc);
}
va_end(argptr);
arglist_entry[n+1].argstring_ptr = (void*)-1;
arglist_entry[n+1].argstring_length = -1;
rc = (*fptr)(&pexecblk,&parglist,SUBROUTINE,p0,p0,&pevalblk,p0,p0);
if (rc != 0) {
printf("IRXEXEC RC:%d\n",rc);
return "";
}
/* make returned result C-processable */
memcpy(result,evalblk.evalblock_evdata,evalblk.evalblock_evlen);
result[evalblk.evalblock_evlen] = '\0';
return result;
}
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
35
Sample legacy exec
/* REXX SESVCRES – SRCVW RESET ACTION */
PARSE ARG pj, pv, pgm, pgmv
/* Trap function display output */
CALL OUTTRAP 'msg.','*','NOCONCAT'
"SRCVW RESET -P" pj "-PV" pv "-PGM" pgm "-PGMV" pgmv
msg = '' /* Clear result string */
DO j = 1 TO msg.0
msg = msg !! msg.j
END
RETURN msg
Associated call:
presult = execREXXProcedure("SESVCRES",4,pj,pv,pgm,pgmv);
The wrapper for the legacy function essentially involves invoking the SCM function (here, SRCVW
RESET) with the appropriate arguments and returning the SCM function output as result string.
Because the SCM function is written as a dialog function, its display output must be trapped and
returned in an appropriate form.
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
36
Debugging
The supplied sample RAM (CRARAMSA) provides the log_wrapper() logging function that writes the
specified data to the host log.
For WDz 6, a separate log file is created with the name: dataset name: <userid>.CRAdhhmm. The log
contains information from both CARMA and the RAM.
For RDz 7, the CARMA log is written to the print file DD:CARMALOG; the RAM log is written to the
print file DD:SYSnnnnn (nnnnn is a running number).
Sample log:
T02161A.CRA00847:
Initializing CARMA at Tue May0 9 08:47:40 2006
-----------------------------------------------v2.0
CARMA: Loading the RAM List
CARMA: Retrieving CAF actions from CRADEF
CARMA: Finished retrieving CAF actions from CRADEF
CARMA: Retrieving CAF disabled actions from CRADEF
CARMA: Finished retrieving CAF disabled actions from CRADEF
…
CARMA: Entering initRAM. Attempting to initialize 2.
CARMA: Entering function: Initialize RAM
CARMA: Opening the VSAM Cluster
CARMA: Looking for module RUDDRAM
CARMA: Attempting to run RAM function: Initialize RAM
SRCVWRAM: Entering initRAM
SRCVWRAM: Received trace level: 3
SRCVWRAM: Received log ptr: 1C2E2794
SRCVWRAM: Received log function ptr: 1C2DA4F8
CARMA: Returned from RAM function: Initialize RAM
CARMA: Exiting function: Initialize RAM
CARMA: Entering function: Get Instances
CARMA: Attempting to run RAM function: Get Instances
SRCVWRAM: Entering getInstances
SRCVWRAM: Gathering instances
SRCVWRAM: Allocating memory for instance array
SRCVWRAM: Adding instances to records array
SRCVWRAM: Returning instance array
CARMA: Returned from RAM function: Get Instances
CARMA: Exiting function: Get Instances
…
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
37
The required level of tracing can be set online from the Connection properties (context):
0 = Error
1 = Warning
2 = Information
3 = Debug
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
38
The higher the level, the more information that will be logged.
The supplied sample RAM (CRARAMSA) provides the log_wrapper() logging function that can be
used to write the specified data to the host log. The function is called with the level to be logged (as
above, -1 = no logging, 0 = error) and the data in printf format.
For example
log_wrapper(0, "Entering getInstances");
log_wrapper(2, "Gathering instances");
log_wrapper(3, "Received instance ID: %.128s", instanceID);
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
39
Errors
RDz also maintains a log file (…<workspace>/.metadata/.log).
This contains debugging information than may be useful for IBM for diagnostic purposes.
Example
!ENTRY com.ibm.carma.client 4 380 Mai 10, 2006 10:13:58.814
!MESSAGE Could not execute Get Container Contents: [380] Error from CARMA Host:
380: Response Processing Error (CARMA Content List)[line 1]: Expected 2 attributes and recieved 1 attributes.
!STACK 0
com.ibm.carma.CARMAException: [380] Error from CARMA Host:
380: Response Processing Error (CARMA Content List)[line 1]: Expected 2 attributes and recieved 1 attributes.
at com.ibm.carma.client.subsystem.CARMASubSystem.processErrorMessage(Unknown Source)
at com.ibm.carma.client.subsystem.CARMASubSystem.processErrorStatus(Unknown Source)
at com.ibm.carma.client.subsystem.CARMASubSystem.executeCommand(Unknown Source)
at com.ibm.carma.client.transport.datastore.DataStoreCommandExecutor.executeCommand(Unknown Source)
at com.ibm.carma.client.transport.datastore.DataStoreCommandExecutor.executeCommand(Unknown Source)
at com.ibm.carma.client.transport.datastore.DatastoreRepositoryTransport.findContainerContents(Unknown Source)
at com.ibm.carma.model.impl.ResourceContainerHelper.refresh(Unknown Source)
at com.ibm.carma.model.impl.CARMAContainerImpl.refresh(Unknown Source)
at com.ibm.carma.model.impl.ResourceContainerHelper.refresh(Unknown Source)
at com.ibm.carma.model.impl.ResourceContainerImpl.refresh(Unknown Source)
at com.ibm.carma.ui.job.RefreshJob.run(Unknown Source)
at org.eclipse.core.internal.jobs.Worker.run(Unknown Source)
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
40
Summary
A few personal suggestions for RAM development
1. Start simple.
2. Until you are sure of what you are doing, supply trace information (log function, displays).
3. Do not make any errors -> a RAM failure will close the connection to a CARMA
(the CRASUBMT job).
Current CARMA restrictions
1. A new member cannot be added to the SCM from CARMA. Although a check-in can be
implemented, there is no direct reference to the associated program entry; this means all
program-related data must be entered.
One work-around is to create a Menu Manager entry (this is described in a subsequent
paper).
2. A checked-out member exists only as a local file.
3. Limited integration with other RDz functionality, such as compile. For example, it is not
possible to compile directly a CARMA repository program. More correctly, it is not possible to
use existing properties.
4. When an extract for a "container" is performed, all members will be copied to the local
CARMA project. In our case, this can be very many members and so is not practicable.
12.08.2009
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
41
12.08.2009
November
14th
©DATEV eG; alle Rechte
vorbehalten
2008
Mainframe Neuheiten
CARMA Developer's Perspective ( © A. Rudd, Datev eG)
2
42
Download