Skip navigation.

Darwin IT

Syndicate content
Darwin-IT professionals do ICT-projects based on a broad range of Oracle products and technologies. We write about our experiences and share our thoughts and tips.Martien van den Akkerhttps://plus.google.com/110503432901891966671noreply@blogger.comBlogger263125
Updated: 4 hours 1 sec ago

Password properties in SoapUI

Tue, 2015-07-21 01:05
By accident I encountered the following behaviour of SoapUI. I wanted to register a username/password combination in SoapUI.
Normally in SoapUI property values are shown as plain text.  Here I miss-typed the property for password on purpose:
But see what happens if I correctly type the word "Password":
Apparently if the property contains the word  "Password", prefixed with something indicative, it will consider the property as a password field. Cool!

By the way: the phrase "Password" should be the last in the name. For example, if you post-fix the property with "-Dev", like "ContentServerPassword-Dev", the content becomes visible again. In those case, you should phrase it like "ContentServer-Dev-Password".

Disable Wrap Data Types

Wed, 2015-07-15 06:50
Just  a moment ago I stumbled on a blog entry of Eric Elsinga about the wrapping of datatypes in Weblogic Datasources, related to the DB-Adapter.

Weblogic wraps objects returned by the database-driver to provide functionality related to debugging, connection utilization tracking and transparent transaction support.
However for some native database objects like BLOBS, CLOBS, ARRAYS etc. this wrapping can affect the performance significantly. When this wrapping is disabled, the application (in our case the DB-Adapter) can work directly on the native objects provided by the Database driver.
To disable the object wrapping do the following:
  1. In the Domain Structure tree, expand Services, then select Data Sources.
  2. On the Summary of Data Sources page, click the data source name.
  3. Select the Configuration: Connection Pool tab.
  4. Scroll down and click Advanced to show the advanced connection pool options.
  5. In Wrap Data Types, deselect the checkbox to disable wrapping.
  6. Click Save.
Of course on a production-mode server you need to Lock&Edit upfront and Activate Changes afterwards.
See also:

OpenSSL and KeyTool commands

Wed, 2015-07-08 03:29
Earlier I wrote an article about message transport security in Oracle B2B. It collects a few usefull Java Keytool and OpenSSL commands to convert and import Certificates.

Today I learned another (from co-worker Joris, thanks).

This is how to get a certificate from an external server.
openssl x509 -in <(openssl s_client -connect {remote-host}:443 -prexit 2>/dev/null) -out /tmp/certificate.crt 

This is usefull, because in some cases the remote host, maybe a virtual one, where by means of Server Name Indication the specific virtual-host's certificate is to be 'asked', while the actual certificate of the physical host is presented by default. Note that Weblogic (and other JEE Appserver as JBoss, Websphere, Glassfish, etc.) does not support SNI.

I think I should create a blog-entry to collect these usefull commands in one page. However I've found these:


OSB & MTOM: When to use Include Binary Data by Reference or Value

Thu, 2015-07-02 09:23
As can be seen in my blogs of these days, I've been busy with implementing a service using MTOM in OSB. When enabling XOP/MTOM Support you'll have to choose between:
  • Include Binary Data by Reference
  • Include Binary Data by Value

I used the first because I want to process the content in another service on another WLS-Domain. However, in my first service catching the initial request I want to do an XSD validation. And although the rest of the message is valid, the Validate activity raises an exception with the message: 'Element not allowed: binary-content@http://www.bea.com/wli/sb/context in element Bestandsdata....'.

Looking into this problem I came up with this section in the doc,  which states that you use 'Include Binary Data by Value' when you want to:
  • transfer your data to a service that does not support MTOM
  • validate your message
Now, what does this other option? OSB then parses the root of the Inbound MIME message in search for  xop:Include-tags. When found, it will Base64 encode the binary-content and replaces the tags with the Base64-string.

Now, although I want exactly that in the end, I don't want that at this point of the service. I want to transform my message, without the Base64-strings. And I want to encode the data only on my other domain.

So I just want to ignore messages that start with the 'Element not allowed: binary-content@...' messages. To do so I came up with the next expression:
fn:count($fault/ctx:details/con:ValidationFailureDetail/con:message[not(fn:starts-with(text(),'Element not allowed: binary-content@http://www.bea.com/wli/sb/context in element Bestandsdata'))])>0 
Add an If-Then-Else activity to your Error Handler Stage with this expression. Add the following Namespace:
  • Prefix: con
  • Namespace:  http://www.bea.com/wli/sb/stages/transform/config

If the expression evaluates to true, then you have in fact an invalid XML-message. In the else branch you can add a Resume to ignore the exception.

This expression might come in handy in other situations as well.

Set environment properties in SoapUI (freeware)

