Friday 14 September 2018

Upgrade SOA 11g to 12c: Invalid Composite File

You might not get it, but not every customer already moved from SOA Suite 11g to 12c. My current customer isn't for instance. Because we're in a bit of a lee period, I'm looking into upgrading their composite projects.

Solve invalid composite files

One thing I ran into quite immediately is that for several projects the composite.xml was invalid. It turned out that it wasn't even upgraded.

I found this support.oracle.com article, DocID 2333742.1. It says that it's not a bug. Because the problem is in the 11g project. Now, we could discus about it, since the 11g project works, and might have been upgraded from an earlier version (10g or early 11g patchset). So, the upgrade process could have been improved. Well the solution is however quite simple.

According to the support note, the .jpr file lacks several elements. A closer look brought me the idea that it could be narrowed down to only one element:
<hash n="oracle.ide.model.TechnologyScopeConfiguration">
  <list n="technologyScope">
    <string v="SOA"/>
  </list>
</hash>
In other words, the project lacks the Techonlogy scope SOA. Apparently Oracle changed the Integration technology in SOA down the product evolution (No bug, but it would be nice that the upgrade process would take this into account). Because of this, the composite is not upgraded.

Changing every one of the tens or hundreds of composite projects can be a tedious job. And I figured that it wouldn't be the only one problem I will run into.

Luckily, the .jpr file is an XML file. So, with an xslt file we could pre-upgrade the .jpr file. So, based on this example, I created the following prepareJpr.xsl stylesheet:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <!-- Update JPR 
  @Author: M. van den Akker, Darwin-IT Professionals, 2018-09-12
  Based on: https://stackoverflow.com/questions/5876382/using-xslt-to-copy-all-nodes-in-xml-with-support-for-special-cases#5877772
  -->
  <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
  <!-- Check Existence of SOA technology, because of Invalid composite file exceptions. MOS DocId 2333742.1-->
  <xsl:template match="hash[@n='oracle.ide.model.TechnologyScopeConfiguration']/list[@n='technologyScope']">  
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
            <!--If SOA doesn't exist then add it -->
            <xsl:choose>
        <xsl:when test="count(./string[@v='SOA'])=0">
            <xsl:comment>Add SOA technology</xsl:comment> 
            <string v="SOA"/>
            </xsl:when>
        <xsl:otherwise><xsl:comment>SOA technology already present </xsl:comment> 
            </xsl:otherwise>
      </xsl:choose>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

If the technology scope does not exist, it adds it with a comment to denote it was added by this utility. If it does not exist, I add a comment to denote that, to be sure that the xslt works and that the project have been handled, but considered ok.

Then I created an prepareSOA11gApplication.xml ANT project that loops over the projects in the target application folder and runs the XSLT over every .jpr file in the application.

It looks like something as follows (since I added some other functionality that I removed for this article):
<?xml version="1.0" encoding="windows-1252" ?>
<!--Ant buildfile generated by Oracle JDeveloper-->
<!--Generated Sep 12, 2018 3:06:25 PM-->
<project xmlns="antlib:org.apache.tools.ant" name="Prepare11gProjects" default="prepareApplication" basedir=".">
  <property file="build.properties"/>
  <taskdef resource="net/sf/antcontrib/antlib.xml">
    <classpath>
      <pathelement location="${ant-contrib.jar}"/>
    </classpath>
  </taskdef>
  <target name="prepareApplication" description="Refactor SOA 11g Project pre upgrade to 12c." depends="">
    <echo>Prepare ${SOA11gAppName} in ${SOA11gAppFolder} </echo>
    <echo>. Prepare projects</echo>
    <foreach target="PrepareProjectFile" param="projectFile">
      <fileset dir="${SOA11gAppFolder}" casesensitive="yes">
        <include name="**/*.jpr"/>
      </fileset>
    </foreach>
  </target>
  <target name="PrepareProjectFile">
    <echo message=".. Prepare ${projectFile}"></echo>
    <property name="projectFileOrg" value="${projectFile}.org"/>
    <echo message="... backup ${projectFile} to ${projectFileOrg}"></echo>
    <move file="${projectFile}" tofile="${projectFileOrg}" overwrite="false"/>
    <echo message="... transform ${projectFileOrg} to ${projectFile} using ${prepareJprXsl}"></echo>
    <xslt style="${prepareJprXsl}" in="${projectFile}.org" out="${projectFile}"/>
  </target>
</project>
I also added functionality to add the projects in a emptied .jws file, and to add a adf-config.xml file.
That way, I get a prepared pre-upgraded workspace that contains only the projects I want to upgrade at that time.

Adapt .jca files

Another type of files that I encountered to be invalid after upgrade, are .jca files. Some projects showed invalid JCA adapters in the composite.
It turns out that Oracle also changed the adapter names in the jca files. A .jca  file starts with:
<adapter-config name="dbDatabaseAdapterService" adapter="db" wsdlLocation="../WSDLs/dbDatabaseAdapterService.wsdl" xmlns="http://platform.integration.oracle/blocks/adapter/fw/metadata">

But in some files this line reads:
<adapter-config name="dbDatabaseAdapterService" adapter="DB Adapter" wsdlLocation="../WSDLs/dbDatabaseAdapterService.wsdl" xmlns="http://platform.integration.oracle/blocks/adapter/fw/metadata">

So, I need a similar XSLT file, that adapts these attributes. For other adapters changes would be:
  • AQ Adapter: aq
  • Apps Adapter: apps
  • etc.
I would rule out that I need other adaptions too.


No comments :