z/TPF support for MongoDB (PJ42292) introduced z/TPF to MongoDB and allowed you to access your z/TPFDF databases through a standard MongoDB interface. With z/TPF support for Java™ (PJ43892), z/TPF became Java compatible and you could run Java applications on your z/TPF system. Both of these APARs are about using commonly used interfaces, standard languages, and widely known skills, bringing those to z/TPF, and helping you unlock the data and capabilities of your z/TPF system.
This article takes another step in that journey, describing how to use these technologies in conjunction with each other - using a MongoDB client in your Java application on z/TPF to access your local z/TPFDF data!
Downloading the MongoDB Java driver
To access a z/TPFDF database from a Java application on z/TPF using the MongoDB interface, you first need to download the MongoDB Java driver. The MongoDB Java driver is available from the MongoDB website, which resides at www.mongodb.org. The driver is also available on github at release of this article at https://mongodb.github.io/mongo-java-driver/. You can access the MongoDB interface to z/TPFDF using either level of the java driver, 2.x or 3.x. These driver levels have slightly different interfaces, with the 3.x level forming a consistent programming interface for MongoDB across different programming languages.
Preparing your z/TPFDF for MongoDB access
After downloading the drivers, you need to prepare your z/TPFDF database for MongoDB access. You may have completed this step if you are already accessing your z/TPFDF data from a remote MongoDB application. Information on this procedure is available in the IBM Information Center https://www-01.ibm.com/software/htp/tpf/pubs/tpfpubs.html.
Prototype MongoDB access without a Java Application
As long as your application uses supported functions, a Java application can access a z/TPFDF database located on your z/TPF system in exactly the same way it would access a traditional MongoDB database.
While developing your application, you can unit test and validate your runtime queries using a MongoDB client such as robomongo https://robomongo.org/ before coding them in an application.
Create Java Database classes
The format of a mongo document response is defined by the DFDL schema loaded to your z/TPF system as part of the database definition. Because this DFDL schema is also an XML schema, you can use standard JAXB tooling to produce Java classes that map to your database objects.
For example, you can use the “xjc” compiler on a development platform like Linux to produce java class definitions, which are used when serializing and deserializing the Mongo request and reply documents. Depending on the contents of the DFDL schema file, you may wish to use the “-nv” option which disables strict validation of the schema.
In the following example, the xjc command is used to create Java classes for an example z/TPFDF PNR database.
> xjc –nv pnr.tpfdf.dfdl.xsd
com/ibm/xmlns/prod/ztpf/dfdl/tpfdf/drcom/ObjectFactory.java
com/ibm/xmlns/prod/ztpf/dfdl/tpfdf/drcom/PinRecord.java
com/ibm/xmlns/prod/ztpf/dfdl/tpfdf/drcom/RemComplex.java
com/ibm/xmlns/prod/ztpf/dfdl/tpfdf/drcom/SignatureRecord.java
com/ibm/xmlns/prod/ztpf/dfdl/tpfdf/drcom/package-info.java
com/ibm/xmlns/prod/ztpf/dfdl/tpfdf/dr26bi/AddressRecord.java
com/ibm/xmlns/prod/ztpf/dfdl/tpfdf/dr26bi/CardRecord.java
com/ibm/xmlns/prod/ztpf/dfdl/tpfdf/dr26bi/DFLREC.java
com/ibm/xmlns/prod/ztpf/dfdl/tpfdf/dr26bi/FactsRecord.java
com/ibm/xmlns/prod/ztpf/dfdl/tpfdf/dr26bi/FlightHistoryRecord.java
com/ibm/xmlns/prod/ztpf/dfdl/tpfdf/dr26bi/Index.java
com/ibm/xmlns/prod/ztpf/dfdl/tpfdf/dr26bi/IntComplex.java
com/ibm/xmlns/prod/ztpf/dfdl/tpfdf/dr26bi/ObjectFactory.java
com/ibm/xmlns/prod/ztpf/dfdl/tpfdf/dr26bi/PassengerNameRecord.java
com/ibm/xmlns/prod/ztpf/dfdl/tpfdf/dr26bi/PassengerNumberRecord.java
com/ibm/xmlns/prod/ztpf/dfdl/tpfdf/dr26bi/PrefixedLREC.java
com/ibm/xmlns/prod/ztpf/dfdl/tpfdf/dr26bi/ServiceRecord.java
com/ibm/xmlns/prod/ztpf/dfdl/tpfdf/dr26bi/package-info.java
Using an Object Mapping Package
To access your data as Java objects, you need to use an object mapping package to translate the MongoDB response into Java objects. The mechanism for translating a MongoDB response into the Java object differs based on which package you use. I have found the Jackson package from FasterXML to be a convenient interface (located on github at https://github.com/FasterXML/jackson). Jettison and Moxy/EclipseLink are two other packages.
The following is an example of accessing a z/TPFDF database through the MongoDB interface. The example maps an LREC returned through the MongoDB interface into a “PassengerNameRecord” java object.
MongoClient mongoClient = null;
DBCollection pnrColl = null;
mongoClient = new MongoClient("localhost");
DB pnrDB = mongoClient.getDB("tpfdf");
pnrColl = pnrDB.getCollection("PNR");
} catch (UnknownHostException e) {
BasicDBObject locator = new BasicDBObject("_index.PnrByDate", new BasicDBObject().append("date", date));
DBObject subfile = pnrColl.findOne(locator);
BasicDBList pnrRecords = (BasicDBList) subfile.get("PassengerNameRecord");
for (Object record : pnrRecords) {
BasicDBObject pnrRecord = (BasicDBObject) record;
ObjectMapper mapper = new ObjectMapper();
mapper.setAnnotationIntrospector(new JaxbAnnotationIntrospector(mapper.getTypeFactory() ));
PassengerNameRecord pnrNameRec = mapper.convertValue(pnrRecord, PassengerNameRecord.class);
You will notice in the example above, the entire document was not transformed directly into Java objects. Performing this conversion is possible with your object mapping package, but you may wish to consider the performance overhead of converting an entire response into Java objects based on your application’s requirements.
Developing and Deploying a MongoDB client
One of the great aspects of this process is that development, unit test, and function test phases for your Java application can be done on a distributed environment. This allows a developer to quickly prototype and modify the client application without going through the process of loading to the z/TPF system, streamlining the process of developing new applications. When testing your Java application, you can test against a local MongoDB database or you can test against a z/TPFDF database on your z/TPF test system that has been enabled for MongoDB access.
Once development is complete, the application may be loaded either as a standalone Java application, or as a RESTful service using JAX-RS deployed to a JAM on z/TPF.
Programming Considerations
When working with the MongoDB client, there are two models recommended for managing connections to a MongoDB database - shared connections and dedicated connections.
Each MongoDB connection uses system resources, so it is not advisable to establish and destroy connections as part of a transactional workload. By having shared connections, a programmer can minimize total used connections. By having dedicated connections, programmers can avoid contention on access to connections.
With either approach the programmer should be aware that the MongoDB connections consume system resources and care should be taken to limit the number of concurrent connections. Also, when releasing a connection, the programmer should ensure use of the MongoClient.close() api to release the system resources in use by the connection.