Introducing “Rittman Mead Consulting”

Posted by Mark Rittman at March 10, 2007 08:25 PM

Back at the start of February I mentioned that I was leaving my consulting job and moving in to the world of independent consultancy; now that the move is complete and I’ve started the new business up, I can finally start talking about what I’ve got planned for the future. As you’ve probably noticed from the new blog home, the name of my new venture is “Rittman Mead Consulting”, a joint venture by myself and a long-term friend and colleague, Jon Mead.

You obviously know me, but Jon is someone I’ve worked with for around four years on a number of Oracle business intelligence & data warehousing projects. Jon and I worked together at SolStonePlus as consulting managers, and around 18 months ago Jon left to join Rocela as Head of Business Intelligence, whilst I stayed on to be their Director of Consulting.

In the end I decided to move on and start up my own consulting business, following on from which Jon and I got talking, and decided to pool our resources and try and build something bigger. The end result is Rittman Mead Consulting, with our objective being to be the No.1 supplier of high-end business intelligence architecture, design, consulting and training resources in the Oracle market.

Jon and I will both be very hands-on, doing the consulting ourselves and working with customers in the UK, Europe and North America. I’d like to think that both of us built good reputations in the past for delivering solid solutions, making use of the latest technology and focusing on delivering results for the customer, and this is something we’re going to major on going in to the future. We’re also going to work closely with partners, both in terms of our peers who want specialist skills in a particular area, and when we have our own customers who, for example, need remote DBA support to go with a new data warehouse we build for them.

The business approach we’re using is to take on consulting projects of between a few days to a few months, both part and full-time, and for one of us to be available at all times. Over time, we plan to grow the business by attracting similarly-minded people to come and work with us; if what we’re doing sounds interesting, you’re currently working as an Oracle BI&W consultant, you’ve got a flexible, entrepreneurial streak, get in touch with us. Our model is companies such as Miracle, Pythian, Fog Creek Software and SourceGear, companies that only employ the best people but then go to great lengths to get the best out of them and develop their career; if these names mean something to you, and you’re a wizard with OWB, BI EE, Discoverer, OLAP and data warehousing, get in touch with us.

We’ve also put together a number of training courses, which we’ll either run internally for customers, or in combination with partners such as Miracle where we’ll jointly market the courses. Our training page lists the current courses, including a five-day “design to deployment” Oracle Warehouse Builder course where we look at data modelling, ETL, project lifecycle management and deployment to production. The aim here is to go beyond the standard OU courses and offer some real-world experience, tackling the business and technical issues that you only come across once you actually use the tools in your own work environment. Jon and I (together with Adrian Ward, which is another piece of news to come) will also be working on the Oracle Press “Oracle Business Intelligence Suite Developer’s Guide” book, so overall we’ll be balancing the consulting work with training and writing.

For the time being though, our focus is on building up a client list, having Jon and I work with them to exceed their expectations, and to advance the art (or is that science?) of building effective, scalable Oracle BI & data warehousing systems. We’ve already got our first customers, and we’d be delighted to work for you if you think we could add some value. The blog will still keep running, and Jon will be adding his own contributions as time goes by. Expect a few postings over the next few months on bootstrapping your own consultancy business, figuring out how to market yourself (for which Eric Sink’s “The Business of Software” is my guide), and trying to maintain the balance between growing a business and exploring new technology. Until then though, wish me luck and get in touch if you’d like some expert assistance with your Oracle BI&W project.

Blog Migration

Posted by admin at March 10, 2007 07:55 AM

If you’re reading this, it means the migration of my blog to the new company site has been successful.

I’ll post more news on what this means over the next few days, but for now, welcome to Rittman Mead Consulting, the name of our new consulting venture.

Using OWB10gR2 in a Production Environment … Revisited

Posted by admin at March 09, 2007 10:00 PM

A couple of weeks ago I posted an article on using Oracle Warehouse Builder 10gR2 in a production environment. Since then, I’ve had the opportunity to spend some time with customers doing just this, and I’ve come up with a few more observations that are worth adding to the original article.

In the original blog posting, I noted that most real-life customer deployments of Warehouse Builder involve more than one target database. This is probably still true, but it’s also worth noting that many customers, especially when they first start out, have a much simpler architecture, and it’s important not to over-complicate things too early on. In particular, I think now that the Multi-configuration feature in the Enterprise ETL Option is a bit of a red-herring, as in the vast majority of situations it’s just not needed. To explain this, I’ll firstly go through some typical customer deployments, and explain where all the various features come in.

The most typical deployment of Warehouse Builder 10gR2 is with a single database with both the repository and target schema in the same database, like this:

Simple OWB Setup

This kind of setup requires a single Control Center, which is contained within the repository used to hold the table and mapping designs.

A slightly more complicated setup is where you have a single repository, and a single target schema, but they are on different databases, like this:

Less simple OWB setup

In this case, you can still use a single Control Center, but it has to be the one on the database used by the target database. To do this, you install a new repository on the target database, register it in your project, and make this the default Control Center for your default configuration (right-click on DEFAULT_CONFIGURATION in the project, edit the properties and select the other control center, making sure you’ve registered the control center in the project beforehand.) Make sure you do this before you create your warehouse target module, then the location you set up will be owned by the correct Control Center. There’s no need to use multi-configuration to get access to this Control Center, you can just enable it by changing the Control Center assigned to the default configuration.

When it comes to deploying these two approaches to production, assuming production has the same tablespace names and table storage parameters as development, you can just create a production repository, export the development repository to an MDL file, and then import it into the production repository to promote the code. Multi-configuration only becomes relevant if you need to store different physical object properties for each environment, but most places I’ve been to don’t need this as development has the same tablespace names as the production environment.

A more complex setup, and one that I focused on in my original posting, was where you had two or more target databases that your project needed to deploy to. In my posting, I said that the only way you could do this was to use multi-configuration to re-point the Control Center Manager to each of the required Control Centers. Someone came back fairly quickly and reminded me that you could, as I’ve just explained, switch the control center associated with your default configuration using the Design Center GUI, and since then I’ve been working with clients on OMB*Plus scripting where this is even easier to do, like this:

OMBCONNECT username/password@host:port:sid

OMBCONNECT CONTROL_CENTER

…omb*plus code to deploy tables using the default control center…

OMBCONNECT SOME_OTHER_CONTROL_CENTER “password”

…omb*plus code to deploy tables to this other control center…

Again, therefore, multi-configuration, whilst it makes your life easier, is by no means a mandatory feature and you can deploy to more than one target database just as easily using standard, ETL Core features. Multi-configuration isn’t really the issue here; sure it lets you easily work with two or more control centers, but this isn’t the real use for it and you can achieve the same just as easy with standard features of the tool. Going from development to production is still the same case as before; you just export the project to an MDL file and import it into the production repository, then go through the same process to deploy to multiple control centers.

That said, most of the points I raised are still valid. You still need to be mindful of which control center owns your locations, as a given control center can only deploy and execute mappings against locations it owns, which must be on the same database as the control center. Versioning is still important, and OMB*Plus is the key to automating the move from development to production without introducing human error. There is a role for multi-configuration, and you can still use it as a way of using a single repository but storing deploying to different locations for development, test and production, but this isn’t the usual approach and it’s better to place the emphasis on what people actually do most of the time.

One thing that did come out of last week’s work was a lot of work on OMB*Plus; it made a lot of the above clearer as it helps expose what OWB is doing under the covers when you deploy tables and mappings; it also makes handling more complex environments a lot more managable because you can script everything. I’ve got a couple of issues left on some scripts I wrote that I need to sort out, but once I do, I’ll post a couple of articles on using OMB*Plus and how you can use it to help productionize an OWB deployment and work with these more complex setups. More on that in a few days, but I thought it worth going back to the original article as I think in retrospect it placed too much emphasis on multi-configuration, which as part of the Enterprise ETL Option isn’t cheap and isn’t actually a prerequisite when working with multi-database environments.

Vista unzip performance, PNG files and more

Posted by Ecco at March 08, 2007 10:09 AM

