<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Gilberto Holms</title>
	<atom:link href="http://gibaholms.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://gibaholms.wordpress.com</link>
	<description>Java/SOA Architecture Blog</description>
	<lastBuildDate>Tue, 03 Jan 2012 21:49:37 +0000</lastBuildDate>
	<language>pt-br</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='gibaholms.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Gilberto Holms</title>
		<link>http://gibaholms.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://gibaholms.wordpress.com/osd.xml" title="Gilberto Holms" />
	<atom:link rel='hub' href='http://gibaholms.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Advanced Validation in Oracle Service Bus 11g</title>
		<link>http://gibaholms.wordpress.com/2011/10/31/advanced-validation-in-oracle-service-bus-11g/</link>
		<comments>http://gibaholms.wordpress.com/2011/10/31/advanced-validation-in-oracle-service-bus-11g/#comments</comments>
		<pubDate>Mon, 31 Oct 2011 15:43:55 +0000</pubDate>
		<dc:creator>gibaholms</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[11g]]></category>
		<category><![CDATA[aqualogic]]></category>
		<category><![CDATA[bea]]></category>
		<category><![CDATA[bus]]></category>
		<category><![CDATA[enterprise]]></category>
		<category><![CDATA[fusion]]></category>
		<category><![CDATA[middleware]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[osb]]></category>
		<category><![CDATA[service]]></category>
		<category><![CDATA[soa]]></category>

		<guid isPermaLink="false">http://gibaholms.wordpress.com/?p=41</guid>
		<description><![CDATA[When implementing Proxy Services in Oracle Service Bus (old BEA AquaLogic Service Bus), it’s important to think about validation of request data. The OSB provides a Validate action that is a good mechanism to validate when the incoming request is conformant to the XML Schema defined in the service contract. However, using only this action [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gibaholms.wordpress.com&amp;blog=12785697&amp;post=41&amp;subd=gibaholms&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>When implementing Proxy Services in Oracle Service Bus (old BEA AquaLogic Service Bus), it’s important to think about validation of request data.</p>
<p>The OSB provides a Validate action that is a good mechanism to validate when the incoming request is conformant to the XML Schema defined in the service contract. However, using only this action is a very poor mechanism to effectively validate a request because of the following reasons:</p>
<ul>
<li>The Validate action accepts validation only against XML Schema (xsd), that has a limited syntax and cannot support more complex validations or rules;</li>
<li>XML Schema cannot support business oriented validations, only structural validations (and very limited);</li>
<li>A good choice for better support in validation would be Schematron, but Oracle Service Bus 11g does not provide Schematron support yet (SOA Suite Mediator already supports, but OSB not);</li>
<li>If your company uses Canonical Model, is very common to use on all your xsd entities elements with <strong>minOccurs=”0”</strong> to get full reusability on the model, however is hard to validate when a specific service operation needs that an element be mandatory, and it weakens the service contract.</li>
</ul>
<p>In this article I will show a good pattern that I use to do more advanced, business oriented validation in Oracle Service Bus using XQuery. Note that deep XQuery knowledge is not in the scope of this article, for more in-depth knowledge about XQuery you need to google (a good start can be found at <a href="http://www.w3schools.com/xquery/default.asp">http://www.w3schools.com/xquery/default.asp</a>). I will predict that the reader has basic XPath concepts to find some nodes in a XML instance (more at <a href="http://www.w3schools.com/xpath/default.asp">http://www.w3schools.com/xpath/default.asp</a>).</p>
<p>In this sample I will focus on the Proxy Service, so I will ignore any business-proxy-business transformations and the sample will show a simple Business Service virtualization through data by-pass, but implementing some complex validation on the request input that is the main objective of this article. You can download the example artifacts in the links bellow this article.</p>
<p>Let’s take a look into the sample request input message that we’ll use in this scenario:</p>
<p><pre class="brush: xml;">
&lt;xsd:element name=&quot;OrderRequest&quot;&gt;
&lt;xsd:complexType&gt;
&lt;xsd:sequence&gt;
&lt;xsd:element name=&quot;Customer&quot;&gt;
&lt;xsd:complexType&gt;
&lt;xsd:sequence&gt;
&lt;xsd:element name=&quot;FirstName&quot; type=&quot;xsd:string&quot; minOccurs=&quot;0&quot; /&gt;
&lt;xsd:element name=&quot;LastName&quot; type=&quot;xsd:string&quot; minOccurs=&quot;0&quot; /&gt;
&lt;xsd:element name=&quot;DocumentNumber&quot; type=&quot;xsd:string&quot; minOccurs=&quot;0&quot; /&gt;
&lt;xsd:element name=&quot;Email&quot; type=&quot;xsd:string&quot; minOccurs=&quot;0&quot; /&gt;
&lt;xsd:element name=&quot;Age&quot; type=&quot;xsd:int&quot; minOccurs=&quot;0&quot;/&gt;
&lt;xsd:element name=&quot;Password&quot; type=&quot;xsd:string&quot; minOccurs=&quot;0&quot; /&gt;
&lt;xsd:element name=&quot;PasswordConfirmation&quot; type=&quot;xsd:string&quot; minOccurs=&quot;0&quot; /&gt;
&lt;/xsd:sequence&gt;
&lt;/xsd:complexType&gt;
&lt;/xsd:element&gt;
&lt;xsd:element name=&quot;Product&quot;&gt;
&lt;xsd:complexType&gt;
&lt;xsd:sequence&gt;
&lt;xsd:element name=&quot;ProductID&quot; type=&quot;xsd:string&quot; minOccurs=&quot;0&quot; /&gt;
&lt;xsd:element name=&quot;ProductRestriction&quot; minOccurs=&quot;0&quot;&gt;
&lt;xsd:simpleType&gt;
&lt;xsd:restriction base=&quot;xsd:string&quot;&gt;
&lt;xsd:enumeration value=&quot;EVERYONE&quot;/&gt;
&lt;xsd:enumeration value=&quot;OVER18&quot;/&gt;
&lt;/xsd:restriction&gt;
&lt;/xsd:simpleType&gt;
&lt;/xsd:element&gt;
&lt;xsd:element name=&quot;Quantity&quot; type=&quot;xsd:int&quot; minOccurs=&quot;0&quot; /&gt;
&lt;/xsd:sequence&gt;
&lt;/xsd:complexType&gt;
&lt;/xsd:element&gt;
&lt;/xsd:sequence&gt;
&lt;/xsd:complexType&gt;
&lt;/xsd:element&gt;
</pre></p>
<p>Observations:</p>
<ul>
<li>Obviously this dummy contract is not real world and has no business relevance in an real order scenario;</li>
<li>The sample simulates the use of Canonical Model entities which sets <strong><em>minOccurs=”0”</em></strong> all over the place, but we know that some information is mandatory to our execute order operation.</li>
</ul>
<p>The starting point of this sample is the structure shown below, that consists of:</p>
<ul>
<li>One OSB Project named “AdvancedValidation” in the default configuration</li>
<li>The “OrderService-v1.wsdl” that represents the contract used in the sample</li>
<li>One Business Service named “OrderBusiness” created from the OrderService WSDL (I recommend you to generate a Mock Service in SoapUI tool to point this Business Service to and run your tests)</li>
<li>One Proxy Service named “OrderProxy” created from the OrderService WSDL, with a basic Message Flow that only routes the original request to the OrderBusiness in the execute operation.</li>
</ul>
<p><a href="http://gibaholms.files.wordpress.com/2011/10/image1.png"><img class="alignnone size-medium wp-image-46" title="Image 01" src="http://gibaholms.files.wordpress.com/2011/10/image1.png?w=300&#038;h=223" alt="" width="300" height="223" /></a></p>
<p>By now the focus will be the Proxy Service message flow.</p>
<p style="text-align:left;">To start our robust validation let’s add the main pipeline pair and put the simple “Validate” action into the request branch, because the minimum expected is that the request message does comply to the XML Schema, and if don’t, the flow does not need to work anymore. In the XPath select the OrderRequest input element in the wizard, in variable body against its XML Schema definition present into the OrderService WSDL.<br />
<a href="http://gibaholms.files.wordpress.com/2011/10/image2.png"><img class="alignnone size-medium wp-image-47" title="Image 02" src="http://gibaholms.files.wordpress.com/2011/10/image2.png?w=300&#038;h=170" alt="" width="300" height="170" /></a><br />
- XPath: ./ord:OrderRequest<br />
- In Variable: body<br />
- Against Resource: OrderService-v1.wsdl/OrderRequest<br />
- Raise Error</p>
<p>Now comes the great part, lets prepare our advanced XQuery validation. Create a XSD named “validation.xsd” into xsd folder. This schema will hold the validation data though the flow. Use the following structure:</p>
<p><pre class="brush: xml;">
&lt;xsd:complexType name=&quot;Validation&quot;&gt;
&lt;xsd:sequence&gt;
&lt;xsd:element name=&quot;Payload&quot;&gt;
&lt;xsd:complexType mixed=&quot;true&quot;&gt;
&lt;xsd:sequence&gt;
&lt;xsd:any/&gt;
&lt;/xsd:sequence&gt;
&lt;/xsd:complexType&gt;
&lt;/xsd:element&gt;
&lt;xsd:element name=&quot;ValidationErrorList&quot; type=&quot;tns:ValidationErrorList&quot;/&gt;
&lt;/xsd:sequence&gt;
&lt;/xsd:complexType&gt;
&lt;xsd:complexType name=&quot;ValidationErrorList&quot;&gt;
&lt;xsd:sequence&gt;
&lt;xsd:element name=&quot;ValidationError&quot; type=&quot;tns:ValidationError&quot; minOccurs=&quot;0&quot; maxOccurs=&quot;unbounded&quot;/&gt;
&lt;/xsd:sequence&gt;
&lt;/xsd:complexType&gt;
&lt;xsd:complexType name=&quot;ValidationError&quot;&gt;
&lt;xsd:sequence&gt;
&lt;xsd:element name=&quot;code&quot; type=&quot;xsd:int&quot;/&gt;
&lt;xsd:element name=&quot;message&quot; type=&quot;xsd:string&quot;/&gt;
&lt;/xsd:sequence&gt;
&lt;/xsd:complexType&gt;
</pre></p>
<p style="text-align:left;">The next step is create the XQuery transformation file to do the validation and fill the previous structure. The input of transformation is the OrderRequest schema and the output is the Validation schema.<br />
<a href="http://gibaholms.files.wordpress.com/2011/10/image3.png"><img class="alignnone size-medium wp-image-48" title="Image 03" src="http://gibaholms.files.wordpress.com/2011/10/image3.png?w=300&#038;h=122" alt="" width="300" height="122" /></a><br />
- Source Types: OrderService-v1.wsdl/OrderRequest<br />
- Target Types: validation.xsd/Validation</p>
<div style="text-align:left;">
<p style="text-align:left;">Now I suggest you to forget the visual editor. Drag-and-drop fields will not help you in more complex transformations (it’s not .NET rs) and will make a mess in the source code, so the better to do is reading some concepts of XQuery and then make your code by the hands. In this sample we’ll validate the following:<br />
- The mandatory fields to the operation, that are: FirstName, DocumentNumber, Email, Age, ProductID and Quantity<br />
- DocumentNumber: must contain only numbers<br />
- Email: must comply to the regex (^[a-z0-9]+([\._-][a-z0-9]+)*@[a-z0-9_-]+(\.[a-z0-9]+){0,4}\.[a-z0-9]{1,4}$)<br />
- Password and PasswordConfirmation: if filled, must be the same value<br />
- ProductRestriction: if filled and value is “OVER18”, the customer must be 18+ years old<br />
- Echo the full request message in the payload tag to use in the flow if necessary</p>
<p><pre class="brush: xml;">
(:: pragma bea:global-element-parameter parameter=&quot;$orderRequest&quot; element=&quot;ns1:OrderRequest&quot; location=&quot;../wsdl/OrderService-v1.wsdl&quot; ::)
(:: pragma bea:schema-type-return type=&quot;ns0:Validation&quot; location=&quot;../xsd/validation.xsd&quot; ::)

declare namespace xf = &quot;http://tempuri.org/AdvancedValidation/xq/RequestValidation/&quot;;
declare namespace ns1 = &quot;http://gibaholms.wordpress.com/samples/wsdl/Order-v1.0&quot;;
declare namespace ns0 = &quot;http://gibaholms.wordpress.com/samples/xsd/2011/11/validation&quot;;

declare function xf:RequestValidation($orderRequest as element(ns1:OrderRequest)) as element() {
&lt;ns0:Validation&gt;
&lt;ns0:Payload&gt;{$orderRequest/.}&lt;/ns0:Payload&gt;
&lt;ns0:ValidationErrorList&gt;{
(: BEGIN - Required Field Validations :)
if (empty($orderRequest/ns1:Customer/ns1:FirstName/text())) then
&lt;ns0:ValidationError&gt;
&lt;ns0:code&gt;1&lt;/ns0:code&gt;
&lt;ns0:message&gt;FirstName: Required Field&lt;/ns0:message&gt;
&lt;/ns0:ValidationError&gt;
else if (empty($orderRequest/ns1:Customer/ns1:DocumentNumber/text())) then
&lt;ns0:ValidationError&gt;
&lt;ns0:code&gt;2&lt;/ns0:code&gt;
&lt;ns0:message&gt;DocumentNumber: Required Field&lt;/ns0:message&gt;
&lt;/ns0:ValidationError&gt;
else if (empty($orderRequest/ns1:Customer/ns1:Email/text())) then
&lt;ns0:ValidationError&gt;
&lt;ns0:code&gt;3&lt;/ns0:code&gt;
&lt;ns0:message&gt;Email: Required Field&lt;/ns0:message&gt;
&lt;/ns0:ValidationError&gt;
else if (empty($orderRequest/ns1:Customer/ns1:Age/text())) then
&lt;ns0:ValidationError&gt;
&lt;ns0:code&gt;4&lt;/ns0:code&gt;
&lt;ns0:message&gt;Age: Required Field&lt;/ns0:message&gt;
&lt;/ns0:ValidationError&gt;
else if (empty($orderRequest/ns1:Product/ns1:ProductID/text())) then
&lt;ns0:ValidationError&gt;
&lt;ns0:code&gt;5&lt;/ns0:code&gt;
&lt;ns0:message&gt;ProductID: Required Field&lt;/ns0:message&gt;
&lt;/ns0:ValidationError&gt;
else if (empty($orderRequest/ns1:Product/ns1:Quantity/text())) then
&lt;ns0:ValidationError&gt;
&lt;ns0:code&gt;6&lt;/ns0:code&gt;
&lt;ns0:message&gt;Quantity: Required Field&lt;/ns0:message&gt;
&lt;/ns0:ValidationError&gt;
(: END - Required Field Validations :)

else

(: BEGIN - Field Specific Validations :)
if (not(matches($orderRequest/ns1:Customer/ns1:DocumentNumber/text(), '^[0-9]+$'))) then
&lt;ns0:ValidationError&gt;
&lt;ns0:code&gt;7&lt;/ns0:code&gt;
&lt;ns0:message&gt;DocumentNumber: Must Contain Only Numbers&lt;/ns0:message&gt;
&lt;/ns0:ValidationError&gt;
else if (not(matches($orderRequest/ns1:Customer/ns1:Email/text(), '^[a-z0-9]+([\._-][a-z0-9]+)*@[a-z0-9_-]+(\.[a-z0-9]+){0,4}\.[a-z0-9]{1,4}$'))) then
&lt;ns0:ValidationError&gt;
&lt;ns0:code&gt;8&lt;/ns0:code&gt;
&lt;ns0:message&gt;Email: Not a Valid Email Format&lt;/ns0:message&gt;
&lt;/ns0:ValidationError&gt;
else if (not(empty($orderRequest/ns1:Customer/ns1:Password/text()))
and $orderRequest/ns1:Customer/ns1:Password/text() != $orderRequest/ns1:Customer/ns1:PasswordConfirmation/text()) then
&lt;ns0:ValidationError&gt;
&lt;ns0:code&gt;9&lt;/ns0:code&gt;
&lt;ns0:message&gt;Password: Must Match PasswordConfirmation&lt;/ns0:message&gt;
&lt;/ns0:ValidationError&gt;
else if (not(empty($orderRequest/ns1:Product/ns1:ProductRestriction/text()))
and $orderRequest/ns1:Product/ns1:ProductRestriction/text() = 'OVER18'
and xs:int($orderRequest/ns1:Customer/ns1:Age/text()) &lt; 18) then
&lt;ns0:ValidationError&gt;
&lt;ns0:code&gt;10&lt;/ns0:code&gt;
&lt;ns0:message&gt;Customer Must Be OVER 18 Years&lt;/ns0:message&gt;
&lt;/ns0:ValidationError&gt;
(: END - Field Specific Validations :)

else ''
}&lt;/ns0:ValidationErrorList&gt;
&lt;/ns0:Validation&gt;
};

declare variable $orderRequest as element(ns1:OrderRequest) external;

xf:RequestValidation($orderRequest)
</pre></p>
</div>
<p style="text-align:left;">Now add an “Assign” activity to evaluate the validation XQuery against a newly created validation variable. We’ll use this variable in the error handler to gain access to the validation codes and messages.<br />
<a href="http://gibaholms.files.wordpress.com/2011/10/image4.png"><img class="alignnone size-medium wp-image-49" title="Image 04" src="http://gibaholms.files.wordpress.com/2011/10/image4.png?w=300&#038;h=149" alt="" width="300" height="149" /></a><br />
- Expression: $body/ord:OrderRequest<br />
- Variable: validation</p>
<p style="text-align:left;">We put now an “IF-ELSE” control to check if exists any validation errors. Don’t forget to add the validation xsd target namespace into “val” prefix.<br />
<a href="http://gibaholms.files.wordpress.com/2011/10/image5.png"><img class="alignnone size-medium wp-image-50" title="Image 05" src="http://gibaholms.files.wordpress.com/2011/10/image5.png?w=300&#038;h=148" alt="" width="300" height="148" /></a><br />
- Add Namespace Definition: val &#8211; http://gibaholms.wordpress.com/samples/xsd/2011/11/validation<br />
- Condition: count($validation/val:ValidationErrorList/val:ValidationError)</p>
<p style="text-align:left;"><!--[if gte mso 9]&gt;--><span style="line-height:115%;font-family:'Times New Roman',serif;font-size:12pt;" lang="EN-US"><span style="line-height:115%;font-family:'Times New Roman',serif;font-size:12pt;" lang="EN-US">Then we raise a custom error with the code of our choice “BUS-1”. Note that this code will be used to capture the error in the handler, just remember that code.</span></span><br />
<a href="http://gibaholms.files.wordpress.com/2011/10/image6.png"><img class="alignnone size-medium wp-image-51" title="Image 06" src="http://gibaholms.files.wordpress.com/2011/10/image6.png?w=300&#038;h=245" alt="" width="300" height="245" /></a><br />
- Code: BUS-1<br />
- Message: Request Validation Error</p>
<p style="text-align:left;"><!--[if gte mso 9]&gt;-->Now the pipeline is finished. We now concentrate the fault treatment in a single error handler associated to the entire flow, adding a “IF-ELSE” action to act as a switch, verifying which of the code is present in the “fault” variable and manually throwing the typed faults declared in our service contract (OrderBusinessFault and OrderTechnicalFault). Obs.: the code “BEA-382505” refers to the internal OSB code that is used for “Validate” action errors.<br />
<a href="http://gibaholms.files.wordpress.com/2011/10/image7.png"><img class="alignnone size-medium wp-image-52" title="Image 07" src="http://gibaholms.files.wordpress.com/2011/10/image7.png?w=300&#038;h=236" alt="" width="300" height="236" /></a><br />
- Condition: $fault/ctx:errorCode = ‘BEA-382505’</p>
<p style="text-align:left;"><a href="http://gibaholms.files.wordpress.com/2011/10/image8.png"><img class="alignnone size-medium wp-image-52" title="Image 08" src="http://gibaholms.files.wordpress.com/2011/10/image8.png?w=300&#038;h=236" alt="" width="300" height="236" /></a><br />
- Condition: $fault/ctx:errorCode = ‘BUS-1’</p>
<p style="text-align:left;">Now just add an Assign activity in the “if” branches that apply the typed soap faults. Just remember that the built-in $fault variable refers to the OSB infrastructure fault, and not to soap fault. So if you try to assign a soap fault directly to this variable, it just doesn’t work. To throw a soap fault you must assign the entire soap body. Don’t forget to add the “ord” prefix namespace pointing to “http://gibaholms.wordpress.com/samples/wsdl/Order-v1.0”. First let’s add the technical faults, that apply in case of schema validation failure (BEA-382505) and case else (any infrastructure error that we are not treating):<br />
<a href="http://gibaholms.files.wordpress.com/2011/10/image9.png"><img class="alignnone size-medium wp-image-54" title="Image 09" src="http://gibaholms.files.wordpress.com/2011/10/image9.png?w=300&#038;h=152" alt="" width="300" height="152" /></a><br />
- Add Namespace Definition: ord &#8211; http://gibaholms.wordpress.com/samples/wsdl/Order-v1.0<br />
- Variable: body<br />
- Expression:</p>
<div style="text-align:left;"><pre class="brush: xml;">
&lt;soap-env:Body&gt;
&lt;soap-env:Fault&gt;
&lt;faultcode&gt;soap-env:Server&lt;/faultcode&gt;
&lt;faultstring/&gt;
&lt;detail&gt;
&lt;ord:OrderTechnicalFault&gt;
&lt;ord:message&gt;Schema Validation Failure&lt;/ord:message&gt;
&lt;/ord:OrderTechnicalFault&gt;
&lt;/detail&gt;
&lt;/soap-env:Fault&gt;
&lt;/soap-env:Body&gt;
</pre></p>
<p><a href="http://gibaholms.files.wordpress.com/2011/10/image10.png"><img class="alignnone size-medium wp-image-55" title="Image 10" src="http://gibaholms.files.wordpress.com/2011/10/image10.png?w=300&#038;h=157" alt="" width="300" height="157" /></a></p>
<p>- Add Namespace Definition: ord &#8211; http://gibaholms.wordpress.com/samples/wsdl/Order-v1.0<br />
- Variable: body<br />
- Expression:</p>
<p><pre class="brush: xml;">
&lt;soap-env:Body&gt;
&lt;soap-env:Fault&gt;
&lt;faultcode&gt;soap-env:Server&lt;/faultcode&gt;
&lt;faultstring/&gt;
&lt;detail&gt;
&lt;ord:OrderTechnicalFault&gt;
&lt;ord:message&gt;SOA Infrastructure Error&lt;/ord:message&gt;
&lt;/ord:OrderTechnicalFault&gt;
&lt;/detail&gt;
&lt;/soap-env:Fault&gt;
&lt;/soap-env:Body&gt;
</pre></p>
</div>
<div style="text-align:left;">
<p style="text-align:left;"><!--[if gte mso 9]&gt;-->Now to add the treatment to our “BUS-1” fault, we can use the message applied by the validation XQuery (notice that any information that might be of interest can be propagated through the $validation variable). Don’t forget to declare the “val” namespace prefix to “http://gibaholms.wordpress.com/samples/xsd/2011/11/validation”:<br />
<a href="http://gibaholms.files.wordpress.com/2011/10/image11.png"><img class="alignnone size-medium wp-image-56" title="Image 11" src="http://gibaholms.files.wordpress.com/2011/10/image11.png?w=300&#038;h=163" alt="" width="300" height="163" /></a><br />
- Add Namespace Definition: ord &#8211; http://gibaholms.wordpress.com/samples/wsdl/Order-v1.0<br />
- Variable: body<br />
- Expression:</p>
<p><pre class="brush: xml;">
&lt;soap-env:Body&gt;
&lt;soap-env:Fault&gt;
&lt;faultcode&gt;soap-env:Server&lt;/faultcode&gt;
&lt;faultstring/&gt;
&lt;detail&gt;
&lt;ord:OrderBusinessFault&gt;
&lt;ord:message&gt;{$validation/val:ValidationErrorList/val:ValidationError[1]/val:message/text()}&lt;/ord:message&gt;
&lt;/ord:OrderBusinessFault&gt;
&lt;/detail&gt;
&lt;/soap-env:Fault&gt;
&lt;/soap-env:Body&gt;
</pre></p>
</div>
<p style="text-align:left;"><!--[if gte mso 9]&gt;--><span style="line-height:115%;font-family:'Times New Roman',serif;font-size:12pt;" lang="EN-US">To finish our sample, just add the “Reply” activities to each “if” branch indicating that invocation returned “With Failure” (causes http 500 return code):</span><span style="font-family:'Times New Roman',serif;font-size:12pt;" lang="EN-US"><span style="font-family:'Times New Roman',serif;font-size:12pt;" lang="EN-US"><span style="font-family:'Times New Roman',serif;font-size:12pt;" lang="EN-US"><span style="font-family:'Times New Roman',serif;font-size:12pt;" lang="EN-US"><br />
<a href="http://gibaholms.files.wordpress.com/2011/10/image12.png"><img class="alignnone size-medium wp-image-57" title="Image 12" src="http://gibaholms.files.wordpress.com/2011/10/image12.png?w=300&#038;h=295" alt="" width="300" height="295" /></a><br />
- Reply: With Failure</span></span></span></span></p>
<p>Well done! You can open the OSB console and do the tests in the Proxy Service. Input some data and observe the results. Don’t forget to start the Mock Service into SoapUI and point the Business Service endpoint to the mock address. An easy way to simulate a generic technical fault is stopping the mock service, crashing the business service like it was “unavailable”.Now I hope this article has helped you to doing more complex validations beyond the limits of xsd into Oracle Service Bus 11g.</p>
<p><strong>Attachments</strong></p>
<p>Source Code: <a href="https://github.com/gibaholms/articles/tree/master/Advanced_Validation_in_OSB">https://github.com/gibaholms/articles/tree/master/Advanced_Validation_in_OSB</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gibaholms.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gibaholms.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gibaholms.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gibaholms.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gibaholms.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gibaholms.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gibaholms.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gibaholms.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gibaholms.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gibaholms.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gibaholms.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gibaholms.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gibaholms.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gibaholms.wordpress.com/41/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gibaholms.wordpress.com&amp;blog=12785697&amp;post=41&amp;subd=gibaholms&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://gibaholms.wordpress.com/2011/10/31/advanced-validation-in-oracle-service-bus-11g/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d827962f003103fa531efd761e59865c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gibaholms</media:title>
		</media:content>

		<media:content url="http://gibaholms.files.wordpress.com/2011/10/image1.png" medium="image">
			<media:title type="html">Image 01</media:title>
		</media:content>

		<media:content url="http://gibaholms.files.wordpress.com/2011/10/image2.png?w=300" medium="image">
			<media:title type="html">Image 02</media:title>
		</media:content>

		<media:content url="http://gibaholms.files.wordpress.com/2011/10/image3.png?w=300" medium="image">
			<media:title type="html">Image 03</media:title>
		</media:content>

		<media:content url="http://gibaholms.files.wordpress.com/2011/10/image4.png?w=300" medium="image">
			<media:title type="html">Image 04</media:title>
		</media:content>

		<media:content url="http://gibaholms.files.wordpress.com/2011/10/image5.png?w=300" medium="image">
			<media:title type="html">Image 05</media:title>
		</media:content>

		<media:content url="http://gibaholms.files.wordpress.com/2011/10/image6.png?w=300" medium="image">
			<media:title type="html">Image 06</media:title>
		</media:content>

		<media:content url="http://gibaholms.files.wordpress.com/2011/10/image7.png?w=300" medium="image">
			<media:title type="html">Image 07</media:title>
		</media:content>

		<media:content url="http://gibaholms.files.wordpress.com/2011/10/image8.png?w=300" medium="image">
			<media:title type="html">Image 08</media:title>
		</media:content>

		<media:content url="http://gibaholms.files.wordpress.com/2011/10/image9.png?w=300" medium="image">
			<media:title type="html">Image 09</media:title>
		</media:content>

		<media:content url="http://gibaholms.files.wordpress.com/2011/10/image10.png?w=300" medium="image">
			<media:title type="html">Image 10</media:title>
		</media:content>

		<media:content url="http://gibaholms.files.wordpress.com/2011/10/image11.png?w=300" medium="image">
			<media:title type="html">Image 11</media:title>
		</media:content>

		<media:content url="http://gibaholms.files.wordpress.com/2011/10/image12.png?w=300" medium="image">
			<media:title type="html">Image 12</media:title>
		</media:content>
	</item>
		<item>
		<title>Improve Hibernate Caching Performance</title>
		<link>http://gibaholms.wordpress.com/2011/10/24/improve-hibernate-caching-performance/</link>
		<comments>http://gibaholms.wordpress.com/2011/10/24/improve-hibernate-caching-performance/#comments</comments>
		<pubDate>Mon, 24 Oct 2011 11:35:23 +0000</pubDate>
		<dc:creator>gibaholms</dc:creator>
				<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[connection]]></category>
		<category><![CDATA[datasource]]></category>
		<category><![CDATA[ehcache]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[pool]]></category>

		<guid isPermaLink="false">http://gibaholms.wordpress.com/?p=34</guid>
		<description><![CDATA[In a Hibernate application, a common problem that people have is performance bottleneck. Principally in web applications, where is difficult to predict the number of users that will access the application, when the system faces an increase of simultaneous accesses, the response time decreases abruptly. The common solution usually is the following: Use a connection [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gibaholms.wordpress.com&amp;blog=12785697&amp;post=34&amp;subd=gibaholms&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In a Hibernate application, a common problem that people have is performance bottleneck. Principally in web applications, where is difficult to predict the number of users that will access the application, when the system faces an increase of simultaneous accesses, the response time decreases abruptly.</p>
<p>The common solution usually is the following:</p>
<ul>
<li>Use a connection polling framework to hold some open connections ready to use (e.g. c3p0, Commons DBCP)</li>
<li>Enable second level cache using a well known cache provider (e.g. EhCache, OSCache, SwarmCache)</li>
<li>Use query cache to the most used queries</li>
</ul>
<p>However, regardless the fact that the connection polling saves the time to open a new ready to use connection, fetching the connection from the pool is very expensive too. Principally in the case of using pooling frameworks that not handle concurrence and blocking very well (particularly I never made benchmarks comparing connection pooling frameworks, however some people in the web says that Commons DBCP have more locks in a concurrence scenario than c3p0, that handles betters multithreading accesses).</p>
<p>Few people know (or even care) that the Hibernate framework by default gets a connection from the pool every time that a session is created, regardless of hitting the cache or not. In other words, if your query spends 1ms to get the connection for the pool and 2ms to execute the statement, the caching will gain only the last 2ms because Hibernate always gets a connection, and adding the fact of the bad concurrence handling of the pooling framework, it can be a very bad bottleneck.</p>
<p><strong>LazyConnectionDataSourceProxy</strong></p>
<p>To solve this problem, the Spring framework provides a class named <strong><em>org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy</em></strong> (<a href="http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/jdbc/datasource/LazyConnectionDataSourceProxy.html">http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/jdbc/datasource/LazyConnectionDataSourceProxy.html</a>). This class acts like a proxy to the real pooled data source fetching the connections lazily. This proxy will fetch the connection only when the first statement is created. In other words, if your hibernate query hits the cache, no connection is fetched from the data source at all.</p>
<p>To use this class is very easy and declarative through the Spring context file and no code changes are required, thanks to dependency injection:</p>
<p><pre class="brush: xml;">

&lt;!-- The real DataSource, e.g. a pooled datasource registered at server JNDI --&gt;
&lt;bean id=&quot;dataSource&quot;&gt;
&lt;property name=&quot;jndiName&quot; value=&quot;jdbc/MYDATABASE&quot;/&gt;
&lt;/bean&gt;

&lt;!-- Wrapping the real datasource into the Spring lazy datasource feature --&gt;
&lt;bean name=&quot;lazyConnectionDataSourceProxy&quot;&gt;
&lt;property name=&quot;targetDataSource&quot; ref=&quot;dataSource&quot; /&gt;
&lt;/bean&gt;

&lt;!-- Refer to the lazy datasource bean when injecting data sources (e.g. session factory, transaction manager) --&gt;
&lt;bean id=&quot;hibernateSessionFactory&quot;&gt;
&lt;property name=&quot;dataSource&quot; ref=&quot;lazyConnectionDataSourceProxy&quot; /&gt;
&lt;!-- other configuration data … --&gt;
&lt;/bean&gt;

</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gibaholms.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gibaholms.wordpress.com/34/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gibaholms.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gibaholms.wordpress.com/34/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gibaholms.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gibaholms.wordpress.com/34/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gibaholms.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gibaholms.wordpress.com/34/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gibaholms.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gibaholms.wordpress.com/34/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gibaholms.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gibaholms.wordpress.com/34/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gibaholms.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gibaholms.wordpress.com/34/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gibaholms.wordpress.com&amp;blog=12785697&amp;post=34&amp;subd=gibaholms&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://gibaholms.wordpress.com/2011/10/24/improve-hibernate-caching-performance/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d827962f003103fa531efd761e59865c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gibaholms</media:title>
		</media:content>
	</item>
		<item>
		<title>Conheçam o FFPOJO – Flat File Pojo Parser</title>
		<link>http://gibaholms.wordpress.com/2010/08/08/conhecam-o-ffpojo-%e2%80%93-flat-file-pojo-parser/</link>
		<comments>http://gibaholms.wordpress.com/2010/08/08/conhecam-o-ffpojo-%e2%80%93-flat-file-pojo-parser/#comments</comments>
		<pubDate>Mon, 09 Aug 2010 02:50:52 +0000</pubDate>
		<dc:creator>gibaholms</dc:creator>
				<category><![CDATA[Open Source]]></category>

		<guid isPermaLink="false">http://gibaholms.wordpress.com/?p=30</guid>
		<description><![CDATA[Olá pessoal... meus colegas de trabalho mais próximos já conhecem o projeto FFPOJO, mas eu ainda estava devendo um post dedicado a ele aqui no meu blog.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gibaholms.wordpress.com&amp;blog=12785697&amp;post=30&amp;subd=gibaholms&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Olá pessoal&#8230; meus colegas de trabalho mais próximos já conhecem o projeto FFPOJO, mas eu ainda estava devendo um post dedicado a ele aqui no meu blog.</p>
<p>A idéia começou quando percebi quem em 60% dos projetos em que eu estava atuando, de uma forma ou outra, trabalhavam em algum momento com arquivos texto&#8230; importações de arquivos texto para o banco de dados, exportação de arquivos para integração com terceiros, para parametrizações&#8230; e ainda extrapolando a barreira dos arquivos texto, os layouts de troca de informação “posicional” ou utilizando um “delimitador” também são muito vistos em comunicações via sockets.</p>
<p>A princípio, os desenvolvedores utilizaram a abordagem convencional&#8230; leitura via streams de dados e parse com substrings (posicionais) e splits (delimitados). Porém, como já era de se esperar, o código ficava horroroso&#8230; totalmente estruturado e dificílimo de manter e evoluir. Foi neste momento que senti a necessidade de utilizar uma abordagem mais orientada a objetos, e fui no Google à procura de frameworks para parse de arquivos texto.</p>
<p>Minha busca foi muito decepcionante, encontrei poucos frameworks, e muito ruins&#8230; em alguns deles o código necessário para utilizá-los era tão grande que ficaria igual ou pior do que a abordagem tradicional, e eles abstraiam muito pouco o seu domínio principal.</p>
<p>Neste momento eu filosofei um pouco sobre o ORM (Object Relational Mapping), que é basicamente uma técnica para abstrair o banco de dados para uma abordagem orientada a objetos&#8230; neste momento senti que era justamente disso que eu precisava, e no momento me veio na cabeça a expressão OFM (Object Flat Mapping), que a meu ver seria perfeito, trabalhar com arquivos texto (flat files) orientado a objeto.</p>
<p>Foi quando decidi criar o FFPOJO, um framework open source para manipulação de arquivos texto baseados em layouts posicionais ou delimitados, no qual implementei algumas características interessantes:</p>
<ul>
<li>Configuração      do “OFM” (Object Flat Mapping) via XML, Annotations, ou ambos (onde o XML      sobrescreve as Annotations)</li>
<li>Cache      de metadados, o que permite um parsing mais performático</li>
<li>Flexibilidade      para trabalhar em baixo nível (text to pojo e pojo to text)</li>
<li>Uso      do conceito de Decorators para conversão customizada de campos (sim,      roubei a idéia do DisplayTag)</li>
<li>Conceito      de Flat File Reader, permitindo definição de headers e traillers</li>
<li>Para      arquivos em disco, realiza leitura utilizando o NIO (Java New IO), onde      constatei um ganho de 25% no acesso a disco para leitura de dados</li>
<li>Permite      trabalhar em modo push através do conceito de Record Processor, que      suporta processamento single-thread e multi-thread</li>
<li>Conceito      de Flat File Writer para gravação de arquivos</li>
<li>Leve,      sem dependências a outros frameworks</li>
</ul>
<p>O FFPOJO foi criado utilizando modelagem orientada ao domínio (DDD) e abusando dos testes unitários.</p>
<p>Meus colegas, eu ficaria feliz se tentassem utilizá-lo quando precisarem trabalhar com arquivos texto, podem contar comigo se tiverem alguma dúvida de implementação&#8230; também ficaria feliz se contribuíssem e reportassem possíveis bugs, sugestões de melhorias também são muito bem vindas.</p>
<p>Para instruções técnicas criei um rápido manual utilizando o Trac do SourceForge, segue abaixo os links:</p>
<ul>
<li>Site do projeto: <a href="http://sourceforge.net/projects/ffpojo/">http://sourceforge.net/projects/ffpojo/</a></li>
<li>Trac do Projeto (manual): <a href="http://ffpojo.sourceforge.net/">http://ffpojo.sourceforge.net/</a></li>
</ul>
<p>Abraços a todos !</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gibaholms.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gibaholms.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gibaholms.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gibaholms.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gibaholms.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gibaholms.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gibaholms.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gibaholms.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gibaholms.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gibaholms.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gibaholms.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gibaholms.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gibaholms.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gibaholms.wordpress.com/30/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gibaholms.wordpress.com&amp;blog=12785697&amp;post=30&amp;subd=gibaholms&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://gibaholms.wordpress.com/2010/08/08/conhecam-o-ffpojo-%e2%80%93-flat-file-pojo-parser/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d827962f003103fa531efd761e59865c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gibaholms</media:title>
		</media:content>
	</item>
		<item>
		<title>Prova SCDJWS 5.0</title>
		<link>http://gibaholms.wordpress.com/2010/05/17/prova-scdjws-5-0/</link>
		<comments>http://gibaholms.wordpress.com/2010/05/17/prova-scdjws-5-0/#comments</comments>
		<pubDate>Mon, 17 May 2010 04:08:21 +0000</pubDate>
		<dc:creator>gibaholms</dc:creator>
				<category><![CDATA[Certificação]]></category>
		<category><![CDATA[certificação]]></category>
		<category><![CDATA[scdjws]]></category>
		<category><![CDATA[sun]]></category>

		<guid isPermaLink="false">http://gibaholms.wordpress.com/?p=24</guid>
		<description><![CDATA[Enfim, o objetivo deste post é comentar um pouco sobre a prova e como me preparei para ela... espero fornecer algumas informações úteis para quem deseja encarar este desafio.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gibaholms.wordpress.com&amp;blog=12785697&amp;post=24&amp;subd=gibaholms&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><strong>Prova SCDJWS 5.0 – Sun Certified Developer for Java Web Services</strong></p>
<p>Quem acompanha meu Twitter já soube&#8230; depois de bastante esforço, consegui passar na prova SCDJWS 5.0 da Sun “na raça”. Quem teve a oportunidade de prestar a prova quando ela ainda era Beta, pode usufruir de uma porcentagem mais baixa para ser aprovado, algo em torno de 42%. Porém, quem deixou para depois (meu caso), agora tem que encarar uma nota de corte de 68% para ser aprovado. Felizmente consegui um score de 89% e passei por mais essa.</p>
<p>Enfim, o objetivo deste post é comentar um pouco sobre a prova e como me preparei para ela&#8230; espero fornecer algumas informações úteis para quem deseja encarar este desafio.</p>
<p>Para quem não conhece a prova, segue abaixo os macro-objetivos e o site da prova:</p>
<ul>
<li>XML Web Service Standards</li>
<li>SOAP 1.2 Web Services Standards</li>
<li>Describing and Publishing (WSDL and UDDI)</li>
<li>JAX-WS</li>
<li>REST, JSON, SOAP and XML Processing APIs (JAXP, JAXB, SAAJ)</li>
<li>JAXR</li>
<li>Java EE 5 Web Services</li>
<li>Security</li>
<li>Developing Web Services</li>
<li>Web Services Interoperability Technologies</li>
<li>General Design and Architecture</li>
<li>Endpoint Design and Architecture</li>
<li>Site da prova: <a href="http://education.oracle.com/pls/web_prod-plq-dad/db_pages.getpage?page_id=41&amp;p_exam_id=1Z0_862">http://education.oracle.com/pls/web_prod-plq-dad/db_pages.getpage?page_id=41&amp;p_exam_id=1Z0_862</a></li>
</ul>
<p><strong>Principais Características da Prova</strong></p>
<ul>
<li>Poucas questões exigindo conhecimento de código de APIs. Durante os estudos me preocupei bastante que caíssem muitas questões contendo códigos-fonte das APIs solicitadas (SAAJ, JAXR, SAX, DOM, StAX, XSLT, etc). Porém, as questões da prova foram na maioria conceituais, solicitando saber diferenças, propósito e cenários de uso destas APIs.</li>
<li>Muito XML Schema, contendo montagens corretas e incorretas de elementos e tipos complexos. É bastante cobrado também mapeamentos de tipos xsd para Java (e também para C# na seção de interoperabilidade).</li>
<li>Como disse acima, cai sim questões sobe Microsoft WCF, porém sempre bem básicas, como por exemplo uso do svctool, características do mapeamento xsd para C# e questões conceituais de interoperabilidade (WSIT).</li>
<li>Bastante cobrado WSDL e identificação de diferenças entre document-style e rpc-style, mapeamento de portTypes para Java e WS-I Basic Profile.</li>
<li>Pouco conhecimento específico das annotations da JAX-WS. As questões de JAX-WS não exigem decoreba de annotations, são mais conceituais.</li>
<li>Na questão de segurança, foi cobrado um pouco de SSL, WS-Security e SAML (single-sign-on) de forma conceitual. Também são mostrados cenários onde devemos identificar qual abordagem de segurança é mais apropriada.</li>
<li>Quanto aos Web Service / Integration Patterns também são mostrados cenários.</li>
<li>UDDI – maldito tópico! Decorem todas as operações fornecidas pela Publishing e Inquiry API, suas respectivas na JAXR e as entidades trabalhadas tanto na espec. do UDDI quanto na JAXR.</li>
</ul>
<p><strong>Principais “Gafes” da Prova</strong></p>
<ul>
<li>Nos objetivos pede para estudar SOAP 1.2, porém na parte de SOAP Fault, acaba cobrando sobre as soap:Faults da versão SOAP 1.1. A parte de soap:Header já cobra da 1.2.</li>
<li>No papel impresso de report que sai no final da prova com o resultado, no meu apareceu “Passing Score 42%, Your Score: 89%”. Que gafe ! 42% era o score da prova beta, o score oficial publicado no site e em todas as informações durante a prova é de 68%. Agora nunca vou saber se este erro ocorreu apenas na impressão do report, ou na hora de computar a aprovação/reprovação, qual score que vai contar de verdade. Porém, existe um comentário no fórum JavaRanch de um candidato que bombou com 60%, logo acredito que na hora de contar, o que vale são os 68 mesmo, não tem moleza não&#8230; mas de qualquer forma, bela gafe da equipe de organização da prova, isso aí pode valer até processo judicial.</li>
</ul>
<p><strong>Material de Estudo</strong></p>
<ul>
<li>Ivan Krizsan Study Notes for SDCJWS 5 (<a href="http://www.coderanch.com/t/437184/java-Web-Services-SCDJWS/certification/SCDJWS-Study-Notes">http://www.coderanch.com/t/437184/java-Web-Services-SCDJWS/certification/SCDJWS-Study-Notes</a>)</li>
<li>Mikalai Zaikin Study Guide for SCDJWS 5 (<a href="http://java.boot.by/scdjws5-guide/">http://java.boot.by/scdjws5-guide/</a>)</li>
<li>Especificações JCP (<a href="http://jcp.org/en/home/index">http://jcp.org/en/home/index</a>):
<ul>
<li>JSR181 &#8211; Web Services Metadata</li>
<li>JSR224 &#8211; JAX WS</li>
</ul>
</li>
<li>The Java Web Services Tutorial 2.0 (<a href="http://java.sun.com/webservices/docs/2.0/tutorial/doc/">http://java.sun.com/webservices/docs/2.0/tutorial/doc/</a>)</li>
<li>WSIT Tutorial (<a href="http://java.sun.com/webservices/reference/tutorials/wsit/doc/index.html">http://java.sun.com/webservices/reference/tutorials/wsit/doc/index.html</a>)</li>
</ul>
<p>É isso ae galera… desculpem não ter escrito mais, mas já são 1h da matina de domingo e amanhã preciso trabalhar.</p>
<p>De qualquer forma, espero ter ajudado&#8230; BOA SORTE !!!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gibaholms.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gibaholms.wordpress.com/24/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gibaholms.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gibaholms.wordpress.com/24/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gibaholms.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gibaholms.wordpress.com/24/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gibaholms.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gibaholms.wordpress.com/24/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gibaholms.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gibaholms.wordpress.com/24/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gibaholms.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gibaholms.wordpress.com/24/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gibaholms.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gibaholms.wordpress.com/24/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gibaholms.wordpress.com&amp;blog=12785697&amp;post=24&amp;subd=gibaholms&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://gibaholms.wordpress.com/2010/05/17/prova-scdjws-5-0/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d827962f003103fa531efd761e59865c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gibaholms</media:title>
		</media:content>
	</item>
		<item>
		<title>Fora do Quadrado com Java NIO e Binary Search</title>
		<link>http://gibaholms.wordpress.com/2010/03/25/fora-do-quadrado-java-nio-com-binary-search/</link>
		<comments>http://gibaholms.wordpress.com/2010/03/25/fora-do-quadrado-java-nio-com-binary-search/#comments</comments>
		<pubDate>Thu, 25 Mar 2010 04:21:44 +0000</pubDate>
		<dc:creator>gibaholms</dc:creator>
				<category><![CDATA[Java IO]]></category>

		<guid isPermaLink="false">http://gibaholms.wordpress.com/?p=3</guid>
		<description><![CDATA[Primeiramente, boas vindas pessoal !!       Este é o meu primeiro post&#8230; primeiro de muitos. Obrigado aos meus colegas de trabalho @rafanoronha e @alnascimento por me incentivarem constantemente na criação do meu blog.        Neste primeiro assunto vou mostrar um caso real de software que ocorreu em um projeto do nosso time no Software Delivery Center na Stefanini, onde tive o prazer de [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gibaholms.wordpress.com&amp;blog=12785697&amp;post=3&amp;subd=gibaholms&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><strong><a href="http://gibaholms.files.wordpress.com/2010/03/gibabizarresearch.jpg"></a>Primeiramente, boas vindas pessoal !!</strong>      </p>
<p>Este é o meu primeiro post&#8230; primeiro de muitos. Obrigado aos meus colegas de trabalho @<a href="http://twitter.com/rafanoronha" target="_blank">rafanoronha</a> e @<a href="http://twitter.com/alnascimento" target="_blank">alnascimento</a> por me incentivarem constantemente na criação do meu blog.      </p>
<p> Neste primeiro assunto vou mostrar um caso real de software que ocorreu em um projeto do nosso time no <a href="http://twitter.com/sdc_stefanini" target="_blank">Software Delivery Center</a> na <a href="http://www.stefanini.com/" target="_blank">Stefanini</a>, onde tive o prazer de dar alguns pitacos técnicos. Tinhamos uma funcionalidade em que precisávamos localizar uma determinada lista de palavras dentro de um dicionário de aproximadamente 70 mil palavras (não podíamos utilizar Lucene e o sistema era intranet).      </p>
<p>Primeira solução imaginada&#8230; no quadrado&#8230; vamos subir estas palavras no nosso poderoso Oracle, criar um mega índice na palavra, que a busca será super rápida. E realmente era rápida&#8230; eh&#8230; para até umas 10 palavras. Quando testávamos um texto razoável de 200 palavras, o tempo de busca já ia pra ordem de minutos, o que ra inviável em produção. Aí já viu&#8230; faz mais índice, segmenta em tabelas separadas, enche de if, parseia via procedure, diversas tentativas e nada.      </p>
<p>Foi quando percebi que precisava encontrar uma solução fora do quadrado&#8230; deitado na minha cama, pensei&#8230; Oracle ? Pra que ?! Quem precisa de Oracle ? Por acaso o Google indexa sua base de sites no Oracle ?! Acho que não ! Logo me veio em mente, vamos indexar isso em arquivo texto! Todos sabem que IO no disco é muito mais rápido que ir no banco, não tem controles de conexão, sessões, camadas de rede no meio&#8230; é tudo alí, na lata.       </p>
<p><strong>Solução: Java NIO + Binary Search  &#8230; vamos entender porque. </strong>      </p>
<p>Java NIO      </p>
<p>Muitas pessoas não sabem que este recurso existe, muito menos conhecem seu poder. A maioria dos desenvolvedores utilizam o velho IO, baseado em Streams (xxxInputStream, xxxOutputStream)&#8230; o problemas dos Streams é que eles são baseados em bytes de forma unitária. Um Stream comum faz operações de IO byte-a-byte, e são unidirecionais (ou é input, ou é output).      </p>
<p>A partir do JDK 1.4, foi introduzida a API Java New IO (NIO), que trouxe o poder do IO de baixo nível para o java. Alguns autores brincam que ela deveria se chamar de LLIO (Low-Level IO) ao invés de NIO. O principal diferencial desta nova API é que ela trabalha com blocos de bytes (buffers) e canais (channels). Fazer operações de IO com blocos de bytes é muito mais rápido que fazer byte-a-byte&#8230; os channels são bidirecionais, o que é muito mais natural pois é como o Sistema Operacional trabalha. Sem contar da capacidade de implementar non-blocking-io e utilizar recursos a nível de SO, como as Mapped Files, que são a base da nossa solução desenvolvida.       </p>
<p><strong><span style="text-decoration:underline;">Problema 1: como gerar o arquivo texto ? </span></strong>      </p>
<p>Ora&#8230; esta é fácil&#8230; fazemos um batch que roda 1 vez por dia, de madrugada. Tudo que ele tem de fazer é um &#8220;SELECT *&#8221; na tabela de palavras e gravar num arquivo texto, com um número fixo de bytes por registro (palavra), para podermos encontrá-los facilmente no arquivo. E o mais importante&#8230;. o &#8220;ORDER BY&#8221; ! Um dos truques sa solução é gerar o arquivo de palavras ordenado em ordem alfabética, para podermos aplicar o famoso algoritmo da <a href="http://pt.wikipedia.org/wiki/Pesquisa_bin%C3%A1ria" target="_blank">Busca Binária (ou Binary Search)</a>.      </p>
<p><strong><span style="text-decoration:underline;">Problema 2: como garantir acesso rápido do IO ao arquivo ? </span></strong>      </p>
<p>Aqui utilizamos o poder do NIO, através das <a href="http://en.wikipedia.org/wiki/Memory-mapped_file" target="_blank">Mapped Files</a>. Este é um recurso poderosíssimo, talvez este post não seja o suficiente para entender a fundo&#8230; requer um pouco de conhecimento sobre SO. Mas em resumo, consiste no seguinte&#8230; quando fazemos um IO comum para ler um arquivo, os bytes do arquivo são trazidos para um buffer intermediário na memória, e este buffer é lido na aplicação. Ou seja, em um Random Access File, para se posicionar no meio do arquivo por exemplo, este buffer precisa ser percorrido até chegar no ponto desejado.      </p>
<p>O recurso das Mapped Files consiste em utilizar o próprio mapeamento do arquivo no FileSystem para identificar os bytes do arquivo, ou seja, não são criados buffers intermediários. É criado um mapeamento do arquivo na memória virtual que fica sincronizado com o mapeamento do arquivo no FileSystem:      </p>
<div id="attachment_4" class="wp-caption alignnone" style="width: 310px"><a href="http://gibaholms.files.wordpress.com/2010/03/mapped_buffer.jpg"><img class="size-medium wp-image-4" title="mapped_buffer" src="http://gibaholms.files.wordpress.com/2010/03/mapped_buffer.jpg?w=300&#038;h=137" alt="Mapped Buffer" width="300" height="137" /></a><p class="wp-caption-text">Mapped Buffer</p></div>
<p>O que acontece de engraçado:    </p>
<ul>
<li>Qualquer alteração no objeto de buffer reflete diretamente no arquivo no disco (você está trabalhando no filesystem, oras !) </li>
<li>Mesmo para mapear um arquivo de vários gigas é consumida pouquíssima memória, pois são utilizados os recursos de cache e paginação comuns do filesystem. Na hora da leitura efetiva do arquivo, ela é feita sobre demanda.</li>
<li> Sua paginação é sincronizada, ou seja, não são criados buffers intermediários.</li>
<li>Se o arquivo for modificado após ter sido mapeado, irão ocorrer exceptions ao fazer a leitura. Portanto, ou fazemos o lock via código, ou garantimos que o arquivo não será modificado durante a leitura. Se for modificado, temos que mapeá-lo novamente antes de ler.</li>
<li>Não ocupa quase nada do Heap da JVM para mapear o arquivo. É tudo feito a nível de SO e memória virtual.</li>
<li>O mapeamento é liberado quando o objeto do buffer é recolhido pelo Garbage Colector (e não quando fechamos o channel).</li>
</ul>
<p>  </p>
<p><strong><span style="text-decoration:underline;">Problema 3: como localizar a palavra rapidamente ? </span></strong>      </p>
<p>Em uma busca convencional, teriamos que ler palavra por palavra, e comparar cada uma com a palavra que buscamos, até encontrá-la (ou não). Absurdo ! Ordenamos justamente para utilizar um modo mais performático&#8230; a Busca Binária. Com este algorítimo, descartamos as palavras de metade em metade, conseguindo um match com pouquíssimas comparações. O NIO garantirá acesso rápido a qualquer posição de byte dentro do arquivo (pois sabemos quantos bytes cada palavra ocupa). Conseguimos encontrar uma palvravra em 70 mil com algo em torno de apenas 17 comparações.      </p>
<p>Produto Final: GibaBizarreSearch.class  </p>
<p><pre class="brush: java;">  

public class GibaBizarreSearch {
 private final int tamanhoRegistroInBytes;
 private final int tamanhoPagina;
 private final File file;
 private final String charset; 

 private List&lt;MappedByteBuffer&gt; buffers; 

 public GibaBizarreSearch(File file, String charset, int tamanhoRegistroInBytes) throws IOException {
  if (tamanhoRegistroInBytes &lt;= 0) {
   throw new IllegalArgumentException(&quot;O tamanho do registro em bytes deve ser maior que zero.&quot;);
  } else if (file == null) {
   throw new IllegalArgumentException(&quot;O objeto file não pode ser nulo.&quot;);
  }
  this.tamanhoRegistroInBytes = tamanhoRegistroInBytes;
  this.tamanhoPagina = (Integer.MAX_VALUE / tamanhoRegistroInBytes) * tamanhoRegistroInBytes;
  this.file = file;
  this.charset = charset;
 }
 
 public void mapear() throws IOException {
  if (!file.exists()) {
   throw new IllegalStateException(&quot;O arquivo indicado para leitura não existe.&quot;);
  } else if (!file.isFile()) {
   throw new IllegalStateException(&quot;O arquivo indicado para leitura não é um arquivo.&quot;);
  } else if (!file.canRead()) {
   throw new IllegalStateException(&quot;O arquivo indicado para leitura não pode ser lido, verifique as permissões no SO.&quot;);
  }
  
  this.buffers = new ArrayList&lt;MappedByteBuffer&gt;();
  FileChannel channel = (new RandomAccessFile(file, &quot;r&quot;)).getChannel();
  
  long channelSize = channel.size();
  long inicio = 0;
  int tamanho = 0;
  for (long i = 0; inicio + tamanho &lt; channelSize; i++) {
   if ((channelSize / tamanhoPagina) == i) {
    tamanho = (int)(channelSize - i * tamanhoPagina);
   } else {
    tamanho = tamanhoPagina;
   }
   inicio = i * tamanhoPagina;
   MappedByteBuffer pagina = channel.map(FileChannel.MapMode.READ_ONLY, inicio, tamanho);
   buffers.add(pagina);
  }
  
  channel.close();
 }
 
 public void desalocar() {
  if (buffers != null &amp;&amp; !buffers.isEmpty()) {
   buffers.clear();
   buffers = null;
  }
 }
 
 public long buscar(String texto) throws UnsupportedEncodingException {
  if (buffers == null) {
   throw new IllegalStateException(&quot;O arquivo não foi mapeado.&quot;);
  }
  
  long posicaoAchou = 0;
  for (int i = 0; i &lt; buffers.size(); i++) {  
   MappedByteBuffer buf = buffers.get(i); 

   int qtdRegistros = buf.limit() / tamanhoRegistroInBytes;
   
   byte[] registro = new byte[tamanhoRegistroInBytes];
   int inf = 0;
   int sup = qtdRegistros - 1;
   int meio = -1; 

   posicaoAchou = 0;
   while(inf &lt;= sup &amp;&amp; posicaoAchou == 0) {
    meio = (int)(inf + sup) / 2;
    buf.position(meio * tamanhoRegistroInBytes);
    buf.get(registro, 0, tamanhoRegistroInBytes);
    String valor = new String(registro, charset).trim();
    if (texto.compareTo(valor) &gt; 0) {
     inf = meio + 1;
    } else if (texto.compareTo(valor) &lt; 0) {
     sup = meio - 1;
    } else {
     posicaoAchou = meio + 1;
    }
   } 

   if (posicaoAchou &gt; 0 || meio != qtdRegistros - 1) {
    if (posicaoAchou &gt; 0) {
     posicaoAchou += i * (tamanhoPagina / tamanhoRegistroInBytes);
    }
    break;
   }
  } 

  return posicaoAchou;
 } 

}  

</pre></p>
<p> </p>
<p>Explicação:  </p>
<ul>
<li><strong>Construtor</strong>: inicializa as variáveis e define o tamanho máximo da página que seja divisível pelo tamanho do registro. O tamanho máximo que podemos mapear num buffer é o range do int (Integer.MAX_VALUE). Portanto, caso o nosso arquivo tenha um tamanho em bytes que exceda este valor (tipo alguns gigas), precisamos dividi-lo em mais buffers. Porém, não podemos cortar um registro no meio e deixar uma parte em cada página, por isso esta divisão.</li>
<li><strong>mapear()</strong>: verifica quantas páginas (buffers) são necessárias para mapear o arquivo. A chamada channel.size() retorna o tamanho total do arquivo em bytes. Este método apenas decide quantas páginas serão necessárias para mapear o arquivo inteiro, de acordo com o tamanho máximo da página que definimos no construtor. Ele realiza então os mapeamentos, e guarda cada página em um buffer da lista. Apenas arquivo muito grandes precisarão de mais de um buffer.</li>
<li><strong>desalocar()</strong>: remove o mapeamento. Vimos que fechar o channel não influencia em nada no mapeamento. Se quisermos desfazer o mapeamento, temos que deixar os buffers elegíveis ao Garbage Collector.</li>
<li><strong>buscar(String): </strong>efetua a busca binária e retorna a posição em que o registro (ou neste caso palavra) foi encontrada, e caso não encontre, retorna zero 0. Note que existe ao final uma consistência para verificar se existe a necessidade de abrir o próximo buffer, pois como está ordenado, se a palavra não foi encontrada em um buffer e for menor que as palavras do próximo buffer, nem precisa verificá-los pois é fato que ela não existe. Ao final existe um pequeno ajuste para adequar a posição do registro de acordo com o número do buffer atual (ex.: se é o registro de posição 5 do segundo buffer, e cada buffer tem 10 registros, então na verdade é o registro de posição 15).</li>
</ul>
<p><strong>Fica aqui um incentivo ! Vamos pensar fora do quadrado !</strong></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gibaholms.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gibaholms.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gibaholms.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gibaholms.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gibaholms.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gibaholms.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gibaholms.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gibaholms.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gibaholms.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gibaholms.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gibaholms.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gibaholms.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gibaholms.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gibaholms.wordpress.com/3/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gibaholms.wordpress.com&amp;blog=12785697&amp;post=3&amp;subd=gibaholms&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://gibaholms.wordpress.com/2010/03/25/fora-do-quadrado-java-nio-com-binary-search/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d827962f003103fa531efd761e59865c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gibaholms</media:title>
		</media:content>

		<media:content url="http://gibaholms.files.wordpress.com/2010/03/mapped_buffer.jpg?w=300" medium="image">
			<media:title type="html">mapped_buffer</media:title>
		</media:content>
	</item>
	</channel>
</rss>
