Skip to main content

A real bug in all Resource Adaptors???

11 replies [Last post]
eduardomartins
Offline
Joined: 2005-10-10

Replying to a forum topic i just spotted this code in the Sip RA ACI Factory getActivityContextInterface(ClientTransaction clientTransaction) method:

return new ActivityContextInterfaceImpl(this.serviceContainer,
this.activityContextFactory.getActivityContext(new SleeActivityHandle(raEntityName, new SipActivityHandle(clientTransaction.getBranchId()), serviceContainer)).getActivityContextId());
}

I think it should be

return new ActivityContextInterfaceImpl(this.serviceContainer,
this.activityContextFactory.getActivityContext((new SleeActivityHandle(raEntityName, new SipActivityHandle(clientTransaction.getBranchId()), serviceContainer)).getActivity()).getActivityContextId());
}

Because when you look for an AC you use an Activity. The way it is right now you can be sure that posting an event in a ClientTransaction doesn't fire the event in the same ACI that you will get using the RA Factory for that ClientTransaction.

The same for the ServerTransaction.
The same for all others RAs, which I think all have aci factories based on that sip ra aci factory code.

Regards,

Eduardo Martins
PT Inovação

PS: Sorry, no time for a tck test.

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
fram
Offline
Joined: 2004-05-13

Eduardo,
sorry for the late reply to your post, the SleeActivityHandle is the object mapped to the AC in the ActivityContextFactory.
The SleeActivityHandle wraps the ActivityHandle created by the resource adaptor. The equals and hashCode methods are proxy to the ActivityHandle methods of the resource adaptor object.
Francesco

ivelin
Offline
Joined: 2003-07-13

I am having hard time understadning your claim. Can you elaborate some more and break down the code changes?

eduardomartins
Offline
Joined: 2005-10-10

JAIN SLEE 1.0 Specs:

"
15.3 Accessing Activity Context Interface Factories from within an SBB
An SBB can explicitly lookup an object that implements the Activity Context Interface Factory interface of
a resource adaptor type in its JNDI component environment. It can use this object to obtain Activity Context
Interface objects from the Activity objects created by resource adaptor entities of the resource adaptor
type. This requires a resource-adaptor-type-binding element in the SBB’s deployment descriptor
to bind an Activity Context Interface Factory object into the JNDI component environment of the SBB.
"

The SIP RA ACI Factory (implemented by class SipActivityContextInterfaceFactoryImpl) has 2 methods to get ACIs:

1) public ActivityContextInterface getActivityContextInterface(ClientTransaction clientTransaction) throws NullPointerException,UnrecognizedActivityException, FactoryException;

and

2) public ActivityContextInterface getActivityContextInterface(ServerTransaction serverTransaction) throws NullPointerException,UnrecognizedActivityException, FactoryException;

This is because the SIP Activity can be a ClientTransaction or ServerTransaction.

Lets check the implementation of method 1), a little simplified as you asked:

{
if (clientTransaction == null)
throw new NullPointerException("sip activity ! huh!!");

//1
SipActivityHandle sipActivityHandle = new SipActivityHandle(clientTransaction.getBranchId());

//2
SleeActivityHandle sleeActivityHandle = new SleeActivityHandle(raEntityName,sipActivityHandle, serviceContainer);

//3
ActivityContext ac = this.activityContextFactory.getActivityContext(sleeActivityHandle);

return new ActivityContextInterfaceImpl(this.serviceContainer,ac.getActivityContextId());
}

The problem is in //3, since this.activityContextFactory is the SLEE's ACI factory and ActivityContext objects are mapped to Activity objects, not SleeActivityHandles. That code line should be:

ActivityContext ac = this.activityContextFactory.getActivityContext(sleeActivityHandle.getActivity());

A simple test can be done to prove this is happening in SIP RA, just try this code in a INVITE event handler:

ServerTransaction serverTransaction = (ServerTransaction) aci.getActivity();
try {
ActivityContextInterface aci2 = acif.getActivityContextInterface(serverTransaction);
if (!aci.equals(aci2))
logger.info("This shouldn't happen.");
} catch (Exception e) {
e.printStackTrace();
}

This problem is not exclusive to the SIP RA, others have the same error, probably because the SIP RA code was the base for its development.

Eduardo Martins
PT Inovação

eduardomartins
Offline
Joined: 2005-10-10