I) Unzip speed. I found an easy work around for my unzip issue; it's called PODP (Plain Old Dos Promt). Thanks to C. Spieler, I can execute unzip from the command line. C:\Users\erajkovi\Downloads>unzip sqldeveloper-1.1.2.2579-no-jre.zip -d \optII) Screen capture and files size. This may just be a fact: PNG is far from giving you a compression level that is comparable to JPEG on Windows Vista,

Error Handling in OWB10gR2

Posted by Mark Rittman at March 05, 2007 05:12 PM

I’m running a workshop for a customer tomorrow, who amongst other things wants to know how error handling works within OWB10gR2. As it’s a fairly involved process, I thought it worth jotting down the steps here in case anyone else is interested.

Typically, in a data warehouse load process, some of the data coming in to your staging area will have errors within in. For example, your business rules might require all customers to be over 18 years old, or data errors in your source system might lead to country codes quoted that don’t exist in your reference data.

In earlier versions of Warehouse Builder, you’d need to build mappings yourself to firstly identify those rows that contained errors, remove these from the source tables and then load the remaining clean rows into the data warehouse. In OWB10gR2 you can still use this approach, but if you’ve licensed the Data Quality Option for OWB10gR2, you can use the new data rules and error tables features to do all the work for you.

To take an example; we have two source tables, called SRC_CUSTOMER and SRC_COUNTRY. There are no constraints on these two tables, and the SRC_COUNTRY table contains a value, “London”, that isn’t a valid country, whilst the SRC_CUSTOMER table contains rows with ages under 18, and with country codes that don’t exist in the SRC_COUNTRY table.

Going in to Warehouse Builder, I import the two source tables in to the respository, and define two target warehouse tables with the same column definition. I don’t add any additional constraints to enforce these business rules (more on this in a moment), but instead create Data Rules to enforce the required business rules.

To enforce the list of allowable countries for the warehouse COUNTRY table, I define a domain list Data Rule that lists the set of allowable country values.

I then create another data rule, this time one that enforces a value being over 18 - I’ll attach this to the AGE column in the CUSTOMER table afterwards. 

Finally, I create a referential data rule that I’ll use later on to check the COUNTRY_ID in the CUSTOMER table to the same column in the COUNTRY table.

Now, I attach these Data Rules to the target warehouse tables. Note that this doesn’t create constraints on these tables, if you want these you need to create them yourself; however it causes Warehouse Builder to create additional “error tables” alongside your target warehouse tables into which it will place rows that breach these data rules.

To attach the data rules to the CUSTOMER table, I open it up in the Data Object Editor, click on the Data Rules tab, and associate the rules with the table, tying the rule parameters to the relevant table columns.

Note the ”Shadow Table” property in the Configuration window - that’s the name of the table Warehouse Builder will create to hold any rows that fail the data rule.

After assigning the remaining data rule to the COUNTRY table, I deploy the tables using the Control Center Manager and use SQL Developer to see what’s been deployed. Notice the error tables that accompany the target warehouse tables.

To use this data rule in a mapping, I create a mapping to take the data in the SRC_COUNTRY table and map it to the target warehouse COUNTRY table. When I add the COUNTRY table, now with a Data Rule attached to it, to the mapping, I now get an additional group that corresponds to the error table.

Still within the Mapping Editor, when I click on the COUNTRY target table and view the table operator properties, I can select what happens when rows fail the Data Rule. I can either ignore the violations, report on them or move the affected rows to the error table. This is specified for each data rule applied to the table.

After doing the same for the CUSTOMER target table, I’m ready to deploy the mappings.

Now, a major restriction of this functionality is that it only runs in row-based mode, which usually runs slower than set-based mode and is usually not well suited to high-volume mappings. Maybe in a future release, when OWB supports DML Error Logging, we’ll get set-based support as well, but for now, you have to modify the mapping to run in row-based mode only, and then deploy it to the target schema.

Once everything’s deployed, I can run the mappings and populate the error tables. Using SQL Developer, I can check out the contents of the error tables and see the rows that have failed the data rule - I can either specify a row in the error table per error, or one per source row, regardless of the error.

 

 

So that in a nutshell is error handling with OWB10gR2. It’s not quite the same as physical object constraints - the constraint is handled “virtually” by Warehouse Builder, and if you use physical constraints as well, your mapping will error as it used to do before (unless you create them disabled or in RELY mode). It also requires you to run your mapping in row-based mode, so it’s not going to be as fast as a set-based mapping where you’ve sorted out all the errors beforehand (or indeed, if you write your own error-handling routine in SQL and use DML Error Logging). But it’s a neat solution, and it drives the process entirely through metadata, so in certain circumstances it’ll be the best approach to handling data errors.

Join me at IOUG's Collaborate 07

Posted on An Expert's Guide to Oracle Technology at March 05, 2007 07:48 AM

COLLABORATE 07 - IOUG Forum Technology and Applications Forum for the Oracle Community April 15-19, 2007 Mandalay Bay Resort and Convention Center Las Vegas , NV Attend Lewis Cunningham's Sessions at COLLABORATE 07 - IOUG Forum Session Code: 112 - Integrating EnterpriseDB in your Oracle Environment, Tuesday April 17, 9:45 - 10:45 Session Code: 474 - Building Reports with Oracle SQL Developer, Monday April 16, 3:3

Off to Iceland, and Thoughts on Hyperion

Posted by Mark Rittman at March 04, 2007 12:37 PM

It’s 9.40am on Sunday morning, and I’m writing this sitting on the train up to Heathrow Airport. Next week is the first full week for my consulting startup and I’m flying off to Reyjavik to do some work with the very nice people over at Miracle Iceland. Ben and the team have a number of BI & data warehousing clients, and I’m working with some of these clients and his team on a few of their projects. One of the things my company is looking to do is to partner with smaller, expert-level consultancies such as Miracle, and we’ll be looking to do similar things with complementary companies in the USA, Europe and ASIAPAC.

Anyway, whilst I’m on the train, it’s an appropriate moment to think about some of the impact and repercussions of Oracle’s proposed takeover of Hyperion. Whilst many of us were caught by surprise by the move (including most people within Oracle, I suspect) the business logic does in fact look pretty compelling, and I think this is a hugely positive move by Oracle. Whilst in the past, there’s been criticism of how Oracle have incorporated previous BI purchases (more on this in a minute), in recent times, the purchases and integration of Peoplesoft, Siebel and the SOA/Identity Management companies have all subsequently been seen as well executed.

In fact, given how the Siebel acquisition went, you can probably expect more changes within Oracle than within the Hyperion team when the takeover is bedded in - if you look at the org chart within Oracle BI product management post- the Siebel and Peoplesoft acquisitions, most of the key roles now are taken by ex-Siebel and Peoplesoft people, with Siebel management taking over BI tools management, and Peoplesoft EPM management taking over Oracle CPM management. Going in to the future, you can certainly see the Hyperion management and sales staff moving over wholesale into a new BI Enterprise Performance Management team at Oracle and driving the business using a distinctly Hyperion style - which will be good for Hyperion’s existing customers, and good for the wider Oracle customer base given their success in the past.

Looking back at my comments when the takeover news broke, my thoughts were mainly around Essbase and how this would relate to Oracle’s existing OLAP server, the OLAP Option to Oracle Database 10g. This is understandable; they are both very capable OLAP servers, both have very strong advocates, and often went head-to-head on customer proof of concept engagements. I’ve heard similar concerns about Discoverer; does this mean the end of Discoverer, will Brio take over, will all the attention now move decisively toward BI EE and the new Hyperion applications? Or, perhaps worse - will customer confusion mean that they won’t buy anything or start any new projects, or even migrate across to tools and applications by other vendors?

The thing is though, to think of this in terms of Essbase vs. Oracle OLAP, or Brio vs. Discoverer, or even Hyperion’s applications vs. Peoplesoft EPM is, I think, to miss the scale or the enormity of what’s going on. What this is really about is Oracle vs. SAP - all Oracle does now, strategically, is framed in it’s desire to be the number one enterprise software vendor, which means being the number one ERP vendor, as all else flows from that. Oracle now is an ERP vendor with a nice sideline in databases and development tools, not the other way around, and they’ll happily live with a more heterogeneous tools and technology environment if it means they can get closer to that goal.

