Showing posts with label best practice. Show all posts
Showing posts with label best practice. Show all posts

Tuesday, January 26, 2010

Check Your Data

It's simple to avoid, but it is surprising how often developers will make the mistake of implementing new functionality without first verifying that it will work with data that already inhabit the database.

For example, your organization might need to update an existing Siebel implementation. One of the new requirements is to evaluate a Contact's Date of Birth, calculating the Contact's age and only allowing certain functionality for Contacts that are older than a limit.

To do this, you might create a calculated field that tests the Date of Birth so that the field's value is TRUE if the Contact is too young. If the field's value is FALSE, the restricted functionality is allowed.

You know that you have to handle NULL, because your calculated field won't return either TRUE or FALSE if the Date of Birth is NULL. But the business requirement calls for making Date of Birth a required field, and you can assume that no new Contacts will be created without a Date of Birth. Unfortunately existing data might contain NULL values that will break this functionality, and a NULL value in a required field can cause more problems, even in screens and views unrelated to the new age restriction.

Some configurators forget to thoroughly test their new functionality against the data already existing in the database. This situation might not be caught in the test cycle if only a small percentage of records have NULL values. But a situation like this can cause big problems if it is not caught before the new functionality is deployed.

The best practice is to carefully test to be sure that new functionality works with old data.

Monday, September 7, 2009

Setting the SSA Primary Field

When I started configuring Siebel, I was mostly self-taught, which means that I usually settled for the first way I found of accomplishing my goal. Setting the primary record on a multi-value group through script is one example.

My method: query for the record I needed in the child buscomp, obtain the row id, and then use that row id to update the primary id field of the parent. For example, if I needed to set the primary position on the Account buscomp, I would begin by looking up the position id, then I would use a SetFieldValue statement to set the Primary Position Id with the id I had retrieved.

Wrong approach! That is the dangerous way. A scripting error will potentially corrupt your database in the same way direct sql could, by breaking its referential integrity. Directly setting a primary id field is not supported by Oracle.

The feature I didn't understand, which makes the process much easier and safer, is a system field called SSA Primary. You may have noticed this field in MVG Applet configurations. It's a system field, much like Created or Id, but it is different in two important ways:
  1. The SSA Primary field does not correspond directly to a database column.
  2. The SSA Primary field is editable.
Like other system fields, it is not listed in the Fields object in Tools, and you don't have to explicitly activate it in scripting.

Using the SSA Primary field, here is the correct way to use script to set the primary on an MVG, as recommended by Oracle:
  1. Get the MVG business component using the BusComp.GetMVGBusComp method.
  2. Use BusComp.SetSearchSpec and BusComp.ExecuteQuery methods to locate the correct record on the MVG business component.
  3. Set the SSA Primary field with the statement BusComp.SetFieldValue("SSA Primary Field", "Y"), substituting the actual business component variable name.
  4. Use BusComp.WriteRecord on the parent business component. This is because the Primary Id field is on the parent.
Some versions of Siebel Tools will give a semantic warning when you check the syntax after you try to set the SSA Primary field. This is a Siebel bug, and this warning can be safely ignored.

Update - Fixed a typo caught by commenter Duarte: Above instructions previously contained BusComp.SetFieldValue("SSA Primary", "Y") instead of BusComp.SetFieldValue("SSA Primary Field", "Y"). Thanks Duarte!

Friday, May 1, 2009

Get Rid of Dead Code

How many Siebel developers believe that the best way to remove lines of code from an existing script is to put some comment characters in front of the un-needed code, preventing it from executing. Many developers will copy an existing line of code to change an operation or add a condition, "commenting" the original version instead of deleting it. -- Added 5/3

Good coding practice tells us to diligently and carefully comment and annotate changes to scripts, right? Lets take a step back for a moment and think it through. I'm not certain that the commented lines of script are very helpful, at least in most cases.

First of all, commented script rarely helps to trace the historical changes made in a script. If the commented changes are dated, as they often are, you might find the date helpful. But script comments don't lend themselves to historical analysis nearly as well as versioning. Comparing a previous version of a script with the current version, in a source control repository for example, is much easier than trying to decipher the versions from comments in the script itself. Especially considering that the comments from several changes are often mixed in together.

Secondly, commented script doesn't help much in understanding how the current version of the script works. Lets face it: when you examine a script, you are not looking at the code that is commented. You skip the comments and focus on the code that is still active. If the developer happened to leave some actual words among all the dead code, you might stop to read it, but you certainly won't spend much analysis to find out how the script used to work.

Thirdly, and perhaps most importantly, dead code can cause significant overhead on the Siebel server. Every development team that habitually comments unused blocks of script will soon find that an entire event handler has been commented. In fact, it is common to find Siebel repositories with multiple event handlers entirely commented out. Also common are scripted event handlers where no script is present at all. Event handlers are marked as scripted even if the script contains no executable code except the application-provided stub:

function WebApplet_PreCanInvokeMethod (MethodName,
&CanInvoke)
{
return (ContinueOperation);
}

These event handlers cause a measurable increase in CPU load, especially when the event is frequently encountered. The empty scripts also become a maintenance issue, increasing the time required to compile an srf.

So, get rid of all that dead code. If a scripted event handler is empty, completely delete the script record in the Tools list applet. If you are removing individual lines of script, make sure you fully document your changes in design documents, and use a source control system to keep previous versions of the script. But keep the script itself clean. A clean repository will be easier to maintain and provide less overhead on your Siebel server.

Wednesday, January 7, 2009

