This is a series which’ll cover Enterprise Integration Patterns (EIP) using OpenESB.
Part 1:Enterprise Integration Patterns (EIP) with OpenESB Part 1 : Content-Based Router
07 Wednesday Sep 2011
Posted Integration, Java, SOA
inThis is a series which’ll cover Enterprise Integration Patterns (EIP) using OpenESB.
Part 1:Enterprise Integration Patterns (EIP) with OpenESB Part 1 : Content-Based Router
11 Monday Apr 2011
Posted Camel, Integration, Java, Siebel, SOA
inTags
Before we begin using Siebel CRM On Demand’s web services, we require the WSDL files. The WSDL files are specific to the account and can be downloaded by logging in to Siebel COD.
Create a new SoapUI project and add the WSDL as initial WSDL. SoapUI will create a new project with placeholder requests for all operations. Let’s open ContactQueryPage operation from SoapUI.
The endpoint path will be something like – https://secure-ausoxxxxx.crmondemand.com/Services/Integration
This path is unique to your instance of Siebel COD.
Next lets remove the body of input and replace it with –
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header/> <soapenv:Body> <con:ContactQueryPage_Input xmlns:con="urn:crmondemand/ws/ecbs/contact/" xmlns:quer="urn:/crmondemand/xml/Contact/Query"> <quer:ListOfContact startrownum="0" pagesize="100" recordcountneeded="true"> <quer:Contact searchspec="[ContactFirstName] LIKE 'John'"> <quer:Id/> <quer:ContactFirstName/> <quer:ContactLastName/> <quer:AccountId/> </quer:Contact> </quer:ListOfContact> </con:ContactQueryPage_Input> </soapenv:Body> </soapenv:Envelope>
This results in Soap Fault response with Siebel error code SBL-ODU-01006 and message : “Internal Error: Session is not available. Aborting.”
This is because we still haven’t added username/password for authentication. There is another option to first get the session and then pass that value in header of the request. However I prefer to use the Stateless version above, as it separates the responsibility of handling session.
Let’s make 2 changes to fix this error.
1) Replace first line of the SOAP request with –
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/07/secext">
2) Add these lines just below the SOAP Envelope element –
<soapenv:Header> <wsse:Security> <wsse:UsernameToken> <wsse:Username>your_siebel_username</wsse:Username> <wsse:Password Type="wsse:PasswordText">your_siebel_password</wsse:Password> </wsse:UsernameToken> </wsse:Security> </soapenv:Header>
What we’ve done here is added WS-SECURITY headers to the SOAP request.
Now the request should run just fine.
Note –
1) You need to add any fields you need to the request before they can be returned by Siebel CRM. e.g., <ContactFirstName/>
2) Its better to confirm data actually exists by logging through web-console.
11 Friday Mar 2011
Tags
While SOA offers all the goodies of loose-coupling, it does require understanding of some basic concepts and formats.
SOAP and WSDL are the prime candidates (or culprits, depending on your view)
SOAP is just a protocol for passing information, important is WSDL.
A WSDL(Web Service Description Language) file defines the contract for web service. It is just like the menu in a restaurant or a table of contents of a book. It tells about what is offered.
Without wasting more time, lets just get to work – understanding WSDL.
A WSDL file may be provided to you or it can generally be accessed by appending “?wsdl” at the end of a web service address.
A WSDL file is best-read bottom-up. It consists of abstract as well as concrete parts. Important parts to focus are (concrete)-
Now focus on the Type attribute of the wsdl:binding, and trace it up in the document. It leads you to portType element. portType is the abstract part of the wsdl.
11 Friday Mar 2011
Posted Database, Integration, Java, Oracle
inRecently I needed to call a stored procedure which had Oracle’s XMLType as IN and OUT parameters.
The first thing to do is add xdb.jar and xmlparserv2.jar file to your application lib. These contain the required class files for Oracle XML API. the jars can be found under your installation of oracle client lib folders. Also don’t forget to add oracle jdbc driver files – ojdbc6 or ojdbc14.
The code I setup was this –
XMLType reqInXml; XMLType reqOutXML; String atpInStr = ""; OpResponse output = null; try { reqInStr = jaxbMarshalRequestToString(input); System.out.println("Input : " + reqInStr); } catch (JAXBException ex) { logger.log(Level.SEVERE, null, ex); } catch (IOException ex) { logger.log(Level.SEVERE, null, ex); } //input.getHeader().setNotes("THIS VALUE RETURNED BY FACADE : " + XXDS); try { Connection con = XXDS.getConnection(); //The IN parameter for stored proc is Oracle XDB XMLType reqInXml = XMLType.createXML(con, reqInStr); OracleCallableStatement stmt = (OracleCallableStatement) con.prepareCall("call DEMO_PROC.ProcessXMLRequest(?, ?, ?, ?)"); stmt.setObject(1, reqInXml); //set out parameters stmt.registerOutParameter (2, OracleTypes.OPAQUE,"SYS.XMLTYPE"); stmt.registerOutParameter(3, Types.INTEGER); stmt.registerOutParameter(4, Types.VARCHAR); stmt.executeQuery(); int resultCode = stmt.getInt(3); String resultMsg = stmt.getString(4); System.out.println("result code : " + resultCode); System.out.println("result msg : " + resultMsg); if (resultCode == 101 || resultCode == 100){ reqOutXML = XMLType.createXML(stmt.getOPAQUE(2)); System.out.println("Output from ERP :" + reqOutXML.getStringVal()); output = jaxbUnmarshalFromString(reqOutXML.getStringVal()); } } ....
This gave me “java.lang.ClassCastException: com.sun.gjc.spi.jdbc40.ConnectionHolder40 cannot
be cast to oracle.jdbc.OracleConnection” Exception. The connection was being returned from GlassFish JDBC ConnectionPool and was instance of OracleConnectionPooldataSource.
The FIX proved tricky, but in the end it was simple –
Do this –
OracleConnection oraCon = con.unwrap(OracleConnection.class); //The IN parameter for stored proc is Oracle XDB XMLType atpInXml = XMLType.createXML(oraCon, atpInStr);
Pass the cast instance of OracleConnection to the XMLType API.
06 Monday Dec 2010
I was working on a solution based on ActiveMQ where we required to pull messages from GlassFishMQ (based on OpenMQ) and put them on OracleAQ.
Now, ActiveMQ uses Camel ESB for internal message routing, this proved useful. However try as I might, I couldn’t find a simple solution to what I wanted to achieve.
My target was to configure ActiveMQ broker which’ll act as a message router and decouple the 2 systems. Both would be unaware of its presence. Sounds really good in theory providing loose coupling.
But the difficult part was finding documentation. All the documentation available was about using ActiveMQ as JMS provider in GlassFish. Not what I was looking at.
So finally after much difficulty, I found the solution. It is simple but difficult to find.
Step 1) Copy imq.jar to ActiveMQ lib directory. The jar is found in GLASSFISH_HOME/imq/lib
Step 2) Add below lines to your activemq configuration file –
This line creates a default connectionFactory using host localhost and port 7676
<bean id="connectionFactoryOpenMQQueue"/>
This part creates a bean with credentials
<bean id="openMQQueueCredentials"> <property name="targetConnectionFactory"> <ref bean="connectionFactoryOpenMQQueue"/> </property> <property name="username"> <value>admin</value> </property> <property name="password"> <value>admin</value> </property> </bean>
This part created the actual scheme, namespace identifier for the connection.
<bean id="openMQQueue"> <property name="connectionFactory" ref="openMQQueueCredentials"/> </bean>
Step 3) Add the routing instructions
This’ll consume message from GlassFishMQ and put it on ActiveMQ’s queue. You can check the messages at http://localhost:8161/admin
<route> <from uri="openMQQueue:queue:q_user_info" /> <to uri="activemq:queue:amq.temp.userinfo.queue"/> </route>
Referred to this info on how to configure the ConnectionFactory – http://docs.sun.com/source/817-0355/adminobj.html
17 Tuesday Aug 2010
Posted Database
inRecently we had a situation when two developers were working on same DB package. Delay in submission of deployment request by one dev resulted in package compilation error as a dependent Type was missing.
I was looking for solution that may help us avoid such situations in future.
Using SVN is one option; other is use of Database Change Management / Database Diff
Some tools for that are –
1) Oracle Change Management Pack
From the docs –
There are three core capabilities of Change Management that allow developers and database administrators to manage changes in database environments:
• Baseline – A point in time of the definition of the database and its associated database objects.
• Comparison – A complete list of differences between a baseline or a database and another baseline or a database.
• Synchronization – The process of promoting changes from a database definition capture in a baseline or from a database to a target database
It allows us to take a baseline(snapshot) at a fixed time and then later we can see how the DB schema and objects have changed. The CMP can also generate DDL scripts, though I am not sure we would want to use it.
Details
• http://download-east.oracle.com/docs/cd/B19306_01/em.102/b31949/change_management.htm
•http://www.oracle.com/technology/products/oem/pdf/change-management-pack-11g-datasheet.pdf
2) PL/SQL Developer Compare User Objects feature
This is available from Tools -> Compare User Objects
3) Oracle SQL Developer Database Diff feature
This is available from Tools -> Database diff
http://www.oracle.com/technology/products/database/sql_developer/files/what_is_sqldev.html#copy See “Schema Copy and Compare”
#1 looks to be most versatile and flexible but DBA rights may be necessary.
#2 & 3 can be used by any developer. I think Oracle SQL Developer is easier and provides more options.
Using any of the above option can help in –
1) Identifying the changed objects and may also serve as a Check List before requesting deployment.
2) The developers concerned can take ownership of specific changed objects.