I remember going to Open World or user group presentations only three years ago and hearing the message - get your data on to an Oracle database, move your business on to Oracle E-Business Suite and use Oracle’s infrastructure - then we can start talking. Nowadays, in a process driven by people like Thomas Kurian, and by the people coming in from the various acquisitions, it’s all about a larger goal, one that’s much bigger than just those customers who’ve standardized on Oracle technology. Buying Essbase doesn’t therefore necessarily lead to Oracle OLAP being discontinued - they’ve got very different architecture and one is more suited to certain situations than the other.

Similarly, Brio underpins much of Hyperion’s financial applications, whilst Discoverer provides much of the ad-hoc reporting for a very large percentage of E-Business Suite customers, so why alienate these customers by de-emphasising or desupporting their products? I think over the last few years, Oracle has done a very good job in extending and enhancing the products they’ve bought, and whilst obviously in time, Oracle will want to migrate them all to a common, next-generation platform, in the meantime there’s very good business to be had in supporting existing customers, and upselling them all the other technology that Oracle can offer.

That said though, it is a pretty significant event that Oracle have bought Essbase, the most obvious, direct rival to Oracle OLAP and one that frankly, has beaten Oracle OLAP hands-down in the market over the past five years. Integrating Essbase, and it’s salespeople and technologists, into Oracle will be a very bitter pill to swallow for many Express and IRI veterans, a bit like George Graham becoming manager of Tottenham Hotspur to use an analogy close to my heart. Whilst the architecture of Oracle OLAP is, in my opinion, superior to Essbase (and there are as many advocates on the Essbase side who would beg to differ), what’s happened to the product over the past five years has been nothing short of a tragedy, and one that is largely made up of Oracle shooting itself in the foot, repeatedly.

To go back five years: both Essbase, and Oracle Express Server, the predecessor to Oracle OLAP, both had similar architectures. They were standalone multi-dimensional OLAP (MOLAP) servers, with their own suite of applications (OFA and OSA for Express, plus developer tools such as Express Objects and Web Agent), and similar market share (Essbase around 30%, Express around 20%). Now over that time, both tools have been affected by the introduction of Microsoft Analysis Services and the subsequent commoditization of what was previously, a very high-cost market, but the paths taken by the two companies have been very different.

Essbase was originally owned by a company called Arbor, who had their own relationship with IBM and Microsoft but saw the writing on the wall with Microsoft’s move into the OLAP market. It decided to deal with the issue by merging with a much larger company called Hyperion Software, who sold analytical applications that Arbor believed would complement their OLAP solutions. Now, over a period of several years after the merger, this new merged company went through it’s own problems (see Nigel Pendse’s OLAP Report, subscription required, for the full historical story) but over time, they bought other complementary companies (including Brio Software) and created their own niche in the Enterprise Performance Management area. They did dabble with database integration - IBM’s DB2 being the chosen platform - but they let IBM do all the work and when it didn’t sell, it was IBM’s problem not Hyperion’s, and they didn’t get sidetracked from the core, MOLAP message. Now over the past five years, Essbase’s market share has fallen from 30% to 20%, but the company itself has held up through selling wider, integrated solutions to the CFO, and of course now has sold out to Oracle for around $3bn, quite a turnaround from their near-disaster following the merger in 1999/2000.

For Oracle’s OLAP offerings though, it’s been a different story. Oracle announced in 2000 that Express was going to be replaced, and enhanced by a new database-integrated OLAP server called Oracle OLAP. The idea was laudable and well received at the time - take the OLAP engine, which in it’s standalone form is dogged by scalability and manageability concerns, but nonetheless runs faster than it’s relational cousin - and embed it in the Oracle database, allowing you to benefit from the enterprise-class scalability and performance of the Oracle database.

The problem however was in the execution; it took Oracle until Oracle 9i Release 2, and more honestly, 10g Release 1 and 10g Release 2, before you had a product that was stable and functional enough to replace Express Server. Oracle took the decision back in 2000 to remove the client-server SNAPI interface and replace it with an internet-enabled, Java API, which whilst in itself a laudable aim meant that OFA and OSA wouldn’t work on this new architecture. All the existing customers of OFA, OSA and custom-build Express applications had to wait until BI Beans became available - an order of magnitude more complex to develop with compared to Express Objects and Web Agent - or, even worse, until Enterprise Planning and Budgeting became available. If only they’d made Oracle OLAP compatible with SNAPI, all the existing OFA and OSA customers could have migrated to Oracle OLAP, kept their existing applications in place, and then migrated in time to the new, Java-based applications.

Couple that with the needless diversion into ROLAP storage, which never performs as well (Essbase and MS AS offered this same option, but no-one uses it as it just doesn’t perform as well as MOLAP storage),the steadfast refusal to support MDX or XML/A, and constant changes over the five years to APIs and metadata, and you eventually end up with a situation where you have a product with an excellent architecture, amazing scalability and functionality, but no customers. Compared to Essbase, Oracle OLAP’s market share has fallen from around 20% five years ago to around 4% now. Oracle made the right decision back in 2000 to enable Express for the internet, and to embed Oracle OLAP in the database - that’s where BI data should be held - but the market read it as five wasted years of architectural navel gazing and the competition - Hyperion with their financial apps and Microsoft with their low cost and wide developer base - got on with the job of winning new customers.

The ironic thing is - where they are now, it’s a superb product. SQL access, accompanied by MDX and XML/A support, with the scalability of Oracle Database 10g - that’d be a world beating product, were it not for the fact that the horse has bolted, unfortunately. That said, from my conversations with customers and attendees at my BI seminars, Oracle are starting to pick up interest now from relational data warehousing customers who are looking to supplement their relational star schemas and MVs with analytic workspaces, and now the tools are so easy to use (AWM 10.2.0.3, OWB 10.2) it’s relatively straightforward and painless to add AWs to your relational data warehouse. Things look bright for Oracle Database 11g as well - from reading the tea leaves at Oracle Open World, AWs and relational storage are starting to come together in a vision that was originally put forward by Oracle with the Oracle 9i OLAP release, where DBAs will be able to switch MVs and AWs interchangeabily with the same tools and SQL techniques used for both forms of storage.

Still, that’s all history now, and certainly with the purchase of Hyperion Solutions, and the previous moves on Siebel and Peoplesoft, it’s clear that firstly, Oracle are seriously delivering on their vision of encircling and then beating SAP in the enterprise software stakes, and secondly, they’re deadly serious about BI, even if it means admitting mistakes in execution in the past. Given what Oracle are offering now - powerful, integrated OLAP in the database, OLAP-enabled “best of breed” financial applications for the CFO, and a powerful, RAD-enabled BI development toolset in BI Enterprise Edition, they’ve certainly got all their bases covered when compared to platform vendors such as MS and IBM, and BI specialists such as Cognos and BO.

The interesting thing, going into the future, will be seeing what elements of each package emerge when Oracle start delivering the BI components of their forthcoming Fusion range of applications. I suspect the Hyperion products will play a very large part in this future architecture - BI Suite EE will provide the business analytics for mid-managers, whilst Hyperion’s products will provide enterprise performance management for the C-level customers. Should be interesting, and in the meantime I’ll be keeping an eye on edelivery.oracle.com after the merger goes through to see when the products become available for download.

Unit testing Swing components - impossible?

Posted by Brian Duff at March 04, 2007 12:40 AM

This entry is cross posted from duffblog 2.0. It may be more readable there...

Testing Swing components seems to fill many developers with fear. "How can I unit test this thing?" they often ask, "it's full of icky event handling code and troublesome painting...".

Frameworks such as Abbot are often the solution developers find for this problem. Essentially, many developers abandon the idea of writing regular unit tests for Swing components, and resort to "click simulators" which are frequently integration tests rather than unit tests.

There is a lot you can do just to test regular Swing components using bog-standard JUnit (or Test-NG) tests. Consider the following fairly basic Swing component.

package org.dubh.blog;

import java.awt.Graphics;

