Weblog

OBI EE explanatory text (narrative view)

An often heard question of customers is: Can we add explanatory text into an report defined in OBI EE. The answer is yes and the report-view you need to use is narrative.

By defining variables in the administrator tool and using them in an Answer-report you can add explanatory text that is stored in any database.

Repository variables can be assigned in 2 ways. One is assigned a value directly to the variable and the other is via Initialization Blocks.

This example has an variable which is based on a Initilization block.

var_1.jpg

var_2.jpg

If we want to add some explanatory text to an Answer report we can use the narrative view. In this narrative view we can use the just created variable. In order to access this Repository variable from Answers you need the following syntax:

@{biServer.variables['variablename']} 

@{biServer.variables['var_country']}

var_3.jpg

Deploying ESB projects using Ant

This post is to summarize and correct some of the information which can be found on this thread: Dealing with changing service wsdl locations in the ESB. (A big thanks to all the people who participated on this thread!)

Let’s start with some issues a lot of people, including me, have run into.

jaxb.properties not found

If you’re using Ant 1.6.5, you need to put some libraries on the classpath before starting ant. In the OTN forum thread some people state that you need to use Ant 1.7, and although Ant 1.7 has some improvements in how it handles classpaths, you do not need to use it. You just need to make sure that the oracle xmlparserv2 jar, the jaxb jars (i’m using version 2.0.5), and apache commons codec jar is on the classpath. In JDeveloper you can do it as displayed below (click image for full size).

Ant esb classpath

NullPointerException when trying to extract a deployment plan

This is caused by a bug in an older version of ESBMetadataMigration.jar. As is mentioned on the thread, this can be solved by using the jar included with Soasuite 10.1.3.3. (you can find it in soasuite/integration/esb/deployment/documentation.zip).

Error detected while reading the Deployment Plan

If you see this error when deploying an ESB, you can solve this by running Ant in a separate JVM. You can specify this in the project properties as is displayed below.

Ant esb jvm

Dynamically determining ESB component GUIDs

Ant has some default tasks that you can use to determine the GUID of a esb service. Using xmlproperty you can read an xml file and extract the value of a guid. Here’s an example:

<xmlproperty file="MyEsb.esbsvc" prefix="myesb"/>
<property name="myesb.guid" value="${myesb.service(guid)}"/>

Complete example

Since Ant 1.6 you have the ability to define macros. Using some simple macros deploying esbs becomes quite simple. Here’s an example:

<target name="deploy">
    <!--
      == Undeploy esb components, by determining the guid from the esbsvc file
      -->
    <xmlproperty file="MyEsb.esbsvc" prefix="myesb"/>
    <property name="myesb.guid" value="${myesb.service(guid)}"/>
    <undeploy-esb guid="${myesb.guid}"/>
    <!--
      == deploy esb project
      -->
    <deploy-esb/>
</target>
<target name="extract.esb.deployment.plan">
  <!--
    == extract deployment plan from deployed esb component
    -->
  <extract-esb-deployment-plan/>
</target>

ESB deployment macros

I’m using the following macro definitions:

