Seamless source “migration” from SOA Suite 12.1.3 to 12.2.1 using WLST and XSLT

1

When you migrate sources from SOA Suite 12.1.3 to SOA Suite 12.2.1, the only change I’ve seen JDeveloper do to the (SCA and Service Bus) code is updating versions in the pom.xml files from 12.1.3 to 12.2.1 (and some changes to jws and jpr files). Service Bus 12.2.1 has some build difficulties when using Maven. See Oracle Support: “OSB 12.2.1 Maven plugin error, ‘Could not find artifact com.oracle.servicebus:sbar-project-common:pom’ (Doc ID 2100799.1)”. Oracle suggests updating the pom.xml of the project, changing the packaging type from sbar to jar and removing the reference to the parent project. This however will not help you because the created jar file does not have the structure required of Service Bus resources to be imported. To deploy Service Bus with Maven I’ve used the 12.1.3 plugin to create the sbar and a custom WLST file to do the actual deployment of this sbar to a 12.2.1 environment. A similar solution is described here.

Updates to the pom files can easily be automated as part of a build pipeline. This allows you to develop 12.1.3 code and automate the migration to 12.2.1. This can be useful if you want to avoid keeping separate 12.1.3 and 12.2.1 versions of your sources during a gradual migration. You can do bug fixes on the 12.1.3 sources and compile/deploy to production (usually production is the last environment to be upgraded) and use the same pipeline to compile and deploy the same sources (using altered pom files) to a 12.2.1 environment.


In order to achieve this I’ve created a WLST script to use XSLT transformations to update the pom files. For composites and Service Bus the transformation to get from 12.1.3 to a working 12.2.1 project is slightly different. You can expand this to also update the group Id for your artifact repository to keep the 12.1.3 and 12.2.1 code separated there also. The transform.py file which is provided in this blog can be used to do other XSLT transformations from WLST also.

WLST

The WLST file (transform.py):
Usage: transform.py -parameter=value [stylesheetfile] [inputfile] [outputfile]

If you do not specify an outputfile, the output is send to the console. If you do not specify an inputfile, the console is used as input. You can specify XSLT parameters which will be used in the transformation. I’ve taken the sample code to do the XSLT transformation in WLST from here and expanded it. When using WLST to execute the script and pipe it to a file (not specifying an outputfile) do mind that you will get “Initializing WebLogic Scripting Tool (WLST) …” and such above your actual script output.

import sys
 
from java.io import FileReader, PrintWriter
from java.lang import System
from javax.xml.transform import TransformerFactory, Transformer
from javax.xml.transform.stream import StreamSource, StreamResult

def transform(source, stylesheet, result, parameters):
    transformer = TransformerFactory.newInstance().newTransformer(stylesheet)
    for (p, v) in parameters: transformer.setParameter(p, v)
    transformer.transform(source, result)
 
args = sys.argv[1:]
parameters = []
while args and args[0].startswith('-'):
   try:
       i = args[0].index('=')
   except ValueError:
       parameters.append((args[0], ""))
   else:
       parameters.append((args[0][1:i], args[0][i+1:]))
   args = args[1:]
   
if len(args) == 1: source = StreamSource(System.in)
elif len(args) >= 2: source = StreamSource(FileReader(args[1]))
else: raise "Usage:  transform.py -parameter=value [stylesheetfile] [inputfile] [outputfile]"

if len(args) == 3: output = args[2]
else: output = ""
 
stylesheet = StreamSource(FileReader(args[0]))
if len(output) == 0:
	result = StreamResult(PrintWriter(System.out))
else:
	result = StreamResult(FileWriter(File(output)))
 
transform(source, stylesheet, result, parameters)
 
stylesheet.reader.close()
source.reader and source.reader.close()
result.writer.close()

XSLT

The transformation for SCA project pom files (migratesca.xsl):

<xsl:stylesheet
    version="1.0"
    xmlns:src="http://maven.apache.org/POM/4.0.0" 
    xmlns="http://maven.apache.org/POM/4.0.0"   
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:namespace-alias stylesheet-prefix="src" result-prefix=""/>

	<xsl:template match="/src:project/src:parent/src:version">
		<src:version>12.2.1-0-0</src:version>
	</xsl:template>

	<xsl:template match="/src:project/src:groupId">
		<src:groupId>
			<xsl:call-template name="string-replace-all">
				<xsl:with-param name="text" select="." />
				<xsl:with-param name="replace" select="'oldgroupid'" />
				<xsl:with-param name="by" select="'newgroupid'" />
			</xsl:call-template>
		</src:groupId>
	</xsl:template>

	<xsl:template match="/src:project/src:build/src:plugins/src:plugin[src:groupId='com.oracle.soa.plugin']/src:version">
		<src:version>12.2.1-0-0</src:version>
	</xsl:template>

	<xsl:template match="@*|node()">
		<xsl:copy>
			<xsl:apply-templates select="@*|node()"/>
		</xsl:copy>
	</xsl:template>
