<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
   <title>SOA Thinker</title>
   <link rel="alternate" type="text/html" href="http://blogs.oracle.com/jeffdavies/" />
   <link rel="self" type="application/atom+xml" href="http://blogs.oracle.com/jeffdavies/xml/rss.xml" />
   <id>tag:blogs.oracle.com,2009:/jeffdavies//422</id>
   <updated>2009-10-01T16:43:07Z</updated>
   <subtitle>A site for SOA thought and discussion.</subtitle>
   <generator uri="http://www.sixapart.com/movabletype/">Movable Type Enterprise 4.23-en</generator>


<entry>
   <title>Using a Converter Class in OSB</title>
   <link rel="alternate" type="text/html" href="http://blogs.oracle.com/jeffdavies/2009/10/using_a_converter_class_in_osb.html" />
   <id>tag:blogs.oracle.com,2009:/jeffdavies//422.14695</id>
   
   <published>2009-10-01T16:28:31Z</published>
   <updated>2009-10-01T16:43:07Z</updated>
   
   <summary>Converter Classes A reader of my book recently asked about using a converter class within the Oracle Service Bus. A converter class is used to help convert data types that cannot automatically be converted using the JAX RPC engine that...</summary>
   <author>
      <name>jeff.x.davies</name>
      
   </author>
   
      <category term="Developer" scheme="http://www.sixapart.com/ns/types#category" />
   
      <category term="SOA" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="converterosboracleservicebus" label="Converter OSB Oracle Service Bus" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="en" xml:base="http://blogs.oracle.com/jeffdavies/">
      <![CDATA[<h1>Converter Classes</h1>
<p>A reader of my book recently asked about using a converter class within the Oracle Service Bus. A converter class is used to help convert data types
that cannot automatically be converted using the JAX RPC engine that ships with OSB. Usually, data conversion between an EJB and OSB is done for you in OSB. However, when dealing with EJBs there are times when automatic conversion is simply not possible. For example, if the EJB returns any of the following, the JAX RPC engine will not
be able to infer the true type being returned:</p>
<p>
<ul>
   <li>java.lang.Object</li>
   <li>java.lang.Object[]</li>
   <li>Java Collections that are not strongly typed</li>
   <li>Java classes that do not follow JavaBean conventions (like the Map class)</li>
</ul>
</p>
<p>The OSB converter class is designed to help you deal with just such return values from an EJB. For our example, we will create an EJB that returns a
java.util.List of customers from a method named getCustomerList(). Since the List is not parameterized, there is no way for OSB to know what the List contains. However,
as developers with access to the code, we know that the List object returned contains Customer objects. So our task is to create a JAR file that converts the List
into an array of Customer objects. You can see the definition of a Customer object in Listing 1.
</p>
<p>Listing 2 shows the rather simple EBJ that we are using. The SampleEJB session bean has a single operation (other than the ejbCreate()): 
<font color="#7f0055"><b>public&nbsp;</b></font><font color="#000000">List&nbsp;getCustomerList</font><font color="#000000">()&nbsp;{</font>. Since the
List return value is not parameterized, the JAX-RPC engine has no idea what the data type is in the List. In the sample code included with this blog, look 
in the SampleEJB project for the details on how the EJB is project is put together. You deploy the SampleEJB project to the WebLogic Server using the normal process.</p>

<p>Also in the sample code you will see the ConverterClass project. This is the project that should answer the most common questions on creating a converter class.
Listing 3 shows the code to the converter class. The important things to remember about the converter class are:</p>
<ul>
	<li>It must implement the com.bea.wli.sb.transports.ejb.ITypeConverter interface. This interface resides in the sb-kernel-api.jar file which is found in the osb_10.3\lib directory of your OSB installation.</li>
	<li>As per the ITypeConverter interface definition, the converter class must have a public static method named convert. The return value of this method may be any type at all, but the arguments to the method
	must be an Object, Object[], Collection, List, Map, etc. Note that you cannot use an ArrayList as an argument. I tried this at first and it simply did not work. While the converter class
	compiled just fine using the ArrayLlist as an argument, later on OSB did not recongize the convert(ArrayLlist) operation as being valid.</li>
</ul>

<p>To make life easy, I also copied and pasted the Customer class (Listing 1) from the SammpleEJB project into the ConverterClass project, keeping the same package name.
Converter classes are deployed as JAR files, so right-click on the ConverterClass project and export it as a jar. At this point it should be clear how you make a 
converter class. Our next step is to get everything plugged into Oracle Service bus so we can use it when calling the EJB.</p>

<p>In the OSB_Config configuration project you will find the EJBConverter project. This  project contains a single business service called EJBService.biz. However, you will also
notice that it contains a folder called JAR and in that folder you will find both the CustomerConverter.jar file (that contain the ConverterClass project compiled into a JAR) and the
SampleEJB.jar file. OSB really only needs the client JAR for an EJB, but the project was so trivial I decided to use the original EJB JAR file to keep things simple.</p>

<p>Configuring the EJBService.biz business service you define it as a Transport Typed Service in the General configuration tab. This is shown in Figure 1, below.</p>
<p>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blogs.oracle.com/jeffdavies/assets_c/2009/10/figure1-1470.html" onclick="window.open('http://blogs.oracle.com/jeffdavies/assets_c/2009/10/figure1-1470.html','popup','width=973,height=360,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://blogs.oracle.com/jeffdavies/assets_c/2009/10/figure1-thumb-740x273-1470.jpg" width="740" height="273" alt="figure1.jpg" class="mt-image-left" style="float: left; margin: 0 20px 20px 0;" /></a></span>
<br />
   <b>Figure 1. The General tab of the business service.</b>
<p>  

<p>The next tab to configure is the Transport tab. On this tab you start by selecting EJB as the protocol. You can leave the load balancing
algorithm as the default (round-robin) for our purposes here. Next, you need to specify the Endpoint URI. Since we are running this code on a single
developer machine, we will use a pretty simple endpoint URI of ejb::ejb.SampleEJBRemoteHome. The endpoint is made up of 3 parts:</p>
<p><b><code>[protocol]:[provider]:[jndi_name]</code></b></p>

<p>For EJBs, the <code>[protocol]</code> will always be <code>ejb</code>. We leave the provider blank because we are calling this EJB on our local machine. 
The <code>[jndi_name]</code> is defined in Listing 2 by the <code>@JndiName()</code> attribute as <code>ejb.SampleEJBRemoteHome</code>. Once you have that endpoint URI
in the list of endpoints, as shown in figure 2, you can move onto the next tab: EJB Transport.</p>

<p>
   <span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blogs.oracle.com/jeffdavies/assets_c/2009/10/figure2-1471.html" onclick="window.open('http://blogs.oracle.com/jeffdavies/assets_c/2009/10/figure2-1471.html','popup','width=973,height=429,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://blogs.oracle.com/jeffdavies/assets_c/2009/10/figure2-thumb-740x326-1471.jpg" width="740" height="326" alt="figure2.jpg" class="mt-image-left" style="float: left; margin: 0 20px 20px 0;" /></a></span> <br />
   <b>Figure 2. The Transport tab of the business service.</b>
<p>  

<p>Configuring the EJB transport (figure 3) is straightforward. You start by selecting the client jar for the EJB, which is in the JAR/ folder of our OSB project. 
You need to use the associated <code>Browse</code> button to select the correct JAR file. You will need to select the Converter Jar the same way. With those two 
JAR files selected, fill in the rest of the form as shown in figure 3.
</p>

<p>
   <span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blogs.oracle.com/jeffdavies/assets_c/2009/10/figure3-1472.html" onclick="window.open('http://blogs.oracle.com/jeffdavies/assets_c/2009/10/figure3-1472.html','popup','width=983,height=674,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://blogs.oracle.com/jeffdavies/assets_c/2009/10/figure3-thumb-740x507-1472.jpg" width="740" height="507" alt="figure3.jpg" class="mt-image-left" style="float: left; margin: 0 20px 20px 0;" /></a></span> <br />
   <b>Figure 3. The EJB Transport tab of the business service.</b>
<p> 

<p><b>NOTE:</b> If you did not define the convert() method in the ConverterClass as accepting an <code>.Object, Object[], Collection, List, Map</code>code>, etc. as the argument then
the Converter drop-down will not appear.</p>

<h2>Listings</h2>

<p><b>Listing 1 - The Customer Class</b><br />
<!-- ======================================================== -->
<!-- = Java Sourcecode to HTML automatically converted code = -->
<!-- =   Java2Html Converter 5.0 [2006-03-04] by Markus Gebhard  markus@jave.de   = -->
<!-- =     Further information: http://www.java2html.de     = -->
<div align="left" class="java">
<table border="0" cellpadding="3" cellspacing="0" bgcolor="#ffffff">
   <tr>
  <!-- start source code -->
   <td nowrap="nowrap" valign="top" align="left">
    <code>
<font color="#7f0055"><b>package&nbsp;</b></font><font color="#000000">com.oracle.ejb;</font><br />
<font color="#ffffff"></font><br />
<font color="#7f0055"><b>import&nbsp;</b></font><font color="#000000">java.io.Serializable;</font><br />
<font color="#ffffff"></font><br />
<font color="#7f0055"><b>public&nbsp;class&nbsp;</b></font><font color="#000000">Customer&nbsp;</font><font color="#7f0055"><b>implements&nbsp;</b></font><font color="#000000">Serializable&nbsp;</font><font color="#000000">{</font><br />
<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>private&nbsp;</b></font><font color="#7f0055"><b>int&nbsp;</b></font><font color="#000000">id;</font><br />
<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>private&nbsp;</b></font><font color="#000000">String&nbsp;firstName;</font><br />
<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>private&nbsp;</b></font><font color="#000000">String&nbsp;lastName;</font><br />
<font color="#ffffff">&nbsp;&nbsp;</font><br />
<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>public&nbsp;</b></font><font color="#000000">Customer</font><font color="#000000">(</font><font color="#7f0055"><b>int&nbsp;</b></font><font color="#000000">theID,&nbsp;String&nbsp;first,&nbsp;String&nbsp;last</font><font color="#000000">)&nbsp;{</font><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>this</b></font><font color="#000000">.id&nbsp;=&nbsp;theID;</font><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>this</b></font><font color="#000000">.firstName&nbsp;=&nbsp;first;</font><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>this</b></font><font color="#000000">.lastName&nbsp;=&nbsp;last;</font><br />
<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">}</font><br />
<font color="#ffffff">&nbsp;&nbsp;</font><br />
<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>public&nbsp;</b></font><font color="#7f0055"><b>int&nbsp;</b></font><font color="#000000">getId</font><font color="#000000">()&nbsp;{&nbsp;</font><font color="#7f0055"><b>return&nbsp;</b></font><font color="#000000">id;</font><font color="#000000">}</font><br />
<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>public&nbsp;</b></font><font color="#7f0055"><b>void&nbsp;</b></font><font color="#000000">setId</font><font color="#000000">(</font><font color="#7f0055"><b>int&nbsp;</b></font><font color="#000000">id</font><font color="#000000">)&nbsp;{&nbsp;</font><font color="#7f0055"><b>this</b></font><font color="#000000">.id&nbsp;=&nbsp;id;&nbsp;</font><font color="#000000">}</font><br />
<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>public&nbsp;</b></font><font color="#000000">String&nbsp;getFirstName</font><font color="#000000">()&nbsp;{&nbsp;</font><font color="#7f0055"><b>return&nbsp;</b></font><font color="#000000">firstName;&nbsp;</font><font color="#000000">}</font><br />
<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>public&nbsp;</b></font><font color="#7f0055"><b>void&nbsp;</b></font><font color="#000000">setFirstName</font><font color="#000000">(</font><font color="#000000">String&nbsp;firstName</font><font color="#000000">)&nbsp;{&nbsp;</font><font color="#7f0055"><b>this</b></font><font color="#000000">.firstName&nbsp;=&nbsp;firstName;</font><font color="#000000">}</font><br />
<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>public&nbsp;</b></font><font color="#000000">String&nbsp;getLastName</font><font color="#000000">()&nbsp;{&nbsp;</font><font color="#7f0055"><b>return&nbsp;</b></font><font color="#000000">lastName;&nbsp;</font><font color="#000000">}</font><br />
<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>public&nbsp;</b></font><font color="#7f0055"><b>void&nbsp;</b></font><font color="#000000">setLastName</font><font color="#000000">(</font><font color="#000000">String&nbsp;lastName</font><font color="#000000">)&nbsp;{&nbsp;</font><font color="#7f0055"><b>this</b></font><font color="#000000">.lastName&nbsp;=&nbsp;lastName;</font><font color="#000000">}</font><br />
<font color="#000000">}</font></code>
    
   </td>
  <!-- end source code -->
   </tr>
  <!-- start Java2Html link -->
   <tr>
    <td align="right">
<small>
<a href="http://www.java2html.de" target="_blank">Java2html</a>
</small>
    </td>
   </tr>
  <!-- end Java2Html link -->
</table>
</div>
<!-- =       END of automatically generated HTML code       = -->
<!-- ======================================================== -->
</p>

<p><b>Listing 2 - SampleEJB Session Bean</b><br />
<!-- ======================================================== -->
<!-- = Java Sourcecode to HTML automatically converted code = -->
<!-- =   Java2Html Converter 5.0 [2006-03-04] by Markus Gebhard  markus@jave.de   = -->
<!-- =     Further information: http://www.java2html.de     = -->
<div align="left" class="java">
<table border="0" cellpadding="3" cellspacing="0" bgcolor="#ffffff">
   <tr>
  <!-- start source code -->
   <td nowrap="nowrap" valign="top" align="left">
    <code>
<font color="#7f0055"><b>package&nbsp;</b></font><font color="#000000">com.oracle.ejb;</font><br />
<font color="#ffffff"></font><br />
<font color="#7f0055"><b>import&nbsp;</b></font><font color="#000000">java.util.ArrayList;</font><br />
<font color="#7f0055"><b>import&nbsp;</b></font><font color="#000000">java.util.List;</font><br />
<font color="#7f0055"><b>import&nbsp;</b></font><font color="#000000">javax.ejb.SessionBean;</font><br />
<font color="#7f0055"><b>import&nbsp;</b></font><font color="#000000">weblogic.ejb.GenericSessionBean;</font><br />
<font color="#7f0055"><b>import&nbsp;</b></font><font color="#000000">weblogic.ejbgen.Session;</font><br />
<font color="#7f0055"><b>import&nbsp;</b></font><font color="#000000">weblogic.ejbgen.JndiName;</font><br />
<font color="#7f0055"><b>import&nbsp;</b></font><font color="#000000">weblogic.ejbgen.FileGeneration;</font><br />
<font color="#7f0055"><b>import&nbsp;</b></font><font color="#000000">weblogic.ejbgen.Constants;</font><br />
<font color="#7f0055"><b>import&nbsp;</b></font><font color="#000000">weblogic.ejbgen.RemoteMethod;</font><br />
<font color="#ffffff"></font><br />
<font color="#3f5fbf">/**</font><br />
<font color="#ffffff">&nbsp;</font><font color="#3f5fbf">*&nbsp;GenericSessionBean&nbsp;subclass&nbsp;automatically&nbsp;generated&nbsp;by&nbsp;Workshop.</font><br />
<font color="#ffffff">&nbsp;</font><font color="#3f5fbf">*</font><br />
<font color="#ffffff">&nbsp;</font><font color="#3f5fbf">*&nbsp;Please&nbsp;complete&nbsp;the&nbsp;ejbCreate&nbsp;method&nbsp;as&nbsp;needed&nbsp;to&nbsp;properly&nbsp;initialize&nbsp;new&nbsp;instances&nbsp;of&nbsp;your&nbsp;bean&nbsp;and&nbsp;add</font><br />
<font color="#ffffff">&nbsp;</font><font color="#3f5fbf">*&nbsp;all&nbsp;required&nbsp;business&nbsp;methods.&nbsp;Also,&nbsp;review&nbsp;the&nbsp;Session,&nbsp;JndiName&nbsp;and&nbsp;FileGeneration&nbsp;annotations&nbsp;</font><br />
<font color="#ffffff">&nbsp;</font><font color="#3f5fbf">*&nbsp;to&nbsp;ensure&nbsp;the&nbsp;settings&nbsp;match&nbsp;the&nbsp;bean's&nbsp;intended&nbsp;use.</font><br />
<font color="#ffffff">&nbsp;</font><font color="#3f5fbf">*/</font><br />
<font color="#646464">@Session</font><font color="#000000">(</font><font color="#000000">ejbName&nbsp;=&nbsp;</font><font color="#2a00ff">&#34;SampleEJB&#34;</font><font color="#000000">)</font><br />
<font color="#646464">@JndiName</font><font color="#000000">(</font><font color="#000000">remote&nbsp;=&nbsp;</font><font color="#2a00ff">&#34;ejb.SampleEJBRemoteHome&#34;</font><font color="#000000">)</font><br />
<font color="#646464">@FileGeneration</font><font color="#000000">(</font><font color="#000000">remoteClass&nbsp;=&nbsp;Constants.Bool.TRUE,&nbsp;remoteHome&nbsp;=&nbsp;Constants.Bool.TRUE,&nbsp;localClass&nbsp;=&nbsp;Constants.Bool.FALSE,&nbsp;localHome&nbsp;=&nbsp;Constants.Bool.FALSE</font><font color="#000000">)</font><br />
<font color="#7f0055"><b>public&nbsp;class&nbsp;</b></font><font color="#000000">SampleEJB&nbsp;</font><font color="#7f0055"><b>extends&nbsp;</b></font><font color="#000000">GenericSessionBean&nbsp;</font><font color="#7f0055"><b>implements&nbsp;</b></font><font color="#000000">SessionBean&nbsp;</font><font color="#000000">{</font><br />
<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>private&nbsp;static&nbsp;final&nbsp;</b></font><font color="#7f0055"><b>long&nbsp;</b></font><font color="#000000">serialVersionUID&nbsp;=&nbsp;</font><font color="#990000">1L</font><font color="#000000">;</font><br />
<font color="#ffffff"></font><br />
<font color="#ffffff">&nbsp;&nbsp;</font><font color="#3f7f5f">/*&nbsp;(non-Javadoc)</font><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;</font><font color="#3f7f5f">*&nbsp;@see&nbsp;weblogic.ejb.GenericSessionBean#ejbCreate()</font><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;</font><font color="#3f7f5f">*/</font><br />
<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>public&nbsp;</b></font><font color="#7f0055"><b>void&nbsp;</b></font><font color="#000000">ejbCreate</font><font color="#000000">()&nbsp;{</font><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f7f5f">//&nbsp;IMPORTANT:&nbsp;Add&nbsp;your&nbsp;code&nbsp;here</font><br />
<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">}</font><br />
<font color="#ffffff"></font><br />
<font color="#ffffff">&nbsp;&nbsp;</font><font color="#3f7f5f">//&nbsp;IMPORTANT:&nbsp;Add&nbsp;business&nbsp;methods</font><br />
<font color="#ffffff">&nbsp;&nbsp;</font><font color="#646464">@RemoteMethod</font><font color="#000000">(</font><font color="#000000">transactionAttribute=Constants.TransactionAttribute.SUPPORTS</font><font color="#000000">)</font><br />
<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>public&nbsp;</b></font><font color="#000000">List&nbsp;getCustomerList</font><font color="#000000">()&nbsp;{</font><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">ArrayList&nbsp;customerList&nbsp;=&nbsp;</font><font color="#7f0055"><b>new&nbsp;</b></font><font color="#000000">ArrayList</font><font color="#000000">()</font><font color="#000000">;</font><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">customerList.add</font><font color="#000000">(</font><font color="#7f0055"><b>new&nbsp;</b></font><font color="#000000">Customer</font><font color="#000000">(</font><font color="#990000">1</font><font color="#000000">,&nbsp;</font><font color="#2a00ff">&#34;Jack&#34;</font><font color="#000000">,&nbsp;</font><font color="#2a00ff">&#34;Benny&#34;</font><font color="#000000">))</font><font color="#000000">;</font><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">customerList.add</font><font color="#000000">(</font><font color="#7f0055"><b>new&nbsp;</b></font><font color="#000000">Customer</font><font color="#000000">(</font><font color="#990000">2</font><font color="#000000">,&nbsp;</font><font color="#2a00ff">&#34;Lucille&#34;</font><font color="#000000">,&nbsp;</font><font color="#2a00ff">&#34;Ball&#34;</font><font color="#000000">))</font><font color="#000000">;</font><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">customerList.add</font><font color="#000000">(</font><font color="#7f0055"><b>new&nbsp;</b></font><font color="#000000">Customer</font><font color="#000000">(</font><font color="#990000">3</font><font color="#000000">,&nbsp;</font><font color="#2a00ff">&#34;Bob&#34;</font><font color="#000000">,&nbsp;</font><font color="#2a00ff">&#34;Hope&#34;</font><font color="#000000">))</font><font color="#000000">;</font><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>return&nbsp;</b></font><font color="#000000">customerList;</font><br />
<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">}</font><br />
<font color="#000000">}</font></code>
    
   </td>
  <!-- end source code -->
   </tr>
  <!-- start Java2Html link -->
   <tr>
    <td align="right">
<small>
<a href="http://www.java2html.de" target="_blank">Java2html</a>
</small>
    </td>
   </tr>
  <!-- end Java2Html link -->
</table>
</div>
<!-- =       END of automatically generated HTML code       = -->
<!-- ======================================================== -->
</p>

<p><b>Listing 3 - CustomerConverter.java</b><br />
<!-- ======================================================== -->
<!-- = Java Sourcecode to HTML automatically converted code = -->
<!-- =   Java2Html Converter 5.0 [2006-03-04] by Markus Gebhard  markus@jave.de   = -->
<!-- =     Further information: http://www.java2html.de     = -->
<div align="left" class="java">
<table border="0" cellpadding="3" cellspacing="0" bgcolor="#ffffff">
   <tr>
  <!-- start source code -->
   <td nowrap="nowrap" valign="top" align="left">
    <code>
<font color="#7f0055"><b>package&nbsp;</b></font><font color="#000000">com.oracle.converter;</font><br />
<font color="#ffffff"></font><br />
<font color="#3f7f5f">//&nbsp;The&nbsp;following&nbsp;interface&nbsp;can&nbsp;be&nbsp;found&nbsp;in&nbsp;sb-kernel-api.jar&nbsp;which&nbsp;is&nbsp;located&nbsp;in&nbsp;your</font><br />
<font color="#3f7f5f">//&nbsp;%OSB_HOME%/osb_10.3/lib/&nbsp;directory</font><br />
<font color="#7f0055"><b>import&nbsp;</b></font><font color="#000000">com.bea.wli.sb.transports.ejb.ITypeConverter;</font><br />
<font color="#7f0055"><b>import&nbsp;</b></font><font color="#000000">com.oracle.ejb.Customer;</font><br />
<font color="#7f0055"><b>import&nbsp;</b></font><font color="#000000">java.util.List;</font><br />
<font color="#ffffff"></font><br />
<font color="#7f0055"><b>public&nbsp;class&nbsp;</b></font><font color="#000000">CustomerConverter&nbsp;</font><font color="#7f0055"><b>implements&nbsp;</b></font><font color="#000000">ITypeConverter&nbsp;</font><font color="#000000">{</font><br />
<font color="#ffffff">&nbsp;&nbsp;</font><br />
<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>public&nbsp;static&nbsp;</b></font><font color="#000000">Customer</font><font color="#000000">[]&nbsp;</font><font color="#000000">convert</font><font color="#000000">(</font><font color="#000000">List&nbsp;customerList</font><font color="#000000">)&nbsp;{</font><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>int&nbsp;</b></font><font color="#000000">listSize&nbsp;=&nbsp;customerList.size</font><font color="#000000">()</font><font color="#000000">;</font><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">Customer</font><font color="#000000">[]&nbsp;</font><font color="#000000">custArray&nbsp;=&nbsp;&nbsp;</font><font color="#7f0055"><b>new&nbsp;</b></font><font color="#000000">Customer</font><font color="#000000">[</font><font color="#000000">listSize</font><font color="#000000">]</font><font color="#000000">;</font><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">custArray&nbsp;=&nbsp;</font><font color="#000000">(</font><font color="#000000">Customer</font><font color="#000000">[])</font><font color="#000000">customerList.toArray</font><font color="#000000">(</font><font color="#000000">custArray</font><font color="#000000">)</font><font color="#000000">;</font><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>return&nbsp;</b></font><font color="#000000">custArray;</font><br />
<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">}</font><br />
<font color="#000000">}</font></code>
    
   </td>
  <!-- end source code -->
   </tr>
  <!-- start Java2Html link -->
   <tr>
    <td align="right">
<small>
<a href="http://www.java2html.de" target="_blank">Java2html</a>
</small>
    </td>
   </tr>
  <!-- end Java2Html link -->
</table>
</div>
<!-- =       END of automatically generated HTML code       = -->
<!-- ======================================================== -->
</p>
<h2>Source Code</h2>
<p>Download the <a href="http://blogs.oracle.com/jeffdavies/2009/10/01/converterclass_projects.zip">source code</a>. After you download the source code you can import it into a OSB
workspace as follows:</p>	
<p>
<ol>
	<li>Run the WorkShop IDE that was installed when you installed your OSB or ALSB product.</li>
	<li>When the IDE is fullly loaded and running, select File -> Import from the main menu bar. This will launch the Import Wizard.</li>
	<li>Select the Existing Projects into Workspace inside of the General folder. Press the Next button.</li>
	<li>Select the Select archive file radio button, and then browse to the source code file that you downloaded. Be sure to select all projects within the archive file.</li>
	<li>Press OK to import the soruce code. After you import all of the source code, wait until the IDE has finished rebuilding its workspace.</li>
	<li>Once the workspace is completely rebuilt, you may see a number of error messages next to some of the projects. This is because these projects are using some 
	additional libraries that Workshop cannot find on your machine. If you do not see these errors, your import is complete. If you see these errors, then keep reading.</li>
	<li>To help Workshop find the missing libraries, you need to define the OSB_HOME variable within the Workshop IDE. To do that, right-click on one of the projects 
	and select the <i>Properties</i> entry from the popup menu.</li>
	<li>In the Properties dialog, select the <i>Java Build Path</i> entry in the list on the left side of the dialog and then be sure the <i>Libraries</i> tab is selected.</li> 
	<li>Press the <i>Add Variable</i> button. This will display the <i>New Variable Classpath Entry</i> dialog. </li>
	<li>Press the <i>Configure Variables...</i> button. This brings up yet another dialog that lists the existing classpath variables.</li>
	<li>Press the <i>New...</i> button and create a new variable named <code>OSB_HOME</code> and then press the <i>Folder...</i> button to enter the main directory of the 
	OSB 10gR3 installation folder. If you used the default installation folder, then the correct path is C:\BEA on a windows machine.</li>
	<li>Press OK to all  open dialogs until you get back to the main Workshop interface. You errors should now disappear after Workshop rebuilds the project.</li>
</ol>
That's all for this installment. Keep your code clean and your hands dirty!
</p>]]>
      
   </content>
</entry>

<entry>
   <title>Service Aggregation</title>
   <link rel="alternate" type="text/html" href="http://blogs.oracle.com/jeffdavies/2009/09/service_aggregation.html" />
   <id>tag:blogs.oracle.com,2009:/jeffdavies//422.14416</id>
   
   <published>2009-09-15T17:45:30Z</published>
   <updated>2009-10-01T16:49:07Z</updated>
   
   <summary>A reader of my book asked about using OSB to aggregate services. His scenario was fairly involved, but the crux of the issue came down to the following question: How do I get a list of information from one low...</summary>
   <author>
      <name>jeff.x.davies</name>
      
   </author>
   
      <category term="Architect" scheme="http://www.sixapart.com/ns/types#category" />
   
      <category term="Developer" scheme="http://www.sixapart.com/ns/types#category" />
   
      <category term="SOA" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="aggregation" label="aggregation" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="en" xml:base="http://blogs.oracle.com/jeffdavies/">
      <![CDATA[<p>A reader of my book asked about using OSB to aggregate services. His scenario was fairly involved, but the crux of 
		the issue came down to the following question:</p>
		
		<p><b>How do I get a list of information from one low level service, and then iterate over that list, using the list
		information to query other low level services?</b></p>
		
		<p>This pattern is called &quot;service aggregation&quot; and it a fundamental capability of the Oracle Service Bus. 
		In this blog entry I will describe the overall integration pattern and then walk through the solution code, which you 
		can download at the end of this blog entry.</p>
		
		<p>The scenario I used is as follows: the have a single, high-level proxy service that takes in a postal code and returns
		a list of customers and the products that they have purchased from our fictitious company. The high-levle proxy service
		has to call two different services to accomplish its goal. The first is a lower-level service that takes the postal code 
		and returns a list of customers.  The second lower-level service take the ID of a single customer and returns a list of 
		products that that specific customer owns. The higher-level proxy service then aggregates these two different lists of 
		information into the return value for the caller.</p>
		
		<p>Service aggregation is an extremely common use for the service bus. The Oracle Service Bus can act as a facade over the
		lower level services, hiding their technical details and their interrelationship from the service consumer. Service 
		aggregation adds alot of value to the overall system by providing a higher level of abstraction. Ideally, you can even 
		hide the very existence of your applications from your service consumers, greatly increasing your overall business and 
		IT agility.</p>
		
		<p>Let's begin with the WSDL for the high level proxy service. This WSDL is going to be focused on the business need, and
		not have any information about <i>how</i> the work is performed within the proxy service. The proxy service takes only a
		<code>postalCode</code> as the argument for the service, and then returns as aggregated list of customers and their products 
		that live in the given postal code. The WSDL for the proxy service can be found in the WSDLs folder of the sample source code
		with the file name of <b>CustomerProduct.wsdl</b>. return type for the service call looks like the following:</p>
		
		<p><code>
		&lt;xsd:complexType name=&quot;ProductType&quot;&gt;<br>
		&nbsp;&nbsp;&lt;xsd:sequence&gt;<br>
		&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:element name=&quot;id&quot; type=&quot;xsd:int&quot; /&gt;<br>
		&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:element name=&quot;name&quot; type=&quot;xsd:string&quot; /&gt;<br>
		&nbsp;&nbsp;&lt;/xsd:sequence&gt;<br>
		&lt;/xsd:complexType&gt;<br>
			<br>
		&lt;xsd:complexType name=&quot;CustomerType&quot;&gt;<br>
		&nbsp;&nbsp;&lt;xsd:sequence&gt;<br>
		&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:element name=&quot;id&quot; type=&quot;xsd:int&quot; /&gt;<br>
		&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:element name=&quot;firstName&quot; type=&quot;xsd:string&quot; /&gt;<br>
		&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:element name=&quot;lastName&quot; type=&quot;xsd:string&quot; /&gt;<br>
		&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:element name=&quot;product&quot; type=&quot;cp:ProductType&quot; minOccurs=&quot;1&quot; maxOccurs=&quot;unbounded&quot; /&gt;<br>
		&nbsp;&nbsp;&lt;/xsd:sequence&gt;<br>
		&lt;/xsd:complexType&gt;
		</code><br><b>Listing 1</b>
		</p>
		
		<p>The two low-level services are fairly straight-forward in their implementation. The Customer.wsdl defines the
		service interface for the low-level service of the same name, as does Product.wsdl. One interesting thing to 
		note is that the structure of the Product in Product.wsdl is different from the structure used in the top-level
		proxy service. I did this deliberately to make the problem more realistic. You will commonly be transforming message 
		between application specific formats, and the more abstract formats used by your higher level services. This is a
		common pattern simply because you don't want to have to change all of your services and recompile all of your 
		service clients just because you upgraded or changed one of the applications in your application landscape.</p>
		
		<p>Lets take a  quick look at how a Product is defined in the Product.wsdl file and compare it to the Product
		element defined in the CustomerProduct.wsdl file shown in Listing 1.</p>
		<p><code>&lt;xsd:complexType name=&quot;ProductType&quot;&gt;<br>
        &nbsp;&nbsp;&lt;xsd:sequence/&gt;<br>
        &nbsp;&nbsp;&lt;xsd:attribute name=&quot;id&quot; type=&quot;xsd:int&quot; /&gt;<br>
        &nbsp;&nbsp;&lt;xsd:attribute name=&quot;name&quot; type=&quot;xsd:string&quot; /&gt;<br>
        &lt;/xsd:complexType&gt;</code><br><b>Listing  2</b></p>
        
        <p>All we have really done is changed the id and name elements from the Product.wsdl definition of a product into
        attributes in the CustomerProduct.wsdl definition of the Product business concept. It may seem minor, but it is 
        the key to loosely coupling systems. When you hear peope talk about &quot;canonical models&quot;, this is what
        they mean:; defining your own model  for information that is independent of any specific application. This also
        gives you the flexibility to add meta data to your canonical models that may not be available in the application 
        specific versions of these concepts/structures.
        </p>
        <p>Figure 1 shows the basic structure of the message flow for the top-level proxy service, <b>XQueryLoopingExample.proxy</b>.
        In the request pipeline we have a service callout to the CustomerService.proxy service. In the request pipeline of the
        service callout we see an assign statement. This assign statement simply prepares the customerListRequest variable with the
        correct data for calling the service.
        </p>
        
        <p>
        <span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blogs.oracle.com/jeffdavies/assets_c/2009/09/figure1-1074.html" onclick="window.open('http://blogs.oracle.com/jeffdavies/assets_c/2009/09/figure1-1074.html','popup','width=740,height=829,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://blogs.oracle.com/jeffdavies/assets_c/2009/09/figure1-thumb-740x829-1074.jpg" width="740" height="829" alt="figure1.jpg" class="mt-image-left" style="float: left; margin: 0 20px 20px 0;" /></a></span><br>
        <b>Figure 1. The overall message flow of the XQueryLoopingExample.proxy</b>
        </p>
        
        <p>Immediately below the service callout we see another assign statement where we create a new variable called
        <code>customerProductList</code>. Ultimately, this variable will contain all of the customer and product information
        that we need to pass back to the caller of the proxy service. For now, it just contains the proper elements that the 
        CustomerProduct.wsdl requires:<br>
        <code>&lt;cp:getCustomerProductByPostalCodeResponse&gt;&lt;/cp:getCustomerProductByPostalCodeResponse&gt;</code>
        </p>
        
        <p>Figure 2 shows the details of the <i>For Each</i> action. The purpose of the Foro Each action is to iterate over
        lists of information. In our example, we need to iterate over the list of customers returned from our first service 
        callout.
        </p>
        
        <p>
        <img src="http://blogs.oracle.com/jeffdavies/2009/09/15/images/figure2.jpg"><br>
        <b>Figure 2. The For Each section of the message flow</b>
        </p>
        
        <p>Figure 3 shows the properties for the For Each action. The <i>Index Variable</i> and <i>Count Variable</i> fields 
        are optional for our  purposes here, but I like to fill them in just so I can get some idea of the number of records
        being selected. This can be handy when you are first configuring the For Each action and you are still trying to get
        the XPath statement correct.
        </p>
        
        <p>
        <img src="http://blogs.oracle.com/jeffdavies/2009/09/15/images/figure3.jpg"><br>
        <b>Figure 3. The For Each properties</b>
        </p>
        
        <p>As you can see in Figure 3, we are using the XPath statement of <code>//Customer</code> to retrieve every customer in the 
        <i>customerListResponse</i> variable (which was populated by the service callout) and to place the individual customer
        information into the <i>customer</i> variable.
        </p>
        
        <p>Now that we can iterate over the list of customers, returned by the first service callout, we are able to execute
        the second service callout to the ProductService.proxy to  retrieve the list of products for each customer. This service
        callout operates in the same manner as the first one did. We have an assign statement in the request pipeline of the 
        service callout that prepares the request document. The response from the service invocation is stored in the 
        <i>productResponse</i> variable.
        </p>
        
        <p>Here is where things start to get interesting and a little fun. At this point we have two variables that contain the
        information that we need to merge into the final response document. Those two variables are <i>$productResponse</i> and 
        <i>$customer</i>. Now we could write a series of assign statements to build up the response document, but that would be
        very cluttered, reduce the readability of the message flow and actually reduce performance a bit. Instead we will use a single
        assign statement that will use an XQuery transform to do the real work. Figure 4 shows the graphical view of the XQuery
        transform.
        </p>
        
        <p>
        <span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blogs.oracle.com/jeffdavies/assets_c/2009/09/figure4-1077.html" onclick="window.open('http://blogs.oracle.com/jeffdavies/assets_c/2009/09/figure4-1077.html','popup','width=868,height=298,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://blogs.oracle.com/jeffdavies/assets_c/2009/09/figure4-thumb-740x254-1077.jpg" width="740" height="254" alt="figure4.jpg" class="mt-image-left" style="float: left; margin: 0 20px 20px 0;" /></a></span><br>
        <b>Figure 4. The XQuery transform</b>
        </p>
        
        <p>When we create the transform, we simply select the two data types that represent the input variables. In our case 
        the input types are  a <i>getCustomerByPostalCodeResponse/CustomerList/Customer</i> and a <i>getCustomerProductResponse</i>, 
        respectively. We also need to specify the return type, which is a <i>getCustomerProductByPostalCodeResponse/Customer</i>.
        Once this is done, the Workshop development environment brings up a graphical view of the source and return types and we simply
        drag and drop from the source to the return type to create the transformation. The only part that may not be obvious is
        the dashed arrow on figure 4, which connects the source and destination Product elements. This is done to tell the XQuery
        engine that there are possibly multiple Products on each side and that we want the XQuery engine to create a Product in
        the return variable for each Product it finds in the source variable.</p>
        
        <p>At this point in the loop, we now have a single customer record with all of the products owned by that customer. The
        insert action is used to insert the <i>$customerProductRecord</i> information into the existing <i>$customerProductList</i>.
        The rest of the proxy service is very straight-forward. There is a replace action in the response pipeline of the pipeline 
        pair that places the <i>$customerProductList</i> into the <i>$body</i> variable. 
        </p>
        
        <p>Finally, there is a validate action that validates that the data
        we are returning conforms to the expected data format defined by the web service. This is definitely a best practice when
        you are developing your services. Validation does take additional time, so it is often turned off in production, but while you
        are developing your services, it can save you alot of time and headache when debugging.
        </p>
        
        <h2>Conclusion</h2>
        <p>That's it for this entry. Hopefully I have shown that service aggregation is not only easy to do, but that it also has 
        the potential to really help your overall architecture by loosening the couplings between your service consumers and low level 
        service providers. It gives you an opportunity to create your own layers of abstraction over the low level services and 
        applications, which in turn puts you in control of your architecture.
        </p>
        <p>I have also received a question about using a converter class to convert EJB information into. XML. That will be my next 
        entry. Until then, get your hands dirty and keep your code clean!</p>
        
<span class="mt-enclosure mt-enclosure-file" style="display: inline;"><a href="http://blogs.oracle.com/jeffdavies/xquerylooping_sbconfig.jar">Download xquerylooping_sbconfig.jar</a></span>]]>
      
   </content>
</entry>

<entry>
   <title>RESTful Services with Oracle Service Bus</title>
   <link rel="alternate" type="text/html" href="http://blogs.oracle.com/jeffdavies/2009/06/restful_services_with_oracle_s_1.html" />
   <id>tag:blogs.oracle.com,2009:/jeffdavies//422.12741</id>
   
   <published>2009-06-04T16:44:52Z</published>
   <updated>2009-06-04T17:50:47Z</updated>
   
   <summary>Recently I was asked about REST (see http://en.wikipedia.org/wiki/Representational_State_Transfer) support in Oracle Service Bus. OSB 10gR3 has full support for REST and implementing a REST approach in a proxy service is very simple. In this example, we will create a proxy...</summary>
   <author>
      <name>jeff.x.davies</name>
      
   </author>
   
      <category term="SOA" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="http://blogs.oracle.com/jeffdavies/">
      <![CDATA[<p>Recently I was asked about REST (see http://en.wikipedia.org/wiki/Representational_State_Transfer)
support in Oracle Service Bus. OSB 10gR3 has full support for REST and
implementing a REST approach in a proxy service is very simple. In this
example, we will create a proxy service that provides a REST interface to a
product catalog.</p>

<h2>Why use OSB for REST?</h2>

<p>Using the Oracle Service Bus to provide an interface as
simple as REST may seem odd at first. There are several good reasons for this
approach though.</p>

<p>
<ol>
<li>You automatically get all of the monitoring, reporting, security and more provided
by OSB for your RESTful services</li>
<li>You keep the benefits of mediation. For example, of our company in this example
purchased another company that provided different products, you could use the
OSB to act as a façade over both product catalogs while providing a single,
unchanged REST interface.</li>
<li>You
can REST-ify existing, non-service enabled assets like EJBs</li>
</ol>
</p>

<h2>The Products Proxy Service</h2>
<p>Let’s get started. First we will create a new OSB
Configuration Project to house our REST services. I named the configuration
project <b><i>RESTConfig</i></b> in the sample source code. You can download
the sample source code here.</p>

<p>Inside of the <b><i>RESTConfig</i></b> project I then
created a standard OSB project named <b><i>SimpleREST</i></b>. Once the OSB
project was created, I was ready to start creating my REST project.</p>

<p>Next I created a proxy service named <b><i>Products</i></b>.
I used the default endpoint URI of <b><i>SimpleREST/Products</i></b> but in a
production environment you’ll most likely want to customize that. Be sure to
define your proxy service as an <b><i>Any XML Service</i></b> so you can accept
and return XML of any flavor.</p>

<p>Now it is time to create our message flow. Here is where
it gets interesting. One of the fundamental concepts in REST is the use of the
native HTTP methods to allow the service consumer to express their intent. The
specific HTTP methods that we are interested in are: GET, POST, PUT, HEAD,
OPTIONS and DELETE. In this example I don’t make use of the TRACE method.
However, you will be able to add that to your projects easily after reading
this.</p>

<p>The handling of each of those methods is different, so we
begin our message flow with a Conditional Branch node (see figure 1). I added a
branch for each of the methods I was interested in. In the Conditional Branch
node I set the <i>XPath</i> field to <code>./ctx:transport/ctx:request/http:http-method/text()</code>
 and the<i>In Variable</i> field to <code>inbound</code>. This is the equivalent to the XPath 
expression <code>$inbound/ctx:transport/ctx:request/http:http-method/text().</code>
 The <code>text()</code> operation at the end is important because I
want to deal with the method in its plain text form and not as an XML
expression.</p>
<img alt="image001.jpg" src="http://blogs.oracle.com/jeffdavies/2009/06/04/image001.jpg" width="576" height="272" /><br>
<p>Figure 1 Standard OSB REST Pattern</p>

<p>When adding the branches it is important to enclose the
contents of the Value field in single quotes (Figure 2) to denote it is a
string value. If you forget this, you will get an error about an unbound XML
node when you run the proxy service because OSB will treat the contents of the
Value field as a variable instead of a string literal.</p>

<p><img alt="image002.jpg" src="http://blogs.oracle.com/jeffdavies/2009/06/04/image002.jpg" width="375" height="107" /><br><br />
<p>Figure 2 Don't forget the quotes!</p></p>

<p>For each branch, add a pipeline pair and name it
appropriately, as shown in figure 1. Before we fill in the GET Pipeline with
the necessary logic, let’s take a moment to decide how we want the HTTP GET method
to be handled. Ideally, we want to be able to point a web browser or other REST
service consumer to a URL like: <code>http://localhost:7001/SimpleREST/Products/id=#</code> to
retrieve a product representation by its ID. Since the proxy service is
listening at <code>http://localhost:7001/SimpleREST/Products</code>,
the remainder of the URL (i.e. the <code>id=#</code>) will be accessible in the message
flow as the relative-URI part of the <i>$inbound</i> variable.</p>

<h3>The GET Method</h3>

<p>Now that we know what the URL should look like for a GET,
we can fill in the logic. In the GET Pipeline (Figure 3) we will add two Assign
actions. The first Assign action will get the first part of the relative URL
(i.e. the <span style='font-size:10.0pt'>id</span> part). We won’t do anything
with this part in this example, but you can use this technique to ensure that
the URL used had the correct format. The expression to use in the first Assign
statement is as follows:</p>

<p><code>fn:tokenize(data($inbound/ctx:transport/ctx:request/http:relative-URI),
'=')[1]</code></p>

<p>This expression will take the relative-URL value and
tokenize it using the ‘=’ character, returning the first token. So if the
relative-URI is “id=27” this expression will return the “id” string. Why XPath
counts from 1 instead of 0 I don’t know. Set the Variable field to <code>attr</code> and you are
done with the first Assign statement.</p>

<p>The second Assign statement is very similar to the first,
except we are retrieving the second part of the relative-URI. Its expression is
as follows:</p>

<p><code>fn:tokenize(data($inbound/ctx:transport/ctx:request/http:relative-URI),
'=')[2]</code></p>

<p>Set the Variable field to <code>productID</code>. In the sample code I include
a Log statement to output the contents of these variables to the console</p>

<p><img alt="image003.jpg" src="http://blogs.oracle.com/jeffdavies/2009/06/04/image003.jpg" width="339" height="347" /><br><br />
<p>Figure 3 The GET Pipeline</p></p>

<p>In the Response Pipeline we will construct our response
message for the GET. We will just mock up a product document for this tutorial.
The following code snippet (which you will put into the <i>Expression</i> field
of the Replace action) shows the value that the Replace action will put into
the <span class=Codeinline><span style='font-size:11.0pt'>$body</span></span>
variable, which is then returned to the caller.</p>

<p><code>&lt;Product&gt;<br>
   &lt;ID&gt;{$productID}&lt;/ID&gt;<br>
   &lt;Name&gt;Foobar&lt;/Name&gt;<br>
   &lt;Price&gt;19.99&lt;/Price&gt;<b>
   &lt;/Product)</code></p>
<p>Listing 1 Constructing the response document</p>

<p>Set the <i>XPath</i> field to just a period (.) and be
sure to select the <i>Replace Node Contents </i> radio button. If you deploy
the project you can test it using your web browser. Assuming your OSB server is
running on the default port 7001, you can use the following URL:</p>

<p><code>http://localhost:7001/SimpleREST/Products/id=2</code></p>

<p>Your web browser should show you the following:</p>

<p><code>&lt;Product&gt;<br>
   &lt;ID&gt;2&lt;/ID&gt; <br>
   &lt;Name&gt;Foobar&lt;/Name&gt;<br>
   &lt;Price&gt;19.99&lt;/Price&gt;<br>
   &lt;/Product&gt;</code></p>

<p><b>Note:</b> Capitalization counts even with REST</p>

<p>Alternatively, you can use the OSB Test Console instead of
a web browser. I recommend using the Test Console (Figure 4) because it gives
you more control over the service call and visibility into the message flow. To
test the GET method, right-click on the <i>Products.proxy</i> file in the
Workshop IDE and select <i>Debug As -&gt; Debug on Server…</i>. When the Test
Console appears, click on the down-arrow icon in the Transport section. This
will allow you to set the relative-URI and http-method fields directly.</p>

<p><img alt="image004.jpg" src="http://blogs.oracle.com/jeffdavies/2009/06/04/image004.jpg" width="506" height="487" /><br><br />
<p>Figure 4 The Transport section of the Test Console</p></p>

<p>When you are happy with your settings, press the Execute
button to run the test. The Test Console (Figure 5) will return the results and
provide you with the response metadata and the invocation trace, which is
useful when debugging your proxy services.</p>
<img alt="image005.jpg" src="http://blogs.oracle.com/jeffdavies/2009/06/04/image005.jpg" width="575" height="491" />
<p>Figure 5 The Test Console response</p>

<p>Now that we have the GET branch taken care of. Let’s take
a quick look at the other HTTP methods that we are supporting.</p>

<h3>The POST Method</h3>

<p>The HTTP POST method is traditionally used with REST to
create new entities. The message content that is POSTed can be in XML format, or
in the format used by HTML forms, which is still the most common mechanism for
submitting data to a web site in use today. However,, I highly recommend that
you keep your information in XML format instead of the HTML Form format simply
because the HTML Form only  supports the GET and POST verbs, whereas with REST
we also want to use the other verbs, like PUT and DELETE.</p>

<p>The POST Pipeline shows how to handle the POST method. It’s
pretty simple in that it extracts the specific information it wants from the
$body and then creates and returns an XML representation, simulating the
creation of a product. You can use the OSB Test Console to test this method by
setting the http-method field to post and then typing in the payload as
follows:</p>

<p><code>&lt;Product&gt;<br>
   &lt;Name&gt;Widget&lt;/Name&gt;<br>
   &lt;Price&gt;99.99&lt;/Price&gt;<br>
&lt;/Product&gt;</code></p>

<p>The two Assign statements in the POST Pipeline simply
extract the name and price information and return a representation of the new
product, with a hard-coded ID of 777</p>

<h3>The PUT Method</h3>

<p>The PUT method is used to update an entity. It operates
very much like the POST method does, except this method will expect to see the
ID in the submitted product representation. You can test this operation in
pretty much the same way that you tested the POST, just change the http-method
to PUT and use the following as your payload:</p>

<p><code>&lt;Product&gt;<br>
   &lt;ID&gt;999&lt;/ID&gt;<br>
   &lt;Name&gt;Widget&lt;/Name&gt;<br>
   &lt;Price&gt;99.99&lt;/Price&gt;<br>
&lt;/Product&gt;</code></p>

<p>Here we will add a little error checking to ensure that
the ID for the product has been specified. The If-Then action (Figure 6) uses
the expression: <code>exists($body/Product/ID)</code> to test
for the presence of the ID element.</p>

<p><img alt="image006.jpg" src="http://blogs.oracle.com/jeffdavies/2009/06/04/image006.jpg" width="551" height="339" /><br><br />
<p>Figure 6 The PUT Pipeline</p></p>

<p>If the ID element is defined, we then use a single Assign
statement to create our entire response document as follows:</p>

<p><code>&lt;Product&gt;<br>
   &lt;ID&gt;{$body/Product/ID/text()}&lt;/ID&gt;<br>
   &lt;Name&gt;{$body/Product/Name/text()}&lt;/Name&gt;<br>
   &lt;Price&gt;{$body/Product/Price/text()}&lt;/Price&gt;<br>
&lt;/Product&gt;</code></p>

<p>If the ID element is missing from the $body, then we throw
an error to alert the service consumer of the problem. In the response pipeline
we simply set <code>$body</code>
to the value of $responseDoc, what was created in our Assign statement.</p>

<h3>The HEAD Method</h3>

<p>The HEAD method is used to return metadata about a
representation to the caller. It’s called the HEAD method because the metadata
is returned in the HTTP headers. This metadata can be anything you want it to
be, but a good place to start is the standard HTTP headers used by the
Inbound-Response to the Inbound-Request. Figure 6 shows the message flow for
HEAD Pipeline (Figure 7). All we do is populate the data of a single Transport
Header action in the response pipeline.</p>
<img alt="image007.jpg" src="http://blogs.oracle.com/jeffdavies/2009/06/04/image007.jpg" width="249" height="212" /><br>
<p>Figure 7 Implementing the HEAD method</p>

<p>Its up to you and your specific needs to define which
headers you want to send back for the HEAD method, but I recommend sending at
least the HTTP Content-Type header with a value along the lines of ‘<code>text/xml; charset=utf-8</code>’.
This will help the HTTP clients know how to parse the text that is returned.
Setting the Connection header to ‘keep-alive’ is also generally a good idea.</p>

<h3>The OPTIONS Method</h3>

<p>Finally, the OPTIONS method is used to convey to the
caller which HTTP methods are appropriate for the Products entity. In this
case, all we need to do is to specify a Transport Header for the outbound
response (see figure 8).</p>
<img alt="image008.jpg" src="http://blogs.oracle.com/jeffdavies/2009/06/04/image008.jpg" width="249" height="212" />
<p>Figure 8 Implementing the OPTIONS Pipeline</p>

<p>Configure the Transport Header as shown in figure 9.</p>
<img alt="image009.jpg" src="http://blogs.oracle.com/jeffdavies/2009/06/04/image009.jpg" width="500" height="158" />
<p>Figure 9 Transport Header Settings</p>

<p>The expression for the header is <code>‘GET, HEAD, PUT, DELETE, OPTIONS’</code>. It
may not be necessary to add the <code>OPTIONS</code> clause, since you have to call it in order to get
the response in the first place, but I show it for completeness. That covers
the basics of using OSB to implement RESTful service patterns. As you can see,
it’s quick and simple to do. Using this technique you can wrap any
functionality in your enterprise using a REST service interface.</p>

<h3>The DELETE Method</h3>

<p>The DELETE method is very straight forward. It expects to
have a product ID specified on the URI and it simply deletes the product with
that ID. Due to its trivial nature, it is not implemented in the sample code.</p>

<h2>Calling RESTful Services from OSB</h2>

<p>In addition to providing a REST interface, OSB can also
invoke REST services. For this part of the exercise we will provide a standard
SOAP interface to OSB. OSB will then take those SOAP calls and invoke the REST
services accordingly. The WSDL for our SOAP interface defines the following
operations: </p>

<p><code>getProductDetail(productID)<br>
createProduct(name)<br>
updateProduct(productID)<br>
deleteProduct(productID)</code></p>

<p>Each of these operations will be performed by the REST
services we created earlier in this tutorial.</p>

<p>We begin by creating a proxy service named CallREST based
on the Products.wsdl file (in the WSDL folder of the SimpleREST project). Since
the WSDL defines several SOAP operations, we start the message flow with an
Operational Branch node, and create branches for each of the operations we want
to handle. Once that is done, add a Pipeline Pair to the getProductDetail
branch, as show in Figure 10.</p>

<p><img alt="image010.jpg" src="http://blogs.oracle.com/jeffdavies/2009/06/04/image010.jpg" width="365" height="230" /><br><br />
<p>Figure 10 The basic structure for the CallREST message flow</p></p>

<p>The <i>getProduct Pipeline</i> consists of a single Stage
node, as shown in Figure 11. The initial Assign statement is used to extract
the product ID from the request document and store it in the <code>$productID</code>
variable. The next node is a Service Callout</p>

<p><img alt="image011.jpg" src="http://blogs.oracle.com/jeffdavies/2009/06/04/image011.jpg" width="255" height="282" /><br><br />
<p>Figure </a>11 The getProduct Pipeline stage</p></p>

<p>The Service Callout (Figure 12) is where most of the work
is done. To configure the Service Callout, be sure to check the Configure
Payload Document radio button since REST does not use a SOAP format. Set the <i>Request
Variable</i> field to <code>requestBodyDocument</code>
and the <i>Response Variable</i> field to <code>responseBodyDocument</code>. That’s all you need to do for the Service Callout action.</p>

<p><img alt="image012.jpg" src="http://blogs.oracle.com/jeffdavies/2009/06/04/image012.jpg" width="174" height="285" /><br><br />
<p>Figure 12 Service Callout contents</p></p>

<p>The first action is a Transport Header. Configuring this
action is simple. Set the <i>Direction</i> field to <code>Outbound Request</code>. 
Also, be sure to check the <i>Pass all Headers</i> checkbox.</p>

<p>Immediately after the Transport Header action are two
Insert actions. The first insert action (Figure 13) is used to specify the HTTP
GET method. Configure it as shown in Figure 13</p>

<p><img alt="image013.jpg" src="http://blogs.oracle.com/jeffdavies/2009/06/04/image013.jpg" width="369" height="149" /><br><br />
<p>Figure </a>13 Specifying the HTTP GET method</p></p>

<p>The second and last Insert action (Figure 14) in the
request pipeline shows how to specify the relative-URI of the request. The expression:
<code>&lt;http:relative-URI&gt;id={$productID}&lt;/http:relative-URI&gt;</code>
is used to create the value of the relative-URI of the outbound request
variable.</p>

<p><img alt="image014.jpg" src="http://blogs.oracle.com/jeffdavies/2009/06/04/image014.jpg" width="422" height="149" /><br />
<p>Figure 14 Specifying the Relative-URI of the request</p></p>

<p>At this point our request of the REST service is properly
formatted. Once the REST service is invoked, the response will be returned to
our message flow in the <code>responseBodyDocument</code>
variable. In the Response Action pipeline of the service callout, we add a
single Replace action (see Figure 15) to take the response document from the
REST service and format it to meet the needs of our SOAP operation.</p>

<p><img alt="image015.jpg" src="http://blogs.oracle.com/jeffdavies/2009/06/04/image015.jpg" width="370" height="148" /><br />
<p>Figure 15 Formatting the &lt;body&gt; that our operation returns</p></p>

<p>The remaining branches follow a similar pattern so there
is no need to document them here. If you want to see the sample code for this
blog entry, you can download it from here: 
<a href="http://blogs.oracle.com/jeffdavies/2009/06/04/simplerest_sbconfig.jar">Download Source</a>
</p>

<h2>Conclusion</h2>

<p>As you can see from this sample, it is very easy to use
Oracle Service Bus to both call existing REST services, and to have OSB provide
a REST interface to existing SOAP services. The benefit of REST is the
simplicity of the interface design. By marrying OSB and REST, you get the
simplicity of REST, while maintaining the ability to define SLA’s on each
service or operation, maintain visibility over these operations using OSBs
built in monitoring and reporting, and still retaining the necessary agility by
being able to quickly alter the OSB message flows and aggregating/orchestrating,
multiple services in the “backend” without the implicit knowledge of the
service consumer.</p>]]>
      
   </content>
</entry>

<entry>
   <title><![CDATA[The Myth of &quot;Right&quot;]]></title>
   <link rel="alternate" type="text/html" href="http://blogs.oracle.com/jeffdavies/2009/02/the_myth_of_right_1.html" />
   <id>tag:blogs.oracle.com,2009:/jeffdavies//422.10007</id>
   
   <published>2009-02-04T22:35:01Z</published>
   <updated>2009-10-01T16:44:12Z</updated>
   
   <summary>SOA Thinker - Feb 2009 Welcome to the February edition of SOA Thinker. At first I thought it would be difficult to blog on a monthly basis. However, I&apos;m beginning to find topics faster than I can write them down!...</summary>
   <author>
      <name>jeff.x.davies</name>
      
   </author>
   
      <category term="Architect" scheme="http://www.sixapart.com/ns/types#category" />
   
      <category term="Developer" scheme="http://www.sixapart.com/ns/types#category" />
   
      <category term="SOA" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="jmx" label="JMX" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="osb" label="OSB" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="soa" label="SOA" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="architecture" label="architecture" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="loosecoupling" label="loose coupling" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="scripting" label="scripting" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="en" xml:base="http://blogs.oracle.com/jeffdavies/">
      <![CDATA[<h1>SOA Thinker - Feb 2009</h1>
<p>Welcome to the February edition of SOA Thinker. At first I thought it would be difficult to blog on a monthly basis.
However, I'm beginning to find topics faster than I can write them down! Let's get started with The Emperor Has No 
Clothes section. Here we will examine another work of fiction in enterprise software development: Getting the design right!</p>

<h2>The Emperor Has No Clothes - The Myth of &quot;Right&quot;</h2>
<p>I frequently hear people say, <i>"With SOA, its very important to design your services right,
so that you don't need to change them in the future."</i> Well I certainly agree that that would be an optimal solution
if it were possible. The problem is, it simple is <i>not</i> possible. The whole idea of getting it "right" assumes
that things do not change in this world. If the world is static, then it's possible to get things "right" and achieve
design perfection.</p>

<div class="rightquote">
<blockquote>
<p>In an ever-changing world there is no such thing as "right"; there is only "right now".</p>
</blockquote>
</div>

<p>Of course, the world is not static, It changes constantly and at a rate faster than most IT systems can handle. The same
people who will advise you  to "design it right" will also acknowledge that in the time it takes to deliver most software 
projects, the requirements will change several times. That very acknowledgment flies in the face of their own advice. In 
an ever-changing world there is no  "right", there is only "right now". So what is a poor software professional to do?</p>

<p>The answer is simple to say, but not always simple to do. The answer is to design software systems and architectures 
that are flexible. They should not be resistant to change, they need to be <i>resilient</i> to change.
This is the fundamental driver behind SOA. The world is changing quickly, your business is changing quickly, you need an 
architecture that can adapt quickly to these changes.</p>

<p>One of the key elements of coupling is knowledge. The more that system A has to know about system B, the more  tightly coupled
system A is with regard to system B. The less knowledge that system A has about system B, the less tightly coupled. Ignorance is 
not only bliss, but it is also the key to loose-coupling.
<p>In my <a href="http://blogs.oracle.com/jeffdavies/2008/10/">October 2008 blog</a> entry, I wrote about point-to-point vs. 
EAI vs. SOA and tallked about tight-coupling. I want to do a deeper dive on tight-coupling in this entry. People often talk about 
how tightly coupled systems
are, but rarely stop to think about how they got that way in the first place. Lets take a look at the simplest example of
coupling, two systems where system A is dependent on system B (i.e. system A "calls" system B). There is a directional 
dependency from A to B. However, they often mis-categorize it as a single dependency when in fact there are multiple dependencies
at work. If we assume that system B is an EJB application, then system A is coupled in the following ways:
</p>
<ul>
	<li><b>Technology</b>: System A can only communicate with system B using EJB. This imposes a skill-set requirement on the
	system A developer.</li>
	<li><b>Transport</b>: System A knows how to communicate with system B using EJB's RMI transport.</li>
	<li><b>Security</b>: System A must authenticate in a manner that system B will accept. There may also be fire-wall issues
	if the two systems are on different networks.</li>
	<li><b>API / Behavior</b>: System A must know the correct method name(s) to invoke and what they do (i.e. their meaning).</li>
	<li><b>Schema</b>: System A must know and use the schema (i.e. object definitions) provided by system B.</li>
	<li><b>Client JAR</b>: System A must have the correct version of the client jar for system B.</li>
</ul>

<p>These constraints are not all specific to EJB integration. Every integration approach brings along a similar set of coupling
requirements. I want to also point out that this list is not exhaustive. There are other ways in which systems may be coupled (i.e. 
a synchronous invocation couples systems in time). The important thing to remember is that for each link you draw on your white 
board that connects two systems together, you are representing multiple individual dependencies. Web services are often touted 
as a technology to loosely couple systems, but in practice web services alone are not sufficient to loosely couple two systems. 
Loose coupling comes from one place: <i><b>architecture</b></i>.</p>

<div class="leftquote">
<blockquote>
<p>Ignorance is not only bliss, but it is also key to loose-coupling.</p>
</blockquote>
</div>

<p>The key concept in loose coupling is providing a mediation layer between the caller and the system that is called. This is a
very common pattern in software but for some strange reason it is uncommon in enterprise architecture. Lets take a look at an example. 
When dealing with a collection of information in Java you would normally interact with a Collection interface, or one of its
sub-interfaces like List, Queue or Set. Interfaces are mediation layers between the user of the interface and the classes
that implement the interface. As you can see, an interface, which contains no implementation logic, acts as a mediation layer
to more loosely couple the caller of the interface and the implementation logic defined in a concrete class. Without the interface,
the caller and the concrete class that is called are going to be tightly coupled. Java interfaces help to add abstraction to the
behavior of the subclass.</p>

<p>This principle is the core of the <a href="http://en.wikipedia.org/wiki/Design_by_contract">
Design by Contract</a> approach. In "design by contract", both the service consumer and the service provider agree to a specific
interface (or set of interfaces). To me, SOA is simply Design by Contract for the enterprise.</p>

<p>The same principle holds true in enterprise software. It is important to separate the caller of a service from the service
implementation. The mediation layer separates the two systems and helps to make them more loosely coupled. With mediation you 
get something almost magical in nature, the ability to manage change much more effectively than you ever could without mediation.
Now you have much greater freedom to change the implementation service without as much concern for affecting any systems that 
may be calling the interface.</p>

<p>So, taking what we just reviewed into consideration, let's examine each of the 6 types of coupling that I listed at the start
and see how mediation helps us to more loosely couple our two systems.</p>
<ul>
	<li><b>Technology</b>: System A communicates to the mediation layer using web services and the mediation layer invokes
	system B using its EJB interface as needed. Benefits: system A (all callers of the mediation layer, really) no longer have to
	know how to use the EJB interface, nor be Java applications. Using web services here allows the system developers to focus on a 
	single, platform neutral messaging technology. This improves agility by reducing the number of skill-sets that application
	developers need to know and by reducing the number of technologies embedded into each application in the enterprise.</li>
	<li><b>Transport</b>: Similar to the Technology topic above, this reduced the number of technologies at work in any integration.</li>
	<li><b>Security</b>: Here, web services help to avoid the fire-wall issue, but  most of the benefit comes from being able to
	declare the security policies in the web service WSDL itself, making security more declarative in nature. Additionally, using a
	mediation layer like the Oracle Service Bus, you can also mediate between security approaches (i.e. convert a basic-auth to a SAML, etc).
	This goes beyond a simple interface and begins to leverage the configuration abilities of the service bus to provide mediation functionality.</li>
	<li><b>API / Behavior</b>: Again, web services provide a declarative and platform-neutral way to define behavior.</li>
	<li><b>Schema</b>: Schemas may now be managed independently of each application. This paves the way for the creation of 
	<a href="http://en.wikipedia.org/wiki/Canonical#Computer_science">canonical schemas
	and data models</a>, which in turn is the gateway to the <a href="http://en.wikipedia.org/wiki/Semantic_web">semantic web</a> in the future.</li>
	<li><b>Client JAR</b>: A service provider can simply publish a  WSDL online for service consumers to use. No longer do you need to
	exchange a file generated by the EJB creator.</li>
</ul>

<p>Each of those examples taken alone provides a reduction in the coupling between two systems. The real power comes when you combine
those elements. That is when you get a noticible decrease in the level of coupling between systems. Loose-coupling is about the synergy
of applying multiple techniques at the enterprise level. There is no single "magic bullet" for loose coupling. It is always deliberate 
and by design.</p>

<h2>Ask the Experts</h2>
<p>More scripting expertise in this months installment. This month's question
is:</p>
<h3>How can I enable/disable proxy services programatically?</h3>
<p>It turns out there are a couple of ways to do this. The first answer comes 
from Jesus Guerra, a Senior Engineer Principal in Spain. His examples uses JMX
to connect to and manipulate the Oracle Service Bus. I'm only showing the pertinent 
code snippet here, but you can view the entire class at: 
<a href="http://blogs.oracle.com/jeffdavies/ProxyServiceUtilJMX.html">ProxyServiceUtilJMX.java</a>.</p>

<p><!-- ======================================================== --><br />
<!-- = Java Sourcecode to HTML automatically converted code = --><br />
<!-- =   Java2Html Converter 5.0 [2006-02-26] by Markus Gebhard  markus@jave.de   = --><br />
<!-- =     Further information: http://www.java2html.de     = --><br />
<div align="left" class="java"><br />
<table border="0" cellpadding="3" cellspacing="0" bgcolor="#ffffff"><br />
   <tr><br />
  <!-- start source code --><br />
   <td nowrap="nowrap" valign="top" align="left"><br />
    <code><br />
<font color="#7f0055"><b>package&nbsp;</b></font><font color="#000000">oracle.osb.jmx;</font><br /><br />
<font color="#ffffff"></font><br /><br />
<font color="#7f0055"><b>public&nbsp;class&nbsp;</b></font><font color="#000000">ProxyServiceUtilJMX&nbsp;</font><font color="#000000">{</font><br /><br />
<font color="#ffffff"></font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>public&nbsp;</b></font><font color="#7f0055"><b>boolean&nbsp;</b></font><font color="#000000">setStatusProxyService</font><font color="#000000">(</font><font color="#000000">String&nbsp;proxyServiceName,&nbsp;String&nbsp;projectName,&nbsp;</font><font color="#7f0055"><b>boolean&nbsp;</b></font><font color="#000000">enable</font><font color="#000000">)&nbsp;{</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>boolean&nbsp;</b></font><font color="#000000">done&nbsp;=&nbsp;</font><font color="#7f0055"><b>false</b></font><font color="#000000">;</font><br /><br />
<font color="#ffffff"></font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">JMXConnector&nbsp;jmxConnector&nbsp;=&nbsp;</font><font color="#7f0055"><b>null</b></font><font color="#000000">;</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">SessionManagementMBean&nbsp;sessionManagementMBean&nbsp;=&nbsp;</font><font color="#7f0055"><b>null</b></font><font color="#000000">;</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>try&nbsp;</b></font><font color="#000000">{</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f7f5f">//get&nbsp;the&nbsp;jmx&nbsp;connector</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">jmxConnector&nbsp;=&nbsp;initConnection</font><font color="#000000">()</font><font color="#000000">;</font><br /><br />
<font color="#ffffff"></font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f7f5f">//&nbsp;get&nbsp;mbean&nbsp;connection</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">MBeanServerConnection&nbsp;mbConnection&nbsp;=&nbsp;jmxConnector.getMBeanServerConnection</font><font color="#000000">()</font><font color="#000000">;</font><br /><br />
<font color="#ffffff"></font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f7f5f">//&nbsp;get&nbsp;domain&nbsp;service&nbsp;mbean.&nbsp;This&nbsp;is&nbsp;the&nbsp;topmost&nbsp;mbean</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">DomainRuntimeServiceMBean&nbsp;domainService&nbsp;=</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">(</font><font color="#000000">DomainRuntimeServiceMBean</font><font color="#000000">)</font><font color="#000000">MBeanServerInvocationHandler.newProxyInstance</font><font color="#000000">(</font><font color="#000000">mbConnection,&nbsp;</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>new&nbsp;</b></font><font color="#000000">ObjectName</font><font color="#000000">(</font><font color="#000000">DomainRuntimeServiceMBean.OBJECT_NAME</font><font color="#000000">))</font><font color="#000000">;</font><br /><br />
<font color="#ffffff"></font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f7f5f">//&nbsp;obtain&nbsp;session&nbsp;management&nbsp;mbean&nbsp;to&nbsp;create&nbsp;a&nbsp;session.</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f7f5f">//&nbsp;This&nbsp;mbean&nbsp;instance&nbsp;can&nbsp;be&nbsp;used&nbsp;more&nbsp;than&nbsp;once&nbsp;to</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f7f5f">//&nbsp;create/discard/commit&nbsp;many&nbsp;sessions</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">sessionManagementMBean&nbsp;=&nbsp;</font><font color="#000000">(</font><font color="#000000">SessionManagementMBean</font><font color="#000000">)</font><font color="#000000">domainService.findService</font><font color="#000000">(</font><font color="#000000">SessionManagementMBean.NAME,&nbsp;SessionManagementMBean.TYPE,&nbsp;</font><font color="#7f0055"><b>null</b></font><font color="#000000">)</font><font color="#000000">;</font><br /><br />
<font color="#ffffff"></font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f7f5f">//&nbsp;create&nbsp;a&nbsp;session</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">sessionManagementMBean.createSession</font><font color="#000000">(</font><font color="#000000">sessionName</font><font color="#000000">)</font><font color="#000000">;</font><br /><br />
<font color="#ffffff"></font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f7f5f">//&nbsp;obtain&nbsp;the&nbsp;ALSBConfigurationMBean&nbsp;instance&nbsp;that&nbsp;operates&nbsp;on&nbsp;the&nbsp;session&nbsp;that&nbsp;has</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f7f5f">//&nbsp;just&nbsp;been&nbsp;created.&nbsp;Notice&nbsp;that&nbsp;the&nbsp;name&nbsp;of&nbsp;the&nbsp;mbean&nbsp;contains&nbsp;the&nbsp;session&nbsp;name.</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">ALSBConfigurationMBean&nbsp;alsbConfMB&nbsp;=</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">(</font><font color="#000000">ALSBConfigurationMBean</font><font color="#000000">)</font><font color="#000000">domainService.findService</font><font color="#000000">(</font><font color="#000000">ALSBConfigurationMBean.NAME&nbsp;+&nbsp;</font><font color="#2a00ff">&#34;.&#34;&nbsp;</font><font color="#000000">+&nbsp;sessionName,&nbsp;ALSBConfigurationMBean.TYPE,&nbsp;</font><font color="#7f0055"><b>null</b></font><font color="#000000">)</font><font color="#000000">;</font><br /><br />
<font color="#ffffff"></font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">ProxyServiceQuery&nbsp;query&nbsp;=&nbsp;</font><font color="#7f0055"><b>new&nbsp;</b></font><font color="#000000">ProxyServiceQuery</font><font color="#000000">()</font><font color="#000000">;</font><br /><br />
<font color="#ffffff"></font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f7f5f">//&nbsp;We&nbsp;look&nbsp;for&nbsp;a&nbsp;PS&nbsp;whose&nbsp;transport&nbsp;is&nbsp;HTTP,&nbsp;WSDL&nbsp;and&nbsp;qualified</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">query.setTransportScheme</font><font color="#000000">(</font><font color="#000000">HTTP_TRANSPORT_SCHEME</font><font color="#000000">)</font><font color="#000000">;</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">query.setWSDLBasedService</font><font color="#000000">(</font><font color="#7f0055"><b>true</b></font><font color="#000000">)</font><font color="#000000">;</font><br /><br />
<font color="#ffffff"></font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>if&nbsp;</b></font><font color="#000000">(</font><font color="#000000">enable</font><font color="#000000">)</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">query.setServiceEnabled</font><font color="#000000">(</font><font color="#7f0055"><b>false</b></font><font color="#000000">)</font><font color="#000000">;</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>else</b></font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">query.setServiceEnabled</font><font color="#000000">(</font><font color="#7f0055"><b>true</b></font><font color="#000000">)</font><font color="#000000">;</font><br /><br />
<font color="#ffffff"></font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f7f5f">//&nbsp;Name&nbsp;of&nbsp;the&nbsp;service&nbsp;to&nbsp;look&nbsp;for</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">query.setLocalName</font><font color="#000000">(</font><font color="#000000">proxyServiceName</font><font color="#000000">)</font><font color="#000000">;</font><br /><br />
<font color="#ffffff"></font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">Ref&nbsp;proxyServiceRef&nbsp;=&nbsp;</font><font color="#7f0055"><b>null</b></font><font color="#000000">;</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">Set&lt;Ref&gt;&nbsp;refs&nbsp;=&nbsp;alsbConfMB.getRefs</font><font color="#000000">(</font><font color="#000000">query</font><font color="#000000">)</font><font color="#000000">;</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">System.out.println</font><font color="#000000">(</font><font color="#2a00ff">&#34;DEBUG:&nbsp;Found&nbsp;resources&nbsp;that&nbsp;&#34;</font><font color="#000000">)</font><font color="#000000">;</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>for&nbsp;</b></font><font color="#000000">(</font><font color="#000000">Ref&nbsp;ref&nbsp;:&nbsp;refs</font><font color="#000000">)&nbsp;{</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">System.out.println</font><font color="#000000">(</font><font color="#000000">ref&nbsp;+&nbsp;</font><font color="#2a00ff">&#34;&nbsp;Project&nbsp;name:&nbsp;&#34;&nbsp;</font><font color="#000000">+&nbsp;ref.getProjectName</font><font color="#000000">())</font><font color="#000000">;</font><br /><br />
<font color="#ffffff"></font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>if&nbsp;</b></font><font color="#000000">(</font><font color="#000000">ref.getProjectName</font><font color="#000000">()</font><font color="#000000">.equalsIgnoreCase</font><font color="#000000">(</font><font color="#000000">projectName</font><font color="#000000">))&nbsp;{</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">proxyServiceRef&nbsp;=&nbsp;ref;</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>break</b></font><font color="#000000">;</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">}</font><br /><br />
<font color="#ffffff"></font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">}</font><br /><br />
<font color="#ffffff"></font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f7f5f">//&nbsp;If&nbsp;we&nbsp;have&nbsp;found&nbsp;the&nbsp;&nbsp;proxy&nbsp;service...</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>if&nbsp;</b></font><font color="#000000">(</font><font color="#000000">proxyServiceRef&nbsp;!=&nbsp;</font><font color="#7f0055"><b>null</b></font><font color="#000000">)&nbsp;{</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">System.out.println</font><font color="#000000">(</font><font color="#2a00ff">&#34;Realizing&nbsp;changes&nbsp;in&nbsp;the&nbsp;session:&nbsp;&#34;&nbsp;</font><font color="#000000">+&nbsp;sessionName</font><font color="#000000">)</font><font color="#000000">;</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">ProxyServiceConfigurationMBean&nbsp;proxyServiceConfigurationMBean&nbsp;=</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">(</font><font color="#000000">ProxyServiceConfigurationMBean</font><font color="#000000">)</font><font color="#000000">domainService.findService</font><font color="#000000">(</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">ProxyServiceConfigurationMBean.NAME&nbsp;+&nbsp;</font><font color="#2a00ff">&#34;.&#34;&nbsp;</font><font color="#000000">+&nbsp;sessionName,</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">ProxyServiceConfigurationMBean.TYPE,&nbsp;</font><font color="#7f0055"><b>null</b></font><font color="#000000">)</font><br /><br />
<font color="#ffffff"></font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>if&nbsp;</b></font><font color="#000000">(</font><font color="#000000">enable</font><font color="#000000">)&nbsp;{</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">proxyServiceConfigurationMBean.enableService</font><font color="#000000">(</font><font color="#000000">proxyServiceRef</font><font color="#000000">)</font><font color="#000000">;</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">}&nbsp;</font><font color="#7f0055"><b>else&nbsp;</b></font><font color="#000000">{</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">proxyServiceConfigurationMBean.disableService</font><font color="#000000">(</font><font color="#000000">proxyServiceRef</font><font color="#000000">)</font><font color="#000000">;</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">}</font><br /><br />
<font color="#ffffff"></font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f7f5f">//&nbsp;activate&nbsp;changes&nbsp;performed&nbsp;in&nbsp;the&nbsp;session</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">sessionManagementMBean.activateSession</font><font color="#000000">(</font><font color="#000000">sessionName,&nbsp;</font><font color="#2a00ff">&#34;Activate&nbsp;changes&nbsp;made&nbsp;in&nbsp;the&nbsp;session:&nbsp;&#34;&nbsp;</font><font color="#000000">+&nbsp;sessionName</font><font color="#000000">)</font><font color="#000000">;</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">done&nbsp;=&nbsp;</font><font color="#7f0055"><b>true</b></font><font color="#000000">;</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">}</font><br /><br />
<font color="#ffffff"></font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">}&nbsp;</font><font color="#7f0055"><b>catch&nbsp;</b></font><font color="#000000">(</font><font color="#000000">Throwable&nbsp;t</font><font color="#000000">)&nbsp;{</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">&lt;omitted&gt;</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">}</font><br /><br />
<font color="#ffffff"></font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">System.out.println</font><font color="#000000">(</font><font color="#2a00ff">&#34;End&nbsp;of&nbsp;program&#34;</font><font color="#000000">)</font><font color="#000000">;</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>return&nbsp;</b></font><font color="#000000">done;</font><br /><br />
<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">}</font><br /><br />
<font color="#000000">}</font></code><br />
    <br />
   </td><br />
  <!-- end source code --><br />
   </tr><br />
  <!-- start Java2Html link --><br />
   <tr><br />
    <td align="right"><br />
<small><br />
<a href="http://www.java2html.de" target="_blank">Java2html</a><br />
</small><br />
    </td><br />
   </tr><br />
  <!-- end Java2Html link --><br />
</table><br />
</div><br />
<!-- =       END of automatically generated HTML code       = --><br />
<!-- ======================================================== --></p>

<p>Takayuki Imanishi took a different approach to solving this problem. He opted to use 
the WebLogic Scripting Tool (WLST) which is based on the Python programming language. The following
script both disables and enables the same proxy service. Not very useful in itself, but it does show
you how to enable or disable a proxy service using WLST.</p>
<code>
from java.lang import String<br>
from com.bea.wli.monitoring import StatisticType<br>
from com.bea.wli.config import Ref<br>
from com.bea.wli.sb.util import Refs<br>
from com.bea.wli.sb.management.configuration import CommonServiceConfigurationMBean<br>
<br>
import sys<br>
# Connect  (username, password, URL)<br>
connect('weblogic', 'weblogic', 't3://localhost:7001')<br>
<br>
domainRuntime()<br>
<br>
# Create a session name<br>
sessionName = sessionName = String("SessionScript"+Long(System.currentTimeMillis()).toString())<br>
<br>
# Get the session MBean and create a session<br>
SessionMBean = findService("Session","com.bea.wli.config.mbeans.SessionMBean")<br>
SessionMBean.createSession(sessionName)<br>
print(String('Session was created ... ').concat(sessionName))<br>
<br>
# Get the ProxyServiceConfigurationMBean specific to our session<br>
mbean = findService(String("ProxyServiceConfiguration.").concat(sessionName),<br>
&nbsp;&nbsp;&nbsp;'com.bea.wli.sb.management.configuration.ProxyServiceConfigurationMBean')<br>
<br>
# Creates a reference to a folder. Here 'TestCase1' is the project name<br>
# and 'ProxyServices' is a folder in the project<br>
folderRef = Refs.makeParentRef('TestCase1/ProxyServices/')<br>
<br>
# Now you can get the proxy service by name<br>
proxyRef = Refs.makeProxyRef(folderRef, 'case1_MQ1_lq01')<br>
<br>
# and disable it,<br>
mbean.disableService(proxyRef)<br>
<br>
# or enable it<br>
mbean.enableService(proxyRef)<br>
<br>
# Now commit (activate) the changes<br>
SessionMBean.commitSession(sessionName)<br>
<br>
print<br>
print('... completed')<br>
print<br>
<br>
disconnect()<br>
exit()<br></code>

<h2>That's all for now</h2>
<p>Until next time, keeps your hands dirty and your code clean!</p>]]>
      
   </content>
</entry>

<entry>
   <title>The Changing Face of Open Source</title>
   <link rel="alternate" type="text/html" href="http://blogs.oracle.com/jeffdavies/2009/01/the_changing_face_of_open_sour.html" />
   <id>tag:blogs.oracle.com,2009:/jeffdavies//422.9677</id>
   
   <published>2009-01-14T22:49:00Z</published>
   <updated>2009-10-01T16:47:49Z</updated>
   
   <summary>I&apos;ve been involved in open source for many years now, both as a consumer and a provider. In 2000 I started a project (as yet unfinished and now defunct) for a UML modeling tool called Thorn (http://sourceforge.net/projects/thorn/). Back then the...</summary>
   <author>
      <name>jeff.x.davies</name>
      
   </author>
   
      <category term="Architect" scheme="http://www.sixapart.com/ns/types#category" />
   
      <category term="Developer" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="xmlslowarchitecturexquery" label="XML slow architecture XQuery" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="en" xml:base="http://blogs.oracle.com/jeffdavies/">
      <![CDATA[<p>I've been involved in open source for many years now, both as a consumer and a provider. In 2000 I started a project (as yet unfinished and now defunct) for a UML modeling tool called Thorn (<a href="http://sourceforge.net/projects/thorn/">http://sourceforge.net/projects/thorn/</a>). Back then the web was still new, but a lot of infrastructure was already in place for creating robust open source projects. <a href="http://www.junit.org/">JUnit</a> wasn't exactly new, but it was (and still is) a great tool. <a href="http://abbot.sourceforge.net/doc/overview.shtml">Abbot</a> was a tool for testing user interfaces. </p>

<p>Online documentation was maturing from simple text files to complete suites of HTML pages that you could access locally. JavaHelp was available for creating a help system that was available from within your Swing application. Of course, JavaDoc was available for developing the documentation needed by the developers that you might coax into helping with your open source project. <a href="http://ant.apache.org/">Ant</a> was available and was the primary build system of choice.</p>

<p>Fast-forward nine years and I find myself working on another open source project, this one called StarBridge (<a href="http://jeffdavies.org/starbridge">http://jeffdavies.org/starbridge </a> not on SourceForge yet). Its a small utility program designed to work with another open source project called Celestia (<a href="http://www.shatters.net/celestia/">http://www.shatters.net/celestia/</a>). Celestia is a "space simulation" program that allows you to view the stars from anywhere in the universe. It works on PC, Mac and Linux platforms and is really a beautiful piece of work. I love the program but I wanted a way to get current satellite information into the Celestia program quickly and easily. Believe it or not, satellite orbits change significantly over time, as does the orbit of the International Space Station. The information on satellite orbits is updated on a daily basis, but the format for that data is not very "people friendly". So I embarked on writing my StarBridge utility to help move information into Celestia.</p>

<p>One of the great things about getting older is that you already know a lot and don't have to spend as much time learning new things. One of the drawbacks of getting older is that many of the things you thought you knew have changed. Open source technologies are no exception. Much has changed since 2000. Lets review some of those changes and how they can bite you if you are living on past assumptions.</p>

<p><strong><u>Swing is the Thing!</u></strong></p>

<p>As I started on my little StarBridge utility program, I decided to write it in Swing and to provide a command line interface (as all good utilities should have). The command line was pretty simple, of course. Swing however presented some interesting changes.</p>

<p>The Swing API has not changed much in the last 9 years, which I think is a testament to its flexible/extensible design. I do hear people disparage Swing, especially with regard to its speed. I wonder how many of them have first-hand experience with the speed issue. The work I've done with Swing has always shown me that Swing is pretty darned fast, instantaneous for my applications at least. </p>

<p>One thing that has changed with Swing is the improved guidance for creating threads. Threading has always been a challenging topic for many engineers and threading in Swing is no exception. The Java designers have seen fit to provide a uniform method for starting the GUI aspects of a Swing application in their own thread. The code below shows how this is done:</p>

<p><code>SwingUtilities.invokeLater(new Runnable() {<br />
&nbsp;&nbsp;&nbsp;public void run() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;createAndShowGUI();<br />
&nbsp;&nbsp;&nbsp;}<br />
});</code></p>

<p>Now many of the older Swing apps DO NOT do this, but that is acceptable. However, Swing developers are now encouraged to take this appraoch in order to ensure that their GUI is running in the event dispatching thread, rather than the main thread of the application.</p>

<p><strong><u>How Good Tools Get Bad Names</u></strong><br />
<strong>(a.k.a. XML Beans is Slow)</strong><br />
----------------------------<br />
Next, I had to store some configuration information for the StarBridge application. In the past I have used property files, but the information that I needed to store in this utility was more hierarchical in nature, so I opted to go with XML and XML Beans instead of the traditional properties file. I also used XML Beans to store the main star data (over 113,000 stars). Reading in and generating the 113K worth of star data goes fairly quickly (a few seconds). The trouble began when I then iterated through the data, instantiating an Java object based on the XML Bean class for each star. That took 68 minutes!</p>

<p>I am convinced that this is the standard scenario for giving tools and technologies the title of, "slow". It is true that when I instatiated each XML Bean so that I could write that bean out into a different text format (the .DAT file format used by Celestia) that the process took 68 minutes. The problem here is not that XML Beans is slow though, the problem has to do with the fast that instantiating that many objects in a serial manner is slow. XML Beans just happened to be the technology I was using at the time. </p>

<p>The lesson here is that it is very tempting to decry a tool or technology as being slow, especially when we don't understand it. I cant tell you how many times I've talked with people that say XML is slow. For example one company I spoke with was telling me that XML is slow because when they pass a loan document from server to server it takes a, "long time". Ok, I certainly believe them. We all know slow when we see it. So I asked a few questions to try to discover the reason for this slowness:</p>

<p><strong>Q:</strong> "How large is the document?"<br />
<strong>A: </strong>"About 150 megabytes", </p>

<p>Now that seemed a little large to me, even for a complex message. </p>

<p><strong>Q: </strong>"What goes into this 150MB message?"<br />
<strong>A:</strong> "Oh, lots of information, including PDF files and some JPEGs."</p>

<p><strong>Q:</strong> "The transmission time alone on 150MB can add up. Do you need to pass around the images and the PDF files inside of the message? Couldn't they be stored on a server farm and referred to in the main message?"<br />
<strong>A: </strong>"Well, that's the way we designed the system 10 years ago, and all of our existing systems rely on that architecture."</p>

<p><strong>Q: </strong>"Ok, fair enough. The transmission times for 150 MB alone can't account for the slowness you've described. Anything else that you think contributes to the slowness?"<br />
<strong>A:</strong> "Well we have to examine the information within the document and route it appropriately several time. As soon as we added that routing logic, it really slowed down. The XPath and XQuery engines are real dogs!"</p>

<p>I think you can see where I am going with this. The customer wasn't just passing a large document around the network. Every time the customer performed any conditional routing to the message, the entire 150MB of message had to be realized into memory and examined. That does take time, especially when you have a lot of those messages whizzing around your network being realized into memory repeatedly. Putting some SOAP headers into the message that contained the data upon which routing logic depended would have addressed the second problem, and taking the time to store the static elements of the message outside of the message itself would have alleviated the transmission time costs tremendously.</p>

<p>The problem that the customer had was not that XML was slow, but that their architecture was slow. Whether those messages were passed around in XML, or Java RMI or some binary format would have little effect on the performance. The bottleneck was their architecture. But no one wants to blame their architecture. </p>

<p>Its much easier to blame a technology you don't really understand. We are all guilty of this. The first time I used XML Beans for that star information and it took 68 minutes to complete, I thought to myself, "uh oh, did I chose a bad technology for this?"</p>

<p>There is no substitute for understanding and real expertise. It is not a question of intelligence. Being smart does not keep us from making these snap judgments. Hopefully, our experience will help us to resist the temptation to blame the tools, especially new tools that we are still learning to use efficiently. A car with square wheels wont go very fast, no matter what size engine you install.</p>

<p>Oh and that 68 minute problem I had; the solution was pretty simple. I just used an XmlInputStream instead and parsed the input stream instead of instantiating the whole object. That dropped the time back down to several seconds for a 35MB document.</p>

<p><strong><u>Open Source Publishing?</u></strong><br />
The other interesting thing I've discovered is that publishing is changing radically. It used to be that you would create a User's Guide for your open source project and include that guide in your ZIP or JAR file. Not any longer. While I have known of and used Wikipedia for years now, I was completely unaware of <a href="http://en.wikibooks.org/wiki/Main_Page">Wikibooks</a>! People are now writing their books using Wikibooks. Its simple and free. People that like to write are often <u><em>not</em></u> developers. As a result, they are often not familiar with the standard tools we developers know and love (like <a href="http://www.sourceforge.net">SourceForge </a>and <a href="http://subversion.tigris.org/">Subversion</a>). Wikibooks allows people interested in writing to contribute to your documentation without having to be developer-savvy. Beisdes, what is the benefit of including documentation in your project if you can just refer to it instead? Just like the story I told earlier about passing around the 150MB document, you are much better off storing the relatively static information elsewhere (wikibooks) and simply referring to it from within your project.</p>

<p><strong><u>The Bookshelf</u></strong><br />
And speaking of books, I thought I'd mention a couple of books that I have recently read. I have a ton of books on my bookshelf and I thought it might be a good idea to share some of my favorites with you.</p>

<p><strong>Swing A Beginner's Guide </strong>- Herbert Schildt (McGraw Hill)<br />
Even though I have done a fair bit of work with Swing in the past, it had been so long that I felt a refresher course would be a good idea. In this book Herbert Schildt does a good job of walking the reader through the major elements of Swing that every Swing developer ought to know. The book is well written and easy to read. I found a fair bit of value in it just because it covered the basics so well.</p>

<p><strong>Java Concurrency in Practice</strong> - Brian Goetz, et. al. (Addison Wesley)<br />
A good guide to threading in Java. Talks about threading in fairly simple terms and is up-to-date for Java 1.6, which was important to me. Definitely a good book to have handy if you are writing (or better yet, about to write) a multi-threaded application. Even a simple tool like StarBridge benefited from understanding the Java threading model better.</p>

<p><strong><u>Ask the Experts</u></strong><br />
John Graves provided the following tip for scripting Oracle Service Bus. This script will turn on monitoring for all proxy servies in ann environment. Not only is the script itself handy, its also a great example of using the WebLogic Scripting Tool (WLST) to solve real-world problems. <br />
Thanks John!<br />
<code>from com.bea.wli.sb.management.configuration import SessionManagementMBean<br />
from com.bea.wli.sb.management.configuration import ALSBConfigurationMBean<br />
from com.bea.wli.sb.management.configuration import ProxyServiceConfigurationMBean<br />
from com.bea.wli.config import Ref</p>

<p>adminURL="t3://localhost:7001";<br />
serverName="AdminServer";<br />
username="weblogic";<br />
password="weblogic";</p>

<p>#=======================================================================================<br />
# Utility function to load a session MBeans<br />
#=======================================================================================<br />
def getSessionMBean(sessionName):<br />
&nbsp;&nbsp;&nbsp;SessionMBean = findService(SessionManagementMBean.NAME,SessionManagementMBean.TYPE)<br />
&nbsp;&nbsp;&nbsp;SessionMBean.createSession(sessionName)<br />
&nbsp;&nbsp;&nbsp;return SessionMBean</p>

<p>connect(username,password,adminURL)<br />
domainRuntime()</p>

<p>sessionName = String("SessionScript"+Long(System.currentTimeMillis()).toString())<br />
smb = getSessionMBean(sessionName)<br />
alsbSession = findService(String(ALSBConfigurationMBean.NAME + ".").concat(sessionName), ALSBConfigurationMBean.TYPE)<br />
psConfig = findService(String(ProxyServiceConfigurationMBean.NAME + ".").concat(sessionName),ProxyServiceConfigurationMBean.TYPE)</p>

<p>allRefs=alsbSession.getRefs(Ref.DOMAIN)<br />
for ref in allRefs:<br />
&nbsp;&nbsp;&nbsp;typeId = ref.getTypeId()<br />
&nbsp;&nbsp;&nbsp;if typeId == "ProxyService":<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print "Enabling Monitoring for: " + ref.getFullName()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;psConfig.enableMonitoring(ref)</p>

<p>smb.activateSession(sessionName, "Turn on proxy monitoring")</p>

<p>disconnect()<br />
exit()<br />
</code></p>

<p>That's all for now. Keep your code clean and your hands dirty!</p>

<p>- Jeff<br />
</p>]]>
      
   </content>
</entry>

<entry>
   <title>More from the Architect&apos;s Dictionary</title>
   <link rel="alternate" type="text/html" href="http://blogs.oracle.com/jeffdavies/2008/11/more_from_the_architects_dictionary.html" />
   <id>tag:blogs.oracle.com,2008:/jeffdavies//422.8644</id>
   
   <published>2008-11-17T22:18:00Z</published>
   <updated>2008-11-17T22:44:16Z</updated>
   
   <summary>Architect’s Dictionary #2 From my last blog entry that contained a section on the “Architect’s Dictionary” I received several email asking for more definitions. I have included threeof them here. I do not have them sorted alphabetically. Instead I present...</summary>
   <author>
      <name>jeff.x.davies</name>
      
   </author>
   
      <category term="SOA" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="http://blogs.oracle.com/jeffdavies/">
      <![CDATA[<h1>Architect’s Dictionary #2</h1>
<p>From my last blog entry that contained a section on the “Architect’s Dictionary” I received several email asking for more definitions. I have included threeof them here. I do not have them sorted alphabetically. Instead I present them in the order that they should be understood.</p>
<h2>Service</h2>
<p>I touched on this in my last blog entry but I thought it was worth a full description. Since services are at the heart of SOA, a solid understanding of what a service is seems in order. There is a weird cloud of mysticism around the definition of a service. I hear people say things like “services aren’t just web services” or “you can write services using [EJB | CORBA | .NET | Tuxedo | etc]”. However, ask these experts to define the term “service” and they usually have a lot of difficulty doing so. Which brings us to a basic principle of any type of engineering: if you can’t define it, you sure as heck can’t build it.</p>
<p>Fortunately, services are not mystical or magical. They are dead simple. You know what a service is, even if you can’t articulate it succinctly. You know what a “service” is because you live and work with services every day. You get electrical service from your local utility company, internet service from your phone/cable company and you get food service every time you go into a restaurant.</p>
<p>For some reason, when people start talking about services in the software architecture world, things suddenly become more complicated than they need to be. Shun that complexity; embrace the simplicity that is at the core of services. Simply put, <i>a service is when I (the service consumer) ask you (the service provider) to do some work on my behalf and you perform that work in the manner I expect and within the timeframe that I expect, without involving me in the work.</i></p>
<p>It’s just that simple. Let’s examine services that you commonly use today, and then we can take a look at how these principles translate into the world of enterprise architecture and SOA.</p>
<h3>Food Service</h3>
<p>Imagine that you are in a restaurant and you tell the waiter that you want a cheeseburger with potato salad on the side and an iced tea for the drink. If the waiter returns with your food but gives you a steak instead of a hamburger, he has not met your expectations (i.e. the manner I expect). The same is true if the waiter delivers the meal that you ordered but it is cold or uncooked. Again, the service has failed because the result does not meet your expectations.</p>
<p>Similarly, if the waiter returns with you food, cooked just the way you ordered it, but it takes him 4 hours to return with t he food, he has again failed to meet your expectations with regard to the time frame. Now imagine that the waiter tells you “Sir, we can fulfill you order, but we need you to come back into the kitchen to cook the meat.” Once again, they cease to provide a service at that point. If you have to do the work, they aren’t providing a service, they are simply helping you do the work.</p>
<h3>Electrical Service</h3>
<p>The same pattern works for electrical service from your local utility company. When I come home at night and turn on the light switch, I fully expect to see the lights come on. Similarly, when I order new electrical service for my new home or apartment, I set a date of delivery when I expect that service to become active. Usually unstated is my expectation that I expect the voltage to match whatever is commonly used in my country. If the service provider fails to meet any of these expectations, they have failed to deliver the service.</p>
<h3>Services in SOA</h3>
<p>I hope the two previous examples struck you as being obvious, they should be. We all know what a service is. All we need to do is apply our common sense definition of a “service” to SOA</p>
<h2>Translation & Transformation</h2>
<p>The terms “translation” and “transformation” are often used together, or interchangeably. While it is technically correct to understand their differences, using them both in the same sentence often strikes me as, “over kill”.</p>
<h3>Translation</h3>
<p>“Translation” is simply the process of converting the content from one for to another. For example, I can translate a sentence from English, “I am hungry”, into Spanish, “Yo tengo hambre”. In terms of XML, an example of translation is:</p><p><code>
&lt;item&gt;<br>
&nbsp;&nbsp;&nbsp;&lt;name&gt;Stereo Speakers&lt;/name&gt;<br>
&nbsp;&nbsp;&nbsp;&lt;price&gt;10.95&lt;/price&gt;<br>
&lt;/item&gt;
</code></p>
<p>Can be translated into Spanish, using the Euro for the price.</p>
<p><code>
&lt;item&gt;<br>
&nbsp;&nbsp;&nbsp;&lt;name&gt;Altavoces estéreos&lt;/name&gt;<br>
&nbsp;&nbsp;&nbsp;&lt;price&gt;8.53&lt;/price&gt;<br>
&lt;/item&gt;
</code></p>
<p>Notice that the translation did not change for form of the information itself, only the content.</p>
<h3>Transformation</h3>
<p>Transformation involves changing the structure of the information, without changing the content. Using our previous example under translation, we can see how transformation works:</p><p><code>
&lt;item&gt;<br>
&nbsp;&nbsp;&nbsp;&lt;name&gt;Stereo Speakers&lt;/name&gt;<br>
&nbsp;&nbsp;&nbsp;&lt;price&gt;10.95&lt;/price&gt;<br>
&lt;/item&gt;<br>
</code></p>
<p>Can be transformed into:</p>
<p><code>
&lt;product&gt;<br>
&nbsp;&nbsp;&nbsp;&lt;name&gt;Stereo Speakers&lt;/name&gt;<br>
&nbsp;&nbsp;&nbsp;&lt;cost&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;10.95&lt;/value&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;currency&gt;USD&lt;/currency&gt;<br>
&nbsp;&nbsp;&nbsp;&lt;/cost&gt;<br>
&lt;/product&gt;
</code></p>
<p>From this example you can see that we did not change the contents themselves (beyond adding a currency tag with its contents). We did change the form of the information though. The key thing to remember is that while translation and transformation are different, they almost always appear together when providing loose coupling between different information systems.</p>

<h2>Location Transparency</h2>
<p>Location transparency is a fancy term for loosely coupling the service consumer from the service provider, with regard to the physical location of the service provider. You use location transparency every time you use the web. If you browse the URL http://www.oracle.com you are using a logical name to access the Oracle web site. Oracle maintains numerous web servers that are mapped to that logical name. You have no idea where the specific web server is (and you really don’t even want to know). On the web, it is common to find a DNS load balancer distributing requests amongst any number of backend servers that do the real work in fulfilling your web requests. Location transparency is a simple concept, yet a powerful tool when it comes to loosely coupling information systems. It is just as applicable in SOA as it is in any other architecture.</p>

<h2>Enterprise Service Bus</h2>
<p>There has been a lot of buzz over the last few years over the Enterprise Service Bus (ESB). Books have been published, as have articles, creating a lot of hype. It may seem as though the only tool you need for SOA is an ESB, or if you have an ESB, then you automatically have an SOA. As is usually the case with any type of hype, these assumptions simply are not true.</p>

<p>One of the problems with the term ESB is that it has so single definition, no agreed upon set of functionality. Different vendors sell “ESBs” with wildly varying functionality. This is completely unlike the J2EE application server market, where there is a well defined specification.</p>

<p>Here I will define what an ESB means to me (and largely to Oracle also, though I make no claim to speak for my own company). I will define the functionality that I expect from any product that claims the title of ESB and attempt to explain the benefits of these features.</p>

<p>Too often I hear people equate an ESB with messaging. “An ESB is really just a messaging engine” is one of the most common misconceptions I hear in the field. This is false on its face. If an ESB was only about messaging, then any messaging system or technology would claim to be an ESB (and some do make that claim). Most J2EE application servers provide JMS capabilities. Are these application servers ESBs? Of course they are not. Obviously, an ESB makes extensive use of a messaging engine, but messaging alone is not enough to claim to be an ESB.</p>

<p>An ESB is a tool that really has a single purpose in enterprise architecture, to provide a mediation layer between service consumers and service providers. Mediation itself is not a feature, but an architectural approach that provides numerous benefits when combined with important capabilities like translation, transformation and location transparency (see above). Here is my list of features that I think an ESB must have to meet today’s demands.</p>
<ul>
<li>Mediation</li>
<li>Location Transparency</li>
<li>Configuration based, not “coded”</li>
<li>Messaging</li>
<li>Publish/Subscribe</li>
<li>Conditional Routing</li>
<li>Content-based Routing</li>
<li>Synchronous & Asynchronous Invocation</li>
<li>Monitoring, Reporting and Alerting</li>
<li>Clustering for Failover, Scalability and High Availability</li>
<li>Translation and Transformation</li>
<li>Industry standards for connectivity and integration</li>
</ul>
<p>The key areas where messaging alone usually falls short are:</p>
<li>Mediation</li>
<li>Location Transparency</li>
<li>Configuration based, not “coded”</li>
<li>Conditional Routing</li>
<li>Content-based Routing</li>
<li>Monitoring, Reporting and Alerting</li>
<li>Clustering for Failover, Scalability and High Availability</li>
<li>Translation and Transformation</li>
<li>Industry standards for connectivity and integration</li>

<p>By providing a flexible, configurable mediation layer between the service consumer and the service provider, and ESB is a key technology and is a critical component in achieving the promised agility of SOA.</p>

<h1>Ask the Experts</h1>
<p>For this installment, I have selected several short questions:</p>

<p><font size="4" style="bold">Q</font> How do I integrate OSB with Cobol and RPG programs running on an AS/400?</p>
<p><font size="4" style="bold">A</font> Check out the information at <a href="http://dev2dev.bea.com/pub/a/2007/04/alsb-ifiveos.html">http://dev2dev.bea.com/pub/a/2007/04/alsb-ifiveos.html</a></p>
<hr width="50%">
<p><font size="4" style="bold">Q</font> What happens when I hot-deploy a change to an existing proxy service?</p>
<p><font size="4" style="bold">A</font> Side by side deployment is, sort of, built in to OSB in that an old version of a proxy service self-deprecates when the last in-flight message is fully processed. If you update a proxy service and deploy it, the old service will not process any new messages but it will finish processing any in-flight messages until it’s done with them. As soon as the new service is deployed, all new incoming messages are processed by it, not by the old version. There’s nothing to configure, no knobs to turn or bells to ring. Its automagic (thanks to Steve Waterhouse for this answer).</p>
<hr width="50%">
<p><font size="4" style="bold">Q</font> How do I integrate OSB 10gR3 with Oracle BPEL engine?</p>
<p><font size="4" style="bold">A</font> This is a very common question and full documentation can be found here: <a href="http://download.oracle.com/docs/cd/E13159_01/osb/docs10gr3/bpelpmtransport/">http://download.oracle.com/docs/cd/E13159_01/osb/docs10gr3/bpelpmtransport/</a></p>

<p>Until next time, keep your hands dirty and your code clean!</p>

<p><i>- Jeff</i></p>]]>
      
   </content>
</entry>

<entry>
   <title>Architect&apos;s Dictionary</title>
   <link rel="alternate" type="text/html" href="http://blogs.oracle.com/jeffdavies/2008/10/architects_dictionary.html" />
   <id>tag:blogs.oracle.com,2008:/jeffdavies//422.7937</id>
   
   <published>2008-10-05T20:45:30Z</published>
   <updated>2008-10-05T21:38:59Z</updated>
   
   <summary>Last week at Oracle Open World I had the opportunity to meet a number of folks interested in Oracle products in general and SOA in particular. One gentleman that I spoke with was very technical, but asked me to explain...</summary>
   <author>
      <name>jeff.x.davies</name>
      
   </author>
   
      <category term="SOA" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="http://blogs.oracle.com/jeffdavies/">
      <![CDATA[<p>Last week at Oracle Open World I had the opportunity to meet a number of folks interested in Oracle products in general and SOA in particular. One gentleman that I spoke with was very technical, but asked me to explain what I meant by, “point-to-point integration”. At first, the question surprised me. Then I realized that I use terms like “point-to-point” and, ‘EAI” so often that I’ve simply come to assume that everyone knew what they meant. This is a hazard of specialization in any field: you assume that everyone you speak with not only recognizes your particular jargon, but also that they have the same definition for those terms that you do.</p>
<p>So I am starting a new section for the blog, The Architect’s Dictionary, where I define some commonly used (and misused) terms from SOA and enterprise architecture. As always, I invite alternate opinions and well-thought argument.</p>
<h2>Point-to-Point Integration</h2>
<p>Point-to-Point (abbreviated to P2P for the purposes of this dictionary) occurs when the IT systems are directly integrated with every other IT system from which they either consume information or provide information. Here is an area where a picture is worth a thousand words (see Figure 1).</p>
<p><a href="http://blogs.oracle.com/jeffdavies/2008/10/05/images/Point-to-Point.html" onclick="window.open('http://blogs.oracle.com/jeffdavies/2008/10/05/images/Point-to-Point.html','popup','width=652,height=499,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false">
<img alt="Point-to-Point.jpg" src="http://blogs.oracle.com/jeffdavies/2008/10/05/images/Point-to-Point.jpg" width="430" height="330" />
</a><br>
<em>Figure 1 Typical Point-to-Point Integration</em></p>
<p>Figure 1 shows a typical P2P integration. The OrderPortal application needs information from the following applications: </p>
<table width="100%" border="1">
<tr><td>Application</td><td>Integration Type</td></tr>
<tr><td>ProductCatalog</td><td>Direct call to the product catalog’s database</td></tr>
<tr><td>InventoryManagement</td><td>Uses the SAP BAPI interface</td></tr>
<tr><td>CreditCheck</td><td>Invokes a web service to get the credit information from the externally hosted credit service bureau</td></tr>
<tr><td>CRM</td><td>Uses a Java Connectivity Adapter (JCA) to access the CRM (Customer Relationship Management) system</td></tr>
<tr><td>OrderManagement</td><td>Sends a file containing the submitted order information via FTP.</td></tr>
<tr><td>BillingSystem</td><td>Uses the VT100 wire protocol to request information from the billing system</td></tr>
<tr><td>FullfillmentM</td><td>A typical EJB application</td></tr>
</table>
<p>This is typical of any P2P. Systems are directly integrated with each other. There is virtually no abstraction of information between systems and for good reason: since you need to know so much about the systems with which you are integrating (i.e. authentication, physical location, specific API version and transport technology) why would you waste any time trying to create a higher level of abstraction between the systems?</p>
<strong>P2P Benefits</strong>
<p>Contrary to popular belief, P2P is not the work of the devil. There are times when P2P is the right approach to your integration challenges. Integrating systems using this approach is usually very fast because you don’t have to do much thinking ahead of time. Just connect the systems as specified by their various APIs and you are done. Because the integration time is generally quick, the initial integration projects cost less (time = money). Furthermore, the data exchange speeds between the systems is usually very fast because there are no mediation layers between the systems to add any overhead (other than the usual machine and process boundaries). It is because of these benefits that P2P is the most common integration patter in use today.</p>
<strong>P2P Drawbacks</strong>
<p>From the diagram you can begin to see how the P2P approach begins to introduce complex interdependencies to your IT system. The above diagram only shows 8 systems and their common relationships. Odds are that your IT environment has anywhere between a dozen applications to many thousands. A direct result of P2P is a rat’s nest of tightly coupled systems. Every time you upgrade any application, the interfaces of that application are likely to have changed. This requires you to modify all of the applications that depend on the upgraded application. So, while P2P is fast and cheap to start, it is slow and expensive to maintain over any length of time. The more your applications change over time (and the more applications that you have), the more time and money you spend on just maintaining what you have. That means you have less time and money to innovate, and to meet rapidly changing business demands. It is this lack of agility in the IT shops of the world</p>
<h2>Enterprise Application Integration (EAI)</h2>
<p>In the 1990’s, Enterprise Resource Planning (ERP) systems were becoming increasingly common in large enterprises. Integrating with these ERPs became imperative. People were beginning to understand that data and processes belonged to the enterprise as a whole, and not specific applications. Many vendors recognized this pattern and set about to create tooling that would ease the integration problems by providing a platform for integration. This was the birth of EAI.</p>
<p>One of the easiest ways to understand EAI is to think of it as the mother of all integrations. All integration logic lives in the EAI platform. EAI is also known as, “spoke-and-hub architecture” and you can see why from the following diagram.</p>
<p><a href="http://blogs.oracle.com/jeffdavies/2008/10/05/images/EAI.html" onclick="window.open('http://blogs.oracle.com/jeffdavies/2008/10/05/images/EAI.html','popup','width=608,height=387,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img alt="EAI.jpg" src="http://blogs.oracle.com/jeffdavies/2008/10/05/images/EAI.jpg" width="401" height="255" />
</a><br>
<em>Figure 2 The EAI "Spoke and Hub" Integration Pattern</em></p>
<strong>EAI Benefits</strong>
<p>EAI does provide a number of benefits over the P2P approach. First, it reduces the number of system integration points to anywhere from n to n * 2, where n is the number applications you are integrating. At its worst case, P2P might give you n * (n-1) integrations. Reducing the number of integration points saves time and money, especially when making changes to an existing system.</p>
<p>EAI also centralizes the inter-application business logic. This provides for greater control of how business logic is implemented in the IT environment. If the business logic changed, you only had to make the necessary changes in the EAI system and you could be pretty darned sure that you had covered your bases. In a P2P environment, business logic was scattered across all applications.</p>
<p>A third and final benefit of EAI is that an enterprise normally only needed a single EAI tool, and therefore a single EAI vendor. This provided the enterprise with a, “single throat to choke” since there was only one integration point, the various application vendors could not as easily point fingers at another vendor: it all came down to the EAI vendor.</p>
<strong>EAI Drawbacks</strong>
<p>The problems with the EAI approach manifested themselves over time, as EAI gained popularity throughout the ‘90s. The first problem is that the architecture itself requires centralized control. By that I mean, if you have a single IT organization that controls all of the implementations and integration in your company, EAI was fine. However, as companies globalized throughout the ‘90s and their IT organizations began to distribute their functions across the planet (IT outsourcing and off shoring), centralized IT control became impossible. You could no longer maintain a core of developers that understood the entire enterprise and how it was wired in the EAI tool. Geographically distinct departments of the global enterprise wanted to control their own IT assets and a centralized IT strategy was no longer viable.</p>
<p>A second drawback of the EAI approach is that it did not simplify integration logic. Basically all it did was to take the P2P rat’s nest of integration logic and put it all into the EAI tool itself. The only thing EAI simplified was the number of inter-system dependencies. The complex system integration logic remained. This centralized approach further complicated matters because a single mistake within the EAI integration logic could bring down the entire enterprise: all of your business logic “eggs” were now in one “basket”.</p>
<p>Along with these drawbacks came a new one, the overhead of the EAI tools acting as a mediation layer between the systems. In a pre-fiber networking era, the more messaging you did “over the wire” the slower the entire system ran. And you were paying this price in execution speed without gaining any benefits of abstraction between the systems. Messages sent from one system to another were still formatted for the specific destination system.</p>
<p>Finally, the cost to implement EAI was enormous. It forced companies to re-integrate all of their system using this new tool. The re-integration effort cost enterprises millions of dollars and provided very little benefit.</p>
<h2>SOA</h2>
<p>SOA is an architectural approach with three major objectives:
<ol>
<li>Provide comprehensive access to the functionality of the entire enterprise in a repeatable, reliable manner.</li>
<li>Leverage existing IT assets, modifying them (if needed) to plug into the new service-oriented enterprise.</li>
<li>Loosely coupling IT system, not only from each other, but even from the business logic that those systems ultimately support. IT systems should be able to change without affecting the high level business processes and services, and those same high level business processes and services should be able to change independently from the low level IT systems that provide functionality. This requires abstraction layers between IT systems and business processes.</li>
</ol>
</p>
<p>SOA is not about:
<ol>
<li>Re-writing the enterprise</li>
<li>Service-enabling every application</li></ol>
</p>
<p>SOA varies from both P2P and EAI in some subtle but very important ways. SOA embraces a “separation of concerns” approach when it comes to the integration of systems. Whereas with P2P and EAI they put all of their integration eggs into one basket, SOA separates these concerns into discrete, manageable pieces. In addition, as its name implies, SOA is a marriage of enterprise architecture and “service orientation”. Finally, SOA is a part of the overall enterprise architecture (EA), whereas P2P and EAI attempted to be a complete approach to EA. As with the previous approaches, let’s take a look at a picture of a logical SOA implementation and then describe its attributes.</p>
<p><a href="http://blogs.oracle.com/jeffdavies/images/SOA_Logical.html" onclick="window.open('http://blogs.oracle.com/jeffdavies/images/SOA_Logical.html','popup','width=1007,height=549,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false">
<img alt="SOA_Logical.jpg" src="http://blogs.oracle.com/jeffdavies/2008/10/05/images/SOA_Logical.jpg" width="664" height="362" />
</a><br>
<em>Figure 3 Logical SOA</em></p>
<p>Probably the biggest difference between SOA and the previous architectures is that SOA does not seek to replace P2P or EAI. That statement may come as a shock to many people. In practice, you will see SOA incorporating P2P and EAI subsystems. SOA is an evolutionary result of everything that we have learned in enterprise computing to date. It not only accounts for the problems we’ve discovered with P2P and EAI, but also what we have learned from early distributed computing technologies, namely CORBA, RMI, EJB, DCOM and JINI.</p>
<strong>Separation of Concerns</strong>
<p>As I stated earlier, SOA is part of Enterprise Architecture. As a result it co-exists perfectly well with P2P, EAI, Event Driven Architecture (EDA), and BPM. Figure 3 shows all of these approaches working together in a single enterprise architecture. In fact, SOA enables all of these disparate architectures to co-exist because of SOAs separation of concerns. It allows EDA, BPM specifically to do what they do best (process and event management) without having to directly connect those systems to every IT application in the enterprise. The key enabling technology for this is mediation shown in the very center of the figure.</p>
<p>Mediation is the key enabler of agility. Without mediation in your architecture, you will never achieve either business or IT agility. Mediation allows you to loosely connect systems with regard to:
<ul>
<li>Physical Location
<li>Message & Data Formats
<li>Transport Protocols
<li>Security Schemes
<li>Operating System or Platform
</ul></p>
<p>Mediation also provides an ideal architectural location to introduce the following capabilities to your enterprise architecture:
<ul>
<li>Monitoring</li>
<li>Reporting</li>
<li>Service Level Agreements</li>
<li>Routing Logic</li>
<li>Alerting</li>
</ul>
</p>
<p>All of these capabilities (and more) exist on Oracle’s Service Bus. However, not all ESBs are created equal and you will find many of these features missing from other ESBs on the market. If you don’t have these capabilities built into your mediation layer, you still won’t have the agility needed, whether your vendors uses a single product for mediation, or 5 products to achieve the same results.</p>
<strong>Service Orientation</strong>
<p>Service Orientation is really a design philosophy, not a technology issue. To understand service orientation we must first understand what a service is. For the purposes of this blog I’ll skip over the supporting documentation that I use in my book (The Definitive Guide to SOA: Oracle Service Bus, Apress) and just come to the definition of a service that I use:</p>
<blockquote><em><strong>Service:</strong></em> When I (the service consumer) ask you (the service provider or proxy) to perform some work on my behalf, and you do it in the manner I expect, within the timeframe I expect, with the quality I expect and without involving me in the work itself.</blockquote>
<p>The word, “expect” is important in that definition because it implies that there is a contract involved between the service consumer and the service provider. The contract (defined in the WSDL of a SOAP message and the SLA defined in the mediation layer) covers issues like timeliness (the response will return within 1 second or less), content (the message format and data types) and quality (the response is complete, or partial).</p>
<p>Service orientation (SO) requires the right mindset. Just as we needed to make a philosophical jump when we moved from procedural programming to object oriented programming, we need to make a similar mental leap to SO. It takes practice and discipline to make that jump, but it can be done.</p>
<strong>SOA Advantages</strong>
<p>SOA provides exponentially more agility to both the business and the IT department because of its separation of concerns. Not only are individual applications more loosely coupled through a combination of separation of concerns and mediation, but clusters of applications that are pre-integrated using P2P or EAI approaches can simply be services enabled and plugged into the mediation layer, reducing costs by leveraging existing systems. You can see how this is done in Figure 3 if you examine the EAI integration (lower-left part of the diagram) you can see how that entire subsystem is plugged into the SOA through a single adapter. It is much faster and cheaper to leverage your existing EAI integration this way.</p>
<p>SOA simplifies (and therefore reduces development and maintenance costs) service consumption. If you compare Figure 1 and Figure 3 with regard to the OrderPortal component, you can see that in Figure 3the OrderPortal component only has to integrate with the mediation layer using an industry standard like Web Services. In figure 1 the portal developer would have to know the transport protocols and APIs for all 6 IT systems to which it was connected. In Figure 3 the portal developer only needs to know 1 transport protocol and API. If you make the same comparison with figure 2, you can see that the OrderPortal developer would have to know EJB and its associated API to the EAI system. In all fairness, the EAI approach is also superior to the P2P approach, yet not as robust as the SOA approach because EAI would still force the portal developer to understand the API aspect of the other systems he needed to invoke, even though those other APIs may be wrapped up with an EJB interface.</p>
<p>Another advantage that is not visible in the diagram is the fact that the SOA mediation layer can perform message translations and transformations, allowing each client to make a “logical” (i.e. not application specific) to the enterprise and receive logical information in return. This is another form of loose coupling and agility: it allows the company to change low-level applications (either through version upgrades or installing a completely different application that performs similar functionality) without having to modify any of the service clients.
Finally, you can see in Figure 3 how both BPM and EDA (in the form of Complex Event Processing) are incorporated into the overall enterprise architecture: the service mediation layer again acts as an information bus into which these other capabilities are plugged in.</p>
<strong>SOA Drawbacks</strong>
<p>Everything in engineering is a trade-off, and SOA does not break that principle. There are areas and applications that should not be service enabled. For example, extreme real-time systems (like missile tracking and navigation) are not well suited for service enablement. This is because service mediation and message translation and transformation may add sufficient overhead to adversely impact the time requirements of these extreme real-time systems. This is not to say that the same holds true for all real-time systems. There are many systems with sub second requirements for which service enablement is still the right approach.</p>
<p>Even in the case of extreme real-time systems, it is usually preferable to service enable a portion of it. In the case of missile tracking, the various events that naturally occur (launch detection, entering national airspace and detonation) are certainly candidates for triggering services in the SOA that are designed to respond to these events. Real-time systems an SOA are not mutually exclusive.</p>
<p>Information streaming is another area where SOA is not a good choice for integration. Extract-Transform & Load (ETL) functions are still better left at the lower levels of the IT environment and should not b e run through a service mediation layer. However, just as is true with the real time systems, there are natural events that occur in ETL processes that may invoke a service in the service mediation layer. And certainly, the resulting information from an ETL process is an ideal candidate for service enablement once the ETL function has completed.</p>
<p>Finally, I would caution not to service enable every application in your enterprise. I think of a service mediation layer as my API to the enterprise. If the enterprise is my television set, then the service mediation layer is my remote control to that TV. You should only service enable applications and data that need to be connected to the service mediation layer. Avoid the temptation to use web services or SOA as an integration approach for 100% of your IT systems, or as the only integration approach within your enterprise. Leverage what already exists as much as possible and change only what you need to.</p>
<hr>
<p>That’s all for this entry. Until next time, keep you code clean and your hands dirty!</p>
<em>- Jeff</em>
]]>
      
   </content>
</entry>

<entry>
   <title>Welcome to SOA Thinker</title>
   <link rel="alternate" type="text/html" href="http://blogs.oracle.com/jeffdavies/2008/09/welcome_to_soa_thinker.html" />
   <id>tag:blogs.oracle.com,2008:/jeffdavies//422.7322</id>
   
   <published>2008-09-22T22:36:41Z</published>
   <updated>2009-10-01T17:20:56Z</updated>
   
   <summary>Welcome to SOA Thinker Welcome to my new blog, SOA Thinker. The purpose of this blog is to discuss various ideas about SOA. Architecture, governance and code will all find a home here. I will also use this blog as...</summary>
   <author>
      <name>jeff.x.davies</name>
      
   </author>
   
      <category term="SOA" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="clothes" label="Clothes" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="emperor" label="Emperor" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="enterpriseservicebus" label="Enterprise Service Bus" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="osb" label="OSB" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="oracle" label="Oracle" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="soa" label="SOA" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="service" label="Service" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="servicebus" label="Service Bus" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="en" xml:base="http://blogs.oracle.com/jeffdavies/">
      <![CDATA[<p><H1>Welcome to SOA Thinker</H1><br />
Welcome to my new blog, SOA Thinker. The purpose of this blog is to discuss various ideas about SOA. Architecture, governance and code will all find a home here. I will also use this blog as a platform to help connect you to internal experts in order to get your real-world issues resolved, and to document those resolutions for the benefit of all readers.</p>

<p>SOA is first and foremost about architecture, but architecture alone has never been enough. Solid, professional code must realize the architecture, just as steel, glass and other building materials realize the architecture of any large scale building. Governance plays it role in this analogy by providing the rules and regulations for the enterprise.</p>

<p>While it is necessary to specialize in a specific discipline (architecture, governance and coding), the more we can learn of the other two disciplines will help us all better communicate, and that is my goal for this blog: not to espouse a particular tool or approach, but promote a fuller understanding of all aspects of SOA. We will leave the ideology out.</p>

<p>I will also use this platform to question the "common sense" ideas that are often bandied about as being fact. The emperor really does not have any clothes on, no matter what the common opinion of the day may be. The simple categorization of ideas as being, "good" or "bad" rarely applies in modern engineering, especially when everyone is learning so much, so quickly.  The only way to truly know an idea is to examine it, try it out in a test environment, and discuss its strengths and weaknesses with you peers. I will use this blog as a vehicle for those ideas, allowing everyone to examine these ideas and make up their own minds.</p>

<h2>The Definitive Guide to SOA: Oracle Service Bus (second edition)</h2>
The second edition of the books hits the shelves today. Published by Apress, you can purchase it through Amazon.com. It has been updated to cover the coming release of Oracle Service Bus 10gR3 and covers the new features with tons of sample code. If you are interested in the Oracle Service Bus, or enterprise service buses in general, this book will help you better understand how to use a service bus in your environment to help your company save money by increasing agility.

<h2>The Emperor Has No Clothes</h2>
At least once a month I will write about the misconceptions or questionable perceptions that I see in the industry. This month's topic is speed.

<p>I routinely meet people in the field that are convinced that, "speed is king". These are usually the same folks that are very concerned about the impact of web services and XML on the overall performance of their enterprise. A few weeks ago I was conducting a training session and I asked the audience if speed was the most important aspect of their software development. Fifty percent of the class raised their hands. The class was comprised of very senior developers and consultants in the SOA field. Even when I asked the obviously leading question, "So there is nothing more important than execution speed?" the hands remained up. This is a common perception and I attribute the fact that only 50% of the class thought speed was the #1 concern to the fact that they were so senior. With less experienced folks the percentage is much higher.</p>

<p>I argue that speed is not the #1 concern anymore. This is a legacy belief from the 60's and 70's. In those times, speed really was king! Enterprise systems were tiny compared to today's standards, often comprising a single mainframe computer. The computer users of that era were largely highly trained (or at least specialized) computer engineers. Reuse occurred at the subroutine level only. Change within the computing environment moved at a glacial pace when compared to today's rapid stream of change. In that era each CPU clock cycle had a dollar value assigned to it. If you didn't write fast code, it cost the company money and possibly the coder his job.</p>

<p>Fast-forward to today's computing environments. A medium-sized enterprise will have several hundred to a thousand servers in their data centers. Interfaces are created to allow comparatively unskilled users (i.e. non-software engineers) to get their work done remotely over a network. EAI and ETL work behind the scenes to enable federated systems to behave as one meta-computer.</p>

<p>If execution speed really was king, none of that would exist. Each enterprise would have a single, massively parallel computer that ran everything in a single, highly complex application. That single application would be written in native assembly code.</p>

<p>It wasn't that many years ago that people thought Java was too slow to run enterprise software. I remember when the C language was considered to be slow by many software engineers. The same holds true for distributed computing. "Crossing the wire" was an expensive prospect, with regard to time.</p>

<p>The pure fact is that speed is not king. We went to smaller, cheaper computers in a distributed environment because money is the real king. We are moving to SOA because re-use helps to save money. We are moving to SOA because interoperability saves money. We are moving to SOA because tightly integrated environments may be fast, but they surely are not agile. The business cannot wait for a year or more while IT reconfigures the software systems to better support the needs of the business. Marketing opportunities will come and pass during that time, costing the company money in lost sales opportunities</p>

<p>Modern businesses demand an IT organization that is highly responsive and cost effective. The trend of doing more work with less resources is nothing new in this world. In fact, the original mainframes offered the same benefit: more work for less money. The trend will continue into the foreseeable future. We, as IT professionals must continue to adapt to this pressure.</p>

<h2>Ask the Experts</h2>
Because I co-authored a book on SOA and the Oracle Service Bus, people often assume that I am an expert in every detail of the product. That is simply untrue. I am fortunate to be surrounded by experts here at Oracle and I make liberal use of their expertise. As a result of my unique position here, I am able to comb through both the internal and external questions from the field, looking for interesting questions to share with you.

<p>In this installment, the question is about the aggregation interval settings and how they are used by the Oracle Service Bus. On a legal note, I do reserve the right to modify the format and the content of all questions before I post them here.</p>

<h3>Question</h3>
<blockquote>Please teach me about the sample interval in the aggregation Intervals.

<p>In the following document says that statistics are recomputed by the sample interval.<br />
--<br />
<a href="http://e-docs.bea.com/alsb/docs26/operations/monitoring.html#wp1091189">http://e-docs.bea.com/alsb/docs26/operations/monitoring.html#wp1091189</a><br />
Statistics are recomputed at regular intervals known as the sample interval.<br />
--<br />
According to my research, the sample interval is valid only when the alert rule is evaluated.<br />
In the following document it says that the statistic are recomputed every minute.<br />
--<br />
<a href="http://e-docs.bea.com/alsb/docs26/operations/monitoring.html#wp1091204">http://e-docs.bea.com/alsb/docs26/operations/monitoring.html#wp1091204</a>--<br />
I think that the sample interval influences only the aggregation interval in alert rule. Is this right?</blockquote></p>

<h3>Answer</h3>
<blockquote>Here's how they relate together.

<p>Statistics are reported either since last reset or for a particular aggregation interval. Aggregation interval is a moving window of time. However it moves in discrete steps called sample interval. Each aggregation interval has a different sample interval, e.g., if ai=5, then si=1, if ai=4 hours si=1 hour.</p>

<p>You can obtain the value of a particular statistic for the aggregation interval defined for the service any time. However it will only be accurate if you obtain it to coincide with its sample interval. For example suppose the aggregation interval for a service is 15 minutes. This means its sample interval is 5 minutes. Let's assume you obtain (query) the values of the statistics at 10:23 am. The statistical values you obtain will not represent the last 15 minutes (i.e., since 10:13). Rather, they will be derived from the data collected in the last 18 minutes (i.e., since 10:05 am.) and interpolated to approximate 15-minute value. Therefore the accurate values are only available at minutes/hours that are multiples of the sample interval associated with the aggregation interval.</p>

<p>Since values are only accurate on sample interval boundaries, an alert is evaluated only at the sample interval associated with its own aggregation interval. An alert with ai=5 is evaluated every minute, but an alert with an ai of 4 hours is evaluated every hour.</p>

<p>There is a separate "aggregation" processes which has nothing to do with the aggregation intervals. This aggregation process gathers statistics every minute from all members of the cluster and adds them up to construct the clusterwide statistical values.</p>

<p>Hope this helps.</blockquote></p>

<p>Many thanks to Tolga Urhan for this information.</p>

<h2>Thanks for Reading!</h2>
I promise to keep this blog insightful, critical and useful! If you have any questions, you can always reach me at <a href="mailto:jeff.x.davies@oracle.com">jeff.x.davies@oracle.com</a>. Until next time...

<p><em>- Jeff</em></p>]]>
      
   </content>
</entry>

</feed>
