Wednesday 20 December 2017

OSB 12c Customization in WLST, some new insights: use the right jar for the job!

Problem setting  and investigation

Years ago I created a Release & Deploy framework for Fusion Middleware, also supporting Oracle Service Bus. Recently revamped it to use 12c. It uses WLST to import the OSB service to the Service Bus, including the execution the customization file.

There are lots of examples to do this, but I want to zoom in on the execution of the customization file.

The WLST function that does this, that I use is as follows:
#=======================================================================================
# Function to execute the customization file.
#=======================================================================================
def executeCustomization(ALSBConfigurationMBean, createdRefList, customizationFile):
    if customizationFile!=None:
      print 'Loading customization File', customizationFile
      inputStream = FileInputStream(customizationFile)
      if inputStream != None:
        customizationList = Customization.fromXML(inputStream)
        if customizationList != None:
          filteredCustomizationList = ArrayList()
          setRef = HashSet(createdRefList)
          print 'Filter to remove None customizations' 
          print "-----"
          # Apply a filter to all the customizations to narrow the target to the created resources
          print 'Number of customizations in list: ', customizationList.size()
          for customization in customizationList:
            print "Add customization to list: "
            if customization != None:
              print 'Customization: ', customization, " - ", customization.getDescription()
              newCustomization = customization.clone(setRef)
              filteredCustomizationList.add(newCustomization)
            else:
              print "Customization is None!"
            print "-----"
          print 'Number of resulting customizations in list: ', filteredCustomizationList.size()
          ALSBConfigurationMBean.customize(filteredCustomizationList)
        else:
          print 'CustomizationList is null!'
      else:
        print 'Input Stream for customization file is null!'
    else:
      print 'No customization File provided, skip customization.'

The parameter ALSBConfigurationMBean can be fetched with:
...
        sessionName = createSessionName()
        print 'Created session', sessionName
        SessionMBean = getSessionManagementMBean(sessionName)
        print 'SessionMBean started session'
        ALSBConfigurationMBean = findService(String("ALSBConfiguration.").concat(sessionName), "com.bea.wli.sb.management.configuration.ALSBConfigurationMBean")
...

The other parameter is the createdRefList, that is build up from the default ImportPlan during import of the config jar:
...
          print 'ÒSB project', project, 'will get updated'
            osbJarInfo = ALSBConfigurationMBean.getImportJarInfo()
            osbImportPlan = osbJarInfo.getDefaultImportPlan()
            osbImportPlan.setPassphrase(passphrase)
            operationMap=HashMap()
            operationMap = osbImportPlan.getOperations()
            print
            print 'Default importPlan'
            printOpMap(operationMap)
            set = operationMap.entrySet()

            osbImportPlan.setPreserveExistingEnvValues(true)

            #boolean
            abort = false
            #list of created artifact refences
            createdRefList = ArrayList()
            for entry in set:
                ref = entry.getKey()
                op = entry.getValue()
                #set different logic based on the resource type
                type = ref.getTypeId
                if type == Refs.SERVICE_ACCOUNT_TYPE or type == Refs.SERVICE_PROVIDER_TYPE:
                    if op.getOperation() == ALSBImportOperation.Operation.Create:
                        print 'Unable to import a service account or a service provider on a target system', ref
                        abort = true
                else:
                    #keep the list of created resources
                    print 'ref: ',ref
                    createdRefList.add(ref)
            if abort == true :
                print 'This jar must be imported manually to resolve the service account and service provider dependencies'
                SessionMBean.discardSession(sessionName)
                raise
            print
            print 'Modified importPlan'
            printOpMap(operationMap)
            importResult = ALSBConfigurationMBean.importUploaded(osbImportPlan)
            printDiagMap(importResult.getImportDiagnostics())              
            if importResult.getFailed().isEmpty() == false:
                print 'One or more resources could not be imported properly'
                raise
...

The meaning is to build up a set of references of created artefact, to narrow down the customizations to only execute them on the artefacts that are actually imported.

Now, back to the executeCustomization function. It first creates an InputStream on the customization file:
inputStream = FileInputStream(customizationFile)

on which it builds a list of customizations using the .fromXML method of the Customization object:
        customizationList = Customization.fromXML(inputStream)

These customizations are interpreted from the Customization file. If you open that you can find several customization elements:
 <cus:customization xsi:type="cus:EnvValueActionsCustomizationType">
        <cus:description/>
...
    <cus:customization xsi:type="cus:FindAndReplaceCustomizationType">
        <cus:description/>
...
    <cus:customization xsi:type="cus:ReferenceCustomizationType">
        <cus:description/>


