Using Spring's CCI access support - Java-Springs

Record conversion

One of the aims of the JCA CCI support is to provide convenient facilities for manipulating CCI records.The developer can specify the strategy to create records and extract datas from records, for use with Spring's Cci Template. The following interfaces will configure the strategy to use input and output records if you don't want to work with records directly in your application.

In order to create an input Record, the developer can use a dedicated implementation of the Record Creator interface.

public interface RecordCreator {
Record create Record(RecordFactory recordFactory) throws ResourceException, DataAccessException;
}

As you can see, the createRecord(..) method receives a Record Factory instance as parameter, which corresponds to the Record Factory of the Connection Factory used. This reference can be used to create Indexed Record or Mapped Record instances. The following sample shows how to use the RecordCreator interface and indexed/mapped records.

public class MyRecordCreator implements RecordCreator {
public Record createRecord(RecordFactory recordFactory) throws ResourceException {
IndexedRecord input = recordFactory.createIndexedRecord("input");
input.add(new Integer(id));
return input;
}
}

An output Record can be used to receive data back from the EIS. Hence, a specific implementation of the Record Extractor interface can be passed to Spring's CciTemplate for extracting data from the output Record.

public interface RecordExtractor {
Object extractData(Record record) throws ResourceException, SQLException, DataAccessException;
}

The following sample shows how to use the RecordExtractor interface.

public class MyRecordExtractor implements RecordExtractor {
public Object extractData(Record record) throws ResourceException {
CommAreaRecord commAreaRecord = (CommAreaRecord) record;
String str = new String(commAreaRecord.toByteArray());
String field1 = string.substring(0,6);
String field2 = string.substring(6,1);
return new OutputObject(Long.parseLong(field1), field2);
}
}

The CciTemplate

The CciTemplate is the central class of the core CCI support package (org. spring frame work.jca.cci.core). It simplifies the use of CCI since it handles the creation and release of resources. This helps to avoid common errors like forgetting to always close the connection. It cares for the lifecycle of connection and interaction objects, letting application code focus on generating input records from application data and extracting application data from output records.

The JCA CCI specification defines two distinct methods to call operations on an EIS. The CCI Interaction interface provides two execute method signatures:

public interface javax.resource.cci.Interaction {
...
boolean execute(InteractionSpec spec, Record input, Record output) throws ResourceException;
Record execute(InteractionSpec spec, Record input) throws ResourceException;
...
}

Depending on the template method called, CciTemplate will know which execute method to call on the interaction. In any case, a correctly initialized InteractionSpec instance is mandatory.

CciTemplate.execute(..) can be used in two ways:

  • With direct Record arguments. In this case, you simply need to pass the CCI input record in, and the returned object be the corresponding CCI output record.
  • With application objects, using record mapping. In this case, you need to provide corresponding RecordCreator and RecordExtractor instances.

With the first approach, the following methods of the template will be used. These methods directly correspond to those on the Interaction interface.

public class CciTemplate implements CciOperations {
public Record execute(InteractionSpec spec, Record inputRecord)
throws DataAccessException { ... }
public void execute(InteractionSpec spec, Record inputRecord, Record outputRecord)
throws DataAccessException { ... }
}

With the second approach, we need to specify the record creation and record extraction strategies as arguments. The interfaces used are those on record conversion. The corresponding CciTemplate methods are the following:

public class CciTemplate implements CciOperations {
public Record execute(InteractionSpec spec, RecordCreator inputCreator)
throws DataAccessException { ... }
public Object execute(InteractionSpec spec, Record inputRecord, RecordExtractor outputExtractor)
throws DataAccessException { ... }
public Object execute(InteractionSpec spec, RecordCreator creator, RecordExtractor extractor)
throws DataAccessException { ... }
}

Unless the outputRecordCreator property is set on the template , every method will call the corresponding execute method of the CCI Interaction with two parameters: Interaction Spec and input Record, receiving an output Record as return value.Cci Template also provides methods to create Index Record and Mapped Record out side a Record Creator implementation, through its create Index Record(..) and
create Mapped Record(..) methods. This can be used within DAO implementations to create Record instances to pass into corresponding Cci Template. execute(..) methods.

public class CciTemplate implements CciOperations {
public IndexedRecord createIndexedRecord(String name) throws DataAccessException { ... }
public MappedRecord createMappedRecord(String name) throws DataAccessException { ... }
}

DAO support

Spring's CCI support provides a abstract class for DAOs, supporting injection of a Connection Factory or a CciTemplate instances. The name of the class is CciDaoSupport: It provides simple set Connection Factory and set Cci Template methods.Internally, this class will create a Cci Template instance for a passed-in Connection Factory, exposing it to concrete data access implementations in sub classes.

public abstract class CciDaoSupport {
public void setConnectionFactory(ConnectionFactory connectionFactory) { ... }
public ConnectionFactory getConnectionFactory() { ... }
public void setCciTemplate(CciTemplate cciTemplate) { ... }
public CciTemplate getCciTemplate() { ... }
}

Automatic output record generation

If the connector used only supports the Interaction.execute(..) method with input and output records as parameters (that is, it requires the desired output record to be passed in instead of returning an appropriate output record), you can set the output Record Creator property of the CciTemplate to automatically generate an output record to be filled by the JCA connector when the response is received. This record will be then returned to the caller of the template.

