How to order control m job using REXX? like Control m utility CTMAPI - mainframe

I have to order few jobs in control m from different scheduling tables. this is manual task so i want to automate it using rexx.
I found below in 'Order or Force under Batch, REXX or CLIST' section of 'CONTROL M USERGUIDE'
EXEC CTMAPI PARM=‘ORDER variable’
I could not find syntax to call CMTAPI using rexx.

ADDRESS 'LINKMVS' is the equivalent of // EXEC PGM=something,PARM='whatever' in REXX. I don't know what the variable is supposed to be, but since this is Control-M, I am going to assume job name. A very simple example:
say 'Enter name of job'
pull jobname
parmvar = 'ORDER' jobname
`ADDRESS 'LINKMVS' 'CTMAPI parmvar'
Please note that for LINKMVS, the variable name goes inside the string passed. The LINKMVS environment substitutes the variable automatically. For example, if I entered MYJOB to the prompt, LINKMVS will build a PARM string of `ORDER MYJOB'. This is the exact equivalent of
// EXEC PGM=CTMAPI,PARM='ORDER MYJOB'
This IBM® Knowledge Center page for the z/OS 2.3 TSO/E REXX Reference manual shows several examples of calling a program in the same manner as // EXEC PGM=,PARM= (item 1). Items 5 through 9 show different ways of using ADDRESS 'LINKMVS'; note how variables are treated in each example.

After suggestions from NicC, zarchasmpgmr and few research, finally i am able to order job with CTMJOB utility. I searched for the loadlib and called TSO using REXX.
/*****REXX*******/
ADDRESS TSO
"CALL 'MY.IN.LOAD(CTMJOB)'
' ORDER DSN=MY.SCHED.LIB TABLE=SCHDTBL,
JOB=JOBNAME,DATE=DATE'"
EXIT
Details found in INCONTROL for ZOS utilities guide. This document was very useful.
http://documents.bmc.com/supportu/952/56/64/195664/195664.pdf

Related

How to run cucumber scenario's based on Test Case ID that is appended with the Scenario name?

