您可能知道可以使用文件传输协议(FTP)来传输文件,但是z / OS FTP服务器有所不同。 该服务器不仅可以提供对z / OSUNIX®System Services文件的标准访问,而且还可以提供以下服务:
您可以从任何FTP会话访问这些类型的信息。 借助Java FTP客户端,您可以充分利用信息。 自然地,本文利用对JES假脱机的访问。
FTP服务器提供对许多JES功能的访问,其中包括:
本文将更详细地介绍第二和第三功能:显示作业状态和接收假脱机输出。
在开始之前,请确保以下内容:
此外,您可以使用多个配置参数中的任何一个来控制JES接口的行为,包括最重要的配置参数JESINTERFACELEVEL
。 表1总结了配置参数。
参数 | 描述 |
---|---|
JESINTERFACELEVEL | 指定JES界面提供的功能级别。 为最大功能设置为2。 |
JESENTRYLIMIT | 限制将返回多少作业。 默认值为200。 |
杰索纳 | 将检索到的作业限制为与此所有者有关的作业。 如果为空,则默认为当前用户。 |
杰索比名字 | 将检索到的作业限制为具有此作业名称的作业。 如果为空,则默认为当前用户并带有* 。 使用*检索所有作业。 |
耶斯达斯 | 将检索到的作业限制为具有此状态的作业。 如果为空,则默认为所有状态。 有效状态为OUTPUT,ACTIVE和INPUT。 |
您可以使用STAT
命令来验证FTP服务器的设置。 清单1显示了一个示例。
ftp> quote stat
211-Server FTP talking to host 192.168.152.1, port 1858
211-User: ISIELW Working directory: ISIELW.
211-The control connection has transferred 117 bytes
211-There is no current data connection.
211-The next data connection will be actively opened
211-to host 192.168.152.1, port 1858,
211-using Mode Stream, Structure File, type ASCII, byte-size 8
211-Automatic recall of migrated data sets.
211-Automatic mount of direct access volumes.
211-Auto tape mount is allowed.
211-Inactivity timer is set to 300
211-Timer FTPKEEPALIVE is set to 0
211-VCOUNT is 59
211-ASA control characters in ASA files opened for text processing
211-will be transferred as ASA control characters.
211-Trailing blanks are removed from a fixed format
211-data set when it is retrieved.
211-Data set mode. (Do not treat each qualifier as a directory.)
211-ISPFSTATS is set to FALSE
211-Primary allocation 1 track. Secondary allocation 1 track.
211-Partitioned data sets will be created with 27 directory blocks.
211-FileType SEQ (Sequential - default).
211-Number of access method buffers is 5
211-RDWs from variable format data sets are discarded.
211-Records on input tape are unspecified format
211-SITE DB2 subsystem name is DB2
211-Data not wrapped into next record.
211-Tape write is not allowed to use BSAM I/O
211-Truncated records will not be treated as an error
...
211-JESLRECL is 80
211-JESRECFM is Fixed
211-JESINTERFACELEVEL is 2
211-Encoding is set to SBCS
211-Port of Entry resource class for IPv4 clients is: TERMINAL
211-Record format VB, Lrecl: 256, Blocksize: 6233
211 *** end of status ***
ftp>
完成配置后,启动与服务器的普通FTP会话。 建立会话后,请使用SITE FILETYPE
子命令指示您要获取JES信息,而不是普通的HFS文件。
清单2显示了Windows®客户端的交互式FTP会话。
C:\>ftp 192.168.152.2
Connected to 192.168.152.2.
220-FTPD1 IBM FTP CS V1R5 at p390.qld.isi.com.au, 04:26:27 on 2006-09-06.
220 Connection will close if idle for more than 5 minutes.
User (192.168.152.2:(none)): isielw
331 Send password please.
Password:
230 ISIELW is logged on. Working directory is "ISIELW.".
ftp> quote SITE FILETYPE=JES
200 SITE command was accepted
ftp>
将文件类型更改为JES后,一些FTP命令的操作方式有所不同,如表2中所述。
命令 | 描述 |
---|---|
目录 | 列出SYSOUT队列上的作业 |
得到 | 返回一个或多个SYSOUT文件 |
放 | 向JES提交工作 |
删除 | 删除SYSOUT文件 |
下面描述了其中两个命令的操作。
SYSOUT队列上的JES作业被视为单级目录。 dir
命令以两种方式之一起作用:
dir
命令返回与JESJOBNAME
参数的当前设置匹配的所有作业的列表。 Jobid
参数的dir
命令返回组成该作业的所有SYSOUT文件的列表。 清单3显示了使用dir
命令的示例。
ftp> dir
200 Port request OK.
125 List started OK for JESJOBNAME=ISIELW*, JESSTATUS=ALL and JESOWNER=ISIELW
JOBNAME JOBID OWNER STATUS CLASS
ISIELW TSU00629 ISIELW OUTPUT TSU ABEND=522 3 spool files
ISIELW TSU00609 ISIELW OUTPUT TSU ABEND=522 3 spool files
ISIELW TSU00294 ISIELW OUTPUT TSU ABEND=522 3 spool files
ISIELW TSU00250 ISIELW OUTPUT TSU ABEND=522 3 spool files
ISIELW TSU00218 ISIELW OUTPUT TSU ABEND=522 3 spool files
ISIELW TSU00199 ISIELW OUTPUT TSU ABEND=622 3 spool files
ISIELW TSU00171 ISIELW OUTPUT TSU ABEND=522 3 spool files
250 List completed successfully.
ftp: 524 bytes received in 0.06Seconds 8.45Kbytes/sec.
ftp> dir TSU00629
200 Port request OK.
125 List started OK for JESJOBNAME=ISIELW*, JESSTATUS=ALL and JESOWNER=ISIELW
JOBNAME JOBID OWNER STATUS CLASS
ISIELW TSU00629 ISIELW OUTPUT TSU ABEND=522
--------
ID STEPNAME PROCSTEP C DDNAME BYTE-COUNT
001 JES2 K JESMSGLG 962
002 JES2 K JESJCL 13983
003 JES2 K JESYSMSG 17176
3 spool files
250 List completed successfully.
ftp: 340 bytes received in 0.03Seconds 10.63Kbytes/sec.
ftp>
请注意以下有关此示例的内容:
get
命令从SYSOUT队列中检索指定的JES作业的内容。 该命令以两种方式之一起作用:
!! END OF JES SPOOL FILE !!
连接在一起!! END OF JES SPOOL FILE !!
!! END OF JES SPOOL FILE !!
。 清单4显示了使用get
命令的示例。
ftp> get TSU00629.x
200 Port request OK.
125 Sending all spool files for requested Jobid
250 Transfer completed successfully.
ftp: 37422 bytes received in 1.19Seconds 31.53Kbytes/sec.
ftp> get TSU00629.1
200 Port request OK.
125 Sending data set ISIELW.ISIELW.TSU00629.D0000002.JESMSGLG
250 Transfer completed successfully.
ftp: 1402 bytes received in 0.16Seconds 8.93Kbytes/sec.
ftp>
本文中的示例是使用Eclipse环境开发并运行的。 请按照以下步骤使用示例源代码:
到目前为止,我已经给出了通过FTP命令行访问JES假脱机文件的示例。 这对于简单的工作而言是很好的选择,但是您可以利用Java等编程方式来利用FTP访问JES的功能。
您可以在两个级别上使用Java来通过FTP访问JES:
下面将更详细地描述这两个级别。
使用Commons Net库很容易,它提供了一种访问包括FTP在内的多种通信协议的方法。 使用库进行FTP访问时,请使用主类FTPClient
。 请参阅Javadoc,以获取有关该类的有用的入门说明。
清单5提供了一个示例来说明该库的易用性。
package evan.org;
import org.apache.commons.net.ftp.*;
import java.io.IOException;
/**
* This class provides a simple example of how to access
* JES files using an FTP server from Java code.
* The user ID and password must be valid for the server
* accessed.
*/
public class FtpExampleOne {
public FtpExampleOne() {
}
public static void main(String[] args) {
FTPClient ftp = null;
String sUserid = "ISIELW";
String sPassword = "PASSWD";
String sHost = "192.168.152.2";
String sJobPrefix = "ISIELW*";
String replyText;
ftp = new FTPClient();
FTPFile[] result = null;
try {
// Connect to the server
ftp.connect(sHost);
replyText = ftp.getReplyString();
System.out.println(replyText);
// Log into the server
ftp.login(sUserid, sPassword);
replyText = ftp.getReplyString();
System.out.println(replyText);
// Tell the server to use the JES interface
ftp.site("filetype=jes");
replyText = ftp.getReplyString();
System.out.println(replyText);
// Get a list of jobs
String[] names = ftp.listNames("*");
for (int i = 0; i < names.length; i++) {
System.out.println("file " + i + " is " + names[i]);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
ftp.quit();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
清单6显示了清单5所示程序的输出。
220-FTPD1 IBM FTP CS V1R5 at p390.qld.isi.com.au, 00:29:00 on 2006-09-07.
220 Connection will close if idle for more than 5 minutes.
230 ISIELW is logged on. Working directory is "ISIELW.".
200 SITE command was accepted
file 0 is TSU00629
file 1 is TSU00609
file 2 is TSU00294
file 3 is TSU00250
file 4 is TSU00218
file 5 is TSU00199
file 6 is TSU00171
清单7中的示例代码片段显示了如何检索SYSOUT文件的内容。
// Retrieve part of a JES job
String sRemoteFilename = "TSU00629.2";
InputStream is = ftp.retrieveFileStream(sRemoteFilename);
BufferedReader br = new BufferedReader(new InputStreamReader((is)));
boolean bContinue = true;
while (bContinue) {
String sLine = br.readLine();
if (sLine != null) {
System.out.println("line ... " + sLine);
} else {
bContinue = false;
is.close();
br.close();
}
}
ftp.completePendingCommand();
清单8显示了使用清单7代码的程序的输出。
220-FTPD1 IBM FTP CS V1R5 at p390.qld.isi.com.au, 00:40:52 on 2006-09-07.
220 Connection will close if idle for more than 5 minutes.
230 ISIELW is logged on. Working directory is "ISIELW.".
200 SITE command was accepted
1 //ISIELW JOB 'ACCT#',REGION=8192K TSU00629
2 //ISPFPROC EXEC ISPFPROC
XX******************************************************************** 00010000
XX* 00020000
XX* ISPF FULL-FUNCTION LOGON PROC 00030000
XX* 00040000
XX********************************************************************* 00050000
3 XXISPFPROC EXEC PGM=IKJEFT01,REGION=0M,DYNAMNBR=175, 00060000
XX PARM='%ISPFCL' 00070000
XX*TEPLIB DD DISP=SHR,DSN=ISIMPO.VSS611.VANLOAD 00080000
上面的示例提供了一种获取JES输出的简单方法。 但是,如何获得对访问和检索内容的更细粒度的控制? FTPClient
的Javadoc描述了listFiles
方法。 此方法提供了一定程度的文件概念封装,因为它返回了FTPFile
对象数组,而不是简单的String
对象。 清单9显示了listFiles
方法的用法。
FTPFile[] result = ftp.listFiles("*");
for (int i=0; i < result.length; i++) {
System.out.println("file " + i + " is " + result[i].getName());
}
如清单10中的输出所示,结果是不可接受的。 检索到的文件名与FTP服务器要报告的文件名不匹配。 看起来,即使Commons Net库可以自动检测主机类型,它也不会扩展到z / OS FTP扩展。
220-FTPD1 IBM FTP CS V1R5 at p390.qld.isi.com.au, 02:03:36 on 2006-09-07.
220 Connection will close if idle for more than 5 minutes.
230 ISIELW is logged on. Working directory is "ISIELW.".
200 SITE command was accepted
file 0 is CLASS
file 1 is files
file 2 is files
file 3 is files
file 4 is files
file 5 is files
file 6 is files
file 7 is files
file 8 is TSU
好消息是您可以使用Commons Net库将FTPClient
配置为解析不同类型的文件列表。 您需要做的就是生成一个解析器,该解析器可以理解dir
命令的输出并创建FTPFile
类的实例。 但是首先,通过扩展FTPFile
类可以获得最大的灵活性。 这使您可以存储可用于描述JES文件的特殊属性。 清单11展示了此类的概述。
package evan.org;
import org.apache.commons.net.ftp.FTPFile;
/**
* The JesJob class extends the FTPFile class. This
* allows for JES
specific information to
* be maintained, in addition to the standard FTPFile
* information.
* This allows information for the spool files such as:
*
* - job name
* - job id
* - job owner
* - job status
* - job class
* - job return code
*
*/public class JesJob extends FTPFile {
private static final long serialVersionUID = 1L;
private String sJobName;
private String sOwner;
private String sStatus;
private String sJobClass;
private String sReturnCode;
private String sNumFiles;
public JesJob() {
super();
sJobName = "";
sOwner = "";
sStatus = "";
sJobClass = "";
sReturnCode = "";
sNumFiles = "";
}
public String getJobName() {
return sJobName;
}
public void setJobName(String jobname) {
sJobName = jobname;
}
...
}
可以配置FTPClient
通过提供的实例,以使用特定的解析器FTPClientConfig
类,如清单12中该目的通过一个类,它实现的名称创建FTPFileEntryParse
接口。
ftp = new FTPClient();
FTPClientConfig conf = new FTPClientConfig("evan.org.SimpleJesFileParser");
ftp.configure(conf);
清单13显示了evan.org.SimpleJesFileParser
的基本实现。
package evan.org;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPFileEntryParser;
public class SimpleJesFileParser implements FTPFileEntryParser {
/** Parses a single line of text, and returns an FTPFile.
* Typically, the text would be something like this:
*
* ISIELW TSU00807 ISIELW OUTPUT TSU ABEND=522 3 spool files
* jobname jobid owner status type result
*
*
* @see org.apache.commons.net.ftp.FTPFileEntryParser#parseFTPEntry(java.lang.String)
*/
public FTPFile parseFTPEntry(String arg0) {
JesJob f = new JesJob();
String sOwner = "";
String sStatus = "";
String sType = "";
String sReturnCode = "";
// Use regular expressions to break into words ...
// remembering that:
// - the first backslash is the Java String escape mechanism
// so that \\S is really just \S in regexp terms.
// - \S means any non-whitespace character
// - \S+ means a bunch of them
// - (\S+) means a bunch of them - as a group
// - \s+ means some whitespace
Pattern p = Pattern.compile("(\\S+)\\s+(\\S+)\\s+(.*)");
Matcher matcher = p.matcher(arg0);
if (matcher.find()) {
String sJobname = matcher.group(1);
String sJobid = matcher.group(2);
String sRemainder = matcher.group(3);
if (!sRemainder.equals("")) {
Pattern p2 = Pattern
.compile("(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(.*)");
Matcher matcher2 = p2.matcher(sRemainder);
if (matcher2.find()) {
sOwner = matcher2.group(1);
sStatus = matcher2.group(2);
sType = matcher2.group(3);
String remainder = matcher2.group(4);
if (remainder.startsWith("RC=")) {
sReturnCode = remainder.substring(3, 8);
}
if (remainder.startsWith("ABEND=")) {
sReturnCode = "S" + remainder.substring(6, 10);
}
if (remainder.startsWith("(JCL error)")) {
sReturnCode = "JCL error";
}
}
}
f.setName(sJobid);
f.setJobName(sJobname);
f.setOwner(sOwner);
f.setStatus(sStatus);
f.setJobClass(sType);
f.setReturnCode(sReturnCode);
f.setType(FTPFile.DIRECTORY_TYPE);
}
return f;
}
/** Filter a list that contains the strings from a list of
* file entries.
* This is an opportunity to remove any superfluous lines;
* that is, strings that do not describe a real file. A common
* example is headings.
*
* @see org.apache.commons.net.ftp.FTPFileEntryParser#preParse(java.util.List)
*/
public List preParse(List arg0) {
Iterator it = arg0.iterator();
while (it.hasNext()) {
Object o = it.next();
if (o instanceof String) {
String s = (String) o;
String sSub = s.substring(9, 14);
if (sSub.equals("JOBID")) {
it.remove();
}
}
}
return arg0;
}
public String readNextEntry(BufferedReader arg0) throws IOException {
String s = arg0.readLine();
return s;
}
}
请注意以下有关图13所示的代码:
FTPFile
实例。 在这种情况下,实际上您将返回JesJob
的实例,因为您想提供额外的JES信息。 preParse
方法从目录列表中过滤掉多余的信息行。 在该示例中,航向线被检测到并被移除。 最后,您可以调用listFiles
方法,如清单14所示。请注意,返回的结果JesJob
转换为JesJob
类型。
ftp = new FTPClient();
FTPClientConfig conf = new FTPClientConfig("evan.org.SimpleJesFileParser");
ftp.configure(conf);
try {
String replyText;
// Connect to the server
ftp.connect(sHost);
replyText = ftp.getReplyString();
System.out.println(replyText);
// Login to the server
ftp.login(sUserid, sPassword);
replyText = ftp.getReplyString();
System.out.println(replyText);
// Tell server that the file will have JCL records
ftp.site("filetype=jes");
replyText = ftp.getReplyString();
System.out.println(replyText);
ftp.site("jesowner=*");
ftp.site("jesjobname=" + sJobPrefix);
FTPFile[] result = ftp.listFiles("*");
for (int i = 0; i < result.length; i++) {
JesJob job = (JesJob) result[i];
System.out.println("file " + i
+ " is " + job.getName()
+ " jobname is " + job.getJobName()
+ " class is " + job.getJobClass()
+ " status is " + job.getStatus()
+ " rc is " + job.getReturnCode());
}
} catch (Exception e) {
e.printStackTrace();
}
清单15显示了清单14代码片段的示例输出。
220-FTPD1 IBM FTP CS V1R5 at p390.qld.isi.com.au, 04:30:52 on 2006-09-07.
220 Connection will close if idle for more than 5 minutes.
230 ISIELW is logged on. Working directory is "ISIELW.".
200 SITE command was accepted
file 0 is TSU00629 jobname is ISIELW class is TSU status is OUTPUT rc is S522
file 1 is TSU00609 jobname is ISIELW class is TSU status is OUTPUT rc is S522
file 2 is TSU00294 jobname is ISIELW class is TSU status is OUTPUT rc is S522
file 3 is TSU00250 jobname is ISIELW class is TSU status is OUTPUT rc is S522
file 4 is TSU00218 jobname is ISIELW class is TSU status is OUTPUT rc is S522
file 5 is TSU00199 jobname is ISIELW class is TSU status is OUTPUT rc is S522
file 6 is TSU00171 jobname is ISIELW class is TSU status is OUTPUT rc is S522
file 7 is TSU00656 jobname is ISIELW class is TSU status is ACTIVE rc is
本文向您展示了如何使用Java访问z / OS JES Sysout文件。 另外,扩展Commons Net Library允许将特定的JES文件属性封装在Java对象中。
翻译自: https://www.ibm.com/developerworks/systems/library/es-zosbatchjavav/index.html