Introduction

Recently one of the requirement is to pick up the file based on current date, the monthly files are placed in respective year folder in the sender FTP server like below. Monthly files for 2015:

/wp-content/uploads/2016/05/2015_956638.png

Monthly files for year 2016:

/wp-content/uploads/2016/05/2016_956696.png

So we need to pick up the file from folder 2016 which is current year and need to pick up May.txt which is current month. You can find the discussion here SAP PI 7.31 – Dynamic Sender File Pickup based … | SCN


Sender file adapter does not support dynamic file name and dynamic directory only it supports in the receiver side. So the approach is to use enhanced receiver determination using java mapping, with in the java mapping if the file name and folder are in current month and year then set the receiver otherwise don’t set the receiver then all other files will be ignored by PI without creating the message. this is one of the way to do this requirement without any further custom developments. This is the reference document to consider this option in future for this kind of similar requirements.


Design

The file is not a XML file, it will be binary file so i am using below data type for both sender and receiver, we can use any data type because i am using java mapping for this scenario because we cannot use message mapping.

/wp-content/uploads/2016/05/sender_data_type_956697.png

I am using below message type for both sender and receiver and service interfaces.

/wp-content/uploads/2016/05/messagetype_956698.png

I am using interface pattern Stateless (XI30-Compatible) because we picking up binary file and if we use other interface pattern at run time system will try to read the root node of the message and we will get an error because our file is not an XML.

/wp-content/uploads/2016/05/serviceinterface_956699.png

I am using below operation mapping for dynamic receiver in ICO. Sender service interface which we created above and receiver interface is standrad ReceiverDetermination from SAP BASIS software component.

/wp-content/uploads/2016/05/operationmapping_956700.png

Java mapping is to read the sender file name and directory using dynamic configuration and compare with current date and current month, if both are equal then i am setting the receiver otherwise i am not setting the receiver, so only for current month file will have the receiver all other files will be ignored because of no receiver.


import com.sap.aii.mapping.api.AbstractTrace;
import com.sap.aii.mapping.api.AbstractTransformation;
import com.sap.aii.mapping.api.DynamicConfiguration;
import com.sap.aii.mapping.api.DynamicConfigurationKey;
import com.sap.aii.mapping.api.OutputPayload;
import com.sap.aii.mapping.api.StreamTransformationException;
import com.sap.aii.mapping.api.TransformationInput;
import com.sap.aii.mapping.api.TransformationOutput;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class FileNameFilterJavaMap
  extends AbstractTransformation
{
  public void transform(TransformationInput transformationInput, TransformationOutput transformationOutput)
    throws StreamTransformationException
  {
    try
    {
      DynamicConfiguration conf = transformationInput.getDynamicConfiguration();
      String fileName = conf.get(DynamicConfigurationKey.create("http://sap.com/xi/XI/System/File", "FileName"));
      String dir = conf.get(DynamicConfigurationKey.create("http://sap.com/xi/XI/System/File", "Directory"));
      Date date = new Date();
      String month = new SimpleDateFormat("MMM").format(date);
      String year = new SimpleDateFormat("yyyy").format(date);
      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
      factory.setIgnoringElementContentWhitespace(true);
      DocumentBuilder builder = factory.newDocumentBuilder();
      Document outputDoc = builder.newDocument();
      Element receivers = outputDoc.createElement("Receivers");
      receivers.setAttribute("ns0", "http://sap.com/xi/XI/System");
      outputDoc.appendChild(receivers);
      Element receiver = outputDoc.createElement("Receiver");
      receivers.appendChild(receiver);
      Element service = outputDoc.createElement("Service");
      if ((fileName.startsWith(month)) && (dir.endsWith(year))) {
        service.setTextContent("BC_RECEIVER");
      }
      receiver.appendChild(service);
      Transformer transformer = TransformerFactory.newInstance().newTransformer();
      transformer.setOutputProperty("indent", "yes");
      transformer.transform(new DOMSource(outputDoc), new StreamResult(transformationOutput.getOutputPayload()
        .getOutputStream()));
    }
    catch (Exception e)
    {
      getTrace().addDebugMessage(e.getMessage());
      throw new StreamTransformationException(e.getMessage());
    }
  }
}



Configuration

I have created below IFlow using dynamic receiver with above created java mapping.

DynamicFileICO.png

Select the operation mapping which we created above in Dynamic Routing section in IFlow properties.

dynamic routing.png

Configure the routing behavior like below routing technique as Dynamic Message Router and if the receiver not found Ignore this error option.

routing behavior.png

Mention multiple folders in the sender channel using additional source file selection option like below.

/wp-content/uploads/2016/05/senderchannel_956717.png

We are not going to delete the files in the source directory so mention the processing mode as Test

processing mode.png

Enable File Name and Directory in the sender channel under Adapter-Specific Message Properties

ASMA1.png

Mention the receiver directory and file name as * or %FileName% because it will be ignored by the adapter as we are using dynamic configuration.

/wp-content/uploads/2016/05/receiver_channel_956719.png

Enable File Name attribute in Adapter-Specific Message Properties of receiver channel.

/wp-content/uploads/2016/05/rece_asma_956720.png

We can schedule the sender channel to run every month to pick up the respective file from respective folder.

Testing

When we run the scenario the adapter will read all the files and ignore the files which is not current moth and year because of no receiver could be determined, we can see in the channel logs like below.

/wp-content/uploads/2016/05/ignore_956721.png

It only create the message for current month and current year which is May.txt from 2016 folder, as you can see in the audit log only May.txt file only sent to the receiver directory.

/wp-content/uploads/2016/05/auditlog1_956722.png

We can find the current month file in target directory.

/wp-content/uploads/2016/05/receiverfile_956738.png

Conclusion

By using enhanced receiver determination in ICO we can ignore all other unrelated files and only pick up the the file based on current date. it will be useful for who ever get this kind of similar requirement in future.

To report this post you need to login first.

10 Comments

You must be Logged on to comment or reply to a post.

  1. Manoj K

    Praveen,

    Great blog,  but by mentioning processing mode as test the same file may get processed again?  For this I guess we need to enable duplicate check at channel level.

    (0) 
    1. Praveen Gandepalli Post author

      Hi Manoj,

      I already mentioned in the blog we need to schedule the sender channel monthly so that the channel pick up the different file every month, it wont be duplicates

      We can schedule the sender channel to run every month to pick up the respective file from respective folder.

      Regards,

      Praveen.

      (0) 
  2. Sonal Mangla

    Hi Praveen

    Thanks for sharing the information. It was very informative.

    However, I can see that you have hardcoded the directory paths with the year.

    /home/xi/test/out/2016

    /home/xi/test/out/2015.

     

    I was wondering if we can do something like /home/xi/test/out/* in order to cater to the all the directories generated for all the future years too.

    I tried using * as wild card but it doesn’t work. Any thoughts?

     

    Regards

    Sonal

    (0) 

Leave a Reply