I wanted to run Cucumber Feature file based on the Test case ID that scanerio name contains.
I know we can use #CucumberOptions 'features' tag and specify the line number to execute e.g "src/test/resources/Folder/myfile.feature:7:12"
This will run scenarios at line 7 and 12. But i wanted to run based on the TC ID.
Below is the feature file code
#Run
Feature: Login Functionality
Scenario: First Test Case(TC.No:1)
Given I perform action 1
Scenario: Second Test Case(TC.No:2)
Given I perform action 2
Scenario: Third Test Case(TC.No:3)
Given I perform action 3
Scenario: Fourth Test Case(TC.No:4)
Given I perform action 4
Scenario: Fifth Test Case(TC.No:5)
Given I perform action 5
All the scenario's are in a single feature.
For the feature file code above i wanted some way through which i can execute based on TC Id. E.g I only want to execute TC1,TC2 and TC5( TC id's picked up from scenario names).
There is a property file that contains the TC Id's to be executed. My code should read the file and then execute only those TC id's.
This can help me in reducing the number of automation TC's to be run.
Is it possible?
You can use the name property of #CucumberOptions or use the '-n' option if you are using the cli option. It also supports regular expressions.
To run TC.No:1 and TC.No:4 use something like this
#CucumberOptions(name = { "TC.No:1|TC.No:4" })
or
#CucumberOptions(name = { "TC.No:1","TC.No:4" })
You can get more details at this link.
As you are reading the ids from a file, the second option is the best. Use the cucumber.api.cli.Main class main() method to execute the features. You can create the options dynamically. Refer to this post.
CLI reference docs.
Not familiar with cucumber-jvm.
But, here is the general logic which should work (based on my ruby Cucumber knowledge)
In the hook, you can write the logic to under before method to get the scenario name scenario.name and then extract the TC.No. Compare the TC.No and skip if it's not part of your list.
Here is the link which will give information how to skip the scenario (use this class in the before method)
https://junit.org/junit4/javadoc/4.12/org/junit/AssumptionViolatedException.html
However, the best practice is to use the tags, it would have been easy if you had #TCId-xx tag. Still you can write a simple program that will scan all the feature files and update the scenarios with the tag based on the TC.No in the scenario name.

JCL : IF Statement with SET Statement

I have set FLAG as 1 and I am execpting ARG value should be DEV only. But am getting as ARG= DEV + CLIENTID
000023 // FLAG=1
000026 // IF (&FLAG=1) THEN
000027 //SET1 SET ARG=DEV
000028 // ELSE
000029 //SET2 SET ARG=DEV+&CLIENT
000030 // ENDIF
It mean JCL assign the value in RUNTIME (before checking the IF Condition).
Please help me to understand.
Thanks!
Bharathi
What #hogstrom said is correct. The JCL IF statement tests Step Return codes and not Variable values:
//IFBAD IF (ABEND | STEP1.RC > 8) THEN
Following on from what he said you can use a variable in an include statement
Include With variable
// INCLUDE MEMBER=OPT&FLAG
and setup members in the proclib
MEMBER=OPT1
// SET ARG=DEV
MEMBER=OPT2
// SET ARG=DEV+&CLIENT
You have to setup an include for every possible value of &FLAG and it is very long winded for one SET. It is more commonly used when you can set lots of variables like:
// INCLUDE MEMBER=ENV&ENV
where &ENV=PROD \ TEST etc
Your case
Do not use flag, just set the variable:
// SET ARG=DEV
or
// SET ARG=DEV+&CLIENT
There is some good information in the JCL Manual to understand the purpose of the IF/THEN/ELSE purpose.
Here are a few bullets from the manual:
The IF/THEN/ELSE/ENDIF statement construct does not conditionally control the processing of JCL; rather, it conditionally controls the
execution of job steps.
The result of processing an IF/THEN/ELSE/ENDIF statement construct, once determined, remains unchanged regardless of the outcome from
running any remaining steps in a job. The system does not reexamine
the original condition at any later job step termination, either
normal or abnormal. See Example 9.
The system allocates all DD statements defined to a step if the execution time evaluation of the relational-expression determines
that a step is to be executed. All data sets defined on DD statements
in the job must be available at the time the job is selected for
execution.
You can nest IF/THEN/ELSE/ENDIF statement constructs up to a maximum of 15 levels. You can specify symbolic parameters on
IF/THEN/ELSE/ENDIF statements provided that they resolve to one of the
supported relational-expression keywords. Any other symbolic
parameters, even if accepted by the system, are not intended or
supported.
What your doing seems logical, but, its not the intended purpose of JCL SET and conditional logic.
In your case, the last SET executed is what is used and why your seeing the DEV + CLIENTID

Parameterized job using Uno-choice plugin

I'm using Uno choice plugin to select parameter values based on previous selections.
(This plugin helped me to reduce parameter count. I can reuse same parameter for multiple platform based on the platform selection)
I used the groovy script to select parameter values.
But it takes too much time to load parameters.
Is there any way to speed up this process?
I had faced similar issues and I was also using groovy scripts to cal shell scripts.I did the following things to reduce time:-
When you click on build with Parameters all task(scripts run at once together) are performed at once.
Use else conditions properly.
Also use Fallback script.
For eg:-
you have parameters such as
1) country
2) state
3) city
each parameter depends on the previous values.
1) Try to only display contents on Jenkins front-end.(cat command).
2) Call a script if only it matches valid values in the previous parameter.
3) minimum on the fly scripts.
4) optimize delays/sleep according to your load time.
5) Remove any extensions whether in chrome/Firefox.
5) Try using the same page in incognito mode.
6) If options are invalid through invalid option without going into any computation.
7) Uninstall plugin which are not required.
Will add more suggestions as I find.
I would request you also to please update if you find any method to optimize time.

Find out ID of 'at' job from within it