import java.awt.event.MouseAdapter;

import java.awt.event.MouseEvent;

import java.util.List;

import java.util.concurrent.CopyOnWriteArrayList;

import javax.swing.JComponent;

/**
 * A user interface widget.
 */
public final class Widget extends JComponent {
  
  private List<WidgetListener> _listeners = 
    new CopyOnWriteArrayList<WidgetListener>();
  private String _label = "";
  
  public Widget() {
    // Just for demonstration purposes.
    addMouseListenernew MouseAdapter() {
      public void mouseClickedMouseEvent e ) {
        if e.getButton() != MouseEvent.BUTTON1 return;
        fireWidgetClicked();
      }
    });
  }
  
  /**
   * Adds a listener. 
   
   @param wl listener to add. Must not be null.
   * @category Event handling
   */
  public void addWidgetListenerWidgetListener wl ) {
    if wl == null throw new NullPointerException"wl is null" );
    
    _listeners.addwl );
  }
  
  /**
   * Removes a listener.
   
   @param wl listener to remove.
   * @category Event handling
   */
  public void removeWidgetListenerWidgetListener wl ) {
    _listeners.removewl );
  }
  
  /**
   * Notifies listeners that the widget was clicked.
   
   * @category Event handling
   */
  protected void fireWidgetClicked() {
    if _listeners.isEmpty() ) return;
    
    WidgetEvent event = new WidgetEventthis );
    for WidgetListener l : _listeners ) {
      l.widgetClickedevent );
    }
  }
  
  /**
   * Sets the label of the widget.
   
   @param label a widget label. Null is allowed, will be 
   *    converted to the empty string.
   */
  public void setLabelString label ) {
    if label == null label = "";
    if label.equals_label ) ) return;
    
    String oldLabel = _label;
    _label = label;
    repaint();
    firePropertyChange"label", oldLabel, label );
  }
  
  /**
   * Returns the label of the widget. 
   
   @return the label of the widget. Never returns null.
   */
  public String getLabel() {
    return _label;
  }
  
  @Override
  public void paintComponent(Graphics g) {
    g.drawString_label, 0, getHeight() );
  }
}

We can start off with the really simple stuff. Let's at least test that we can make new instances of Widget.

  public void testConstructor() {
    new Widget();
  }

Seems pretty dumb? Well... that constructor contains code, so maybe it could throw an exception. It'd be good to catch this when running our tests rather than when the code is out running in production. If you can do nothing else, at least constructing a class in a test is better than no test at all. But wait! There's a lot more we can do here. What about testing the pretty boring setLabel() / getLabel() set?

  public void testGetAndSetLabel() {
    Widget widget = new Widget();
    // Test the initial state.
    assertEquals"", widget.getLabel() );
    // Test setting and getting.
    widget.setLabel"Hello!" );
    assertEquals"Hello!", widget.getLabel() );
    // Test edge case ( null label )
    widget.setLabelnull );
    assertEquals"", widget.getLabel() );
  }

OK.. this is a bit more meaty. We're testing some real assertions here. Now for the "hard" stuff. How can we test events? Well... Ignore the fact that these are events for now, and just look at the code for what it is. The management of listeners and the sending of events doesn't actually require AWT in most Swing components. Even if it did, we're not testing AWT here, we're testing Widget.

Let's use a common technique for testing listeners - introduce an inner class that provides a stub listener which simply tracks the events it receives:

  private class WidgetListenerStub implements WidgetListener {
    List<WidgetEvent> receivedEvents = new ArrayList<WidgetEvent>();

    public void widgetClicked(WidgetEvent e) {
      receivedEvents.add);
    }
  }

Now testing that we can add and remove widget listeners and receive events is easy:

  public void testWidgetListeners() {
    Widget widget = new Widget();
    
    // Test firing when there are no listeners.
    widget.fireWidgetClicked();
    
    WidgetListenerStub l = new WidgetListenerStub();
    widget.addWidgetListener);
    
    widget.fireWidgetClicked();
    assertEquals1, l.receivedEvents.size() );
    assertSamewidget, l.receivedEvents.get).getSource() );
    
    widget.removeWidgetListener);
    widget.fireWidgetClicked();
    assertEquals1, l.receivedEvents.size() );
  }

OK... what hasn't been tested yet? Well, we probably want to test multiple listeners and property change event notifications. Those are a pretty easy extrapolation from the example above.

One thing we haven't tested yet is that actually clicking in the widget with the mouse causes WidgetEvents to be fired. To do this, we don't have to actually test that a low level operating system mouse click event will cause our event to be fired. In other words, again, we're not testing AWT. We trust that Sun did a good job testing AWT already. No Robots required. Let's focus on events just at the level of our component, using a bit of reflection magic:

  public void testMouseClickTriggersEvent() throws Exception {
    Widget widget = new Widget();
    WidgetListenerStub stub = new WidgetListenerStub();
    widget.addWidgetListenerstub );
    
    // Simulate a mouse click using reflection.
    MouseEvent event = new MouseEventwidget, MouseEvent.MOUSE_CLICKED, 0
      MouseEvent.BUTTON1_MASK, 10101false );
    Method process = Component.class.getDeclaredMethod
      "processEvent", AWTEvent.class );
    process.setAccessibletrue );
    process.invokewidget, event );
    
    assertEquals1, stub.receivedEvents.size() );
    
  }

We're sending a mouse event directly to our widget component, and verifying that it causes the Widget to fire a WidgetEvent as expected. The really cool thing about this is that this does not require the component to be visible on screen, and it doesn't require native AWT event handling. Indeed, this test works perfectly fine even in headless mode (when the system property java.awt.headless=true, or you're running on a system with no graphics display).

One last thing we haven't tested: paintComponent(). This is arguably the toughest thing of all to test. Like the constructor example, it's at least a good idea to call this method in a test and make sure no exceptions occur. We can go a little bit further and actually test that paintComponent really painted something. More on that in my older blog entry, Unit Tesing: Coverage in Those Hard to Reach Places.

While frameworks like Abbot have their place, it's a lot easier to test Swing components with regular JUnit or Test-NG tests than you might think.

Oracle Buys Hyperion

Posted on An Expert's Guide to Oracle Technology at March 02, 2007 08:34 AM

Well, this is big news but Vincent McBurney beat me to it. Which is ok since he did such a good job of it. If you read down to the comments, Dratz added the topics I was planning to add. I have a pretty extensive background with Brio (now Hyperion). I first used it when I started a contract with Yale in 1997. That was an Oracle applications imple

Check parameters for validity... good advice!

Posted by Brian Duff at March 02, 2007 05:10 AM

This item is cross posted from duffblog 2.0. It may be more readable there...

I recently ran into a weird NullPointerException in part of our code:

Exception in thread "main" java.lang.NullPointerException 
at org.dubh.blog.Graph$Vertex.access$000(Graph.java:17)
at org.dubh.blog.Graph.getVerticesConnectedTo(Graph.java:14)
at org.dubh.blog.Graph.main(Graph.java:26)

Hmm... access$000? That's odd. The code looked something like this:

  01 package org.dubh.blog;
02 
03 import java.util.ArrayList;
04 import java.util.HashMap;
05 import java.util.List;
06 
07 final class Graph
08 {
09   private HashMap _vertices = new HashMap();
10 
11   public List getVerticesConnectedToObject vertexKey )
12   {
13     Vertex vertex = (Vertex_vertices.getvertexKey );
14     return vertex.fromEdges;
15   }
16 
17   private final class Vertex
18   {
19    private final List fromEdges = new ArrayList();
20  }
21   
22   public static void mainString[] args )
23   {
24     Graph graph = new Graph();
25     graph.getVerticesConnectedTogetSomeVertex() );
26   }
27 }

Can you tell quickly from looking at these two pieces of information what the problem is?

It turns out that getSomeVertex() was returning null, and this was being passed in as the value of vertexKey. Unlike its older cousin, Hashtable, which would throw a NullPointerException if you tried to get null, HashMap.get( null ) returns null, so the vertex variable in getVerticesConnectedTo() was also null.

