cancel
Showing results for 
Search instead for 
Did you mean: 

Multiple Payloads Mapping possible? Just the first Payload is mapped.

Former Member
0 Kudos

Hi,

is it possible to map multiple Payloads in one XI Message?

My Source File is a zip (xml files) I unziped it in Sender CC

I have message structure as this in my integration server

XI Message

- payload 1

- payload 2

- payload 3

- ....

The payload reflects the message type in Design.

I want to send to ABAP Proxy and use every payload for storing data.

I use a Interface Mapping - 1 to 0..unbounded and also advance interface determination with Interface Mapping.

But just the first payload is getting mapped.

So, is it possible in general to get multi payloads mapped without BPM?

We will have 10.000 xml per zip, so BPM is not an option, because of performance.

Thanks and best regards

Silvio

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Kudos

hi, all payloads are the same message type

former_member181985
Active Contributor
0 Kudos

Hi,

Then you require a java mapping.

First of all, Dont use PayloadZip bean to unzip at file channel.

Do a java mapping, which can read the zip stream and can unzip for each entry. since you said all the files in the zip will have same message structure you need to take care while forming a message since if you keep on appending each unzipped entry it will be slightly deviate from the actual intended structure.

E.g.,

suppose the zip file contains say 10 files(payloads),

First read the first zip entry and write the unzipped stream to output stream. Remember, since you already know the structure of a message dont write the end tag of the message for the first time.(use some java logic)

for the remaining next 2nd to 9 th zip entries or fies read the unzipped stream and omit the beginning and ending tags while writing it to outputstream. (use some java logic)

for the last entry i.e., 10 th file read the unzipped stream omit the first tag and simply write the reamining stream to output stream.(use some java logic)

Now you have a single message structure and now in interface mapping use one more mapping say a graphical message mapping which does the next job of mapping this structure to Proxy structure.

snippet java mapping code which can does unzipping:

import com.sap.aii.mapping.api.StreamTransformation;
import com.sap.aii.mapping.api.*;

import java.io.*;
import java.util.*;
import java.util.zip.*;
import java.util.Map;

public class UnZipPayloadJavaMapping implements StreamTransformation
{
	static final int BUFFER = 1024*1000;
    private Map param;


    public UnZipPayloadJavaMapping(){  }

	public void setParameter (Map map) 
	{
		param = map;
		if (param == null) 
		{
			param = new HashMap();
		}
	}

	public static void main(String args[])
	{
		try
		{
			FileInputStream fin = new FileInputStream(args[0]);
			FileOutputStream fout = new FileOutputStream(args[1]);
			UnZipPayloadJavaMapping mapping = new UnZipPayloadJavaMapping();
			mapping.execute(fin, fout);
		}
		catch (Exception e)
			{
				e.printStackTrace();
			}
	}
    public void execute(InputStream inputstream, OutputStream outputstream)
    {

			int len = 0;
			byte buf[] = new byte[BUFFER]; 	
			
			try
			{
				ZipInputStream zis = new ZipInputStream(inputstream);
				ZipEntry objZipEntry = null;

				while((objZipEntry = zis.getNextEntry()) != null)	
				{
					while ((len = zis.read(buf, 0, BUFFER)) > 0)	//IMP: write the your logic for implementing removing tags etc as explained above,				
						outputstream.write(buf, 0, len);					
				}

			}
			catch(Exception e){ e.printStackTrace();}
    }

}

Also consider the following factors before implementing the above. since in your requirement a zip file on sender side might contain 10, 000 files and each file might be in the order of mega bytes I guess, then obviously you cannot unzip all entries as it might lead memory problems and JAVA stack becomes down.

So choose an optimum size which can suit your XI box.

Thanks,

- Gujjeti.

Answers (5)

Answers (5)

rkuip
Discoverer
0 Kudos

What worked for me (PI 7.3, merging messages from a zip archive). 

package javaMapping;


import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.*;
import java.util.Date;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.sap.aii.mapping.api.AbstractTrace;
import com.sap.aii.mapping.api.MappingTrace;

import com.sap.aii.mapping.api.StreamTransformationConstants;
import com.sap.aii.mapping.api.StreamTransformationException;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
//1. AbstractTransformation class is imported.
// The associated jar file is: com.sap.xpi.ib.mapping.lib.jar
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.StreamTransformationException;
import com.sap.aii.mapping.api.TransformationInput;
import com.sap.aii.mapping.api.TransformationOutput;
import com.sap.aii.mapping.api.InputHeader;

public class transform extends AbstractTransformation {

static int BUFFER = 1024*1000;

