Thursday, July 12, 2012

Diagnosing and Reporting a Product Bug



When upgrading a customized UCM instance from a pre-10g release to 11g, we encountered a subtle but critical bug in OTS (Oracle Text Search), where the result of an incremental index update sometimes differed from that of a full collection index rebuild.

In this case, the client instance had a number of custom metadata fields, including Major Revision and Minor Revision. While Major Revision was a required field, a Minor Revision value was optional. A custom component allowed a user to explicitly search for documents with a blank Minor Revision. Here is where the fun started.

All content that had been migrated from the old instance to the 11g instance could be successfully be retrieved by the component, regardless of its Major Revision and/or Minor Revision values (or lack of value). All newly added content could be retrieved using the custom component…unless the Minor Revision was blank, and the search criteria being passed to the custom component explicitly looked for a blank Minor Revision. In that one case, no search results were returned.

For example, here were the results for a search of Document Number SO-G-108. Note that there are 15 items returned, 9 of which have blank minor revisions:




When we added the condition that the minor revision value must be blank, we got:




Yes, only 7 of the 9. From the Release Dates, we could see that the 2 that were missing had been checked in on April 24, i.e. after the content migration and a full search index rebuild. Just for reference, here’s how I defined that search:





I should add that when I was running the test show above, for the one with the 15-item result set, I also ran it with &IsSoap=1 appended to the URL, and the xppMinorRev values looked identical for all 9 with blank values there, i.e. there was no visible difference in the metadata values for the 7 that came back in the more specific search versus the 2 that did not.

In order to further help pinpoint the issue, we performed another collection index rebuild, and lo and behold, the search now returned all 9 documents with the blank minor revision. We then immediately checked in another document fitting the criteria, and repeated the steps above. Sure enough, the “new” document showed up when only the Document Number was specified, but was not in the search results when the blank Minor Revision was added to the criteria. So, it was time to open a bug report with Oracle, with clear instructions on how to reproduce the errant behavior. Clearly, incremental indexing that occurs upon check-in was suspect here. The bug was opened, and Oracle replied: 





The short version of this long email is:  Bob is right, this is a bug. I’ll open one.  

Searching on nulls is fixed in ps5 for DATABASE.METADATA and DATABASE.FULLTEXT. However, I haven’t checked OracleTextSearch yet, so this is good test.

I created two text fields to test what Bob described. This query is converted to the following format before getting run on the database:

Universal format: xTextField <matches> `SO-G-108` <AND> xMinorRevision <matches> ``
Converted native query: ' ((SO#0023G#0023108) WITHIN xTextField)   and   ((idcnull) WITHIN xMinorRevision) '

Notice that the empty string `` is converted to idcnull for that actual database search.

When I look in the idctext2 table, I can see that empty xMinorRevision fields have ‘idcnull’ as their value.  So far everything makes sense.

select dDocName, xMinorRevision from idctext2 where xTextField LIKE 'SO-G-108';


DDOCNAME                       XMINORREVISION                
------------------------------ ------------------------------
PFLIES-LNX.US.001405           A                             
PFLIES-LNX.US.001406           A                             
PFLIES-LNX.US.001403           idcnull                       
PFLIES-LNX.US.001404           B       

When I run the query described above I get one hit, which is what I expect.
xTextField <matches> `SO-G-108` <AND> xMinorRevision <matches> ``

I can manually run this query on the database using the instructions in the note:
Troubleshooting OracleTextSearch in UCM 10g and 11g: How To Convert UCM Searches into SQL Queries (Doc ID 1333414.1)

This query is exactly the same as what UCM runs. It returns the expected document.
SELECT dDocName FROM idctext2 WHERE CONTAINS(dDocName, '((SO#G#108) WITHIN xTextField)   and   ((idcnull) WITHIN xMinorRevision) ')>0;

DDOCNAME                       XMINORREVISION                
------------------------------ ------------------------------
PFLIES-LNX.US.001403           idcnull 

Now, I go to optimize the field xMinorRevision and run a fast rebuild.  The fast rebuild does what it always does, and that’s update the otsmeta column, adding: 
<sdxMinorRevision>IDCNULL</sdxMinorRevision>.
 
If a minor revision exists, then it’s set to
<sdxMinorRevision>B</sdxMinorRevision>.  
The “sd” prefix means that the field is an SDATA section. 
 
However, and here’s where Bob is right about the problem, new checkins have idcnull set in the xMinorRevision field. But in the otsmeta column, the sdata section lacks IDCNULL. So yeah, looks like a bug. I’ll open one…
 
New checkins after the fast rebuild have this in otsmeta:
<sdxMinorRevision></sdxMinorRevision>

When they should have this:
<sdxMinorRevision>IDCNULL</sdxMinorRevision>


Oracle subsequently supplied a patch to the client, which resolved the problem.