OK... so why did the NullPointerException happen on line 17 (which is the inner class declaration), instead of line 14, which is where we're actually dereferencing the null variable? Well, it's because the Java compiler creates a super-secret static method for accessing the fields of inner classes. With the geeky power of javap, you can see it being called in the bytecode:

public java.util.List getVerticesConnectedTo(java.lang.Object);
  Code:
   0:   aload_0
   1:   getfield        #4; //Field _vertices:Ljava/util/HashMap;
   4:   aload_1
   5:   invokevirtual   #5; //Method java/util/HashMap.get:(Ljava/lang/Object;)Ljava/lang/Object;
   8:   checkcast       #6; //class org/dubh/blog/Graph$Vertex
   11:  astore_2   12:  aload_2
   13:  invokestatic    #7; //Method org/dubh/blog/Graph$Vertex.access$000:(Lorg/dubh/blog/Graph$Vertex;)Ljava/util/List;
   16:  areturn

If the generated method were written in Java it would look something like this:

    private final class Vertex
{
  private final List fromEdges = new ArrayList();

  private static List access$000Vertex instance )
  {
    return instance.fromEdges;
  }
}

Now the reason for the NPE happening before vertex is dereferenced on line 14 is pretty obvious.

Two lessons from this:

1) Follow Josh Bloch's Advice in Effective Java - "Item 23: Check parameters for validity"

A simple null check in the getVerticesConnectedTo method would have produced a much more readable exception:

public List getVerticesConnectedToObject vertex )
{
  if vertex == null throw new NullPointerException"vertex is null" );
  ...
}

Yields:

Exception in thread "main" java.lang.NullPointerException: vertex is null 
at org.dubh.blog.Graph.getVerticesConnectedTo(Graph.java:13)
at org.dubh.blog.Graph.main(Graph.java:27)

2) It's almost always better to access fields from other classes using method calls. Even in private inner classes.

It would have been better if the Vertex inner class above had provided an accessor method for the fromEdges field. If it had, the exception would have been clearer.  A few people worry about the performance of method calls vs. field access. Remember that performance solutions aren't solutions until you can prove as much using a profiler, and that the point is somewhat moot in the above case, since there's effectively a static method call rather than a getfield in the generated bytecode anyway, canceling out the programmer's misguided attempt to save cycles and / or typing. Cough... the programmer in this case, of course, being me :)

Visit duffblog 2.0

Posted by Brian Duff at March 02, 2007 05:05 AM

I've started a new blog, Duffblog 2.0, which will be dedicated to not-necessarily-Oracle related stuff such as general Java coding. You can find it here:

http://blog.dubh.org

For a while, I'll probably cross post Java related articles both to the old and new blogs, and keep my blogs.oracle.com blog for purely Oracle related stuff (e.g. for JDeveloper and SQL Developer)

Note: if you have trouble reaching blog.dubh.org, try again in a couple of days. It's a new DNS entry, so might take a wee while to propagate.

JAX-WS 2.1 : First spin.

Posted by Ecco at March 01, 2007 11:53 PM

JAX-WS 2.1 is out. Here is a blog entry that will give you all the details you need: see the Fast & Furious. For me, it means it's time to give it a try and build some interface to PayPal Web services. The performance improvement seams to be worth a closer look.In my current project, I have start to look at performance between different implementations for a given Business Process, and I am

“Oracle to Buy Hyperion” - New York Times, CNN

Posted by Mark Rittman at March 01, 2007 06:54 AM

“NEW YORK (Reuters) — Oracle Corp., the world’s top database software maker, is near an agreement to buy Hyperion Solutions Corp., which makes software that lets companies analyze and track their performance, for about $3 billion, The New York Times said on Wednesday in its online edition.

The transaction is expected to be announced as soon as Thursday, and terms were not immediately available, the newspaper said citing unnamed people briefed on the transaction.”

See articles at CNN, New York Times and Houston Chronicle. Hyperion is of course the maker of Essbase, a product I’ve described in the past as “Express done properly” in that they focused on a single product, didn’t get tied up in integrating it with a database, and instead focused on a particular niche, in their case financial analytics. Essbase as a technology is on a par with Express Server and no doubt what Oracle are interested in here is Hyperion’s expertize in the area of analytic financial applications, and their no doubt high-value customer base.

It’ll be interesting to see where they take the Essbase technology - I expect, like Peoplesoft and E-Business Suite, they’ll maintain the two code streams and at some point, incorporate some of the best bits of Essbase in Oracle OLAP - and of course Hyperion own Brio, a ROLAP reporting tool not too dissimilar to Discoverer.

Still, the rumour looks fairly well corrobated and it’ll be interesting to see the industry analysts’ reactions - will it be seen as two legacy OLAP vendors clinging together in the face of Microsoft Analysis Services’s inexorable rise in market share, or will it finally give Oracle access to best-of-breed financial MOLAP applications to sell alongside the mostly ROLAP BI Suite Enterprise Edition? Interesting times indeed.

Catching up

Posted on An Expert's Guide to Oracle Technology at February 28, 2007 08:42 PM

Hi all. I promise that the final entry in my streams series will be posted shortly. It's mostly written. It just needs to be cleaned up and made presentable. I just uploaded my white paper to the IOUG site. I'll be speaking there in April. In case you don't know, IOUG is in Las Vegas this year. I don't drink or gamble (much anyway) so Las Vegas is not as exciting to me as say New York, New Orleans or San Francisco but I think I will enjoy it. I will also be speaking at ODTUG in June. I

Vista and the integrated unzip feature, tips wanted?

Posted by Ecco at February 28, 2007 08:09 PM

If you have any tips to share, please drop me a comment here. It may help other as well... So far, the only result I got from Google are this "Worse Than Failure" entry with screen shoot similar to mine, and an entry from Microsoft's support that seams off topic... Here is how the process started. After I got started on search the net and into the mood that trigger this entry, it got even

Leaving Madrid, and Leaving Work

Posted by Mark Rittman at February 28, 2007 05:48 PM

I’m currently sitting in the departures lounge at Madrid Airport, having just completed the latest round of my BI Seminar at the Oracle offices in town. This is actually quite an auspicious date for myself, as it’s the last day at my current employers, and from tomorrow I’ll be out in the big wide world of self-employment. More on that later.

The trip to Spain didn’t start out so well as yet again, some honest looking person (a business man in a suit, no less) outside the airport told me some story about having lost his wallet, and could I lend him 30 euros so he could get a taxi home. I fell for this once before, with some dishevelled looking bloke at Liverpool Lime Street station telling me he’d lost his ticket and could I possibly help out. In the end I bought him a ticket and gave him my address to send the money to; surprise surprise after a week or so nothing turned up.

This time though, the person involved looked pretty honest, and I thought that I’d like someone to help me out if I was in the same situation. Anyway, I left him my email address for him to PayPal me the money, and, yet again - nothing. I don’t doubt he actually had lost his wallet, but I suspect, when he thought about it the next day, he’d never see me again and it was just as easy to not send the money on. You live and learn.

Anyway, I got to the hotel and after ringing on the bell for about 10 minutes (it was about 10pm and the hotel was in a residential area) someone eventually answered and let me in. After checking in I asked if there was a restaurant or a bar - no there wasn’t actually, and in addition there were no ironing board to go with the (probably broken, they thought) iron. In the end, my rat-like consultant’s cunning kicked in and I was able to create a meal out of snacks harvested from a vending machine, and iron my shirt on a towel placed on a desk.

Anyway, I got to the Oracle office the next day, and the next thing that threw me was the course timetable. Normally, I run four 1.5 hour sessions (a tip from Jonathan Lewis) each day, however in Spain, apparently you work through until about 3pm, then have a long lunch, then come back. Therefore I had to fit my all my four sessions into the “morning”, and get through until 3pm without lunch when we finished for the day (the hotel did provide a buffet breakfast, luckily). Anyway, I was starting to think that this would be a seminar trip where I actually starved to death, but in the end the time went fairly quickly and I found a bar around the corner from the hotel where I could get something to eat around 4ish.