When I schedule a job with 'at' it is assigned an id, viz:
job 44 at 2014-01-28 17:30
When that job runs I would like to get at that id from within it. This is on Centos, FWIW. I have established that no environment variable contains the ID. When the Perl code in that job runs I would like it to be able to print the job ID (44 in this example).
Yes, I know that atq shows an = next to jobs that are executing, but there might be more than one of those at a time.
I could do something like pass a unique argument to the job when scheduling it, capture the ID, save that and the argument to a file somewhere, read that from the job. That's a lot of work I'd rather not go to if I don't have to, and it seems like this should be simple but I'm drawing a blank.
What follows is figured out by reading sources of at-3.14. The way at puts job id and the time when it is run into the file name should be similar for any version, but I haven't checked this.
To begin whith at encodes the job id and the time when a particular job should be run into the file name describing a job. The file name has format aJJJJJTTTTTTTT, where JJJJJ is 5 character hexadecimal string, the job id, and TTTTTTTT is an 8 character hexadecimal string, the time when the job should be run. The time is stored as seconds from the epoch.
At jobs are run by feeding a job description file as the standard input to sh -c. Fortunately the Linux kernel provides a symbolic link, /proc/self/fd/0, which will point to the standard input of the process currently being executed (play with ls -l /proc/self/fd/0 in case you need to assure yourself that this indeed is so).
A file describing a job has been deleted by the time a job is run. However, the file is still available for the kernel because it has been duplicated with dup(2) before being used as the standard input for a job. So, actually we are resolving a symbolic link to a file name which is not visible any more. In the perl script at the end we need to take this into account as readlink will return something like /foo/bar/baz (deleted) instead of /foo/bar/baz. And we're interested in just the file name which has all the information we need.
The reason why the symbolic link points to a deleted file is because at daemon unlinks the original before executing the job. Unlinking gets done only after creating a copy, a hard link, which begins with = instead of a. With this the at daemon tries to ensure there will be only one copy of a job running: the daemon will not execle(2), ie. it will bail out, should the link(2) fail. Because the original file has been subject to open(2) and dup(2) the inode is still there for the kernel to use because it still has hard links pointing to it.
After a fairly long and possibly confusing introduction, here is how to put it all together:
#!/usr/bin/perl
use strict;
use warnings;
my $job_file = readlink("/proc/self/fd/0");
if (index($job_file, " ") > 0) {
$job_file = substr($job_file, 0, index($job_file, " ") - 1);
}
my $tmp = substr($job_file, rindex($job_file, "/") + 1);
$tmp =~ s/^a([0-9a-f]{5})[0-9a-f]+/$1/;
my $job_id = hex($tmp);
if ($job_id > 0) {
printf("My AT job id is %d.\n", $job_id);
}
# end of file.

How to list out a GDG base properties through REXX

How to know GDG base properties through REXX code; Of course we can view the GDG limit thru File-aid 3.2 option But need to list the properties on the fly and may be used in consecutive program/module. Hope made you clear and waiting for response!
(Do let me know if any other information is required?)
From REXX, you can target TSO then use the listcat command:
ADDRESS TSO
"LISTCAT ENTRY('XXX') ALL"
where XXX is the GDG base.
For capturing TSO output, look into OUTTRAP which can capture the output from most TSO commands - I haven't specifically tested listcat since I don't have a z900 under my desk at home :-) I'll give it a shot at work tomorrow.
Call OutTrap "xyzzy."
should give you the output into the xyzzy stem variable and you can stop the capture with:
Call OutTrap "off"
Something like this should do it.
/* REXX */
arg entry .
call outtrap "listc."
"LISTCAT ENT("entry") GDG ALL"
if rc > 0 then exit 12
do i = 1 to listc.0
if pos("LIMIT", listc.i) > 0 then do
limit = word(translate(listc.i,' ','-'),2)
say 'GDG limit is' limit
leave
end
end
One caveate to the above suggestion... If you only want GDG entries you may need to consider removing the keyword ALL on the LISTCAT ENTRY('XXX') ALL line. I believe the ALL word will list GDG & Non-GDG datasets that happen to match the catalog entry name.

Resources