Ivan Smirnov’s Blog

February 7, 2010

WID tips: limit amount of Java code in snippets

Filed under: Uncategorized — ivansmirnov @ 12:03 PM

When you need to add custom functionality to an application you develop in WebSphere Integration Developer or extend its capabilities, you use Java. There are several ways to do this and at least one is available in each context:

  • on the module/assembly diagram level – create a Java component
  • inside a mediation flow – write your Java in a Custom Mediation primitive
  • in a BPEL process – use Snippet activity
  • in a BO map – use Custom transform

Best practice: only trivial code should go into Snippets and Custom Transform. Refactor more complex code into a utility Java class.

To promote code clarity and simplify maintenance, troubleshooting and debugging, I strongly urge limiting the amount of code you put in Custom Primitive, Snippet and Custom Transform to. Only trivial code should go there. Please do not implement complex or business-relevant logic there. These Java usages are not easily accessible (hidden behind layers of components), difficult to code-review and more cumbersome to step through when using a debugger. If you need to execute something more complex, refactor the logic into a separate utility class and limit your snippet (or custom transform) to a simple method call on the utility class. This approach adheres to many architectural best practices: separation of concerns (Information Expert pattern), promotion of reusability. Code quality improves and your application is easier to understand and maintain.

December 14, 2009

WPS: Querying human tasks with multiple custom properties

Filed under: Technology, Uncategorized — Tags: , , , , — ivansmirnov @ 11:17 PM

Suppose you have a human task application running on WebSphere Process Server. Your application requires creating, manipulating and assigning tasks based on certain criteria that are not exposed by HTM interface. Naturally, you add a custom property to your tasks to hold this “side” information. This process is described in this developerWorks article.

As an example, your query might look like this:
resultSet = htm.query(
"DISTINCT TASK.TKIID, TASK.NAME, TASK_CPROP.NAME",
"TASK_CPROP.NAME = 'branch'", …)

But what if you have more then 1 custom property? This Infocenter article gives an example where clause:
"TASK_CPROP1.NAME = 'prop1' AND " TASK_CPROP1.STRING_VALUE = 'v1' AND
TASK_CPROP2.NAME = 'prop2' AND " TASK_CPROP2.STRING_VALUE = 'v2'"

When do you need to add these ordinal numbers (like 1 and 2 in the example above) to the TASK_CPROP table name? Does the number has anything to do with the order in which the properties are defined on the task?

Rule:

  1. If you only use a single custom property in a query, reference TASK_CPROP table without ordinal number.
    You should not use TASK_CPROP1, TASK_CPROP2 or 3,4,5…9 in this case.
  2. If you use more then one custom property in a query, differentiate between them by adding a number to TASK_CPROP table name. You can pick any numbers you want, but be consistent within each query: use TASK_CPROP1 for one parameter, TASK_CPROP2 for another and so on.
    The number has no relationship with the order in which parameters are defined on the task.

    For example, your task may have 3 properties defined in the following order: propcount, branch, costCenter.

    Task with 3 properties: propcount, branch, costCenter

    And the following query referencing “branch” as #1 and “costCenter” as #2 will be perfectly valid:
    htm.query("DISTINCT TASK.TKIID, TASK.NAME, TASK_CPROP1.STRING_VALUE, TASK_CPROP2.STRING_VALUE",
    "TASK_CPROP1.NAME='branch' and TASK.CPROP2.NAME='costCenter'", ...)

Explanation:
Underlying data for custom properties of human tasks is stored in database table TASK_INST_PROP_T and exposed through a database view TASK_CPROP. Both the table and the view are agnostic of property number. The view is documented here. The view contains only 4 columns: TKIID, NAME, DATA_TYPE and STRING_VALUE. There is only one table/view for custom properties and it has no room to store property’s ordinal number. TASK_CPROP1, TASK_CPROP2 and so on are aliases created in the FROM clause of the query, which is auto-generated behind the scenes based on SELECT and WHERE clauses. So this query:
htm.query("DISTINCT TASK.TKIID, TASK.NAME, TASK_CPROP1.STRING_VALUE, TASK_CPROP2.STRING_VALUE",
"TASK_CPROP1.NAME='branch' and TASK.CPROP2.NAME='costCenter'", ...)