Anyway, the next surprise was that I had two translators provided by Oracle, who sat in a little booth at the back of the room and translated my seminar in real-time. I’ve heard in the past that this can be a little unusual at the start, as some languages (Italian, for example) take a lot more words to say the same thing compared to English. In the end, it worked pretty well - the translators were “Oracle technology-aware” and even raised a few laughs when they translated my poor attempts at humour. One of the unexpected benefits of being translated is that you end up speaking slower and clearer, and you think a bit more about what you’re saying, so I think in actual fact it was probably one of the best received seminars I’ve done.

For now though, the event has finished and I’m back at the airport waiting to go back. You can’t help liking Spain as it reminds you so much of holidays and summer, and apart from getting mugged at the airport and surviving on crisps and water on the first night, again it’s been a great two days. I’m starting to work now on a new seminar for the next Oracle financial year, and this time around, we’ll be able to dig down further with the technology as people will have had more time to use it themselves. For now, I’m thinking about BI EE and SOA, Oracle Data Integrator and Data Mining, but of course although the new cutting-edge stuff is interesting, in reality people are generally working with what’s available now, specifically BI SE and how it’s going to integrate with the new BI EE technologies. We’ll have to wait and see.

Anyway, that’s it for me now. As I said earlier, today’s my last day as Director of Consulting at SolStonePlus, and from tomorrow, I’ll be employee No.1 of my own new startup company. Keep and eye on this site over the next few days and weeks as more details become public, but for me, and for those that will be joining me, this is going to be a pretty exciting time.

Bye for now.

Debugging slow processes on Linux

Posted by Brian Duff at February 23, 2007 01:32 AM

Always pesky... Was using JDeveloper yesterday, navigated to one of the directories corresponding to our source control system (/ade) in the file chooser, and the product completely stalled for several minutes on the AWT event thread doing an I/O operation, and never came back.

I switched to bash, and tried an ls on the directory:

ls /ade
Yikes. This also stalled in a classic un-ctrl-c-able hang-of-death. I've used the strace command to diagnose this kind of thing in the past. First I tried this:
strace -e trace=file ls /ade
This tells strace to run the 'ls' command, tracing all file related kernel calls to stdout. Surprisingly, this completed instantly. It then occurred to me that (like most linux distros), RHEL 4 comes configured out of the box so that ls is aliased to show colors. Perhaps the extra work needed to get the colors was the problem? Let's try this:
strace -e trace=file ls --color=auto
Aha... now strace trundled along for a bit, then stalled on a call to fstat on /ade/jsmith_view. Something was afoot with that directory. First step, make sure to unalias ls so that I can use it again:
unalias ls
Now find out a bit more about that directory.
ls -l /ade | grep jsmith_view
From this I could see that /ade/jsmith_view was a symlink to /net/stbbo08/ade/jsmith_view. /net is configured in /etc/auto.master to automount NFS exports. A quick ping confirmed that stbbo08 was inaccessible. Presumably NFS is taking aeons to time out. Since jsmith isn't actively using this machine right now, I purged the /ade/jsmith_view symlink using a quick rm.

Fun stuff - strace really is very useful for this kind of thing. I used to use FileMon and APIMon a bit back when I worked on a Windows machine for similar purposes...

SOAPFaultException: IllegalArgumentException: Decoding tip

Posted by Ecco at February 20, 2007 12:46 PM

As part of my ongoing work on the SOA and SCA (Society of Confused Architects) bandwagon, I have a new not-so-easy error to explain and share with you. Here is how the error will reads from the client side, when using Oracle Web Services tech Stack on the 10gR3 releases: javax.xml.rpc.soap.SOAPFaultException: Caught exception while handling request: deserialization error:

Miracle Scotland Database Forum, May 2007

Posted by Mark Rittman at February 18, 2007 09:14 PM

Although I’ve been lucky enough to go to a number of user group events in the past few years, one event I’ve always ended up missing out on is the Miracle Database Forum over in Denmark. Well, Thomas Presslie has just announced the Miracle Scotland Database Forum up in Edinburgh on May 29th to 31st, and I’m definately not going to miss out on this one.

Looking through the speaker list, there’s some familiar names such as Jonathan Lewis, James Morle, Doug Burns, Mogens Nørgaard, Carel-Jan Engel and Anjo Kolk, plus some others that I’ve either met briefly or have heard good words about such as Kurt Van Meerbeeck, Alex Gorbachev and Dan Fink. What particularly appeals to me (apart from the social aspect, of course) is the chance to spend a few days dedicated to database presentations; the majority of what I do, even though mostly focused around tools, comes down in the end to the database, and knowing for example how to trace an ETL job, understand how parallel query works, how the CBO parses a query or how to design a scalable system is essential to what I do. I’m trying to persuade a few other Database Forum virgins such as Peter Scott to come up, but otherwise, I’ll travel up there on the Thursday on my own and try and get to meet some of the other hundred or so attendees.

My only concern is the bit about sharing a room; like Tom Kyte once said (I think), the thought of sharing with strangers usually brings me out in a panic, but as sharing seems to be the tradition for Database Forum events, I might as well go for it -although as I sometimes snore I guess I ought to put Bill (Shrek) Thater down as my suggested room-mate…

Anyway, as Thomas is doing a sterling bit of community service in putting the event together, and moreover as it sounds like an excellent way to spend a few days, get yourself over to the event Web page and register before the limited amount of places are gone. And hopefully, I’ll see you there…

User Groups and Forums

Posted by Mark Rittman at February 18, 2007 08:50 PM

Although I’m going freelance from March 1st, one thing I intend to keep up is attending and presenting at user groups. They’re always great fun to attend, and they’re a fantastic opportunity to share ideas and experiences. I’ve been a member of the UK Oracle User Group for around seven years, and I’ve chaired the UKOUG Business Intelligence & Reporting Tools SIG for three years; I’m also a member of the IOUG and ODTUG, and went over to their conferences (here, here) for the first time last year.

With this all in mind, I’ve signed up to do a number of presentations at the various user group events over the next few months, mostly around Oracle BI Suite Enterprise Edition, Discoverer migration, Oracle Warehouse Builder 10gR2 and Oracle Data Integrator. Here’s the details:

The presentation on Oracle BI Suite Enterprise Edition for Discoverer Users should be a particularly interesting one, as I’m doing it in collaboration with Mike Durran, Oracle product manager for Discoverer; we’ll be looking at the possibilities Oracle BI EE provides for users of Discoverer, what you might expect out of an upgraded system, how you can migrate from Discoverer to BI EE, and how you can interoperate if you choose to stick with Discoverer but want to use BI EE features such as Delivers, BI Publisher and so on. Mike and I will be demonstrating the Discoverer to BI EE migration utility, and I’ll demonstrate a migrated version of the Videostore dataset running in Oracle Interactive Dashboards.

The Data Integrator for OWB Developers talk will go through the ODI architecture, relate it to Oracle Warehouse Builder but also put it in the context of Fusion Middleware and Oracle BI EE. Where I’m coming from with this is to put the product in context, try and show how it relates to OWB, show the differences in it’s approach (Knowledge Modules, how it provides change data capture and SCD handling across different platforms and so on). With both of these two presentations, the driver for me is to try and hook up with organizations looking to migrate or interoperate Discoverer with BI EE, or who want to use some of the advanced features in ODI to enhance their data integration efforts.

The OWB Lifecycle presentation is all around the issues and technology involved in taking an OWB project from a laptop proof-of-concept to a full, production system. I blogged about this the other day, and again I’m looking to start debate and discussions around how the new free, and paid-for, features in OWB10gR2 are used when deploying into a real-life environment.

Finally, I’ll be attending the Collaborate’07 event and the Miracle Scotland Database Forum as a “civilian”, in that for once I’ll be a paying customer (sort of, I’m going to the Collaborate event as a guest of the UKOUG, which is very kind of them), which although It’ll be a bit strange, it’ll actually be nice for once to not have to worry about presenting and instead sit back and listen to all the great speakers. I’ll write something extra about the Miracle Scotland event in a few moments. Until then, expect some postings around these subjects as I work out the material.

Log Buffer #32: a Carnival of the Vanities for DBAs

