integrating sap the java ee way - jboss one day talk 2012
DESCRIPTION
Cuckoo is an open source Resource Adapter for SAP that is compatible to the Java Connector Architecture (JCA) version 1.5. It enables developers of Java EE applications to call functions in a SAP backend, making use of Java EE features like Container Managed Transactions and Security. Hibersap helps developers of Java applications to call business logic in SAP backends. It defines a set of Java annotations to map SAP function modules to Java classes as well as a small, clean API to execute these function modules and handle transaction and security aspects. Hibersap's programming model is quite similar to those of modern O/R mappers, significantly speeding up the development of SAP interfaces and making it much more fun to write the integration code.TRANSCRIPT
Integrating SAP the Java EE way
JBoss OneDayTalk 2012
Carsten Erker
Remember those days...?
Statement st = conn.createStatement(); ResultSet rs = st.executeQuery( "SELECT * FROM customer" );
List<Customer> customers = new ArrayList<Customer>();
while ( rs.next() ) { Customer customer = new Customer(); customer.setId( rs.getString( "ID" ) ); customer.setFirstName( rs.getString( "FIRST_NAME" ) ); customer.setLastName( rs.getString( "LAST_NAME" ) ); ... customers.add( customer ); } ...
Who is still doing this?
Nowadays we do something like this...
@Entitypublic class Customer{ @Id @GeneratedValue private Long id; private String firstName; private String lastName; ...}
List<Customer> customers = entityManager .createQuery( "select c from Customer c" ) .getResultList();
When calling business logic in SAP we don‘t want to go the old
way...
Setting the stage...
Courtesy of Special Collections, University of Houston Libraries. UH Digital Library.
The SAP Java Connector (JCo)
How it works...
Calls function modules in SAP backend
Function modules are a piece of code written in
ABAP
They have an interface with different types of
parameters to pass data
FUNCTION BAPI_SFLIGHT_GETLIST.*"-----------------------------------------------------*"*"Lokale Schnittstelle:*" IMPORTING*" VALUE(FROMCITY) LIKE BAPISFDETA-CITYFROM*" VALUE(TOCITY) LIKE BAPISFDETA-CITYTO*" VALUE(AIRLINECARRIER) LIKE BAPISFDETA-CARRID*" EXPORTING*" VALUE(RETURN) LIKE BAPIRET2 STRUCTURE BAPIRET2*" TABLES*" FLIGHTLIST STRUCTURE BAPISFLIST*"-----------------------------------------------------
JCo runs on top of the SAP-proprietary
RFC interface (Remote Function Call)
JCo can be used in Client and Server mode
Example code calling a function module in
SAP...
JCoDestination destination = JCoDestinationManager.getDestination( "NSP" );JCoFunction function = destination.getRepository().getFunction( "BAPI_FLCUST_GETLIST" );function.getImportParameterList().setValue( "MAX_ROWS", 10 );
function.execute( destination );
JCoParameterList tableParams = function.getTableParameterList();JCoTable table = tableParams.getTable( "CUSTOMER_LIST" );
List<Customer> customers = new ArrayList<Customer>();
for ( int i = 0; i < table.getNumRows(); i++ ){ table.setRow( i ); Customer customer = new Customer(); customer.setId( table.getLong( "CUSTOMERID" ) ); customer.setLastName( table.getString( "CUSTNAME" ) ); customers.add( customer );}...
=> Lots of glue code, tedious mapping of
parameters
But - JCo has some benefits that make it a good fit for business
apps...
It can be used with Transactions
It implements Connection Pooling
SAP functions can be called asynchronously
It is fast
The bad points...
The programming model
Does not fit very well into the Java EE world:
Not trivial to use it with CMT
The same goes for Security
The alternative: Java EE Connector Architecture (JCA)
JCA is a Java EE standard
JCA was created for the interaction of Java EE applications with
Enterprise Information Systems, such as SAP
A Resource Adapter is an implementation of JCA for a certain EIS
A RA is deployed in an Application Server in form of a Resource
Archive (.rar)
The RA takes care of...
Transaction Management
Connection Management
Security Management
... all this in a standard way
JCA solves a lot of problems, except one...
The programming model
:-(
JCA defines the Common Client
Interface (CCI) for a standard way to access
an EIS
Because of the many different natures of
EIS‘s, it is overly generic
It operates on Lists, Maps and/or ResultSets representing the data
Additionally, a lot of glue code needs to be
written
In this, it is not too different from SAP‘s
Java Connector...
@Resource( mappedName = "java:jboss/eis/NSP" )private ConnectionFactory connectionFactory;
...
Connection connection = connectionFactory.getConnection();Interaction interaction = connection.createInteraction();
RecordFactory rf = connectionFactory.getRecordFactory();
MappedRecord input = rf.createMappedRecord( "BAPI_FLCUST_GETLIST" );input.put( "CUSTOMER_NAME", "Ernie" );input.put( "MAX_ROWS", 20 );
MappedRecord output = ( MappedRecord ) interaction.execute( null, input );...
List<Customer> customers = new ArrayList<Customer>();
IndexedRecord customerTable = ( IndexedRecord ) output.get( "CUST_LIST" ); for ( Object row : customerTable ){ MappedRecord record = ( MappedRecord ) row;
Customer customer = new Customer(); customer.setId( ( String ) record.get( "CUSTOMERID" ) ); customer.setName( ( String ) record.get( "CUSTNAME" ) ); ... result.addCustomer( customer );}
SAP offers a RA that only runs on SAP
Application Servers
Any more alternatives?
For read-only and less frequent SAP calls
consider using Web Services
A SOA platform may be well suited for not-so-
tight integration
Introducing the cool stuff...
Photo by Alan Levine, CC-BY 2.0, http://www.flickr.com/photos/cogdog
It implements JCA version 1.5
It currently only supports the
outbound way
Under the hood, it uses the SAP Java
Connector (JCo)
The next steps...
Upgrading Cuckoo to JCA version 1.6
Adding inbound capability
Cuckoo is Open Source under
LGPL License
More info:https://sourceforge.net/p/cuckoo-ra/
Example application:https://github.com/cerker/
cuckoo-example
What was all the fuss about the programming
model?
We still have to solve this problem...
Hibersap is something like an O/R mapper for
SAP functions
It makes use of Java annotations to map
SAP functions and their parameters to Java
objects
It has an API that is quite similar to Hibernate/JPA
Thus it fits very well into the modern Java
world
Hibersap takes care of most of the glue code
It can be either used with JCo or with a JCA
Resource Adapter
Switching between them is a matter of
configuration
This makes integration testing a breeze
Finally, some code...
The business object...
public class Customer{ @Parameter("CUSTOMERID") private String id;
@Parameter( "CUSTNAME" ) private String firstName; ...}
@Bapi( "BAPI_FLCUST_GETLIST" )public class CustomerList{ @Import @Parameter("MAX_ROWS") private int maxRows;
@Table @Parameter( "CUSTOMER_LIST" ) private List<Customer> customers; ...}
The API...
Session session = sessionManager.openSession();
CustomerList customerList = new CustomerList( 10 );session.execute( customerList );
List<Customer> customers = customerList.getCustomers();
The configuration...
<hibersap> <session-manager name="NSP"> <context>org.hibersap.execution.jca.JCAContext</context> <jca-connection-factory> java:jboss/eis/sap/NSP </jca-connection-factory> <annotated-classes> <annotated-class> de.akquinet.jbosscc.cuckoo.example.model.CustomerSearch </annotated-class> ... </annotated-classes> </session-manager></hibersap>
META-INF/hibersap.xml => JCA
<hibersap> <session-manager name="NSP"> <context>org.hibersap.execution.jco.JCoContext</context> <properties>" " " <property name="jco.client.client" value="001" />" " " <property name="jco.client.user" value="sapuser" />" " " <property name="jco.client.passwd" value="password" />" " " <property name="jco.client.ashost" value="10.20.30.40" />" " " <property name="jco.client.sysnr" value="00" /> ..." " </properties> <annotated-classes> <annotated-class> de.akquinet.jbosscc.cuckoo.example.model.CustomerSearch </annotated-class> ... </annotated-classes> </session-manager></hibersap>
META-INF/hibersap.xml => JCo
Bean Validation can be used on parameter
fields...
@Parameter( "COUNTR_ISO" ) @NotNull @Size(min = 2, max = 2) private String countryKeyIso;
Converters allow for data type or format
conversion on parameter fields...
@Parameter( "TYPE" ) @Convert( converter = SeverityConverter.class ) private Severity severity;
Hibersap is Open Source and licensed
under LGPL
Putting it all together...
In a Java EE application we should use Cuckoo RA
Thus, we can make use of CMT in EJBs
...and all the other benefits of JCA
Using Hibersap, we gain an elegant and
lightweight programming model
... especially when using Hibersap‘s EJB tools
Thus, we get much nicer code that is easier to understand, maintain
and test
Example application:https://github.com/cerker/cuckoo-hibersap-example
Tooling...
JBoss Forge plugin:https://github.com/
forge/plugin-hibersap
See also:http://blog.akquinet.de/
2012/07/12/
Hibersap-Camel Component:
https://github.com/bjoben/camel-hibersap
About me...
Carsten ErkerSoftware Architect and Consultantakquinet AG in Berlin / Germany
Questions?