may be translated into SQL resembling this (my reconstruction, not actual SQL from WPS product):

SELECT
DISTINCT TASK.TKIID, TASK.NAME, TASK_CPROP1.STRING_VALUE, TASK_CPROP2.STRING_VALUE
FROM
TASK INNER JOIN TASK_CPROP as TASK_CPROP1 ON TASK.TKIID=TASK_CPROP1.TKIID
INNER JOIN TASK_CPROP as TASK_CPROP2 ON TASK.TKIID=TASK_CPROP2.TKIID
WHERE
TASK_CPROP1.NAME='branch'
and TASK.CPROP2.NAME='costCenter'

Same logic applies, mutatis mutandis, to task templates (TASK_TEMPL_CPROP view) and escalations (ESCALATION_CPROP view)

December 2, 2009

WSRR: WS-I validator and loading WSDL files

Filed under: Technology, Uncategorized — Tags: , , , , , , — ivansmirnov @ 7:54 PM

To WebSphere Service Registry and Repository (WSRR) practitioners, I’d like to recommend this excellent developerWorks article explaining how to leverage WS-I compliance validator that is part of that software. Among the things you will learn: how to make this validator enforce arbitrary restrictions expressed in Schematron.

Just one thing to keep in mind: this article was written for WSRR 6.2 and you will not be able to reproduce the scenario in this article with default settings of WSRR 6.3 (original or with Fixpack 1). This is because MAKE_GOVERNABLE event will not fire for WSDL documents containing endpoint definitions in default setup. I recommend that you replace MAKE_GOVERNABLE with CREATE event in sample code – then it will work.

Here’s how the story unfolds. When you load a service document (a WSDL document or a SCA module) into WSRR, a complex sequence of actions is taken by the software behind the scene. WSDL document is validated. The document is parsed and concepts relevant to WSRR are identified. Those include service, port, binding, operation, message and endpoint definitions, XML schema elements and types. All these objects are linked together. As these objects are created, configurable modifier kicks in to enable governance and initiate appropriate lifecycle. Once one item in a collection of linked objects has governance enabled, all other linked items are pointed to the same governance record. From that point on, they are governed together: it is not possible to enable governance separately for any other item in the linked collection.

Configurable modifier named “Triggers” contains the following fragment:

<!-- Mapping to push the relevant items through the Service Endpoint Lifecycle -->
<mapping>
<entity>
<any-of>
<model-type model-uri="http://www.ibm.com/xmlns/prod/serviceregistry/v6r3/ServiceModel#ServiceEndpoint"/>
<model-type model-uri="http://www.ibm.com/xmlns/prod/serviceregistry/v6r3/ServiceModel#MQServiceEndpoint"/>
<model-type model-uri="http://www.ibm.com/xmlns/prod/serviceregistry/v6r3/ServiceModel#SOAPServiceEndpoint"/>
<model-type model-uri="http://www.ibm.com/xmlns/prod/serviceregistry/v6r3/ServiceModel#ExtensionServiceEndpoint"/>
</any-of>
</entity>
<configuration name="InitiateEndpointLifecycle"/>
</mapping>

And configurable modifier named “InitiateEndpointLifecycle” includes this:

<?xml version="1.0" encoding="UTF-8"?>

<action-configuration xmlns="http://www.ibm.com/xmlns/prod/serviceregistry/Actions"
name="InitiateEndpointLifecycle"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.ibm.com/xmlns/prod/serviceregistry/Actions Actions.xsd">

<!-- Transition the selected object into the SLA Lifecycle -->
<make-governable-action uri="http://www.ibm.com/xmlns/prod/serviceregistry/lifecycle/v6r3/LifecycleDefinition#InitiateEndpointLifecycle"/>

</action-configuration>

These 2 modifiers are both enabled in Governance Enablement profile. Putting all this together, if a SOAP Service Endpoint is found in WSDL document, a SOAPServiceEndpoint object will be created and endpoint lifecycle will be initiated. WSDL document itself will be linked to the governance record of the SOAP Endpoint. It will not be possible to enable governance on the WSDL document separately.

Indeed, when a sample WSDL is loaded, we see exactly this effect. When I click on newly loaded WSDL document and proceed to the Governance tab, I see the following:

Governance Tab of WSDL document