<!-- below for Java embedding in BPEL processes -->
	<xsl:template match="/src:project/src:build/src:plugins/src:plugin[src:groupId='com.oracle.soa.plugin']">
		<xsl:copy>
			<xsl:apply-templates select="node()|@*"/>
			<xsl:if test="not(src:dependencies)">
				<dependencies>
					<dependency>
						<groupId>javax.el</groupId>
						<artifactId>javax.el-api</artifactId>
						<version>3.0.0</version>
					</dependency>
				</dependencies>
			</xsl:if>
		</xsl:copy>
	</xsl:template>

	<xsl:template name="string-replace-all">
		<xsl:param name="text" />
		<xsl:param name="replace" />
		<xsl:param name="by" />
		<xsl:choose>
			<xsl:when test="$text = '' or $replace = ''or not($replace)" >
				<!-- Prevent this routine from hanging -->
				<xsl:value-of select="$text" />
			</xsl:when>
			<xsl:when test="contains($text, $replace)">
				<xsl:value-of select="substring-before($text,$replace)" />
				<xsl:value-of select="$by" />
				<xsl:call-template name="string-replace-all">
					<xsl:with-param name="text" select="substring-after($text,$replace)" />
					<xsl:with-param name="replace" select="$replace" />
					<xsl:with-param name="by" select="$by" />
				</xsl:call-template>
			</xsl:when>
			<xsl:otherwise>
				<xsl:value-of select="$text" />
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
</xsl:stylesheet>

The transformation for Service Bus pom files (migratesb.xsl):

<xsl:stylesheet
    version="1.0"
    xmlns:src="http://maven.apache.org/POM/4.0.0" 
    xmlns="http://maven.apache.org/POM/4.0.0"   
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:namespace-alias stylesheet-prefix="src" result-prefix=""/>
<!--
	if you want to remove the parent
	<xsl:template match="/src:project/src:parent"/>
-->
	
	<xsl:template match="/src:project/src:groupId">
		<src:groupId>
			<xsl:call-template name="string-replace-all">
				<xsl:with-param name="text" select="." />
				<xsl:with-param name="replace" select="'oldgroupid'" />
				<xsl:with-param name="by" select="'newgroupid'" />
			</xsl:call-template>
		</src:groupId>
	</xsl:template>
<!--
	if you want to change the packaging
	<xsl:template match="/src:project/src:packaging[text()='sbar']">
		<src:packaging>jar</src:packaging>
	</xsl:template>
-->
	<xsl:template match="@*|node()">
		<xsl:copy>
			<xsl:apply-templates select="@*|node()"/>
		</xsl:copy>
	</xsl:template>

	<xsl:template name="string-replace-all">
		<xsl:param name="text" />
		<xsl:param name="replace" />
		<xsl:param name="by" />
		<xsl:choose>
			<xsl:when test="$text = '' or $replace = ''or not($replace)" >
				<xsl:value-of select="$text" />
			</xsl:when>
			<xsl:when test="contains($text, $replace)">
				<xsl:value-of select="substring-before($text,$replace)" />
				<xsl:value-of select="$by" />
				<xsl:call-template name="string-replace-all">
					<xsl:with-param name="text" select="substring-after($text,$replace)" />
					<xsl:with-param name="replace" select="$replace" />
					<xsl:with-param name="by" select="$by" />
				</xsl:call-template>
			</xsl:when>
			<xsl:otherwise>
				<xsl:value-of select="$text" />
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>	

</xsl:stylesheet>

You can download the sources, sample pom files and a sample command-line here: https://github.com/MaartenSmeets/migrate1213to1221

About Author

Maarten is a software architect and Oracle ACE. Over the past years he has worked for numerous customers in the Netherlands in developer, analyst and architect roles on topics like software delivery, performance, security and other integration related challenges. Maarten is passionate about his job and likes to share his knowledge through publications, frequent blogging and presentations.

1 Comment

  1. I am looking for this way migrate from 12.1.3 to 12.2.1 by using WLST and XSLT now I am clear how to do. Thank You Very Much.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.