<project default="init" name="build-macros" xmlns:esb="antlib:oracle.tip.esb.client.anttasks">
  <taskdef uri="antlib:oracle.tip.esb.client.anttasks"
           resource="oracle/tip/esb/client/anttasks/antlib.xml"
           loaderref="oracle.esb.ant">
    <classpath>
      <path refid="oracle.esbant.lib"/>
      <path refid="apache.commons.httpclient.lib"/>
      <path refid="apache.commons.logging.lib"/>
      <path refid="apache.commons.codec.lib"/>
      <path refid="oracle.esb.lib"/>
      <path refid="java.jaxb.lib"/>
      <path refid="oracle.xmlparser.lib"/>
    </classpath>
  </taskdef>
  <!--
    ============================================================================
    == deploy esb
    ============================================================================
    -->
  <macrodef name="deploy-esb">
    <attribute name="deploymentplanFile"
               default="${basedir}/${src.dir}/${ant.project.name}-esbplan-${build.env}.xml"/>
    <attribute name="esbHost" default="${integration.server.host}"/>
    <attribute name="esbPort" default="${integration.server.port}"/>
    <attribute name="esbAdminUser"
               default="${integration.server.admin.username}"/>
    <attribute name="esbAdminPassword"
               default="${integration.server.admin.password}"/>
    <sequential>
      <echo>Deploying esb project ${ant.project.name} using plan @{deploymentplanFile}</echo>
      <property name="esbplan" location="@{deploymentplanFile}"/>
      <esb:deployESBSuitcase esbmetadataserverhostname="@{esbHost}"
                             esbmetadataserverport="@{esbPort}"
                             username="@{esbAdminUser}"
                             password="@{esbAdminPassword}"
                             deploymentplanfilename="${esbplan}"
                             sourcedirectory="${basedir}"></esb:deployESBSuitcase>
    </sequential>
  </macrodef>
  <!--
    ============================================================================
    == extract esb deployment plan
    ============================================================================
    -->
  <macrodef name="extract-esb-deployment-plan">
    <attribute name="templateDeploymentplanFile"
               default="${basedir}/${srcgen.dir}/${ant.project.name}-esbplan-template.xml"/>
    <sequential>
      <mkdir dir="${srcgen.dir}"/>
      <delete file="@{templateDeploymentplanFile}"/>
      <echo>Creating deployment plan @{templateDeploymentplanFile}</echo>
      <esb:extractESBDeploymentPlan sourcedir="${basedir}"
                                    deploymentplanfile="@{templateDeploymentplanFile}"/>
    </sequential>
  </macrodef>
  <!--
    ============================================================================
    == undeploy esb
    ============================================================================
    -->
  <macrodef name="undeploy-esb">
    <attribute name="guid"/>
    <attribute name="esbHost" default="${integration.server.host}"/>
    <attribute name="esbPort" default="${integration.server.port}"/>
    <attribute name="esbAdminUser"
               default="${integration.server.admin.username}"/>
    <attribute name="esbAdminPassword"
               default="${integration.server.admin.password}"/>
    <sequential>
      <echo>Undeploying ESB from @{esbHost}</echo>
      <esb:undeployESBEntities esbmetadataserverhostname="@{esbHost}"
                               esbmetadataserverport="@{esbPort}"
                               username="@{esbAdminUser}"
                               password="@{esbAdminPassword}">
        <system guid="@{guid}"/>
      </esb:undeployESBEntities>
    </sequential>
  </macrodef>
</project>

Most macros have sensible default values for the attributes which usually means you don’t have to specify any attributes. The properties used in the defaults are read from a property file.

The deployment macro expects a deployment plan in the src directory. You need to specify a build.env property to tell it which deployment to use.

Continuum 1.1 available

Last week continuum version 1.1 was released. It contains at least one feature i’ve been waiting for: automatically rebuilding dependent projects. I’m considering however, not to upgrade continuum, but to switch to hudson. It seems to be more widely used, which results in a lot useful plugins and better documentation. Time to testdrive both…

Storing webservice properties using dynamic MBeans

Storing webservice properties using dynamic MBeans.

Recently I needed to store some settings in a JSR-181 webservice. Since I did not have a user interface and I don’t want to use property files I thought to try and store them in a MBean using JMX.
This gives the administrator the change to alter the properties through the Oracle Enterprise Manager instead of digging for property files on the server. It actually is pretty straightforward to implement a MBean. However to implement it dynamic is a bit harder so here how I did it:

First create a class which name ends with: MBean and implements the DynamicMBean interface.
Here’s my class:

public class SettingsMBean implements DynamicMBean {
  private Properties properties = null;
  private MBeanInfo info = null;
  private MBeanConstructorInfo[] conInfo = null;
  private MBeanOperationInfo[] operInfo = null;
  private MBeanAttributeInfo[] attrInfo = null;
  private MBeanNotificationInfo[] notifInfo = null;
  public static final String LOADPROPERTIES = "loadProperties";
  public static final String SAVEPROPERTIES = "saveProperties";

  public SettingsMBean() {
  }

  public Object getAttribute(String attribute) {
    return properties.getProperty(attribute);
  }

  public void setAttribute(Attribute attribute) {
    if (properties.getProperty(attribute.getName()) != null) {
      properties.setProperty(attribute.getName(),(String)attribute.getValue());
    }
  }