Posted on An Expert's Guide to Oracle Technology at February 16, 2007 11:54 AM

Welcome, to the 32nd edition of Log Buffer, the weekly survey of database blogs. What shall I talk about? Hmmm, maybe I'll start with the Oracle blogosphere. Might as well get started with controversy by reading an entry by Dean at the Oracle Contractors Blog. Dean asks if a $5 haircut is a fair price if the service you get sucks in "

Oracle and ISO 8601 dates

Posted by Brian Duff at February 16, 2007 01:33 AM

The nifty Oracle TIMESTAMP column type is very useful, particularly if your database might be in a different time zone from your client and you want to make sure that you normalize times properly.

If you care about time zone information, be sure to use the TIME ZONE option when creating the column:

CREATE TABLE THING (  
"NAME" VARCHAR2(100), 
"START_DATE" TIMESTAMP(6) WITH TIME ZONE
DEFAULT SYSTIMESTAMP NOT NULL ENABLE );
Insert a row...

INSERT INTO THING( NAME ) VALUES ( 'Brian' );

Now, grab an ISO-8601 date with time zone information:

SELECT TO_CHAR( START_DATE, 'YYYY-MM-DD HH24:MI:SStzhtzm' );

SD
========================
2007-02-15 19:21:57-0800

Running OWB10gR2 in a Production Environment

Posted by Mark Rittman at February 14, 2007 10:42 PM

I’ve been giving some thought recently to how Oracle Warehouse Builder 10gR2 is configured and used when working in a production environment. Most people who “kick the tires” with OWB10gR2 do so on their own laptop, or on their own pc, with a local database on which the repository, source tables and target environment are all held. In real life though, things are often a bit more complicated:

  • In production, you often have your source data on one or more databases, your repository on another, and the target data warehouse environment is usually on another box altogether.
  • You’ll want to use change management, so that the introduction of new data, modifications to data warehouse structures and alterations of mappings is done in a controlled, planned way.
  • Objects, mappings and other project elements will need to be versioned, and you’ll need to be able to roll back to previous project states if things go wrong with an upgrade.
  • You’ll usually have test and production environments, instead of just dev.
  • There’ll be more than just you as a developer, and you’ll therefore want some sort of security and scoping of project elements
  • You’ll need to ensure you’re licensed properly - a tricky area since parts of OWB are now chargeable on a per-CPU basis.

If anyone can think of any others, add a comment and let me know.

So, starting off with the first point - you’ll be dealing with more than one database. In real life, and in the book I’m writing, you often want to have your repository and the target data warehouse held on different databases, often on different servers. This might be because your OWB repository is on a database running in ARCHIVELOG mode, as the repository is effectively an OLTP application that you need to be able to recover to the last committed transaction. Oracle recommends configuring the database holding your repository with an 8K block size, whilst your data warehouse database might be running in NOARCHIVELOG mode, with a 16K block size. The obvious thing is to put the repository and data warehouse on their own databases, as shown in the diagram below:

One of the new things that OWB10gR2 introduced was a unified repository; on simple, single database environments you just install a single repository on the database that contains your data warehouse, and both the design repository tables, and the runtime repository tables (now renamed to the “Control Center”) are stored in the same repository schema. This default Control Center can manage locations (i.e. deployment schemas) on it’s own database and on other ones, but crucially, if you want to run mappings on these other databases, you have to go and create repositories on those databases as well, and Warehouse Builder will use those repositories’ Control Center tables to store details on mapping executions on those remote databases.

Now when you start working with multiple Control Centers, you need to use a new feature called Multi-Configurations in order to work with Control Centers other than the default one that’s created with your main repository. (UPDATE: No you don’t actually, as pointed out in the comments for this article, and in this subsequent blog post where I show how this can be done with just standard, ETL Core features. Multi-Configuration is still useful when handling more than one Control Center, but it’s not essential. Bear that in mind when reading the rest of this posting, and check out the subsequent posting for how I handle this requirement now.) Multi-Configurations are an Enterprise ETL feature, which means to me that you can’t run mappings on databases other than the one that contains your design metadata unless you pony up for the $10k per CPU license fee, and that’s on both the (presumably small) repository database and the (presumably large, with lots of CPUs) data warehouse database. (UPDATE: Again, wrong, you can switch between more than one control center using standard features; see this article for more details.) Licensing aside though, what this does mean is that you need to be careful when you first set your project up, to ensure that you create all your locations, control centers and modules in the right order: (UPDATE: This is still correct)

  1. First of all, create your main repository as normal on the smaller of the two databases.
  2. Log in to the Warehouse Builder Design Center, and create any database modules that are held on this same database. The locations that get created along with the database modules will be owned by your default Control Center.
  3. Now, you need to create a second Configuration, give it a name, and then when prompted for the Control Center it will use, use the “New” button to create a new one on the data warehouse database.
  1. Now, make this new configuration your active configuration.
  2. Next, create all the database modules that will be owned by this other Control Center whilst this other configuration is active; this ensures the right Control Center owns the right locations.
  3. When you finish creating these modules and locations, switch back to the default Control Center. Create your project as normal, but when you need to deploy and running objects and mappings to the locations owned by the other Control Center, make sure you switch beforehand to the other configuration that owns these locations.

UPDATE: You can do the same thing by registering the additional control center as above, but then switching the control center used by the DEFAULT_CONFIGURATION to this other one before registering the remote locations.

Multiple Configurations are useful for another reason as well; they allow you to associate different sets of physical attributes with your database objects. For example, you might have development, test and production environments, each with their own databases. Your development environment might just have a USERS tablespace, and you haven’t licensed the partitioning option for that database. Your production environment, however, has a tablespace per objects, and you’re looking to partition your fact tables into one partition per month. Using multiple configurations, you can associate different physical properties for your object, and switch between them by activating the correct configuration.

So that deals with multiple databases and multiple environments, as long as each environment is running the same data model, same version of mappings and so on. But what if your development environment is further ahead that your test and production environments, and you need to keep a separate record of your project as deployed in development, compared to test and production? Well, the most practical approach I can think of is to keep with multiple configurations, but have separate repositories for each of the environments; each repository still contains references to all three configurations (to allow us to partition our tables in production, but not in development) and to promote code through dev to test to prod, you use the MDL export and import facility to move project elements between repositories. Not quite as elegant as CVS or Subversion, but it gets you there in the end.

Working with just the development environment for the time being, the question becomes: how to we control the impact of changes and modifications to the project metadata, and how do we introduce version control? In OWB10gR2, these two issues are handled by the Metadata Dependency Manager, and the Change Manager respectively.