The intent of this article is twofold:
  1. For any reader who has experienced similar behavior – this is indeed a bug, and Oracle does have a patch to address it. I am unsure if it has been included in any official patch release.
  2. If you suspect a bug in a product, be persistent and methodical in diagnosing and reporting the problem. If the behavior surfaces in a customization (as it did here), your first priority must be to successfully demonstrate the bad behavior WITHOUT the involvement of the customization in the mix. Finally, report the bug in as much detail as possible, and provide detailed instructions on how to reproduce the bad behavior. This will go a long way in getting the problem addressed.



Thursday, June 21, 2012

Debugging Pages in Content Server 11g



More often than not, new developers working with Content Server are baffled as to “how” to find a given resource include to edit, or exactly what data sets are available on a given page.

There are some very useful flags that can be used to reveal a “behind the scenes” look at what is actually happening on a given page. 

This post deals exclusively with the 11g release.  There are other flags available that work in previous releases of the software, but most of them have been rolled up into a new flag (IsPageDebug), which will be covered later in this post.


  • IsJava
This variable can be set as either a flag on a page or as a parameter to a service call.  When set to “1”, it instructs the Content Sever to return the data in the databinder using the Content Server’s hda format as shown (using the service PING_SERVER for an example).  

http://myinstance/idcplg?IdcService=PING_SERVER&IsJava=1

Contrary to the official documentation, IsJava returns both “local” data, plus any result sets that are generated as a by-product of the INITIAL request.  






  • IsSoap
This variable can be set as either a flag on a page or as a parameter to a service call.  When set to “1”, it instructs the Content Sever to return the data in the databinder using a SOAP format as shown (using the service PING_SERVER for an example).

http://myinstance/idcplg?IdcService=PING_SERVER&IsSoap=1

Contrary to the official documentation, IsSoap returns both “local” data, plus any result sets that are generated as a by-product of the INITIAL request.





  • trace
This Idoc function enables logging a debug or trace message to the debug trace output. A message can also be output to the console or to the system logs.

This function can used when creating dynamichtml includes in components, or as statements in profiles and workflows in the various applets.  


The use of tracing messages, particularly in workflows, is a powerful way to debug problems where the standard debug isn’t clear.

The trace function takes two mandatory parameters and one optional parameter.




Option
Obligation
Notes
The message itself
Mandatory
The options are

  • Your special text string, or a string variable that has been accumulated. 
  • It can also be set to “#all” to output the entire contents of the databinder as it exists when the <$trace$> statement is called.
  • It can also be set to “#local” to output just the data in the local data section of the databinder as it exists when the <$trace$> statement is called.

The location where the message will be relayed.
Mandatory (the documentation says “optional” but the trace isn’t output or visible anywhere if this option isn’t set.)
The options are

  • “#console” - displays to a console or the system audit trace.
  • “#log” - logs a message in the HTML log files.
  • The name of a variable (such as “StatusMessage”). In that case, the message is appended to the current value.

Tracing section
Optional
This option is only valid when “#console” is selected as the second parameter.  To log a message strictly as a profile debugging tool, for example, this parameter would be set to “docprofile”.  A list of valid OOTB values can be found on the System Audit page, under the “Tracing Sections” portion of the page.

Using a section helps to tidy up the output, and makes reading the tracing messages much easier.



Examples of a trace statement:

The following example logs the string message to the system console, which is always logged:
                           <$trace("message", "#console")$>

The following example logs the string message to the system console in the pagecreation tracing section.
                           <$trace("message", "#console", "pagecreation")$>

The following example logs the string message to the HTML Content Server log file.
                           <$trace("message", "#log")$>

The following example dumps all local variables and their values to the system console.
                           <$trace("#local", "#console")$>

The following example dumps all local variables, result sets, and environment variables to the system console.
                           <$trace("#all", "#console")$>


The following example dumps all data to the variable “MyTraceDump”, which can then be displayed on the page. This is useful for HCSP developers who may not have the appropriate access rights to view the console or the logs.
                              
<$trace("#all", "MyTraceDump")$>
            <$MyTraceDump$>
As an example of using <$trace$> in an applet scenario, here is a profile rule with a trace statement, and the resulting output in the system audit trace in the “docprofile” section.





  • IsPageDebug
I am utterly shocked that this flag is not in the official 11g documentation!!  IsPageDebug in my opinion is the most powerful debugging tool available for a developer in 11g.  It exposes the same functionality as IsJava and ScriptDebugTrace in earlier versions, but adds the most powerful part - the full contents of the final page binder, and some javascript tracing as well.  

With IsJava and IsSoap, it was noted above that only the INITIAL binder is exposed.  However, many pages have either special functions or <$executeService$> calls during the course of the page rendering that add data to the binder.  This data is not available on the initial request, but IsPageDebug gets all of that data and makes it available at the click of a button.


Note that this parameter must be used with a page that has a template associated with it.  It won’t work with PING_SERVER, for example, but would work wonderfully with a checkin page or a search page.


http://myinstance/idcplg?IdcService=CHECKIN_NEW_FORM&IsPageDebug=1
Near the bottom right corner of the page, a small gray button is displayed.







Clicking the button expands a tray as depicted.






