Showing posts with label oradb. Show all posts
Showing posts with label oradb. Show all posts

Monday, January 23, 2012

OBIEE 11g: Where's the Compare Repositories Dialog?

Recently I decided to try out the new patching capabilities for the metadata in OBIEE 11g. The big reason for me was to avoid having to reset my connection pools. Each time I did a 3 way merge, the connection pools would get over-written with their development credentials. When I was doing the merge, I could never find a way to isolate (leave out) those objects, so it was off to try the patching.

What this patching does is creates an xml file of the differences between 2 RPDs. You can then edit that XML file if you so desire. Most of my duties over the last couple of years have centered around the RPD and front-end stuff, not nearly as much on the administrative side (i.e. migrations). So I need to catch up with the rest of the world.

Reading through the docs, I'm told that I need to use the "Compare repositories" dialog. OK, easy enough.



Where is my entry for it?

OK, let's try the Compare entry.



Since I'm using the prod_20120122 RPD, I select the dev_20120122 RPD.

I'm prompted for the Repository Password and then it spins for a few seconds, then gives me this



I select Yes.



OK...where's the Compare Repositories Dialog like the docs say?

I see the icons have changed signifying differences, but no dialog as mentioned in the docs.

What if I select No?



Ah, there it is.

Interestingly, if I maximize that Compare Repositories Dialog, the next time I run the Compare, I can see it plain as day.



Hopefully you'll find this next time you endeavor to learn how to patch your RPD and can't seem to find the Compare Repositories Dialog.

Thursday, December 15, 2011

Trace Data: Not Just For DBAs

On Wednesday, I attended Cary Millsap's Mastering Oracle Trace Data class here in Tampa.

Why?

Why would I go? I am working with OBIEE which is about 42 layers above the database...who cares about trace data? Well, performance is usually the number 1 item on everyone's list. Page loads to slow. Report takes to long to run. Whether it's trying to tune the application server (WLS) or figure out why Report A takes so long to run, we do a lot of performance analysis. In most cases, it ends up being the SQL that is run. What I mean by the SQL is that it's usually bringing back quite a few records. I've seen people try to pull back millions of records and then pivot all that data putting a nice load on the BI Server and hogging all the resources from everyone else.

On occasion though, there are other things that are going on (with the SQL) that we can't pinpoint.

Recently we had to back out a production implementation because one of the load processes seemed to just hang, threatening to slow down a larger process.

I asked the DBAs why.

Crickets.

Shouldn't that be an answer a DBA provides?

Disk? Network? CPU? Memory? Which one?