  public AttributeList getAttributes(String[] attributes) {
    AttributeList list = new AttributeList();
    list.add(new Attribute("properties", properties));
    for (String name: attributes) {
      String value = properties.getProperty(name);
      if (value != null) {
        list.add(new Attribute(name, value));
      }
    }
    return list;
  }

  public AttributeList setAttributes(AttributeList attributes) {
    Attribute[] attrs = (Attribute[])attributes.toArray(new Attribute[0]);
    AttributeList retlist = new AttributeList();

    for (Attribute attr: attrs) {
      String name = attr.getName();
      Object value = attr.getValue();

      if ((properties.getProperty(name) != null) && value instanceof String) {
        properties.setProperty(name, (String)value);
        retlist.add(new Attribute(name, value));
      }
    }
    try {
      saveProperties();
    } catch (Exception e) {
      e.printStackTrace();
      return new AttributeList();
    }
    return retlist;
  }

  public Object invoke(String actionName, Object[] params, String[] signature) {
    if (actionName.compareToIgnoreCase("loadProperties")==0) {
      if (loadProperties()) {
        this.constructInfo();
      }
    }
  }

  public MBeanInfo getMBeanInfo() {
    if (this.info == null) {
      constructInfo();
    }
    return info;
  }

  private Boolean saveProperties() {
    //TODO: inplement save method...
  }

  public Boolean loadProperties() {
    //TODO: implement load method...
  }

  private void constructInfo() {
    this.constructConstructorInfo();
    this.constructOperationInfo();
    this.constructAttributeInfo();

    String className = "SettingsMBean";
    String description = "Webservice settings MBean";

    this.info = new MBeanInfo(className, description, attrInfo, conInfo, operInfo, notifInfo);
  }

  private void constructConstructorInfo() {
    String name = "Default";
    String description = "Default no-args constructor";
    MBeanParameterInfo[] signature = null; //no params since it's a no-args constructor...
    this.conInfo = new MBeanConstructorInfo[1];
    this.conInfo[0] = new MBeanConstructorInfo(name, description, signature);
  }

  private void constructOperationInfo() {
    String type = Boolean.TYPE.getName();
    int impact = MBeanOperationInfo.ACTION;
    this.operInfo = new MBeanOperationInfo[2];
    this.operInfo[0] = new MBeanOperationInfo(LOADPROPERTIES, "Loads all properties", null, type, impact);
    this.operInfo[1] = new MBeanOperationInfo(SAVEPROPERTIES, "Save all properties", null, type, impact);
  }

  private void constructAttributeInfo() {
    SortedSet names = new TreeSet();
    for (Object name : properties.keySet()) {
      names.add((String) name);
    }
    String nameProps = "All properties";
    String description = "Webservice properties";
    this.attrInfo = new MBeanAttributeInfo[names.size() + 1];
    this.attrInfo[0] = new MBeanAttributeInfo(nameProps, "java.util.Properties", description, true, false, false);
    Iterator it = names.iterator();
    for (int i = 1; i < attrInfo.length; i++) {
      String name = it.next();
      attrInfo[i] = new MBeanAttributeInfo(name, "java.lang.String","Property " + name, true, true, false);
    }
  }

}

Second you need to deploy the MBean.
I created a separate .jar file for the bean using ant. I deployed this in my .ear file and created an orion-application.xml in which you can declare the mbean:

<orion-application>
  <jmx-mbean objectname=":type=Application,name=SettingsMBean"
    class="nl.iteye.beans:SettingsMBean">
    <description>Settings MBean</description>
  </jmx-mbean>
</orion-application>

After deploying you can use the Enterprise Manager to view/update your properties on the fly. I left out some of the details of filling the properties.

I created this with help from Pat Lee.

Oracle using Flex for a lot of products…

According to Adobe employee and RIA Cowboy James Ward Oracle’s been demonstrating a lot of applications using Flex during OOW 2007. Ward has a couple of postings on his weblog describing applications (including some pictures) using flex: Metalink, Bi Publisher, Enterprise Manager, Siebel CRM, Sales Prospector and Sales library. The pictures are a bit fuzzy, so it’s hard to say how much flex these applications are using. Some look like their complete ui is implemented using Flex, other applications look like a combination of ADF Faces and Flex charts. Not sure though, the pictures aren’t clear enough. And it might not even be possible to tell by looking at the interface. One thing is clear though, flex is the way to go for graphical UI’s.

