cancel
Showing results for 
Search instead for 
Did you mean: 

Create Adapter module for picking file from Unix server

former_member190358
Participant
0 Kudos

Hello SAP Gurus,

I have a file-to-file scenario .

The source file is provided in Unix server where once it gets written , the file is not getting renamed or deleted.

One more twist is that this file with content has a check if there is a similar file with  ".OK" extension(which is empty).

Lets take an example :

Directory : /usr/interface/test has two files :

ABC.ok is without content

ABC is with content.

"ABC. ok" gets populated by ABAP program, in the end when the entire file is written , so that we do not have the possibility of picking the file in the middle.

Now  i have to write a Adapter module to check following things :

1)  if  " ABC.OK " exists then pick up the actual file with content

2) Delete the "ABC.OK"  file

3) Move the actual file to archive folder for future reference.

Could you please help in this .

Regards,

Ravi

View Entire Topic
former_member184681
Active Contributor
0 Kudos

Hi Ravi,

I have described working with trigger files in PI in one of my Wikis below, have a look and let me know if you still have some questions:

http://wiki.sdn.sap.com/wiki/display/XI/Sender+File+Adapter+Frequently+Asked+Questions

Regards,

Greg

former_member190358
Participant
0 Kudos

Hello Grzegorz,

Thanks a lot for your helpful blog.

The Fourth question in your blog gives me an approach for my solution. But i have two question :

1) Will this work for filenames like  " ABC_* " . Bcoz i have 5 files during the day coming from Application server and they all have to be treated in the same way.

2) At the end, i would like to delete both the files from the source directory .

" ABC_* " and " ABC_*.OK "  as well.

I can set the deletion of " ABC_* " file by setting the communication channel setting .

But how about deletion of " ABC_*.OK " file.?

Your quick response is very much appreciated.

Regards,

Ravi

former_member184681
Active Contributor
0 Kudos

Dear Ravi,