"The problem is in //3, since this.activityContextFactory is the SLEE's ACI factory and ActivityContext objects are mapped to Activity objects, not SleeActivityHandles."

It turns out i've been cheated by an Object variable named activity in the EventRouter (which is a SleeActivityHandle) because after a deep trace it turns out that SleeActivityHandles are, after all, used to map ACs.

Eduardo Martins
PT Inovação

ivelin
Offline
Joined: 2003-07-13

thanks for the deep debug. how would you rename this variable?

eduardomartins
Offline
Joined: 2005-10-10

Lets rollback from that Object variable named activity in EventRouterImpl's method routeTheEvent(EventPosting ep):

1) The value of that variable is retreived from the EventPosting object passed as the method parameter.

2) The method is invoked only by EventExecutor objects in it's run() method. The EventExecutor object is a runnable object to be executed by the concurrent qued executor engine which is the core of the event router.

3) EventExecutor objects are created in routeEvent(EventTypeID eventTypeId, Object event, Object activity, Address address) method of EventRouterImpl
and this method is invoked by:

3.1) method postEvent(ComponentKey eventKey, Object event, ActivityContextInterface aci, Address address) in class SLEEContainer - The comments say it's to be used in fire event methods but it's never used, I don't think this method would work well since it sends the aci where the event was fired as the activity so in the end we would have an EventPosting with an aci as the activity

3.2) method enqueueEvent(EventTypeID eventTypeId, Object event, Object activity, Address address) in class SleeEndpointImpl - this methods just send the values received as parameters. The SleeEndpointImpl is the implementation for RA's SleeEndpoint. To send a new event to SLEE an RA invokes the SleeEndpoint's method named fireEvent(ActivityHandle handle, Object event, int eventType, Address address) and this method adds a transaction action that will later (there is DeferredEvent proxy that we will ignore) enqueue the event. It's in this fireEvent method that a SleeActivityHandle is sent as the activity parameter of the enqueueEvent.

3.3) method enqueueEvent(EventTypeID eventTypeId, Object event, Object activity, Address address) in class SleeInternalEndpointImpl - this methods just send the values received as parameters. The SleeInternalEndpointImpl is the implementation for SLEE's endpoint used by the TimerFacility and SleeRemoteService to send events. Both send activities and not slee activity handles as in 3.2

So, resuming, we have 3 mechanisms to enqueue an Event and each send diferent things as the activity parameter so I don't know if the variable is to named something else or a better analisys has to be made and normalize it's use.

Regards,

Eduardo Martins
PT Inovação

baranowb
Offline
Joined: 2006-01-09

So if I got it right, param of getActivityContextInterface method should be "activity" but "sleeHandle" ??
I got slightly confused.

fram
Offline
Joined: 2004-05-13

If I've understood correctly Eduardo, there is no problem with the mapping, the ActivityContextFActory maps between SleeActvityHandle and ActvityContext and this is correct. The issue that Eduardo is raising is about the confusion inside the code and an etherogenous way of handling event posting to the container.
We need to clean up the code after analyze the implication of providing an homogenous event posting mechanism inside the implementation.
Part of the confusion is due to bad variable naming like using "activty" as the name of the parameter instead of sleeActivityHandle.
Francesco

eduardomartins
Offline
Joined: 2005-10-10

You're right Francesco. Part of this problem is that JAIN SLEE 1.0 specs does not define the API between SLEE and the RA. In section 15.9 it "drafts" what must be provided from both parts but nothing more. One thing the specs say is that we have a 1:1 relation between Activity and ActivityContext. We may wonder why there is the SleeActivityHandle, since this information is part of the ActivityContext. I think a better approach would be to have two types of ActivityContext implementations, one for internal activities (null activities, profile activities and service activities) and another for external and this one would include the type of info on the SLEEActivityHandle.

Eduardo Martins
PT Inovação

fram
Offline
Joined: 2004-05-13

The SleeActivityHandle is used by the mobicents implementation because the activity object is not passed with the event when an event is fired by the resource adaptor. The activity object is retrieved by the container only when an SBB need to access the activity object. The SleeActivityHandle contains the reference to the resource adaptor responsible for the activity object.
So now we have a 1:1 mapping between activity and SleeActivityHandle and a 1:1 mapping between SleeActvityHandle and ActivityContext.

Francesco

eduardomartins
Offline
Joined: 2005-10-10

What I am questing is the need for that handle, why not send the activity.

Eduardo Martins
PT Inovação