View previous topic :: View next topic |
Author |
Message |
BoomerangThree Beginner
Joined: 29 Mar 2005 Posts: 5 Topics: 1
|
Posted: Tue Mar 29, 2005 9:16 am Post subject: Accessing IMS from External Program such as Java |
|
|
I have a couple questions concerning IMS, IMS Connect, and Java Connector for IMS. Any assistance will be greatly appricated.
1) If I understand correctly, IMS Connect is a piece of software middleware that allows various clients to access IMS?
2) Are there situations where COBOL programs sit behind IMS Connect and interact with IMS on behalf of a client?
3) Also if I understand correctly, you can write a program, Java program for example that interacts directly with IMS via IMS Connect on the server side and IMS Connector for Java on the client side or interacts with a COBOL program that acts as a proxy for the Java program and does the interaction to IMS and returns the results to the Java program.
Thanks for taking time to reply. |
|
Back to top |
|
|
kolusu Site Admin
Joined: 26 Nov 2002 Posts: 12372 Topics: 75 Location: San Jose
|
|
Back to top |
|
|
BoomerangThree Beginner
Joined: 29 Mar 2005 Posts: 5 Topics: 1
|
Posted: Tue Mar 29, 2005 10:08 am Post subject: |
|
|
Thank you.
One question about real world implementations.
So, from reading the Guide you can access IMS "directly" from a Java program via SQL and JDBC. This is great.
The question is: Is it common to front-end IMS with COBOL programs that accept a message, carry out the functionality against IMS and return a result? It appears that there is nothing preventing this, just wondering if it's common place. _________________ BoomerangThree |
|
Back to top |
|
|
kolusu Site Admin
Joined: 26 Nov 2002 Posts: 12372 Topics: 75 Location: San Jose
|
Posted: Tue Mar 29, 2005 12:24 pm Post subject: |
|
|
BoomerangThree,
Quote: |
The question is: Is it common to front-end IMS with COBOL programs that accept a message, carry out the functionality against IMS and return a result? It appears that there is nothing preventing this, just wondering if it's common place.
|
Our shop does that. We use JSP using Java bean which connects to the mainframe via socket to invoke IMS transaction written in COBOL and pass the data back to the invoking object(JSP). _________________ Kolusu
www.linkedin.com/in/kolusu |
|
Back to top |
|
|
BoomerangThree Beginner
Joined: 29 Mar 2005 Posts: 5 Topics: 1
|
Posted: Tue Mar 29, 2005 1:14 pm Post subject: |
|
|
Most excellent. THANK YOU for the feedback.
1) Do you use IMS Connector for Java?
2) If you do use IMS Connector for Java is there any reasons that you can share as to why you use COBOL programs to interface to IMS rather than allowing IMS Connector for Java to go directly to IMS.
3) If you are not using IMS Connector, is there any other reason why not, other than, COBOL is present, easy enough to just leverage the COBOL programs, ect... _________________ BoomerangThree |
|
Back to top |
|
|
Sreejith Intermediate
Joined: 02 Dec 2002 Posts: 155 Topics: 25 Location: N.Ireland
|
Posted: Wed Mar 30, 2005 12:02 pm Post subject: |
|
|
The last time I looked at IMS Connect it was not able to do direct access to IMS database from JAVA running on non-mainframe platform. The way my shop uses IMS connect is by using a product called SeeBeyond which will talk to an existing mainframe IMS MPP transaction via IMS Connect.
We can also use the following Java Servelet supplied by IBM to talk to an IMS transaction on mainframe which can access IMS/DB2 database.
Code: |
import java.io.*;
import java.net.*;
import java.util.*;
public class Sample {
private Socket socket = null;
// connection information
private String hostName;
private int portNumber;
// IMS information
private String tranCode;
private String datastoreID;
private String ltermName;
// RACF security information
private String racfUserID;
private String racfGroupName;
private String password;
// IMS Connect information
private String clientID;
private String exitID = "*SAMPLE*";
private byte syncLevel;
private byte commitMode;
private int prefixLength = 80;
public Sample(String hostName, int portNumber, String datastoreID, String ltermName,
String tranCode, String clientID, String racfUserID, String racfGroupName,
String password, byte syncLevel, byte commitMode) {
// set the corresponding transaction data, making all strings 8 characters long
this.hostName = stringPad(hostName, ' ', 13);
this.portNumber = portNumber;
this.datastoreID = stringPad(datastoreID, ' ', 8);
this.ltermName = stringPad(ltermName, ' ', 8);
this.tranCode = stringPad(tranCode, ' ', 8);
this.clientID = stringPad(clientID, ' ', 8);
this.racfUserID = stringPad(racfUserID, ' ', 8);
this.racfGroupName = stringPad(racfGroupName, ' ', 8);
this.password = stringPad(password, ' ', 8);
this.syncLevel = syncLevel;
this.commitMode = commitMode;
}
/**
* Connects to the host.
*/
public void connect() {
try {
// open a socket for the transaction
socket = new Socket(hostName, portNumber);
} catch (Exception e) {
System.err.println(e);
System.exit(1);
}
}
/**
* Disconnects from the host.
*/
public void disconnect() {
// verify socket open before attempting to disconnect
if (socket != null) {
try {
socket.close();
socket = null;
} catch (Exception e) {
System.err.println(e);
System.exit(1);
}
}
}
/**
* Sends prefix and segment data.
*/
public void send(String segment, char nad) {
int totalLength;
// +4 for first LL, ZZ and final LL, ZZ
totalLength = 4 + prefixLength + 4;
// add in segment length, if segment is defined
if ((segment != null) && (segment.length() > 0)) {
totalLength += segment.length() + 12; // +12 for LL, ZZ, tranCode
}
try {
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
out.writeInt(totalLength); // send total message length
out.writeShort(prefixLength); // send LL
out.writeShort((short)0); // send ZZ
out.writeBytes(exitID); // send identifier
out.writeInt(0); // send extra full word 0
out.writeInt(0); // send RESV
out.writeBytes(clientID); // send client id
out.writeByte(0); // send FLG 1
out.write(commitMode); // send FLG 2 - commit mode
out.write(syncLevel); // send FLG 3 - synclevel
out.writeByte(nad); // send FLG 4 - ack/nack/decallocate
out.writeBytes(tranCode); // send transaction code
out.writeBytes(datastoreID); // send datastore id
out.writeBytes(ltermName); // send lterm name
out.writeBytes(racfUserID); // send RACF id
out.writeBytes(racfGroupName); // send RACF group
out.writeBytes(password); // send password
// the 'if' is not supposed to be executed when you ACK, NACK, DECALLOCATE, as data is irrelevant
if ((segment != null) && (segment.length() > 0)) {
// + 12 for LL and ZZ and trancode
short recordLength = (short)(segment.length() + 12);
out.writeShort(recordLength); // send LL
out.writeShort((short)0); // send ZZ
out.writeBytes(tranCode); // send transaction code
out.writeBytes(segment); // send segment
}
// send final LL ZZ to signal no more data to IMS Connect
out.writeShort((short)4); // send LL
out.writeShort((short)0); // send ZZ
} catch (Exception e) {
System.err.println(e);
System.exit(1);
}
}
/**
* Receives output segments.
*/
public Vector receive() {
// initialize segment vector
Vector segments = new Vector();
try {
DataInputStream in = new DataInputStream(socket.getInputStream());
// read total length
int totalLength = (int) in.readShort();
// read ZZ
in.readShort();
// read identifier (exitID)
byte[] identifierBytes = null;
if (totalLength < 12) {
identifierBytes = new byte[totalLength - 4];
} else {
identifierBytes = new byte[8];
}
in.readFully(identifierBytes);
String identifier = new String(identifierBytes);
// check first segment for possible errors / alerts
if (identifier.equals("*REQMOD*")) {
// read mod name
byte[] modBytes = new byte[8];
in.readFully(modBytes);
String modName = new String(modBytes);
// add mod name to segment vector
segments.add("MOD NAME: " + modName);
} else if (identifier.equals("*REQSTS*")) {
// read return code and reason code
int returnCode = in.readInt();
int reasonCode = in.readInt();
// add them to the segment vector
segments.add("RETURN CODE: " + returnCode);
segments.add("REASON CODE: " + reasonCode);
// return since there should be no more data
return segments;
} else {
if (totalLength <= 12)
segments.add(identifier);
else {
// read in the rest of the segment data
byte[] segmentBytes = new byte[totalLength - 12];
in.readFully(segmentBytes);
segments.add(identifier + new String(segmentBytes));
}
}
String segmentData = "";
// continue trying to read in data till we come across *CSMOKY*
while (! segmentData.equals("*CSMOKY*")) {
// read next segment
// read LL, ZZ
short recordLength = in.readShort();
in.readShort();
// read in segment data
byte[] segmentBytes = new byte[recordLength - 4];
in.readFully(segmentBytes);
segmentData = new String(segmentBytes);
// add it to the segment vector
segments.add(segmentData);
}
} catch (Exception e) {
System.err.println(e);
System.exit(1);
}
// return segment vector
return segments;
}
/**
* Pads or truncates the String to the specified length.
*/
private String stringPad(String string, char padChar, int padLength) {
// construct a stringbuffer for padding efficiency
StringBuffer stringBuffer = new StringBuffer(string);
// pad the stringbuffer if string.length() is less than padLength
for (int i = 0; i < (padLength - string.length()); i++) {
stringBuffer.append(padChar);
}
// if truncation was necessary, substring will take care of that
return stringBuffer.substring(0, padLength);
}
public static void main(String[] args) {
// set default values
String hostName = "10.31.227.153";
int portNumber = 3404;
String datastoreID = "IM7P";
String ltermName = "";
String tranCode = "PART";
String clientID = "TEAM04";
String racfUserID = "TEAM04";
String racfGroupName = "";
String password = "TEAM04"; // no passwrd
byte syncLevel = 0x00; // synclevel = none
byte commitMode = 0x20; // send-commit
// set input text
String segment = "AN960C10";
// create a new sample object
Sample sample = new Sample(hostName, portNumber, datastoreID, ltermName, tranCode, clientID,
racfUserID, racfGroupName, password, syncLevel, commitMode);
// connect to the host
System.err.println("Connecting to the host...");
sample.connect();
// send the segment data
System.err.println("Sending input data...");
sample.send(segment, ' ');
// get the response back
System.err.println("Receiving response...");
Vector segments = sample.receive();
// print out the response
for (int i = 0; i < segments.size(); i++) {
System.err.println("Segment " + i + ": " + segments.elementAt(i));
}
// disconnect from the host
System.err.println("Disconnecting from the host...");
sample.disconnect();
}
}
|
|
|
Back to top |
|
|
BoomerangThree Beginner
Joined: 29 Mar 2005 Posts: 5 Topics: 1
|
Posted: Wed Mar 30, 2005 12:41 pm Post subject: |
|
|
Sreejith,
Thanks for the response. I "believe" that I read and saw some example code that appeared to interact directly with IMS from a Java program, "via" IMS Connect. It also used IMS Connect for Java on the Java Client side.
Anyone else have any thoughts.
Thanks again for taking time... _________________ BoomerangThree |
|
Back to top |
|
|
Bithead Advanced
Joined: 03 Jan 2003 Posts: 550 Topics: 23 Location: Michigan, USA
|
Posted: Thu Mar 31, 2005 10:55 am Post subject: |
|
|
You may have been looking at JAVA on the mainframe. IMS Connect is simply a TCP/IP listener that passes messages to IMS via OTMA.
I have kept away from access to IMS by any other external means because of concerns about locking. |
|
Back to top |
|
|
BoomerangThree Beginner
Joined: 29 Mar 2005 Posts: 5 Topics: 1
|
Posted: Thu Mar 31, 2005 12:08 pm Post subject: |
|
|
Bithead,
Can I ask a couple more questions?
Can you confirm or modify the following:
1) A java servlet calls standard JCA methods that in turn communicate with the IMS Connector for Java "runtime" that is installed on a Websphere App Server?
2) The IMS Connector for Java "runtime" then communicates via TCP/IP to IMS Connect on the mainframe?
3) IMS Connect passes the command to IMS where it is processed and returns a result.
4) Reverse 3, 2, 1? _________________ BoomerangThree |
|
Back to top |
|
|
Bithead Advanced
Joined: 03 Jan 2003 Posts: 550 Topics: 23 Location: Michigan, USA
|
Posted: Mon Apr 04, 2005 11:49 am Post subject: |
|
|
Boomerang3,
Our shop does not use the IMS connector for JAVA but we do connect to IMS Connect from our JAVA applications (In Websphere). The connection is made via a TCP/IP socket using the port number defined in the IMS Connect configuration file.
IMS Connect then uses cross-system coupling to communicate with OTMA (Part of IMS) which then passes the message to the IMS control region.
You are correct in your thinking of how it works. |
|
Back to top |
|
|
MikeBaker Beginner
Joined: 04 May 2004 Posts: 96 Topics: 9
|
Posted: Sat Apr 09, 2005 8:40 am Post subject: |
|
|
Kolusu,
Why do you use a COBOL program on the backend? Is there some special design/performance reason for this? Why not have Java talking directly to IMS instead?
I would be interested to know. Thanks.
Mike. |
|
Back to top |
|
|
kolusu Site Admin
Joined: 26 Nov 2002 Posts: 12372 Topics: 75 Location: San Jose
|
Posted: Sun Apr 10, 2005 8:49 am Post subject: |
|
|
MikeBaker,
The JSP calls an IMS transaction which was existing from ages. They did not want to code the entire business logic once again Java. All the Programmers use the regular IMS DC screens , only the customers who are aginst green screens use the web. So if any changes are made , then you only need to change in one place.
Thanks
Kolusu _________________ Kolusu
www.linkedin.com/in/kolusu |
|
Back to top |
|
|
blueash Beginner
Joined: 02 Dec 2002 Posts: 16 Topics: 6
|
Posted: Tue Aug 23, 2005 11:39 pm Post subject: |
|
|
I have the following requirement (of which I have been able to finish some based on above discussion) - please correct if any of the following is wrong,
1. Call a IMS Transaction by Java in non-mainframe environment (I am using the Java Servlet provided by Bithead and would be passing the relevant information to the "segment" - a single record)
2. This record needs to be inserted in the existing IMS database.
3. The transaction id called by servlet would be defined in IMS connect configuration file as well as in the IMS online region.
4. This transaction would run a COBOL/IMS program having same name as the PSB name mapped to above transaction id. Also it would have the data mapping of "segment" passed thru Java described in the linkage section.
5. Would use "ISRT" to write the information received in linkage section to the IMS Database. Return the success/failure information to Java.
Thanks! |
|
Back to top |
|
|
Bithead Advanced
Joined: 03 Jan 2003 Posts: 550 Topics: 23 Location: Michigan, USA
|
Posted: Wed Aug 24, 2005 7:30 am Post subject: |
|
|
blueash,
3) The transaction id does not need to be defined to IMS Connect unless you have a security exit in place. It only needs to be defined to IMS.
4) You would execute the transaction. The data is obtained by GN to message queue rather than being passed in the LINKAGE SECTION like a subroutine.
The rest of the information looks correct. |
|
Back to top |
|
|
Arun Tomer Beginner
Joined: 24 Aug 2005 Posts: 3 Topics: 0 Location: Global !!!
|
Posted: Fri Aug 26, 2005 5:39 am Post subject: |
|
|
The basic thing here is you would just be invoking an IMS Transaction which would have a related PSB and program to do the necessary functions. After that transaction is performed, you can capture the messages and should be able to send them back to your invoking application. That transacation would be performed as background transaction in IMS. Whenever you would invoke that transacation and put an input message for it, the corresponding background application(COBOL/IMS DB-DC) would pick up that message on transaction getting scheduled and process it. Thanks ! |
|
Back to top |
|
|
|
|