Search code examples
csvgroovyapache-nifi

Nifi Groovy script to modify csv rows giving MissingMethodException error


I am working on a groovy script which will take following csv file as input

Id, Name, Class
1, Kevin,[Eight, Nine]
2, Mark,Four

and create or change csv as follows

Id, Name, Class
1, Kevin,Eight
1, Kevin,Nine
2, Mark,Four

Basically, If column Class has array of string then put it in multiple rows replicating all other column values.

def flowFile = session.get()
if(!flowFile) return
try {
flowFile = session.write(flowFile, {inputStream, outputStream ->
    outputStream.withWriter("UTF-8"){ w ->
        inputStream.eachLine("UTF-8"){ line ->
            def subString = line.takeBetween('[', ']')
            def splitArray = subString.split(',')
             if(splitArray.length > 1) {
                def lineBefore = line.takeBefore('[');
                def lineAfter = line.takeAfter(']');
                for(int i=0;i<splitArray.length;i++) {
                    w << lineBefore << row.getAt(i) << lineAfter << '\n'
                }
            }else {
                w << line << '\n'
            }
        }
    }
} as StreamCallback)

session.transfer(flowFile, REL_SUCCESS)
}catch(e) {
      log.error('Error capturing nextLink', e)
      session.transfer(flowFile, REL_FAILURE)
}

I am getting the below error:

 Error capturing nextLink: groovy.lang.MissingMethodException: No signature of method: java.lang.String.takeBetween() is applicable for argument types: (String, String) values: [[, ]]

But the method takeBetween in def subString = line.takeBetween("[", "]") is working perfectly fine in eclipse


Solution

  • The following groovy script with 'substring' method instead of 'takeBetween' helped me create the csv in required format

    def flowFile = session.get()
    if(!flowFile) return
    try {
    flowFile = session.write(flowFile, {inputStream, outputStream ->
        outputStream.withWriter("UTF-8"){ w ->
            inputStream.eachLine("UTF-8"){ line ->
             def splitArray = new String[0];
             def subString = "";
             def x = line.indexOf("[")+1;
             def y = line.indexOf("]");
             if(x > 0 && y >0)
             subString = line.substring(x,y);
             if(subString != null && subString.length() >0)
                 splitArray = subString.split(',')
                 if(splitArray.length > 1) {
                     def lineBefore = line.substring(0,x);
                     def lineAfter = line.substring(y,line.length());
                    for(int i=0;i<splitArray.length;i++) {
                        w << lineBefore << splitArray.getAt(i) << lineAfter << '\n'
                    }
                }else {
                    w << line << '\n'
                }
            }
        }
    } as StreamCallback)
    
    session.transfer(flowFile, REL_SUCCESS)
    }catch(e) {
          log.error('Error capturing nextLink', e)
          session.transfer(flowFile, REL_FAILURE)
    }