<?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/"
	>

<channel>
	<title>Whitehorses </title>
	<atom:link href="http://blog.whitehorses.nl/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.whitehorses.nl</link>
	<description>Oracle Integration, SOA &#38; BPM experts - SOA Suite, BPM Suite, ADF, ACM, WebLogic</description>
	<lastBuildDate>Tue, 10 Jul 2018 12:46:46 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	

<image>
	<url>http://blog.whitehorses.nl/wp-content/uploads/2016/11/apple-touch-icon.png</url>
	<title>Whitehorses </title>
	<link>http://blog.whitehorses.nl</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>The Struggles of Personalization in ADF</title>
		<link>http://blog.whitehorses.nl/2018/07/10/the-struggles-of-personalization-in-adf/</link>
		<comments>http://blog.whitehorses.nl/2018/07/10/the-struggles-of-personalization-in-adf/#comments</comments>
		<pubDate>Tue, 10 Jul 2018 12:39:30 +0000</pubDate>
		<dc:creator><![CDATA[Mike Heeren]]></dc:creator>
				<category><![CDATA[ADF / Enterprise Java]]></category>
		<category><![CDATA[12c]]></category>
		<category><![CDATA[adf]]></category>
		<category><![CDATA[application development framework]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[MDS]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Personalization]]></category>

		<guid isPermaLink="false">http://blog.whitehorses.nl/?p=5334</guid>
		<description><![CDATA[A Mike Heeren &#38; Richard Olrichs co-production ADF comes with the out-of-the-box features of personalization. This means that whenever you configure personalisation, users can persist changes they make to the application across sessions and personalize their experience with the application. We have seen that this feature can also confuse some of our users, so it [&#8230;]]]></description>
				<content:encoded><![CDATA[<p></p><p style="text-align: center"><i><span style="font-weight: 400">A Mike Heeren &amp; Richard Olrichs co-production</span></i></p>
<p><span style="font-weight: 400">ADF comes with the out-of-the-box features of personalization. This means that whenever you configure personalisation, users can persist changes they make to the application across sessions and personalize their experience with the application. We have seen that this feature can also confuse some of our users, so it is not always wise to use this. It depends on the use case you have. However, when recently implementing personalization on an ADF 12.2.1.2 application, we had a couple of issues regarding persisting these personalizations to the MDS.</span><span style="font-weight: 400"><br />
</span><span style="font-weight: 400"><br />
</span><span style="font-weight: 400">We felt that most of the blogs we came across while implementing these features, share the joyful out-of-the-box configuration. Just select some of the checkboxes in the properties and you are done, ready to enjoy your beer and have your designers and product owners cheer for you. </span><span style="font-weight: 400"><br />
</span><span style="font-weight: 400">Sometimes however, real life applications at customers do not match the out-of-the-box configuration and things can become a little bit more tricky than you might expect. </span></p>
<p><span style="font-weight: 400">Let&#8217;s start at the top, and go through some of the steps you will always need within your application for personalization to work. You need to have authentication and authorization set up. If you also want to follow our struggles, we have posted a sample application at the end of this blog to show both the problems as well as the solutions. </span></p>
<h1><span style="font-weight: 400">Getting started with customizations</span></h1>
<p><span style="font-weight: 400">The basic configuration of customization in ADF is pretty simple. We start with a simple ADF application (with authentication already configured), and select the </span><i><span style="font-weight: 400">Project Properties</span></i><span style="font-weight: 400"> &gt; </span><i><span style="font-weight: 400">ADF View</span></i><span style="font-weight: 400">. Here we check </span><i><span style="font-weight: 400">Enable user customization</span></i><span style="font-weight: 400"> and </span><i><span style="font-weight: 400">Across sessions using MDS</span></i><span style="font-weight: 400">, as seen below:</span></p>
<p><a href="http://blog.whitehorses.nl/wp-content/uploads/2018/07/Getting-started_1.png"><img class="alignnone wp-image-5337 size-large" src="http://blog.whitehorses.nl/wp-content/uploads/2018/07/Getting-started_1-540x257.png" alt="" width="540" height="257" srcset="http://blog.whitehorses.nl/wp-content/uploads/2018/07/Getting-started_1-540x257.png 540w, http://blog.whitehorses.nl/wp-content/uploads/2018/07/Getting-started_1-300x143.png 300w, http://blog.whitehorses.nl/wp-content/uploads/2018/07/Getting-started_1-768x365.png 768w, http://blog.whitehorses.nl/wp-content/uploads/2018/07/Getting-started_1.png 1054w" sizes="(max-width: 540px) 100vw, 540px" /></a></p>
<p><span style="font-weight: 400">When enabling user customizations, the following files are edited:</span></p>
<ul>
<li style="font-weight: 400"><span style="font-weight: 400">In the </span><i><span style="font-weight: 400">adf-config.xml</span></i><span style="font-weight: 400"> file the following lines are added:</span></li>
</ul>
<pre class="brush: xml">&lt;adf-faces-config xmlns="http://xmlns.oracle.com/adf/faces/config"&gt;
	&lt;persistent-change-manager&gt;
		&lt;persistent-change-manager-class&gt;oracle.adf.view.rich.change.MDSDocumentChangeManager&lt;/persistent-change-manager-class&gt;
	&lt;/persistent-change-manager&gt;
&lt;/adf-faces-config&gt;</pre>
<ul>
<li style="font-weight: 400"><span style="font-weight: 400">In the </span><i><span style="font-weight: 400">web.xml</span></i><span style="font-weight: 400"> file the </span><i><span style="font-weight: 400">javax.faces.FACELETS_RESOURCE_RESOLVER</span></i><span style="font-weight: 400"> context-param is changed from </span><i><span style="font-weight: 400">oracle.adfinternal.view.faces.facelets.rich.AdfFaceletsResourceResolver</span></i><span style="font-weight: 400"> to </span><i><span style="font-weight: 400">oracle.adfinternal.view.faces.facelets.rich.MDSFaceletsResourceResolver</span></i><span style="font-weight: 400">, and the following blocks are added:</span></li>
</ul>
<pre class="brush: xml">&lt;servlet&gt;
	&lt;servlet-name&gt;adflibResources&lt;/servlet-name&gt;
	&lt;servlet-class&gt;oracle.adf.library.webapp.ResourceServlet&lt;/servlet-class&gt;
&lt;/servlet&gt;
...
&lt;servlet-mapping&gt;
	&lt;servlet-name&gt;adflibResources&lt;/servlet-name&gt;
	&lt;url-pattern&gt;/adflib/*&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;
...
&lt;filter&gt;
	&lt;filter-name&gt;ADFLibraryFilter&lt;/filter-name&gt;
	&lt;filter-class&gt;oracle.adf.library.webapp.LibraryFilter&lt;/filter-class&gt;
&lt;/filter&gt;
...
&lt;filter-mapping&gt;
	&lt;filter-name&gt;ADFLibraryFilter&lt;/filter-name&gt;
	&lt;url-pattern&gt;/*&lt;/url-pattern&gt;
	&lt;dispatcher&gt;FORWARD&lt;/dispatcher&gt;
	&lt;dispatcher&gt;REQUEST&lt;/dispatcher&gt;
&lt;/filter-mapping&gt;
...
&lt;context-param&gt;
	&lt;param-name&gt;oracle.adf.jsp.provider.0&lt;/param-name&gt;
	&lt;param-value&gt;oracle.mds.jsp.MDSJSPProviderHelper&lt;/param-value&gt;
&lt;/context-param&gt;
&lt;context-param&gt;
	&lt;param-name&gt;org.apache.myfaces.trinidad.CHANGE_PERSISTENCE&lt;/param-name&gt;
	&lt;param-value&gt;oracle.adf.view.rich.change.FilteredPersistenceChangeManager&lt;/param-value&gt;
&lt;/context-param&gt;</pre>
<ul>
<li style="font-weight: 400"><span style="font-weight: 400">Finally, the following block will be added to the project </span><i><span style="font-weight: 400">.jpr</span></i><span style="font-weight: 400"> file:</span></li>
</ul>
<pre class="brush: xml">&lt;hash n="oracle.adfdtinternal.view.rich.setting.ADFViewSettings"&gt;
	&lt;value n="ENABLE_ADF_WEBAPP_LIB_SUPPORT" v="true"/&gt;
	&lt;value n="KEY_ENABLE_USER_CUSTOMIZATIONS" v="2"/&gt;
&lt;/hash&gt;</pre>
<p><span style="font-weight: 400">After this we need to configure the </span><i><span style="font-weight: 400">adf-config.xml</span></i><span style="font-weight: 400"> file and add the </span><i><span style="font-weight: 400">oracle.adf.share.config.UserCC</span></i><span style="font-weight: 400"> Customization Class on the </span><i><span style="font-weight: 400">MDS</span></i><span style="font-weight: 400"> tab. This is a default customization class that is shipped with ADF. You can also write your own, but that is more of a use case for customization than it is for personalization. In our case we’ll just configure the application using the </span><i><span style="font-weight: 400">UserCC</span></i><span style="font-weight: 400">:</span></p>
<p><a href="http://blog.whitehorses.nl/wp-content/uploads/2018/07/Getting-started_2.png"><img class="alignnone size-large wp-image-5338" src="http://blog.whitehorses.nl/wp-content/uploads/2018/07/Getting-started_2-540x318.png" alt="" width="540" height="318" srcset="http://blog.whitehorses.nl/wp-content/uploads/2018/07/Getting-started_2-540x318.png 540w, http://blog.whitehorses.nl/wp-content/uploads/2018/07/Getting-started_2-300x177.png 300w, http://blog.whitehorses.nl/wp-content/uploads/2018/07/Getting-started_2-768x452.png 768w, http://blog.whitehorses.nl/wp-content/uploads/2018/07/Getting-started_2.png 1147w" sizes="(max-width: 540px) 100vw, 540px" /></a></p>
<p><span style="font-weight: 400">Now you need to configure the components that you want the end user to be able to personalize. This can be done in the </span><i><span style="font-weight: 400">View</span></i><span style="font-weight: 400"> tab. Select the </span><i><span style="font-weight: 400">ADF Faces Components</span></i><span style="font-weight: 400"> Tag Library, because we want to personalize the table and column components, these are default component from ADF Faces. By default all attributes will be persisted, you can uncheck them if you do not wish to persist these:</span></p>
<p><a href="http://blog.whitehorses.nl/wp-content/uploads/2018/07/Getting-started_3.png"><img class="alignnone size-large wp-image-5339" src="http://blog.whitehorses.nl/wp-content/uploads/2018/07/Getting-started_3-540x316.png" alt="" width="540" height="316" srcset="http://blog.whitehorses.nl/wp-content/uploads/2018/07/Getting-started_3-540x316.png 540w, http://blog.whitehorses.nl/wp-content/uploads/2018/07/Getting-started_3-300x176.png 300w, http://blog.whitehorses.nl/wp-content/uploads/2018/07/Getting-started_3-768x450.png 768w, http://blog.whitehorses.nl/wp-content/uploads/2018/07/Getting-started_3.png 1150w" sizes="(max-width: 540px) 100vw, 540px" /></a></p>
<p><span style="font-weight: 400">After the above steps are configured, you can give a fancy demo on your demo application, and everybody is happy. However, in our production application, there were still a few issues to tackle, we struggled with some of these.    </span></p>
<h1><span style="font-weight: 400">Struggle 1: Task flows from libraries combined with a file based MDS on a Windows machine.</span></h1>
<p><span style="font-weight: 400">Our application was not a simple MVC application, but like many application out there, we used ADF libraries to include taskflows from library projects and included them in a bigger main application. When we turned on personalisation on components from task flows which come from libraries instead of directly from the application, they were not correctly persisted to the file based MDS on Windows machines.</span></p>
<p><span style="font-weight: 400">When running the application via JDeveloper (in our example application by right clicking </span><i><span style="font-weight: 400">default.jsf</span></i><span style="font-weight: 400"> in the </span><i><span style="font-weight: 400">ViewController</span></i><span style="font-weight: 400"> project, and selecting </span><i><span style="font-weight: 400">Run</span></i><span style="font-weight: 400">), we see that the task flow that comes directly from the </span><i><span style="font-weight: 400">ViewController</span></i><span style="font-weight: 400"> project (the table on the left of the screen), behaves as expected. However, when personalizing the table from the task flow that comes from the imported library (so from the </span><i><span style="font-weight: 400">ViewControllerLibrary</span></i><span style="font-weight: 400"> project), we see the following warning in the log files.</span></p>
<pre class="brush: ps">&lt;Apr 5, 2018, 10:44:26,157 AM CEST&gt; &lt;Warning&gt; &lt;oracle.adf.view.rich.change.MDSDocumentChangeManager&gt; &lt;BEA-000000&gt; &lt;Attempt to persist a DocumentChange failed : MDS-02401: The operation ModifyAttribute on the column node is not allowed.    

oracle.mds.exception.MDSRuntimeException: java.net.MalformedURLException: no !/ in spec    

java.lang.NullPointerException: no !/ in spec&gt;</pre>
<p><span style="font-weight: 400">We can verify that the preferences were persisted to the MDS for the left table, but not for the right table, by opening the application (with the same user) in another browser:</span></p>
<p><a href="http://blog.whitehorses.nl/wp-content/uploads/2018/07/Issue_1.png"><img class="alignnone size-large wp-image-5340" src="http://blog.whitehorses.nl/wp-content/uploads/2018/07/Issue_1-435x400.png" alt="" width="435" height="400" srcset="http://blog.whitehorses.nl/wp-content/uploads/2018/07/Issue_1-435x400.png 435w, http://blog.whitehorses.nl/wp-content/uploads/2018/07/Issue_1-300x276.png 300w, http://blog.whitehorses.nl/wp-content/uploads/2018/07/Issue_1-768x706.png 768w, http://blog.whitehorses.nl/wp-content/uploads/2018/07/Issue_1.png 1132w" sizes="(max-width: 435px) 100vw, 435px" /></a></p>
<p><span style="font-weight: 400">Unfortunately, this issue occurs when using task flows from libraries in combination with using a file based MDS on a Windows machine. Weblogic is not able to create a file path, which contains </span><i><span style="font-weight: 400">!/</span></i><span style="font-weight: 400"> (which is used to indicate that the resource is part of a library). </span></p>
<p><span style="font-weight: 400">Luckily, in our case all other DTAP environments don’t use a file based MDS, but a database MDS. In the database MDS, we don’t have the file path issues, so there we won’t see this issue. So on all environments except the (local) Integrated WLS, we don’t see these warning logs, and we will see both table personalizations being persisted. It might take you some time to realise this, if you do not want to deploy to Dev or Test without having the Personalization working on your local machine. </span></p>
<h1><span style="font-weight: 400">Struggle 2: Deploying the application as EAR instead of via JDeveloper</span></h1>
<p><span style="font-weight: 400">Deploying both from JDeveloper as well as creating an EAR file seems to work. However, there was still some struggle there as well. The personalisation was working when deploying via JDeveloper, but when we would build in EAR from the application via JDeveloper, and deploy it manually to the Integrated WLS via the console, none of the settings were persisted to the MDS, and we saw the following warning in the log files:</span></p>
<pre class="brush: ps">&lt;Apr 5, 2018, 2:58:12,545 PM CEST&gt; &lt;Warning&gt; &lt;oracle.adf.view.rich.change.DocumentUtils&gt; &lt;BEA-000000&gt; &lt;ADFv: Trouble getting the mutable document from MDS. MDS-01273: The operation on the resource /WEB-INF/view-from-library.jsff.xml failed because source metadata store mapped to the namespace / DEFAULT is read only..&gt;</pre>
<p><span style="font-weight: 400">By opening the application in different browsers again, we can also confirm that neither of customizations the tables is persisted in the MDS now:</span></p>
<p><a href="http://blog.whitehorses.nl/wp-content/uploads/2018/07/Issue_2.png"><img class="alignnone size-large wp-image-5341" src="http://blog.whitehorses.nl/wp-content/uploads/2018/07/Issue_2-435x400.png" alt="" width="435" height="400" srcset="http://blog.whitehorses.nl/wp-content/uploads/2018/07/Issue_2-435x400.png 435w, http://blog.whitehorses.nl/wp-content/uploads/2018/07/Issue_2-300x276.png 300w, http://blog.whitehorses.nl/wp-content/uploads/2018/07/Issue_2-768x706.png 768w, http://blog.whitehorses.nl/wp-content/uploads/2018/07/Issue_2.png 1132w" sizes="(max-width: 435px) 100vw, 435px" /></a></p>
<p><span style="font-weight: 400">When Personalization across sessions with the MDS is configured, JDeveloper always creates a metadata store usages in the </span><i><span style="font-weight: 400">adf-config</span></i><span style="font-weight: 400"> file at deployment time. This configuration is named </span><i><span style="font-weight: 400">MAR_TargetRepos</span></i><span style="font-weight: 400">. </span></p>
<p><span style="font-weight: 400">It does not matter that we have configured a different metadata store usages within the </span><i><span style="font-weight: 400">adf-config</span></i><span style="font-weight: 400">. If the </span><i><span style="font-weight: 400">MAR_TargetRepos</span></i><span style="font-weight: 400"> is not present while creating the EAR file, it will be added to the </span><i><span style="font-weight: 400">adf-config</span></i><span style="font-weight: 400"> file. The only solution that we found to this, is by naming our metadata store usages to match the expected default, then it will not override or add anything. </span></p>
<p><span style="font-weight: 400">We added the following snippet to the </span><i><span style="font-weight: 400">adf-config/adf-mds-config/mds-config</span></i><span style="font-weight: 400"> tag in </span><i><span style="font-weight: 400">adf-config.xml</span></i><span style="font-weight: 400">:</span></p>
<pre class="brush: xml">&lt;persistence-config&gt;
	&lt;metadata-namespaces&gt;
		&lt;namespace path="/persdef" metadata-store-usage="MAR_TargetRepos"/&gt;
	&lt;/metadata-namespaces&gt;
	&lt;metadata-store-usages&gt;
		&lt;metadata-store-usage id="MAR_TargetRepos" default-cust-store="true"&gt;
			&lt;metadata-store class-name="oracle.mds.persistence.stores.file.FileMetadataStore"&gt;
				&lt;property name="metadata-path" value="${TEMP}"/&gt;
				&lt;property name="partition-name" value="PersDef"/&gt;
			&lt;/metadata-store&gt;
		&lt;/metadata-store-usage&gt;
	&lt;/metadata-store-usages&gt;
&lt;/persistence-config&gt;</pre>
<p><span style="font-weight: 400">Note that we did not set </span><i><span style="font-weight: 400">deploy-target</span></i><span style="font-weight: 400"> to </span><i><span style="font-weight: 400">true</span></i><span style="font-weight: 400">, because if we do this, our custom </span><i><span style="font-weight: 400">MAR_TargetRepos</span></i><span style="font-weight: 400"> will be overridden with the default implementation again, when building the EAR file. This default implementation does not contain the </span><i><span style="font-weight: 400">FileMetadataStore</span></i><span style="font-weight: 400"> implementation:</span></p>
<pre class="brush: xml">&lt;metadata-store-usage id="MAR_TargetRepos" deploy-target="true" default-cust-store="true"/&gt;</pre>
<p><span style="font-weight: 400">Because we want to override the default </span><i><span style="font-weight: 400">MAR_TargetRepos</span></i><span style="font-weight: 400">, so the personalization will also work when deploying the EAR instead of deploying via JDeveloper, we do not set the </span><i><span style="font-weight: 400">deploy-target</span></i><span style="font-weight: 400"> to </span><i><span style="font-weight: 400">true </span></i><span style="font-weight: 400">so the default (</span><i><span style="font-weight: 400">false</span></i><span style="font-weight: 400">) will be used. In this case the </span><i><span style="font-weight: 400">FileMetadataStore</span></i><span style="font-weight: 400"> configuration will be preserved in the EAR file.</span></p>
<p><span style="font-weight: 400">If we deploy the new EAR file, we see the same behaviour as we did when deploying it via JDeveloper. Also, when we use the personalization functions on the screen, we will see files being created within the </span><i><span style="font-weight: 400">PersDef</span></i><span style="font-weight: 400"> folder within the </span><i><span style="font-weight: 400">%TEMP%</span></i><span style="font-weight: 400"> environment variable.</span></p>
<p><span style="font-weight: 400">This </span><i><span style="font-weight: 400">FileMetadataStore </span></i><span style="font-weight: 400">configuration is changed (back) to a </span><i><span style="font-weight: 400">DBMetaDataStore </span></i><span style="font-weight: 400">configuration by an ANT build script, before deploying on the different DTAP environments instead of the Integrated WLS environment. An example of such ANT script can be found below.</span></p>
<pre class="brush: xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;project xmlns="antlib:org.apache.tools.ant"&gt;
	&lt;property environment="env"/&gt;
	&lt;property name="ear.location" location="/path/to/your/deployment.ear"/&gt;
	&lt;!-- Classpath --&gt;
	&lt;path id="wlst.classpath"&gt;
		&lt;fileset file="${env.WLS_HOME}/modules/features/wlst.wls.classpath.jar"/&gt;
	&lt;/path&gt;
	&lt;!-- WLST task definition --&gt;
	&lt;taskdef name="wlst" classname="weblogic.ant.taskdefs.management.WLSTTask" classpathref="wlst.classpath"/&gt;
	&lt;!-- Target to replace persDef repository --&gt;
	&lt;target name="replace-persdef-repo"&gt;
		&lt;echo message="Updating MDS config for [${ear.location}]..."/&gt;
		&lt;wlst failonerror="true" debug="false" classpathref="wlst.classpath"&gt;
			&lt;arg file="${ear.location}"/&gt;
			&lt;script&gt;
			archive = getMDSArchiveConfig(fromLocation = sys.argv[0])
			archive.setAppSharedMetadataRepository(
				namespace='/persdef',
				repository='mds-owsm',
				partition='PersDef',
				type='DB',
				jndi='jdbc/mds/owsm'
			)
			archive.save()
			&lt;/script&gt;
		&lt;/wlst&gt;
		&lt;echo message="Updating MDS config done!"/&gt;
	&lt;/target&gt;
&lt;/project&gt;</pre>
<p><span style="font-weight: 400">Be sure that the </span><i><span style="font-weight: 400">WLS_HOME</span></i><span style="font-weight: 400"> environment variable is set in the system environment variables, and the </span><i><span style="font-weight: 400">ear.location</span></i><span style="font-weight: 400"> property is replaced in the ANT file when you want to use the above example.</span></p>
<h1><span style="font-weight: 400">Struggle 3: Suddenly our application does persisting during the session. </span></h1>
<p><span style="font-weight: 400">We have configured the </span><i><span style="font-weight: 400">adf-config</span></i><span style="font-weight: 400"> to persist only certain components and attributes across the session. This works very nice and clear, however, suddenly all the other components also persist their state, just not across the session, but during the session. </span></p>
<p><span style="font-weight: 400">It is possible that this is not what you want, it certainly was not what we expected or had in mind for our application, but there is nothing much we can do about it. It would have made more sense to turn this off for all the components and only persist those that were configured to be persisted.</span></p>
<p><span style="font-weight: 400">Luckily the ADF components have an attribute </span><i><span style="font-weight: 400">persist </span></i><span style="font-weight: 400">and </span><i><span style="font-weight: 400">dontPersist </span></i><span style="font-weight: 400">on them. When reading the documentation on these attributes, it sounds exactly like what we need for our application! Before adding the </span><i><span style="font-weight: 400">dontPersist </span></i><span style="font-weight: 400">attribute to the hundreds of components we have in the application, we decide to test it on a couple. What we found out was very unpleasing, basically these attributes could be used for documentation purpose or for fun, but it certainly did nothing concerning persistence. </span></p>
<p><span style="font-weight: 400">We decided to create our own custom class to adjust the framework and get this working. To achieve this, the </span><i><span style="font-weight: 400">context-param</span></i> <i><span style="font-weight: 400">org.apache.myfaces.trinidad.CHANGE_PERSISTENCE</span></i><span style="font-weight: 400"> can be adjusted to a custom class.</span></p>
<p><span style="font-weight: 400">At first we tried to extend the </span><i><span style="font-weight: 400">oracle.adf.view.rich.change.FilteredPersistenceChangeManager</span></i><span style="font-weight: 400"> class, which is the class ADF uses by default. However, unfortunately this class is declared </span><i><span style="font-weight: 400">final</span></i><span style="font-weight: 400">. We decided to create a class that extends the </span><i><span style="font-weight: 400">org.apache.myfaces.trinidad.change.SessionChangeManager</span></i><span style="font-weight: 400"> class, and use the </span><i><span style="font-weight: 400">FilteredPersistenceChangeManager</span></i><span style="font-weight: 400"> as an instance variable. This may not be the prettiest solution, but it serves our purpose:</span></p>
<pre class="brush: java">package nl.whitehorses.personalization.changemanager;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;

import oracle.adf.view.rich.change.FilteredPersistenceChangeManager;

import org.apache.myfaces.trinidad.change.AttributeComponentChange;
import org.apache.myfaces.trinidad.change.ChangeManager;
import org.apache.myfaces.trinidad.change.ComponentChange;
import org.apache.myfaces.trinidad.change.DocumentChange;
import org.apache.myfaces.trinidad.change.SessionChangeManager;

public class CustomChangeManager extends SessionChangeManager {

	private final FilteredPersistenceChangeManager fpcmInstance = new FilteredPersistenceChangeManager();

	@Override
	public void addComponentChange(final FacesContext context, final UIComponent component, final ComponentChange change) {
		if (component == null || component.getAttributes() == null) {
			return;
		}
		final String[] persistArray = (String[]) component.getAttributes().get("persist");
		if (persistArray == null) {
			return;
		}
		for (final String persistVal : persistArray) {
			if (persistVal != null &amp;&amp; change instanceof AttributeComponentChange &amp;&amp; ("ALL".equals(persistVal) || ((AttributeComponentChange) change).getAttributeName().equals(persistVal))) {
				fpcmInstance.addComponentChange(context, component, change);
			}
		}
	}

	@Override
	public void addDocumentChange(final FacesContext context, final UIComponent component, final DocumentChange change) {
		fpcmInstance.addDocumentChange(context, component, change);
	}

	@Override
	public boolean supportsDocumentPersistence(final FacesContext context) {
		return fpcmInstance.supportsDocumentPersistence(context);
	}

	@Override
	public ChangeManager.ChangeOutcome addDocumentChangeWithOutcome(final FacesContext context, final UIComponent component, final DocumentChange change) {
		return fpcmInstance.addDocumentChangeWithOutcome(context, component, change);
	}

}</pre>
<p><span style="font-weight: 400">As you can see, the logic for the </span><i><span style="font-weight: 400">persist</span></i><span style="font-weight: 400"> attribute has been implemented in the </span><i><span style="font-weight: 400">addComponentChange</span></i><span style="font-weight: 400"> method. The </span><i><span style="font-weight: 400">addComponentChange</span></i><span style="font-weight: 400"> method from the </span><i><span style="font-weight: 400">FilteredPersistenceChangeManager</span></i><span style="font-weight: 400"> instance, will only be called when the component contains the </span><i><span style="font-weight: 400">persist </span></i><span style="font-weight: 400">attribute which is set to </span><i><span style="font-weight: 400">ALL</span></i><span style="font-weight: 400">. Besides the </span><i><span style="font-weight: 400">addComponentChange</span></i><span style="font-weight: 400"> method, all other (public) methods from the </span><i><span style="font-weight: 400">FilteredPersistenceChangeManager</span></i><span style="font-weight: 400"> have been implemented to use the instance variable as well.</span></p>
<h1><span style="font-weight: 400">Conclusion</span></h1>
<p><span style="font-weight: 400">After some struggles and adjustments to the implementation and configuration of the application, we got personalization to work in our real world application used by customers. We overcame the struggles, but this was not as easy as the blogs on the internet made us believe beforehand. We hope that sharing this experience, might save you for some of the troubles we had. </span></p>
<p><span style="font-weight: 400">To give you some more insight in the code and the struggles, we have created a (simple) demo application </span><i><span style="font-weight: 400">AdfPersonalization</span></i><span style="font-weight: 400">, to reproduce the issues we had, and which we used to solve them.</span></p>
<p><span style="font-weight: 400">This application consists of the default </span><i><span style="font-weight: 400">Model</span></i><span style="font-weight: 400"> and </span><i><span style="font-weight: 400">ViewController</span></i><span style="font-weight: 400"> projects. Also, we added a </span><i><span style="font-weight: 400">ViewControllerLibrary</span></i><span style="font-weight: 400"> project. This </span><i><span style="font-weight: 400">ViewControllerLibrary</span></i><span style="font-weight: 400"> project is imported as a library by the </span><i><span style="font-weight: 400">ViewController</span></i><span style="font-weight: 400"> project. </span></p>
<p><span style="font-weight: 400">The </span><i><span style="font-weight: 400">AdfPersonalization</span></i><span style="font-weight: 400"> application can be deployed to Weblogic in multiple ways:</span></p>
<ul>
<li style="font-weight: 400"><span style="font-weight: 400">Using the ‘Run’ button in JDeveloper.</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Using </span><i><span style="font-weight: 400">Application &gt; Deploy &gt; … to IntegratedWebLogicServer</span></i><span style="font-weight: 400"> in JDeveloper. This can be done to verify that struggle 2 is no longer an issue.</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Using </span><i><span style="font-weight: 400">Application &gt; Deploy &gt; … to EAR</span></i><span style="font-weight: 400">, followed by running the </span><i><span style="font-weight: 400">replace-persdef-repo</span></i><span style="font-weight: 400"> ANT target from the </span><i><span style="font-weight: 400">build.xml</span></i><span style="font-weight: 400"> file. Afterwards the EAR can be deployed to a Weblogic servers, which is capable using a database based MDS. This can be done to verify struggle 1 is no longer an issue.</span></li>
</ul>
<p><span style="font-weight: 400">The source of this project can be downloaded via <a href="http://blog.whitehorses.nl/wp-content/uploads/2018/07/AdfPersonalization.zip">AdfPersonalization.zip</a></span><span style="font-weight: 400">.</span></p>
<h1><span style="font-weight: 400">Resources</span></h1>
<ul>
<li style="font-weight: 400"><a href="https://docs.oracle.com/cd/E51367_01/fa_lcm_gs/OADTC/configure-personalization.htm#OADTC461"><span style="font-weight: 400">Configuring End-User Personalization</span></a></li>
<li style="font-weight: 400"><a href="https://docs.oracle.com/middleware/1212/adf/ADFFD/customize.htm#ADFFD2077"><span style="font-weight: 400">Customizing Applications with MDS</span></a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.whitehorses.nl/2018/07/10/the-struggles-of-personalization-in-adf/feed/</wfw:commentRss>
		<slash:comments>26</slash:comments>
		</item>
		<item>
		<title>Progressive Web Apps &#8211; bridging the gap between apps and websites</title>
		<link>http://blog.whitehorses.nl/2018/05/30/progressive-web-apps-bridging-the-gap-between-apps-and-websites/</link>
		<comments>http://blog.whitehorses.nl/2018/05/30/progressive-web-apps-bridging-the-gap-between-apps-and-websites/#comments</comments>
		<pubDate>Wed, 30 May 2018 07:06:32 +0000</pubDate>
		<dc:creator><![CDATA[Patrick Sinke]]></dc:creator>
				<category><![CDATA[Fullstack Development]]></category>
		<category><![CDATA[Web and mobile]]></category>
		<category><![CDATA[apps]]></category>
		<category><![CDATA[cross-platform]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[progressive web app]]></category>
		<category><![CDATA[pwa]]></category>
		<category><![CDATA[service workers]]></category>
		<category><![CDATA[WebAssembly]]></category>

		<guid isPermaLink="false">http://blog.whitehorses.nl/?p=5329</guid>
		<description><![CDATA[Apps, websites, mobile sites For a long time, developers had to choose whether they would build a (mobile) web site or an app to reach their audience. Both have their own set of advantages and disadvantages. Web sites are platform independent, but lack functionality and cannot be used offline. Apps deeply integrate with the device [&#8230;]]]></description>
				<content:encoded><![CDATA[<p></p><h2>Apps, websites, mobile sites</h2>
<p>For a long time, developers had to choose whether they would build a (mobile) web site or an app to reach their audience. Both have their own set of advantages and disadvantages. Web sites are platform independent, but lack functionality and cannot be used offline. Apps deeply integrate with the device on which they are installed but have to be developed for each platform and are not as easily updated.</p>
<h2>Progressive Web Apps</h2>
<p>The solution for that is called a Progressive Web App. Basically, it&#8217;s a website with added functionality. And there are a number of featues that a PWA requires.</p>
<p>First, a PWA-enabled website should contain an SSL certificate in order to prevent Man in the Middle (MitM) attacks between the app and the backend.</p>
<p>Sceond, it contains a JSON file called a Web Application Manifest. This file holds information about the name of the application, links to the web app icons or image objects and details about the splash screen.</p>
<p>Last but not least, a PWA has a feature called service workers. These are little JavaScript programs who enable push notifications, background data loading and caching. But wait, there&#8217;s more. They also provide access to important features of your mobile device like location, camera and things like Apple Pay. And another thing, web features like <a href="https://webassembly.org/">WebAssembly</a> (for executing near-native code in the webbrowser) are possible with service workers too. This property of the PWA truly bridges the gap between web pages and app features.</p>
<h2>Are we there yet?</h2>
<p>Although the technology is promising, there are still some hurdles to be taken. Not all features of all mobile devices are supported yet. So is Touch ID not useable without an extra layer like Phone Gap or Cordova. Also, push notifications do not work on iOS devices because background processes are required for service workers and not supported (yet).</p>
<p>The word &#8220;progressive&#8221; in PWA stands for the idea that although not all functionality is supported by every device, the features that are enabled will work anyway, without breaking the entire app. So if push notification do not work, the site is still able to cache and refresh data. Basically, it&#8217;s the next step after progressive web sites, that enabled developers to build one site for many different screen resolutions and input types.</p>
<p>If PWA&#8217;s are going to be the next big thing is still a question. But they will pave the way for a smoother user experience across devices and a more generic design of apps anyway. The gap between native apps and websites has become narrower, although still not fully bridged.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.whitehorses.nl/2018/05/30/progressive-web-apps-bridging-the-gap-between-apps-and-websites/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>The MongoDB ObjectId explained in under 2 minutes</title>
		<link>http://blog.whitehorses.nl/2018/04/16/the-mongodb-objectid-explained-in-under-2-minutes/</link>
		<comments>http://blog.whitehorses.nl/2018/04/16/the-mongodb-objectid-explained-in-under-2-minutes/#comments</comments>
		<pubDate>Mon, 16 Apr 2018 15:00:40 +0000</pubDate>
		<dc:creator><![CDATA[Patrick Sinke]]></dc:creator>
				<category><![CDATA[Big & Fast Data]]></category>
		<category><![CDATA[Fullstack Development]]></category>
		<category><![CDATA[Web and mobile]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[ObjectId]]></category>

		<guid isPermaLink="false">http://blog.whitehorses.nl/?p=5326</guid>
		<description><![CDATA[As you may have noticed, especially when your background is from a MySQL or Oracle database, is that the unique identifier for database records (or &#8216;documents&#8217; in MongoDB) is quite different. It&#8217;s not a incremental counter, but a long string of characters. 12 bytes in hexadecimal format, to be precise. And although they appear to [&#8230;]]]></description>
				<content:encoded><![CDATA[<p></p><p>As you may have noticed, especially when your background is from a MySQL or Oracle database, is that the unique identifier for database records (or &#8216;documents&#8217; in MongoDB) is quite different. It&#8217;s not a incremental counter, but a long string of characters. 12 bytes in hexadecimal format, to be precise. And although they appear to contain no information, they actually do. This is how an ObjectId is composed.</p>
<p>Let&#8217;s take an ObjectId:</p>
<pre><span class="s2">507f1f77bcf86cd799439011
</span></pre>
<p>The first part is a 4-byte value representing the seconds since the Unix epoch (hence, it&#8217;s a timestamp!), the next part is a 3-byte machine identifier unique for every machine, then a 2-byte containing the process id, and finally a 3-byte counter, starting with a random value.</p>
<p>This combination of values (timestamp, machine, process, counter) guarantees a unique value for the ObjectId.</p>
<p>Because the timestamp is included, it&#8217;s possible to extract it from the Id. That&#8217;s fairly simple, because Mongo provides a function for that:</p>
<div class="copyable-code-block highlight-javascript notranslate">
<div class="highlight">
<pre><span class="nx">ObjectId</span><span class="p">(</span><span class="s2">"507c7f79bcf86cd7994f6c0e"</span><span class="p">).</span><span class="nx">getTimestamp</span><span class="p">()</span>

returns</pre>
<pre><span class="nx">ISODate</span><span class="p">(</span><span class="s2">"2012-10-15T21:26:17Z"</span><span class="p">)

Just as simple is extracting the stringvalue:

<code class="xref mongodb mongodb-method docutils literal notranslate"><span class="pre">ObjectId.valueOf((<span class="s2">"507c7f79bcf86cd7994f6c0e"</span>)
</span></code> returns <span class="s2">507c7f79bcf86cd7994f6c0e</span> See <a href="https://docs.mongodb.com/manual/reference/method/ObjectId/#examples">the MongoDB reference</a> for more examples.</span></pre>
</div>
</div>
<pre>
</pre>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.whitehorses.nl/2018/04/16/the-mongodb-objectid-explained-in-under-2-minutes/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Node.js tutorial part 2; building a proper website</title>
		<link>http://blog.whitehorses.nl/2018/02/12/node-js-tutorial-part-2-building-a-proper-website/</link>
		<comments>http://blog.whitehorses.nl/2018/02/12/node-js-tutorial-part-2-building-a-proper-website/#comments</comments>
		<pubDate>Mon, 12 Feb 2018 14:54:46 +0000</pubDate>
		<dc:creator><![CDATA[Patrick Sinke]]></dc:creator>
				<category><![CDATA[Miscellaneous]]></category>

		<guid isPermaLink="false">http://blog.whitehorses.nl/?p=5122</guid>
		<description><![CDATA[Your first fully functional Node.js application In the first part of this tutorial we set up a development environment. As you have noticed there, the core of a Node.js application is a server side Javascript file. You will be editing this file a lot and along the while it will grow accordingly. I think the [&#8230;]]]></description>
				<content:encoded><![CDATA[<p></p><h3>Your first fully functional Node.js application</h3>
<p><a href="http://blog.whitehorses.nl/2016/06/23/node-js-tutorial-part-1-setting-up-your-environment/">In the first part of this tutorial</a> we set up a development environment. As you have noticed there, the core of a Node.js application is a server side Javascript file. You will be editing this file a lot and along the while it will grow accordingly.</p>
<p>I think the first step you will take, is change your code so that node.js serves a proper website. This can be an entirely new site, but without much effort an existing one too.</p>
<p>First things first. npm is the tool we used for creating a first application. When installing packages with npm, you have different options for installing them. With npm -g &lt;packagename&gt; you install global (system-wide) packages, without the -g packages are installed into the current directory/project.</p>
<p>When we&#8217; re on it , install MongoDB on your system. We&#8217;re going to use it in our application as a database. Installation is pretty straightforward on most systems, <a href="https://docs.mongodb.com/manual/installation/">this site</a> is an excellent starting point.</p>
<p>There are a number of npm packages that are of huge value when creating node.js applications, but the choice is enormous. The following list (in no particular order) of packages is especially invaluable:</p>
<ul>
<li>path</li>
<li>express</li>
<li>mongoose</li>
<li>body-parser</li>
</ul>
<p>Let&#8217;s see how we use this in a simple but functional Node.js application. Create a new directory for your project and run</p>
<pre>npm init</pre>
<p>The wizard is pretty self-explanatory. Now we install the necessary npm packages. Install them using these commands:</p>
<pre>npm install express --save
npm install express-session --save
npm install body-parser --save
npm install mongoose --save</pre>
<p>To make things easy for you, here&#8217;s a code snippet you can paste into the index.js at the root of your project:</p>
<pre class="brush: js">// initiate express middleware
const express = require('express');
const app = express();

// assign the directory 'public' for storing static 
// files (e.g. HTML and CSS)
app.use(express.static('public'));

// enable the parsing of request bodies and 
// simplified handling of JSON content
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({extended: true}));

// initiatie Mongoose for MongoDB connectivity
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/rodeo', {
   keepAlive: true,
   reconnectTries: 10
});

// define a schema for a mongoDB collection
const Schema = mongoose.Schema;

var transactieSchema = new Schema({
   userName: {type: String},
   transactieDatum: {type: Date},
   code: {type: String},
   aantal: {type: Number},
   bedrag: {type: Number}
   //  _id: false
},
   {collection: 'transacties'});
mongoose.model('transacties', transactieSchema);

// Do some neat forwarding of the root of your site 
// to a default file
app.get('/', (req, res) =&gt; res.sendfile('index.html'));

// a function for handling a post request
postTransacties = function (req, res, next) {
   console.log(req.body);
   var transacties = mongoose.model('transacties');
   var transactie = new transacties(req.body);
   transactie.save(function (err) {
      if (err) {
         console.log(err);

      }
      return res.json({value: 'hello'});
   });

};

// a function for handling a get request
getTransacties = function (req, res, next) {
   var transacties = mongoose.model('transacties');
   transacties.find({}, function (err, data) {
      return res.json(data);
   });

};

// routing for post and get on the /transacties url
app.route('/transacties')
   .post(postTransacties)
   .get(getTransacties);

// finally, let's fire up a webserver at port 3500
app.listen(3500, function () {
   console.log('listening on *:3500');
   module.exports = app;
});</pre>
<p>This is not the best practice in terms of maintainability (it&#8217;s better to keep your database, router and controller-middleware in different files), but it will demonstrate everything you need for a full-fledged Node.js application including posting and retrieving data.</p>
<p>Final thing you need is a new directory &#8220;public&#8221;. Create an index.hml there with this contents:</p>
<pre class="brush: js">&lt;html&gt;&lt;head&gt;
&lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt;
	 $(document).ready(function () {
 $('body').on('click', '.addone', function () {
      var res = {
         userName: $('.naam').val(),
         transactieDatum: new Date(),
         code: $('.code').val(),
         aantal: $('.aantal').val(),
         bedrag: $('.bedrag').val()
      };
      console.log(res);
         $.ajax({
            type: "POST",
            url: "/transacties",
            data: res,
            success: function (result) {
               console.log('succes');
            },
            error: function (jqXHR, textStatus) {
               console.log(textStatus);
            }
         });
      
   });
   });
	&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div class="form-group-sm row"&gt;
                        &lt;label for="Naam" class="col-sm-3 col-form-label"&gt;Naam&lt;/label&gt;
                       &lt;input id="naam"  name="code" class="form-control naam"&gt;  
                     &lt;/div&gt;

              &lt;label for="code" class="col-sm-3 col-form-label"&gt;Code&lt;/label&gt;
                       &lt;input id="code"  name="code" class="form-control code"&gt;  
                     &lt;/div&gt;
&lt;div class="form-group-sm row"&gt;
                        &lt;label for="aantal" class="col-sm-3 col-form-label"&gt;Aantal&lt;/label&gt;
                       &lt;input id="aantal" type="number"  name="code" step="1" class="form-control aantal"&gt;  
                     &lt;/div&gt;
                        &lt;label for="bedrag" class="col-sm-3 col-form-label"&gt;Bedrag&lt;/label&gt;
                       &lt;input id="bedrag" type="number"  name="bedrag" step="0.01" class="form-control bedrag"&gt;  
                     &lt;/div&gt;
                    
 &lt;div class="form-group-sm row"&gt;
 	&lt;button class="addone" data-toggle="tooltip" span="" style="color:darkgreen" title="Opslaan"&gt;Save&lt;/button&gt;
 &lt;/div&gt;
 &lt;/body&gt;
&lt;/html&gt;</pre>
<p>Now, go to the root of your project and type</p>
<pre>node index.js</pre>
<p>And when you point your browser to http://localhost:3500 a simple input form will be presented.</p>
<p>If you want to check if everything works as expected, fill in the form, press Save and go to http://localhost:3500/transacties . A JSON document will be displayed with all the records you saved.</p>
<p>That&#8217;s all. Now you have a fully working skeleton from where you can start building your enterprise website in Node.js!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.whitehorses.nl/2018/02/12/node-js-tutorial-part-2-building-a-proper-website/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Enforce the HTML5 max attribute of input items with JavaScript</title>
		<link>http://blog.whitehorses.nl/2018/02/10/enforce-the-html5-max-attribute-of-input-items-with-javascript/</link>
		<comments>http://blog.whitehorses.nl/2018/02/10/enforce-the-html5-max-attribute-of-input-items-with-javascript/#comments</comments>
		<pubDate>Sat, 10 Feb 2018 21:02:55 +0000</pubDate>
		<dc:creator><![CDATA[Patrick Sinke]]></dc:creator>
				<category><![CDATA[Web and mobile]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[max]]></category>
		<category><![CDATA[min]]></category>

		<guid isPermaLink="false">http://blog.whitehorses.nl/?p=5316</guid>
		<description><![CDATA[The HTML5 max and min attribute on input items The max attribute is introduced in HTML5 and specifies the maximum value for an &#60;input&#62; element. Unfortunately, it doesn&#8217;t enforce the maximum value entered when typing in numbers as you might expect. The syntax for the HTML element is as follows: &#60;input max=&#8221;number&#124;date&#8220;&#62; With a small [&#8230;]]]></description>
				<content:encoded><![CDATA[<p></p><h3>The HTML5 max and min attribute on input items</h3>
<p>The max attribute is introduced in HTML5 and specifies the maximum value for an &lt;input&gt; element. Unfortunately, it doesn&#8217;t enforce the maximum value entered when typing in numbers as you might expect.</p>
<p>The syntax for the HTML element is as follows:</p>
<p>&lt;input max=&#8221;<i>number</i>|<i>date</i>&#8220;&gt;</p>
<p>With a small JavaScript function it&#8217;s possible to make sure no value larger than the max value (or smaller than the min value) may be entered. Just put the following code in your $(document).ready(function) {}:</p>
<pre class="brush: js">   $(document).on('keyup', '.myInputItem', function () {
      if (parseInt($(this).val()) &gt;= $(this).attr('max'))
      {
         $(this).val($(this).attr('max'));
      }
   });</pre>
<p>The function fires on the keyup event. The if statement compares the value of the input item with the max value. When it is higher, it will replace the contents with the max value.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.whitehorses.nl/2018/02/10/enforce-the-html5-max-attribute-of-input-items-with-javascript/feed/</wfw:commentRss>
		<slash:comments>29</slash:comments>
		</item>
		<item>
		<title>Mediator throwing incomplete BusinessFaultException</title>
		<link>http://blog.whitehorses.nl/2017/10/31/mediator-throwing-incomplete-businessfaultexception/</link>
		<comments>http://blog.whitehorses.nl/2017/10/31/mediator-throwing-incomplete-businessfaultexception/#comments</comments>
		<pubDate>Tue, 31 Oct 2017 19:40:41 +0000</pubDate>
		<dc:creator><![CDATA[Mike Heeren]]></dc:creator>
				<category><![CDATA[Integration, SOA & BPM]]></category>
		<category><![CDATA[BPEL]]></category>
		<category><![CDATA[bpm]]></category>
		<category><![CDATA[Component]]></category>
		<category><![CDATA[composite]]></category>
		<category><![CDATA[fault]]></category>
		<category><![CDATA[Mediator]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Policies]]></category>
		<category><![CDATA[SOA]]></category>

		<guid isPermaLink="false">http://blog.whitehorses.nl/?p=5298</guid>
		<description><![CDATA[<p>A while ago I ran into the issue that business fault information was not returned to the calling system by the Mediator component in the SOA composite. Instead, only a message that a business fault occurred was responded to the calling system. </p>
]]></description>
				<content:encoded><![CDATA[<p></p><p>A while ago I ran into the issue that business fault information was not returned to the calling system by the Mediator component in the SOA composite. Instead, only a message that a business fault occurred was responded to the calling system. The response would look something like the below example:</p>
<pre class="brush: xml; gutter: false; toolbar: false; auto-links: false; wrap-lines: false">&lt;env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope"&gt;
	&lt;env:Header/&gt;
	&lt;env:Body&gt;
		&lt;env:Fault&gt;
			&lt;env:Code&gt;
				&lt;env:Value&gt;env:Receiver&lt;/env:Value&gt;
			&lt;/env:Code&gt;
			&lt;env:Reason&gt;
				&lt;env:Text xml:lang="en-US"&gt;oracle.fabric.common.BusinessFaultException&lt;/env:Text&gt;
			&lt;/env:Reason&gt;
			&lt;env:Role/&gt;
			&lt;env:Detail&gt;
				&lt;exception/&gt;
			&lt;/env:Detail&gt;
		&lt;/env:Fault&gt;
	&lt;/env:Body&gt;
&lt;/env:Envelope&gt;</pre>
<p>In this blogpost I will describe what caused this issue, and how it could be solved.</p>
<h1>Fault policies and Mediators</h1>
<p>Let’s start with some information about fault policies in combination with Mediator components. When fault policies are introduced to a composite, you need to keep the following things in mind:</p>
<ul>
<li>When the Mediator is configured <em>sequencial</em>, only the following fault policy actions are supported on the Mediator component: Abort, Rethrow and Java code.</li>
<li>When the Mediator is configured <em>parallel</em>, only the following fault policy actions are supported on the Mediator component: Retry, Rethrow, Human intervention, Abort and Java code.</li>
</ul>
<h1>What was causing the issue?</h1>
<p>In our case the SOA composite exposed both synchronous and asynchronous services. The composite was also using fault policies. There were 2 fault policies defined:</p>
<ul>
<li>A fault policy for asynchronous services. This fault policy would trigger a Human intervention action.</li>
<li>A fault policy for synchronous services. This fault policy would trigger a Rethrow action.</li>
</ul>
<p>Because most components in the composite were asynchronous, the fault policy on composite level was configured to the asynchronous fault policy. For all synchronous BPEL components, this fault policy was overridden on component level.</p>
<p>The issue was caused by the fact that the synchronous fault policy was only applied to the BPEL components, and not to the Mediator components. So when a (business) fault was raised in the BPEL component, the fault policy would rethrow the fault to the Mediator. However, the Mediator would try to start a Human intervention action (due to the asynchronous fault policy on the composite level), which is not supported for a <em>sequencial</em> configured Mediator.</p>
<p>This could also be seen in the Enterprise Manager. The rule marked in the image below was not displayed at that moment.</p>
<p><a href="http://blog.whitehorses.nl/wp-content/uploads/2017/10/Fault-policies.png"><img class="alignnone wp-image-5299 size-large" src="http://blog.whitehorses.nl/wp-content/uploads/2017/10/Fault-policies-540x113.png" alt="" width="540" height="113" srcset="http://blog.whitehorses.nl/wp-content/uploads/2017/10/Fault-policies-540x113.png 540w, http://blog.whitehorses.nl/wp-content/uploads/2017/10/Fault-policies-300x63.png 300w, http://blog.whitehorses.nl/wp-content/uploads/2017/10/Fault-policies-768x161.png 768w" sizes="(max-width: 540px) 100vw, 540px" /></a></p>
<h1>Solving the issue</h1>
<p>With the above knowledge, it was not very hard to solve the issue. Instead of configuring the fault policy on composite level to the asynchronous fault policy, we configured the composite fault policy to the synchronous fault policy. For every asynchronous BPEL component the fault policy was overridden on component level.</p>
<p>This resulted in faults like the below example being returned to the calling systems again:</p>
<pre class="brush: xml; gutter: false; toolbar: false; auto-links: false; wrap-lines: false">&lt;env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope"&gt;
	&lt;env:Header/&gt;
	&lt;env:Body&gt;
		&lt;env:Fault xmlns:ns0="nl.whitehorses.services/faults/1.0"&gt;
			&lt;env:Code&gt;
				&lt;env:Value&gt;env:Receiver&lt;/env:Value&gt;
				&lt;env:Subcode&gt;
					&lt;env:Value&gt;ns0:fault&lt;/env:Value&gt;
				&lt;/env:Subcode&gt;
			&lt;/env:Code&gt;
			&lt;env:Reason&gt;
				&lt;env:Text xml:lang="en-US"/&gt;
			&lt;/env:Reason&gt;
			&lt;env:Role/&gt;
			&lt;env:Detail&gt;
				&lt;FaultDetails xmlns="nl.whitehorses.services/faults/1.0"&gt;
					&lt;Code&gt;F12345&lt;/Code&gt;
					&lt;Description&gt;TEST&lt;/Description&gt;
				&lt;/FaultDetails&gt;
			&lt;/env:Detail&gt;
		&lt;/env:Fault&gt;
	&lt;/env:Body&gt;
&lt;/env:Envelope&gt;</pre>
<p><strong>Sources:</strong></p>
<ul>
<li><a href="http://docs.oracle.com/cd/E36909_01/dev.1111/e10224/bp_faults.htm">Using Fault Handling in a BPEL Process</a></li>
<li><a href="http://docs.oracle.com/cd/E36909_01/dev.1111/e10224/med_faulthandling.htm">Using Oracle Mediator Error Handling</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.whitehorses.nl/2017/10/31/mediator-throwing-incomplete-businessfaultexception/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>How to compare Mongo _id&#8217;s in Javascript</title>
		<link>http://blog.whitehorses.nl/2017/10/15/how-to-compare-mongo-_ids-in-javascript/</link>
		<comments>http://blog.whitehorses.nl/2017/10/15/how-to-compare-mongo-_ids-in-javascript/#comments</comments>
		<pubDate>Sun, 15 Oct 2017 11:55:12 +0000</pubDate>
		<dc:creator><![CDATA[Patrick Sinke]]></dc:creator>
				<category><![CDATA[Web and mobile]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[mongoose]]></category>
		<category><![CDATA[ObjectId]]></category>

		<guid isPermaLink="false">http://blog.whitehorses.nl/?p=5289</guid>
		<description><![CDATA[<p>When comparing MongoDB generated _id fields in Javascript, you'll soon or later find out you cannot simply compare them as if they are plain text variables. </p>
]]></description>
				<content:encoded><![CDATA[<p></p><p>When comparing MongoDB generated _id fields in Javascript, you&#8217;ll soon or later find out that the following code will not give expected results:</p>
<pre class="brush: js; gutter: false; toolbar: false; auto-links: false; wrap-lines: false">var id1 = mongoose.Types.ObjectId('58a0625246cb87062919eb62');
var id2 = mongoose.Types.ObjectId('58a0625246cb87062919eb62');
if (id1===id2) {
 console.log('elements are equal but we dont get here!' );
}</pre>
<p>Although this appears a valid comparison, the console.log will never be printed. ObjectId&#8217;s are objects, and although when printed to the console appear as ordinary text, they cannot be simply compared.</p>
<p>A simple solution is using the .equals() function, which is part of the MongoDB driver:</p>
<pre class="brush: js; gutter: false; toolbar: false; auto-links: false; wrap-lines: false">var id1 = mongoose.Types.ObjectId('58a0625246cb87062919eb62');
var id2 = mongoose.Types.ObjectId('58a0625246cb87062919eb62');
if (id1.equals(id2)) {
 console.log('elements are equal' );
}</pre>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.whitehorses.nl/2017/10/15/how-to-compare-mongo-_ids-in-javascript/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>IoT on #oow17 and in my life</title>
		<link>http://blog.whitehorses.nl/2017/10/03/iot-on-oow17-and-in-my-life/</link>
		<comments>http://blog.whitehorses.nl/2017/10/03/iot-on-oow17-and-in-my-life/#comments</comments>
		<pubDate>Tue, 03 Oct 2017 16:23:34 +0000</pubDate>
		<dc:creator><![CDATA[Maurik-Jan Veenman]]></dc:creator>
				<category><![CDATA[Big & Fast Data]]></category>
		<category><![CDATA[Business & IT]]></category>

		<guid isPermaLink="false">http://blog.whitehorses.nl/?p=5281</guid>
		<description><![CDATA[<p>Last Sunday I attended an interesting Oracle OpenWord session about how Federal Express uses the electronics in cars to coach their drivers, to save fuel and prevent excessive engine and tyre wear. </p>
]]></description>
				<content:encoded><![CDATA[<p></p><p>Last Sunday I attended an interesting session at Oracle OpenWord. It was a session about how Federal Express, an American company who delivers parcels, used the electronics in cars that monitor tyre pressure, a lot of parameters from the engine and the gps of the car to collect huge amounts of data. With this data they could coach drivers to drive more fluently to save fuel and prevent excessive engine and tyre wear. They saved money because they optimized routes and minimized the time of cars running idle. They could also inform the customer exactly when the parcel would arrive, because they could see live how well the trip is going (deviations or accidents and a very lucky drive were all noticed and used to update the estimated time of arrival.</p>
<p>I thought it was an inspiring session, because they used what is already there (the car electronics, a database), and combine it with a small device that sends all this information via the phone data network to the organization. Then they add clever analytics software and they are much more in control, and can use and maintain their equipment much more efficiently. In the past there was a little buffer taken for many things, now that is no longer necessary, because they can see exactly when, for instance, the tyres of the car need to be resurfaced, because one can see the exact mileage.</p>
<p>The next day Mark Hurd was talking about predictions he had made, and proving that they were right. One of them was that much more devices in our lives will be connected with each other to make our life easier. Until now I had the idea that all these things were not going as fast as he had predicted them.</p>
<p>But suddenly I realized that even in my own life a lot of things are being combined with each other to comfort my life: if I start up my Blu-ray player, my TV is automatically started, my ‘toon’ (smart thermostat and domotica controller) measures how much power I use and tells that to the power company, so that I don’t have to fill in a end-of-year measurement manually anymore. If I step into my car, my phone is automatically connected, and the app ‘flitsmeister’ is automatically started because it detects that the phone connects to my car. If I Google a restaurant on my phone, I can let google maps guide me to there, if I hear a good song, I can let Shazam listen to it, and find the song’s title for me. When I booked Oracle OpenWorld with my credit card, the bank called me to check if that was a normal, wanted transaction.</p>
<p>These are all examples of clever use of things that are there like phones and what’s in them, databases, the data network, the data itself and analytic software to help us make our lives better. I love it, and I am proud to be a part of the industry that makes this happen!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.whitehorses.nl/2017/10/03/iot-on-oow17-and-in-my-life/feed/</wfw:commentRss>
		<slash:comments>300</slash:comments>
		</item>
		<item>
		<title>OGh Tech Experience 2017 &#8211; recap</title>
		<link>http://blog.whitehorses.nl/2017/06/19/ogh-tech-experience-2017-recap/</link>
		<comments>http://blog.whitehorses.nl/2017/06/19/ogh-tech-experience-2017-recap/#comments</comments>
		<pubDate>Mon, 19 Jun 2017 20:09:45 +0000</pubDate>
		<dc:creator><![CDATA[Michel van Zoest]]></dc:creator>
				<category><![CDATA[ADF / Enterprise Java]]></category>
		<category><![CDATA[Big & Fast Data]]></category>
		<category><![CDATA[Business & IT]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Enterprise Mobility]]></category>
		<category><![CDATA[Integration, SOA & BPM]]></category>
		<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Oracle platform]]></category>
		<category><![CDATA[Oracle tools]]></category>
		<category><![CDATA[Web and mobile]]></category>
		<category><![CDATA[12c]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[API Fortress]]></category>
		<category><![CDATA[apiary]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[blockchain]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[event]]></category>
		<category><![CDATA[FMW]]></category>
		<category><![CDATA[Fusion Middleware]]></category>
		<category><![CDATA[ics]]></category>
		<category><![CDATA[implementation]]></category>
		<category><![CDATA[Integration]]></category>
		<category><![CDATA[management]]></category>
		<category><![CDATA[microservices]]></category>
		<category><![CDATA[nloug]]></category>
		<category><![CDATA[nl_oug]]></category>
		<category><![CDATA[OGh]]></category>
		<category><![CDATA[oghtech17]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[pcs]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[pl/sql]]></category>
		<category><![CDATA[process]]></category>
		<category><![CDATA[Service Orientation]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://blog.whitehorses.nl/?p=5237</guid>
		<description><![CDATA[<p>On June 15th and 16th 2017 the very first OGh Tech Experience was held. This 2-day conference was a new combination of the DBA Days and Fusion Middleware Tech Experience that were held in previous years. To summarize: OGh hit bullseye. It was two days packed with excellent in-depth technical sessions, good customer experiences and great networking opportunities.</p>
]]></description>
				<content:encoded><![CDATA[<p></p><p>On June 15th and 16th 2017 the very first OGh Tech Experience was held. This 2-day conference was a new combination of the DBA Days and Fusion Middleware Tech Experience that were held in previous years. To summarize: OGh hit bullseye. It was two days packed with excellent in-depth technical sessions, good customer experiences and great networking opportunities.</p>
<p>The venue was well chosen. De Rijtuigenloods in Amersfoort is a former maintenance building of the Dutch Railways converted into a conference center. So the backdrop and even the location of some sessions were old train carriages.</p>
<div id="attachment_5239" style="width: 550px" class="wp-caption aligncenter"><img src="http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-15-08.19.06-540x304.jpg" alt="Tech Experience Entrance" width="540" height="304" class="size-large wp-image-5239" srcset="http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-15-08.19.06-540x304.jpg 540w, http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-15-08.19.06-300x169.jpg 300w, http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-15-08.19.06-768x432.jpg 768w" sizes="(max-width: 540px) 100vw, 540px" /><p class="wp-caption-text"></p>
<p>Tech Experience Entrance</p>
<p></p></div>
<p>The first bombshell was dropped in the introduction by OGh Chairman Robin Buitenhuis. Starting July 1st, the OGh will be renamed to nlOUG, the Netherlands Oracle User Group. This will provide OGh with a more international allure and hopefully attract more foreign speakers and visitors to their events.</p>
<p>After the introduction it was time for the first Keynote. Maria Colgan (<a href="http://twitter.com/sqlmaria" target="_blank" rel="noopener">@sqlmaria</a>) the Oracle Database Product Manager delivered a great talk about bridging the gap between developers and dba&#8217;s, by letting them work together as DevOps teams. Even though I don&#8217;t agree with her definition of DevOps (I agree more with Lucas Jellema, but more about that later in this blog), I do agree with her sentiments.</p>
<div id="attachment_5244" style="width: 550px" class="wp-caption aligncenter"><img src="http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-15-09.19.10-540x304.jpg" alt="Maria Colgan on Oracle Database 12c and DevOps" width="540" height="304" class="size-large wp-image-5244" srcset="http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-15-09.19.10-540x304.jpg 540w, http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-15-09.19.10-300x169.jpg 300w, http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-15-09.19.10-768x432.jpg 768w" sizes="(max-width: 540px) 100vw, 540px" /><p class="wp-caption-text"></p>
<p>Maria Colgan on Oracle Database 12c  and DevOps</p>
<p></p></div>
<p>During her talk a lot of new Database 12c features were shown, that were interesting for both the DBA as the Fusion Middleware attendees. A few highlights:</p>
<ul>
<li>leveraging REST from the database by using SQL Developer as ORDS (Oracle Rest Data Services)</li>
<li>dbms_json and json_dataguide to implement json directly from/in the database</li>
<li>new Materialized View features like Enable On Query Computation</li>
<li>ALTER TABLE INMEMORY for better performance</li>
<li>dbms_redact to redact data for security reasons</li>
</ul>
<p>After the first keynote and much needed refreshments due to the tropical temperatures, the parallel sessions started. Because the Tech Experience was a combination of two events, there were 9 simultanious tracks about many different subjects. Ranging from DBA and PL/SQL to Integration &amp; Process and Web &amp; Mobile, choosing an interesting track was easy.</p>
<p>My first session was one by <a href="https://twitter.com/Jphjulstad" target="_blank">Jon Petter Hjulstad</a>, namely &#8216;Experiences from SOA 12.2 implementations&#8217;. Because my current customer is in a transition from 11g to 12c, this one gave me some insight in what to expect and what to avoid.</p>
<div id="attachment_5265" style="width: 550px" class="wp-caption aligncenter"><img src="http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-16-08.57.15-540x304.jpg" alt="Tools of the trade" width="540" height="304" class="size-large wp-image-5265" srcset="http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-16-08.57.15-540x304.jpg 540w, http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-16-08.57.15-300x169.jpg 300w, http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-16-08.57.15-768x432.jpg 768w" sizes="(max-width: 540px) 100vw, 540px" /><p class="wp-caption-text">Tools of the trade</p></div>
<p>My second session was also in the Integration &amp; Process track. This one was on &#8216;Case Management in Process Cloud&#8217; delivered by <a href="https://twitter.com/ralf_mueller" target="_blank">Ralf Mueller</a>. He showed the audiance the path that Oracle is taking in expanding the Process Cloud with Unstructured or Dynamic Processes by introducing stages that can be invoked by rules, similar to the on-premise ACM implementation. He even did a demo, to show the ease with which a new implementation can be built.<br />
Later Ralf gave a glimpse into the future of Process Cloud by talking about Adaptive Processes. That will be supported by AI and Machine Learning, data based rules and a Deep Learning Algorithm. Stuff out of sci-fi!</p>
<p>After this it was time for some good old SQL. <a href="https://blogs.oracle.com/sql/ceed2b59-1de1-43fe-bc6b-07b1410f148b" target="_blank">Chris Saxon</a> showed the audience some magic that can be achieved by using some neat features that the Oracle Database has hidden. Some examples are:</p>
<ul>
<li>SQL Translation Framework</li>
<li>Edition Base Redefinition</li>
<li>Index Organized Tables</li>
<li>Invisible Columns</li>
</ul>
<div id="attachment_5251" style="width: 310px" class="wp-caption aligncenter"><img class="size-medium wp-image-5251" src="http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-15-17.10.02-cropped-300x122.jpg" alt="Don't ask Tom" width="300" height="122" srcset="http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-15-17.10.02-cropped-300x122.jpg 300w, http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-15-17.10.02-cropped-768x312.jpg 768w, http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-15-17.10.02-cropped-540x220.jpg 540w" sizes="(max-width: 300px) 100vw, 300px" /><p class="wp-caption-text">Don&#8217;t ask Tom</p></div>
<p>My next session was by Sandra Flores (<a href="http://twitter.com/sandyfloresmx" target="_blank" rel="noopener">@sandyfloresmx</a>), an Integration specialist from Mexico. She explained her vision on SOA, Microservices and Service Orientation. Especially how they connect to each other. My main takeaway from this session was, that Microservices can be a part of a SOA, but they are both a part of a Service Orientation.</p>
<div id="attachment_5252" style="width: 550px" class="wp-caption aligncenter"><img src="http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-15-14.30.04-cropped-540x344.jpg" alt="The Samurai Way" width="540" height="344" class="size-large wp-image-5252" srcset="http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-15-14.30.04-cropped-540x344.jpg 540w, http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-15-14.30.04-cropped-300x191.jpg 300w, http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-15-14.30.04-cropped-768x489.jpg 768w" sizes="(max-width: 540px) 100vw, 540px" /><p class="wp-caption-text"></p>
<p>The Samurai Way</p>
<p></p></div>
<p>The last session of the first day that I visited was by Lonneke Dikmans and Ronald van Luttikhuizen. In this session they showed the audience how Architects and Integration Specialist can start debates on the architecture of a integration implementation.</p>
<p>The day was concluded with a very good dinner and some much needed drinks.</p>
<div id="attachment_5266" style="width: 550px" class="wp-caption aligncenter"><img src="http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-15-20.42.55-540x304.jpg" alt="A bit rusty" width="540" height="304" class="size-large wp-image-5266" srcset="http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-15-20.42.55-540x304.jpg 540w, http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-15-20.42.55-300x169.jpg 300w, http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-15-20.42.55-768x432.jpg 768w" sizes="(max-width: 540px) 100vw, 540px" /><p class="wp-caption-text">A bit rusty</p></div>
<p>On the second day of the event, things started off with another keynote. This time it was <a href="https://blogs.oracle.com/groundside/" target="_blank">Duncan Mills</a>, who titled his session &#8220;How I learned to stop worrying and love the Cloud&#8221;. In his keynote, he explained how he started his life as a young programmer and gradually growed into the person he is now, and what lessons he learned along the way.<br />
It was a fun talk and it provided lots of insights for developers and managers alike.<br />
Duncan explained how an organization can take it&#8217;s path towards the Cloud. This path consists of four steps in his opinion, but an organization should not go further up that path than they dare to go. If step 1 is enough for them, you don&#8217;t have to go further to be able to profit from the Cloud. If you take it too far, adoption might get too forced.</p>
<div id="attachment_5249" style="width: 550px" class="wp-caption aligncenter"><img src="http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-16-09.24.45-540x304.jpg" alt="Duncan Mills - Path to the Cloud" width="540" height="304" class="size-large wp-image-5249" srcset="http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-16-09.24.45-540x304.jpg 540w, http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-16-09.24.45-300x169.jpg 300w, http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-16-09.24.45-768x432.jpg 768w" sizes="(max-width: 540px) 100vw, 540px" /><p class="wp-caption-text"></p>
<p>Duncan Mills &#8211; Path to the Cloud</p>
<p></p></div>
<p>Another great lesson was based on Richard Dawkins book &#8220;<a href="https://en.wikipedia.org/wiki/The_Selfish_Gene" target="_blank">The Selfish Gene</a>&#8220;, about how genes that wanted to grow started the evolotion of organisms. Therefore Duncan introduced us to the Selfish Developer. He explained that helping developers in all their whims (like: &#8220;give me another environment to test stuff&#8221;) will help an organization evolve.<br />
<div id="attachment_5255" style="width: 550px" class="wp-caption aligncenter"><img src="http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-16-09.27.03-540x304.jpg" alt="The Selfish Developer" width="540" height="304" class="size-large wp-image-5255" srcset="http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-16-09.27.03-540x304.jpg 540w, http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-16-09.27.03-300x169.jpg 300w, http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-16-09.27.03-768x432.jpg 768w" sizes="(max-width: 540px) 100vw, 540px" /><p class="wp-caption-text">The Selfish Developer</p></div></p>
<p>And finally Duncan explained a list of things he learned along the way.</p>
<ul>
<li>Be pragmatic</li>
<li>Don&#8217;t over-design</li>
<li>(Mostly) Don&#8217;t take anyone&#8217;s word for it</li>
<li>Strive for automation</li>
<li>Work in short iterations</li>
<li>Make mistakes!</li>
</ul>
<div id="attachment_5267" style="width: 550px" class="wp-caption aligncenter"><img src="http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-19-21.29.43-540x304.jpg" alt="I guess you had to be there, to get this reference :-)" width="540" height="304" class="size-large wp-image-5267" srcset="http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-19-21.29.43-540x304.jpg 540w, http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-19-21.29.43-300x169.jpg 300w, http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-19-21.29.43-768x432.jpg 768w" sizes="(max-width: 540px) 100vw, 540px" /><p class="wp-caption-text">I guess you had to be there, to get this reference <img src="https://s.w.org/images/core/emoji/11/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p></div>
<p>Because the venue was an old railway complex, some session were inside railway cars, like my first parallel session of day two.<br />
Luc Gorissen had an inspiring presentation about Faulthandling in ACM and BPM. It all starts with the functional design. You have to think about the happy-flow, but you should never forget what should happen when something technical (like a failing server) or something functional (incorrect zipcode or unknown user) goes wrong.<br />
Not until you combine your Fault Categories, Fault Strategy, Layering Model, Design Guidelines and Implementation Guidelines, you will get a complete Fault Handling Implementation.<br />
<div id="attachment_5260" style="width: 550px" class="wp-caption aligncenter"><img src="http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-16-10.58.07-540x304.jpg" alt="Fault Handling" width="540" height="304" class="size-large wp-image-5260" srcset="http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-16-10.58.07-540x304.jpg 540w, http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-16-10.58.07-300x169.jpg 300w, http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-16-10.58.07-768x432.jpg 768w" sizes="(max-width: 540px) 100vw, 540px" /><p class="wp-caption-text">Fault Handling</p></div></p>
<p>Next up was Xander van Rooijen of Rabobank. He showed an example of an API Management implementation.<br />
Using Apiary for the API design and API Fortress for testing, they were able to create a full API implementation on Oracle&#8217;s API Platform CS bêta environment. Now they wait for Oracle to be able to push it to production.</p>
<p>Another client story was by Froukje van der Wulp and Maarten Smeets of spir-it, the IT department of the Dutch Council of the Judiciary. They explained how spir-it has transformed it&#8217;s organization from a classic Waterfall to an Agile environment. This enabled them to tackle large performance issues in their complex applications for digitizing the Judiciary.<div id="attachment_5261" style="width: 550px" class="wp-caption aligncenter"><img src="http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-16-14.21.31-540x304.jpg" alt="Always faster" width="540" height="304" class="size-large wp-image-5261" srcset="http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-16-14.21.31-540x304.jpg 540w, http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-16-14.21.31-300x169.jpg 300w, http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-16-14.21.31-768x432.jpg 768w" sizes="(max-width: 540px) 100vw, 540px" /><p class="wp-caption-text">Always faster</p></div></p>
<p>In the last parallel track I visited a session by Robert van Mölken on Blockchain. For me a very new and unknown subject. But his session gave me insight and I learned that Blockchains are an implementation of the techniques used by Bitcoin.</p>
<p>The final word was for Lucas Jellema. In the third and last keynote he wrapped up the conference.<br />
With many salutes to audience, speakers and organizers he gave some valuable lessons. And he wasn&#8217;t afraid to disagree with some of the other speakers. As I said in the beginning of this blog, his definition of DevOps is different from the one that Maria Colgan showed. His description of a DevOps team is more practical: &#8220;You build it, you run it, you fix and evolve it&#8221;.</p>
<div id="attachment_5263" style="width: 550px" class="wp-caption aligncenter"><img src="http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-16-15.54.03-540x304.jpg" alt="We salute you!" width="540" height="304" class="size-large wp-image-5263" srcset="http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-16-15.54.03-540x304.jpg 540w, http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-16-15.54.03-300x169.jpg 300w, http://blog.whitehorses.nl/wp-content/uploads/2017/06/2017-06-16-15.54.03-768x432.jpg 768w" sizes="(max-width: 540px) 100vw, 540px" /><p class="wp-caption-text">We salute you!</p></div>
<p>Lucas&#8217; talk on bridging the gaps that exist on many levels, left the audience inspired to come back again next year. </p>
<p>If you got curious after reading this blog, please visit the <a href="https://www.nloug.nl/handouts.aspx" target="_blank">nlOUG website</a> to download handouts from the Tech Experience.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.whitehorses.nl/2017/06/19/ogh-tech-experience-2017-recap/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Building OSB 12c releases on resource level using Maven</title>
		<link>http://blog.whitehorses.nl/2017/01/12/building-osb-12c-releases-on-resource-level-using-maven/</link>
		<comments>http://blog.whitehorses.nl/2017/01/12/building-osb-12c-releases-on-resource-level-using-maven/#comments</comments>
		<pubDate>Thu, 12 Jan 2017 08:55:21 +0000</pubDate>
		<dc:creator><![CDATA[Mike Heeren]]></dc:creator>
				<category><![CDATA[Integration, SOA & BPM]]></category>
		<category><![CDATA[Oracle tools]]></category>
		<category><![CDATA[12c]]></category>
		<category><![CDATA[Archive]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[OSB]]></category>
		<category><![CDATA[Project]]></category>
		<category><![CDATA[release]]></category>
		<category><![CDATA[Resource]]></category>
		<category><![CDATA[sbar]]></category>

		<guid isPermaLink="false">http://blog.whitehorses.nl/?p=5212</guid>
		<description><![CDATA[<p>A while ago I published a Whitebook (in Dutch) about building OSB 12c releases on resource level using Maven. In the Whitebook, you could read which functionality we were missing in the regular Oracle Service Bus plugin for Maven and how we were able to create this functionality using a custom Maven plugin.</p>
]]></description>
				<content:encoded><![CDATA[<p></p><p>A while ago I published a <a href="http://www.whitehorses.nl/whitebooks/2016/osb-12c-releases-op-resource-niveau-bouwen-maven" target="_new">Whitebook</a> (in Dutch) about building OSB 12c releases on resource level using Maven. In the Whitebook, you could read which functionality we were missing in the regular Oracle Service Bus plugin for Maven and how we were able to create this functionality using a custom Maven plugin.</p>
<p>I have added the code of this custom Maven plugin to the following public repository: <a href="https://bitbucket.org/whitehorsesbv/servicebusplugin" target="_new">https://bitbucket.org/whitehorsesbv/servicebusplugin</a></p>
<h1>Used settings</h1>
<p>The custom Maven plugin has been developed and tested on multiple environments, so we can confirm that the Maven plugin is working if you are using the following version(s):</p>
<table style="width: 1241px">
<tbody>
<tr>
<td style="width: 189px"><b>Application</b></td>
<td style="width: 1042px"><b>Version</b></td>
</tr>
<tr>
<td style="width: 189px">Java</td>
<td style="width: 1042px">1.7.0_79, 1.8.0_101</td>
</tr>
<tr>
<td style="width: 189px">Maven</td>
<td style="width: 1042px">3.3.9</td>
</tr>
<tr>
<td style="width: 189px">Oracle Service Bus</td>
<td style="width: 1042px">12.1.3, 12.2.1</td>
</tr>
</tbody>
</table>
<h1>Installing the custom Maven plugin</h1>
<p>First start to install the custom Maven plugin to your local Maven repository. To do this, you can download both the JAR and the POM file from the <a href="https://bitbucket.org/whitehorsesbv/servicebusplugin/downloads" target="_new">download page of the repository</a>. After you have downloaded both files, you can execute the following commands to install it to you local Maven repository:</p>
<pre class="brush: ps">mvn install:install-file -Dfile=servicebus-plugin-1.0.jar -DgroupId=nl.whitehorses.servicebus -DartifactId=servicebus-plugin -Dversion=1.0 -Dpackaging=jar
mvn install:install-file -Dfile=servicebus-plugin-1.0.pom -DgroupId=nl.whitehorses.servicebus -DartifactId=servicebus-plugin -Dversion=1.0 -Dpackaging=pom</pre>
<pre class="brush: ps"></pre>
<h1>Building a Service Bus project on resource level</h1>
<p>Now that the custom Maven plugin is available in the Maven repository, we are able to build OSB projects using this plugin instead of the default Oracle plugin. To do so, open the <i>pom.xml</i> file in the OSB project directory. By default, the <i>pom.xml </i>file will look something like the below example:</p>
<p><strong>pom.xml</strong></p>
<pre class="brush: xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt; 
&lt;project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt; 
	&lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt; 
	&lt;parent&gt; 
		&lt;groupId&gt;com.oracle.servicebus&lt;/groupId&gt; 
		&lt;artifactId&gt;sbar-project-common&lt;/artifactId&gt; 
		&lt;version&gt;12.1.3-0-0&lt;/version&gt; 
	&lt;/parent&gt; 
	&lt;groupId&gt;nl.whitehorses&lt;/groupId&gt; 
	&lt;artifactId&gt;Employee&lt;/artifactId&gt; 
	&lt;version&gt;1.0-SNAPSHOT&lt;/version&gt; 
	&lt;packaging&gt;sbar&lt;/packaging&gt; 
	&lt;description/&gt; 
&lt;/project&gt;</pre>
<p>If we package the project into an archive using the above <i>pom.xml</i> file by executing <i>mvn</i><i> package</i> via the command line, we will get an archive that can be used to deploy the OSB project on project level to the OSB. The build archive can be found in the <i>.data/maven </i>folder within the project directory.</p>
<p>If we change the value of the <i>pom.xml</i> file to the below example, and we package the project the project using the same command, we will get an archive  which can be used to deploy on resource level via the OSB. In the below example the following files will be added to the archive:</p>
<ul>
<li>All files within the <i>Business</i> directory.</li>
<li>All files within the <i>Pipeline </i>directory, except <i>UpdateEmployee.pipeline</i>.</li>
</ul>
<p><strong>pom.xml</strong></p>
<pre class="brush: xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt; 
&lt;project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt; 
	&lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt; 
	&lt;groupId&gt;nl.whitehorses&lt;/groupId&gt; 
	&lt;artifactId&gt;Employee&lt;/artifactId&gt; 
	&lt;version&gt;1.0-SNAPSHOT&lt;/version&gt; 
	&lt;packaging&gt;sbar&lt;/packaging&gt; 
	&lt;build&gt; 
		&lt;directory&gt;${project.basedir}/.data/maven&lt;/directory&gt; 
		&lt;sourceDirectory&gt;${project.basedir}&lt;/sourceDirectory&gt; 
		&lt;resources&gt; 
			&lt;resource&gt; 
				&lt;directory&gt;${project.basedir}&lt;/directory&gt; 
			&lt;/resource&gt; 
		&lt;/resources&gt; 
		&lt;plugins&gt; 
			&lt;plugin&gt; 
				&lt;groupId&gt;nl.whitehorses.servicebus&lt;/groupId&gt; 
				&lt;artifactId&gt;servicebus-plugin&lt;/artifactId&gt; 
				&lt;version&gt;1.0&lt;/version&gt; 
				&lt;extensions&gt;true&lt;/extensions&gt; 
				&lt;configuration&gt; 
					&lt;!-- Configure the Oracle Home directory --&gt; 
					&lt;oracleHome&gt;C:\Oracle\Middleware1221\Oracle_Home&lt;/oracleHome&gt; 
					&lt;!-- Specify whether this is a system release --&gt; 
					&lt;system&gt;false&lt;/system&gt; 
					&lt;!-- Configure the export level of the release, possible values are PROJECT and RESOURCE --&gt; 
					&lt;exportLevel&gt;RESOURCE&lt;/exportLevel&gt; 
					&lt;!-- Optional parameter to specify which of the resources should be included into the archive --&gt; 
					&lt;includes&gt; 
						&lt;include&gt;**/Business/*&lt;/include&gt; 
						&lt;include&gt;**/Pipeline/*&lt;/include&gt; 
					&lt;/includes&gt; 
					&lt;!-- Optional parameter to specify which of the resources should be excluded from the archive --&gt; 
					&lt;excludes&gt; 
						&lt;exclude&gt;**/Pipeline/UpdateEmployee.pipeline&lt;/exclude&gt; 
					&lt;/excludes&gt; 
				&lt;/configuration&gt; 
			&lt;/plugin&gt; 
		&lt;/plugins&gt; 
	&lt;/build&gt; 
&lt;/project&gt;</pre>
<p><span class="TextRun SCX120136446" lang="EN-US" xml:lang="EN-US"><span class="NormalTextRun SCX120136446">Instead of using the </span></span><em><span class="TextRun SCX120136446" lang="EN-US" xml:lang="EN-US"><span class="NormalTextRun SCX120136446">includes</span></span></em><span class="TextRun SCX120136446" lang="EN-US" xml:lang="EN-US"><span class="NormalTextRun SCX120136446"> and </span></span><em><span class="TextRun SCX120136446" lang="EN-US" xml:lang="EN-US"><span class="NormalTextRun SCX120136446">excludes</span></span></em><span class="TextRun SCX120136446" lang="EN-US" xml:lang="EN-US"><span class="NormalTextRun SCX120136446"> tags, we can also add a </span></span><em><span class="TextRun SCX120136446" lang="EN-US" xml:lang="EN-US"><span class="NormalTextRun SCX120136446">resources</span></span></em><span class="TextRun SCX120136446" lang="EN-US" xml:lang="EN-US"><span class="NormalTextRun SCX120136446"> tag to the </span></span><em><span class="TextRun SCX120136446" lang="EN-US" xml:lang="EN-US"><span class="NormalTextRun SCX120136446">pom.xml</span></span></em><span class="TextRun SCX120136446" lang="EN-US" xml:lang="EN-US"><span class="NormalTextRun SCX120136446"> file, which points towards a configuration file. </span></span><span class="TextRun SCX120136446" lang="EN-US" xml:lang="EN-US"><span class="NormalTextRun SCX120136446">This can be used to specify which files need to be included and excluded. For example, the below files will result in exactly the same archive as we would get using the </span></span><span class="TextRun SCX120136446" lang="EN-US" xml:lang="EN-US"><span class="NormalTextRun SCX120136446"><em>includes</em> </span></span><span class="TextRun SCX120136446" lang="EN-US" xml:lang="EN-US"><span class="NormalTextRun SCX120136446">and </span></span><em><span class="TextRun SCX120136446" lang="EN-US" xml:lang="EN-US"><span class="NormalTextRun SCX120136446">excludes</span></span></em><span class="TextRun SCX120136446" lang="EN-US" xml:lang="EN-US"><span class="NormalTextRun SCX120136446"> tags:</span></span><span class="EOP SCX120136446"> </span></p>
<p><strong>pom.xml</strong></p>
<pre class="brush: xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt; 
&lt;project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt; 
	&lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt; 
	&lt;groupId&gt;nl.whitehorses&lt;/groupId&gt; 
	&lt;artifactId&gt;Employee&lt;/artifactId&gt; 
	&lt;version&gt;1.0-SNAPSHOT&lt;/version&gt; 
	&lt;packaging&gt;sbar&lt;/packaging&gt; 
	&lt;build&gt; 
		&lt;directory&gt;${project.basedir}/.data/maven&lt;/directory&gt; 
		&lt;sourceDirectory&gt;${project.basedir}&lt;/sourceDirectory&gt; 
		&lt;resources&gt; 
			&lt;resource&gt; 
				&lt;directory&gt;${project.basedir}&lt;/directory&gt; 
			&lt;/resource&gt; 
		&lt;/resources&gt; 
		&lt;plugins&gt; 
			&lt;plugin&gt; 
				&lt;groupId&gt;nl.whitehorses.servicebus&lt;/groupId&gt; 
				&lt;artifactId&gt;servicebus-plugin&lt;/artifactId&gt; 
				&lt;version&gt;1.0&lt;/version&gt; 
				&lt;extensions&gt;true&lt;/extensions&gt; 
				&lt;configuration&gt; 
					&lt;!-- Configure the Oracle Home directory --&gt; 
					&lt;oracleHome&gt;C:\Oracle\Middleware1221\Oracle_Home&lt;/oracleHome&gt; 
					&lt;!-- Specify whether this is a system release --&gt; 
					&lt;system&gt;false&lt;/system&gt; 
					&lt;!-- Configure the export level of the release, possible values are PROJECT and RESOURCE --&gt; 
					&lt;exportLevel&gt;RESOURCE&lt;/exportLevel&gt; 
					&lt;!-- Optional parameter to specify which of the resources should be included into and excluded from the archive --&gt; 
					&lt;resources&gt;C:\JDeveloper\mywork\Whitehorses\Employee\archiveResources.xml&lt;/resources&gt; 
				&lt;/configuration&gt; 
			&lt;/plugin&gt; 
		&lt;/plugins&gt; 
	&lt;/build&gt; 
&lt;/project&gt;</pre>
<p><strong>archiveResources.xml</strong></p>
<pre class="brush: xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt; 
&lt;resources&gt; 
	&lt;!-- Optional parameter to specify which of the resources should be included into the archive --&gt; 
	&lt;includes&gt; 
		&lt;include&gt;**/Business/*&lt;/include&gt; 
		&lt;include&gt;**/Pipeline/*&lt;/include&gt; 
	&lt;/includes&gt; 
	&lt;!-- Optional parameter to specify which of the resources should be excluded from the archive --&gt; 
	&lt;excludes&gt; 
		&lt;exclude&gt;**/Pipeline/UpdateEmployee.pipeline&lt;/exclude&gt; 
	&lt;/excludes&gt; 
&lt;/resources&gt;</pre>
<h1>Adding an Assembly project to add multiple projects to single archive</h1>
<p>The final step of creating full OSB release archives on resource level, was that we wanted to add multiple projects to a single archive. We achieved this by first building every OSB project separately, and later build an Assembly application which combines all projects into a single archive file. To do this, we use the parent <i>pom.xml</i> file to build all projects (including the <i>assembly</i> project). It is important that the <i>assembly </i>project is build last.</p>
<p>The parent <i>pom.xml </i>file, which will build every project, including the assembly project, will look something like the below example:</p>
<p><strong>pom.xml</strong></p>
<pre class="brush: xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt; 
&lt;project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt; 
	&lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt; 
	&lt;groupId&gt;nl.whitehorses&lt;/groupId&gt; 
	&lt;artifactId&gt;Whitehorses&lt;/artifactId&gt; 
	&lt;version&gt;1.0-SNAPSHOT&lt;/version&gt; 
	&lt;packaging&gt;pom&lt;/packaging&gt; 
	&lt;modules&gt; 
		&lt;!-- All OSB projects --&gt; 
		&lt;module&gt;Clockwise&lt;/module&gt; 
		&lt;module&gt;Employee&lt;/module&gt; 
		&lt;module&gt;Office&lt;/module&gt; 
		&lt;!-- Assembly project --&gt; 
		&lt;module&gt;Assembly&lt;/module&gt; 
	&lt;/modules&gt; 
&lt;/project&gt;</pre>
<p><span class="TextRun SCX255205017" lang="EN-US" xml:lang="EN-US"><span class="NormalTextRun SCX255205017">The </span></span><em><span class="TextRun SCX255205017" lang="EN-US" xml:lang="EN-US"><span class="NormalTextRun SCX255205017">pom.xml</span></span></em><span class="TextRun SCX255205017" lang="EN-US" xml:lang="EN-US"><span class="NormalTextRun SCX255205017"><em> </em>file of the Assembly project will look </span></span><span class="TextRun SCX255205017" lang="EN-US" xml:lang="EN-US"><span class="NormalTextRun SCX255205017">like the below example. It is important that if you add new projects, you don&#8217;t only add them to the parent </span></span><em><span class="TextRun SCX255205017" lang="EN-US" xml:lang="EN-US"><span class="NormalTextRun SCX255205017">pom.xml </span></span></em><span class="TextRun SCX255205017" lang="EN-US" xml:lang="EN-US"><span class="NormalTextRun SCX255205017">file, but you also add them as a dependency to the Assembly project.</span></span><span class="EOP SCX255205017"> </span></p>
<p><strong>pom.xml</strong></p>
<pre class="brush: xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt; 
&lt;project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt; 
	&lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt; 
	&lt;groupId&gt;nl.whitehorses&lt;/groupId&gt; 
	&lt;artifactId&gt;Assembly&lt;/artifactId&gt; 
	&lt;version&gt;1.0-SNAPSHOT&lt;/version&gt; 
	&lt;dependencies&gt; 
		&lt;dependency&gt; 
			&lt;groupId&gt;nl.whitehorses&lt;/groupId&gt; 
			&lt;artifactId&gt;Clockwise&lt;/artifactId&gt; 
			&lt;version&gt;1.0-SNAPSHOT&lt;/version&gt; 
			&lt;type&gt;sbar&lt;/type&gt; 
		&lt;/dependency&gt; 
		&lt;dependency&gt; 
			&lt;groupId&gt;nl.whitehorses&lt;/groupId&gt; 
			&lt;artifactId&gt;Employee&lt;/artifactId&gt; 
			&lt;version&gt;1.0-SNAPSHOT&lt;/version&gt; 
			&lt;type&gt;sbar&lt;/type&gt; 
		&lt;/dependency&gt; 
		&lt;dependency&gt; 
			&lt;groupId&gt;nl.whitehorses&lt;/groupId&gt; 
			&lt;artifactId&gt;Office&lt;/artifactId&gt; 
			&lt;version&gt;1.0-SNAPSHOT&lt;/version&gt; 
			&lt;type&gt;sbar&lt;/type&gt; 
		&lt;/dependency&gt; 
	&lt;/dependencies&gt; 
	&lt;build&gt; 
		&lt;finalName&gt;sbconfig_${project.version}&lt;/finalName&gt; 
		&lt;plugins&gt; 
			&lt;plugin&gt; 
				&lt;artifactId&gt;maven-jar-plugin&lt;/artifactId&gt; 
				&lt;version&gt;2.6&lt;/version&gt; 
				&lt;executions&gt; 
					&lt;execution&gt; 
						&lt;id&gt;default-jar&lt;/id&gt; 
						&lt;phase&gt;never&lt;/phase&gt; 
					&lt;/execution&gt; 
				&lt;/executions&gt; 
			&lt;/plugin&gt; 
			&lt;plugin&gt; 
				&lt;artifactId&gt;maven-assembly-plugin&lt;/artifactId&gt; 
				&lt;version&gt;2.6&lt;/version&gt; 
				&lt;configuration&gt; 
					&lt;appendAssemblyId&gt;false&lt;/appendAssemblyId&gt; 
					&lt;descriptors&gt; 
						&lt;descriptor&gt;${basedir}/src/main/assembly/assembly.xml&lt;/descriptor&gt; 
					&lt;/descriptors&gt; 
				&lt;/configuration&gt; 
				&lt;dependencies&gt; 
					&lt;dependency&gt; 
						&lt;groupId&gt;nl.whitehorses.servicebus&lt;/groupId&gt; 
						&lt;artifactId&gt;servicebus-plugin&lt;/artifactId&gt; 
						&lt;version&gt;1.0&lt;/version&gt; 
					&lt;/dependency&gt; 
				&lt;/dependencies&gt; 
				&lt;executions&gt; 
					&lt;execution&gt; 
						&lt;id&gt;make-assembly&lt;/id&gt; 
						&lt;phase&gt;package&lt;/phase&gt; 
						&lt;goals&gt; 
							&lt;goal&gt;single&lt;/goal&gt; 
						&lt;/goals&gt; 
					&lt;/execution&gt; 
				&lt;/executions&gt; 
			&lt;/plugin&gt; 
		&lt;/plugins&gt; 
	&lt;/build&gt; 
&lt;/project&gt;</pre>
<p><span class="TextRun SCX236312442" lang="EN-US" xml:lang="EN-US"><span class="NormalTextRun SCX236312442">This </span></span><em><span class="TextRun SCX236312442" lang="EN-US" xml:lang="EN-US"><span class="NormalTextRun SCX236312442">pom.xml </span></span></em><span class="TextRun SCX236312442" lang="EN-US" xml:lang="EN-US"><span class="NormalTextRun SCX236312442">file also points to an </span></span><em><span class="TextRun SCX236312442" lang="EN-US" xml:lang="EN-US"><span class="NormalTextRun SCX236312442">assembly.xml</span></span></em><span class="TextRun SCX236312442" lang="EN-US" xml:lang="EN-US"><span class="NormalTextRun SCX236312442"> file, which contains some configuration about how the Assembly archive should be build </span></span><span class="TextRun SCX236312442" lang="EN-US" xml:lang="EN-US"><span class="SpellingError SCX236312442">bij</span></span><span class="TextRun SCX236312442" lang="EN-US" xml:lang="EN-US"><span class="NormalTextRun SCX236312442"> the Maven assembly plugin. This </span></span><em><span class="TextRun SCX236312442" lang="EN-US" xml:lang="EN-US"><span class="NormalTextRun SCX236312442">assembly.xml</span></span><span class="TextRun SCX236312442" lang="EN-US" xml:lang="EN-US"><span class="NormalTextRun SCX236312442"> </span></span></em><span class="TextRun SCX236312442" lang="EN-US" xml:lang="EN-US"><span class="NormalTextRun SCX236312442">fil</span></span><span class="TextRun SCX236312442" lang="EN-US" xml:lang="EN-US"><span class="NormalTextRun SCX236312442">e should look like the below example:</span></span><span class="EOP SCX236312442"> </span></p>
<p><strong>assembly.xml</strong></p>
<pre class="brush: xml">&lt;assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd"&gt; 
	&lt;id&gt;src&lt;/id&gt; 
	&lt;formats&gt; 
		&lt;format&gt;sbar&lt;/format&gt; 
	&lt;/formats&gt; 
	&lt;includeBaseDirectory&gt;false&lt;/includeBaseDirectory&gt; 
	&lt;dependencySets&gt; 
		&lt;dependencySet&gt; 
			&lt;outputDirectory&gt;/&lt;/outputDirectory&gt; 
			&lt;unpack&gt;true&lt;/unpack&gt; 
		&lt;/dependencySet&gt; 
	&lt;/dependencySets&gt; 
&lt;/assembly&gt;</pre>
<p>If you navigate to the directory which contains the parent <i>pom.xml</i> file, and you execute <i>mvn</i> <i>install</i> via the command line, the OSB release will be build.</p>
<p>For a working example of the above, please download: <a href="http://blog.whitehorses.nl/wp-content/uploads/2017/01/Building-OSB-12c-releases-on-resource-level-using-Maven.zip">Building-OSB-12c-releases-on-resource-level-using-Maven.zip</a></p>
<h1>Deploying the archive via Maven</h1>
<p>It is also possible to deploy the generated (Assembly) archive directly to an OSB server via the Maven plugin. To achieve this, we should add the <em>deploy-assembly</em> goal of the custom Maven plugin to the desired Maven phase. We chose the <em>pre-integration-test</em> phase for deploying the archive to the OSB server. The <em>pom.xml</em> file in the Assembly project can be updated like the below example to connect the Maven <em>pre-integration-test</em> phase to the <em>deploy-assembly </em>goal of the Maven plugin:</p>
<pre class="brush: xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt; 
&lt;project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt; 
	&lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt; 
	&lt;groupId&gt;nl.whitehorses&lt;/groupId&gt; 
	&lt;artifactId&gt;Assembly&lt;/artifactId&gt; 
	&lt;version&gt;1.0-SNAPSHOT&lt;/version&gt; 
	&lt;dependencies&gt; 
		&lt;dependency&gt; 
			&lt;groupId&gt;nl.whitehorses&lt;/groupId&gt; 
			&lt;artifactId&gt;Clockwise&lt;/artifactId&gt; 
			&lt;version&gt;1.0-SNAPSHOT&lt;/version&gt; 
			&lt;type&gt;sbar&lt;/type&gt; 
		&lt;/dependency&gt; 
		&lt;dependency&gt; 
			&lt;groupId&gt;nl.whitehorses&lt;/groupId&gt; 
			&lt;artifactId&gt;Employee&lt;/artifactId&gt; 
			&lt;version&gt;1.0-SNAPSHOT&lt;/version&gt; 
			&lt;type&gt;sbar&lt;/type&gt; 
		&lt;/dependency&gt; 
		&lt;dependency&gt; 
			&lt;groupId&gt;nl.whitehorses&lt;/groupId&gt; 
			&lt;artifactId&gt;Office&lt;/artifactId&gt; 
			&lt;version&gt;1.0-SNAPSHOT&lt;/version&gt; 
			&lt;type&gt;sbar&lt;/type&gt; 
		&lt;/dependency&gt; 
	&lt;/dependencies&gt; 
	&lt;build&gt; 
		&lt;finalName&gt;sbconfig_${project.version}&lt;/finalName&gt; 
		&lt;plugins&gt; 
			&lt;plugin&gt; 
				&lt;artifactId&gt;maven-jar-plugin&lt;/artifactId&gt; 
				&lt;version&gt;2.6&lt;/version&gt; 
				&lt;executions&gt; 
					&lt;execution&gt; 
						&lt;id&gt;default-jar&lt;/id&gt; 
						&lt;phase&gt;never&lt;/phase&gt; 
					&lt;/execution&gt; 
				&lt;/executions&gt; 
			&lt;/plugin&gt; 
			&lt;plugin&gt; 
				&lt;artifactId&gt;maven-assembly-plugin&lt;/artifactId&gt; 
				&lt;version&gt;2.6&lt;/version&gt; 
				&lt;configuration&gt; 
					&lt;appendAssemblyId&gt;false&lt;/appendAssemblyId&gt; 
					&lt;descriptors&gt; 
						&lt;descriptor&gt;${basedir}/src/main/assembly/assembly.xml&lt;/descriptor&gt; 
					&lt;/descriptors&gt; 
				&lt;/configuration&gt; 
				&lt;dependencies&gt; 
					&lt;dependency&gt; 
						&lt;groupId&gt;nl.whitehorses.servicebus&lt;/groupId&gt; 
						&lt;artifactId&gt;servicebus-plugin&lt;/artifactId&gt; 
						&lt;version&gt;1.0&lt;/version&gt; 
					&lt;/dependency&gt; 
				&lt;/dependencies&gt; 
				&lt;executions&gt; 
					&lt;execution&gt; 
						&lt;id&gt;make-assembly&lt;/id&gt; 
						&lt;phase&gt;package&lt;/phase&gt; 
						&lt;goals&gt; 
							&lt;goal&gt;single&lt;/goal&gt; 
						&lt;/goals&gt; 
					&lt;/execution&gt; 
				&lt;/executions&gt; 
			&lt;/plugin&gt;
			&lt;plugin&gt;
				&lt;groupId&gt;nl.whitehorses.servicebus&lt;/groupId&gt; 
				&lt;artifactId&gt;servicebus-plugin&lt;/artifactId&gt; 
				&lt;version&gt;1.0&lt;/version&gt; 
				&lt;executions&gt;
					&lt;execution&gt;
						&lt;id&gt;deploy-assembly&lt;/id&gt;
						&lt;phase&gt;pre-integration-test&lt;/phase&gt;
						&lt;goals&gt;
							&lt;goal&gt;deploy-assembly&lt;/goal&gt;
						&lt;/goals&gt;
					&lt;/execution&gt;
				&lt;/executions&gt;
			&lt;/plugin&gt;
		&lt;/plugins&gt; 
	&lt;/build&gt; 
&lt;/project&gt;</pre>
<p>If we navigate to the directory containing the parent <em>pom.xml</em> file again, we will be able to deploy the release to the OSB server by executing the <em>mvn pre-integration-test </em>statement. The following parameters must/can be added to this command:</p>
<table style="width: 594px">
<tbody>
<tr style="height: 24px">
<td style="width: 354px;height: 24px"><strong>Parameter</strong></td>
<td style="width: 100px;height: 24px"><strong>Required?</strong></td>
<td style="width: 138px;height: 24px"><strong>Default value</strong></td>
</tr>
<tr style="height: 24px">
<td style="width: 354px;height: 24px">-Dserver.url</td>
<td style="width: 100px;height: 24px">Yes</td>
<td style="width: 138px;height: 24px">&#8211;</td>
</tr>
<tr style="height: 24px">
<td style="width: 354px;height: 24px">-Dserver.username</td>
<td style="width: 100px;height: 24px">Yes</td>
<td style="width: 138px;height: 24px">&#8211;</td>
</tr>
<tr style="height: 24px">
<td style="width: 354px;height: 24px">-Dserver.password</td>
<td style="width: 100px;height: 24px">Yes</td>
<td style="width: 138px;height: 24px">&#8211;</td>
</tr>
<tr style="height: 24px">
<td style="width: 354px;height: 24px">-Ddeployment.preserve.credentials</td>
<td style="width: 100px;height: 24px">&#8211;</td>
<td style="width: 138px;height: 24px">true</td>
</tr>
<tr style="height: 24px">
<td style="width: 354px;height: 24px">-Ddeployment.preserve.envValues</td>
<td style="width: 100px;height: 24px">&#8211;</td>
<td style="width: 138px;height: 24px">true</td>
</tr>
<tr style="height: 24.375px">
<td style="width: 354px;height: 24.375px">-Ddeployment.preserve.operationalValues</td>
<td style="width: 100px;height: 24.375px">&#8211;</td>
<td style="width: 138px;height: 24.375px">true</td>
</tr>
<tr style="height: 24px">
<td style="width: 354px;height: 24px">-Ddeployment.preserve.securityAndPolicyConfig</td>
<td style="width: 100px;height: 24px">&#8211;</td>
<td style="width: 138px;height: 24px">true</td>
</tr>
<tr style="height: 24px">
<td style="width: 354px;height: 24px">-Ddeployment.preserve.accessControlPolicies</td>
<td style="width: 100px;height: 24px">&#8211;</td>
<td style="width: 138px;height: 24px">true</td>
</tr>
<tr style="height: 24px">
<td style="width: 354px;height: 24px">-Ddeployment.customization.file</td>
<td style="width: 100px;height: 24px">No</td>
<td style="width: 138px;height: 24px">&#8211;</td>
</tr>
<tr style="height: 24px">
<td style="width: 354px;height: 24px">-Ddeployment.session.activate</td>
<td style="width: 100px;height: 24px">&#8211;</td>
<td style="width: 138px;height: 24px">true</td>
</tr>
<tr style="height: 24px">
<td style="width: 354px;height: 24px">-Ddeployment.session.discardOnError</td>
<td style="width: 100px;height: 24px">&#8211;</td>
<td style="width: 138px;height: 24px">true</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>These settings represent the &#8220;Advanced Settings&#8221; when manually uploading an archive via the servicebus console.</p>
<p><img class="alignnone wp-image-5226 size-large" src="http://blog.whitehorses.nl/wp-content/uploads/2017/01/OSB_Advanced_Settings-400x400.png" width="400" height="400" srcset="http://blog.whitehorses.nl/wp-content/uploads/2017/01/OSB_Advanced_Settings-400x400.png 400w, http://blog.whitehorses.nl/wp-content/uploads/2017/01/OSB_Advanced_Settings-150x150.png 150w, http://blog.whitehorses.nl/wp-content/uploads/2017/01/OSB_Advanced_Settings-300x300.png 300w, http://blog.whitehorses.nl/wp-content/uploads/2017/01/OSB_Advanced_Settings.png 624w" sizes="(max-width: 400px) 100vw, 400px" /></p>
<p>Good luck building your OSB releases on resouce level using Maven!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.whitehorses.nl/2017/01/12/building-osb-12c-releases-on-resource-level-using-maven/feed/</wfw:commentRss>
		<slash:comments>64</slash:comments>
		</item>
	</channel>
</rss>
