OSB: Configuration with custom XQuery functions

The OSB supports a mechanism of customization. Unfortunately this mechanism is very limited and is not able to change all values. There are hundreds of situations where some kind of configuration is needed and which can’t be solved with customization:

  • A configurable value need to be added to a request
  • Username and password can’t be provided with a service account because they are not transferred as basic authentication
  • The behavior of a proxy service should be able to be changed by a switch
  • Paths for reading and writing files from should be configurable

For these cases we decided to implement an old fashioned configuration file.  But how should we access the values from the configuration file?

One possibility would be java callouts. But it is cumbersome to add a java callout for each needed value.

A better solution for this kind of framework functionality is custom XQuery functions.

First we create a java project in our favorite java development tool. For the XQuery we have to create a class with static methods. Simple parameters are supported and overloading the methods is ok. For our configuration XQuery we use this java class ConfigXQueryFunctions:

1 package com.opitzconsulting.osb.xquery.config; 2 3 import com.opitzconsulting.osb.util.ConfigUtil; 4 5 public class ConfigXQueryFunctions { 6 7 public static String getServerName() { 8 return System.getenv(HOSTNAME); 9 } 10 11 public static String getEnvironmentVariable(final String envName) { 12 return System.getenv(envName); 13 } 14 15 public static String getSystemProperty(final String propertyName) { 16 return System.getProperty(propertyName); 17 } 18 19 public static String getSystemProperty(final String propertyName, final String defaultValue) { 20 return System.getProperty(propertyName, defaultValue); 21 } 22 23 public static String getConfigFileName() { 24 return ConfigUtil.getFileName(); 25 } 26 27 public static String getEnvironment() { 28 return ConfigXQueryFunctions.getConfigMandatoryValue(env.name); 29 } 30 31 public static String getConfigValue(final String configValueName) { 32 return ConfigXQueryFunctions.getConfigValue(configValueName, null); 33 } 34 35 public static String getConfigValue(final String configValueName, final String defaultValue) { 36 return ConfigUtil.getValue(configValueName, defaultValue); 37 } 38 39 public static int getConfigValue(final String configValueName, final int defaultValue) { 40 return ConfigUtil.getValue(configValueName, defaultValue); 41 } 42 43 public static boolean getConfigValue(final String configValueName, final boolean defaultValue) { 44 return ConfigUtil.getValue(configValueName, defaultValue); 45 } 46 47 public static String getConfigMandatoryValue(final String configValueName) { 48 return ConfigUtil.getMandatoryValue(configValueName); 49 } 50 51 public static int getConfigMandatoryValueInt(final String configValueName) { 52 return ConfigUtil.getMandatoryValueInt(configValueName); 53 } 54 55 public static boolean getConfigMandatoryValueBoolean(final String configValueName) { 56 return ConfigUtil.getMandatoryValueBoolean(configValueName); 57 } 58 59 } 60

The class references here another class holding the real configuration information. It is a good idea to implement an auto-reload of the configuration to support on the fly changes. The method signatures in the example don’t have a parameter for a file or a OSB project, so there can be only one configuration file for the OSB.

After writing the java code and some unit tests (unit tests are a very good idea here because it is much work to do a redeployment of the XQuery lib for doing a change) the code should be compiled into a jar file.

Additionally we need a xml file describing the XQuery functions.