Governance Tab of WSDL document

If I click on the “Root governance record” link, it takes me to the SOAP Service Endpoint:

SOAP Endpoint governance tab

SOAP Endpoint governance tab

WebSphere Business Monitor: troubleshooting events not flowing through a monitor model

Filed under: Technology, Uncategorized — Tags: , , , , — ivansmirnov @ 5:26 PM

One of the most common problems in WebSphere Business Monitor runtime administration is events not making it all the way to Dashboards (Portal or Business Space). Applications are running normally and emitting events that should be input to WebSphere Business Monitor (colloquially known as BAM), but BAM produces no output: no instance data is seen in dashboards. I’ve recently had an opportunity to troubleshoot 2 BAM installations in different organizations on consecutive days and I was faced with this problem in both cases.

Here are some things to check if you come across this situation:
1. A good first step in problem determination if you have access to monitor database is to check tables in the monitor model schema. There are few tables in this schema, so the task is easy. Here’s the list of tables from one simple model I developed:
CONSUMED_EVENT_T
PROCESSED_EVENTS
EVENT_SEQUENCE_INDICES
INCOMING_EVENTS
MCT_XTRCTMDLM_20091201151007
KCT_KPI_TRIGGER_20091201151007

There is one table per monitoring context (the one which name starts with MCT), plus tables for incoming, consumed and processed events, tables for KPIs and, in this case, one more service table. If this is the first time you attempt to run a model, you are just interested in cardinalities (number of rows in tables). Otherwise, you’d be looking at the number of recent rows.
If there is no data in any tables, events are not being routed to BAM. If there are rows in incoming_events table only, events are sent to BAM, but monitor model is not processing events. In the end, if the model works correctly, you should see one row in the monitoring context (MCT_*) table per, well, monitoring context created by original events.

2. Check that your monitor model is startable. Inspect SystemOut.log of the server running your model’s moderator module.
This message indicates successful startup of the monitor model:
[12/2/09 13:53:53:375 EST] 00000011 ConsumerDaemo I com.ibm.wbimonitor.mm.TestModel3.20081024161629.moderator.ConsumerDaemonHandlerImpl startDaemon() CWMRT3005I: The Monitor Model "TestModel3 20081024161629" is starting consumption on this server or cluster member in SERIAL_ST mode with reordering=false from PRIMARY_JMS_QUEUE.

On the other hand, this message indicates failure:
CWMRT2009W: The MM application is not in a startable state. This is usually because lifecycle steps are not complete.

If you see this error, perform step 3.

3. Check that mandatory lifecycle steps have been performed. Log on to admin console, go to Applications -> Monitor Models -> your model -> click on version -> make sure that all lights are green.
Monitor version deployment - lifecycle steps complete OK
“Schema created” is the only lifecycle step that impacts operational data flow through monitor model.
If “Schema created” step is red, database schema creation for the model did not complete. Click on “Manage schema” link on the right. If your database environment is not restrictive and monitor database user has administrative permissions, you can create schema by clicking “Run Create Schema Script” button. In case of restrictive databases, such as DB2 for z/OS, this button is not even enabled. You will need to export the DDL by clicking “Export Create Schema Script” and work with your DBA to create and configure schema.

4. Check that CEI distribution is active
Click on your model version, and check the text under “CEI distribution mode”.
Monitor model version CEI distribution is ActiveIt should be active AND it should be in the right mode. In most cases (with exception of test environment), you likely are using queue bypass, in which case CEI distribution mode should read “Active (monitor model queue bypass)”.
To change distribution mode, click on “Change CEI distribution mode” link on the right.
CEI distribution is Active with Queue bypass
Select desired value from “Target” drop down and click OK. Restart the target CEI server/cluster!

5. Check that correct CEI server has been configured as event source. This is a common problem in complex multiple cluster topologies.
Click on your model (not version) and then click on “Change CEI configuration”.
CEI source server selection
Check the table under “Event group profile list name” at the bottom of the properties page. In case of a complex topology with multiple CEI servers in the cell, all CEI-enabled clusters/servers will be listed individually. Make sure the right CEI server is selected (checkbox ticked). If you need to make a change, follow this procedure. First, checkboxes are made inactive (unavailable) if at least one model version has active CEI distribution. Deactivate CEI distribution for all model versions (change distribution mode to Inactive) as described in previous step. Wait for a minute for the change to become effective. Then come back to this property page – those checkboxes will become enabled. Select the right cluster/server, click Apply and then change distribution mode to Active for all model versions as described in step 4.

