Announcement

Collapse
No announcement yet.

Javascript RAW SFTP Reader

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Javascript RAW SFTP Reader

    Hi guys, this is a channel we have develop to read from a SFTP different kind of files (.txt, .xml, .edi) basically its a raw reader that reads any file and split accordingly, for example, delimited files (txt) are split by row, XML file by segments and EDI by certain segment.

    Please, if you have comment that would help in order to improve the channel would be more appreciate.

    Code:
    importPackage(com.jcraft.jsch);
    importPackage(java.io);
    importPackage(java.lang);
    importPackage(java.nio.charset);
    
    var messages = new java.util.ArrayList();
    
    try {
        machineName = Packages.java.net.InetAddress.getLocalHost().getHostName();
        //logger.info('machineName:  ' + machineName);
    } catch (e) {
        logger.error('Machine Name could not be determined.  Error is:  ' + e);
    }
    
    var client = globalChannelMap.get('client');
    var development = '';
    var verbose = true;
    
    if (machineName == 'MirthPROD') {
        development = false;
    } else {
        development = true;
    }
    
    var jsch = new JSch();
    jsch.addIdentity(client.keyFilePath());
    
    var session = jsch.getSession(client.id.toLowerCase(), client.sftpHost, 22); 
    if (verbose) {
    	logger.info('Session created ');
    }
    
    session.setConfig('StrictHostKeyChecking', 'no');
    session.connect();
    
    var channel = session.openChannel('sftp');
    //var ioexception = new Packages.java.io.IOException;
    channel.connect();
    
    if (verbose) {
    	logger.info('Connected to SFTP ');
    	logger.info('Home Directory: ' + channel.getHome());
    }
    
    if (development) {
        channel.cd('/home/' + client.id.toLowerCase() + '/local/inbound/test/');
    } else {
        channel.cd('inbound');
    }
    
    if (verbose) {
    	logger.info('Current Directory: ' + channel.pwd());
    }
    
    var directoryList = channel.ls('*.*');
    var arrayOfFiles = [];
    
    if (directoryList.size() > 0) {
    
        for (var i = 0; i < directoryList.size(); i++) {
        	
            	var file = directoryList.get(i).getFilename();
         	       	arrayOfFiles.push(file);
        }
        arrayOfFiles.sort().reverse();
    }
    
    if (arrayOfFiles.length > 0) {
    	
        for (var j = 0; j < arrayOfFiles.length; j++) {	
        	
            var filename = arrayOfFiles[j];
            var k = j + 1;
            
            logger.info('File #' + [k] + ': ' + filename);
     
            if ((filename.includes('.xml'))) {
    
    		// Setup file variables 
            	var line;
            	var i;
            	var record = '';
            	var tagStart = false;
            	var tag = '';
            	var batchSequenceId = 0;
              var batchComplete = 'false';
    
    		// Starts downloading a file as an InputStream
              var is = channel.get(filename);
              var bReader = new BufferedReader(new InputStreamReader(is));
    
    		// Setup XML MasterSegment and ChildSegment
    		if (filename.includes('AUTH')) {
    						
    			var masterSegment = /\<\/?\s*PriorAuthorizations(\s+.*|\s*\/)?\>/; 
    			var childSegment = /\<\/\s*PriorAuthorization\s*\>/;
    			
    		} else if (filename.includes('SRVC')) {
    						
    			var masterSegment = /\<\/?\s*RenderedServices(\s+.*|\s*\/)?\>/; 
    			var childSegment = /\<\/\s*RenderedService\s*\>/;
    			
    		} else if (filename.includes('RECP')) { 
    			
    			var masterSegment = /\<\/?\s*Recipients(\s+.*|\s*\/)?\>/; 
    			var childSegment = /\<\/\s*Recipient\s*\>/;
    			
    		} else if (filename.includes('PROV')) {
    			
    			var masterSegment = /\<\/?\s*Providers(\s+.*|\s*\/)?\>/; 
    			var childSegment = /\<\/\s*Provider\s*\>/;
    			
    		} else { 
    			// Future
    		}        
    
    		 // 
               while ((i = bReader.read()) != -1) {
               	
               	// Get char from InputStream
                   var ch = String.fromCharCode(i);
                   
                   // Set tagStart to true if the char is '<'
                   if (ch == '<') {
                       tagStart = true;
                   }
                   // Build the tag while tagStart is not '>'
                   if (tagStart) {
                       	tag += ch;
                       	//logger.info('tag: ' + tag);
                       
                   } else {
                   	// Build the record 
                   	record += ch;
                       	//logger.info('record: ' + record);
                   }
                   
    			// When the tag is closed check if is a complete record
                   if (ch == '>') {
                       	tagStart = false;
    
    				// Check child Segment Tag
                      	if (childSegment.test(tag)) {
    
                      		// Split record per <> </> segments
                      		batchSequenceId = batchSequenceId + 1;
                           	//logger.info('Record+Tag: ' + record+tag);
                           	
                           	var sourceMap = {
                               	"machineName": machineName,
                              	"client": client,
                               	"originalFilename": filename,
                               	"batchSequenceId": batchSequenceId,
                               	"batchComplete": batchComplete
                           	}
    
    					// Add the record to the Messages Array
                           	messages.add(new RawMessage((record + tag), null, sourceMap));
                           	// Clear record and tag
                           	record = '';
                           	tag = '';
                       }
                       
    				// Check is not final Segment
                       if(!masterSegment.test(tag)) {
                       		// add tag to the record
                       		record += tag;
                       		//logger.info('record: ' + record);
                       }
    				// Clear tag
                       	tag = '';
                   }
               }
    
               // Get the last message and change the batchComplete to true
               messages.get(messages.size() - 1).getSourceMap().batchComplete = 'true';
            }
    
            // Process TXT
            if (filename.includes('.txt')) {
    		
    		  // Setup file variables
                var line;
                var batchSequenceId = 0;
                var batchComplete = 'false';
                
                // Starts downloading a file as an InputStream
                var is = channel.get(filename);
                var bReader = new BufferedReader(new InputStreamReader(is));
    
    
    		  // Read how many lines in order to identify the last line
                var lines = bReader.lines().filter({
                    test: function (x) {
                        return x.length != 0
                    }
                }).toArray();
    
                // Set batchComplete when is the last line
                for (var i = 1; i < lines.length; i++) {
                	
                    if (lines.length - 1 == i) {
                        batchComplete = 'true';
                    }
    
    			 // Split delimited file by line
                    line = lines[i];
                    batchSequenceId = batchSequenceId + 1;
    
                    var sourceMap = {
                        "machineName": machineName,
                        "client": client,
                        "originalFilename": filename,
                        "batchSequenceId": batchSequenceId,
                        "batchComplete": batchComplete
                    }
    
                    messages.add(new RawMessage(line, null, sourceMap));
                }
            }
    
            // Process EDI/X12
            if (filename.includes('.edi')) {
    
    		  // Setup file variables
    		  var batchSequenceId = 0;
                var batchComplete = 'false';
                var curMessage = "";
                var segment = "";
                var strBreak = "DTP\*349";
                var strFinal = "SE\*";
    
                // Starts downloading a file as an InputStream
                var is = channel.get(filename);
                var bReader = new BufferedReader(new InputStreamReader(is));
                
    		  // Read the entire file
                line = bReader.readLine();
    
                // Serialize the file into XML
                var x12Message = SerializerFactory.getSerializer('EDI/X12').toXML(line);
    
                // Serialize the file back to EDI/X12 (because reading as inputstream returns the file without structure)
                var x12Raw = SerializerFactory.getSerializer('EDI/X12').fromXML(x12Message);
    
    	       // 
                var segmentScanner = new java.util.Scanner(x12Raw);
                segmentScanner.useDelimiter('~');
    
    	       // 
                while (segmentScanner.hasNext()) {
                    segment = segmentScanner.next();
                    curMessage += segment + '~';
    
    		      // Split segment by strBreak -> "DTP*349
                    if ((segment.indexOf(strBreak) != -1)) {
    
                    	//
                        batchSequenceId = batchSequenceId + 1;
    
    				// If next segment is SE* (footer) set batchComplete to true
                        if (segmentScanner.next().contains(strFinal)) {
                            batchComplete = 'true';
                        }
                        
                        var sourceMap = {
                            "machineName": machineName,
                            "client": client,
                            "originalFilename": filename,
                            "batchSequenceId": batchSequenceId,
                            "batchComplete": batchComplete
                        }
                        
                        //logger.info('curMessage: ' + curMessage);
                        messages.add(new RawMessage(curMessage, null, sourceMap));
                        curMessage = "";
                    }
                }
            }
    
            // move the file to upload folder and delete it afterwards
            //channel.rename('/home/' + client.id.toLowerCase() + '/local/inbound/test/' + filename,'/home/' + client.id.toLowerCase() + '/local/inbound/' + filename);
        }
    } else {
        logger.info('No files in the directory...');
    }
    
    channel.disconnect();
    session.disconnect();
    
    
    return messages;
Working...
X