Crickets. (I didn't ask those exact questions, I think I said, "Reads? Writes? Network? Load?")

That is just one of the reasons I wanted to attend Mr. Millsap's class. That, and I've heard he's well regarded and does a pretty decent job presenting. OK, I admit it, I just want to show the DBA up. There, said it.

I really shouldn't have to though. It's supposed to be a partnership. They don't know much about OBIEE, so I help them there. I expect help in things like this.

Why? Part II

If you are a developer, understanding trace data will make you better. You'll no longer have to guess, you'll know.

Of course there's what I hinted at above, being able to go to your DBA(s) and prove something. No better feeling in the world.

How?

MR Trace is by far the easiest. It's integrated with SQL Developer. It's a great place to start.

MR Tools - For the more advanced professional. Mostly geared towards the DBA type, but incredibly useful to developers as well. It includes:

- mrskew - your trace file profiler and data miner
- mrls: your trace file lister
- mrcallrm: your trace file correction fluid
- mrtrim: your trace file tim calculator
- mrtrimfix: your trace file time value fixer

Method R Profiler:
The classic tool that started it all, the Method R Profiler is software that makes simple work of knowing exactly why your application consumes the response time it does. With minimal training, a Method R Profiler user can—in just minutes—identify the root cause of an Oracle-based application performance problem, propose sensible solutions to it, and predict the end-user response time impact of each proposed solution.

There are of course other products, check them out here.

Ask Mr. Millsap to come to your town. Try out MR Trace. You won't be sorry you did.

Tuesday, October 18, 2011

KScope + DevOps

Last year I had the pleasure of getting the Sunday Symposium together for KScope 11, this year, I have completed my takeover of the Database track by becoming the track lead.

I thought this was the best job ever, then I was attacked Nancy Kerrigan style by my handlers.

All that said, I think I've gathered a pretty good group of people to help review and select the abstracts for next year's conference (San Antonio, TX).

There will be 4 sub-tracks this year:
- Design/Data Modeling
- Maintenance (Performance, Tuning, Upgrades)
- MySQL
- (Dev)Operations

The one I am most excited about is the (Dev)Operations sub-track, aka, DevOps.

What is DevOps?

I'm glad you asked..

"DevOps" is an emerging set of principles, methods and practices for communication, collaboration and integration between software development (application/software engineering) and IT operations (systems administration/infrastructure) professionals.[1] It has developed in response to the emerging understanding of the interdependence and importance of both the development and operations disciplines in meeting an organization's goal of rapidly producing software products and services.

I am not necessarily a fan of the movement, but I am a fan of the principles behind it.

Every developer has a story about working with an evil DBA. LIkewise, every DBA has a story about some application that went to production where they were left completely out of the process.

But it is more than just a simple, "Can't we all just get along?" plea, this is about creating better software and streamlining processes.

My personal experience has been one of woeful cooperation, at any level. Our thought, our hope, is that this well help give other Oracle professionals better ideas on how to start down this road.

If you are interested in this topic, sign up. If you want to present on this (or any other) topic, register here.

Thursday, September 29, 2011

Great Night of Baseball

If you are a baseball fan, last night was spectacular.

Even more so, if like me, you were fans of either the Tampa Bay Rays, Boston Red Sox, Atlanta Braves or St. Louis Cardinals.

Well, the Braves and Red Sox fan's wouldn't call last night spectacular...spectacularly horrible...maybe.

I decided to take LC and my father to the game last name, the Three Chet's if you will.



David Price was pitching for the Rays and the Yankees were throwing Johnny Bullpen, or the remainder of their 40 man roster, to save their arms for the post-season. The Yankees had already clinched their spot, the Rays were tied with the Red Sox for the Wild Card slot. Boston was playing the Baltimore Orioles at the same time.

On September 3rd, the Red Sox had a 9 game lead over the Rays, a seemingly insurmountable lead. But this is baseball, it's not over until the fat lady sings. The fact that the Rays were now tied with the Red Sox was a testament to the Ray's pitching and the utter collapse of the Boston Red Sox.

It didn't look good for the Rays. In the 6th inning, the Rays were down 7-0. Evan Longoria struck out with men on base to end the inning. He couldn't have looked more dejected...he just flipped his bat at home and starting walking out to 3rd base. That's when we decided to leave.

First, it was a school night. It was after 9 PM and it would take about 45 minutes to drop my dad off and another 15 minutes to get home. Second, it was 7-0 and the Rays appeared to have given up. So off we went.

We listened to the game on the way home, hearing that the Red Sox vs. Orioles game was in rain-delay. Dropping me dad off, we watched a little bit of the top of the 8th inning before heading home.

The Rays scored 1 run, 2 runs, 3 runs and had 2 men on base with Longoria coming to bat. I'm thinking he needs to hit a double...home runs are rally-killers (no one is on base...it just "seems" desolate out in the field). Before we could turn onto the freeway, Longoria hits a 3 run homerun to bring the score to 7-6 in the bottom of the 8th. Wow, just wow.

100 MPH on the Veteran's Expressway to get home...

Sitting in front of the TV...we watch the first 2 hitters in the bottom of the 9th make outs. They pinch-hit Dan Johnson, hitting .108 this season. Johnson was pulled up from the minors just a couple of weeks ago:

HE'S BAAACK: The Rays are bringing their lucky charm to Boston, having called up Dan Johnson, whose list of key hits includes the monumental and momentous pinch-homer off Red Sox closer Jonathan Papelbon on Sept. 9, 2008, with the bat mounted in his house as a memento.

Johnson said he'd welcome the chance for history to repeat itself: "I would love to add a bat to the collection, no doubt."

Johnson, 32, was thrilled just to be back in the majors, having been sent down in late May and hampered much of the year by a wrist injury.

With 2 strikes Johnson wrapped one around the right field foul pole to tie the game. LC and I jumped up, hi-fived, screamed and yelled...wow, just wow.

At 11:17, the 10th inning I believe, I sent LC to bed.

Around midnight, the Orioles/Red Sox game had resumed and it was now the bottom of the 9th, with Papelbon in to pitch. He strikes out the first 2 hitters. With 2 strikes, Chris Davis doubled. Nolan Reimold doubled to switch places with Davis, tie game. Then Robert Andino singled to left scoring the pinch-runner giving the Orioles the win.

As this was announced, Longoria was coming to the plate for the Rays (this is how I remember it anyway)...couple of pitches later, he hits a screamer down the left field line barely clearing the left field wall. Rays win, Rays win!

Monday, September 19, 2011

OOW: Predictions

I haven't seen too many (ok, none) of these this year, but one today hit home:

Predicting OBIEE 11.1.1.6 by Joe Leva.

I've been lucky enough to hang out (err, stalk, as he would say) with Joe in the recent past, he's a smart dude. Here's his prediction in short:

Prior keynotes have brought us Exadata (and Exadata 2) and Exalogic. The Oracle database is clearly a pillar of their business, it was a good first choice for a machine. The middleware stack is another large area of the Oracle product line, hence Exalogic. Wouldn’t it be nice if you could run OBIEE on the Exalogic? What would we call an OBIEE machine? ExaIntelligence? The Oracle BI Machine?

Now, just in case I’m right on this, how do I support this? The packaged software and hardware in the “machines” is a way for Oracle to capture revenue that would otherwise go to implementation partners. The BI machine is a logical inevitable progression, if it doesn’t come this year it will be next year. The economics demand it.

Now wouldn't that be cool, an OBIEE machine a la Exadata or Exalogic? I'll take 1, or 2.

Do you have any predictions for what will be announced this year? FMW will be big I'm sure. There's a big announcement on September 21st (Wednesday), maybe it's the Exadata Mini(-me)?

Let's hear some more fun predictions...

The Exadata Mini - Exclusive Picture!

Early this morning ZDNet's Larry Dignan reported that Oracle would be announcing the "Exadata Mini" edition: Oracle's 'Exadata mini' would aim for midmarket

Well, through tireless research and a lot of hacking, I've found a picture of said machine:



Vern Troyer, the actor who plays "Mini-me" from the Austin Powers movies, stands 32 inches tall, which for the rest of the world, is 81.28 centimeters.

It stands at 20" tall, and as Mr. Dignan reports, this could fit under your desk.

If you're curious to know how Oracle was able to reduce the size...check out this video:

Friday, September 16, 2011

More T-Shirts

Recently I was asked to create some merchandise that fell outside of my norm.

Specifically, I was asked to create a onesie, or piece baby outfit. I tried using my normal method of creating a simple png (pixel) graphic in gimp, however, when I tried to add that to something other than a regular old t-shirt, the application didn't give me the option to do so. Apparently I needed to use vector graphics. I should have known this, since I'm a design genius and all that.

I thought I could continue to use gimp and simply save the file as an encapsulated post script and upload it. Spreadshirt has a semi-automated system that, apparently, attempts to open the file. If it can't, it sends it off for review by their staff. Sometime in the next day or 2, I get an email telling me whether it has passed or not. None of my 3 attempts passed. In my rejection notice, they said I could send them the file directly and ask what's wrong. That's when I got a nice primer on vector vs. pixel graphics. I needed to use a tool like Corel Draw, Illustrator or Inkscape. I chose Inkscape, it was free and runs on Linux. Yay for me. Yay for OSS.

So here are my first 2 attempts at using vector graphics.

First, the custom order:



Next, the LOWER( ORACLENERD ) edition:



There's still time to get one before Oracle OpenWorld, just a little over 2 weeks away.

Thursday, September 15, 2011

Prepping for Oracle OpenWorld 2011

SQL> SELECT TO_DATE( 20111001, 'YYYYMMDD' ) - SYSDATE time_to_oow
  2  FROM dual;

TIME_TO_OOW
-----------
 15.8921065
Wow. Just a little over 2 weeks to go. Time certainly flies.

As I'm wont to do, I've put off just about everything. For the last 2 weeks I've been scrambling to get a room. Two days ago I looked at the prices in downtown San Francisco and I thought I might be living sleeping on someone's floor, or sleeping on the street (don't think I haven't done that). It was even more serious because I had promised a friend of mine that I would cover his accommodations; he had helped me out last year when Kate got sick by buying me a ticket to get home immediately (end of the month, I was out of funds).

Yesterday I finally scored a place through airbnb. Somewhere on Lombard street, Russian Hill? Whatever. It's 1.7 miles to the Moscone Center.



In San Francisco, 1.7 miles is nothing. Far too many great distractions (people watching) for it to feel like a long walk. Bonus points for staying (getting) in shape while there. Bonus points for helping the effects of the beer wear off before sleep. Negative bonus points if I get lost, which I will, especially if I am alone. No sherpa this year unfortunately.

As soon as I booked my room, I booked my flight. They're still cheap too.

I haven't even looked at the sessions yet. Shocking.

Lots of activities planned though:

- Sunday - Oracle ACE dinner thingy.
- Monday - Customer meeting and OTN party.
- Tuesday - Nothing yet.
- Wednesday - Blogger meet-up, Appreciation Event
- Thursday - Nothing
- Friday - OBIEE Meetup thingy with product development.

Somewhere in there I'm supposed to fight with Kellyn Pot'Vin. Additional fun will be a repeat of last year's game, The Piwowar challenge. Personally, I like Pot' Wen(ch), but that might get me punched again.

I've been throwing a little bit too. They have this Home Run Derby...area, where I can go and throw my arm out trying to see how hard I can throw after 10 years. I may be in a sling after the first day.

It's gonna be a hoot. So excited to hang out with a bunch of smart, passionate people and talk shop (or beer). I don't think I've left my house in weeks, I really need to get out.

OOW 2011 Twitter List

For the past couple of years George Woods has been compiling a list of Twitterites who will be attending Oracle OpenWord. 2009 and 2010. I realized this year I hadn't seen it yet, so I emailed him. Unfortunately he will be unable to attend, he's working with that other database right now.

There is no planned event for us yet, but it can't hurt to have if something does come up.

If you plan on attending, please fill out this simple form; twitter handle is the only thing required.



You can find the document here. If I can figure out how to embed the list here, I will do so.

OK, I just stole the iframe method from the above form. It's ugly, but it's better than nothing.



If you know of a better (and easy) way, let me know.

Wednesday, September 14, 2011

OBIA: Installing Informatica 9.0.1

I'm in the process of building out a tip-to-tail dev/test system that includes the components from OBIA.

The components include:
- EBS Vision database
- Informatica PowerCenter 9.0.1
- Data Warehouse Administration Console (DAC)
- OBIEE 11.1.1.5
- OBIA 7.9.6.3

I recently rebuilt my EBS instance. I put my last go at it on a removable disk and seem to have misplaced it.

This will be part of a series of posts describing the entire process. I don't do it often enough and so I have to "remember" what I did, now I'll have my own reference.

Environment

As usual, this is running in a VirtualBox virtual machine.
- Host: Ubuntu 11.04, Natty Narwhal
- VirtualBox: 4.1.2
- Guest: Oracle Enterprise Linux (64 bit)
Linux oracle-web-tier 2.6.32-200.13.1.el5uek #1 SMP
x86_64 x86_64 x86_64 GNU/Linux
- Installed software: 11gR2 Database, OBIEE 11.1.1.5, Oracle Web Tier

I grabbed the download from edelivery, file name is: V26109-01.zip.

Other references:

- OBIA 7.9.6.3 Documentation Library
- OBIA Installation Guide for Informatica PowerCenter Users Release 7.9.6.3: Specifically this section, Installing Informatica PowerCenter Services.

Step 1, create a database account.
CREATE USER infa IDENTIFIED BY testing
  DEFAULT TABLESPACE users;

GRANT DBA TO infa;
**Note I have given DBA privileges, this is not necessary.**

It is simply easier, for now, to do it this way.

Step 2, unzip the files on your system.

It is recommended that you create an OS user specific to this task. I am using my previously existing oracle (dba, oinstall) account

Step 3, run the install.sh file
[oracle@oracle-web-tier infa_zips]$ ./install.sh
OS detected is Linux
unjar task is in progress.............
unjar of ESD completed.....
Do you want to continue installation (y/n) ?
y
Starting installation ...

\***************************************************************************
\* Welcome to the Informatica 9.0.1 HotFix 2 Server Installer.  *
\***************************************************************************


To verify whether a machine meets the system requirements for an Informatica installation, 
run the Pre-Installation System Check Tool (i9Pi) before you start the installation process. 
You can find the i9Pi tool in the following directory: /i9Pi


Before you continue, read the 9.0.1 HotFix 2 Installation Guide and Release Notes.
You can find the 9.0.1 HotFix 2 documentation in the Documentation Center at 
http://my.informatica.com
Configure the LANG and LC_ALL variables to generate appropriate code pages and 
create and connect to repositories and Repository Services.
Do you want to continue? (Y/N)Y
Installer requires operating system Linux version 2.6 and later.
Current operating system Linux version 2.6.
Current operating system meets minimum requirements.

 Select a choice :  
1.   Install Informatica 9.0.1 with Hot Fix 2 or Upgrade from a previous version of Informatica 
to Informatica 9.0.1 with Hot Fix 2 
2.   Apply Informatica 9.0.1 Hot Fix 2 to existing 9.0.1 install.
Enter the choice(1 or 2):1
 
-----------------------------------------------------------
Checking for existing 9.0.1 HotFix 2 product installation.
Select (G)UI mode (needs X Window support) or (C)onsole mode (G/C):G
Launching installer in GUI mode ...
Preparing to install...
Extracting the JRE from the installer archive...
Unpacking the JRE...
Extracting the installation resources from the installer archive...
Configuring the installer for this system's environment...

Launching installer...

Preparing SILENT Mode Installation...

===============================================================================
Informatica 9.0.1 Services HotFix2               (created with InstallAnywhere)
-------------------------------------------------------------------------------


System Requirements:



License Key and installation directory:



Confirmation:



Running...



Configuring...



Create a domain and Enable HTTPS. Enable HTTPS is checked by default, I won't be using it.



Configure the database connection and JDBC URL



Testing the connection...



Informatica Domain. I'm going to accept the defaults:



Summary


===============================================================================
Configuring Installation...
---------------------------

 [==================|==================|==================|==================]
 [------------------|------------------|------------------|------------------]

Installation Complete.
To verify your installation, open up http://localhost:6007/administrator/, username is administrator and the password is the one you supplied during installation.



You'll be redirected to this page.



Next steps will be to cover the Information Repository Service and Informatica Integration Service. That of couse, is later.

Tuesday, September 13, 2011

Pythian Acquires "Dude Who Gets Stuff Done"

Pythian, the world's leading remote DBA service company, has announced the (non-hostile) acquisition of John Piwowar.

Wait, Pythian didn't announce it, officially anyway...



Source



Source

Maybe it was John?

...Starting today, I begin the "on-boarding" process at Pythian, as a member of one of their ERP teams.
In a way, it feels as much like starting school as it does a new job. This move represents my biggest career challenge to date, and I
look forward to learning a ton (and contributing a ton) in the company of a lot of smart, talented people. Since I'm going to be packing
my brain full of new things over the next 3 weeks, I expect that the only blog activity here will be from pre-scheduled posts, drafts that
I'd been putting off finishing until recently. Once I'm up to speed on the new system, you'll hopefully be hearing more from me on the
Pythian blog!

I think it's obvious from John's post how excited he is. I am excited for him too. John's an awesome dude, sherpa (for me), protector (of me, from myself), and DBA.

Find John in the following locations:

- Twitter
- Blog
- LinkedIn
- oraclenerd

OK, this didn't turn out as funny as I had intended, whatever.

Great move for both parties. Can't wait to see what John does with the vast resources available to him now.

Saturday, September 10, 2011

OBIEE: Start/Stop Individual Components (Manually)

Previously I wrote about how to start and stop individual components via Enterprise Manager.

This time, I'm going to run through the manual steps to do the same, start and stop individual components using the Oracle Process Manager and Notification Server (OPMN) Tool.

First, navigate to the ORACLE_INSTANCE/bin directory. For me on Linux, that is /obiee/Middleware/instances/instance. List out the directory contents and you should see the opmnctl
[oracle@oracle-web-tier bin]$ ls -lah
total 56K
drwx------  3 oracle dba 4.0K Aug 16 00:53 .
drwx------ 14 oracle dba 4.0K Sep  8 17:09 ..
drwxr-x---  2 oracle dba 4.0K Aug 16 00:53 essbase_ha
-rwx------  1 oracle dba  44K Aug 16 00:53 opmnctl
Let's see what is running:
[oracle@oracle-web-tier bin]$ ./opmnctl status

Processes in Instance: instance1
---------------------------------+--------------------+---------+---------
ias-component                    | process-type       |     pid | status  
---------------------------------+--------------------+---------+---------
coreapplication_obiccs1          | OracleBIClusterCo~ |    1525 | Alive   
coreapplication_obisch1          | OracleBIScheduler~ |    1443 | Alive   
coreapplication_obijh1           | OracleBIJavaHostC~ |    1487 | Alive   
coreapplication_obips1           | OracleBIPresentat~ |    1469 | Alive   
coreapplication_obis1            | OracleBIServerCom~ |   30698 | Alive
All of the components are running. Good. Let's shut down everything.
[oracle@oracle-web-tier bin]$ ./opmnctl shutdown
[oracle@oracle-web-tier bin]$ ./opmnctl status
opmnctl status: opmn is not running.
And bring everything back up.
[oracle@oracle-web-tier bin]$ ./opmnctl startall
opmnctl startall: starting opmn and all managed processes...
[oracle@oracle-web-tier bin]$ ./opmnctl status

Processes in Instance: instance1
---------------------------------+--------------------+---------+---------
ias-component                    | process-type       |     pid | status  
---------------------------------+--------------------+---------+---------
coreapplication_obiccs1          | OracleBIClusterCo~ |    3124 | Alive   
coreapplication_obisch1          | OracleBIScheduler~ |    3123 | Alive   
coreapplication_obijh1           | OracleBIJavaHostC~ |    3121 | Alive   
coreapplication_obips1           | OracleBIPresentat~ |    3120 | Alive   
coreapplication_obis1            | OracleBIServerCom~ |    3122 | Alive
Now, let's stop the BI Server, coreapplication_obis1 or OrcleBIServerCom~. There are 2 ways to bring this down. Well, one command, stopproc, but 2 different ways. Notice the column headers up above, you have ias-component and process-type. Using ias-component:
[oracle@oracle-web-tier bin]$ ./opmnctl stopproc ias-component=coreapplication_obis1
opmnctl stopproc: stopping opmn managed processes...
[oracle@oracle-web-tier bin]$ ./opmnctl status

Processes in Instance: instance1
---------------------------------+--------------------+---------+---------
ias-component                    | process-type       |     pid | status  
---------------------------------+--------------------+---------+---------
coreapplication_obiccs1          | OracleBIClusterCo~ |    3124 | Alive   
coreapplication_obisch1          | OracleBIScheduler~ |    3123 | Alive   
coreapplication_obijh1           | OracleBIJavaHostC~ |    3121 | Alive   
coreapplication_obips1           | OracleBIPresentat~ |    3120 | Alive   
coreapplication_obis1            | OracleBIServerCom~ |     N/A | Down
Start it back up.
[oracle@oracle-web-tier bin]$ ./opmnctl startproc ias-component=coreapplication_obis1
opmnctl startproc: starting opmn managed processes...
[oracle@oracle-web-tier bin]$ ./opmnctl status

Processes in Instance: instance1
---------------------------------+--------------------+---------+---------
ias-component                    | process-type       |     pid | status  
---------------------------------+--------------------+---------+---------
coreapplication_obiccs1          | OracleBIClusterCo~ |    3124 | Alive   
coreapplication_obisch1          | OracleBIScheduler~ |    3123 | Alive   
coreapplication_obijh1           | OracleBIJavaHostC~ |    3121 | Alive   
coreapplication_obips1           | OracleBIPresentat~ |    3120 | Alive   
coreapplication_obis1            | OracleBIServerCom~ |    3525 | Alive 
process-type shutdown:
[oracle@oracle-web-tier bin]$ ./opmnctl stopproc process-type=OracleBIServerComponent
opmnctl stopproc: stopping opmn managed processes...
[oracle@oracle-web-tier bin]$ ./opmnctl status

Processes in Instance: instance1
---------------------------------+--------------------+---------+---------
ias-component                    | process-type       |     pid | status  
---------------------------------+--------------------+---------+---------
coreapplication_obiccs1          | OracleBIClusterCo~ |    3124 | Alive   
coreapplication_obisch1          | OracleBIScheduler~ |    3123 | Alive   
coreapplication_obijh1           | OracleBIJavaHostC~ |    3121 | Alive   
coreapplication_obips1           | OracleBIPresentat~ |    3120 | Alive   
coreapplication_obis1            | OracleBIServerCom~ |     N/A | Down
Note that I didn't use OracleBIServerCom~. It expects the full name of the component, in this case, OracleBIServerComponent. If you use the shortened name, you'll get this:
[oracle@oracle-web-tier bin]$ ./opmnctl stopproc process-type=OracleBIServerCom~
opmnctl stopproc: stopping opmn managed processes...
================================================================================
opmn id=oracle-web-tier:9501
    No processes or applications match the specified configuration.
Finally, bring the BI Server back up.
[oracle@oracle-web-tier bin]$ ./opmnctl startproc process-type=OracleBIServerComponent
opmnctl startproc: starting opmn managed processes...
[oracle@oracle-web-tier bin]$ ./opmnctl status

Processes in Instance: instance1
---------------------------------+--------------------+---------+---------
ias-component                    | process-type       |     pid | status  
---------------------------------+--------------------+---------+---------
coreapplication_obiccs1          | OracleBIClusterCo~ |    3124 | Alive   
coreapplication_obisch1          | OracleBIScheduler~ |    3123 | Alive   
coreapplication_obijh1           | OracleBIJavaHostC~ |    3121 | Alive   
coreapplication_obips1           | OracleBIPresentat~ |    3120 | Alive   
coreapplication_obis1            | OracleBIServerCom~ |    3803 | Alive
Fairly simple.

For a full list of opmnctl commands, simply run ./opmnctl help and you'll get the following output:
[oracle@oracle-web-tier bin]$ ./opmnctl help

usage: opmnctl [verbose] [<scope>] <command> [<options>]

verbose: print detailed execution message if available

Permitted <scope>/<command>/<options> combinations are:

 scope    command     options
-------  ---------   ---------
          start                         - Start opmn
          startall                      - Start opmn & all managed processes
          stopall                       - Stop opmn & all managed processes
          shutdown                      - Shutdown opmn & all managed processes
[<scope>] startproc   [<attr>=<val> ..] - Start opmn managed processes
[<scope>] restartproc [<attr>=<val> ..] - Restart opmn managed processes
[<scope>] stopproc    [<attr>=<val> ..] - Stop opmn managed processes
[<scope>] reload                        - Trigger opmn to reread opmn.xml
[<scope>] status      [<options>]       - Get managed process status
[<scope>] metric      [<attr>=<val> ..] - Get DMS metrics for managed processes
[<scope>] dmsdump     [<dmsargs>]       - Get DMS metrics for opmn
[<scope>] debug       [<attr>=<val> ..] - Display opmn server debug information
[<scope>] set         [<attr>=<val> ..] - Set opmn log parameters
[<scope>] query       [<attr>=<val>]    - Query opmn log parameters
          launch      [<attr>=<val> ..] - Launch a configured target process
          phantom     [<attr>=<val> ..] - Register phantom processes
          ping        [<max-retry>]     - Ping local opmn
          validate    [<filename>]      - Validate the given opmn xml file
          help                          - Print brief usage description
          usage       [<command>]       - Print detailed usage description
          createinstance                - Create an Oracle Instance
          createcomponent               - Create a specified component
          deleteinstance                - Delete an instance and components
          deletecomponent               - Delete a specified component
          registerinstance              - Register with admin server
          redeploy                      - Redeploy the admin server application
          unregisterinstance            - Unregister with admin server
          updateinstanceregistration    - Update instance registration
          updatecomponentregistration   - Update component registration

Friday, September 9, 2011

OBIEE: Start/Stop Individual Components (Enterprise Manager)

The very first thing I thought, after firing up my first OBIEE 11g instance, was how freaking intimidating it was.

You have Enterprise Manager, the WLS Console and regular old /analytics. Nah...not too much.

Whatever.

Of course I'm still learning it daily, but most of the basics I have down now.

A basic concept which was super-easy in 10g, like stopping and starting individual services like the BI Server and Presentation Server, didn't seem so easy any more.

Now this isn't rocket science, but I'm sure it will help someone new (and intimidated!) by OBIEE 11g.

First, using Enterprise Manager.

After logging in, you'll see the Farm_bifoundation_domain (essentially your home) page:



From there, navigate to the Business Intelligence folder and click on coreapplication:



This will take you to your coreapplication (BI) page:



From there, you can stop all components of the BI Server; BI Server, Presentation, Java Host, etc.



Easy.

Sometimes though, you just need to restart one of the services, usually the BI Server or the Presentation Server.

Easy enough, see that tab Capacity Management, click on it:



That'll take you here, where you can start, stop and restart individual services:



Simply select the service you want to stop, start or restart like so:



Then select Stop Selected and you'll be prompted to confirm your selection:



Now you've stopped the BI Server service.



You can confirm this by looking at the Overview page as well:



There is also a manual way of doing this. Since it's Friday evening, I will wait until later to write that one up. Must go watch Megamind or some other fun kids movie with one of the monsters.

OBIEE 11g: Unresolved table: "**NONE**". (HY000)

Yesterday I was having problems simply converting the Usage Tracking catalog. It may or may not be related to having Web Tier (or any other non-OBIEE component) installed, I can't say with certainty though.

The reason that you have to convert/upgrade the Usage Tracking RPD/Web Catalog is because a pre 11g version was inadvertently shipped. Good news though, if you have upgrade issues like I've had, you can get an 11g copy of the RPD (both 11.1.1.3 and 11.1.1.5) on MOS. No upgraded web catalog though.

I managed to merge the Usage Tracking metadata into my RPD, then I was off to make the web catalog work. I copied the Usage Tracking web catalog over to the SampleAppLIte web catalog and tried to run it.



If you can't read that, it says:
[nQSError: 27004] Unresolved table: "**NONE**". (HY000)
I went in and played with the permissions, restarted the server, nothing worked. I kept getting the same message.

Twitter machine to the rescue.



I started to go through the criteria for one specific report.

The only thing that jumped out at me was that none of the folder qualifiers had quotes around them, like Measures."Some Measure". That's OK, because there is no space.

I replaced each and every criteria in the report, ran it, same error.

Wait, there's a filter.

Remove it.

The report runs.

w00t.

So I went into Catalog Manager > Properties > Edit XML and sure enough:



I replaced **NONE** with Usage Tracking, reloaded the metadata (and bounced the server for good measure), and voila!

Thursday, September 8, 2011

OBIEE 11g: UPGCMP-02712

Amusingly, the Usage Tracking components (RPD, Web Catalog) must be upgraded from 10g to 11g (11.1.1.5 for me). Not sure how this was missed, but it was.

I've run through the Upgrade Assistant multiple times, each one failing.



Here's the log:
[2011-09-08T03:07:12.156-04:00] [Framework] [NOTIFICATION] [] [upgrade.Framework] [tid: 13] 
[ecid: 0000J97r9aPFw000jzwkno1EQ6_m000004,0] Start 11g Components: false
[2011-09-08T03:07:12.185-04:00] [Framework] [NOTIFICATION] [] [upgrade.Framework] [tid: 13] 
[ecid: 0000J97r9aPFw000jzwkno1EQ6_m000004,0] Starting to upgrade BIEE.
[2011-09-08T03:07:12.239-04:00] [Framework] [ERROR] 
[UPGAST-00138] [upgrade.Framework] [tid: 13] [ecid: 0000J97r9aPFw000jzwkno1EQ6_m000004,0] 
upgrade exception occurred
[2011-09-08T03:07:12.239-04:00] [Framework] [ERROR] [] [upgrade.Framework] [tid: 13] 
[ecid: 0000J97r9aPFw000jzwkno1EQ6_m000004,0] 
Cause: An unexpected upgrade exception has occurred. Action: See the secondary error message 
for additional details.
[2011-09-08T03:07:12.239-04:00] [Framework] [ERROR] [] [upgrade.Framework] [tid: 13] 
[ecid: 0000J97r9aPFw000jzwkno1EQ6_m000004,0] 
UPGCMP-02712: Expected oracle.biee.admin:oracleInstance=*,type=BIDomain.OracleInstance,
group=Service Oracle instance, found 2
[2011-09-08T03:07:12.240-04:00] [Framework] [ERROR] [] [upgrade.Framework] [tid: 13] 
[ecid: 0000J97r9aPFw000jzwkno1EQ6_m000004,0] 
UPGCMP-02712: Expected oracle.biee.admin:oracleInstance=*,type=BIDomain.OracleInstance,
group=Service Oracle instance, found 2
[2011-09-08T03:07:12.240-04:00] [Framework] [NOTIFICATION] [] [upgrade.Framework] [tid: 13] 
[ecid: 0000J97r9aPFw000jzwkno1EQ6_m000004,0] 
Finished upgrading BIEE with status: Failure.
[2011-09-08T03:07:12.241-04:00] [Framework] [NOTIFICATION] [] [upgrade.Framework] [tid: 13] 
[ecid: 0000J97r9aPFw000jzwkno1EQ6_m000004,0] 
Finished upgrading components.
[2011-09-08T03:07:12.241-04:00] [Framework] [NOTIFICATION] [] [upgrade.Framework] [tid: 13] 
[ecid: 0000J97r9aPFw000jzwkno1EQ6_m000004,0]   
0 components upgraded with success.
[2011-09-08T03:07:12.241-04:00] [Framework] [NOTIFICATION] [] [upgrade.Framework] [tid: 13] 
[ecid: 0000J97r9aPFw000jzwkno1EQ6_m000004,0]   
1 components upgraded with failure.
My Oracle Support (MOS) didn't turn up any hits on that error number. The Google Machine did though. This OTN Forum post has the same exact problem. It appears that Merlin128 is talking to him or herself. I'm ok with that.

yes it was the web-tier.. or actually any component that creates a second instance...the upgrade utility only works with 1 instance installed.. to temporarily have only one instance.. I was able to change this file. run the upgrade. then change it back...middleware\user_projects\domains\bifoundation_domain\opmn\topology.xml

I tried that, commented out the second ias-instance section and restarted all the services (Linux 64).

Run the Upgrade Assistant, no joy.

With a little more research on MOS, I found note ID 1336567.1 which provides an 11.1.1.3 and 11.1.1.5 RPD. Yay.

To my above comment about how a pre-11g component got in there, the MOS note says:

The UsageTracking.rpd shipped is actually a pre 11.1.1.3 version and cannot be opened in the current versions of OBIEE 11g Administrator. It was shipped inadvertently.

All was not lost, I did find the master note for Usage Tracking Issues, ID 1293415.1.

So, I can't open the Usage Tracking web catalog in Catalog Manager (runcat.sh). I tried to deploy just the Usage Tracking catalog...and the BI Presentation server wouldn't come back up. Upgrade Assistant still doesn't work.

Help?

Update 09/08/2011 13:33 EST

So I thought I could use the Oracle created SampleApp (v105, not v107) and received a similar failure:
[2011-09-08T10:29:57.471-07:00] [Framework] [ERROR] [UPGAST-00138] 
[upgrade.Framework] upgrade exception occurred
[2011-09-08T10:29:57.471-07:00] [Framework] [ERROR] 
[upgrade.Framework] 
Cause: An unexpected upgrade exception has occurred. 
Action: See the secondary error message for additional details.
[2011-09-08T10:29:57.471-07:00] [Framework] [ERROR] [upgrade.Framework] 
UPGCMP-02712: Expected oracle.biee.local:* Oracle instance, found 0
[2011-09-08T10:29:57.471-07:00] [Framework] [ERROR] [upgrade.Framework] 
UPGCMP-02712: Expected oracle.biee.local:* Oracle instance, found 0
That VM has Essbase, amongst other components. I speculate there is some sort of (yet unknown) weirdness going on when you don't have a straight (just OBIEE) install.

Wednesday, September 7, 2011

DROP DATABASE;

I decided to blow away one of my newly created databases. Instead of using the DBCA, I decided to try it manually.
DROP DATABASE;

DROP DATABASE
*
ERROR at line 1:
ORA-01586: database must be mounted EXCLUSIVE and not open for this operation
Not it.
SQL> SHUTDOWN;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> STARTUP MOUNT EXCLUSIVE;
ORACLE instance started.

Total System Global Area 1048059904 bytes
Fixed Size                  2219992 bytes
Variable Size             608174120 bytes
Database Buffers          432013312 bytes
Redo Buffers                5652480 bytes
Database mounted.
SQL> DROP DATABASE;
DROP DATABASE
*
ERROR at line 1:
ORA-12719: operation requires database is in RESTRICTED mode
Ugh.
SQL> STARTUP NOMOUNT;
ORACLE instance started.

Total System Global Area 1048059904 bytes
Fixed Size                  2219992 bytes
Variable Size             608174120 bytes
Database Buffers          432013312 bytes
Redo Buffers                5652480 bytes
SQL> DROP DATABASE;
DROP DATABASE
*
ERROR at line 1:
ORA-01507: database not mounted


SQL> ALTER DATABASE MOUNT;

Database altered.

SQL> DROP DATABASE;
DROP DATABASE
*
ERROR at line 1:
ORA-12719: operation requires database is in RESTRICTED mode
Not it. Here's the SQL Reference. Maybe that RESTRICTED reference means something...
SQL> STARTUP MOUNT RESTRICTED;
ORACLE instance started.

Total System Global Area 1048059904 bytes
Fixed Size                  2219992 bytes
Variable Size             608174120 bytes
Database Buffers          432013312 bytes
Redo Buffers                5652480 bytes
ORA-01504: database name 'RESTRICTED' does not match parameter db_name
'TESTING'
Barnacles. Perhaps the Administrator's Guide has something.
SQL> STARTUP MOUNT TESTING;
ORACLE instance started.

Total System Global Area 1048059904 bytes
Fixed Size                  2219992 bytes
Variable Size             608174120 bytes
Database Buffers          432013312 bytes
Redo Buffers                5652480 bytes
Database mounted.
SQL> DROP DATABASE;
DROP DATABASE
*
ERROR at line 1:
ORA-12719: operation requires database is in RESTRICTED mode


SQL> ALTER DATABASE RESTRICTED;
ALTER DATABASE RESTRICTED
                        *
ERROR at line 1:
ORA-02231: missing or invalid option to ALTER DATABASE


SQL> ALTER DATABASE READ ONLY;
ALTER DATABASE READ ONLY
                    *
ERROR at line 1:
ORA-02231: missing or invalid option to ALTER DATABASE
Last try
SQL> STARTUP NOMOUNT RESTRICT;
ORACLE instance started.

Total System Global Area 1048059904 bytes
Fixed Size                  2219992 bytes
Variable Size             608174120 bytes
Database Buffers          432013312 bytes
Redo Buffers                5652480 bytes
SQL> DROP DATABASE;
DROP DATABASE
*
ERROR at line 1:
ORA-01507: database not mounted


SQL> ALTER DATABASE MOUNT;

Database altered.

SQL> DROP DATABASE;

Database dropped.

Disconnected from Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
Voila!

Thursday, September 1, 2011

T-Shirt: Now in Pink

I haven't done much with the T-Shirt collection lately. For whatever reason, I finally decided to do one in pink.

You have one month until Oracle OpenWorld...and did I mention it goes to a good cause?

Wednesday, August 31, 2011

PL/SQL + BI Publisher + Customer Calendar

by Husam Khalaf
I had a requirement to automate running a set of BI Publisher reports using the corporate fiscal calendar. The problem with BI Publisher scheduler is that is uses the normal calendar and there is no way to integrate a custom calendar instead. So I had to choose between two options to solve this problem:

1 - Utilize BI Publisher's Web Services API using Java code.

2 - Utilize BI Publisher's Web Services API using PL/SQL code.

The first option was more popular, I could google it and I found some examples that I could start with. The problem is that I am not a big fan of Java, and last time I've done coding in Java was a few years ago. On the other hand, I love PL/SQL, and I've done web services calls using custom PL/SQL before, such as integrating to CRM OnDemand and some Online Payment Gateway, but the problem was that I've never done that with BI Publisher. So I had to google this option first and unfortunately I could find almost nothing regarding this, so I had to start almost from scratch. I found two documents that were helpful to some extent:Long story short, I was able to accomplish this goal using PL/SQL, and I thought it may be a nice idea to share my experience if someone comes across a similar requirement. Here is a summary of what I've done:
  • I created a variables table to store some parameters that may be different in different environments (Development, Testing and Production):
BIP_WS_CONFIG
ATTRVAL
NSxmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="xmlns=http://1.2.3.4:9999/oxp/service/PublicReportService
REP_ABS_PATH/National Sales/BIP Reports/DPI/
WSDL_URLhttp://1.2.3.4:9704/xmlpserver/services/PublicReportService
USERNAMEbip_service_acct
PWDD486ACCFD
BIP_SERVER1.2.3.4
BIP_PORT9999

Where 9999 can be replace by your BI Publisher port#, and 1.2.3.4 can be replaced by you BI Publisher server. I am also encrypting the BI Publisher service account password using some custom encryption function that I won't demonstrate here.
  • I created a utility package to handle web service calls in general, I tried not to make it specific to BI Publisher web services for reusability.
create or replace
PACKAGE pkg_webservice_utl 
AS
  g_app_name VARCHAR2(50);
  FUNCTION make_request(
      p_appl             IN VARCHAR2,
      p_url              IN VARCHAR2,
      p_action           IN VARCHAR2 default 'SOAPAction',
      p_version          IN VARCHAR2 default '1.1',
      p_envelope         IN CLOB,
      p_proxy_override   IN VARCHAR2 default null,
      p_wallet_path      IN VARCHAR2 default null,
      p_wallet_pwd       IN VARCHAR2 default null) RETURN XMLTYPE;
  FUNCTION parse_xml   (
      p_appl             IN VARCHAR2,
      p_xml              IN XMLTYPE,
      p_xpath            IN VARCHAR2,
      p_ns               IN VARCHAR2 default null) RETURN VARCHAR2;
  FUNCTION clob_to_varchar2( p_clob_in  CLOB) RETURN VARCHAR2;
  FUNCTION encrypt( P_STR VARCHAR2 ) RETURN RAW;
  FUNCTION decrypt( P_XCRYPT VARCHAR2 ) RETURN VARCHAR2;
END pkg_webservice_utl;
/
show errors 

create or replace
PACKAGE BODY PKG_WEBSERVICE_UTL AS
------------------------------------------------------------
-----------------------------***************----------------
------------------------------------------------------------
-- Package WEB_SERVICE_UTL
-- This package provides functions that can be used to
-- invoke web services
-- Example: Invoke web service call to run and schedule BI
-- Publisher reports
------------------------------------------------------------
-----------------------------***************----------------
------------------------------------------------------------
 
  FUNCTION clob_to_varchar2 (p_clob_in CLOB) RETURN VARCHAR2 
  AS
------------------------------------------------------------
-----------------------------***************----------------
------------------------------------------------------------
-- Function CLOB_TO_VARCHAR2
-- Purpose:
-- This function coverts a clob to varchar2
-- Returns: The passed clob in varchar2 format
------------------------------------------------------------
-----------------------------***************----------------
------------------------------------------------------------
    v_strt        INTEGER := 1;
    v_chunk_size  INTEGER := 4000;
    v_return      VARCHAR2(32767) := NULL;
    v_err_return  NUMBER;
  BEGIN
    IF DBMS_LOB.getlength ( p_clob_in ) > 32767 THEN
      RETURN NULL;
    END IF;
    -- Parse the CLOB
    WHILE LENGTH (NVL(v_return,0)) <> DBMS_LOB.getlength ( p_clob_in )
    LOOP
     v_return := v_return || DBMS_LOB.SUBSTR ( p_clob_in,
                                               v_chunk_size,
                                             ( v_chunk_size * ( v_strt - 1 ) ) + 1 );
     v_strt := v_strt + 1;
    END LOOP;

    RETURN v_return;
  EXCEPTION 
    WHEN OTHERS THEN
    --log the error in some error table        
    return null; 
  END clob_to_varchar2;

  FUNCTION make_request (
    p_appl              IN VARCHAR2,
    p_url               IN VARCHAR2,
    p_action            IN VARCHAR2 DEFAULT 'SOAPAction',
    p_version           IN VARCHAR2 DEFAULT '1.1',
    p_envelope          IN CLOB, 
    p_proxy_override    IN VARCHAR2 DEFAULT NULL,
    p_wallet_path       IN VARCHAR2 DEFAULT NULL,
    p_wallet_pwd        IN VARCHAR2 DEFAULT NULL ) RETURN XMLTYPE 
  AS
-----------------------------------------------------------
-----------------------------***************----------------
------------------------------------------------------------
-- Function MAKE_REQUEST
-- Purpose:
-- This function submits a web service call in HTTP request
-- and utilizes the oracle package to construct HTTP
-- requests and read HTTP responses
-- Returns: The HTTP response (SOAP) in XML format
------------------------------------------------------------
-----------------------------***************----------------
------------------------------------------------------------
    TYPE HEADER IS RECORD (NAME VARCHAR2(256), VALUE VARCHAR2(1024));
    TYPE header_table IS TABLE OF HEADER INDEX BY BINARY_INTEGER;
    v_request_cookies   utl_http.cookie_table;
    v_response_cookies  utl_http.cookie_table;
    v_http_req          utl_http.req;
    v_http_resp         utl_http.resp;
    v_hdrs              header_table;   
    v_request_headers   header_table;
    v_hdr               HEADER;  
    v_clob              CLOB;   
    v_raw_data          RAW(512);     
    v_response          VARCHAR2(2000);
    v_name              VARCHAR2(256);
    v_hdr_value         VARCHAR2(1024); 
    v_line              VARCHAR2(1000);
    v_status_code       PLS_INTEGER;
    v_env_len           INTEGER := 0;
    v_err_return        NUMBER;
  BEGIN
    g_app_name := p_appl;
    v_env_len := v_env_len + lengthb(clob_to_varchar2(p_envelope));
    dbms_output.put_line('v_env_lenb= '||v_env_len);
    dbms_output.put_line('Setting proxy');
    utl_http.set_proxy (proxy => p_proxy_override);
    dbms_output.put_line('Setting timeout');
    utl_http.set_persistent_conn_support(true);
    utl_http.set_transfer_timeout(180);  -- 180 seconds

    -- set wallet if needed
    IF instr(lower(p_url),'https') = 1 THEN
      utl_http.set_wallet(p_wallet_path, p_wallet_pwd);
    END IF;

    -- set cookies if necessary
    IF V_request_cookies.count > 0 THEN
      utl_http.clear_cookies;
      utl_http.add_cookies(v_request_cookies);
    END IF;

    dbms_output.put_line('Begining HTTP request');
    v_http_req := utl_http.begin_request(p_url, 'POST');

    -- set standard HTTP headers for a SOAP request
    dbms_output.put_line('Setting HTTP request headers'); 
    utl_http.set_header(v_http_req, 'Proxy-Connection', 'Keep-Alive');

    IF p_version = '1.2' THEN
      utl_http.set_header(v_http_req, 'Content-Type', 'application/soap+xml; charset=UTF-8; action="'||p_action||'";');
    ELSE
      utl_http.set_header(v_http_req, 'SOAPAction', p_action);
      utl_http.set_header(v_http_req, 'Content-Type', 'text/xml; charset=UTF-8');
    END IF;

    dbms_output.put_line('Setting header length');
    utl_http.set_header(v_http_req, 'Content-Length', v_env_len);
    dbms_output.put_line('Setting headers from v_request_headers');

    --set headers from v_request_headers
    FOR i in 1.. v_request_headers.count LOOP
      utl_http.set_header(v_http_req, v_request_headers(i).name, v_request_headers(i).value);
    END LOOP;

    dbms_output.put_line('Reading the envelope and write it to the HTTP request');

    -- read the envelope, convert to UTF8 if necessary, then write it to the HTTP request
    utl_http.write_text(v_http_req, clob_to_varchar2(p_envelope));

    -- get the response
    dbms_output.put_line('getting the response');

    v_http_resp := utl_http.get_response(v_http_req);
    dbms_output.put_line('Response status_code: '   ||v_http_resp.status_code);   
    dbms_output.put_line('Response reason_phrase: ' ||v_http_resp.reason_phrase);  
    dbms_output.put_line('Response http_version: '  ||v_http_resp.http_version); 

    -- set response code, response http header and response cookies global
    v_status_code := v_http_resp.status_code;
    utl_http.get_cookies(v_response_cookies);

    FOR i in 1..utl_http.get_header_count(v_http_resp) LOOP
      utl_http.get_header(v_http_resp, i, v_name, v_hdr_value);
      v_hdr.name  := v_name;
      v_hdr.value := v_hdr_value;
      v_hdrs(i)   := v_hdr;
    END LOOP;

    v_request_headers := v_hdrs;
    dbms_output.put_line('converting the HTTP response');

    BEGIN <>
      LOOP UTL_HTTP.read_raw(v_http_resp, v_raw_data, 512);
        v_clob := v_clob || UTL_RAW.cast_to_varchar2(v_raw_data);
      END LOOP response_loop;

    EXCEPTION 
      WHEN UTL_HTTP.end_of_body THEN    
        dbms_output.put_line('End of body in response loop');
        UTL_HTTP.end_response(v_http_resp);   
      WHEN OTHERS THEN
        dbms_output.put_line('Unkown error in response loop:'||sqlerrm);
        return null;
    END;

    dbms_output.put_line('Response length: '||LENGTH(v_clob) );   
    dbms_output.put_line('HTTP response:'); 

    FOR i in 0..CEIL(LENGTH(v_clob) / 512)-1 LOOP
      v_line := SUBSTR(v_clob, i * 512 + 1, 512);
      dbms_output.put_line('[' || LPAD(i, 2, '0') || ']: ' || v_line);
      EXIT WHEN i > 50 - 1;   
    END LOOP;

    dbms_output.put_line('Closing HTTP request and response');

    IF v_http_req.private_hndl IS NOT NULL THEN      
      UTL_HTTP.end_request(v_http_req);   
    END IF;     

    IF v_http_resp.private_hndl IS NOT NULL THEN
      UTL_HTTP.end_response(v_http_resp);   
    END IF;

    dbms_output.put_line('Converting response text to XML');
    return xmltype.createxml(v_clob);
  EXCEPTION 
    WHEN OTHERS THEN
      --log the error in some error table
      return null;
  END make_request;

  FUNCTION parse_xml 
    ( p_appl  IN VARCHAR2,
      p_xml   IN XMLTYPE,
      p_xpath IN VARCHAR2,
      p_ns    IN VARCHAR2 DEFAULT NULL ) RETURN VARCHAR2 
  AS
------------------------------------------------------------
-----------------------------***************----------------
------------------------------------------------------------
-- Function parse_xml
-- Purpose:
-- This function reads SOAP response content in XML format
-- and parses it to
-- extract certain response values
-- Returns: A variable of varchar2 data type
------------------------------------------------------------
-----------------------------***************----------------
------------------------------------------------------------
    v_response          VARCHAR2(32767);
    v_err_return        NUMBER;
  BEGIN
    g_app_name := p_appl;
    dbms_output.put_line('Parsing result from SOAP response XML');
    v_response := dbms_xmlgen.convert(p_xml.extract(p_xpath,p_ns).getstringval(),1);
    dbms_output.put_line(v_response);
    return v_response;
  EXCEPTION 
    WHEN OTHERS THEN
      --log the error in some error table
      return null;
  END parse_xml;
END PKG_WEBSERVICE_UTL;
/

show errors
I created a function that uses this utility package to schedule a BI Publisher report:
create or replace
FUNCTION fn_schedule_report 
  ( P_REPORT_NM VARCHAR2 , 
    P_FORMAT VARCHAR2, P
    _BURST NUMBER DEFAULT 1 ) RETURN NUMBER 
IS
-------------------------------------------------------------------------------
-----------------------------***************-----------------------------------
-------------------------------------------------------------------------------
-- Function FN_SCHEDULE_REPORT
-- Purpose:
-- This function utilizes the WEB_SERVICE_PKG to schedule / run BIP Publisher
-- reports through web service calls
-- Returns: Job ID if sucess , 0 if failure
-------------------------------------------------------------------------------
-----------------------------***************-----------------------------------
-------------------------------------------------------------------------------
  v_response        VARCHAR2(32767);
  v_ns              VARCHAR2(4000);
  v_url             VARCHAR2(500);
  v_job_name        VARCHAR2(500);
  v_report_name     VARCHAR2(500);
  v_report_abs_path VARCHAR2(500);
  v_report_rel_path VARCHAR2(500);
  v_bip_server      VARCHAR2(500);
  v_username        VARCHAR2(50);
  v_password        VARCHAR2(50);
  v_seq             NUMBER;
  v_soap_env        CLOB;
  v_xml             XMLTYPE;
  v_burst           NUMBER; 
  v_err_return      NUMBER;
  v_port            NUMBER;
BEGIN
  -- get web service paramerters from the BIP_WS_CONFIG variables table
  select trim(val)
  INTO   v_ns
  FROM   BIP_WS_CONFIG
  WHERE  upper(attr) = 'NS';

  select trim(val)
  into   v_report_rel_path
  FROM   BIP_WS_CONFIG
  WHERE  upper(attr) = 'REP_ABS_PATH';

  select trim(val)
  into   v_url
  FROM   BIP_WS_CONFIG
  WHERE  upper(attr) = 'WSDL_URL';

  select trim(val)
  into   v_username
  FROM   BIP_WS_CONFIG
  WHERE  upper(attr) = 'USERNAME';

  SELECT trim(val)
  into   v_bip_server
  FROM   BIP_WS_CONFIG
  WHERE  upper(attr) = 'BIP_SERVER';

  SELECT trim(val)
  into   v_port
  FROM   BIP_WS_CONFIG
  WHERE  upper(attr) = 'BIP_PORT';

  select pkg_webservice_utl.decrypt(trim(val)) val
  into   v_password
  FROM   BIP_WS_CONFIG
  where  upper(attr) = 'PWD';

  IF p_burst = 1 THEN
    v_burst := 1;
  ELSE
    v_burst := 0;
  END IF;

  -- set report name
  v_report_name:= p_report_nm;

  -- generate a new JOB id
  select bip_job_id.nextval
  into   v_seq
  from   dual;

  v_job_name    := substr(v_report_name,instr(v_report_name,'/')+1 )||' #'||v_seq;

  v_report_abs_path := v_report_rel_path||v_report_name||'/'||v_report_name||'.xdo';
  dbms_output.put_line('absolute path:'|| v_report_abs_path);


  v_soap_env := '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
     <soapenv:Body>
        <pub:scheduleReport xmlns:pub="xmlns=http://'||v_bip_server||':'||v_port||'/oxp/service/PublicReportService">
           <scheduleRequest>
              <deliveryRequest>
              </deliveryRequest>
              <reportRequest>
                 <attributeFormat>'||lower(p_format)||'
                 <reportAbsolutePath>'||v_report_abs_path||'
              </reportRequest>
              <userJobName>'||v_job_name||'
              <scheduleBurstringOption>'||v_burst||'
           </scheduleRequest>
           <userID>'||v_username||'
           <password>'||v_password||'
        </pub:scheduleReport>
     </soapenv:Body>
  </soapenv:Envelope>';

  dbms_output.put_line('calling make_request function');

  v_xml := pkg_webservice_utl.make_request
              ( p_appl => P_APP,
                p_url  => v_url,
                p_envelope => v_soap_env );

  v_response := pkg_webservice_utl.parse_xml(p_app, v_xml,'//scheduleReportReturn/text()',v_ns);

  -- v_response is expected to be a numeric value "job id" if the report is
  -- successfully scheduled, check if value is numeric
  IF REGEXP_LIKE (v_response, '^[0-9]*$') THEN
    dbms_output.put_line('Job ID:'||v_response||' submitted successfully');
    return v_response;
  ELSE
    dbms_output.put_line('Report Schedule Request Failed');
    return 0;
  END IF;

EXCEPTION 
  WHEN OTHERS THEN
    -- log error into some error log
    dbms_output.put_line(sqlerrm);
    return 0;
END fn_schedule_report;
  • Finally, I wanted to get the status of the scheduled report. This is a little bit tricky because I could not find a BI Publisher web service operation that returns this information. The only 3 operations that I thought may help were:
    • -getScheduledReportStatus and getScheduledReportInfo operations: Only return info about a job that is still in the scheduler. Once the scheduled report is kicked off, it will be removed from the 'scheduler', so null will be returned.
    • -getScheduledReportHistoryInfo: Always returned null, I could not figure why is that, but it may be for the same reason above.
So after doing some research, I figured that there are two BI Publisher tables that can be utilized to obtain a scheduled report status:
  • XMLP_SCHED_JOB: maintains information about scheduled jobs. Once a report is scheduled an record will be inserted into this table along with information about that job.
  • XMLP_SCHED_OUTPUT: maintains information about running jobs (reports) or completed ( with success or failure) jobs. Once a report is kicked off a record will be inserted into this table along with information about that job. This is the table that we need.
So I wrote a function to get the status of an execute report as follows:
create or replace
FUNCTION FN_GET_REPORT_STAT( P_APP VARCHAR2, P_JOB_ID NUMBER ) RETURN NUMBER 
IS
------------------------------------------------------------
-----------------------------***************----------------
--------------------------------------------------------------  Purpose:
-- This function checks that status of a report by Job ID
-- Returns: 0 if sucess 'S', 1 if failed 'F', 2 if pending 'C'
------------------------------------------------------------
-----------------------------***************----------------
------------------------------------------------------------
  v_stat       CHAR(1) := 'C';
  v_timeout    NUMBER;
  v_duration   NUMBER;
  v_err_return NUMBER;
BEGIN
  IF p_job_id = 0 THEN --invalid job id
    return 1;
  ELSE
    SELECT status
    INTO   v_stat
    FROM   xmlp_sched_output
    WHERE  job_id = p_job_id;
  END IF;
 
  IF v_stat = 'S' THEN  -- success
    dbms_output.put_line('Report job# '||p_job_id||' finished successfully');
    return 0;
  ELSIF v_stat = 'C' THEN   -- Pending
    dbms_output.put_line('Report job# '||p_job_id||' is pending');
    return 2;
  ELSE  -- Failure or others like deleted, suspended..etc
    dbms_output.put_line('Report job# '||p_job_id||' failed');
    return 1;
  END IF;

  EXCEPTION 
    WHEN NO_DATA_FOUND THEN
     --Job is not started yet, so a record won't exist yet in xmlp_sched_output
     dbms_output.put_line('Job# '||p_job_id||' is not started yet and  record  does not exist yet in xmlp_sched_output');
     return 2;
    WHEN OTHERS THEN
    --log error in some error table
      return 1;
END FN_GET_REPORT_STAT;
/
show errors
Putting it all together:
I created a Unix shell script that does the following:

- Call
FN_SCHEDULE_REPROT( P_REPORT_NM => 'Report name',

P_FORMAT => 'Pdf',
P_BURST => 1 )
- Pass the retuned value to function FN_GET_REPORT_STAT

- If returned status from the FN_GET_REPORT_STAT function is 0 then return 'success'

- If returned status from the FN_GET_REPORT_STATfunction is 1 then return 'fail'

- If returned status from the FN_GET_REPORT_STAT function is 2 then loop every X minutes up to Y minutes (using the Unix sleep function) while status = 2 and check for status again as above ..etc

Tuesday, August 30, 2011

OBIEE 11g Performance with Google Page Speed

A few weeks ago I tried out YSlow on OBIEE 11g.

I finally managed to find some time to mess around with Oracle Web Tier (HTTP and WebCache).

The results:



I went from a D to a C. Not terrible.

This time, I also used Google Page Speed.



41 out of 100 using just the application server (WLS).

Now adding in the Oracle Web Tier components, Oracle HTTP Server and Oracle Web Cache.



76 out of 100. Much better.

OBIEE 11g is built on Oracle WebLogic Server. It was not intuitive, to me anyway, that everything was being served via an application server. Therefore, there is no caching of static files or compression.

Putting a web server in front of your application server is a very easy way to increase page load times.

I would assume (stop laughing) that any web server would do the exact same thing as the Oracle Web Tier components...but, you know me.