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:
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“> 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>103104<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>114115<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>125126<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>136137<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>147148</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