The Metadata Dependency Manager performs three functions:

  1. It allows you to interactively determine which objects in your project have metadata dependencies on and object - useful if you want to change an column datatype or definition, and you’re wondering what other columns are loaded from it;
  2. It allows you to select an object and see how it was populated (known as “data lineage”), and
  3. If an object column has changed, you can propagate the changes through to the other objects that are dependent on it.
    Where this works best is when a column in a source table changes it’s definition, and you want to make sure all the downstream tables, dimensions and cubes pick up this new definition. What is doesn’t handle is situations where new columns get added to your source objects, or where columns get deleted - in these situations, you can use the impact viewer to indentify the downstream objects, then it’s down to you to either add the new column in the right place, or remove them.Going on to version control now, this is handled by the (confusingly named) Change Manager. If you’re familiar with change management and version control from earlier Warehouse Builde versions, this is much the same as before. Versioning is handled through taking snapshots of objects, modules or the whole project, which can be either signature snapshots, which allow you to determine the different between the snapshotted items and other items, or full snapshots, which can be restored back from. Using snapshots and the change manager, you can take copies of your project at various project stages, resort back to earlier copies or work out what’s changed since the previous release.

    Again, it’s not quite Subversion; you can’t branch your code, merge branches back again or do other “proper” source code management, and you still need to back up the repository database as this is where the snapshots are stored, but it’s a start.

    On to security now. In earlier versions of Warehouse Builder, you generally logged on to the Design Center as it was by using the repository owner username and password. You could set up Warehouse Builder to use existing database accounts as a login, with Warehouse Builder then presenting the user with a list of all the repositories they could connect to before starting the Design Center, but once in, there was no way of controlling what project items they could work with - all you could do was track who worked with what, and go and get them afterwards if they mucked anything up.

    The 10g Release 2 version of OWB introduced proper access control to your Warehouse Builder projects, which is turned off by default but can be easily enabled by modifying the properties of an object, module or project. The first step is to either register existing developer database accounts, or create them from new, using the Global Explorer in the Design Center. This creates database accounts in the database that your active Control Center resides in, and registers them with Warehouse Builder, and optionally with the Control Center.

    Then, you right-click on whatever object you wish to set security on, and using the Security tab, set the desired access permissions. The “Propagate Changes” button at the bottom allows you to propagate these permissions to any child objects.

    Finally, unlike development and proof of concept environments where you don’t have to worry about licensing too much, in production, you’ve got to make sure all your licenses are in order. Oracle introduced new licensing with version 10g Release 2, where the features of the product were divided up in to free, Core ETL functionality, and pay-extra additional functionality sold as options to the Enterprise Edition of the Oracle Database.

    Now what’s in what option is fairly well documented on the Oracle website, but if you haven’t studied the option details properly, there’s a few aspects of it that might catch you out:

    • Multiple configurations, required to access additional Control Centers, are an Enterprise ETL feature
    • As are schedules, target load ordering, and for and while loops, together with notifcations and routes, in process flows
    • … and Slowly Dimension Type 2 and 3 support, and support for VARRAYs, deploying directly to a Discoverer End User Layer and transportable modules.
    • Whilst all the data profiling functionality (including data rules, automatic corrections and data auditors) requires another database option, the Data Quality option at $15k per CPU.

    I think in reality, this means on any non-trivial (i.e. production) project with more than a single deployment environment, and which needs to schedule mappings, maintain slowly changing dimensions and so on, you’ll end up needing the Enterprise ETL license. Although that might be a cost you hadn’t budgeted for, compared to creating all this by hand, and then maintaining it afterwards, it’s probably a pretty wise investment.

    Anyway, that’s my thoughts on what’s involved in running OWB10gR2 in real, multi-database environments with change and version control and code promotion between development, test and prod. An area I haven’t covered is automating the whole process (including, critically, code promotion between environments and regression testing of the ETL build) using OMB*Plus, but if this sounds interesting (or if you’ve got some suggestions), add a comment or come along to the UKOUG Scottish SIG BI Event where I’ll be presenting on the subject on March 15th.

    A Couple of New Blogs

    Posted by Mark Rittman at February 14, 2007 08:58 PM

    A quick nod to a few new blogs that I’ve recently spotted.

    Simon Ellis is someone I’ve worked with on a couple of projects before, and is a pretty capable technologist and project lead working in the Oracle middleware and architecture space. Simon’s posted a couple of good articles recently on Oracle’s move into the “fabric” market, and the new Secure Enterprise Search application, and knowing what Simon knows about the wider Oracle picture I’ll be sure to pop back there every so often.

    Someone Simon rates very highly is Nick Price, another ex-Oracle person who now works in recruitment. As I’m just about to dive into the independent consultancy market myself, maybe Nick will be someone to keep an eye on…

    Finally, I happened across a new blog by Metricsphere’s Director of BI, Jeff McQuigg, on working with Oracle BI Suite Enterprise Edition. Blogs on BI EE are still fairly rare (this one by Adrian Ward is another one to keep an eye on) and I noticed some good postings by Jeff on Achieving good performance with Analytics, Subject Area Planning, and to what degree you should use the Common Enterpise Information Model to do your data integration, vs. using your ETL tool. Good stuff.

    A Couple of New Blogs

    Posted by mark at February 14, 2007 08:58 PM

    A quick nod to a few new blogs that I’ve recently spotted.

    Simon Ellis is someone I’ve worked with on a couple of projects before, and is a pretty capable technologist and project lead working in the Oracle middleware and architecture space. Simon’s posted a couple of good articles recently on Oracle’s move into the “fabric” market, and the new Secure Enterprise Search application, and knowing what Simon knows about the wider Oracle picture I’ll be sure to pop back there every so often.

    Someone Simon rates very highly is Nick Price, another ex-Oracle person who now works in recruitment. As I’m just about to dive into the independent consultancy market myself, maybe Nick will be someone to keep an eye on…

    Finally, I happened across a new blog by Metricsphere’s Director of BI, Jeff McQuigg, on working with Oracle BI Suite Enterprise Edition. Blogs on BI EE are still fairly rare (this one by Adrian Ward is another one to keep an eye on) and I noticed some good postings by Jeff on Achieving good performance with Analytics, Subject Area Planning, and to what degree you should use the Common Enterpise Information Model to do your data integration, vs. using your ETL tool. Good stuff.

    IBM up to their same old whining and inventing their own truth again

    Posted on An Expert's Guide to Oracle Technology at February 14, 2007 05:50 PM

    The Edison Group recently published a paper (not Oracle as you have read by erroneous IBM bloggers) that shows, amongst other things:

    • Database administrators (DBAs) can perform typical administrative functions in 38% less time when using Oracle Database 10g Release 2 compared to IBM DB2 UDB 9.1.
    • Oracle Database 10g Release 2 requires 35% fewer steps for the same set of standard RDBMS tasks than IBM DB2 UDB 9.1 u

    Tame Meat, Mate?

    Posted on An Expert's Guide to Oracle Technology at February 13, 2007 05:10 PM

    I was in a meeting the other day and someone shared some wisdom, "There is no I in team." So, being a professional smart aleck, I piped in with, "It's true there is no I in team, but there is an M and an E." (Disclaimer: I did not make that up but I can't remember where I first heard it). Once that thought hit my head, I thought to myself, "Self, what else is in team?" If I rearrange the letters in team, I get: TEAM = META. Not very interesting. TEAM = TAME. Hmmm. TEAM = MEAT. Ick. TEAM

    Overloading Procedures in PL/SQL

    Posted on An Expert's Guide to Oracle Technology at February 09, 2007 03:22 PM

    A FAQ that I get, well, frequently, is about overloading procedures. I think most people get how to overload but not when or why. Today I am going to explain a classic example of where overloading makes your life easier. More importantly, it makes the life of the code maintainer behind you easier.

    I am going to use the sample data on the HR schema for this entry. Specifically, the EMPLOYEES table.

    In real life, I have had to dump table to text files so many times

    Looking Closer at BI Suite EE 10gR3

    Posted by mark at February 08, 2007 05:05 PM

    I’ve been spending all my spare time recently on the book I’m working on, and so deliberately stayed away from the new Oracle BI Suite Enterprise Edition so that I didn’t get distracted. I’ve got a couple of days free now, and as the new versions of all these bits of software - BI Enterprise Edition, BI Publisher and so on - have just made whole sections of my Oracle University BI Masterclass material obsolete, I downloaded all the software and upgraded my development environment this morning.

    The install went fine, easier than a normal Oracle installation to be honest, as there’s no Universal Installer and you just use a Windows InstallShield installer instead - not sure how this will work with the Linux version though, when I get a chance I’ll try and install this as well. Compared to the previous Siebel Analytics install, you need a Java JDK1.5 or higher (I used JDK 1.6) rather than JDK1.4, and you don’t need to separately install the J2EE web component into an application server, it comes with a standalone OC4J container, although you get the option of installing in to Oracle Application Server 10.1.3 as well. All told, a surprisingly painless exercise, although as I said installing it into a proper Application Server environment, or on Linux, or on Microsoft IIS, might be a bit more complicated.

    One I started it up and logged in to the Dashboard application, it all looked fairly familiar compared to Siebel Analytics 7.8. There’s a new Oracle 11g look and feel (blue is obviously the new red), but the dashboard functionality looks much the same as before.

     

    One nice touch with this new release is the “Paint” dataset and demo dashboard - it doesn’t need a database, and instead uses a set of XML data files stored under the \OracleBI\Server\Sample\Paint directory. This means you can get up and running and play around with the dashboard, even before you connect the server to a database.

    Taking a