Using XMLType, XMLDB and XQuery

This is a small example for a coworker, but maybe someone else can also benefit from it. This question was “can we store multiple xml document types in one column and easily query on xml contents”?

First create a table with an XMLType column, and insert some data:

SQL> create table mydocs
  ( id number primary key, doc xmltype);

Table created.

SQL> insert into mydocs values
  ( 1, XMLType('< ?xml version="1.0"?><order><productid>2</productid><amount>5</amount></order>'));

1 row created.

SQL> insert into mydocs values
  (2,XmlType('< ?xml version="1.0"?><customer><name>Pete Jansen</name><phone>+31-30-1234567</phone></customer>'));

1 row created.

Query documents using an xpath expression in the where clause:

SQL> set long 5000
SQL> column xml format a40
SQL> select id, doc as xml from mydocs where existsNode(doc,'/order/productId/text() = "2"') >= 1
SQL> /

        ID XML
---------- ----------------------------------------
         1 < ?xml version="1.0"?>
           <order>
             <productid>2</productid>
             <amount>5</amount>
           </order>

Query values from xml documents:

SQL> select id, extractValue(doc,'/order/productId') as xml from mydocs;

        ID XML
---------- ------------------------------
         1 2
         2

Using xquery to retrieve xml documents:

SQL> select xmlquery('for $i in ora:view("MYDOCS")/ROW/DOC return $i' returning content) as xml from dual
SQL> /

XML
----------------------------------------
<doc><order>
  <productid>2</productid>
  <amount>5</amount>
</order>
</doc><doc><customer>
  <name>Pete Jansen</name>
  <phone>+31-30-1234567</phone>
</customer>
</doc>

And, to continue with the example from my previous post, query the same data using XQLPlus:

E:oraclejdev1111r2lib>java -classpath xquery.jar;xmlparserv2.jar;xsu12.jar;..jdbclibojdbc14.jar;..jliborai18n-collection.jar
;..rdbmsjlibxdb.jar oracle.xquery.XQLPlus

XQuery Command Line Tool
Version 1.0
Enter XQuery statements followed by /;

XQL> set sqlconn default jdbc:oracle:thin:test/test@ora11:1521:orcl
XQL> for $i in ora:view('MYDOCS')/ROW/DOC return $i
  2  /;

Result
----------------------------------------------------
<doc>
   <order>
      <productid>2</productid>
      <amount>5</amount>
   </order>
</doc>

<doc>
   <customer>
      <name>Pete Jansen</name>
      <phone>+31-30-1234567</phone>
   </customer>
</doc>

Executing XQuery statements with XQLPlus

Oracle’s xquery implementation contains a sqlplus like tool which you can use to run simple xquery statements. You can find the xquery implementation in %JDEV_HOME%/lib. To run it, use the following statement:

E:oraclejdev1111r2lib>java -classpath xquery.jar;xmlparserv2.jar;xsu12.jar;..jdbclibojdbc14.jar;..jliborai18n-collation.jar
oracle.xquery.XQLPlus

XQuery Command Line Tool
Version 1.0
Enter XQuery statements followed by /;

XQL> help

XQuery Command Line Tool
Enter XQuery statements followed by /;
To execute queries in a file from the XQL prompt, enter @ followed by the <filename>
To execute queries in a file from the shell prompt, enter java XQLPlus </filename><filename>
Set command helps set environment variables:
set sqlconn default <jdbc -connect-string>
set sqlconn <name> <jdbc -connect-string>
set echo   (ON | OFF)
set timing (ON | OFF)
set var <variable name> <value>
set initialctx <filename>

A simple xquery example:

XQL> for $i in <doc><row>text1</row><row>text2</row><row>text3</row></doc>//row return $i
  2  /;

Result
----------------------------------------------------
<row>text1</row>

<row>text2</row>

<row>text3</row>

You can use xquery to query data in a database table. First you need to specify the database connection using set sqlconn. when you’ve set the database you can use ora:view to query data from a table:

XQL> set sqlconn default jdbc:oracle:thin:jat/jat@xesoa1:1521:xe
XQL> for $i in ora:view('BOOKS') return $i
  2  /;

