on 10-06-2015 1:47 AM
Hi All,
I am facing a problem in configuring the SOAP action dynamically where as it is a pass through interface does not require a messae mapping.
As far as I know SOAP action can be configured dynamically by using a udf in message maping.
Could you please share your ideas on configuring SOAP action dynamically without message mapping?
Appreciate your quick response.
Thanks,
Pushpa
Hi Pushpa
Before even considering the feasibility, can you elaborate what is the logic to dynamically determine the SOAP action value?
Rgds
Eng Swee
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Dear Pushpa
From the following online help, the SOAP action is available as ASMA in the sender as SHeaderSOAPACTION and receiver as THeaderSOAPACTION.
Configuring the Sender SOAP Adapter - Advanced Adapter Engine - SAP Library
Configuring the Receiver SOAP Adapter - Advanced Adapter Engine - SAP Library
Therefore, if you want a solution without message mapping, you can use DynamicConfigurationBean in the receiver SOAP channel to transfer the value from SHeaderSOAPACTION to THeaderSOAPACTION. Refer to the following blog for a sample of how you can do it, you just have to change the namespace and attribute name accordingly.
Remember to check ASMA and Transport Binding in both your sender and receiver channels.
Rgds
Eng Swee
Hi Eng Swee,
Could you please elaborate on how to give module bean details to get SOAP action in the receiver SOAP channel?
As per your reply my understanding was
1. Need to check ASMA and Variable Transport binding in Sender SOAP channel
2.Add Dynamic configuration bean module in receiver SOAP channel and also check ASMA and Variable Transport binding as well.
I am not sure what details to give in Processing sequence and module configuration
Should I mention SOAP Action in variable Transport binding attributes in both Sender and Receiver channels??
Awaiting your reply.
Regards,
Pushpa
Hi Pushpa,
The sender soap adapter soap action is like below:
You can use below adapter module to set dynamic soap action.
package com.custom.af.modules;
import javax.ejb.CreateException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import com.sap.aii.af.lib.mp.module.Module;
import com.sap.aii.af.lib.mp.module.ModuleContext;
import com.sap.aii.af.lib.mp.module.ModuleData;
import com.sap.aii.af.lib.mp.module.ModuleException;
import com.sap.engine.interfaces.messaging.api.Message;
import com.sap.engine.interfaces.messaging.api.MessageKey;
import com.sap.engine.interfaces.messaging.api.MessagePropertyKey;
import com.sap.engine.interfaces.messaging.api.PublicAPIAccessFactory;
import com.sap.engine.interfaces.messaging.api.XMLPayload;
import com.sap.engine.interfaces.messaging.api.auditlog.AuditAccess;
import com.sap.engine.interfaces.messaging.api.auditlog.AuditLogStatus;
public class DynamicSOAPActionBean implements SessionBean, Module {
/**
*
*/
private static final long serialVersionUID = 1L;
private SessionContext myContext;
public ModuleData process(ModuleContext moduleContext, ModuleData inputModuleData) throws ModuleException {
String CLASS_NAME = getClass().getSimpleName();
try {
// Get message
Message msg = (Message) inputModuleData.getPrincipalData();
// Create Messagekey
MessageKey key = new MessageKey(msg.getMessageId(), msg.getMessageDirection());
// Get AuditAccess
AuditAccess audit = PublicAPIAccessFactory.getPublicAPIAccess().getAuditAccess();
// Audit log message will appear in MDT of Channel Monitoring
audit.addAuditLogEntry(key, AuditLogStatus.SUCCESS, CLASS_NAME + ": Module Called");
// Read Module Parameters
String soapActionPrefix = moduleContext.getContextData("soapActionPrefix");
if (soapActionPrefix == null) {
throw new ModuleException("Parameter soapActionParameter is missing");
}
audit.addAuditLogEntry(key, AuditLogStatus.SUCCESS, "Read parameter soapActionPrefix: " + soapActionPrefix);
// Get XMLPayload
XMLPayload xmlPayload = msg.getDocument();
if (xmlPayload != null) {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
Document document = factory.newDocumentBuilder().parse(xmlPayload.getInputStream());
String operationName = document.getDocumentElement().getLocalName();
audit.addAuditLogEntry(key, AuditLogStatus.SUCCESS, "OperationName: " + operationName);
String soapAction = soapActionPrefix + operationName;
MessagePropertyKey KEY_SOAPACTION = new MessagePropertyKey("THeaderSOAPACTION",
"http://sap.com/xi/XI/System/SOAP");
msg.setMessageProperty(KEY_SOAPACTION, soapAction);
audit.addAuditLogEntry(key, AuditLogStatus.SUCCESS, "SOAP Action successfully set. soapAction: " + soapAction);
}
} catch (Exception e) {
throw new ModuleException(e.getClass() + ": " + e.getMessage());
}
return inputModuleData;
}
public void ejbRemove() {
}
public void ejbActivate() {
}
public void ejbPassivate() {
}
public void setSessionContext(SessionContext context) {
setMyContext(context);
}
public void setMyContext(SessionContext myContext) {
this.myContext = myContext;
}
public SessionContext getMyContext() {
return myContext;
}
public void ejbCreate() throws CreateException {
}
}
I am getting the soap action from root node of the payload, so if you need to set any prefix to the root node you can use below receiver channel configuration:
Regards,
Praveen.
Pushpa,
Was just wondering why Praveen is providing an custom adapter module to solve your issue when I realized that I might have read your required logic incorrectly.
You mentioned that:
The input SOAP message has two events 'Create' and 'Close'.
I had initially thought that the event meant the input SOAP message's SOAP action. Can you clarify further what you mean by "event"? If it is not the SOAP action, then is it a value in the payload or something else?
Rgds
Eng Swee
Thanks Eng Swee and Praveen
my actual scenario is:
The input SOAP message has either create message or Close message, according to this I have to set SOAP action in the receiver channel that is either 'Create' or 'Close'.
I hope the screenshots provided here may solve my issue. I will try and let you know.
Thanks once again.
Pushpa.
Yes Eng Swee,
input SOAP message is like:( input message is either create event message or Close event message)
<Create event>
.... other XML content
</Create event>
or
<Close event>
.... other XML content
</Close event>
and the SOAP actions are:
soapAction="XYZ/CreateEvent"
soapAction="XYZ/CloseEvent"
Regards,
Pushpa
Hi Pushpa
If that is the case, ignore the solution in the screenshot I provided earlier. It is not achievable using standard modules alone.
You need to either do this using a message mapping with UDF or the custom adapter module provided by Praveen above.
My recommendation would be to go for the mapping with UDF because it is a more supportable solution than having a custom module. No point insisting on not having a message mapping and ending up with a custom module.
Rgds
Eng Swee
Hi Eng,
If we go with adapter module approach then we can reuse the adapter module in other similar interfaces in future, if we go with message mapping approach then we have to do this mapping each and every interface, what do you say
I have similar requirement in my project, previously my client developed 10 individual interfaces between two systems, i have created one service interface with 10 operations and i have provided single WSDL to them, based on the operation which they called i need to setup dynamic soap action in receiver side with one channel.
i have implemented adapter module and i am using this module in almost 20 other interfaces without mapping and dynamic soap action.
Regards,
Praveen.
Praveen,
I definitely agree with you - if there is a potential for reuse of the solution, custom adapter module is definitely the better long term choice. My personal opinion would be developing custom adapter module has to be "worth" the effort, and it has to be done in a generic way to enable high future reuse.
Pushpa,
At the end of the day, the decision to go for whichever solution depends on your project/organization circumstances/needs, i.e. if you foresee that this requirement is just a one-off, do you want to develop a module for it, or do you expect many such interfaces in the future.
If you do the adapter module route, the challenge for you is to take Praveen's coding and make necessary modifications to it (example how to translate the <Create event> root node to a XYZ/CreateEvent action) and yet make sure the logic is robust enough for future reuse with none/minimal changes.
Rgds
Eng Swee
Hi Eng Swee,
Thanks a lot for your help. Though I dont use this kind of functionality in other interfaces I have to go with custom module as there is no option left out for me.
Hi Praveen,
I am new to create custom adapter modules and I need to get approval from client for this.
Could you please tell me what we have to do to create a custom adapter module and how much time it would take to do this.
Thanks,
Pushpa
Hi Pushpa
You can check out the Additional Reference section of my blog below for materials to get you started on custom adapter module development. You will need to develop it in an NWDS version that is compatible with your PI version.
Since you are new to this, there is a bit of a learning curve involved and as such it is hard to say how much time this would take.
Rgds
Eng Swee
User | Count |
---|---|
82 | |
10 | |
10 | |
9 | |
6 | |
6 | |
5 | |
5 | |
4 | |
3 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.