1 <?xml version=“1.0″ encoding=“UTF-8″?> 2 <xpf:xpathFunctions xmlns:xpf=“http://www.bea.com/wli/sb/xpath/config&#8220;> 3 <xpf:category id=“OSB Configuration XQuery Functions“> 4 5 <xpf:function> 6 <xpf:name>getServerName</xpf:name> 7 <xpf:comment>Returns the hostname of the server.</xpf:comment> 8 <xpf:namespaceURI>http://opitz-consulting.com/osb/custom/functions/config</xpf:namespaceURI> 9 <xpf:className>com.opitzconsulting.osb.xquery.config.ConfigXQueryFunctions</xpf:className> 10 <xpf:method>java.lang.String getServerName()</xpf:method> 11 <xpf:isDeterministic>true</xpf:isDeterministic> 12 <xpf:scope>Pipeline</xpf:scope> 13 <xpf:scope>SplitJoin</xpf:scope> 14 </xpf:function> 15 16 <xpf:function> 17 <xpf:name>getEnvironmentVariable</xpf:name> 18 <xpf:comment>Returns the value of the environment variable with the name given by the parameter.</xpf:comment> 19 <xpf:namespaceURI>http://opitz-consulting.com/osb/custom/functions/config</xpf:namespaceURI> 20 <xpf:className>com.opitzconsulting.osb.xquery.config.ConfigXQueryFunctions</xpf:className> 21 <xpf:method>java.lang.String getEnvironmentVariable(java.lang.String)</xpf:method> 22 <xpf:isDeterministic>true</xpf:isDeterministic> 23 <xpf:scope>Pipeline</xpf:scope> 24 <xpf:scope>SplitJoin</xpf:scope> 25 </xpf:function> 26 27 <xpf:function> 28 <xpf:name>getSystemProperty</xpf:name> 29 <xpf:comment>Returns the value of the system property with the name given by the parameter.</xpf:comment> 30 <xpf:namespaceURI>http://opitz-consulting.com/osb/custom/functions/config</xpf:namespaceURI> 31 <xpf:className>com.opitzconsulting.osb.xquery.config.ConfigXQueryFunctions</xpf:className> 32 <xpf:method>java.lang.String getSystemProperty(java.lang.String)</xpf:method> 33 <xpf:isDeterministic>true</xpf:isDeterministic> 34 <xpf:scope>Pipeline</xpf:scope> 35 <xpf:scope>SplitJoin</xpf:scope> 36 </xpf:function> 37 38 <xpf:function> 39 <xpf:name>getSystemPropertyDefault</xpf:name> 40 <xpf:comment>Returns the value of the system property with the name given by the parameter. If the system property is not set the default value given by the second parameter is returned.</xpf:comment> 41 <xpf:namespaceURI>http://opitz-consulting.com/osb/custom/functions/config</xpf:namespaceURI> 42 <xpf:className>com.opitzconsulting.osb.xquery.config.ConfigXQueryFunctions</xpf:className> 43 <xpf:method>java.lang.String getSystemProperty(java.lang.String, java.lang.String)</xpf:method> 44 <xpf:isDeterministic>true</xpf:isDeterministic> 45 <xpf:scope>Pipeline</xpf:scope> 46 <xpf:scope>SplitJoin</xpf:scope> 47 </xpf:function> 48 49 <xpf:function> 50 <xpf:name>getConfigFileName</xpf:name> 51 <xpf:comment>Returns the name and the path of the file containing the configuration.</xpf:comment> 52 <xpf:namespaceURI>http://opitz-consulting.com/osb/custom/functions/config</xpf:namespaceURI> 53 <xpf:className>com.opitzconsulting.osb.xquery.config.ConfigXQueryFunctions</xpf:className> 54 <xpf:method>java.lang.String getConfigFileName()</xpf:method> 55 <xpf:isDeterministic>true</xpf:isDeterministic> 56 <xpf:scope>Pipeline</xpf:scope> 57 <xpf:scope>SplitJoin</xpf:scope> 58 </xpf:function> 59 60 <xpf:function> 61 <xpf:name>getEnvironment</xpf:name> 62 <xpf:comment>Returns the name of the environment the configuration is designated.</xpf:comment> 63 <xpf:namespaceURI>http://opitz-consulting.com/osb/custom/functions/config</xpf:namespaceURI> 64 <xpf:className>com.opitzconsulting.osb.xquery.config.ConfigXQueryFunctions</xpf:className> 65 <xpf:method>java.lang.String getEnvironment()</xpf:method> 66 <xpf:isDeterministic>true</xpf:isDeterministic> 67 <xpf:scope>Pipeline</xpf:scope> 68 <xpf:scope>SplitJoin</xpf:scope> 69 </xpf:function> 70 71 <xpf:function> 72 <xpf:name>getConfigValue</xpf:name> 73 <xpf:comment>Returns the value of the configuration entry with the name given by the parameter. If the configuration entry doesn’t exist null is returned.</xpf:comment> 74 <xpf:namespaceURI>http://opitz-consulting.com/osb/custom/functions/config</xpf:namespaceURI> 75 <xpf:className>com.opitzconsulting.osb.xquery.config.ConfigXQueryFunctions</xpf:className> 76 <xpf:method>java.lang.String getConfigValue(java.lang.String)</xpf:method> 77 <xpf:isDeterministic>true</xpf:isDeterministic> 78 <xpf:scope>Pipeline</xpf:scope> 79 <xpf:scope>SplitJoin</xpf:scope> 80 </xpf:function> 81 82 <xpf:function> 83 <xpf:name>getConfigValueDefault</xpf:name> 84 <xpf:comment>Returns the value of the configuration entry with the name given by the parameter. If the configuration entry doesn’t exist the default value given by the second parameter is returned.</xpf:comment> 85 <xpf:namespaceURI>http://opitz-consulting.com/osb/custom/functions/config</xpf:namespaceURI> 86 <xpf:className>com.opitzconsulting.osb.xquery.config.ConfigXQueryFunctions</xpf:className> 87 <xpf:method>java.lang.String getConfigValue(java.lang.String, java.lang.String)</xpf:method> 88 <xpf:isDeterministic>true</xpf:isDeterministic> 89 <xpf:scope>Pipeline</xpf:scope> 90 <xpf:scope>SplitJoin</xpf:scope> 91 </xpf:function> 92 93 <xpf:function> 94 <xpf:name>getConfigValueInt</xpf:name> 95 <xpf:comment>Returns the value of the configuration entry with the name given by the parameter as an integer value. If the configuration entry doesn’t exist or the conversion fails the default value given by the second parameter is returned.</xpf:comment> 96 <xpf:namespaceURI>http://opitz-consulting.com/osb/custom/functions/config</xpf:namespaceURI> 97 <xpf:className>com.opitzconsulting.osb.xquery.config.ConfigXQueryFunctions</xpf:className> 98 <xpf:method>int getConfigValue(java.lang.String, int)</xpf:method> 99 <xpf:isDeterministic>true</xpf:isDeterministic> 100 <xpf:scope>Pipeline</xpf:scope> 101 <xpf:scope>SplitJoin</xpf:scope> 102 </xpf:function> 103 104 <xpf:function> 105 <xpf:name>getConfigValueBoolean</xpf:name> 106 <xpf:comment>Returns the value of the configuration entry with the name given by the parameter as a boolean value. If the configuration entry doesn’t exist or the conversion fails the default value given by the second parameter is returned.</xpf:comment> 107 <xpf:namespaceURI>http://opitz-consulting.com/osb/custom/functions/config</xpf:namespaceURI> 108 <xpf:className>com.opitzconsulting.osb.xquery.config.ConfigXQueryFunctions</xpf:className> 109 <xpf:method>boolean getConfigValue(java.lang.String, boolean)</xpf:method> 110 <xpf:isDeterministic>true</xpf:isDeterministic> 111 <xpf:scope>Pipeline</xpf:scope> 112 <xpf:scope>SplitJoin</xpf:scope> 113 </xpf:function> 114 115 <xpf:function> 116 <xpf:name>getConfigMandatoryValue</xpf:name> 117 <xpf:comment>Returns the value of the configuration entry with the name given by the parameter. If the configuration entry doesn’t exist an exception is thrown.</xpf:comment> 118 <xpf:namespaceURI>http://opitz-consulting.com/osb/custom/functions/config</xpf:namespaceURI> 119 <xpf:className>com.opitzconsulting.osb.xquery.config.ConfigXQueryFunctions</xpf:className> 120 <xpf:method>java.lang.String getConfigMandatoryValue(java.lang.String)</xpf:method> 121 <xpf:isDeterministic>true</xpf:isDeterministic> 122 <xpf:scope>Pipeline</xpf:scope> 123 <xpf:scope>SplitJoin</xpf:scope> 124 </xpf:function> 125 126 <xpf:function> 127 <xpf:name>getConfigMandatoryValueInt</xpf:name> 128 <xpf:comment>Returns the value of the configuration entry with the name given by the parameter as an integer value. If the configuration entry doesn’t exist or the conversion fails an exception is thrown.</xpf:comment> 129 <xpf:namespaceURI>http://opitz-consulting.com/osb/custom/functions/config</xpf:namespaceURI> 130 <xpf:className>com.opitzconsulting.osb.xquery.config.ConfigXQueryFunctions</xpf:className> 131 <xpf:method>int getConfigMandatoryValueInt(java.lang.String)</xpf:method> 132 <xpf:isDeterministic>true</xpf:isDeterministic> 133 <xpf:scope>Pipeline</xpf:scope> 134 <xpf:scope>SplitJoin</xpf:scope> 135 </xpf:function> 136 137 <xpf:function> 138 <xpf:name>getConfigMandatoryValueBoolean</xpf:name> 139 <xpf:comment>Returns the value of the configuration entry with the name given by the parameter as a boolean value. If the configuration entry doesn’t exist or the conversion fails an exception is thrown.</xpf:comment> 140 <xpf:namespaceURI>http://opitz-consulting.com/osb/custom/functions/config</xpf:namespaceURI> 141 <xpf:className>com.opitzconsulting.osb.xquery.config.ConfigXQueryFunctions</xpf:className> 142 <xpf:method>boolean getConfigMandatoryValueBoolean(java.lang.String)</xpf:method> 143 <xpf:isDeterministic>true</xpf:isDeterministic> 144 <xpf:scope>Pipeline</xpf:scope> 145 <xpf:scope>SplitJoin</xpf:scope> 146 </xpf:function> 147 148 </xpf:category> 149 </xpf:xpathFunctions> 150

The category id while be the text shown in eclipse while using the functions. And also the namespace is important: Eclipse is generating while using the function a prefix out of the namespace. If you change the namespace afterwards you have to change the prefix on every location you used the XQuery function.

The names of the XQuery functions should NOT be overloaded here. Overloaded names didn’t work for me and I have not found out how to fix it.

Now we have to deploy the XQuery to the OSB and to Eclipse. It is a drop in deployment: You have to copy the JAR archive and the XML file to the folder Oracle_OSB1/config/xpath-functions. After that a restart of the OSB / Eclipse is necessary.

Now you can use your custom XQuery functions inside of XQuerys

BLOG_OSB_CustomXQuery_01

or inside the proxyservice

BLOG_OSB_CustomXQuery_02

 

Bernhard Mähr @ OPITZ-CONSULTING published at https://thecattlecrew.wordpress.com/

Über bmaehr

Ich bin ein Technik-Fan, der in der Informatik seinen Beruf und seine Berufung gefunden hat.
Dieser Beitrag wurde unter BPM & System Integration abgelegt und mit , , verschlagwortet. Setze ein Lesezeichen auf den Permalink.

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s