如何在InvokeScriptedProcessor中使用“ DBCPConnectionPoolLookup”?

时间:2019-07-12 13:46:27

标签: groovy apache-nifi

我正在用Groovy编写InvokeScriptedProcessor(ISP),我设置了“ DBCPConnectionPoolLookup”控制器,并使用“ UpdateAttribute”设置了database.name。但是我得到这个错误:

  

由于以下原因无法处理会话:   java.lang.UnsupportedOperationException:无法查找   没有属性的DBCPConnectionPool;管理者   产生1秒:java.lang.RuntimeException:   java.lang.UnsupportedOperationException:无法查找   没有属性的DBCPConnectionPool

如何使用“ DBCPConnectionPoolLookup”连接到选定的数据库?

Error

config

import groovy.json.JsonBuilder
import groovy.json.JsonSlurper
import groovy.json.JsonOutput
import groovy.sql.Sql

import groovy.sql.GroovyRowResult;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;

import java.nio.charset.StandardCharsets

import org.apache.commons.io.IOUtils

import org.apache.nifi.annotation.behavior.EventDriven
import org.apache.nifi.annotation.documentation.CapabilityDescription
import org.apache.nifi.components.PropertyDescriptor
import org.apache.nifi.dbcp.DBCPService
import org.apache.nifi.processor.Relationship
import org.apache.nifi.processor.exception.ProcessException
import org.apache.nifi.processor.io.StreamCallback
import org.apache.nifi.processor.util.StandardValidators

@EventDriven
@CapabilityDescription("Execute a series of JDBC queries adding the results to each JSON presented in the FlowFile")
class GroovyProcessor implements Processor {

    def log

    final static Relationship REL_SUCCESS = new Relationship.Builder()
            .name("success")
            .description('FlowFiles that were successfully processed and had any data enriched are routed here')
            .build()

    final static Relationship REL_FAILURE = new Relationship.Builder()
            .name("failure")
            .description('FlowFiles that were not successfully processed are routed here')
            .build()

    Set<Relationship> getRelationships() { [REL_FAILURE, REL_SUCCESS] as Set }

    final static PropertyDescriptor DBCP_SERVICE = new PropertyDescriptor.Builder()
            .name("dbcp-connection-pool-services")
            .displayName("Database Connection Pool Services")
            .description("The Controller Service that is used to obtain a connection to the database.")
            .required(true)
            .identifiesControllerService(DBCPService)
            .build()
    final static PropertyDescriptor CLIENT_ID = new PropertyDescriptor.Builder()
            .name("clientId")
            .displayName("clientId")
            .description("Value to be used in queries.")
            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
            .required(true)
            .expressionLanguageSupported(true)
            .build()

    @Override
    List<PropertyDescriptor> getPropertyDescriptors() {
        Collections.unmodifiableList([DBCP_SERVICE]) as List<PropertyDescriptor>
    }

    void initialize(ProcessorInitializationContext context) { log = context.logger }

    public static GroovyRowResult toRowResult(ResultSet rs) throws SQLException {
        ResultSetMetaData metadata = rs.getMetaData();
        Map<String, Object> lhm = new LinkedHashMap<String, Object>(metadata.getColumnCount(), 1);
        for (int i = 1; i <= metadata.getColumnCount(); i++) {
            lhm.put(metadata.getColumnLabel(i), rs.getObject(i));
        }
        return new GroovyRowResult(lhm);
    }

    void onTrigger(ProcessContext context, ProcessSessionFactory sessionFactory) throws ProcessException {
        def session = sessionFactory.createSession()
        def flowFile = session.get()
        if (!flowFile) return

        def dbcpService = context.getProperty(DBCP_SERVICE).asControllerService(DBCPService)
        def conn = dbcpService.getConnection()
        try {
            def sql = new Sql(conn)
            flowFile = session.write(flowFile,
                    { inputStream, outputStream ->
                        def clientId = context.getProperty(CLIENT_ID).evaluateAttributeExpressions(flowFile).value
                        def definitionId = flowFile.getAttribute('definition.id')
                        def jobId  = flowFile.getAttribute('job.id')
                        def q = """QUERY"""
                        def result = []

                        sql.eachRow(q) {
                            def temp = [:]
                            temp.header = [:]
                            temp.details = []
                            temp.RawData = [:]
                            temp.StagedExtractsUuid = it.uuid
                            temp.DataMapStatus=it.DataMapStatus
                            temp.RawData = new JsonSlurper().parseText(it.RawData)
                            sql.eachRow("QUERY") {
                                temp.header = toRowResult(it)
                                sql.eachRow("QUERY") {
                                    temp.details.add(toRowResult(it))
                                }
                            }
                            result.add(temp)
                        }
                        outputStream.write(new JsonBuilder(result).toString().getBytes('UTF-8'))
                    } as StreamCallback)
            session.transfer(flowFile, REL_SUCCESS)
        } catch (final Throwable t) {
            log.error('{} failed to process due to {}', [this, t] as Object[])
            session.transfer(flowFile, REL_FAILURE)
        } finally {
            session.commit()
            conn.close()
        }
    }


    @Override
    Collection<ValidationResult> validate(ValidationContext context) { null }

    @Override
    PropertyDescriptor getPropertyDescriptor(String name) {
        switch (name) {
            case 'JSON Lookup attribute': return LOOKUP_ATTR
            case 'Database Connection Pool Services': return DBCP_SERVICE
            default: return null
        }
    }

    @Override
    void onPropertyModified(PropertyDescriptor descriptor, String oldValue, String newValue) {}

    @Override
    String getIdentifier() { null }

}

processor = new GroovyProcessor()

1 个答案:

答案 0 :(得分:2)

获得连接后,您需要传递流文件属性,否则它将无法访问您的database.name属性。

所以不是:

dbcpService.getConnection()

应该是:

dbcpService.getConnection(flowFile.getAttributes()))