Two-Track Development: Part 1 - Establish a Process

Siebel projects often have lengthy development cycles, and enterprises often find that they need to manage overlapping releases where a development cycle is not complete before work begins on the next effort. Faced with such a requirement, project teams find themselves in the unenviable position of maintaining two Siebel development repositories at once, one for each project.

In the image to the left, you can see two development paths, one for Q1 and one for Q2. The Q1 path has an active development effort, with ongoing test cycles in QA and UAT. The Q2 path does not have a UAT environment, because only the Q1 path will be migrated to production. After the Q1 path deploys, Q2 will become the primary path, including DEV 2, TEST 2, and UAT. A new Q3 path can be created with the DEV 1 and TEST 1 environments.

To allow development to proceed on the Q2 path, the Q2 team must always be working with the latest version of the code from the previous project. The latest changes from the Q1 path must be merged to the Q2 path so that Q2 developers are working with an environment that looks like the one they will ultimately release. In other words, the Q2 repository includes a superset of Q1 and Q2 changes, just as the production repository will after Q2 deploys.

To successfully manage the process, it helps to have a regular merge schedule. At a pre-specified interval, such as once per week, a dedicated team member can discover changes to the DEV 1 environment, mediate conflict resolution between those changes and required configurations in the DEV 2 environment, and propagate those changes into the DEV 2 environment.

Once all changes have been merged into DEV 2, they will follow the normal promotion process to system test and, ultimately UAT and production.

How can this work? Over the next several posts I'll discuss some of the issues involved, along with some technical hints. I'll be relying especially on a process developed by a colleague of mine, Ashutosh Nigam.

Tuesday, May 27, 2008

On Field Update Invoke

The On Field Update Invoke user property is a clean way to run some custom functionality when a BusComp field is updated. If you reflexively assume that you need to put script in the SetFieldValue event, you should consider this user property to execute your specialized functionality instead.

The syntax is as follows:

User Property Name: On Field Update Invoke n
User Property Value: "[FieldToCheck]", "[BusCompName]", "[MethodName]", "[Condition]"

Condition is an optional parameter. If you leave it out, the method will be called any time the field is updated. If you include it, the condition must be true for the method to be invoked.


FieldToCheck is also optional. If the parameter is omitted, include double quotes as a placeholder. The method will be invoked any time the BusComp is updated, as if it were called from the BusComp_WriteRecord event. If the parameter is present, the user property works just like BusComp_SetFieldValue; the update happens as soon as the cursor leaves the FieldToCheck field.


Note that you can run a BusComp method on a different BusComp than the one that spawns the event. Specify the BusCompName and the MethodName. Siebel does this quite extensively (for updating child records when a parent record is updated, for example) to implement vanilla functionality. The BusComp method is invoked on another business component in the active Business Object.

It is also important to understand what methods can be called from this user property. It can be used to call an eScript function. You can add eScript to the BusComp_PreInvokeMethod event to capture the invocation and call a function on the current BusComp, and from there invoke a workflow process or business service.

The user property can also invoke methods on the Business Component Class that would normally be invoked through the InvokeMethod method. For example, you could call the CompleteActivity method on an Activity. Be aware of the specialized methods that are available for the class you are using.

If your implementation includes Siebel Order Management, Signals can also be raised from this user property. For any of the Order Management Business Components, if a method is not found on the business component itself, Siebel will raise a signal if it exists.

Whatever you choose, Siebel recommends the On Field Update Invoke user property as preferable to adding scripting to the BusComp_SetFieldValue event. The SetFieldValue event is inefficient, and even though the On Field Update Invoke user property may invoke a custom script, it can be more efficient than invoking the same script from the SetFieldValue event.

Wednesday, May 21, 2008

Another Reason to Comment

Carefully commenting all updated repository objects has clear benefits. It helps trace repository changes back to the responsible configurators. It helps accomplish a sort of configuration management so that you have a rudimentary history of changes that were made to the repository.

Complicating repository configuration management is the fact that Siebel developers do not start with a blank slate. Unlike a discreet block of script, Siebel configuration might involve meeting a single requirement by changing the value of one or two properties on several pre-existing objects throughout many different projects in the repository. Careful commenting can provide information about what changes were made, and why, and when.

One drawback for commenting the Siebel repository objects is the relatively small size of the Comments attribute itself, which commonly contains information about several changes by different developers to meet more than one requirement. If each comment includes the initials of the developer, the date, the requirement number, and a description of the changes made, you will quickly run out of space. A good approach to keeping comments concise is to reference an external document, such as a detailed technical design.

With all the configuration management concerns, you might not consider another, possibly more important reason to carefully comment repository object changes. These comments can be invaluable during a repository upgrade.

During configuration, upgrading can be the last thing you want to consider, but if the project is successful, upgrading is inevitable. And the Siebel upgrade process includes a many tedious and time-consuming steps. After the repository merge, which is an automated process that transforms the repository objects from one version to the next, there are usually hundreds or thousands of conflicts that must be manually reviewed. The Reviewing Siebel Repository Object Property Conflicts process is one of the most difficult, tedious, and error-prone tasks of the entire upgrade.

The conflicts that must be manually reviewed are cases where there are three versions of the same repository object, and there is no clear path for the automated upgrade to take. Siebel provides an Attribute List View that makes the process as easy as possible, and you have a 90% chance that the automated merge has actually identified the correct "Standard Win" version. But, for the remaining 10% of the attributes, which can be literally hundreds of choices, developer comments can be the key to an informed decision.