    public void transform(TransformationInput arg0, TransformationOutput arg1) throws StreamTransformationException {

    
    int len = 0, ptr = 0, startOfSegment = 0, endOfSegment = 0;
    byte buf[] = new byte[BUFFER];
    String inData = "";
    String openRow = "<row><text>";
    String closeRow = "</text></row>";
    String xmlDefinition = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
    String openMessage =  "<ns1:mt_mt940_in xmlns:ns1=\"urn:sap.thg.com:ecc:r2r\">";
    String closeMessage = "</ns1:mt_mt940_in>";
   
    // getTrace().addInfo("JAVA Mapping Called");

    // String inData = convertStreamToString(arg0.getInputPayload().getInputStream());

    ZipInputStream zis = new ZipInputStream(arg0.getInputPayload().getInputStream());
   
    ZipEntry objZipEntry = null;
   
    try
    {
    
       arg1.getOutputPayload().getOutputStream().write(xmlDefinition.getBytes("UTF-8"));
       arg1.getOutputPayload().getOutputStream().write(openMessage.getBytes("UTF-8"));
       
     while((objZipEntry = zis.getNextEntry()) != null)    
     {
      // inData = objZipEntry.toString();
     
            // inData = String.format("Entry: %s len %d added %TD",
            //  objZipEntry.getName(), objZipEntry.getSize(),new Date(objZipEntry.getTime()));
           
     
             while ((len = zis.read(buf, 0, BUFFER)) > 0)     //IMP: write the your logic for implementing removing tags etc as explained above,                   
            {
            
             //inData = String.format("Entry: %s len %d added %d",
                //   objZipEntry.getName(), objZipEntry.getSize(), len);
            
             inData = "<file><name>" + objZipEntry.getName() + "</name>";               
             arg1.getOutputPayload().getOutputStream().write(inData.getBytes("UTF-8"));
            
                ptr = 0;
                while (ptr < (len - 2) )
                {                
                 arg1.getOutputPayload().getOutputStream().write(openRow.getBytes("UTF-8"));
                 startOfSegment = ptr;
                   
                 //inData = String.format("@Start Pointer: %d Length: %d", ptr, len);
                    //arg1.getOutputPayload().getOutputStream().write(inData.getBytes("UTF-8"));
                
                 while ( buf[ptr] != 13 ) { ptr = ptr + 1; };
                
                 endOfSegment = ptr;
                 //inData = String.format("@End Start: %d End: %d",startOfSegment, endOfSegment);
                    //arg1.getOutputPayload().getOutputStream().write(inData.getBytes("UTF-8"));
                                 
                    arg1.getOutputPayload().getOutputStream().write(buf, startOfSegment, endOfSegment - startOfSegment);
                   arg1.getOutputPayload().getOutputStream().write(closeRow.getBytes("UTF-8"));
                    ptr = ptr + 2;
                   
                    //inData = String.format("@End Pointer: %d Length: %d", ptr, len);
                    //arg1.getOutputPayload().getOutputStream().write(inData.getBytes("UTF-8"));
                    
                   
                }
                inData = "</file>";               
             arg1.getOutputPayload().getOutputStream().write(inData.getBytes("UTF-8"));
            
            }
     }
     arg1.getOutputPayload().getOutputStream().write(closeMessage.getBytes("UTF-8"));
       
    }
    catch(Exception e){ e.printStackTrace();
    }
    // InputHeader messageHeader = arg0.getInputHeader();
   
    // String messageId = messageHeader.getMessageId()

   
   }
    
    public String convertStreamToString(InputStream in){
    StringBuffer sb = new StringBuffer();
    try
    {
    InputStreamReader isr = new InputStreamReader(in);
    Reader reader =
    new BufferedReader(isr);
    int ch;
    while((ch = in.read()) > -1) {
        sb.append((char)ch);}
        reader.close();
    }
    catch(Exception exception) { }
    return sb.toString();
    }
}



Former Member
0 Kudos

Hi, thanks for the complete answers!

I will have a try with that solution. My files are around 5kb each file, so I think we will have not that serious performance problem.

Thanks and best regards

Silvio

former_member181985
Active Contributor
0 Kudos

>XI Message

>- payload 1

>- payload 2

>- payload 3

Does all the payloads (payload1, payload2 etc..) in the zip message will have the same structure or different.?

Thanks,

- Gujjeti.

Former Member
0 Kudos

Hi,

thanks for fast reply.

I created that scenario already with this settings.

unfortunately the mapping is working for the first payload.

So it seems that the mapping of a multiple payloads is not working without BPM.

Silvio

rodrigoalejandro_pertierr
Active Contributor
0 Kudos

hi,

each message has diferent structure ??

if not,create the DT and assign all the structures. to do this in Message Mapping go to signature tab and import it with ocurrance 0:N. dont forget to assign the same ocurrance in OM.

but you have a problem beacuse doing it when you receiver at least one message the MM is executed, so. i think probablyh you will need a simple BPM to collect all messages.

Thanks

Rodrigo