cancel
Showing results for 
Search instead for 
Did you mean: 

Dynamic configuration of SOAP action

former_member255627
Participant
0 Kudos

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

Accepted Solutions (1)

Accepted Solutions (1)

engswee
Active Contributor
0 Kudos

Hi Pushpa

Before even considering the feasibility, can you elaborate what is the logic to dynamically determine the SOAP action value?

Rgds

Eng Swee

former_member255627
Participant
0 Kudos

Hi Eng Swee,

Thanks for your quick response.

The input SOAP message has two events 'Create' and 'Close'.

When Create event comes in SOAP message, SOAP action should be  'Create'

when close event comes, then SOAP action should be 'Close'

It is asynchronous SOAP to SOAP scenario.

Regards,

Pushpa

engswee
Active Contributor
0 Kudos

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

former_member255627
Participant
0 Kudos

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

former_member255627
Participant
0 Kudos

Hi,

Could anyone help me on this, I am still not having correct idea on implementing this with dynamic configuration bean module.

Appreciate quick responses.

Thanks,

Pushpa

engswee
Active Contributor
0 Kudos

Hi Pushpa

The modules should be configured like the screenshot below:-

Rgds

Eng Swee

former_member182412
Active Contributor
0 Kudos

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.

engswee
Active Contributor
0 Kudos

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

former_member255627
Participant
0 Kudos

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.

engswee
Active Contributor
0 Kudos

Pushpa

By Create or Close message, do you mean the root XML tag?

<Create>

.... other XML content

</Create>

<Close>

.... other XML content

</Close>

Don't follow my screenshots yet because unless I understand the requirement correctly, they might not be valid.

Rgds

Eng Swee

former_member255627
Participant
0 Kudos

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

engswee
Active Contributor
0 Kudos

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

former_member182412
Active Contributor
0 Kudos

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.

engswee
Active Contributor
0 Kudos

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

former_member255627
Participant
0 Kudos

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

engswee
Active Contributor
0 Kudos

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

Answers (0)