Integration Knowledge Kit Developer Journal JBoss Enterprise SOA Platform 5.3.1 A developer's journal of lessons learned and metrics to compare developer productivity and performance costs. The journal explores why platform choices count covering the planning, expertise, and knowledge required to quickly and flexibly build and deploy highly scalable applications. Appvance, Inc. 1735 Technology Drive, Suite 820 San Jose, CA 95110 USA Phone: 855.254.1164 Web: http://www.appvance.com email: fcohen@appvance.com August 5, 2013 2013 Appvance. All rights reserved. Ok to freely copy and distribute with this copyright notice intact. JBoss SOA Platform Developer s Journal Page 1 of 51
Index Document Purpose and Brief Introduction to Project Scope!... 3 Server and Tools Setup!... 4 JBoss Required Tools!... 5 JBoss Enterprise SOA Platform!... 8 Creation of Web Services!... 9 Design Business Process!... 27 Making Changes!... 43 Versioning!... 50 Conclusions!... 51 JBoss SOA Platform Developer s Journal Page 2 of 51
1. Document Purpose and Brief Introduction to Project Scope This is a developer s journal where developers are going to write their experience installing and using JBoss tools for BPM over SOA. For this purpose the following steps will be followed: 1. Installation of Tools and Environment Setup Using local machine (JBoss), servers will be installed and properly configured to enable the development of services. Notes will be taken during this process regarding download time, and installation and setup troubleshooting. 2. Creation of Web Services In order to test the tools, a set of services was defined to be developed with each set of tools. These Web Services are to be developed: a. Allocate Purchase Order: a service with three operations, of which only one will be used. This service will be implemented using regular SOAP binding over HTTP and using a regular bean/servlet. b. Reserve Parts: This is a service implemented using regular SOAP binding over HTTP and using an EJB. This has a front-end app, to allow user s a peek at the requested order and approve it. As it has a human interaction factor, the Web service should be asynchronous. c. Price the Purchase Order: this service sets a price to the Order. This simulates the connection to a third party application. The idea is to use a connector/adapter to wrap the call to external an external system using web services. In this step, notes will be taken regarding the difficulty and characteristics of Web service creation and deployment using the mentioned tools. For each change to be made, it will be analyzed the support offered by the tool and any workaround needed to do the change. If a change cannot be applied to a service, a justification will be given. Further details about the scope can be found in the Appvance Integration Kit 2013 RFP.pdf document at http://www.appvance.com/kit JBoss SOA Platform Developer s Journal Page 3 of 51
2. Server and Tools Setup Chapter Summary Important Issues: None. Monday, July 8 Time: 3 hours System Features: AMD Athlon II X2 260u Processor 1.80 GHz 6 GB RAM 500 GB SATA Disk Windows 7 64 bit Operative System Download Internet Speed Average: 0.5Mbps Architect s Comment: These are the development workstations, not the final server deployment platform. JBoss SOA Platform Developer s Journal Page 4 of 51
3. JBoss Required Tools Chapter Summary Important Issues: The important part to note here is that the official platform contains old versions of the components. A full stack is always welcomed as it has everything integrated, and the developer does not need to glue together all the technologies. There is a fail with the IDE: the stable version is not available and not packed with the full platform. We started working with a list of tools: jboss-as-distribution-6.1.0.final.zip eclipse-standard-kepler-r-win32.zip soapui-pro-x64-4.5.2.exe jboss-eap-6.1.0.zip jbossesb-4.11.zip jbossesb-server-4.11.zip Later on we found out this list was available as a package called JBoss Enterprise SOA Platform, so we downloaded that one for the final part. JBoss SOA Platform Developer s Journal Page 5 of 51
First Bump Monday, July 8 Time: 3 hours After installing the downloaded tools, the first thing was to quickly create a helloworld service. To do this I followed the steps suggested in the following website: http://eai-course.blogspot.com.ar/2012/11/the-helloworld-in-jboss-enterprise.html The first problems appeared almost immediately, when I was just trying to create an ESB Project. The message was the following: I was missing the Jboss Tools for SOA. Unfortunately, I couldn t use my current Eclipse version so I had to download Eclipse Indigo(SR2), as indicate the following link: http://pfelitti87.blogspot.com.ar/2012/08/installing-jboss-esb-in-jboss-as-51.html JBoss SOA Platform Developer s Journal Page 6 of 51
Then, I integrated the JBoss ESB 4.11 to JBoss AS 5.1.0.GA, run the server, and I had the server up. A little bit of bad start. Architect s Comment: These problems are common when trying to create your stack of tools. Versions do not play nice if you are not careful. That is why a packaged solution is better. JBoss SOA Platform Developer s Journal Page 7 of 51
JBoss Enterprise SOA Platform Monday, July 8 Time: 2 hours After working a little with the services, I found out that it was better to try the Enterprise SOA Platform, as it has all the modules already working together. It contains not only the JBoss Server, but also the ESB and other components. When downloading, I noticed that the jbpm is also included, but as a separated download. When trying to install this it required the JBoss Enterprise Business Rules Management System Platform (BRMS) that was not included in the package! The BRMS is an additional package, so if you need to use the jbpm there is an extra cost. The installation is not a point and click though, the developer has to manually edit a couple of file to remove hashes and that s it. I just followed the instructions in: https://access.redhat.com/site/documentation/en-us/jboss_enterprise_soa_platform/ 5/html-single/SOA_Getting_Started_Guide/index.htm Finally, although the documentation says so, the JBoss Developer Studio is not included in the SOA Platform package, I had to downloaded it separately. The problem here is that JBDS is version 7 now, but as of May 2013 the SOA tooling for JBDS 6 has not been released yet (see https://access.redhat.com/site/solutions/279393). The JBDS 7 that I downloaded did not have the tooling and I couldn t use it. So, I had to go to the nightly build repository and find the update site (http://download.jboss.org/jbosstools/ updates/nightly/soa-tooling/4.1.kepler/4.1.0/) for Kepler Eclipse and use that (unsupported). BTW, I was unable to download JBDS 5, even in older versions, it requested some information and always presented an error saying my answers were not correct. Architect s Comment: This is not a good thing. The supported Developer studio is too old and the update speed of the tooling is not a good sign. JBoss SOA Platform Developer s Journal Page 8 of 51
4. Creation of Web Services Chapter Summary Important Issues: There is not special creation tool for web services than the regular found in Eclipse. Still, ESB is able to expose SOAP services in a declarative way, although it not always work. ESB Exposed Web Services do not support JMS transport, at least conceptually. The ESB has a heavy use of JMS queues, but only for internal format messages. There is no way to expose REST services in the ESB, only a regular RESTEasy version, and there is no support for OData as the actual implementation is not compatible with RESTEasy. Learning about Web Services Creation with JBoss ESB. Monday, July 8 Time: 1 hours Once the Tool Kit was installed, I tried to develop a simple web service. Web services can be created using an ESB project or a simple Dynamic Web Project. There are many articles explaining how to do it. Here are two simple articles found: http://www.mastertheboss.com/jboss-soa/jboss-esb-webservice-producer https://community.jboss.org/wiki/soa-p43simplewebserviceproxy?_sscc=t JBoss SOA Platform Developer s Journal Page 9 of 51
POAllocationService (common) Tuesday, July 9 Time: 4 hours 1. The firs service was a normal SOAP service. The solution was created in an ESB Project, with one class that has the code of all three methods being asked. The idea behind this is allowing a normal Java class that offers a service and is not already exposed as such, to be exposed using a wrapper. The ESB uses an action called SOAPProcessor to expose the class operations as a service to anyone working with the ESB. The class has to be annotated with normal @Webservice and @Webmethod annotations. 2. In our case, we are not going to use the SOAPProcessor directly. We just need three things: a provider to allow the connection, a listener to that connection, and an action indicating the class and method to call. To expose that service, we need understand the jboss-esb.xml configuration file. This file is the most important one in the project. It contains all configuration of the service. 3. First the jbr-provider defines a port as a bus. Then the service declaration, we use a jbr-listener to map to that bus and an action containing the reference to particular method. <?xml version="1.0"?> <jbossesb parameterreloadsecs="5" xmlns="http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/ jbossesb-1.0.1.xsd" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http:// anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/ jbossesb-1.0.1.xsd http://anonsvn.jboss.org/repos/labs/labs/jbossesb/trunk/product/ etc/schemas/xml/jbossesb-1.0.1.xsd"> <providers> <jbr-provider name="myhttpgateway" protocol="http"> <jbr-bus busid="myhttpgateway" port="7777"/> </jbr-provider> </providers> <services> <service category="mycategory" description="mydescription" invmscope="global" name="myhttpproxyservice"> <listeners> <jbr-listener busidref="myhttpgateway" is-gateway="true" name="myhttpgateway"/> </listeners> <actions inxsd="files/in/request.xsd" outxsd="files/out/response.xsd" > <action class="services.firstservicews" name="action" process="addnewpo"/> </actions> </service> </jbossesb> JBoss SOA Platform Developer s Journal Page 10 of 51
4. Note the inxsd and the OutXsd, these will tell the action what is expected to be sent to the method and what it should produce. The class is not an annotated one like with SOAPProcessor, but a special one that should work as an action and thus should extend org.jboss.soa.esb.actions.abstractactionlifecycle. Also the methods should receive and return org.jboss.soa.esb.message.message. We don t care about the message format, we only get the body with message.getbody().get().tostring() and store the result using message.getbody().add(thebody). The actual format, delivery and transportation is defined by the ESB configuration. 5. This is the way ESB has to expose the service. Of course, it is not pretty to directly touch XML code. 6. Now, if we consult "http://localhost:8080/contract/", we see the url of the wsdl of the new service. Architect s Comment: There is something odd about that web service exposure, as it is not using the given port 7777 but regular 8080. Sounds like a automatically generated SOAP Proxy. JBoss SOA Platform Developer s Journal Page 11 of 51
7. Then, I test this service in SOAP UI, and return the xml asked. This xml, would be the next service entry. Architect s Comment: The actual need of touching XML is removed with a specialized IDE. In this case the developer was using the normal IDE, but with the ESB tools plugin installed, wonder why id didn t include something to visually expose the service, or why it was not seen by the developer. JBoss SOA Platform Developer s Journal Page 12 of 51
New tools Tuesday, July 9 Time: 4 hours 1. After changing to the JBDS 7 with the SOA Tooling, I uploaded the project and found out a more graphical editor for the jboss-esb. 2. Here you can see the two services (service two was also done here). For the first service, I selected the action where I just select the class and then the process is the operation of the web service and also the method to call. JBoss SOA Platform Developer s Journal Page 13 of 51
POReservePartsService (common) Wednesday, July 10 Time: 4 hours The second service requires using a JMS queue to be asynchronous. I found many articles, and was also difficult to understand how JBoss works in this regard. The following video helped me a lot in building the second service: http://www.youtube.com/watch?v=tfguw0d-aao&nr=1&feature=endscreen The errors found was: DEPLOYMENTS IN ERROR: Deployment "vfsfile:/c:/ /MyESBProject.esb/" is in error due to the following reason(s): org.jboss.soa.esb.listeners.config.model.modelexception: Unsupported schema namespace: http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/ schemas/xml/jbossesb-1.3.1.xsd This was because I was used 1.3.1 and should use 1.0.1. 1. Then I created a first version of the second service on a new project. The problem was that when we do the integration, we should have everything in the same project. 2. To create it, had to add the following in the jboss-esb: <jms-provider name="jbossmq" connection-factory="connectionfactory"> <jms-bus busid="quickstartgwchannel"> <jms-message-filter dest-type="queue" dest-name="queue/quickstart_helloworld_request_gw" /> </jms-bus> <jms-bus busid="quickstartesbchannel"> <jms-message-filter dest-type="queue" dest-name="queue/quickstart_helloworld_request_esb" /> </jms-bus> </jms-provider> 3. The service remained as follows: <service category="secondserviceesb" name="simplelistener" description="second Service"> <listeners> <jms-listener name="jms-gateway" busidref="quickstartgwchannel" is-gateway="true" /> <jms-listener name="helloworld" busidref="quickstartesbchannel" /> </listeners> <actions mep="oneway"> <action name="action1" class="services.secondservicews" process="displaymessage" /> </actions> </service> JBoss SOA Platform Developer s Journal Page 14 of 51
4. The second service simulates pending completion of other processes, and return randomly generated approval code. 5. In http://localhost:8080/contract we can see the queue installed: 6. For testing, I create a Test_Client that it execute the service and return the following: 15:37:59,370 INFO [STDOUT] Process another messages... 15:38:04,370 INFO [STDOUT] <clientid>2324</clientid><orderallocationid>525</ orderallocationid><parts>part1, part2</parts> JBoss SOA Platform Developer s Journal Page 15 of 51
Second Bump and redo of the service Wednesday, July 10 Time: 4 hours 1. There was a problem deploying using the new tooling. For some reason, what worked before now throws: Deployment "vfsfile:/f:/jboss/jboss-soa-p-5/jboss-as/server/default/deploy/ FirstAndSecondServices.esb/" is in error due to the following reason(s): java.lang.classnotfoundexception: org.jboss.jms.server.destination.queueservice from BaseClassLoader@80c01f4{vfsfile:/F:/JBoss/jboss-soa-p-5/jboss-as/server/ default/deploy/firstandsecondservices.esb/}. So I think it is time to better redo some work using the new tooling. 2. The first thing I noticed is the new ESB file is now 1.3.1 (see the second service above), so I guess it is another version problem. 3. Creating the esb config was quite easy with add buttons and forms. JBoss SOA Platform Developer s Journal Page 16 of 51
4. Still, I got some problems as now the service does note deploy if the listener s is-gateway is true. Setting it as false indicates now that ERROR [ESBAwareGenerator] JbossRemoting listener only supported in Gateway mode. Anyhow, the service seems to be deployed and the contract and WSDL are readable. BTW, I changed the ports. POReserveParts second try Thursday, July 11 Time: 8 hours 1. Since I was using the new tooling, I tried to create the second service with the SOAPProcessor, so it can be changed later easily. For this, I need a regular web service, that only can be created in a dynamic web project. So, a new POReserveParts was created. 2. There I create a new Simple Web Service, named POReservePartsWS with POReservePartsWSImpl class. This will help as I need to create a complex Web Service supporting BOD (which is easier to work using WSDL first). 3. Next I need to upload the BOD. In doing so, I find out there is a problem with the schema. 4. It seems some of the includes are missing. Anyway, I used this to create a simple WSDL that accepted that ProcessPurchaseOrder element and returned a special ReserveParts schema. JBoss SOA Platform Developer s Journal Page 17 of 51
5. With that, now I can create a Web Service using the wizards, topdown. JBoss SOA Platform Developer s Journal Page 18 of 51
6. Note there is no indication of what transport will it use. Architect s Comment: This is the common web service generation tool. It is strictly for HTTP SOAP web services, so JMS services or the sort cannot be done here. Although this is a common tool, the need for a JMS transport web service should be provided somehow. 7. Problem. The actual service appears to be created and deployed. A new project was created as an EAR, but there is no sign of web service code. Anywhere. 8. Trying again, the same result. Will try to do that in a regular Eclipse. 9. No, the error is: IWAB0399E Error in generating Java from WSDL: java.lang.nullpointerexception at org.apache.axis.wsdl.tojava.javabeanhelperwriter.getasfieldname (JavaBeanHelperWriter.java:435) 10.That sounds a lot like a problem loading the BOD. Trying to do the same thing using a normal project with a simple WSDL passing Strings, it generated the code! When doing the same thing with the BOD, the code was not generated and no error was thrown. 11.So, we give up with the BOD in this case and we will create one special input XSD for this case. Architect s Comment: I may not blame the tool, as it seems the actual BOD schema was incomplete. JBoss SOA Platform Developer s Journal Page 19 of 51
Friday, July 12 Time: 6 hours 1. Trying to create the service with two custom XSDs gave the same problem: nothing generated. An annoying thing was I cannot delete a service once generated, there is no way to remove or change anything. Again, we created another dynamic web project and now we created a default WSDL (that comes with string as input and output) and it generated some code! Next thing I changed the operation name and since there was no refresh option, I had to create the service again. It warned me that the implementation classes where already there, but it did it, the new classes reflected the change. Now, I changed the request and response to my custom XSD and finally I got it to generate the code. Now I publish that and it appears listed in the web services console. 2. But that is a normal HTTP web Services. There is no option anywhere to create a service using JMS, so I would need to use the SOAPProcessor wrapper. 3. That is done easily in the JBoss ESB configuration. We need to add a JMS provider with two queues (one for gateway and the other one to communicate back to the esb), and then two listeners in the service. The action now is SOAPProducer JBoss SOA Platform Developer s Journal Page 20 of 51
4. Now, we need to create the queues. In all the examples the queues are created using JBossMQ, as I did in the first try. But with the SOA Platform, the HornetQ is used and JBossMQ is missing. There is not much about Hornet but the samples (QuickStarts) part had some guidance. Problem is it is not really explained, there are just lots of examples and code with no documentation explaining what to do. I tried using the helloworld one that has a JMS example, and added the hornetqjms.xml as indicated but still throw an error saying the queues do not exist. After some reading (where some indicate we need to add the queues in the server configuration) I tried to do that and since I had to shut down the server, I found out what we needed to do is to restart the server! No hot deploy on creation go queues. Architect s Comment: This seems to be a problem with the Hornet server, the failure to hot deploy the solution (not the queue). 5. Now, we do have both services in the contract. The JMS is exposed in ESB even when the backend is done using a normal web service. JBoss SOA Platform Developer s Journal Page 21 of 51
JBoss SOA Platform Developer s Journal Page 22 of 51
POPricingService (common) Friday, July 12 Time: 2 hours 1. Now I need to create a web service that consumes an OData service, and return the results via REST. First, I did a research about OData, and I found some interesting links: http://blog.concentra.co.uk/2013/02/04/understanding-odata/ http://msdn.microsoft.com/en-us/library/ff478141.aspx 2. After reading these articles, now I have a better idea about OData. I found a Java library, called odata4j (http://odata4j.org/), other one called Restlet (http:// restlet.org/), and another one called RESTEasy (http://www.jboss.org/resteasy). 3. I wanted to use the first one, but I had some troubles using it. As RESTEasy is one of the many JBoss projects, I must use it for my web service, but later I discover that odata4j was not compatible with it. So I decided to use the second approach, the Restlet library next week. Architect s Comment: This is a major issue to me, but I cannot blame JBoss as it seems the open source is the one that is not compatible with OData. In any case, the platform should provide a OData library or add the support to the open source. JBoss SOA Platform Developer s Journal Page 23 of 51
Monday, July 15 Time: 8 hours 1. I found a tutorial about accessing OData from Android devices using Restlet (http://weblogs.asp.net/uruit/archive/2011/09/13/accessing-odata-from-androidusing-restlet.aspx), and this tutorial also applies for Java. 2. As we don t have any OData service, I use one that is provided by the OData official website (http://www.odata.org/2012/05/odata-v3-demo-services/). As we can see, they provide one service only for read-only access, and other service for read-write access. I use the first one. The URL of this service is: http:// services.odata.org/odata/odata.svc/ 3. Using Restlet OData Generator, I m able to create a couple of Java classes, which allow me to access the information provided by the OData service. 4. So, after generate all this classes, I use them in my REST web service. Finally, when I call the REST service (http://localhost:8080/resteasyservices/ dateservice/getdate), it consumes the information in the OData service, and returns some of this information in a JSON object. 5. Now, I found out that is not what it was requested. I need an OData service of my own. Looking again in JBoss world I found that the Teiid project of virtual DataBases now supports OData4j, but it only works on version 8.x that needs JBoss 7.x (we are using 5.2). So, that does not work for us (http:// planet.jboss.org/post/odata_support_in_teiid). 6. Given that, there is NO way of creating an OData service on JBoss, we will need to create one and deploy it to a normal Tomcat. So, we installed one on port 9090 and created an app using a regular Eclipse. Testing will occur tomorrow. JBoss SOA Platform Developer s Journal Page 24 of 51
Tuesday, July 16 Time: 4 hours 1. We create a regular dynamic web application, add a class that implements de ODataProducerFactory and then use a InMemoryProducer to serialize a couple of java beans containing the product order header and lines (those are reused from another project). 2. Lastly, we only need to tell the app to serve our svc request (the OData requests) using our producer class: <!-- Servlet 1: Expose the OData service endpoint --> <servlet> <servlet-name>odata</servlet-name> <servlet-class>com.sun.jersey.spi.container.servlet.servletcontainer</ servlet-class> <init-param> <param-name>javax.ws.rs.application</param-name> <param-value>org.odata4j.jersey.producer.resources.odataapplication</ param-value> </init-param> <init-param> <param-name>odata4j.producerfactory</param-name> <param-value>com.appvance.services.priceproductorderfactory</paramvalue> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>odata</servlet-name> <url-pattern>/pporder.svc/*</url-pattern> </servlet-mapping> JBoss SOA Platform Developer s Journal Page 25 of 51
3. We create this in a Kepler Eclipse, generate the war and deploy it to Tomcat. The request and result looks like this: 4. Now we are ready to create the Business Process. JBoss SOA Platform Developer s Journal Page 26 of 51
5. Design Business Process Chapter Summary Important Issues: It seems there is a good communication and integration between jbpm and ESB. Still, it seems immature, maybe because of the old versions. The Asynchronous Call problem found here is serious. There should be a simple and surefire integration solution between the jbpm and the ESB, the two offered do not deliver or are deprecated. jbpm Tuesday, July 16 Time: 2 hours 1. First, I investigated how implement BPM with JBoss. The first approach, with a standalone JBDS, suggested to use a plugin. I found jbpm, a tool for implement BPM with jboss. I needed to install this on eclipse. In principle, we installed droolsjbpm, but had very little information on how to perform BPM with ESB. 2. Once I had the tooling for SOA Platform, all the tooling was there. I found the following video somehow helpful to begin the process, but it is confusing: http://www.youtube.com/watch?v=jfbeqhauocw JBoss SOA Platform Developer s Journal Page 27 of 51
Tuesday, July 16 Time: 2 hours 1. As shown in the video, I created a new ESB Project to hold the workflow. Then, in a BPMN folder, I create a jbpm process. 2. The look of the screen is not promising: there are too few items in the palette. 3. The components list of the SOA Platform (https://access.redhat.com/site/articles/ 111773) it is said that the jbpm version included is the 3.2.14, which is very old! 4. The available nodes include a special ESB Service that can be used to call the services that are exposed in the ESB. If the Web Service is an external one, then it gets complicated, as we need to create one node, add an action of type handler that will call a class, and in that class we can call the web service using plain Java. This is very flexible, but it also means we will need to transform XSD directly in code. 5. Additionally, looking on how to expose the process as a web services, it seems we need to create a regular web service and use the jbpm to load the process and execute it. JBoss SOA Platform Developer s Journal Page 28 of 51
6. In other words, most of the integration work is being done in the java code. It is time to look for another option. Architect s Comment: It seems jbpm alone will not deliver and it is meant for other kind of work, not integration. JBoss SOA Platform Developer s Journal Page 29 of 51
BPEL Wednesday, July 17 Time: 3 hours 1. The other option is to use BPEL. This language is closer to the web services and thus may be more helpful for the task at hand. 2. We start by creating a BPEL project and then adding a BPEL Process File. The wizards offer the option to build your file from a WSDL, which we accept. 3. Unfortunately, that didn t work. For some reason, the WSDL from the first service was not loading in the wizard (although it had defined ports, the wizard said it didn t). So, we started with a normal one. 4. We finally chose to use a pattern, but after looking at the BPEL options, we found out that although very easy to use to call regular web services, the JBoss SOA Platform Developer s Journal Page 30 of 51
transformations and such will be somehow difficult to achieve as there were no components made for that. Again, writing java code for specific tasks. 5. There is one third option to look after. Architect s Comment: BPEL is more for orchestration of web services, and not for integration. JBoss SOA Platform Developer s Journal Page 31 of 51
EBS and jbpm combination. Wednesday, July 17 Time: 5 hours 1. The ESB can be used to expose services, but also can be used to perform actions. The jbpm can call ESB services, which can be not only custom actions but also conversion tasks using Xpath (with smooks framework http:// www.smooks.org) and other things. 2. The first thing was to create a hello world jbpm and then execute it from ESB. In ESB we expose a web service that will execute the BpmProcessor action with a StartProcessInstanceCommand command. With that, we can start any jbpm process from ESB. 3. Sadly the first attempt did not work well. The ESB needs one service Endpoint as a gateway (Called from outside) and one from ESB (called from inside). This is because the external one needs to be wrapped as the internal ESB message. But the ESB seems to have a problem since long (https://community.jboss.org/ message/509027) where the actual EndPoint returns an error saying the EPR is not supported. No idea how to solve that. 4. After some time looking at it, it seems that we needed several things in place: the gateway should be a HTTP gateway, the ESB endpoint should be a JMS, and there should be a queue somename for it and another one somename_reply ending in the reply so it can be answered. 5. Next pain point was the jbpm. I thought that deploying a project with the jbpm in it will also deploy the process. I was wrong, we need to deploy it using a special deploy tab in the designer. The problem is: the deploy buttons are missing! JBoss SOA Platform Developer s Journal Page 32 of 51
6. It should be the SOA Tooling. Bad. 7. I had to perform some tricks. First, the POProcess.jpdl.xml file I had to rename it to processdefinition.xml, and then zip it into another file. That is because the only way is to deploy from console. In there, you should load a zip file containing the processdefinition.xml (with that exact name), plus all the other artifacts needed. Done that, the process appeared in the console, at last! It took me a long time. Architect s Comment: In one hand, we cannot blame the tool as it is a nightly build used in an unsupported version of JBDS, but on the other hand the platform should deliver the corresponding tooling, and it didn t do that. JBoss SOA Platform Developer s Journal Page 33 of 51
Calling the first service Thursday, July 18 Time: 5 hours 1. This was not an easy task, although it was easy to understand. The flow should simply use an ESB Service node to call the web service, and since it is an ESB exposed service, it was easy. 2. There I found out that calling the jbpm from ESB is an asynchronous call by design and that I will have problems to wait for the response after the whole cycle. I read a lot trying to find a way to make it synchronous but everyone advices against it. There was one option using a reply to original, kind of creating a callback, but that didn t work, the platform did not support that property. JBoss SOA Platform Developer s Journal Page 34 of 51
Calling the Second Service Thursday, July 18 Time: 2 hours 1. The call to the second service required first to adjust the XML. The output from POAllocation is different to the input for ReserveParts. Here, there is no component in jbpm to perform transformations, but there is in the ESB. So I created a new Service to do that. We just need to use a XSLT action. 2. The POA2RT is a xsl that will convert the output from POAllocation to the input of Reserve Parts. 3. We call that from the BPM. In the call to POAllocation, we mapped the result from ESB BODY_CONTENT to AllocationResponse. That is a variable in the jbpm context. We will pass that to the ESB BODY_CONTENT and get back the result in ReservePartResponse. JBoss SOA Platform Developer s Journal Page 35 of 51
Thursday, July 18 Time: 1 hours Friday, July 19 Time: 6 hours 1. This works nicely. But then, the problem of calling asynchronous services arises. Reading through the forums I could find several posts trying to deal with this: the nodes in the jbpm are executed in a sequence, to avoid the problems of multitasking and such (http://stackoverflow.com/questions/2044926/trueparallel-processing-in-jbpm). To avoid this only thread consuming the processor in long calls, the process is sent asynchronously. So, the call in each node is the fire out of execution of a task in another thread or server, and then an internal wait state for a callback to signal the node to continue. The problem with this is I couldn t find a way to fire a call and then wait for the answer in another node. The ESBNotifier is an action that is a fire and forget, you call it in a task during a transition. It is done in the transition so you are not in a state. When you enter the state, new things can happen, but I see no way to have the state waiting for the transaction to end (like waiting in for a message in a queue). There is no notion of that in the jbpm. 2. So, there is no out of the box, simple way of doing an asynchronous call. If you do your jbpm not modeling but using programming, there are tricks you can perform including adding things to databases and such. Not going into there. 3. But the first thing to do is to add a call to the service. Surprisingly, it didn t work! Even when calling directly the service endpoint indicated in the ESB exposed service, it says: java.lang.illegalargumentexception: Cannot create SOAP envelope from: {http://xmlns.oracle.com/bpm/bpmobject/ws/reservepartsws} ReservePartsWS. 4. After more than one hour trying to find the problem, there is no documentation or reference to something similar anywhere! The service is done using that xsd and the SOAPProcessor should simply create a SOAP message to consume it, but it does not throwing that error. Makes no sense, more if I use the same payload and call the service directly and it works. That means there is something in the SOAP wrapping implementation that is wrong. It seems I have to rewrite the services, again. Architect s Comment: This is not good. First that things created to do something cannot do it out of the box without much pain, and second the lack of reasonable errors we can search for a solution. JBoss SOA Platform Developer s Journal Page 36 of 51
Third rewrite of the Second Service. Friday, July 19 Time: 2 hours 1. We will do it the ESB way, creating a custom activity with the code in it. That completely gets to almost zero the integration capabilities of this tool. I have to create all the services IN the ESB to be able to call them. That simple call to an external services is no possible even with the specialized SOAPProcessor (it may be, makes no sense it is not, but I was not able with a simple service to replicate that simple tutorial). 2. The POReserveParts service then forgets about the SOAPProcessor and creates a new custom activity, just like in service one. It simply recreates a response using a string builder. 3. That was a very simple and easy thing to do, and it worked, sort of. For some reason, it performs the conversion of the XML but when printing the result it does that under ERROR indication in the log (21:30:04,471 ERROR [STDERR] After POReserve:). No idea why. I even replaced the activity with a simple XLS to do the conversion and same ERROR indication. Finally, I just printed the input twice, the first time it appears as INFO and the second one as ERROR. Totally nonsense. 4. BTW, the most annoying thing with this IDE is that any change that redeploys the ESB project, it will throw an error saying javax.jms.jmsexception: There is no queue with name queue/reserve_parts_request_gw, and you MUST RESTART THE WHOLE server to make it go away. Of course, the queue is there, defined, and found, but the redeploy misses it and then 3 minutes wasted restarting the server. We will take a look next week. JBoss SOA Platform Developer s Journal Page 37 of 51
Monday, July 23 Time: 8 hours 1. It seems that the ERROR in the log is actually important. It is not returning to the calling Node because it needs to have a return address for a fault. No idea what the fault is and no idea where to set that fault returning address. 2. The code here https://community.jboss.org/message/505715#505715 show a possible use of a queue for this, in the listener definition, with <fault-to desttype="queue" dest-name="csmfaultchannel"/> but the faul-to is not supported in this version. 3. Now, I set the server log to DEBUG. The amount of logs, particularly of the queue server that simply creates an entry for each check of the queues, is not letting me see anything (incredible amount of useless info). Still, I got the server log and digging into it I finally found the error: the callback command function fails with a java.lang.numberformatexception: null. Looking at that code in internet, the failiin line is : long tokenid = Long.parseLong( portref.getextensionvalue( Constants.TOKEN_ID )); That constant is defined as TOKEN_ID = "jbpmtokenid". Finally, looking at the values that the jbpm passes to the ESB, a couple of lines before in the log, I see <wsa:referenceproperties jbossesb:jbpmtokenid : 41/>,. 4. So, the value is there but the callback fails to capture it for some reason. All that is internal JBoss code that I m not supposed to be debugging! 5. Now, to be fair, the call back command is not in the tooling. I had to add it manually using a custom action (writing directly in the source <action class="org.jboss.soa.esb.services.jbpm.actions.jbpmcallback" name="callback"/ > ). So, the actual class exists and is being called, but it is not exposed in the tooling, that may mean it is not ready for production. If so, what am I supposed to use? 6. There are some blog posts saying I can use SignalCommand ( https:// access.redhat.com/site/documentation/en-us/jboss_enterprise_soa_platform/ 4.2/html-single/SOA_ESB_JBPM_Integration_Guide/index.html ), but in others it says that is removed in newer versions due to the info it needs ( https:// community.jboss.org/thread/144559 ). But, I m not using that version simply because the one incorporated in the Platform is an older one. 7. So, we can give it a try with the signalcommand, but before that I also want to note that I used two actual calls: the EsbActionHandler that is supposed to be used in synchronous calls (this adds the callback automatically) and the EsbNotifier that is used for asynchronous calls. The idea is that the EsbNotifier just calls and returns immediately, but the problem is that it has no way of indicating the mapping back from the ESB. That is, a true fire and forget. So, the idea of asynchronous call where you expect some value returned later on is not clearly defined in the tool. This is a delicate balance: the call should not expect a JBoss SOA Platform Developer s Journal Page 38 of 51
return, and the service actions MEP should be set to OneWay, but you can signal back with the Callback (that should take care of all automatically but is not working) or the SignalCommand (where you need to provide all the callback info) 8. Now, to try on the SignalCommand, we follow this tutorial: http://www.bpmguide.de/2008/06/12/jboss-jbpm-meets-esb/. It seems to do something similar to what we are trying to do, but it also implies some coding work. 9. It the code, I find something interesting: the author creates a correlating action that copies one attribute as an entry in the ESB message map, and I bet it is to make available to the SignalCommand (that, BTW, is not in the tooling either). The line in the custom action is this: message.getbody().add( Constants.TOKEN_ID, message.getproperties().getproperty("referenceid") ); 10.Will finish tomorrow. Architect s Comment: Important to note that there are examples that supposedly do what we need, but they do not work with our current version, either too old or too new. JBoss SOA Platform Developer s Journal Page 39 of 51
Tuesday, July 24 Time: 3 hours 1. Bad luck, trying to do that, the compiler complains Constants is missing. The blog code uses org.jboss.soa.esb.services.jbpm.constants but the compiler cannot find it! But since I already know that constant, I can use it directly: message.getbody().add( "jbpmtokenid", message.getproperties().getproperty("referenceid") ); 2. Ok, I tried using the CallBack but it didn t work, same error. When using SignalCommand I got: org.jboss.soa.esb.configurationexception: Attribute 'command' has an invalid value- see Constants.OpCode enum for possible values. That attribute is SignalCommand, which means it is really removed. 3. That leaves me with no option than calling the second service synchronously. JBoss SOA Platform Developer s Journal Page 40 of 51
Calling the Third Service Tuesday, July 24 Time: 5 hours 1. Leaving the ReserveParts, now I need a simple REST consumer client to call the third services. Bad news again: there is almost no single reference of how to do that. There is no special action in ESB nor any special node action in jbpm. There is much material on a special REST interface to manage jbpm from outside (like starting a process and such), but nothing executing REST services as a consumer. 2. The only reference is this (https://community.jboss.org/thread/177086), which points to jbpm 5.3 that we don t have, and depicting a solution I was foreseeing: you need to create a custom action to call java code that consumes your service. So, no out of the box functionality for this. We need to start creating a simple client then. 3. If you want to use jbpm directly, you can use an action of type Handler. That will allow you to select a class that should be called. The problem here is I had no idea of how to create that class. Remember I had to deploy the process manually zipping it? I have no idea of how to create a jar and make it available to the process. So, I will skip trying to do that. Since we are using ESB for all the other calls, I will follow the same path here: one ESB service that calls a custom action that is my actual client. 4. This is a simple code, using a normal URLConnection. @Process public Message process(message message) { URL url; StringBuffer buffer = new StringBuffer(); try { // get URL content String authstring = "admin:admin"; byte[] authencbytes = Base64.encodeBase64(authString.getBytes()); String authstringenc = new String(authEncBytes); // gets the Product Order Lines Collection. No Navigation implemented url = new URL( "http://localhost:9090/priceposervice/pporder.svc/ ProductOrderLines"); URLConnection conn = url.openconnection(); conn.setrequestproperty("authorization", "Basic " + authstringenc); // open the stream and put it into BufferedReader BufferedReader br = new BufferedReader( new InputStreamReader(conn.getInputStream())); String inputline; while ((inputline = br.readline())!= null) { buffer.append(inputline); } JBoss SOA Platform Developer s Journal Page 41 of 51
5. As simple as that: call the service with a get. We are skipping the extraction of the Message body, parsing of XML, calling the OData service with some parameters to get something, as that would be just Java coding and no integration testing of the Platform. Architect s Comment: Adding the possibility to use code directly give much flexibility, but then it tool should also give the canned code to just use common functionality without needed to code it in java. JBoss SOA Platform Developer s Journal Page 42 of 51
6. Making Changes Chapter Summary Important Issues: HTTPs is rather complex to set up as the certificates should live in the application itself! The lack of easy to configure endpoint, or controlling the auto exposure of web services, gives a lot of trouble in changing and maintaining the services. If you cannot expose a HTTPS service from ESB, you are adding a security flaw as there is a segment (from the client to the ESB) that is not protected. Adding Security to Service One Wednesday, July 25 Time: 8 hours 1. The first change is to add HTTPS support to service one. That means changing the protocol in the service we created. Since that was a simple service in the ESB, we just need to add a new provider that supports HTTPS. In fact, it is the same JBR HTTP providers just that we change the protocol. 2. But, we still need to setup security. The SOA Platform has no connector in SSL installed, we need to create the keystore. We do that using keytool, and now we have JBoss with a 8443 port secured. JBoss SOA Platform Developer s Journal Page 43 of 51
3. Still, that does not help with our service. There is an error saying the keystore url was not found. Looking in internet I find this quickstart (http://code.google.com/ p/thompsen/source/browse/trunk/quickstarts/https_2way_ssl/?r=431) from where I learn by reviewing the code (no article or explanation), that there are other parameters and that the keystore should be included in the esbcontent directory of the application. 4. The parameters for the provider will look like this: <jbr-provider name="ppojbrhttpsprovide" protocol="https"> <property name="jbr-keystoreurl" value="localhost.keystore" /> <property name="jbr-keystorepassword" value="123456" /> <property name="jbr-truststoreurl" value=" localhost.keystore" /> <property name="jbr-truststorepassword" value="123456" /> <property name="serviceinvokertimeout" value="20000" /> <jbr-bus busid="ppojbrhttps" port="8098"/> </jbr-provider> 5. Still, we had some problems. The deployment of this with the same port as the regular HTTPS (8443), gave some problems and the contract page was not displayed. Changing the port fixed that thing, but the contract now shows this: 6. First, the HTTP endpoint was removed, so it should not appear there! Second, the HTTPS endpoint is missing! So, I still have the same WSDL. The reason may be simple: the HTTP listener does not affect the publication of the service! Even when the HTTP provider is set to port 8099, the ESB publishes the web service through 8080/POServices/ebws. 7. Testing directly with https://localhost:8098, there is an error from JmsComposer. That means something simple: those http listener are exposing the ESB queues access, not a SOAP service. That was a similar problem indicated here: https:// community.jboss.org/message/604664. 8. There is a tip there: use an HTTP Gateway. Let s try it. I add a HTTP Gateway and also indicate that the transport should be confidential. JBoss SOA Platform Developer s Journal Page 44 of 51
9. Unfortunately, the same thing happened: the actual exposure of the web service is not, somehow, affected by the HTTP listeners, or the providers. If there is no listener, there is no WSDL. If you add one of them in gateway mode, the WSDL will appear but under 8080. That means, it seems there is no way I can find to turn that into a secured service. 10.This took me all day, basically trying to figure out the WSDL publication algorithm. Wasted time. Architect s Comment: Mentioned before: no possibility of controlling the actual exposure of services. That is not acceptable. JBoss SOA Platform Developer s Journal Page 45 of 51
Friday, July 26 Time: 8 hours 1. Now, we still have a problem here. The jbpm calls the ESB using the internal messaging system. That is, the call from the jbpm will enter through the JMS, and not through the HTTPS (or HTTP in this case). 2. Again, there is no way to call the external HTTP Web Service using the JBPM, but there is a client in the ESB (actually, we can also use SOAPProducer, but it didn t work, remember?). Let s try at least that one. 3. The first thing to do was to create another workflow. I copied the one we had and named V2. Now, we need another starter. And there we had a problem: making another starter service in ESB was quite easy (just copy), but it would not display any service WSDL URL! 4. I tried all that I can think of, even creating new gateways, queues and all. That service did not want to be exposed. So, I have a second workflow but no way to start it. 5. To continue using the second process, I changed the original starter to start the second process. 6. Made a copy of the POServices, since the ESB is part of this workflow. I would need to change a couple of the services. I had some problems deploying as I had to recreate all the queues, and then remove the SSL MBean as it was duplicated, etc. Will continue Monday. JBoss SOA Platform Developer s Journal Page 46 of 51
Monday, July 30 Time: 6 hours 1. Finally, we are ready to add the call to the Web Service. Since we have a POAllocation WS in services V1, in the new V2, in the second one instead of calling a custom action I will call the V1 service, just like calling any regular WS. For that I use this: <action name="soapui-client-action" class="org.jboss.soa.esb.actions.soap.soapclient"> <property name="wsdl" value="http://localhost:8080/pposervices/ebws/pposervices/ POAllocationService?wsdl" /> <!-- <property name="paramslocation" value="ws-parameter"/> maybe doesn't work because of Bug JBESB1409 --> <property name="operation" value="poallocationserviceop" /> <property name="responseasognlmap" value="true" /> <property name="soapaction" value= "http://soa.jboss.org/pposervices/ POAllocationServiceOp" /> </action> 2. This SOAPClient is used in the blog post above to call an external web service. Not really sure how it does the mapping of the message to the call payload, but I assume that anything in BODY_CONTENT will be passed as payload in the SOAP package. 3. Again, it does not work. It gets up to the call of the service but nothing else is shown, not even an error. The next message indicates that nothing was returned to the workflow as the next variable comes in null. Turning on the debug mode (which floods with queue messages) I can see: ActionProcessingException: Invalid payload type in message body location 'org.jboss.soa.esb.message.defaultentry'. Expected 'java.util.map', was 'java.lang.string'. So, it seems I have to do something before. 4. Following the tutorial, the parameters in the service are set in a map with the operation name. That is, a map with a key called POAllocationServiceOp in our case. Following the example, that is just a qualification of the key name, the second part is the actual parameter name. I assume it is the message name, so the key is POAllocationServiceOp.POAllocationServiceReq. I create then a custom activity to put that in the message, like this: public Message process(message m) { HashMap parameters = new HashMap(); parameters.put("poallocationserviceop.poallocationservicereq", m.getbody().get()); } m.getbody().add( parameters ); return m; 5. That will put that HashMap as the default entry in the message with an entry that is the current message s default entry. Let s see how it works. 6. The call was made successfully, but with one problem: the response was packed as a hashmap and not as a XML. I guess it is this line s fault: <property name="responseasognlmap" value="true" /> JBoss SOA Platform Developer s Journal Page 47 of 51
7. Setting that to false, I get a different body, a SOAP Message! body: [ objects: {org.jboss.soa.esb.message.defaultentry=<env:envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'> <env:header></env:header><env:body> <p:allocateporesponsetype xmlns:p='http://xmlns.oracle.com/bpm/bpmobject/wstypes/ AllocatePOResponseType' xmlns:xsi='http://www.w3.org/2001/xmlschema-instance' xsi:schemalocation='http://xmlns.oracle.com/bpm/bpmobject/wstypes/ AllocatePOResponseType AllocatePOResponseType.xsd '> <p:orderallocationid>0</p:orderallocationid> <p:purchaseorderid>0</p:purchaseorderid> <p:allocateresponsedate>thu Aug 01 14:52:01 UTC 2013</p:allocateResponseDate> <p:status>true</p:status> </p:allocateporesponsetype></env:body></env:envelope>} ] 8. Ok, this client performs the call, but leaves in the message the full SOAP response! This makes no sense at all, for a client that is supposed to make the SOAP envelope transparent! 9. The next step is the transformation, and since it is a XSLT it will work through the SOAP Envelope, but that shouldn t happen. Architect s Comment: This simple call to a service is cumbersome, overly complicated and flawed. How come the developer should prepare the payload for the call, and the response is not parsed out and left with the SOAP envelope? JBoss SOA Platform Developer s Journal Page 48 of 51
Second Change: from JMS to REST. Monday, July 30 Time: 1 hours 1. Time is going away and the actual change here is to make an external REST service (as there is no REST exposure in the ESB), and then call it using the URLConnection as before. 2. This particular change would be quick to do but almost not using any of the tool features but custom actions. Architect s Comment: The decision to leave this out is due to the irrelevance to the study. JBoss SOA Platform Developer s Journal Page 49 of 51
7. Versioning Tuesday, July 31 Time: 5 hours 1. Current uploaded workflows are kept in versions, but there is no clear or documented way of selecting one version over the other one. In this case, the workflow version has no meaning as the heavy lifting is done in the ESB, and we talked about the duplication effort earlier on. 2. Now, the versioning where different payloads are to be directed to different workflow (or different starter services in this case), to make changes, is done using the ContentBasedRouter. This is a simple thing to do and what we are going to use it is to create a XSD with an optional parameter that will be tested and with that we will send that XML to a transformer before going into the workflow. 3. Notice that this is not an evaluation in the jbpm but in the ESB. 4. Reading (https://access.redhat.com/site/documentation/en-us/ JBoss_Enterprise_SOA_Platform/4.2/html/SOA_ESB_Content_Based_Routing) to learn how to use the routers. It seems we can use simple XPath. 5. To make it simple, we are going to use the status value in the incoming XML. It will route it based on the value, if 1 then go to workflow 1, if 2 then to workflow 2. I can then replace the actual call to start process in the workflow started service with the router code, and create another service with V1 to be called when the status is 1. This is the router code: <action class="org.jboss.soa.esb.actions.contentbasedrouter" name="contentbasedrouter"> <property name="cbralias" value="xpath"/> <property name="destinations"> <namespace prefix="ppur" uri="http://xmlns.oracle.com/bpm/bpmobject/pricepurchaseorder/ppurchaserorderws" /> <route-to service-category="workflow" service-name="poworkflowstarterv1" expression="//ppur:status/text()=1" /> <route-to service-category="workflow" service-name="poworkflowstarterv2" expression="//ppur:status/text()=2" /> </property> </action> JBoss SOA Platform Developer s Journal Page 50 of 51
6. And this is the new service diagram: 7. Note that POWorkflowStarter is now a router and there are POWorkflowStarterV1 and POWorkflowStarterV2, each will start a different workflow. At least this works. Architect s Comment: This routing part really worked well. We didn t test all the options though, but it looked very powerful. 8. Conclusions 1. This tool is clumsy and you really need to know what is happening and how to tweak things to make it work. That, for productivity, is a very negative thing. 2. I m amazed the tool in the commercial platform comes with a so old version of everything. An update is mandatory. 3. Although there are many quickstarts showing how to do things, changing them to make them suitable for our needs breaks them, and you cannot actually learn a lot without explanation. That is, you are forced to learn by reading the code. 4. In particular, jbpm may be good for human and business workflows, but it is not suitable for integration, at all. On the other hand, ESB seems to be more oriented to that integration, but lacks ease of use and more integration options (not having REST support, like consuming WADL and such, is a big minus nowadays). JBoss SOA Platform Developer s Journal Page 51 of 51