Are your SOA and BPM composite deployments ready for Continuous Delivery?

How do you automate continuous change to your environments consistently?

Consider a simple scenario. You have a Composite Application and you want to deploy it from Development/CI through to Production. Oracle provide a useful Apache Ant script for doing automated deployment of Composites with relative ease.

Now let's consider the fact that multiple revisions of a single BPM or SOA Composite Application can be deployed side-by-side. You may choose for each change to be a new revision or for only major and breaking changes to be a new revision. Either way, your automation will probably need to consider retirement of Composite Application revisions over time. After all, you don't want to have unused Composite Revisions hanging around in your Platform doing nothing but adding overhead.

Of course, Oracle also provide an Apache Ant script for doing automated undeployment of Composites. Unfortunately, it will fail if a composite is already undeployed. But, does this matter?

For me, this matter's a lot. Let me explain and discuss some of the solutions for reliable Continuous Delivery of SOA and BPM Composites.

Don't make me think

Automation should focus on taking a desired state and applying it to a target environment rather than performing a specific task which only works under certain strict conditions. In other words, an operator shouldn't have to think too hard about whether their automated deployment is going to work, it should just work.

Idempotency

For automation to just work it should first be idempotent which means when executed with the same input more than once it should have no additional effect.

"Insanity is doing the same thing over and over again and expecting different results." - Albert Einstein

Now let's go back to our non-idempotent undeploy script. It will work the first time (provided no one has already undeployed)... but it will fail the second-time with an error stating it has already been undeployed.

Initial State before undeploy
Non-idempomentIdempotent
Action PerformedResultAction PerformedResult
Composite revision deployed Undeployed SUCCESS Undeployed SUCCESS
Composite revision has already been manually undeployed Failed due to previous undeploy FAIL Skipped undeploy SUCCESS
Composite removal happened in the last release Failed due to previous undeploy FAIL Skipped undeploy SUCCESS
Composite revision was never promoted to this enironment in the first place Failed due to composite not existing FAIL Skipped undeploy SUCCESS

Automation should not require human intervention for decisions it could safely make on its own

Your automated deployment should be part of a single automated release process so your undeployment step is just one part of a larger whole. If it fails, it will fault the remaining tasks until a human gets involved.

If you want reliable Application Releases, you should use a consistent approach. An undeploy script that only works once and then fails for future releases or for deployments to new environments just won't cut it.

Option 1: Scripting

If you're comfortable with scripting, there are of course countless ways to make your release process idempotent, if you are willing to invest the time.

For example, in our example with undeployment, you could build a wrapper Apache Ant project which does a stop of the composite first (which is interestingly already idempotent unlike the deploy) then if it displays a certain message that would indicate the Composite is not deployed then we can skip the undeployment step altogether. Of course, this approach requires processing on the output of a script rather than it's exit code which is not ideal... but alas, it's what we have to work with.

Here's how to do an idempotent undeployment:

<project name="SCA Undeploy">

 <property name="failOnError" value="true" />
 <!-- The below should ideally use a GUID to prevent concurrent modification -->
 <property name="tmp.output" value="/tmp/xxx" />

 <target name="undeploy-sca">
  <ant dir="${ant_soa_home}/bin" antfile="ant-sca-mgmt.xml" target="stopComposite" inheritAll="false" output="${tmp.output}">
   <property name="host" value="${internal.soa.host}" />
   <property name="port" value="${internal.soa.plain_port}" />
   <property name="user" value="${core.fmw.admin.username}" />
   <property name="password" value="${core.fmw.admin.password}" />
   <property name="compositeName" value="${sca.composite.name}" />
   <property name="partition" value="${sca.composite.partition}" />
   <property name="revision" value="${sca.composite.revision}" />
  </ant>
  <condition property="is.undeployed">
   <resourcecontains resource="${tmp.output}" substring="The configuration file, deployed-composites.xml, does not contain"/>
  </condition>
  <antcall target="undeploy-sca-if-exists">
   <param name="skip.undeploy" value="${is.undeployed}"/>
  </antcall>
  <delete file="${tmp.output}"/>
</target>

 <target name="undeploy-sca-if-exists" unless="skip.undeploy">
  <ant dir="${ant_soa_home}/bin" antfile="ant-sca-deploy.xml" target="undeploy" inheritAll="false">
   <property name="serverURL" value="${internal.soa.deployment_url}" />
   <property name="user" value="${core.fmw.admin.username}" />
   <property name="compositeName" value="${sca.composite.name}" />
   <property name="partition" value="${sca.composite.partition}" />
   <property name="revision" value="${sca.composite.revision}" />
   <property name="failOnError" value="${failOnError}" />
  </ant>
 </target>

</project>  

You can call the script like this:

ant undeploy-sca  
-Dinternal.soa.deployment_url=http://localhost:8001 
-Dsca.composite.name=POProcessing 
-Dsca.composite.revision=rev6-cmdline
-Dcore.fmw.admin.username=weblogic 
-Dsca.composite.partition=partition.name
-Dant.soa.home=/u01/app/oracle/product/fmw1213/soa

Are scripts always the answer?

Scripts can be great for automation as they allow you to perform things quickly and consistently without needing manual labour. But there is still some labour to create them, test them, debug them and keep them up-to-date as new Oracle product releases come along.

Option 2: Rubicon Red MyST

An alternative is to use Rubicon Red MyST which is a DevOps solution for Oracle Middleware and SOA Cloud Services. MyST comes with out-of-the-box support for Automated Release Management and Platform Provisioning of Oracle-based solutions and you don't need to write a single script. Instead, you define your application deployments declaratively and manage the promotion of them through a Release Pipeline. If you'd like to learn more about MyST you can visit our pages on Continuous Delivery and Platform Provisioning.

Craig Barr

I am a Software Engineer with a decade of experience empowering Enterprises in Banking, Logistics, Manufacturing with Service-Oriented Architecture, Microservices and Cloud Computing.

Brisbane, Australia https://twitter.com/craigbarrau