These buttons have mostly very useful data associated with them.


  1. idocscript trace -This option performs like <$ScriptDebugTrace=1$> performed in versions 10g and earlier.  It displays a list of every include statement evaluated to render a page, along with the file/filesystem path where that include statement is actually located.  Indentations in the code show the number of times the include statement has been overridden, which is really helpful when debugging issues with includes that contain “super” references.







request binder - This option shows the data available at the time of the page request.






response binder – This option is similar to IsJava, where the initial data binder for the service response is shown.  Clicking on a header like “Local Data” shows/hides the information associated with the section.






final page binder – this option exposes all of the result sets and local variables available AFTER the page has completed rendering.  This is way useful when trying to figure out “how” a data value was computed for display, since additional data can be loaded as part of the page build process.  It also shows any local data variables that may have been altered during page generation. Clicking on a header like “Local Data” shows/hides the information associated with the section.






javascript log – this option shows the javascript trace calculated on the page using the idc JavaScript trace functions.  This is not a substitute for a normal JavaScript debugger, and I haven’t found a really good use for the functionality – yet.






Hopefully this bit of information is useful to help find answers when you need to know “where” something is coming from.

Monday, June 11, 2012

Declaring Records in 11g Like 10g and Earlier

With the 11g release of WebCenter Records (formerly Universal Records Management),
the definition of a “record” is now much blurrier than in previous versions of the
software.


While the new flexibility is nice, sometimes there is a desire to make sure that an item
really can’t get changed when it gets to a certain point – like when the “Is Record” box
in 10g and earlier was explicitly checked. Without that declaration, an item could still
be edited or otherwise manipulated.


A use case for “locking” such an item usually occurs when a policy or a contract is
being created. The document goes through several iterations of revision, and finally,
the last revision should be declared a “record”.


In 11g, the “Is Record” isn’t exposed on a checkin or update page. However, you can
still get the same functional result with a bit of configuration.

  1. In config.cfg, enable the following setting (RmaEnableFixedClone=true), and restart the managed server
  2. Once the system is restarted, go to the retention category where the document resides.
  3. “Browse”the category and find the item to be declared a record
  4. Under the “Actions” menu, select “Content Actions --> Create Fixed Clone”.

  1. The following dialog appears.
  2. Complete the options in the dialog. You will have to select the correct category where the cloned item will reside. Browse to the correct category, and then select “OK”. You will be returned to the document info page for the original item.
  3. Go to the retention category where the cloned item was placed. The following entry should appear. Depending on the system configuration, an icon may appear as shown.
  4. Clicking the info icon, and viewing the document information page shows the item as non-editable, non-deletable, and non-revisable. (If the entire metadata set for the item was displayed, the value for xIsRecord is now set to “1”).

Note that this technique only works with electronic content. Items managed by Physical Content Management are not affected by cloning.

Tuesday, May 15, 2012

Troubleshooting and Installation of WebCenter Sites 11gr1


David Parry & Tom Smith from Perficient teamed up with me to work through an installation of Oracle's first branded release of WebCenter Sites.

There are a number of key new features, but we don't go over any in this walkthrough. Perhaps we, or others, can join together to work through sample scenarios? I believe working like this is a great way to jumpstart the open community that Oracle embraces.

I've created a Vimeo Group for WebCenter Sites videos. Feel free to contribute!

Here's the official release notification from Oracle:

http://www.oracle.com/technetwork/middleware/webcenter/sites/overview/webcenter-sites-
111160-whatsnew-1610697.pdf

We really focus on everything before that point. After all, what good is knowing the product if you can't install it :)

Here's the video, no marketing, no company pitches, just teamwork:

http://vimeo.com/user11725852/wcsitestroubleshootingandinstallation

Keep in mind that this was a remote screen capture via google hangout. The quality isn't 100% (or 90%), but the key points are made. Next time, extra steps will be taken to improve capture quality.

Here's to collaboration!
-ryan

Monday, May 14, 2012

WCContent: Adding WebCenter Content to IE Quick Search


1. Go to the Admin Server

2. Open the Advanced Component Manager

3. Update the installed & enabled DesktopIntegrationSuite Component


4. Check the box for "Enable web browser search plug-in"


5. Click Update

6. Restart Content Server

7. Log into Content Server

8. Navigate to "My Content Server" --> "My Downloads"

9. Click on "Add browser search"
                a. pick the version of your running browser


10. Verify that the search provider was added correctly


11. Test!
            a. Notice that the search provider updates the quick search text field as well!






Enjoy!
-ryan

WebCenter Sites 11gr1 Jumpstart kit -- Available!


Hey all,

The WebCenter Sites 11gr1 Jumpstart Kit is available!

You can find it under Patch number 14060594

-ryan

WebTier 11.1.1.6 PS5 -- Now a full installer!


Quick update everyone,

FYI, the 11.1.1.6 WebTier binary is a full installer.

The previous few patch releases required 11.1.1.2 as a base installation, then an upgrade to the current release.

No longer the case!

Enjoy.

-ryan