For this purpose, use the following configuration (assuming your original file's extension is .xml, if not, change accordingly):

For file deletion, simply set Processing Mode = Delete in the Processing tab page. The additional file should be deleted together with the main file automatically by PI.

Regards,

Greg

former_member190358
Participant
0 Kudos

Hello Greg,

Since i do not have connection between R/3  application server and XI server , so could you please let me know if there is any way to work with FTP and not NFS protocol.

Regards,

Ravi

former_member184681
Active Contributor
0 Kudos

Dear Ravi,

For FTP, it gets more complicated, since you cannot use the option mentioned. Instead, you can:

1. Develop a custom adapter module that will check if the trigger file exists.

2. Use the Lookup API to check the trigger file during mapping in a UDF, and throw Smart Exceptions in case it isn't there.

Regards,

Greg

former_member190358
Participant
0 Kudos

Hello Greg ,

I have actually tried and written a code.

The scenario is that it checks for "ABC.OK" file in the directory . If it finds then it executes the code.

But the problem is that the actual file ABC ( with content ) is not getting deleted from this code.

Also  pls note that i am using fclient because, while testing we got the FTP timeout error. so we are connecting with the FTP client via code.

But unfortunately, this fclient is not having a class for deletion of file and so my entire effort has gone for a toss.

/**

*

*/

package com.sap.module;

import java.io.BufferedReader;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.io.OutputStream;

import java.rmi.RemoteException;

import java.text.SimpleDateFormat;

import java.util.Calendar;

import javax.ejb.EJBException;

import javax.ejb.SessionBean;

import javax.ejb.SessionContext;

import javax.ejb.TimedObject;

import javax.ejb.Timer;

import sun.net.ftp.FtpClient;

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.Payload;

import com.sap.engine.interfaces.messaging.api.PublicAPIAccessFactory;

import com.sap.engine.interfaces.messaging.api.auditlog.AuditAccess;

import com.sap.engine.interfaces.messaging.api.auditlog.AuditLogStatus;

public class GetMaterialInformationBean implements SessionBean, TimedObject {

   

    public ModuleData process(ModuleContext moduleContext, ModuleData inputModuleData)

    throws ModuleException  {

        try{

            AuditAccess audit = null;

            MessageKey key = null;

            Object obj = null;                

            Message msg = null;

            String host = null;

            String uname = null;

            String pwd = null;

            String archiveDir = null;

            int read;

            Calendar currentDate = Calendar.getInstance();

            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");

            String dateNow = formatter.format(currentDate.getTime());

            obj = inputModuleData.getPrincipalData();

            msg = (Message) obj;

            //Values to be maintained as channel parameters

            host = moduleContext.getContextData("host");

            uname = moduleContext.getContextData("uname");

            pwd = moduleContext.getContextData("password");

            archiveDir = moduleContext.getContextData("archiveDir");

            if (host == null) {

                throw new ModuleException(

                        "Error in module: Module Parameter \"host\" not specified");

            }

            if (uname == null) {

                throw new ModuleException(

                        "Error in module: Module Parameter \"uname\" not specified");

            }

            if (pwd == null) {

                throw new ModuleException(

                        "Error in module: Module Parameter \"password\" not specified");

            }

            if (archiveDir == null) {

                throw new ModuleException(

                        "Error in module: Module Parameter \"archiveDir\" not specified");

            }

            Payload p = msg.getMainPayload();

            try {

                key = new MessageKey(msg.getMessageId(), msg.getMessageDirection());

                audit = PublicAPIAccessFactory.getPublicAPIAccess()

                        .getAuditAccess();

            } catch (Exception e) {

                ModuleException me = new ModuleException(e);

                throw me;

            }

            audit.addAuditLogEntry(key, AuditLogStatus.SUCCESS,"enteredModule");

            String okfileName = msg.getMessageProperty("http://sap.com/xi/XI/System/File","FileName");

            String dirName = msg.getMessageProperty("http://sap.com/xi/XI/System/File","Directory");

            int index = okfileName.indexOf(".");

            String fileName = okfileName.substring(0,index);

            String arcFileName = fileName + dateNow;

            msg.setMessageProperty("http://sap.com/xi/XI/System/File","FileName",fileName);

            //audit.addAuditLogEntry(key, AuditLogStatus.SUCCESS,"mainfileName" + fileName);

            String fileLocation = dirName+ "/" + fileName;

            String archiveLocation = archiveDir+"/" +arcFileName;

            audit.addAuditLogEntry(key, AuditLogStatus.SUCCESS,"mainfileLocation=" + fileLocation);           

            FtpClient fClient = new FtpClient();

            fClient.openServer(host);

            fClient.login(uname,pwd);

            audit.addAuditLogEntry(key, AuditLogStatus.SUCCESS,"connection established");

            fClient.ascii();

           

                       

            /*For picking file from Server

             File f1 = new File(fileLocation);           

            boolean success = f1.exists();

            audit.addAuditLogEntry(key, AuditLogStatus.SUCCESS,"success=" + success );

            if( !success ){

                throw new Exception("File is not available");               

            }      

            byte[] buffer = new byte[(int)f1.length()];

            FileInputStream f = new FileInputStream(fileLocation);

            f.read(buffer);                  

            p.setContent(buffer);

            msg.setMainPayload(p);

            inputModuleData.setPrincipalData(msg);   */

           

           

            //Read data from the file  FtpClient way

             InputStream in = fClient.get(fileLocation);

            //long length = in.available();

            

             BufferedReader BR = new BufferedReader(new InputStreamReader(in));

             StringBuilder SB = new StringBuilder();

             String line1 = null;

             while ((line1 = BR.readLine()) != null) {

             SB.append(line1 + "\n");

             }

             BR.close();

             String data = SB.toString();               

            byte[] buffer = data.getBytes();

            //in.read(buffer);

            p.setContent(buffer);

            msg.setMainPayload(p);

            inputModuleData.setPrincipalData(msg);

           

            //Write file to archive directory and delete file           

            OutputStream out = fClient.put(archiveLocation);

            audit.addAuditLogEntry(key, AuditLogStatus.SUCCESS,"archivefileLocation=" + archiveLocation);

            out.write(buffer);   

            audit.addAuditLogEntry(key, AuditLogStatus.SUCCESS,"" +

                    "written to archive file");

            //boolean resp = fClient.deleteFile(fileLocation);

            //audit.addAuditLogEntry(key, AuditLogStatus.SUCCESS,"File deleted, response" + resp);

           

                   

           

            //last steps

            out.close();

            audit.addAuditLogEntry(key, AuditLogStatus.SUCCESS,"out is closed");

            fClient.closeServer();

            audit.addAuditLogEntry(key, AuditLogStatus.SUCCESS,"server connection is closed");

            return inputModuleData;

           

            fClient.

           

        }catch(Exception ex)

        {

            ModuleException me = new ModuleException(ex);

            throw me;    

        }

    }

former_member184681
Active Contributor
0 Kudos

How about using this code to delete the file?

http://www.kodejava.org/examples/358.html

It looks reasonable

Regards,

Greg

former_member190358
Participant
0 Kudos

Hello Greg,

I am using classes from SUN and that code is  using APACHE

import sun.net.ftp.FtpClient;

against

import org.apache.commons.net.ftp.FTPClient;

Regards,
Ravi

former_member184681
Active Contributor
0 Kudos

Well, right, I didn't notice that. However, this example with your particular class looks promising: http://www.nsftools.com/tips/SunFtpWrapper.java. Using this issueCommand("DELE " + fileName) method, you should be able to delete the file.

Regards,

Greg

former_member190358
Participant
0 Kudos

I tried using the wrapper as well.

But when i used it last time, it gave me error in reading the file. I think i did something wrong.

Can you please guide me in using this DELETE code of wrapper in correct way .

Regards,

Ravi

former_member184681
Active Contributor
0 Kudos

Dear Ravi,

Actually I am not an expert with this class, nor a Java genie, just sharing some ideas that seem promising. How about simply calling:

fClient.issueCommand("DELE " + fileName);

Did you try this?

Regards,

Greg

former_member190358
Participant
0 Kudos

Hi Greg,

its giving me the following error .........And idea !!