These all are mapped to subclasses of the Customization. And now the reason that I write this blogpost is that I ran into a problem with my import tooling. In the EnvValueActionsCustomizationType the endpoint replacements for the target environments is done. And the weren't executed. In fact these customizations were in the customizationList, but as a None/Null object. Thus, executing this complete list using ALSBConfigurationMBean.customize(filteredCustomizationList) would run in an exception, refering to a null object in the customization list. That's why they're filtered out. But why weren't these interpreted by the .fromXml() method?

Strangely enough in the javaAPI docs of 12.2.1 the EnvValueActionsCustomization does not exist, but the EnvValueCustomization does. But searching My Oracle Support shows in Note 1679528.2: 'A new customization type EnvValueActionsCustomizationType is available in 12c which is used when creating a configuration plan file.' and here in the Java API doc (click on com.bea.wli.config.customization) it is stated that EnvValueCustomization is deprecated and EnvValueActionsCustomization should be used in stead.
Apparently the docs is not updated completely....
And it seems that I used a wrong jar file: The customization file was created using the Console, and executing the customization file using the console did execute the endpoint replacements. So I figured that I must be using a wrong version of the jar file.
So I searched on my BPM quickstart installation (12.2.1.2) for the class EnvValueCustomization:
Jar files containing EnvValueCustomization
  • C:\Oracle\JDeveloper\12210_BPMQS\osb\lib\modules\oracle.servicebus.configfwk.jar/com\bea\wli\config\customization\EnvValueCustomization.class
  • C:\Oracle\JDeveloper\12210_BPMQS\oep\spark\lib\spark-osa.jar/com\bea\wli\config\customization\EnvValueCustomization.class
  • C:\Oracle\JDeveloper\12210_BPMQS\oep\common\modules\com.bea.common.configfwk_1.3.0.0.jar/com\bea\wli\config\customization\EnvValueCustomization.class
And then I did a search with EnvValueActionsCustomization.
Jar files containing EnvValueActionsCustomization:
  • C:\Oracle\JDeveloper\12210_BPMQS\osb\lib\modules\oracle.servicebus.configfwk.jar/com\bea\wli\config\customization\EnvValueActionsCustomization.class

Solution

It turns out that in my ANT script I used:
<path id="library.osb">
  <fileset dir="${fmw.home}/oep/common/modules">
     <include name="com.bea.common.configfwk_1.3.0.0.jar"/>
  </fileset> 
  <fileset dir="${weblogic.home}/server/lib">
    <include name="weblogic.jar"/>
    <include name="wls-api.jar"/>
  </fileset>
  <fileset dir="${osb.home}/lib">
    <include name="alsb.jar"/>
  </fileset>
</path>

Where I should use:
<path id="library.osb">
  <fileset dir="${fmw.home}/osb/lib/modules">
    <include name="oracle.servicebus.configfwk.jar"/>
  </fileset>
  <fileset dir="${weblogic.home}/server/lib">
    <include name="weblogic.jar"/>
    <include name="wls-api.jar"/>
  </fileset>
  <fileset dir="${osb.home}/lib">
    <include name="alsb.jar"/>
  </fileset>
</path>

Conclusion

It took me quite some time to debug this. But learned how the customization works. I found quite some examples that use com.bea.common.configfwk_1.X.0.0.jar. And apparently during my revamping, I updated this class path (actually I had 1.7, and found only 1.3 in my environment).  But, somehow Oracle found it sensible to replace it with oracle.servicebus.configfwk.jar while keeping the old jar files.
So use the right Jar for the job!

5 comments :

Amith said...

Hello,

I am facing similar problem. I am deploying the OSB 12c processes using scripts. Process is getting deployed but the customization file(values in file ex:endpoint URL) is not getting overwritten even the deployment is successful. Please let me know what is missing. Can you help in this issue?

Thanks,
Amith

Anonymous said...

Hi Amith,

Better to ask this question on https://community.oracle.com/community/support/middleware/oracle-soa-suite or https://community.oracle.com/community/groundbreakers/fusion_middleware/soa_and_process_management/soa_suite_3. Then more people can get into it. And you can provide more details.

Regards,
Martien

Amith said...

Hi Martien,

Thanks for the reply.

I had asked the question in oracle community more than a month ago and did not get any response. However, i have again started a discussions on the links you suggested.No response again.

Here is the link : https://community.oracle.com/message/15056915#15056915

Could you please take your time and help me in this issue ?

Thanks,
Amith

Anonymous said...

Hi Amith,

I did took a look and found it earlier, but there is a response/question of Vladodidas that you did not answer.

I elaborated on his question, so you might want to look into that to help us investigating your problem.

We can't by visually checking the flow of your script find the problem without having the input and/or some output.

Regards,
Martien

Amith said...

Hi Martien,

Sorry about that. Thanks for the reply. I thought no one replied to that discussion.

Now i see the reply from Vladodidas. I will give the required artefacts soon.

Thanks,

Amith