October 31, 2009

Update on Alphablox in WebSphere Business Monitor

Filed under: Technology, Uncategorized — Tags: , , , , , — ivansmirnov @ 11:58 AM

Earlier this year I blogged about installing Alphablox as part of WebSphere Business Monitor. Real production environments require clustering, and it was difficult to accomplish. Using DB2 on z/OS for data repository was particularly daunting task. Mike Killelea commented on my original post, noting that IBM disclaimed support for this scenario.

This time of the year, IBM is preparing version 7 of its BPM stack for release. From what I saw, Alphablox is much better integrated into Business Monitor (BAM). Remember, until now you had to run a separate Alphablox installer (with the exception of non-production-grade standalone profile). Now, ABX install is fully integrated. I specifically inquired about z/OS database support and was told that it is ON. I’ll post an update when I learn more.

October 19, 2009

Eliminate spurious orbtrc files on WebSphere client when using HTTPS tunneling

Filed under: Technology, Uncategorized — Tags: , , , , , , , — ivansmirnov @ 8:42 PM

When using WebSphere Application Client (J2EE, thin or pluggable) to access EJBs on WebSphere Application Server, an optional ORB trace file may be created. You can specify trace file location and name, but if you do not, default file name is orbtrc.timestamp.txt (e.g. orbtrc.10112009.1815.37.txt)
Of course, oftentimes you do not want any trace, and you certainly can turn tracing off. Well, with one exception. If you are using HTTP tunneling with SSL (HTTPS tunneling), trace file will be created automatically with the default name. This behavior has been known to affect several versions of WAS. I last confirmed it in WAS 6.1.
This may be annoying or inappropriate in some client environments. As a workaround, redirect trace output to null device by adding the following parameters to your client JVM command line:
for Windows
-Dcom.ibm.CORBA.Debug.Output=nul:
for Unix/Linux, use /dev/null.

October 18, 2009

No driverType in Oracle JDBC driver

Filed under: Technology, Uncategorized — Tags: , , , — ivansmirnov @ 9:19 PM

Database access in WebSphere Application Server is performed through JDBC Providers. JDBC Provider is a configuration element specifying JDBC driver class. For actual database access, one creates Data Sources underneath a JDBC Provider.
At runtime, the first time a data source is accessed, corresponding JDBC Provider is activated. At this time, WebSphere logs a series of informational messages detailing JDBC Provider version and configuration. One of the messages you can see in SystemOut log is DSRA8208I, which Infocenter documents this way:

DSRA8208I: JDBC driver type : {0}
Explanation: The JDBC driver type.
User Response: The JDBC driver type is now used by applications.

Driver type is JDBC driver type and nowadays almost universally equals 4 (pure Java).
When DB2 provider is in use, you might see this:
DSRA8208I: JDBC driver type : 4

However, with Oracle provider the message shows an empty driver type, which may cause confusion or concerns :
DSRA8208I: JDBC driver type : ""

What happened here? Has the driver loaded incorrectly or is unrecognized? Don’t worry. There is no reason for alarm – Oracle provider does not have “driverType” parameter and so this value is always empty with Oracle.

September 12, 2009

Stateful Session Bean failover performance in WebSphere Application Server

Filed under: Technology, Uncategorized — ivansmirnov @ 10:58 PM

Students of EJB specification may remember that it describes Stateful Session Beans (SFSB), a mechanism to preserve state in EJB container. This feature was not popular, as state is mostly handled in Web container in JEE applications, with EJB container providing stateless services. WebSphere Application Server, being a superb J2EE container, supports SFSB. Beginning with WAS version 6, when deployed to a clustered environment, you can enable SFSB failover, so your valuable state is not lost when an EJB container goes down for any reason. It is a telling indicator of low demand that this feature was not available in WebSphere until version 6 (J2EE 1.4 / J2SE 5), which came out in late 2004. SFSB failover in WAS is implemented through bean passivation. After each method call, bean is passivated, which requires serialization. Serialized object is then distributed to other EJB containers in the same cluster. Unlike HTTP session replication, tuning optimizations, such as time-based writes, are not available for SFSB failover. It is all or nothing: either you have no replication/failover or you incur overhead of inlined passivation on every call. Resulting performance is predictably poor. And I can not really blame IBM for not polishing a feature that is in apparently little demand. Another reason for you to stick with HTTP sessions and avoid SFSB.

