Wednesday, November 5, 2008

Accessing Axis2 Information at Client and Service

Most of the people get used to implement web services either using POJO or generated services with wsdl using wsdl2java tool. The preferred way to generate the client code is again to use wsdl2java tool with service wsdl. In other words people preferred to use data bound java classes.
But sometimes they need to get inside information even at the Client and service level. Axis2 internally keep XML data as an Axiom object. It uses the context hierarchy in processing data. For each message Axis2 creates a message context which is bound to an Operation Context. Normally an Operation Context can have one or two message contexts depending on the Operation MEP (message exchange pattern). Therefore if there is a way to get access to Message Context or Operation Context all these details can be retrieved by using them.

At server side.
At the server side message context can be accessed like this,
MessageContext messageContext = MessageContext.getCurrentMessageContext();

once get the message context then any thing can be access from that
messageContext.getEnvelope(); // getting soap envelop
messageContext.getProperties(); // getting all the properties these inclued properties set by transports as well
messageContext.getOperationContext(); // accessing operation context
messageContext.getAxisOperation(); // axis operation information
messageContext.getAxisService(); // axis servier information

At the client side.
At the client side operation context can be accessed like this,
OperationContext operationContext = stub._getServiceClient().getLastOperationContext();
MessageContext outMessageContext = operationContext.getMessageContext(WSDL2Constants.MESSAGE_LABEL_OUT);
MessageContext inMessageContext = operationContext.getMessageContext(WSDL2Constants.MESSAGE_LABEL_IN);

Once got the message context other can be accessed as given above.

11 comments:

Anonymous said...

Amila, using configContext.createMessageContext() on the server side we can obtain the properties you described but I cannot figure it out how a client can get access to the server's messageContext and obtain information as the TimeoutInterval.

Amila Suriarachchi said...

What do you mean by "client can get access to the server's messageContext and obtain information as the TimeoutInterval."

Anonymous said...

In other words: I want to get some properties of the server using a client. I mean there is any way to obtain such properties using the API? Thank you for your time.

Amila Suriarachchi said...

no. I think this is not something you have to try with web services. web services are used to communicate using standard protocols. The only thing client access is the response as describes in the wsdl.
In other words you should not try to write server dependent clients.

Ravi said...

Hi Amila,

what does getLastOperationContext return?

I have a code which intercepts OperationClient.execute() using aspectworkz and I have the instance of OperationClient in my hand. What and all information can I get from OperationClient? Looks like MessageContext obtained from OperationClient does not have any information other than envelop. "Options" object obtained from OperationClient has toEndPoint value and operation value.
Can we get any other information apart from SOAP envelop, operation and toEndPoint on client side? Is Operation name mandatory option at client side?

Jaime Hablutzel said...

Thanks I needed that to save signed SOAP envelopes for audit

Das said...

Hi Amila,

I am trying to add username and password in HTTP header when the axis client is issuing the first request. To use the addHttpHeader() method I need to obtain the MessageContext. I tried your approach, but it doesn't seem to work when I am making the first request. I am using Axis2-1.6.1. Also in the client stub code generated the addHttpHeader() is losing it's visibility in the client-side code which instantiates the client.Stub, I overrode it in the client-side [public void addHttpHeader(MessageContext messageContext, String name, String value){
super.addHttpHeader(messageContext, name, value);
}] to get access to it. Is there a more elegant way to do this?

Rudy said...

Hi Amila,
I am trying to set the AttachmentMap of the MessageContext. the AttachmentMap contains String fileName as key and DataHandler as value. The problem is that the key (fileName) is always replaced by an auto-generated content-id like "1.eda40b06e35c37a7bf9113ecce78e76737d29599c9edd652@apache.org"!
Have you any idea why?
I appreciate your help.
Rudy.

this is what I am doing:
public DataHandler[] downloadAppsLogs()
{
Collection logsFilesDataHandler = new ArrayList();
Attachments logsFilesAttachments = new Attachments();
File[] logsFiles = getLogsFiles();
for (File file : logsFiles)
{
if (file != null)
{
FileDataSource fileDataSource = new FileDataSource(file);
DataHandler fileDataHandler = new DataHandler(fileDataSource);
logsFilesDataHandler.add(fileDataHandler);
logsFilesAttachments.addDataHandler(file.getName(), fileDataHandler);
}
}
try
{
MessageContext.getCurrentMessageContext().
getOperationContext().
getMessageContext(WSDLConstants.MESSAGE_LABEL_OUT_VALUE).
setAttachmentMap(logsFilesAttachments);
}
catch(AxisFault e)
{
throw new DownloadFailedException(e);
}
return logsFilesDataHandler.toArray(new DataHandler[logsFilesDataHandler.size()]);
}

Anonymous said...

Das,
Were you able to resolve your issue? I am running into a similar problem where I'm acting as a client and need to get access to the SOAPEnvelope to then sign it.

I run Amila's code:

OperationContext operationContext = stub._getServiceClient().getLastOperationContext();

But the problem is that it returns NULL. Probably because I haven't ran any operations yet (i.e. haven't sent SOAP request yet).

Any help would be appreciated.

--ross

Unknown said...

I am getting the same problem as Ross.

Amila/Ross, Have you been able to resolve this problem? Please let me know what solution have you used to resolve this.

Thanks,
Siddu

Unknown said...

MessageContext context = MessageContext.getCurrentMessageContext();

context is null because I have not run any operations on the webservice yet.

Please suggest.

Thanks,
Siddu