Thu, 2015-07-02 04:26
Ever used SoapUI to test services on multiple environments? Then you probably ran in to the job of ever changing the endpoints to the hosts of the particular environment; development, test, acceptance, production (although I expect you wouldn't use SoapUI against a prod-env). This is not that hard if you have only one service endpoint in the project. But what if you want to test against multiple services or have to call a service on one system with the result of the other during a testcase. You can even have testcases that mock services called by your (BPEL/BPM) process and call back the process to have it process to a further stage. And then you can end up having multiple endpoints per environment.

You can set multiple endpoints on a request and toggle between them. But you'll have to do that for every request.

SoapUI however, supports the use of properties in the endpoints. So you can setup different host-properties and URI properties on the project:
In this case you see that I have one property for the Service URI, the part of the URL after the host:port, and several ...Host properties for each seperate environment, and one actual.

As said, you can have a property based endpoint like this:
So I have one single endpoint defined based on:
http://${#Project#CSServiceHost}/${#Project#CSServiceURI}
Here you see that the endpoint is based on two properties: ${#Project#CSServiceHost} and ${#Project#CSServiceURI}. In those properties '#Project#' refers to the level in SoapUI the properties are defined. You can also refer to #TestSuite#, #TestCase#, etc.

Now you could manually copy and paste the host of the particular environment to the actual host property, but that can be error prone when dealing with multiple endpoints.
What I did was to create a seperate TestSuite called 'ProjectSettings'. In there I created a testcase per environment: 'SetLocalHosts', SsetDevHosts', etc. In there I created a PropertyTransfer that transfers the particular env-host-property to the actual host-property:

You can create a property transfer for each applicable host in your environment. You can enhance the testcase with particular groovyscripts to determine the properties on run-time. You could even call a generic TestCase from there.

Running the particular testcase before your tests will setup your SoapUI project for the target environment in one go.

Maybe I'll enhance this further in my projects, but for now I find this neat. However, it would have been nice if SoapUI would support different environments with hostnames/urls applicable for that environment. And that you could select a target-environment on project level using a poplist.
Also it would be nice to have custom scripts (like macro's) on project level, that could be coupled to a button in the button bar, in stead of how I do it above.

OSB11g what is the scope of the for-each loop variable?

Wed, 2015-07-01 07:36
Earlier I wrote an article on the strange behaviour of the OSB11g For-each activity (Osb-11g: for each is index-variable an integer?). Today I found out some other peculiar behaviour.

I had to loop over a sequence of  documents, each refering to an attachment. The first document processed well, but at the second iteration the attachment couldn't be found. At first I used Soap with Attachments and now I changed my service to use MTOM. Anyway, at first I thought it to be a SoapUI problem. But adding debug-alerts (I find alerts more comfortable then logs) showed me that the second attachment is really referred to in the message. So apparently, it's not a SoapUI problem.

What happened? Well, have the following for-each:
So I loop over a bunch of documents and at each iteration I'll get the particular document in the document variable. Then I get the attachment, transfer it into a base64-encoded-string, and replace the content with the base64-encoded-string, ... , in the $document variable!!!!! Is that wrong? Well, I expected that in the next iteration the $document variable would be replaced by the new occurrence. But apparently changing the for-each-variable will change the scope of the variable and makes it a 'normal' variable, instead of the loop variable. And since I replaced the contents, It did not have the reference to the next attachment. The quick fix I did was to copy the loop variable to a seperate variable using an assign and then do the changes on that next variable. Each new iteration the content of that variable is overwritten by the assing of the new iteration-variable.

But better is probably to use the index variable and do the changes directly on the main variable, in my case $documents.

So conclusion? Don't change the loop variable!

UPDATE: Oh, by the way, the reason that I change a seperate variable during the loop was that it apparently is not possible to do a Replace or Insert within a loop upon using the index variable. You'll get an error like: 'XQuery exception: line 34, column 11: {err}XP0008 [{bea-err}XP0008a]: Variable
 "$documentIndex" used but not declared for expression: declare namespace jca =
 'http://www.bea.com/wli/sb/transports/jca';... ' in the expression. So what I did was to copy the document-array from the body variable to a $documents variable, delete all the documents in the body variable (leaving the documents-element). Then loop over the $documents variable, create a new $documentNew variable from $document with the changed variables and insert that in the body variable again.

MTOM using SoapUI and OSB

Tue, 2015-06-30 06:40
MTOM (Message Transmission Optimization Mechanism) is incredibly hard... to find practical information about, on SoapUI and OSB. There are loads of articles. Like:
But I need to process documents that are send using MTOM to my service. And to be able to test it, I need to create a working example of a SoapUI project to do exactly that. Also about SoapUI and MTOM there are loads of examples, and it is quite simple really. But I had a more complex wsdl that I was able to use for Soap with Attachments (SwA) wich is also simple really. But how to connect those two in a simple working example? Well, actually, it turns out not so hard either... So bottom-line, MTOM with SoapUI and OSB is not so hard. If you know how, that is.

So let's work this out on a step-by-step basis.
XSD/WSDL I'll start with a simple XSD:
<?xml version="1.0" encoding="windows-1252" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.darwin-it.nl/MTOM"
targetNamespace="http://www.darwin-it.nl/MTOM"
elementFormDefault="qualified">
<xsd:element name="mtomRequest" type="MtomRequestType"/>
<xsd:complexType name="MtomRequestType">
<xsd:sequence>
<xsd:element name="document" type="xsd:base64Binary"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="mtomResponse" type="MtomResponseType"/>
<xsd:complexType name="MtomResponseType">
<xsd:sequence>
<xsd:element name="document" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>

In JDeveloper, this looks like:
The key is the 'xsd:base64Binary' type of the request document. In the response I have a string: in this example I'll base64-encode the attachment using a java-class. Just to show how to process the document. But in my project this is what I need to do.

The WSDL is just as easy, plain synchronous Request-Response:

<wsdl:definitions name="MTOMService" targetNamespace="http://oracle.com/sca/soapservice/ContentServer/MTOMService/MTOMService" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:inp1="http://www.darwin-it.nl/MTOM" xmlns:tns="http://oracle.com/sca/soapservice/ContentServer/MTOMService/MTOMService" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
<wsdl:types>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:import namespace="http://www.darwin-it.nl/MTOM" schemaLocation="../xsd/MTOMRequestResponse.xsd"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="requestMessage">
<wsdl:part name="part1" element="inp1:mtomRequest"/>
</wsdl:message>
<wsdl:message name="replyMessage">
<wsdl:part name="part1" element="inp1:mtomResponse"/>
</wsdl:message>
<wsdl:portType name="execute_ptt">
<wsdl:operation name="execute">
<wsdl:input message="tns:requestMessage"/>
<wsdl:output message="tns:replyMessage"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="execute_pttSOAP11Binding" type="tns:execute_ptt">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="execute">
<soap:operation style="document" soapAction="http://oracle.com/sca/soapservice/ContentServer/MTOMService/MTOMService/execute"/>
<wsdl:input>
<soap:body use="literal" parts="part1"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal" parts="part1"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="execute_ptt">
<wsdl:port name="execute_pttPort" binding="tns:execute_pttSOAP11Binding">
<soap:address location="http://www.example.com"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Did you know that in JDeveloper it is really easy to create this WSDL? Just, create a SOA Project, drag and drop a Webservice on the exposed services lane, define a wsdl as synchronous, with a request and response message. Then open the wsdl in the wsdl editor and drag the operations to the binding pane and then the binding to the services pane:
The SoapUI Part Now, create a new SoapUI project based on this WSDL. It turns out that SoapUI interprets this base64Binary field and creates special content:

This body refers to an attachment, that is not yet added:
      <mtom:mtomRequest>
<mtom:document>cid:915251933163</mtom:document>
</mtom:mtomRequest>
Let's add an image to it, by opening the 'Attachments' tab and clicking on the plus-button: You can select the 'Part' to which the attachment is to be linked. Doing so will change the 'Type' into 'CONTENT'. Edit either the 'ContentID' or the id in the document-element (indicated by 'cid:') to match eachother.

At this point, you can create a mock-service on the request and set the host of the mockservice to 'localhost' and 'MTOMService' in the mock-service editor:
Then you can right-click on the Mock-server and select 'Add endpoint to interface'.

Running the Request, will send the following message to the Mock Service:
(Altough the title is 'Response 1', what you see here is the request received by the Mock Service).
Apparently SoapUI base64 encoded the attachment and embedded it into the document-element.

Now you can enable MTOM on the request. Select the Request and go to the properties pane:
When running the request again SoapUI won't base 64 encode the attachment but send it as a compressed MIME/Multipart-attachment, with a reference in the document:
In the http-log you'll find:
POST /MTOMService HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: multipart/related; type="application/xop+xml"; start="<rootpart@soapui.org>"; start-info="text/xml"; boundary="----=_Part_11_531670487.1435664879005"
SOAPAction: "http://oracle.com/sca/soapservice/ContentServer/MTOMService/MTOMService/execute"
MIME-Version: 1.0
Content-Length: 39605
Host: localhost:8080
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)


------=_Part_11_531670487.1435664879005

Content-Type: application/xop+xml; charset=UTF-8; type="text/xml"

Content-Transfer-Encoding: 8bit

Content-ID: <rootpart@soapui.org>


<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:mtom="http://www.darwin-it.nl/MTOM">
<soapenv:Header/>
<soapenv:Body>
<mtom:mtomRequest>
<mtom:document><inc:Include href="cid:915251933163" xmlns:inc="http://www.w3.org/2004/08/xop/include"/></mtom:document>
</mtom:mtomRequest>
</soapenv:Body>
</soapenv:Envelope>

------=_Part_11_531670487.1435664879005

Content-Type: image/jpeg; name=SoapUIMTOMRequest.jpg

Content-Transfer-Encoding: binary

Content-ID: <915251933163>

Content-Disposition: attachment; name="SoapUIMTOMRequest.jpg"; filename="SoapUIMTOMRequest.jpg"


[0xff][0xd8][0xff][0xe0][0x0][0x10]JFIF[0x0][0x1][0x1][0x0][0x0][0x1][0x0][0x1][0x0][0x0][0xff][0xdb][0x0]C[0x0][0x6][0x4][0x5][0x6][0x5][0x4][0x6][0x6][0x5][0x6][0x7][0x7][0x6][0x8]
[0x10]

[0x9][0x9]
[0x14][0xe][0xf][0xc][0x10][0x17][0x14][0x18][0x18][0x17][0x14][0x16][0x16][0x1a][0x1d]%[0x1f][0x1a][0x1b]#[0x1c][0x16][0x16] , #&')*)[0x19][0x1f]-0-(0%()([0xff][0xdb][0x0]C[0x1][0x7][0x7][0x7]
[0x8]
[0x13]

[0x13]([0x1a][0x16][0x1a](((((((((((((((((((((((((((((((((((((((((((((((((([0xff][0xc0][0x0][0x11][0x8][0x0][0xdc][0x3]7[0x3][0x1]"[0x0][0x2][0x11][0x1][0x3][0x11][0x1][0xff][0xc4][0x0][0x1b][0x0][0x1][0x0][0x2][0x3][0x1][0x1][0x0][0x0][0x0][0x0][0x0][0x0][0x0][0x0][0x0][0x0][0x0][0x5][0x6][0x2][0x3][0x4][0x1][0x7][0xff][0xc4][0x0]P[0x10][0x0][0x1][0x2][0x5][0x2][0x3][0x4][0x5][0x8][0x6][0x8][0x4][0x4][0x6][0x3][0x0][0x1][0x2][0x3][0x0][0x4][0x5][0x11][0x12][0x13]![0x6]"#[0x14][0x15]1QAVa[0x95][0xd2][0x7]2[0x81][0x92][0xa5][0xb3][0xd3][0xd4][0x16]37Ru[0x94]45Bqt[0xb1][0xb4][0xd1]$6r[0x91]%Dbs[0x17]&C[0xa1][0xc1][0xe1]cd[0xb2][0xff][0xc4][0x0][0x19][0x1][0x1][0x1][0x1][0x1][0x1][0x1][0x0][0x0][0x0][0x0][0x0][0x0][0x0][0x0][0x0][0x0][0x0][0x1][0x2][0x3][0x4][0x5][0xff][0xc4][0x0]5[0x11][0x0][0x1][0x3][0x0][0x8][0x4][0x6][0x2][0x2][0x2][0x2][0x3][0x1][0x0][0x0][0x0][0x0][0x1][0x2][0x11][0x3][0x12]!1AQa[0xf0][0x4][0x14]q[0xc1][0x13]"[0x81][0x91][0xa1][0xd1][0xb1][0xe1]2[0xf1]Bb[0x5][0x92]#r[0xd2]R[0xff][0xda][0x0][0xc][0x3][0x1][0x0][0x2][0x11][0x3][0x11][0x0]?[0x0][0xfb];[0xf2][0x8d]O|[0xa3][0x19][0x19][0x85]L[0x9]4[0xd2];@i[0x99][0x87][0x19][0x19][0x87][0xad][0x97]![0x1b][0xd8][0xda];;[0xbf][0x87][0xae][0xa0]{[0xc0][0x14][0xa8][0xa0][0x85]O[0xcd][\r][0xc1][0xb1][0xf1]W[0xb3][0xc7][0xd3][0xe3][0x1a][0xd8][0xfd][0xaa][0xb9][0xfc][0x8][0xfd][0xfc]j[0x9d][0xfe][0x98][0xff][0x0][0xfe][0xe2][0xbf][0xce]=[0x1c]=[0x12]R[0xaa][0xa2][0x9c])[0xe9]V[0x8d][0x11]P[0xea][0xee][0xfe][0x1d][0xf3][0x9f][0xf7][0x84][0xd7][0xc7][0xe][0xef][0xe1][0xdf]9[0xff][0x0]xM|q[E~[0x9a][0xb9][0x99][0xb6][0xb5][0xd6][0x94][0xca][0xa5]ky[0xf5][0xb2][0xb4][0xcb][0xa4] [0xd9]}b4[0xc9]I[0xb8] *[0xe0][0xa5]W[0xf9][0xa6][0xdd][0x14][0xba][0x94][0xad]R]OI[0xad]d!E[0xb]C[0x8d])[0xa7][0x1b]U[0x81][0xb2][0x90][0xb0][0x14][0x93]b[\r][0x88][0x17][0x4][0x1f][0x2][0xc]z[0xf9]&[0xea]y[0xf9][0x9a]D[0xc0][0x9c][0xee][0xfe][0x1d][0xf3][0x9f][0xf7][0x84][0xd7][0xc7][0xe][0xef][0xe1][0xdf]9[0xff][0x0]xM|q^[0xab][0xd7])4].[0xf8][0xaa]HHk_O[0xb5]L![0xac][0xed]k[0xdb]"/k[0x8f][0xf]1[0x1d]4[0xf9][0xe9]J[0x94][0x9b]st[0xe9][0xa6]&[0xe5]\[0xbe][0xf]0[0xe0]q
[0xb1] [0xd9]Ccb[0x8][0xfa]#<[0xa5][0x1c][0xc4][0xa8][0xe6][0x9f]|[0x13][0x1d][0xdf][0xc3][0xbe]s[0xfe][0xf0][0x9a][0xf8][0xe1][0xdd][0xfc];[0xe7]?[0xef][0x9][0xaf][0x8e]#[0xe1][0x17][0x93]fjNm[0xf9]!![0xdd][0xfc];[0xe7]?[0xef][0x9][0xaf][0x8e][0x1d][0xdf][0xc3][0xbe]s[0xfe][0xf0][0x9a][0xf8][0xe2]>[0x10][0xe4][0xd9][0x9a][0x8e]m[0xf9]!![0xdd][0xfc];[0xe7]?[0xef][0x9][0xaf][0x8e][0x1d][0xdf][0xc3][0xbe]s[0xfe][0xf0][0x9a][0xf8][0xe2]>[0x10][0xe4][0xd9][0x9a][0x8e]m[0xf9]!![0xdd][0xfc];[0xe7]?[0xef][0x9][0xaf][0x8e][0x1d][0xdf][0xc3][0xbe]s[0xfe][0xf0][0x9a][0xf8][0xe2][0x1d][0xf9][0xe9]F'%[0xa5][0x1f][0x9a]a[0xa9][0xa9][0xac][0xb4][0x19][[0x81]+w[0x11]u`[0x93][0xba][0xac]76[0xf0][0x8d][0xb3]
[0xc6]Y[0xf5]j-[0xab]4[0xbe]t7[0xa8][0xa4][0xf2][0x9d][0xd2][0x9c]Uuy[0xb][0x1d][0xed][0xe]M[0x99][0xa9]y[0xa7][0xe4][0x84][0x9f]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8w[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x88]y[0xa5][0xbe][0x8e][0xd5][0x96][0xab]8!IV[0x8]+[0xd0]G[[0x12][0x9e][0x91][0xd4]x[0xd9]<[0xbb][0xdb]o[0xa5]4[0xb7][0xd1][0xda][0xb2][0xd5]g[0x4])*[0xc1][0x5]z[0x8][0xeb]bS[0xd2]:[0x8f][0x1b]'[0x97]{m[0xf4][0xce]Q[0x9a][0x97][0x99]~[0x84][0xc7]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8w[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x88]y[0xa5][0xbe][0x8e][0xd5][0x96][0xab]8!IV[0x8]+[0xd0]G[[0x12][0x9e][0x91][0xd4]x[0xd9]<[0xbb][0xdb]o[0xa5]4[0xb7][0xd1][0xda][0xb2][0xd5]g[0x4])*[0xc1][0x5]z[0x8][0xeb]bS[0xd2]:[0x8f][0x1b]'[0x97]{m[0xf4][0xb9]Fj9[0x97][0xe8]Lw[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x87]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8[0x87][0x9a][[0xe8][0xed]Yj[0xb3][0x82][0x14][0x95]`[0x82][0xbd][0x4]u[0xb1])[0xe9][0x1d]G[0x8d][0x93][0xcb][0xbd][0xb6][0xfa]SK}[0x1d][0xab]-VpB[0x92][0xac][0x10]W[0xa0][0x8e][0xb6]%=#[0xa8][0xf1][0xb2]yw[0xb6][0xdf]K[0x94]f[0xa3][0x99]~[0x84][0xc7]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8w[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x88]y[0xa5][0xbe][0x8e][0xd5][0x96][0xab]8!IV[0x8]+[0xd0]G[[0x12][0x9e][0x91][0xd4]x[0xd9]<[0xbb][0xdb]o[0xa5]4[0xb7][0xd1][0xda][0xb2][0xd5]g[0x4])*[0xc1][0x5]z[0x8][0xeb]bS[0xd2]:[0x8f][0x1b]'[0x97]{m[0xf4][0xb9]Fj9[0x97][0xe8]Lw[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x87]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8[0x87][0x9a][[0xe8][0xed]Yj[0xb3][0x82][0x14][0x95]`[0x82][0xbd][0x4]u[0xb1])[0xe9][0x1d]G[0x8d][0x93][0xcb][0xbd][0xb6][0xfa]SK}[0x1d][0xab]-VpB[0x92][0xac][0x10]W[0xa0][0x8e][0xb6]%=#[0xa8][0xf1][0xb2]yw[0xb6][0xdf]K[0x94]f[0xa3][0x99]~[0x84][0xc7]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8w[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x88]y[0xa5][0xbe][0x8e][0xd5][0x96][0xab]8!IV[0x8]+[0xd0]G[[0x12][0x9e][0x91][0xd4]x[0xd9]<[0xbb][0xdb]o[0xa5]4[0xb7][0xd1][0xda][0xb2][0xd5]g[0x4])*[0xc1][0x5]z[0x8][0xeb]bS[0xd2]:[0x8f][0x1b]'[0x97]{m[0xf4][0xb9]Fj9[0x97][0xe8]Lw[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x87]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8[0x87][0x9a][[0xe8][0xed]Yj[0xb3][0x82][0x14][0x95]`[0x82][0xbd][0x4]u[0xb1])[0xe9][0x1d]G[0x8d][0x93][0xcb][0xbd][0xb6][0xfa]SK}[0x1d][0xab]-VpB[0x92][0xac][0x10]W[0xa0][0x8e][0xb6]%=#[0xa8][0xf1][0xb2]yw[0xb6][0xdf]K[0x94]f[0xa3][0x99]~[0x84][0xc7]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8w[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x88]y[0xa5][0xbe][0x8e][0xd5][0x96][0xab]8!IV[0x8]+[0xd0]G[[0x12][0x9e][0x91][0xd4]x[0xd9]<[0xbb][0xdb]o[0xa5]4[0xb7][0xd1][0xda][0xb2][0xd5]g[0x4])*[0xc1][0x5]z[0x8][0xeb]bS[0xd2]:[0x8f][0x1b]'[0x97]{m[0xf4][0xb9]Fj9[0x97][0xe8]Lw[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x87]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8[0x87][0x9a][[0xe8][0xed]Yj[0xb3][0x82][0x14][0x95]`[0x82][0xbd][0x4]u[0xb1])[0xe9][0x1d]G[0x8d][0x93][0xcb][0xbd][0xb6][0xfa]SK}[0x1d][0xab]-VpB[0x92][0xac][0x10]W[0xa0][0x8e][0xb6]%=#[0xa8][0xf1][0xb2]yw[0xb6][0xdf]K[0x94]f[0xa3][0x99]~[0x84][0xc7]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8w[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x88]y[0xa5][0xbe][0x8e][0xd5][0x96][0xab]8!IV[0x8]+[0xd0]G[[0x12][0x9e][0x91][0xd4]x[0xd9]<[0xbb][0xdb]o[0xa5]4[0xb7][0xd1][0xda][0xb2][0xd5]g[0x4])*[0xc1][0x5]z[0x8][0xeb]bS[0xd2]:[0x8f][0x1b]'[0x97]{m[0xf4][0xb9]Fj9[0x97][0xe8]Lw[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x87]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8[0x87][0x9a][[0xe8][0xed]Yj[0xb3][0x82][0x14][0x95]`[0x82][0xbd][0x4]u[0xb1])[0xe9][0x1d]G[0x8d][0x93][0xcb][0xbd][0xb6][0xfa]SK}[0x1d][0xab]-VpB[0x92][0xac][0x10]W[0xa0][0x8e][0xb6]%=#[0xa8][0xf1][0xb2]yw[0xb6][0xdf]K[0x94]f[0xa3][0x99]~[0x84][0xc7]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8w[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x88]y[0xa5][0xbe][0x8e][0xd5][0x96][0xab]8!IV[0x8]+[0xd0]G[[0x12][0x9e][0x91][0xd4]x[0xd9]<[0xbb][0xdb]o[0xa5]4[0xb7][0xd1][0xda][0xb2][0xd5]g[0x4])*[0xc1][0x5]z[0x8][0xeb]bS[0xd2]:[0x8f][0x1b]'[0x97]{m[0xf4][0xb9]Fj9[0x97][0xe8]Lw[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x87]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8[0x87][0x9a][[0xe8][0xed]Yj[0xb3][0x82][0x14][0x95]`[0x82][0xbd][0x4]u[0xb1])[0xe9][0x1d]G[0x8d][0x93][0xcb][0xbd][0xb6][0xfa]SK}[0x1d][0xab]-VpB[0x92][0xac][0x10]W[0xa0][0x8e][0xb6]%=#[0xa8][0xf1][0xb2]yw[0xb6][0xdf]K[0x94]f[0xa3][0x99]~[0x84][0xc7]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8w[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x88]y[0xa5][0xbe][0x8e][0xd5][0x96][0xab]8!IV[0x8]+[0xd0]G[[0x12][0x9e][0x91][0xd4]x[0xd9]<[0xbb][0xdb]o[0xa5]4[0xb7][0xd1][0xda][0xb2][0xd5]g[0x4])*[0xc1][0x5]z[0x8][0xeb]bS[0xd2]:[0x8f][0x1b]'[0x97]{m[0xf4][0xb9]Fj9[0x97][0xe8]Lw[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x87]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8[0x87][0x9a][[0xe8][0xed]Yj[0xb3][0x82][0x14][0x95]`[0x82][0xbd][0x4]u[0xb1])[0xe9][0x1d]G[0x8d][0x93][0xcb][0xbd][0xb6][0xfa]SK}[0x1d][0xab]-VpB[0x92][0xac][0x10]W[0xa0][0x8e][0xb6]%=#[0xa8][0xf1][0xb2]yw[0xb6][0xdf]K[0x94]f[0xa3][0x99]~[0x84][0xc7]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8w[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x88]y[0xa5][0xbe][0x8e][0xd5][0x96][0xab]8!IV[0x8]+[0xd0]G[[0x12][0x9e][0x91][0xd4]x[0xd9]<[0xbb][0xdb]o[0xa5]4[0xb7][0xd1][0xda][0xb2][0xd5]g[0x4])*[0xc1][0x5]z[0x8][0xeb]bS[0xd2]:[0x8f][0x1b]'[0x97]{m[0xf4][0xb9]Fj9[0x97][0xe8]Lw[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x87]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8[0x87][0x9a][[0xe8][0xed]Yj[0xb3][0x82][0x14][0x95]`[0x82][0xbd][0x4]u[0xb1])[0xe9][0x1d]G[0x8d][0x93][0xcb][0xbd][0xb6][0xfa]SK}[0x1d][0xab]-VpB[0x92][0xac][0x10]W[0xa0][0x8e][0xb6]%=#[0xa8][0xf1][0xb2]yw[0xb6][0xdf]K[0x94]f[0xa3][0x99]~[0x84][0xc7]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8w[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x88]y[0xa5][0xbe][0x8e][0xd5][0x96][0xab]8!IV[0x8]+[0xd0]G[[0x12][0x9e][0x91][0xd4]x[0xd9]<[0xbb][0xdb]o[0xa5]4[0xb7][0xd1][0xda][0xb2][0xd5]g[0x4])*[0xc1][0x5]z[0x8][0xeb]bS[0xd2]:[0x8f][0x1b]'[0x97]{m[0xf4][0xb9]Fj9[0x97][0xe8]Lw[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x87]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8[0x87][0x9a][[0xe8][0xed]Yj[0xb3][0x82][0x14][0x95]`[0x82][0xbd][0x4]u[0xb1])[0xe9][0x1d]G[0x8d][0x93][0xcb][0xbd][0xb6][0xfa]SK}[0x1d][0xab]-VpB[0x92][0xac][0x10]W[0xa0][0x8e][0xb6]%=#[0xa8][0xf1][0xb2]yw[0xb6][0xdf]K[0x94]f[0xa3][0x99]~[0x84][0xc7]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8w[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x88]y[0xa5][0xbe][0x8e][0xd5][0x96][0xab]8!IV[0x8]+[0xd0]G[[0x12][0x9e][0x91][0xd4]x[0xd9]<[0xbb][0xdb]o[0xa5]4[0xb7][0xd1][0xda][0xb2][0xd5]g[0x4])*[0xc1][0x5]z[0x8][0xeb]bS[0xd2]:[0x8f][0x1b]'[0x97]{m[0xf4][0xb9]Fj9[0x97][0xe8]Lw[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x87]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8[0x87][0x9a][[0xe8][0xed]Yj[0xb3][0x82][0x14][0x95]`[0x82][0xbd][0x4]u[0xb1])[0xe9][0x1d]G[0x8d][0x93][0xcb][0xbd][0xb6][0xfa]SK}[0x1d][0xab]-VpB[0x92][0xac][0x10]W[0xa0][0x8e][0xb6]%=#[0xa8][0xf1][0xb2]yw[0xb6][0xdf]K[0x94]f[0xa3][0x99]~[0x84][0xc7]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8w[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x88]y[0xa5][0xbe][0x8e][0xd5][0x96][0xab]8!IV[0x8]+[0xd0]G[[0x12][0x9e][0x91][0xd4]x[0xd9]<[0xbb][0xdb]o[0xa5]4[0xb7][0xd1][0xda][0xb2][0xd5]g[0x4])*[0xc1][0x5]z[0x8][0xeb]bS[0xd2]:[0x8f][0x1b]'[0x97]{m[0xf4][0xb9]Fj9[0x97][0xe8]Lw[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x87]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8[0x87][0x9a][[0xe8][0xed]Yj[0xb3][0x82][0x14][0x95]`[0x82][0xbd][0x4]u[0xb1])[0xe9][0x1d]G[0x8d][0x93][0xcb][0xbd][0xb6][0xfa]SK}[0x1d][0xab]-VpB[0x92][0xac][0x10]W[0xa0][0x8e][0xb6]%=#[0xa8][0xf1][0xb2]yw[0xb6][0xdf]K[0x94]f[0xa3][0x99]~[0x84][0xc7]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8w[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x88]y[0xa5][0xbe][0x8e][0xd5][0x96][0xab]8!IV[0x8]+[0xd0]G[[0x12][0x9e][0x91][0xd4]x[0xd9]<[0xbb][0xdb]o[0xa5]4[0xb7][0xd1][0xda][0xb2][0xd5]g[0x4])*[0xc1][0x5]z[0x8][0xeb]bS[0xd2]:[0x8f][0x1b]'[0x97]{m[0xf4][0xb9]Fj9[0x97][0xe8]Lw[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x87]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8[0x87][0x9a][[0xe8][0xed]Yj[0xb3][0x82][0x14][0x95]`[0x82][0xbd][0x4]u[0xb1])[0xe9][0x1d]G[0x8d][0x93][0xcb][0xbd][0xb6][0xfa]SK}[0x1d][0xab]-VpB[0x92][0xac][0x10]W[0xa0][0x8e][0xb6]%=#[0xa8][0xf1][0xb2]yw[0xb6][0xdf]K[0x94]f[0xa3][0x99]~[0x84][0xc7]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8w[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x88]y[0xa5][0xbe][0x8e][0xd5][0x96][0xab]8!IV[0x8]+[0xd0]G[[0x12][0x9e][0x91][0xd4]x[0xd9]<[0xbb][0xdb]o[0xa5]4[0xb7][0xd1][0xda][0xb2][0xd5]g[0x4])*[0xc1][0x5]z[0x8][0xeb]bS[0xd2]:[0x8f][0x1b]'[0x97]{m[0xf4][0xb9]Fj9[0x97][0xe8]Lw[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x87]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8[0x87][0x9a][[0xe8][0xed]Yj[0xb3][0x82][0x14][0x95]`[0x82][0xbd][0x4]u[0xb1])[0xe9][0x1d]G[0x8d][0x93][0xcb][0xbd][0xb6][0xfa]SK}[0x1d][0xab]-VpB[0x92][0xac][0x10]W[0xa0][0x8e][0xb6]%=#[0xa8][0xf1][0xb2]yw[0xb6][0xdf]K[0x94]f[0xa3][0x99]~[0x84][0xc7]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8w[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x88]y[0xa5][0xbe][0x8e][0xd5][0x96][0xab]8!IV[0x8]+[0xd0]G[[0x12][0x9e][0x91][0xd4]x[0xd9]<[0xbb][0xdb]o[0xa5]4[0xb7][0xd1][0xda][0xb2][0xd5]g[0x4])*[0xc1][0x5]z[0x8][0xeb]bS[0xd2]:[0x8f][0x1b]'[0x97]{m[0xf4][0xb9]Fj9[0x97][0xe8]Lw[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x87]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8[0x87][0x9a][[0xe8][0xed]Yj[0xb3][0x82][0x14][0x95]`[0x82][0xbd][0x4]u[0xb1])[0xe9][0x1d]G[0x8d][0x93][0xcb][0xbd][0xb6][0xfa]SK}[0x1d][0xab]-VpB[0x92][0xac][0x10]W[0xa0][0x8e][0xb6]%=#[0xa8][0xf1][0xb2]yw[0xb6][0xdf]K[0x94]f[0xa3][0x99]~[0x84][0xc7]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8w[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x88]y[0xa5][0xbe][0x8e][0xd5][0x96][0xab]8!IV[0x8]+[0xd0]G[[0x12][0x9e][0x91][0xd4]x[0xd9]<[0xbb][0xdb]o[0xa5]4[0xb7][0xd1][0xda][0xb2][0xd5]g[0x4])*[0xc1][0x5]z[0x8][0xeb]bS[0xd2]:[0x8f][0x1b]'[0x97]{m[0xf4][0xb9]Fj9[0x97][0xe8]Lw[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x87]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8[0x87][0x9a][[0xe8][0xed]Yj[0xb3][0x82][0x14][0x95]`[0x82][0xbd][0x4]u[0xb1])[0xe9][0x1d]G[0x8d][0x93][0xcb][0xbd][0xb6][0xfa]SK}[0x1d][0xab]-VpB[0x92][0xac][0x10]W[0xa0][0x8e][0xb6]%=#[0xa8][0xf1][0xb2]yw[0xb6][0xdf]K[0x94]f[0xa3][0x99]~[0x84][0xc7]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8w[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x88]y[0xa5][0xbe][0x8e][0xd5][0x96][0xab]8!IV[0x8]+[0xd0]G[[0x12][0x9e][0x91][0xd4]x[0xd9]<[0xbb][0xdb]o[0xa5]4[0xb7][0xd1][0xda][0xb2][0xd5]g[0x4])*[0xc1][0x5]z[0x8][0xeb]bS[0xd2]:[0x8f][0x1b]'[0x97]{m[0xf4][0xb9]Fj9[0x97][0xe8]Lw[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x87]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8[0x87][0x9a][[0xe8][0xed]Yj[0xb3][0x82][0x14][0x95]`[0x82][0xbd][0x4]u[0xb1])[0xe9][0x1d]G[0x8d][0x93][0xcb][0xbd][0xb6][0xfa]SK}[0x1d][0xab]-VpB[0x92][0xac][0x10]W[0xa0][0x8e][0xb6]%=#[0xa8][0xf1][0xb2]yw[0xb6][0xdf]K[0x94]f[0xa3][0x99]~[0x84][0xc7]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8w[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x88]y[0xa5][0xbe][0x8e][0xd5][0x96][0xab]8!IV[0x8]+[0xd0]G[[0x12][0x9e][0x91][0xd4]x[0xd9]<[0xbb][0xdb]o[0xa5]4[0xb7][0xd1][0xda][0xb2][0xd5]g[0x4])*[0xc1][0x5]z[0x8][0xeb]bS[0xd2]:[0x8f][0x1b]'[0x97]{m[0xf4][0xb9]Fj9[0x97][0xe8]Lw[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x87]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8[0x87][0x9a][[0xe8][0xed]Yj[0xb3][0x82][0x14][0x95]`[0x82][0xbd][0x4]u[0xb1])[0xe9][0x1d]G[0x8d][0x93][0xcb][0xbd][0xb6][0xfa]SK}[0x1d][0xab]-VpB[0x92][0xac][0x10]W[0xa0][0x8e][0xb6]%=#[0xa8][0xf1][0xb2]yw[0xb6][0xdf]K[0x94]f[0xa3][0x99]~[0x84][0xc7]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8w[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x88]y[0xa5][0xbe][0x8e][0xd5][0x96][0xab]8!IV[0x8]+[0xd0]G[[0x12][0x9e][0x91][0xd4]x[0xd9]<[0xbb][0xdb]o[0xa5]4[0xb7][0xd1][0xda][0xb2][0xd5]g[0x4])*[0xc1][0x5]z[0x8][0xeb]bS[0xd2]:[0x8f][0x1b]'[0x97]{m[0xf4][0xb9]Fj9[0x97][0xe8]Lw[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x87]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8[0x87][0x9a][[0xe8][0xed]Yj[0xb3][0x82][0x14][0x95]`[0x82][0xbd][0x4]u[0xb1])[0xe9][0x1d]G[0x8d][0x93][0xcb][0xbd][0xb6][0xfa]SK}[0x1d][0xab]-VpB[0x92][0xac][0x10]W[0xa0][0x8e][0xb6]%=#[0xa8][0xf1][0xb2]yw[0xb6][0xdf]K[0x94]f[0xa3][0x99]~[0x84][0xc7]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8w[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x88]y[0xa5][0xbe][0x8e][0xd5][0x96][0xab]8!IV[0x8]+[0xd0]G[[0x12][0x9e][0x91][0xd4]x[0xd9]<[0xbb][0xdb]o[0xa5]4[0xb7][0xd1][0xda][0xb2][0xd5]g[0x4])*[0xc1][0x5]z[0x8][0xeb]bS[0xd2]:[0x8f][0x1b]'[0x97]{m[0xf4][0xb9]Fj9[0x97][0xe8]Lw[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x87]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8[0x87][0x9a][[0xe8][0xed]Yj[0xb3][0x82][0x14][0x95]`[0x82][0xbd][0x4]u[0xb1])[0xe9][0x1d]G[0x8d][0x93][0xcb][0xbd][0xb6][0xfa]SK}[0x1d][0xab]-VpB[0x92][0xac][0x10]W[0xa0][0x8e][0xb6]%=#[0xa8][0xf1][0xb2]yw[0xb6][0xdf]K[0x94]f[0xa3][0x99]~[0x84][0xc7]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8w[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x88]y[0xa5][0xbe][0x8e][0xd5][0x96][0xab]8!IV[0x8]+[0xd0]G[[0x12][0x9e][0x91][0xd4]x[0xd9]<[0xbb][0xdb]o[0xa5]4[0xb7][0xd1][0xda][0xb2][0xd5]g[0x4])*[0xc1][0x5]z[0x8][0xeb]bS[0xd2]:[0x8f][0x1b]'[0x97]{m[0xf4][0xb9]Fj9[0x97][0xe8]Lw[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x87]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8[0x87][0x9a][[0xe8][0xed]Yj[0xb3][0x82][0x14][0x95]`[0x82][0xbd][0x4]u[0xb1])[0xe9][0x1d]G[0x8d][0x93][0xcb][0xbd][0xb6][0xfa]SK}[0x1d][0xab]-VpB[0x92][0xac][0x10]W[0xa0][0x8e][0xb6]%=#[0xa8][0xf1][0xb2]yw[0xb6][0xdf]K[0x94]f[0xa3][0x99]~[0x84][0xc7]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8w[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x88]y[0xa5][0xbe][0x8e][0xd5][0x96][0xab]8!IV[0x8]+[0xd0]G[[0x12][0x9e][0x91][0xd4]x[0xd9]<[0xbb][0xdb]o[0xa5]4[0xb7][0xd1][0xda][0xb2][0xd5]g[0x4])*[0xc1][0x5]z[0x8][0xeb]bS[0xd2]:[0x8f][0x1b]'[0x97]{m[0xf4][0xb9]Fj9[0x97][0xe8]Lw[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x87]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8[0x87][0x9a][[0xe8][0xed]Yj[0xb3][0x82][0x14][0x95]`[0x82][0xbd][0x4]u[0xb1])[0xe9][0x1d]G[0x8d][0x93][0xcb][0xbd][0xb6][0xfa]SK}[0x1d][0xab]-VpB[0x92][0xac][0x10]W[0xa0][0x8e][0xb6]%=#[0xa8][0xf1][0xb2]yw[0xb6][0xdf]K[0x94]f[0xa3][0x99]~[0x84][0xc7]w[0xf0][0xef][0x9c][0xff][0x0][0xbc]&[0xbe]8w[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x88]y[0xa5][0xbe][0x8e][0xd5][0x96][0xab]8!IV[0x8]+[0xd0]G[[0x12][0x9e][0x91][0xd4]x[0xd9]<[0xbb][0xdb]o[0xa5]4[0xb7][0xd1][0xda][0xb2][0xd5]g[0x4])*[0xc1][0x5]z[0x8][0xeb]bS[0xd2]:[0x8f][0x1b]'[0x97]{m[0xf4][0xb9]Fj9[0x97][0xe8]Lw[0xe][0xf9][0xcf][0xfb][0xc2]k[0xe3][0x84]G[0xb2][0xa7][0xd3]>B[0x92][0x96][0xf0]8[0xa9].$[0xa9][0xb6]Qwq$[0xe9]s[0xb8][0xab]&[0xe9][0xbf]([0xff][0x0][0xee][0x8c][0xaf]
[0xc4][0xcf]~[0x85]N%[0xda]o[0xd4][0xeb]c[0xf6][0xaa][0xe7][0xf0]#[0xf7][0xf1][0xaa]w[0xfa]c[0xff][0x0][0xfb][0x8a][0xff][0x0]8[0xda][0xc7][0xed]U[0xcf][0xe0]G[0xef][0xe3]T[0xef][0xf4][0xc7][0xff][0x0][0xf7][0x15][0xfe]q[0x8e][0xf][0xf9])[0xae].[0xe4]>r[0x95]PMG[0x89][0x9e][0xa9][0xbd]:[0xe4][0xbc][0xd4][0xb4][0xc8][0x98]q[0xd6][0xdb]m[0xb7][0x98]d[0xe9][0xbe][0x94][0xe8][0x80][0xe2][0xb4][0xc9][0x8][0x5][0xc0]V[0x7][0xea][0xc9][0x5]D[0xcd][0xf0][0x13][0xb2]st[0x97][0xa7]d[0xdd][0x9a]}[0xc9][0x97][0xca][0xdf]~eM)N[0xad])J[0x1][0xc9][0x9e][0x92][0x80]JP[0x9b][0xb7][0xb7]-[0x8f]0Tl[0xfd][0xc][0xe1][0xf0][0xf4][0xf3][0xc9][0xa6]2[0x87][0xa7][0x9b][0x98]je[0xc4][0x12][0x95][0xbc][0x87][0xd5][0x93][0x81]J[0x6][0xe6][0xe7][0xc3][0xd2][0x9f][0x4][0xd8]m[0x16][0x4][0xa4]$XG[0xd3]s[0x91]n[0xde][0xf1]<[0xae]rD![0xf2]?[0x96]t:[0xe7][0x1d][0xf0]
[0x18][0xa1][0xb1]_p[0xf7][0x85][0xa9][0xcf][0xad][0x8]C[0xdd]$x[0x95][0x82][0x91]o[0x9d][0xb8][0xfe][0xcf][0x9c]Gp[0x85]~_[0x85]>F8[0x87][0x8a][0xa8][0x89][0x90][0x98]T[0xd4][0xfb][0x93][0xa8][0x91]d[0x94][0xb7]"[0xb7]V[0xdb]ia[[0x2]p[0x5]$[0x80][0x13]q[0xb0][0xd8][0x85][0x1f][0xae][0xce][0xd1]i[0xf3][0xd5]zmRj_9[0xea]n[0xaf]ew5[\r]=D[0xe2][0xbd][0x81][0xb1][0xb8][0x16][0xdc][0x1b]z#[0x9e]O[0x85][0xe8][0x92]s[0x95][0x99][0x99]jk[0x8]r[0xb1]n[0xde][0x8]%[0x13][0x16]

Where I removed all the new-line and timing codings, for readability. This is what actually goes 'over the line'.
The OSB PartNow we're ready for the OSB part. Create a new OSB project and add the wsdl and xsd to it. If you created the wsdl, like I did, in JDeveloper, you can create the OSB project with the same name in the same folder as the JDeveloper project.

Create a new Proxy Service, and name it 'MTOMService' for instance. Base it on the MTOMService wsdl, created above.
I added a Pipeline, with stages and alerts to log the $attachments and $body variables. However, it turns out that since we're using MTOM via a base64Binary-element, the Attachments variable is empty. The body variable contains the message as seen in SoapUI.



Now, the most interesting part here is: 'How to get to the attachment-content?' Using 'Soap with Attachments' (SwA), the $attachments variable gives access to the binary content, with an expression like:
$attachments/ctx:attachment[ctx:Content-ID/text()=$contentId]/ctx:body/ctx:binary-content
Where 'ctx:' is an internal namespace of OSB:

But since the $attachments is empty, this won't work. It is the base64Binary element that gives access to the content, in just the same way. So the expression is:
$body//mtom:document/ctx:binary-content

I added an assign with this as an expression to a seperate variable called 'documentBin'.

Then I added a Java Callout to my Base64-encoding method. For this I used the class described in my previous article. I jarred it and added the jar to my project. The input of this class is a 'byte[] bytes' and the output is a 'String' for wich I used the variable 'documentB64'. Then I added a replace with the following to pass back the response:
<mtom:mtomResponse xmlns:mtom="http://www.darwin-it.nl/MTOM">
<mtom:document>{$documentB64}</mtom:document>
</mtom:mtomResponse>

Then, an important setting: enable MTOM: go to the Message Handling tab of the proxy service:
Check the box 'Enabled' of 'XOP/MTOM Support'. Leave radio-button to 'Include Binary Data by Reference'. Save the proxy service.
The proof in the eatingNow, publish it to a running OSB server and change the Endpoint URL within SoapUI to the OSB Service.
Running the SoapUI Request via OSB results in the following response:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header xmlns:mtom="http://www.darwin-it.nl/MTOM"/>
<soapenv:Body xmlns:mtom="http://www.darwin-it.nl/MTOM">
<mtom:mtomResponse>
<mtom:document>/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwg....</mtom:document>
</mtom:mtomResponse>
</soapenv:Body>
</soapenv:Envelope>

The Alert of the documentB64 variable shows:
ConclusionI spent quite some time searching the internet-area on usable articles on SoapUI, OSB and MTOM. But in the end, writing this article cost me more time then implementing this. I hope this article can be rightfully categorized in my 'FMW made Simple'-series.
DownloadsI made my projects downloadable via:


Deployment plan of resource adapter missing

Mon, 2015-06-29 07:29
Today I was struggling with my OSB domain. Last week I switched laptops and did a new OSB installation on my new laptop and thought it was smart to just zip the OSB Domain from my old laptop to unzip it on my new laptop.

What I forgot was to copy the adapter plan.xml from the oracle home on my old laptop. So the resource adapter did not start correctly. It was even not editable, since it required the missing adapter plan. Searching the domain on files containing the name of the plan brought me to editing the config.xml of the domain.

For all the resource adapters you'll find entries like:
 <app-deployment>
<name>DbAdapter</name>
<target>AdminServer</target>
<module-type>rar</module-type>
<source-path>C:/Oracle/Middleware/Oracle_OSB1/soa/connectors/DbAdapter.rar</source-path>
<deployment-order>322</deployment-order>
<plan-dir xsi:nil="true"></plan-dir>
<plan-path>C:\Oracle\Middleware\Oracle_OSB1\soa\connectors\DBAdapterPlan.xml</plan-path>
<security-dd-model>DDOnly</security-dd-model>
<staging-mode>nostage</staging-mode>
</app-deployment>
If you compare this to an entry that was not edited before, for instance, the AQ Adapter, you'll find that the other Adapter lacks the elements for  plan-dir and plan-path. So I deleted those and restarted my domain. When I edited the adapter again, it asked for the plan name again, as it would on editing it for the first time. Nice thing is that the default/demo entries were there again. So I only had to edit my own custom datasource and was on track again.

Base64 encoding/decoding in OSB

Wed, 2015-06-24 04:28
Of course there are several java examples to do a base64 encoding on the internet. And there are almost nearly as much encoding implementations in different environments. But which one works in Weblogic/OSB11g? And to implement those examples, compile and jar them, I find myself on a quest for the necessary jars. Of course you can refer to the weblogic.jar in your project of ant file. But that is a little too much, I think. I'd like to find and deliver the bare minimum of jars needed for my project.

For my latest customer/project I came up with this class:

package nl.alliander.osb.base64;

import java.io.IOException;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import weblogic.utils.encoders.BASE64Decoder;
import weblogic.utils.encoders.BASE64Encoder;
import java.nio.charset.Charset;

public class Base64EncoderDecoder
{
private static final Charset UTF8_CHARSET;

public static void main(final String[] args) {
}

public static String encode(final byte[] bytes) {
final BASE64Encoder encoder = new BASE64Encoder();
final String encodedString = encoder.encodeBuffer(bytes);
return encodedString;
}
public static int getLength(final byte[] bytes) {
int length = bytes.length;
return length;
}
public static byte[] decode(final String b64Document) throws IOException {
final BASE64Decoder decoder = new BASE64Decoder();
final InputStream inputStream = new ByteArrayInputStream(b64Document.getBytes(Base64EncoderDecoder.UTF8_CHARSET));
final byte[] decodedBytes = decoder.decodeBuffer(inputStream);
return decodedBytes;
}

static {
UTF8_CHARSET = Charset.forName("UTF-8");
}
}

And if you use JDeveloper11g as a IDE the only lib you need to compile this is: com.bea.core.utils.full_1.9.0.1.jar. Or com.bea.core.utils.full_1.10.0.0.jar, if using oepe version 11.1.1.8. The jars can be found in ${oracle.home}/modules. Where ${oracle.home} refers to your JDeveloper11g or OEPE-Middleware installation.

By the way, in my OSB project I need to process Attachments in my message (Soap with Attachments), where I need to upload the documents to a ContentServer. Unfortunately the ContentServer needs the filesize (it apparenlty does not determine it by base64-decoding it). So I added the getLength() method to determine it with a java-callout similar to the base64-encode.


Input of the methods is a variable like 'attachmentBin' resulted from an Assing with an expression like:
$attachments/ctx:attachment[ctx:Content-ID/text()=$contentId]/ctx:body/ctx:binary-content


The Byte-Anniversary

Tue, 2015-06-16 05:15
I was looking into my blog-entries, and found that my former blog was number 254. So by entering this nonsense blog-entry, I reach the 255. Which makes it my 8-bit, or byte, anniversary:


And apparently my articles have been read as well... Nice thing is that I've reached this amount in nearly 8 years. So up to the next byte. Unfortunately in this case 2 bytes does not make up a Word...

Index variables in Replace/Insert/Delete: Bug or not a bug?

Tue, 2015-06-16 04:01
At my current customer I'm to process Attachments in Oracle Service Bus (11g).
I get a soap message, in which several documents are registered to be processed in a Content Server.
For each document the content is delivered as an soap/mime-attachment.

Because of some requirements I need to store the message, complete with the attachments Base64 encoded, in the database. So I have to pick each attachment, base64 encode it and then insert the content at the corresponding document in the soap message. So I need to do an insert or replace of a specific element of the body variable based on an index variable.

It turns out that you can perfectly do an assign with an expression like:
$body/stag:StageDocumentsRequestMessage/Payload/stag:documents/stag:document[contentId/text()=$contentId]
to a variable, for instance called document.

I can do an insert of the base64-encoded content into that document variable. But that does not get into the body variable. Since, apparently, document is a copy of and not a reference to the particular node.

So lets do a replace with the xpath-expresin:
$body/stag:StageDocumentsRequestMessage/Payload/stag:documents/stag:document[contentId/text()=$contentId]
in the variable body. But this gives the error:
[PL_MyPipeLine, Request Pipeline, HandleAttachments, Delete action] XPath expression validation failed: An error was reported compiling the XPath expression: XQuery exception: line 34, column 91: {err}XP0008 [{bea-err}XP0008a]: Variable "$contentId" used but not declared for expression: declare namespace stag = 'http://www.darwin-it.nl/CS/StageDoc';
declare namespace jca = 'http://www.bea.com/wli/sb/transports/jca';
declare namespace wsp = 'http://schemas.xmlsoap.org/ws/2004/09/policy';
...


Same counts for Insert and delete: I thought of inserting a new version of the node in the list and delete the old one, but that would not work either.

I've googled around, and found several occurences of basically the same problem, but no satisfying solution.

At support.oracle.com I found the following bug:
"Bug 17940786 : CANNOT USE INDEX VARIABLE IN THE REPLACE ACTION WITHIN FOR-EACH LOOP" with the following description:

The customer uses 2 for-each loops with index variables ($i, $j).
In the Replace action, in the Xpath expression buider, they want to use
"./entity1[$i]/entity2[$j]". This is not permitted by the editor. The problem
also occurs with only 1 variable like "./entity1[$i]/entity2[1]".

However, for no apparent reason, this "bug" has the status "92 - Closed, Not a Bug". So apparently, Oracle finds it as "functioning as designed". But why can't I modify or delete a particular node indexed by a variable?
Apparently I'm now stuck with building the document list document-by-document and do a replace of the complete document-list...

SQLDeveloper and Userdefined datatypes in tables

Wed, 2015-06-03 05:49
You might have tables that contain columns with a userdefined datatypes. For instance from 11g onwards SOASuite contain Integration B2B, with that datamodel

B2B works with advanced queueing with the queue-table ip_qtab based on the IP_MESSAGE_TYPE Oracle Type wich is defined like:
create or replace type IP_MESSAGE_TYPE as OBJECT (
MSG_ID VARCHAR2(128),
INREPLYTO_MSG_ID VARCHAR2(128),
FROM_PARTY VARCHAR2(512),
TO_PARTY VARCHAR2(512),
ACTION_NAME VARCHAR2(512),
DOCTYPE_NAME VARCHAR2(512),
DOCTYPE_REVISION VARCHAR2(512),
MSG_TYPE INT,
PAYLOAD CLOB,
ATTACHMENT BLOB
);
In the queuetable you then have a payload column based on this type. When you do a select on such a table the payload column has actually several attributes. Tools like Pl/Sql Developer from Allroundautomations or TOAD apparently encounter that the column is based on the Oracle Type, so they actually show the seperate attributes in the grid.

SQLDeveloper (currently 4.3) apparently does not so. But it is quite easy to add this information in your select. For a select on the queuetable (actually with AQ you shouldn't query the queuetable, but the accompanying AQ$<queuetable> view) it will look like:

SELECT QTB.QUEUE,
QTB.MSG_ID,
QTB.CORR_ID,
QTB.MSG_PRIORITY,
QTB.MSG_STATE,
QTB.RETRY_COUNT,
QTB.USER_DATA.MSG_ID MSG,
QTB.USER_DATA.INREPLYTO_MSG_ID INREPLYTO_MSG_ID,
QTB.USER_DATA.FROM_PARTY FROM_PARTY,
QTB.USER_DATA.TO_PARTY TO_PARTY,
QTB.USER_DATA.ACTION_NAME ACTION_NAME,
QTB.USER_DATA.DOCTYPE_NAME DOCTYPE_NAME,
QTB.USER_DATA.DOCTYPE_REVISION DOCTYPE_REVISION,
QTB.USER_DATA.MSG_TYPE MSG_TYPE,
QTB.USER_DATA.PAYLOAD PAYLOAD,
QTB.CONSUMER_NAME,
QTB.PROTOCOL
FROM AQ$IP_QTAB QTB;

You see that the trick is to just add the attribute as a seperate identifier to the user_data-column, using the dot-notation.

If you're certain that the selected rows contain a valid XML document in the Payload attribute you could provide that attribute to the xmltype() constructor:
SELECT QTB.QUEUE,
QTB.MSG_ID,
QTB.CORR_ID,
QTB.MSG_PRIORITY,
QTB.MSG_STATE,
QTB.RETRY_COUNT,
QTB.USER_DATA.MSG_ID MSG,
QTB.USER_DATA.INREPLYTO_MSG_ID INREPLYTO_MSG_ID,
QTB.USER_DATA.FROM_PARTY FROM_PARTY,
QTB.USER_DATA.TO_PARTY TO_PARTY,
QTB.USER_DATA.ACTION_NAME ACTION_NAME,
QTB.USER_DATA.DOCTYPE_NAME DOCTYPE_NAME,
QTB.USER_DATA.DOCTYPE_REVISION DOCTYPE_REVISION,
QTB.USER_DATA.MSG_TYPE MSG_TYPE,
xmltype(QTB.USER_DATA.PAYLOAD) PAYLOAD,
QTB.CONSUMER_NAME,
QTB.PROTOCOL
FROM AQ$IP_QTAB QTB;

And of course this works for other tables as well. This is just a quick example for a table based on an object type. Unfortunately I don't have some example data in the queue at the moment.

Quick-Tip: DIA with docked Toolbox

Thu, 2015-05-28 02:54
This week I was asked to create a component-diagram  at my new customer. They use DIA as an alternative for Visio. Funny thing is that it apparently orginated from Linux/Gnome, since the file-explorer resembles the File-browser of Gnome. But it has also a Windows installer.

When you start the tool from the windows menu, it's started with the toolbox docked or attached to the canvas. But when you use either dia.exe or diaw.exe from the command line, or as I wanted to do from the toolbar from TotalCommander, you get two seperate windows. One for the toolbox and one for the canvas. So how to start it with a docked toolbox? With a little trial&error I found the following command:
dia-win-remote.exe diaw.exe --integrated
In the bin folder of the Dia-installation-home, there is also a dia-win-remote.exe. It takes one of the other exe's (dia.exe or diaw.exe) as an input. If you add the option "--integrated" it will show the combined window.

Expand swap using SSM

Wed, 2015-05-13 06:24
The mere reason that I dug into SSM yeasterday was that I wanted to install the Oracle Database 12c.

(Did you know yesterday came from the word 'yeast'? So actually yeasterday: because one used the yeast of the day before to bake the bread of today. Also in Dutch  the word for yeast: 'gist', still sounds in the word for yeasterday: 'gisteren'.)

I ran however against the prerequisite check on the swap space that was only 2GB because of my default OL7 install. And the Universal Installer required 8GB at least. So I needed to expand it. There are several ways to do it. But since I was into SSM, it was a good practice to use that. And it turns out very simple to do. It shows how easy it is to add a new device to a pool and an existing volume.

So I created a new disk of 8GB to my VM (I only need 8GB, but I thought I'd simply add it to the existing 2GB, to be certain to have enough with 10GB).


So, after booting up, verify existence of non assigned device (/dev/sdc):
[root@darlin-vce-db ~]# ssm list
--------------------------------------------------------------
Device Free Used Total Pool Mount point
--------------------------------------------------------------
/dev/sda 20.00 GB PARTITIONED
/dev/sda1 500.00 MB /boot
/dev/sda2 40.00 MB 19.47 GB 19.51 GB ol
/dev/sdb 0.00 KB 100.00 GB 100.00 GB pool01
/dev/sdc 8.00 GB
--------------------------------------------------------------
-----------------------------------------------------
Pool Type Devices Free Used Total
-----------------------------------------------------
ol lvm 1 40.00 MB 19.47 GB 19.51 GB
pool01 lvm 1 0.00 KB 100.00 GB 100.00 GB
-----------------------------------------------------
---------------------------------------------------------------------------
Volume Pool Volume size FS FS size Free Type Mount point
---------------------------------------------------------------------------
/dev/ol/root
ol 17.47 GB xfs 17.46 GB 12.29 GB linear /
/dev/ol/swap
ol 2.00 GB linear
/dev/pool01/disk01
pool01 100.00 GB xfs 99.95 GB 99.95 GB linear /u01
/dev/sda1
500.00 MB xfs 496.67 MB 305.97 MB part /boot
---------------------------------------------------------------------------

Then add the device to the 'ol'-pool:
[root@darlin-vce-db ~]# ssm add -p ol /dev/sdc
Physical volume "/dev/sdc" successfully created
Volume group "ol" successfully extended

And verify again:
[root@darlin-vce-db ~]# ssm list
--------------------------------------------------------------
Device Free Used Total Pool Mount point
--------------------------------------------------------------
/dev/sda 20.00 GB PARTITIONED
/dev/sda1 500.00 MB /boot
/dev/sda2 40.00 MB 19.47 GB 19.51 GB ol
/dev/sdb 0.00 KB 100.00 GB 100.00 GB pool01
/dev/sdc 8.00 GB 0.00 KB 8.00 GB ol
--------------------------------------------------------------
----------------------------------------------------
Pool Type Devices Free Used Total
----------------------------------------------------
ol lvm 2 8.04 GB 19.47 GB 27.50 GB
pool01 lvm 1 0.00 KB 100.00 GB 100.00 GB
----------------------------------------------------
---------------------------------------------------------------------------------------
Volume Pool Volume size FS FS size Free Type Mount point
---------------------------------------------------------------------------------------
/dev/ol/root ol 17.47 GB xfs 17.46 GB 12.29 GB linear /
/dev/ol/swap ol 2.00 GB linear
/dev/pool01/disk01 pool01 100.00 GB xfs 99.95 GB 99.95 GB linear /u01
/dev/sda1 500.00 MB xfs 496.67 MB 305.97 MB part /boot
---------------------------------------------------------------------------------------

Now resize the swap volume:
[root@darlin-vce-db ~]# ssm resize -s+8GB /dev/ol/swap
Size of logical volume ol/swap changed from 2.00 GiB (512 extents) to 10.00 GiB (2560 extents).
Logical volume swap successfully resized

And, again, verify:
[root@darlin-vce-db ~]# ssm list
--------------------------------------------------------------
Device Free Used Total Pool Mount point
--------------------------------------------------------------
/dev/sda 20.00 GB PARTITIONED
/dev/sda1 500.00 MB /boot
/dev/sda2 0.00 KB 19.51 GB 19.51 GB ol
/dev/sdb 0.00 KB 100.00 GB 100.00 GB pool01
/dev/sdc 36.00 MB 7.96 GB 8.00 GB ol
--------------------------------------------------------------
-----------------------------------------------------
Pool Type Devices Free Used Total
-----------------------------------------------------
ol lvm 2 36.00 MB 27.47 GB 27.50 GB
pool01 lvm 1 0.00 KB 100.00 GB 100.00 GB
-----------------------------------------------------
---------------------------------------------------------------------------------------
Volume Pool Volume size FS FS size Free Type Mount point
---------------------------------------------------------------------------------------
/dev/ol/root ol 17.47 GB xfs 17.46 GB 12.29 GB linear /
/dev/ol/swap ol 10.00 GB linear
/dev/pool01/disk01 pool01 100.00 GB xfs 99.95 GB 99.95 GB linear /u01
/dev/sda1 500.00 MB xfs 496.67 MB 305.97 MB part /boot
---------------------------------------------------------------------------------------

Now check the swap space:
[root@darlin-vce-db ~]# swapon -s
Filename Type Size Used Priority
/dev/dm-1 partition 2097148 0 -1

Hey, it's still 2GB!

Let's check fstab to get the swap mount-definitions: 
[root@darlin-vce-db ~]# cat /etc/fstab

#
# /etc/fstab
# Created by anaconda on Mon May 11 20:20:14 2015
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/ol-root / xfs defaults 0 0
UUID=7a285d9f-1812-4d72-9bd2-12e50eddc855 /boot xfs defaults 0 0
/dev/mapper/ol-swap swap swap defaults 0 0
/dev/mapper/pool01-disk01 /u01 xfs defaults 0 0


Turn off swap:
[root@darlin-vce-db ~]# swapoff /dev/mapper/ol-swap

And (re-)create new swap:
[root@darlin-vce-db ~]# mkswap -c /dev/mapper/ol-swap
0 bad pages
mkswap: /dev/mapper/ol-swap: warning: wiping old swap signature.
Setting up swapspace version 1, size = 10485756 KiB
no label, UUID=843463de-7552-4a73-84a6-761f261d9e9f

Then enable swap again:
[root@darlin-vce-db ~]# swapon /dev/mapper/ol-swap

And check swap again:
[root@darlin-vce-db ~]# swapon -s
Filename Type Size Used Priority
/dev/dm-1 partition 10485756 0 -1

Yes!!! That did the job. Easy does it...

LVM with SSM on OL7

Tue, 2015-05-12 02:53
Or how to  encrypt your title with acronyms...

Today I wanted to create a VM with an Oracle SOA/BPM Suite 12c installation, since I'm to give a workshop on the installation of it. I used Oracle Linux 6 for my installations and the last few years I did play around quite a lot with it (for someone who is not a core systems administrator), to upgrade all my VM's to the latest update, remove obsolete kernels, add volumes to do installations, etc. I used Oracle database 11g, that in the last few monts I upgraded to the latest patch set of 11gR2 11.2.0.4.

I could do with a OL6U6 VM with that upgraded 11gR2 database, I did a upgrade of a quite clean VM only yesterday. But since OL7 is in the field already, and DB12c even for a few years. So I thought to try my luck with that.

However, I found that OL7 behaves quite different compared to OL6. Gnome is different, but tools like Logical Volume Manager are absent.  I found that there is no graphical LVM available in OL7 apparently. Since I'm not the only one that sought for it in vain, I assume it's really not there. By the way: there is a disks tool, but that only allows you to format a bare disk, not to create LV's.

Luckily I found this great article on a new tool from Red Hat: the system storage manager (ssm). Apparently it is open source, since you can find it on sourceforge, and it is available for Oracle Linux as well.

Install ssm Yep, you need to install it first:
$ sudo yum install system-storage-manager
Or do it as root (I'm didn't setup sudo for my one-user-virtual-course-environments):
[root@darlin-vce-db ~]# yum install system-storage-manager
By the way: system-config-lvm, the LVM in previous OL's, is apparently deprecated.

List volumesFirst list the current devices and volumes using 'ssm list':
[root@darlin-vce-db ~]# ssm list
-----------------------------------------------------------
Device Free Used Total Pool Mount point
-----------------------------------------------------------
/dev/sda 20.00 GB PARTITIONED
/dev/sda1 500.00 MB /boot
/dev/sda2 40.00 MB 19.47 GB 19.51 GB ol
/dev/sdb 100.00 GB
-----------------------------------------------------------
-------------------------------------------------
Pool Type Devices Free Used Total
-------------------------------------------------
ol lvm 1 40.00 MB 19.47 GB 19.51 GB
-------------------------------------------------
-------------------------------------------------------------------------------
Volume Pool Volume size FS FS size Free Type Mount point
-------------------------------------------------------------------------------
/dev/ol/root ol 17.47 GB xfs 17.46 GB 12.81 GB linear /
/dev/ol/swap ol 2.00 GB linear
/dev/sda1 500.00 MB xfs 496.67 MB 305.97 MB part /boot
-------------------------------------------------------------------------------
As you can see, I added a new disk to my VM, that is listed as /dev/sdb.  And you can't find it in the volumes, because I didn't do anything with it yet.
 
Add new LV mounted on /u01 In the past, you needed to perform quite some steps to create a volume: you had to prepare a disk, create a volume group, add a volume to it, assign space to the volume, make a filesystem on it, and mount it.

Now, here's where ssm pays off. Let's first create a folder to use as a mount point.
[root@darlin-vce-db ~]# mkdir /u01
I picked up the name of this mountpoint  during my Oracle days, with my first steps on Linux. But I can't remember what the story or rationale is behind 'u01'. However, it works for me, and it shows up in the Oracle doc, so I stick with it.
Now, lets create a volume called disk01, on a pool called pool01 with /dev/sdb assigned to it, and let's create the new default filesystem xfs on it. Oh, and my SDB was created with a size of 100GB:
[root@darlin-vce-db ~]# ssm create -s 100GB -n disk01 --fstype xfs -p pool01 /dev/sdb /u01
Not enough space (104853504.0 KB) in the pool 'pool01' to create volume! Adjust (N/y/q) ? Y
Logical volume "disk01" created.
meta-data=/dev/pool01/disk01 isize=256 agcount=4, agsize=6553344 blks
= sectsz=512 attr=2, projid32bit=1
= crc=0 finobt=0
data = bsize=4096 blocks=26213376, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=0
log =internal log bsize=4096 blocks=12799, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0

Apparently this could be done in one go. Since the 100GB of the disk does not match exactly the 100GB asked for the volume, it asked to adjust it.

Now do a list again
[root@darlin-vce-db ~]# ssm list
--------------------------------------------------------------
Device Free Used Total Pool Mount point
--------------------------------------------------------------
/dev/sda 20.00 GB PARTITIONED
/dev/sda1 500.00 MB /boot
/dev/sda2 40.00 MB 19.47 GB 19.51 GB ol
/dev/sdb 0.00 KB 100.00 GB 100.00 GB pool01
--------------------------------------------------------------
-----------------------------------------------------
Pool Type Devices Free Used Total
-----------------------------------------------------
ol lvm 1 40.00 MB 19.47 GB 19.51 GB
pool01 lvm 1 0.00 KB 100.00 GB 100.00 GB
-----------------------------------------------------
---------------------------------------------------------------------------------------
Volume Pool Volume size FS FS size Free Type Mount point
---------------------------------------------------------------------------------------
/dev/ol/root ol 17.47 GB xfs 17.46 GB 12.81 GB linear /
/dev/ol/swap ol 2.00 GB linear
/dev/pool01/disk01 pool01 100.00 GB xfs 99.95 GB 99.95 GB linear /u01
/dev/sda1 500.00 MB xfs 496.67 MB 305.97 MB part /boot
---------------------------------------------------------------------------------------

Here you find that there is now a pool called 'pool01', with a volume  named 'disk01', mounted on /u01.

To List filesystem on '/u01' issue the command 'df /u01':
[root@darlin-vce-db ~]# df /u01
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/pool01-disk01 104802308 32928 104769380 1% /u01

 I want to have it added to the /etc/fstab, to have it auto mounted. So edit the file as follows:
[root@darlin-vce-db u01]# cat /etc/fstab

#
# /etc/fstab
# Created by anaconda on Mon May 11 20:20:14 2015
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/ol-root / xfs defaults 0 0
UUID=7a285d9f-1812-4d72-9bd2-12e50eddc855 /boot xfs defaults 0 0
/dev/mapper/ol-swap swap swap defaults 0 0
/dev/mapper/pool01-disk01 /u01 xfs defaults 0 0


I duplicated the first line, with /dev/mapper/ol-root, to the end of the file, and renamed the device according to the filesystem listing of /u01 above. And the mountpoint to /u01 of course.
Create group oinstall and add it to oracle I want to use the new volume for my Oracle installations. So first lets create the group oinstall and add it to oracle:
[root@darlin-vce-db u01]# groupadd oinstall
[root@darlin-vce-db u01]# usermod oracle -G oinstall --a
[root@darlin-vce-db u01]# groups oracle
oracle : oracle oinstall
Then add an app folder and make oracle owner of it
[root@darlin-vce-db ~]# cd /u01
[root@darlin-vce-db u01]# mkdir app
[root@darlin-vce-db u01]# chown oracle:oinstall app
ConclusionThat wasn't too hard, was it? Following the article mentioned earlier, you can add disks to a volume about as easy. Now, I'll be off to try to install DB12c...

No space left on device...

Wed, 2015-05-06 09:20
Today I ran into something curious, that I saw a few weeks ago on a training that I gave: the root filesystem  ran full (Oracle Linux 6). At first I did not find anything that caused the problem, but the command 'df -k' indeed suggested a full root filesystem. Using 'du -sh /home/oracle' we found that that folder consumed an unreasonable amount of space. In my case today I found the same. It turns out that there are 2 hidden files that were the problem:

[oracle@darlin-vce-soa ~]$ ls -al
...
-rw-------. 1 oracle oinstall 4488290304 May 6 16:09 .xsession-errors
-rw-------. 1 oracle oinstall 19752 May 4 16:47 .xsession-errors.old
[oracle@darlin-vce-soa ~]$ rm -rf .xsession-errors
[oracle@darlin-vce-soa ~]$ rm -rf .xsession-errors.old 
 
As you can see the .xsession-errors file is terribly large, in the training we found that it was the .old file. Actually it turns out that these files are rolling errors-logs of the output of applications that use a graphical interface. In this case it logs amongst others the output of JDeveloper, and my grow very large due to java-exceptions. So in case of a regular exception raised by JDeveloper, you might want to keep these files 'in the eye'.

You can savely remove those files, to save up space. But if they have grown that big, you might want to tail those to see what causes the problems.

Another tip might be to remove old kernels: when upgrading to a new kernel, Oracle Linux keeps the old kernel files. You can find a description to remove those here.