July 5, 2009

Coexistence of WebSphere Business Monitor and Process Server 6.2

Filed under: Technology, Uncategorized — Tags: , , , , , , — ivansmirnov @ 9:56 PM

UPDATE 11/12: The fix for the issue described below is included in WBM 6.2 Fixpack 2, now publicly available.

ORIGINAL POST:
If you installed WebSphere Business Monitor (aka BAM) version 6.2 into the same directory as Process Server or WESB 6.2, you may run into problems with overlapping OSGI plugins.
Your WPS/WESB modules and mediations could fail with JXPath error like this:

[5/18/09 19:25:21:744 EDT] 0000005f ExceptionUtil E CNTR0020E: EJB threw an unexpected (non-declared) exception during invocation of method "transactionRequiredActivitySessionNotSupported" on bean "BeanId(TestFanoutApp#TestFanoutEJB.jar#Module, null)". Exception data:
Mediation primitive failure:
Mediation primitive: FanOut1
Component: TestFanout
Module: TestFanout
com.ibm.wsspi.sibx.mediation.MediationBusinessException: CWSXM3752E: Error using XPath expression [Ljava.lang.Object;@7d6e7d6e to locate repeating element: org.apache.commons.jxpath.JXPathException: No value for xpath: /body/print/input/orders. This has been reported by the following entity: ID=FanOut1,Request,print,PrintOrder,http://TestFanout/PrintOrder,TestFanout,TestFanout
at com.ibm.ws.sibx.mediation.primitives.util.ExceptionHelper.newMediationBusinessException(ExceptionHelper.java:128)
at com.ibm.ws.sibx.mediation.primitives.fan.FanOutMediation.locateRepeatingElement(FanOutMediation.java:726)
at com.ibm.ws.sibx.mediation.primitives.fan.FanOutMediation.performNonAggregationMediate(FanOutMediation.java:593)
at com.ibm.ws.sibx.mediation.primitives.fan.FanOutMediation.mediate(FanOutMediation.java:265)
at com.ibm.ws.sibx.scax.mediation.engine.JavaMediationPrimitive.performInvocation(JavaMediationPrimitive.java:630)
at com.ibm.ws.sibx.scax.mediation.engine.JavaMediationPrimitive.invoke(JavaMediationPrimitive.java:352)
at com.ibm.ws.sibx.scax.mediation.engine.MediationPrimitive.invokeConnections(MediationPrimitive.java:318)
at com.ibm.ws.sibx.scax.mediation.engine.JavaMediationPrimitive.fireOutputTerminals(JavaMediationPrimitive.java:728)
at com.ibm.ws.sibx.scax.mediation.engine.JavaMediationPrimitive.performInvocation(JavaMediationPrimitive.java:650)
at com.ibm.ws.sibx.scax.mediation.engine.JavaMediationPrimitive.invoke(JavaMediationPrimitive.java:352)
at com.ibm.ws.sibx.scax.mediation.engine.MediationPrimitive.invokeConnections(MediationPrimitive.java:318)
at com.ibm.ws.sibx.scax.mediation.engine.Input.invoke(Input.java:138)
at com.ibm.ws.sibx.scax.mediation.engine.RequestFlow.invokeFlow(RequestFlow.java:132)
at com.ibm.ws.sibx.scax.mediation.engine.MediationFlow.invokeRequestFlow(MediationFlow.java:145)
at com.ibm.wsspi.sibx.mediation.flow.ejb.MediationFlowBean.invokeRequestFlow(MediationFlowBean.java:231)
at com.ibm.wsspi.sibx.mediation.flow.ejb.EJSLocalStatelessTestFanout_c53bef64.invokeRequestFlow(EJSLocalStatelessTestFanout_c53bef64.java:127)
at com.ibm.ws.sibx.scax.mediation.component.ejb.EJBMediationFlowComponentImpl.invokeRequestFlow(EJBMediationFlowComponentImpl.java:223)
at com.ibm.ws.sibx.scax.runtime.handler.MFCImplementationHandler.processMessage(MFCImplementationHandler.java:199)
at com.ibm.ws.sca.internal.message.impl.MessageDispatcherImpl.processMessageWithPCI(MessageDispatcherImpl.java:715)
at com.ibm.ws.sca.internal.message.impl.MessageDispatcherImpl.processMessage(MessageDispatcherImpl.java:1167)
at com.ibm.ws.sca.internal.message.impl.ManagedMessageImpl.process(ManagedMessageImpl.java:843)
at com.ibm.wsspi.sca.ejb.module.impl.ModuleSessionBean.processUOWMessage(ModuleSessionBean.java:336)
at com.ibm.wsspi.sca.ejb.module.impl.ModuleSessionBean.transactionRequiredActivitySessionNotSupported(ModuleSessionBean.java:315)
at com.ibm.wsspi.sca.ejb.module.EJSLocalStatelessModule_43132892.transactionRequiredActivitySessionNotSupported(EJSLocalStatelessModule_43132892.java:233)
at com.ibm.ws.sca.internal.uow.handler.UOWStrategyImpl.transactionGlobalActivitySessionFalse(UOWStrategyImpl.java:311)
at com.ibm.ws.sca.internal.uow.handler.JoinUOWHandler.processMessage(JoinUOWHandler.java:165)
[snip]

Or you may have classloading problems when trying to work with monitor models.

Same issues may occur with fixpack 1 of both products (WPS/WESB 6.2.0.1 and WBMonitor 6.2.0.1)
This is happening because WPS/WESB and WBM/BAM each comes with its own version of JXPath libraries. A fix for this issue will soon be publicaly available from the monitor team. It would restrict visibility of JXPath library packaged with WBM to monitor code.
If your symptoms match, please ask IBM support about JR33245.

June 7, 2009

Database creation script for Alphablox install

Filed under: Technology, Uncategorized — Tags: , , , , , , — ivansmirnov @ 9:28 PM

Suppose you install Alphablox, say as part of WebSphere Business Monitor product. Alphablox has been and still remians (as of version 6.2) an important integral part of WBM, providing dimensional analysis of monitored data and KPIs. Alphablox requires a number of database objects to function. By default it will attempt to create database tables it needs upon first run. But what if you are using DB2 for z/OS or another restrictive database environment, where programs are not allowed to run DDL. DBAs hold the keys to database structure and you are required to submit any DDL to a DBA for review and execution. Not unreasonable for a structured corporate IT where I’d expect to find WebSphere Business Monitor.
So you want to get your hands on DDL Alphablox would attempt to execute and hand it your DBA. It is possible, even though scripts are not on the surface as they are for the rest of WBM (or othe products in Business Process Management stack).

While scripts do not exist in a form of standalone DDL files, DDL statements are available. Just inspect properties file named $ABX_ROOT/repository/servers/$dbtype.dmlsql, where $ABX_ROOT is the root of Alphablox installation directory and $dbtype is your database type, e.g. db2_zos.dmlsql
Look for properties named DDL.CREATE1-DDL.CREATE6 and DDL.INDEX1-DDL.INDEX10

You will find entries like this:

DDL.CREATE1            = CREATE TABLE ABX_VERSION (DESCRIPTION VARCHAR(32) NOT NULL, VALUE VARCHAR(64) NOT NULL)

This is not a complete script, of course. You will have to add things like tablespaces and permission grants, but all it is exactly what program needs.

DROP statements and a number of updates/inserts round out this file.

UPDATE 12/5/2009. In response to Mike Killelea’s comment below. I worked with Mike on the DB2-z/OS based Alphablox installation. Mike correctly mentions that ABX install over DB2/z not straightforward. Installation procedure is nothing like regular ABX install and you have to jump through some hoops. Yet in the end it is possible to host Alphablox repository on DB2-z/OS. In my post, I wanted to give a pointer that would be useful in doing so. It is certainly not all you will need to do. I’m not in a position to disclose details of this procedure – please contact IBM support. I just wanted to correct the record in that the task is doable.

Older Posts »

Blog at WordPress.com.