This property simply holds an implementation of the Record Creator interface, used for that purpose.The output Record Creator property must be directly specified on the CciTemplate. This could be done in the application code like so:

cciTemplate.setOutputRecordCreator(new EciOutputRecordCreator());

Or (recommended) in the Spring configuration, if the CciTemplate is configured as a dedicated bean instance:

<bean id="eciOutputRecordCreator" class="eci.EciOutputRecordCreator"/>
<bean id="cciTemplate" class="org.springframework.jca.cci.core.CciTemplate">
<property name="connectionFactory" ref="eciConnectionFactory"/>
<property name="outputRecordCreator" ref="eciOutputRecordCreator"/>
</bean>

Table Usage of Interaction execute methods

Usage of Interaction execute methods

Using a CCI Connection and Interaction directly

Cci Template also offers the possibility to work directly with CCI connections and interactions, in the same manner as Jdbc Template and Jms Template. This is useful when you want to perform multiple operations on a CCI connection or interaction, for example.The interface Connection Call back provides a CCI Connection as argument,in order to perform custom operations on it, plus the CCI Connection Factory which the Connection was created with. The latter can be useful for example to get an associated Record Factory instance and create indexed/mapped records, for example.

public interface ConnectionCallback {
Object doInConnection(Connection connection, ConnectionFactory connectionFactory)
throws ResourceException, SQLException, DataAccessException;
}

The interface Interaction Call back provides the CCI Interaction, in order to perform custom operations on it, plus the corresponding CCI Connection Factory.

public interface InteractionCallback {
Object doInInteraction(Interaction interaction, ConnectionFactory connectionFactory)
throws ResourceException, SQLException, DataAccessException;
}

Example for CciTemplate usage

Firstly, some initializations on the CCI InteractionSpec must be done to specify which CICS program to access and how to interact with it.

ECIInteractionSpec interactionSpec = new ECIInteractionSpec();
interactionSpec.setFunctionName("MYPROG");
interactionSpec.setInteractionVerb(ECIInteractionSpec.SYNC_SEND_RECEIVE);

Then the program can use CCI via Spring's template and specify mappings between custom objects and CCI Records.

public class MyDaoImpl extends CciDaoSupport implements MyDao {
public OutputObject getData(InputObject input) {
ECIInteractionSpec interactionSpec = ...;
OutputObject output = (ObjectOutput) getCciTemplate().execute(interactionSpec,
new RecordCreator() {
public Record createRecord(RecordFactory recordFactory) throws ResourceException {
return new CommAreaRecord(input.toString().getBytes());
}
},
new RecordExtractor() {
public Object extractData(Record record) throws ResourceException {
CommAreaRecord commAreaRecord = (CommAreaRecord)record;
String str = new String(commAreaRecord.toByteArray());
String field1 = string.substring(0,6);
String field2 = string.substring(6,1);
return new OutputObject(Long.parseLong(field1), field2);
}
});
return output;
}
}

As discussed previously, callbacks can be used to work directly on CCI connections or interactions.

public class MyDaoImpl extends CciDaoSupport implements MyDao {
public OutputObject getData(InputObject input) {
ObjectOutput output = (ObjectOutput) getCciTemplate().execute(
new ConnectionCallback() {
public Object doInConnection(Connection connection, ConnectionFactory factory)
throws ResourceException {
// do something...
}
});
}
return output;
}
}

For a more specific callback, you can implement an Interaction Call back. The passed-in Interaction will be managed and closed by the Cci Template in this case.

public class MyDaoImpl extends CciDaoSupport implements MyDao {
public String getData(String input) {
ECIInteractionSpec interactionSpec = ...;
String output = (String) getCciTemplate().execute(interactionSpec,
new InteractionCallback() {
public Object doInInteraction(Interaction interaction, ConnectionFactory factory)
throws ResourceException {
Record input = new CommAreaRecord(inputString.getBytes());
Record output = new CommAreaRecord();
interaction.execute(holder.getInteractionSpec(), input, output);
return new String(output.toByteArray());
}
});
return output;
}
}

For the examples above, the corresponding configuration of the involved Spring beans could look like this in non-managed mode:

<bean id="managedConnectionFactory" class= "com.ibm.connector2.cics.ECIManagedConnectionFactory">
<property name="serverName" value="TXSERIES"/>
<property name="connectionURL" value="local:"/>
<property name="userName" value="CICSUSER"/>
<property name="password" value="CICS"/>
</bean>
<bean id="connectionFactory" class="org.springframework.jca.support.LocalConnectionFactoryBean">
<property name="managedConnectionFactory" ref="managedConnectionFactory"/>
</bean>
<bean id="component" class="mypackage.MyDaoImpl">
<property name="connectionFactory" ref="connectionFactory"/>
</bean>

In managed mode (that is, in a Java EE environment), the configuration could look as follows:

<jee:jndi-lookup id="connectionFactory" jndi-name="eis/cicseci"/>
<bean id="component" class="MyDaoImpl">
<property name="connectionFactory" ref="connectionFactory"/>
</bean>

All rights reserved © 2018 Wisdom IT Services India Pvt. Ltd DMCA.com Protection Status

Java-Springs Topics