Result
----------------------------------------------------
<row>
   <id>1</id>
   <title>Processing XML with Java: A Guide to SAX, DOM, JDOM, JAXP, and TrAX</title>
   <author_id>1</author_id>
</row>

<row>
   <id>2</id>
   <title>Java &amp; XML, 2nd Edition: Solutions to Real-World Problems</title>
   <author_id>2</author_id>
</row>

<row>
   <id>3</id>
   <title>Java, XML, and the JAXP</title>
   <author_id>3</author_id>
</row>

You can also use xquery to query data from xml documents:

XQL> for $i in doc('file:///E:/projects/xquery-demo/xquerydemo-1/src/nl/iteye/xquerydemo1/books.xml')//book where $i/title/text() =
'Xml primer' return $i
  2  /;

Result
----------------------------------------------------
<book category="WEB">
   <title lang="en">Xml primer</title>
   <author>Erik T. Ray</author>
   <year>2003</year>
   <price>39.95</price>
</book>

By default xquery statements are executed by the client side xquery implementation. You can also execute your statements in a database server:

XQL> set server on
  Server Side Execution
XQL> set sqlconn default jdbc:oracle:thin:hr/hr@ora11:1521:orcl
XQL> for $i in <doc><row>1</row></doc> return $i
  2  /;

Result
----------------------------------------------------
<doc><row>1</row></doc>
XQL>

Of course, you can also use sqlplus to execute xquery statements on an Oracle database server.

Btw, you should be able to specify variable values using “set var”, but i haven’t been able to get that to work. And after looking at the source code, i don’t think that’s implemented, at least for client side xquery statements.

JDeveloper 11g preview 2 available

Hidden in Steve Munch’s presentation about adf 11g features is the news that jdeveloper 11g technology preview 2 is available for download.

Btw, there’s some good documentation about adf 11 available on otn: New Oracle ADF Developer Guide (pdf) & New Oracle ADF Faces Web UI Developer Guide (pdf)

Update
Looks like I’m having an off-day, as this is old news. Steve Munch already posted this news on September 27th, and i even linked to that story in the IT-eye weblog. I guess we’ll have to wait till December for some new software, when a public beta of the soa suite release 11 will be made available.

Pair programming and productivity

The Agile Software Development blog has an interesting post about The value of pairing when both partners are experienced. The post cites some interesting study results:

The University of Utah study in 2000 found as much as an 86% reduction in defects, with an increase of initial coding time of between 0% and 15%, as compared with two people working individually to produce the same quantity of code.

Oracle Vm

Today oracle announced Oracle VM (Data sheet), a server virtualization product. According to what i’ve read it’s based on Xen. This shouldn’t be a big surprise as RedHat Enterprise Linux 5 includes Xen, and Oracle’s Linux is, let’s put this nicely, based on RedHat Enterprise Linux.

The good news is that Oracle is supporting their products in virtualized servers. In the past we’ve had problems getting support for vmware based virtual servers. At least now we have a supported solution, which makes it a lot easier to roll out virtual environments.

The Oracle VM FAQ contains some surprising info. For one, Oracle claims that their virtualization product is three times more efficient than existing x86 server virtualizing products. This means that they’ve been improving Xen, as i thought that vmware had a better performance than Xen.

Oracle VM also supports moving live virtual machine from one physical host to another. I didn’t know Xen could do this, but Xen’s wiki page tells me differently.

More info, and a screenshot of the management console on Rittman’s blog.

Update:
Xen in Oracle Enterprise Linux must be different from Oracle VM, as virtualization is only supported for products running on Oracle VM. Running Oracle RDBMS, Oracle Application Server or any of the other products on Xen in Oracle Enterprise Linux isn’t supported. Weird. Do you think that there is a reason why these products could be supported when running on Oracle Enterprise Linux as a virtualization host?

Btw, the Oracle VM press release confirms that Oracle VM is based on Xen. Which makes you think, what did Citrix buy?

Here’s a screenshot of the Oracle VM manager interface taken from the Data sheet:
Oracle VM manager

Another thing i just noticed: Oracle Application Server is supported on Oracle VM, but Oracle SOA Suite isn’t included in the list of supported software.

Another update
Here’s another good writeup about Oracle VM: Path Shuf on Oracle VM.

Technology
Ben jij slim genoeg voor IT-eye