diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/pom.xml b/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/pom.xml
index af9c124788..81cd910588 100644
--- a/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/pom.xml
+++ b/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/pom.xml
@@ -127,6 +127,10 @@
2.7
compile
+
+ com.squareup.okhttp3
+ mockwebserver
+
org.apache.nifi
nifi-mock
@@ -154,34 +158,6 @@
nifi-schema-registry-service-api
test
-
- javax.servlet
- javax.servlet-api
- test
-
-
- org.eclipse.jetty
- jetty-servlet
- test
-
-
- org.apache.derby
- derby
- ${derby.version}
- test
-
-
- org.apache.derby
- derbytools
- ${derby.version}
- test
-
-
- org.codehaus.groovy
- groovy-json
- ${nifi.groovy.version}
- test
-
@@ -190,8 +166,6 @@
apache-rat-plugin
- src/test/resources/complex.avsc
- src/test/resources/simple.avsc
src/test/resources/test.csv
src/test/resources/test_sep_escape_comment.csv
src/test/resources/test_Windows-31J.csv
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/TestRestLookupService.groovy b/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/TestRestLookupService.groovy
deleted file mode 100644
index 2184f3d72f..0000000000
--- a/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/TestRestLookupService.groovy
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.nifi.lookup
-
-import okhttp3.MediaType
-import okhttp3.Protocol
-import okhttp3.Request
-import okhttp3.Response
-import okhttp3.ResponseBody
-import org.apache.nifi.lookup.rest.MockRestLookupService
-import org.apache.nifi.serialization.SimpleRecordSchema
-import org.apache.nifi.serialization.record.MapRecord
-import org.apache.nifi.serialization.record.MockRecordParser
-import org.apache.nifi.serialization.record.RecordField
-import org.apache.nifi.serialization.record.RecordFieldType
-import org.apache.nifi.serialization.record.RecordSchema
-import org.apache.nifi.util.TestRunner
-import org.apache.nifi.util.TestRunners
-import org.junit.jupiter.api.BeforeEach
-import org.junit.jupiter.api.Test
-
-import static groovy.json.JsonOutput.toJson
-import static org.junit.jupiter.api.Assertions.assertEquals
-import static org.junit.jupiter.api.Assertions.assertNotNull
-import static org.junit.jupiter.api.Assertions.assertTrue
-
-class TestRestLookupService {
- TestRunner runner
- MockRecordParser recordReader
- MockRestLookupService lookupService
-
- static final String JSON_TYPE = "application/json"
-
- @BeforeEach
- void setup() {
- recordReader = new MockRecordParser()
- lookupService = new MockRestLookupService()
- runner = TestRunners.newTestRunner(TestRestLookupServiceProcessor.class)
- runner.setValidateExpressionUsage(false)
-
- runner.addControllerService("lookupService", lookupService)
- runner.addControllerService("recordReader", recordReader)
- runner.setProperty(lookupService, RestLookupService.RECORD_READER, "recordReader")
- runner.setProperty("Lookup Service", "lookupService")
- runner.setProperty(lookupService, RestLookupService.URL, "http://localhost:8080")
- // Add a dynamic property using Expression Language (expecting to be provided by FlowFile attribute)
- runner.setProperty(lookupService, 'test', '${test.ff.attribute}')
- runner.enableControllerService(lookupService)
- runner.enableControllerService(recordReader)
- runner.assertValid()
- }
-
- @Test
- void testSimpleLookup() {
- recordReader.addSchemaField("name", RecordFieldType.STRING)
- recordReader.addSchemaField("age", RecordFieldType.INT)
- recordReader.addSchemaField("sport", RecordFieldType.STRING)
-
- recordReader.addRecord("John Doe", 48, "Soccer")
- recordReader.addRecord("Jane Doe", 47, "Tennis")
- recordReader.addRecord("Sally Doe", 47, "Curling")
-
- lookupService.response = buildResponse(toJson([ simpleTest: true]), JSON_TYPE)
- def result = lookupService.lookup(getCoordinates(JSON_TYPE, "get"), ['test.ff.attribute' : 'Hello'])
- assertTrue(result.isPresent())
- def headers = lookupService.getHeaders()
- assertNotNull(headers)
- def headerValue = headers.get('test')
- assertNotNull(headerValue)
- assertEquals(1, headerValue.size())
- assertEquals('Hello', headerValue.get(0))
- def record = result.get()
- assertEquals("John Doe", record.getAsString("name"))
- assertEquals(48, record.getAsInt("age"))
- assertEquals("Soccer", record.getAsString("sport"))
- }
-
- @Test
- void testNestedLookup() {
- runner.disableControllerService(lookupService)
- runner.setProperty(lookupService, RestLookupService.RECORD_PATH, "/person")
- runner.enableControllerService(lookupService)
- runner.assertValid()
-
- recordReader.addSchemaField("id", RecordFieldType.INT)
- final List personFields = new ArrayList<>()
- final RecordField nameField = new RecordField("name", RecordFieldType.STRING.getDataType())
- final RecordField ageField = new RecordField("age", RecordFieldType.INT.getDataType())
- final RecordField sportField = new RecordField("sport", RecordFieldType.STRING.getDataType())
- personFields.add(nameField)
- personFields.add(ageField)
- personFields.add(sportField)
- final RecordSchema personSchema = new SimpleRecordSchema(personFields)
- recordReader.addSchemaField("person", RecordFieldType.RECORD)
- recordReader.addRecord(1, new MapRecord(personSchema, new HashMap() {{
- put("name", "John Doe")
- put("age", 48)
- put("sport", "Soccer")
- }}))
-
- lookupService.response = buildResponse(toJson([ simpleTest: true]), JSON_TYPE)
- def result = lookupService.lookup(getCoordinates(JSON_TYPE, "get"))
- assertTrue(result.isPresent())
- def record = result.get()
-
- assertEquals("John Doe", record.getAsString("name"))
- assertEquals(48, record.getAsInt("age"))
- assertEquals("Soccer", record.getAsString("sport"))
-
- /*
- * Test deep lookup
- */
-
- runner.disableControllerService(lookupService)
- runner.setProperty(lookupService, RestLookupService.RECORD_PATH, "/person/sport")
- runner.enableControllerService(lookupService)
- runner.assertValid()
-
- result = lookupService.lookup(getCoordinates(JSON_TYPE, "get"))
- assertTrue(result.isPresent())
- record = result.get()
- assertNotNull(record.getAsString("sport"))
- assertEquals("Soccer", record.getAsString("sport"))
- }
-
- private static Map getCoordinates(String mimeType, String method) {
- def retVal = [:] as Map
- retVal[RestLookupService.MIME_TYPE_KEY] = mimeType
- retVal[RestLookupService.METHOD_KEY] = method
-
- retVal
- }
-
- private static Response buildResponse(String resp, String mimeType) {
- return new Response.Builder()
- .code(200)
- .body(
- ResponseBody.create(resp, MediaType.parse(mimeType))
- )
- .message("Test")
- .protocol(Protocol.HTTP_1_1)
- .request(new Request.Builder().url("http://localhost:8080").get().build())
- .build()
- }
-}
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/TestRestLookupServiceProcessor.groovy b/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/TestRestLookupServiceProcessor.groovy
deleted file mode 100644
index 9ca24421b6..0000000000
--- a/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/TestRestLookupServiceProcessor.groovy
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.nifi.lookup
-
-import org.apache.nifi.components.PropertyDescriptor
-import org.apache.nifi.processor.AbstractProcessor
-import org.apache.nifi.processor.ProcessContext
-import org.apache.nifi.processor.ProcessSession
-import org.apache.nifi.processor.exception.ProcessException
-
-class TestRestLookupServiceProcessor extends AbstractProcessor {
- static final PropertyDescriptor CLIENT_SERVICE = new PropertyDescriptor.Builder()
- .name("Lookup Service")
- .description("RestLookupService")
- .identifiesControllerService(RestLookupService.class)
- .required(true)
- .build()
-
- @Override
- void onTrigger(ProcessContext context, ProcessSession session) throws ProcessException {
-
- }
-
- @Override
- protected List getSupportedPropertyDescriptors() {
- List propDescs = new ArrayList<>()
- propDescs.add(CLIENT_SERVICE)
- return propDescs
- }
-}
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/db/TestDatabaseRecordLookupService.groovy b/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/db/TestDatabaseRecordLookupService.groovy
deleted file mode 100644
index 6f50bcb01c..0000000000
--- a/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/db/TestDatabaseRecordLookupService.groovy
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.lookup.db
-
-import org.apache.nifi.controller.AbstractControllerService
-import org.apache.nifi.dbcp.DBCPService
-import org.apache.nifi.lookup.LookupFailureException
-import org.apache.nifi.lookup.LookupService
-import org.apache.nifi.lookup.TestProcessor
-import org.apache.nifi.processor.exception.ProcessException
-import org.apache.nifi.reporting.InitializationException
-import org.apache.nifi.serialization.record.Record
-import org.apache.nifi.util.TestRunner
-import org.apache.nifi.util.TestRunners
-import org.junit.jupiter.api.BeforeAll
-import org.junit.jupiter.api.BeforeEach
-import org.junit.jupiter.api.Test
-
-import java.sql.Connection
-import java.sql.DriverManager
-import java.sql.SQLException
-import java.sql.Statement
-
-import static org.hamcrest.CoreMatchers.instanceOf
-import static org.hamcrest.MatcherAssert.assertThat
-import static org.junit.jupiter.api.Assertions.assertEquals
-import static org.junit.jupiter.api.Assertions.assertNull
-
-
-class TestDatabaseRecordLookupService {
-
- private TestRunner runner
-
- private final static Optional EMPTY_RECORD = Optional.empty()
- private final static String DB_LOCATION = "target/db"
-
- @BeforeAll
- static void setupClass() {
- System.setProperty("derby.stream.error.file", "target/derby.log")
- }
-
- @BeforeEach
- void setup() throws InitializationException {
- final DBCPService dbcp = new DBCPServiceSimpleImpl()
- final Map dbcpProperties = new HashMap<>()
-
- runner = TestRunners.newTestRunner(TestProcessor.class)
- runner.addControllerService("dbcp", dbcp, dbcpProperties)
- runner.enableControllerService(dbcp)
- }
-
- @Test
- void testDatabaseLookupService() throws InitializationException, IOException, LookupFailureException {
- // remove previous test database, if any
- final File dbLocation = new File(DB_LOCATION)
- dbLocation.delete()
-
- // load test data to database
- final Connection con = ((DBCPService) runner.getControllerService("dbcp")).connection
- final Statement stmt = con.createStatement()
-
- try {
- stmt.execute("drop table TEST")
- } catch (final SQLException sqle) {
- }
-
- stmt.execute("create table TEST (id integer not null, val1 integer, val2 varchar(10), constraint my_pk primary key (id))")
- stmt.execute("insert into TEST (id, val1, val2) VALUES (0, NULL, 'Hello')")
- stmt.execute("insert into TEST (id, val1, val2) VALUES (1, 1, 'World')")
-
- final DatabaseRecordLookupService service = new DatabaseRecordLookupService()
-
- runner.addControllerService("db-lookup-service", service)
- runner.setProperty(service, DatabaseRecordLookupService.DBCP_SERVICE, "dbcp")
- runner.assertNotValid()
- runner.setProperty(service, DatabaseRecordLookupService.TABLE_NAME, "TEST")
- runner.setProperty(service, DatabaseRecordLookupService.LOOKUP_KEY_COLUMN, "id")
- runner.enableControllerService(service)
- runner.assertValid(service)
-
- def lookupService = (DatabaseRecordLookupService) runner.processContext.controllerServiceLookup.getControllerService("db-lookup-service")
-
- assertThat(lookupService, instanceOf(LookupService.class))
-
- final Optional property1 = lookupService.lookup(Collections.singletonMap("key", "0"))
- assertNull(property1.get().getAsInt("VAL1"), "Should be null but is not")
- assertEquals("Hello", property1.get().getAsString("VAL2"))
-
- final Optional property2 = lookupService.lookup(Collections.singletonMap("key", "1"))
- assertEquals(1, property2.get().getAsInt("VAL1"))
- assertEquals("World", property2.get().getAsString("VAL2"))
-
- // Key not found
- final Optional property3 = lookupService.lookup(Collections.singletonMap("key", "2"))
- assertEquals(EMPTY_RECORD, property3)
- }
-
- @Test
- void testDatabaseLookupServiceSpecifyColumns() throws InitializationException, IOException, LookupFailureException {
- // remove previous test database, if any
- final File dbLocation = new File(DB_LOCATION)
- dbLocation.delete()
-
- // load test data to database
- final Connection con = ((DBCPService) runner.getControllerService("dbcp")).connection
- final Statement stmt = con.createStatement()
-
- try {
- stmt.execute("drop table TEST")
- } catch (final SQLException sqle) {
- }
-
- stmt.execute("create table TEST (id integer not null, val1 integer, val2 varchar(10), constraint my_pk primary key (id))")
- stmt.execute("insert into TEST (id, val1, val2) VALUES (0, NULL, 'Hello')")
- stmt.execute("insert into TEST (id, val1, val2) VALUES (1, 1, 'World')")
-
- final DatabaseRecordLookupService service = new DatabaseRecordLookupService()
-
- runner.addControllerService("db-lookup-service", service)
- runner.setProperty(service, DatabaseRecordLookupService.DBCP_SERVICE, "dbcp")
- runner.assertNotValid()
- runner.setProperty(service, DatabaseRecordLookupService.TABLE_NAME, "TEST")
- runner.setProperty(service, DatabaseRecordLookupService.LOOKUP_KEY_COLUMN, "id")
- runner.setProperty(service, DatabaseRecordLookupService.LOOKUP_VALUE_COLUMNS, "val1")
- runner.enableControllerService(service)
- runner.assertValid(service)
-
- def lookupService = (DatabaseRecordLookupService) runner.processContext.controllerServiceLookup.getControllerService("db-lookup-service")
-
- assertThat(lookupService, instanceOf(LookupService.class))
-
- final Optional property1 = lookupService.lookup(Collections.singletonMap("key", "0"))
- assertNull(property1.get().getAsInt("VAL1"), "Should be null but is not")
-
- final Optional property2 = lookupService.lookup(Collections.singletonMap("key", "1"))
- assertEquals(1, property2.get().getAsInt("VAL1"))
-
- // Key not found
- final Optional property3 = lookupService.lookup(Collections.singletonMap("key", "2"))
- assertEquals(EMPTY_RECORD, property3)
- }
-
- @Test
- void exerciseCacheLogic() {
- // remove previous test database, if any
- final File dbLocation = new File(DB_LOCATION)
- dbLocation.delete()
-
- // load test data to database
- final Connection con = ((DBCPService) runner.getControllerService("dbcp")).connection
- final Statement stmt = con.createStatement()
-
- try {
- stmt.execute("drop table TEST")
- } catch (final SQLException sqle) {
- }
-
- stmt.execute("create table TEST (id integer not null, val1 integer, val2 varchar(10), constraint my_pk primary key (id))")
- stmt.execute("insert into TEST (id, val1, val2) VALUES (0, NULL, 'Hello')")
- stmt.execute("insert into TEST (id, val1, val2) VALUES (1, 1, 'World')")
-
- final DatabaseRecordLookupService service = new DatabaseRecordLookupService()
-
- runner.addControllerService("db-lookup-service", service)
- runner.setProperty(service, DatabaseRecordLookupService.DBCP_SERVICE, "dbcp")
- runner.assertNotValid()
- runner.setProperty(service, DatabaseRecordLookupService.TABLE_NAME, "TEST")
- runner.setProperty(service, DatabaseRecordLookupService.LOOKUP_KEY_COLUMN, "id")
- runner.setProperty(service, DatabaseRecordLookupService.CACHE_SIZE, "10")
- runner.enableControllerService(service)
- runner.assertValid(service)
-
- def lookupService = (DatabaseRecordLookupService) runner.processContext.controllerServiceLookup.getControllerService("db-lookup-service")
-
- assertThat(lookupService, instanceOf(LookupService.class))
-
- final Optional property1 = lookupService.lookup(Collections.singletonMap("key", "1"))
- assertEquals(1, property1.get().getAsInt("VAL1"))
- assertEquals("World", property1.get().getAsString("VAL2"))
-
- final Optional property2 = lookupService.lookup(Collections.singletonMap("key", "1"))
- assertEquals(1, property2.get().getAsInt("VAL1"))
- assertEquals("World", property2.get().getAsString("VAL2"))
-
- final Optional property3 = lookupService.lookup(Collections.singletonMap("key", "0"))
- assertNull(property3.get().getAsInt("VAL1"))
- assertEquals("Hello", property3.get().getAsString("VAL2"))
-
- final Optional property4 = lookupService.lookup(Collections.singletonMap("key", "0"))
- assertNull(property4.get().getAsInt("VAL1"))
- assertEquals("Hello", property4.get().getAsString("VAL2"))
- }
-
- /**
- * Simple implementation for component testing.
- *
- */
- class DBCPServiceSimpleImpl extends AbstractControllerService implements DBCPService {
-
- @Override
- String getIdentifier() {
- "dbcp"
- }
-
- @Override
- Connection getConnection() throws ProcessException {
- try {
- Class.forName("org.apache.derby.jdbc.EmbeddedDriver")
- DriverManager.getConnection("jdbc:derby:${DB_LOCATION};create=true")
- } catch (e) {
- throw new ProcessException("getConnection failed: " + e);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/db/TestSimpleDatabaseLookupService.groovy b/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/db/TestSimpleDatabaseLookupService.groovy
deleted file mode 100644
index 1a1dcca14d..0000000000
--- a/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/db/TestSimpleDatabaseLookupService.groovy
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.lookup.db
-
-import org.apache.nifi.controller.AbstractControllerService
-import org.apache.nifi.dbcp.DBCPService
-import org.apache.nifi.lookup.LookupFailureException
-import org.apache.nifi.lookup.LookupService
-import org.apache.nifi.lookup.TestProcessor
-import org.apache.nifi.processor.exception.ProcessException
-import org.apache.nifi.reporting.InitializationException
-import org.apache.nifi.serialization.record.Record
-import org.apache.nifi.util.TestRunner
-import org.apache.nifi.util.TestRunners
-import org.junit.jupiter.api.BeforeAll
-import org.junit.jupiter.api.BeforeEach
-import org.junit.jupiter.api.Test
-
-import java.sql.Connection
-import java.sql.DriverManager
-import java.sql.SQLException
-import java.sql.Statement
-
-import static org.hamcrest.CoreMatchers.instanceOf
-import static org.hamcrest.MatcherAssert.assertThat
-import static org.junit.jupiter.api.Assertions.assertEquals
-import static org.junit.jupiter.api.Assertions.assertFalse
-
-class TestSimpleDatabaseLookupService {
-
- private TestRunner runner
-
- private final static Optional EMPTY_RECORD = Optional.empty()
- private final static String DB_LOCATION = "target/db"
-
- @BeforeAll
- static void setupClass() {
- System.setProperty("derby.stream.error.file", "target/derby.log")
- }
-
- @BeforeEach
- void setup() throws InitializationException {
- final DBCPService dbcp = new DBCPServiceSimpleImpl()
- final Map dbcpProperties = new HashMap<>()
-
- runner = TestRunners.newTestRunner(TestProcessor.class)
- runner.addControllerService("dbcp", dbcp, dbcpProperties)
- runner.enableControllerService(dbcp)
- }
-
- @Test
- void testDatabaseLookupService() throws InitializationException, IOException, LookupFailureException {
- // remove previous test database, if any
- final File dbLocation = new File(DB_LOCATION)
- dbLocation.delete()
-
- // load test data to database
- final Connection con = ((DBCPService) runner.getControllerService("dbcp")).connection
- final Statement stmt = con.createStatement()
-
- try {
- stmt.execute("drop table TEST")
- } catch (final SQLException sqle) {
- }
-
- stmt.execute("create table TEST (id integer not null, val1 integer, val2 varchar(10), constraint my_pk primary key (id))")
- stmt.execute("insert into TEST (id, val1, val2) VALUES (0, NULL, 'Hello')")
- stmt.execute("insert into TEST (id, val1, val2) VALUES (1, 1, 'World')")
-
- final SimpleDatabaseLookupService service = new SimpleDatabaseLookupService()
-
- runner.addControllerService("db-lookup-service", service)
- runner.setProperty(service, SimpleDatabaseLookupService.DBCP_SERVICE, "dbcp")
- runner.assertNotValid()
- runner.setProperty(service, SimpleDatabaseLookupService.TABLE_NAME, "TEST")
- runner.setProperty(service, SimpleDatabaseLookupService.LOOKUP_KEY_COLUMN, "id")
- runner.setProperty(service, SimpleDatabaseLookupService.LOOKUP_VALUE_COLUMN, "VAL1")
- runner.enableControllerService(service)
- runner.assertValid(service)
-
- def lookupService = (SimpleDatabaseLookupService) runner.processContext.controllerServiceLookup.getControllerService("db-lookup-service")
-
- assertThat(lookupService, instanceOf(LookupService.class))
-
- // Lookup VAL1
- final Optional property1 = lookupService.lookup(Collections.singletonMap("key", "0"))
- assertFalse(property1.isPresent())
- // Key not found
- final Optional property3 = lookupService.lookup(Collections.singletonMap("key", "2"))
- assertEquals(EMPTY_RECORD, property3)
-
- runner.disableControllerService(service)
- runner.setProperty(service, SimpleDatabaseLookupService.LOOKUP_VALUE_COLUMN, "VAL2")
- runner.enableControllerService(service)
- final Optional property2 = lookupService.lookup(Collections.singletonMap("key", "1"))
- assertEquals("World", property2.get())
- }
-
- @Test
- void exerciseCacheLogic() {
- // remove previous test database, if any
- final File dbLocation = new File(DB_LOCATION)
- dbLocation.delete()
-
- // load test data to database
- final Connection con = ((DBCPService) runner.getControllerService("dbcp")).connection
- final Statement stmt = con.createStatement()
-
- try {
- stmt.execute("drop table TEST")
- } catch (final SQLException sqle) {
- }
-
- stmt.execute("create table TEST (id integer not null, val1 integer, val2 varchar(10), constraint my_pk primary key (id))")
- stmt.execute("insert into TEST (id, val1, val2) VALUES (0, NULL, 'Hello')")
- stmt.execute("insert into TEST (id, val1, val2) VALUES (1, 1, 'World')")
-
- final SimpleDatabaseLookupService service = new SimpleDatabaseLookupService()
-
- runner.addControllerService("db-lookup-service", service)
- runner.setProperty(service, SimpleDatabaseLookupService.DBCP_SERVICE, "dbcp")
- runner.assertNotValid()
- runner.setProperty(service, SimpleDatabaseLookupService.TABLE_NAME, "TEST")
- runner.setProperty(service, SimpleDatabaseLookupService.LOOKUP_KEY_COLUMN, "id")
- runner.setProperty(service, SimpleDatabaseLookupService.CACHE_SIZE, "10")
- runner.setProperty(service, SimpleDatabaseLookupService.LOOKUP_VALUE_COLUMN, "VAL1")
- runner.enableControllerService(service)
- runner.assertValid(service)
-
- def lookupService = (SimpleDatabaseLookupService) runner.processContext.controllerServiceLookup.getControllerService("db-lookup-service")
-
- assertThat(lookupService, instanceOf(LookupService.class))
-
- // Lookup VAL1
- final Optional property1 = lookupService.lookup(Collections.singletonMap("key", "1"))
- assertEquals("1", property1.get())
- final Optional property3 = lookupService.lookup(Collections.singletonMap("key", "0"))
- assertFalse(property3.isPresent())
-
-
- runner.disableControllerService(service)
- runner.setProperty(service, SimpleDatabaseLookupService.LOOKUP_VALUE_COLUMN, "VAL2")
- runner.enableControllerService(service)
- final Optional property2 = lookupService.lookup(Collections.singletonMap("key", "1"))
- assertEquals("World", property2.get())
-
- final Optional property4 = lookupService.lookup(Collections.singletonMap("key", "0"))
- assertEquals("Hello", property4.get())
- }
-
- /**
- * Simple implementation for component testing.
- *
- */
- class DBCPServiceSimpleImpl extends AbstractControllerService implements DBCPService {
-
- @Override
- String getIdentifier() {
- "dbcp"
- }
-
- @Override
- Connection getConnection() throws ProcessException {
- try {
- Class.forName("org.apache.derby.jdbc.EmbeddedDriver")
- DriverManager.getConnection("jdbc:derby:${DB_LOCATION};create=true")
- } catch (e) {
- throw new ProcessException("getConnection failed: " + e);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/rest/MockRestLookupService.groovy b/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/rest/MockRestLookupService.groovy
deleted file mode 100644
index 4983d426ff..0000000000
--- a/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/rest/MockRestLookupService.groovy
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.nifi.lookup.rest
-
-import okhttp3.Headers
-import okhttp3.Request
-import okhttp3.Response
-import org.apache.nifi.lookup.RestLookupService
-
-class MockRestLookupService extends RestLookupService {
- Response response
- Headers headers
-
- @Override
- protected Response executeRequest(Request request) {
- this.headers = request.headers()
- return response
- }
-
- Map> getHeaders() {
- headers.toMultimap()
- }
-}
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/rest/SchemaUtil.groovy b/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/rest/SchemaUtil.groovy
deleted file mode 100644
index 8ac4e4b459..0000000000
--- a/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/rest/SchemaUtil.groovy
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.nifi.lookup.rest
-
-class SchemaUtil {
- static final String SIMPLE = SchemaUtil.class.getResourceAsStream("/simple.avsc").text
-
- static final String COMPLEX = SchemaUtil.class.getResourceAsStream("/complex.avsc").text
-}
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/rest/handlers/BasicAuth.groovy b/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/rest/handlers/BasicAuth.groovy
deleted file mode 100644
index eb0c6f0510..0000000000
--- a/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/rest/handlers/BasicAuth.groovy
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.nifi.lookup.rest.handlers
-
-import org.eclipse.jetty.server.Request
-import org.eclipse.jetty.server.handler.AbstractHandler
-
-import javax.servlet.ServletException
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
-
-import static groovy.json.JsonOutput.prettyPrint
-import static groovy.json.JsonOutput.toJson
-
-class BasicAuth extends AbstractHandler {
-
- @Override
- void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
- baseRequest.handled = true
- def authString = request.getHeader("Authorization")
- def headers = []
- request.headerNames.each { headers << it }
-
- if (!authString || authString != "Basic am9obi5zbWl0aDp0ZXN0aW5nMTIzNA==") {
- response.status = 401
- response.setHeader("WWW-Authenticate", "Basic realm=\"Jetty\"")
- response.setHeader("response.phrase", "Unauthorized")
- response.contentType = "text/plain"
- response.writer.println("Get off my lawn!")
- return
- }
-
- response.writer.println(prettyPrint(
- toJson([
- username: "john.smith",
- password: "testing1234"
- ])
- ))
- }
-}
\ No newline at end of file
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/rest/handlers/ComplexJson.groovy b/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/rest/handlers/ComplexJson.groovy
deleted file mode 100644
index c8790f89fa..0000000000
--- a/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/rest/handlers/ComplexJson.groovy
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.nifi.lookup.rest.handlers
-
-import javax.servlet.http.HttpServlet
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
-
-import static groovy.json.JsonOutput.prettyPrint
-import static groovy.json.JsonOutput.toJson
-
-class ComplexJson extends HttpServlet {
- @Override
- void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
- response.contentType = "application/json"
- response.outputStream.write(prettyPrint(
- toJson([
- top: [
- middle: [
- inner: [
- "username": "jane.doe",
- "password": "testing7890",
- "email": "jane.doe@test-example.com"
- ]
- ]
- ]
- ])
- ).bytes)
- }
-}
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/rest/handlers/NoRecord.groovy b/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/rest/handlers/NoRecord.groovy
deleted file mode 100644
index 2c4a3a75e5..0000000000
--- a/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/rest/handlers/NoRecord.groovy
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.nifi.lookup.rest.handlers
-
-import org.slf4j.Logger
-import org.slf4j.LoggerFactory
-
-import javax.servlet.http.HttpServlet
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
-
-import static groovy.json.JsonOutput.prettyPrint
-import static groovy.json.JsonOutput.toJson
-
-class NoRecord extends HttpServlet {
- Logger logger = LoggerFactory.getLogger(NoRecord.class)
- @Override
- void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
-
- response.contentType = "application/json"
- response.outputStream.write(prettyPrint(
- toJson([:])
- ).bytes)
- }
-}
\ No newline at end of file
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/rest/handlers/SimpleJson.groovy b/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/rest/handlers/SimpleJson.groovy
deleted file mode 100644
index 4897b5ce69..0000000000
--- a/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/rest/handlers/SimpleJson.groovy
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.nifi.lookup.rest.handlers
-
-import org.slf4j.Logger
-import org.slf4j.LoggerFactory
-
-import javax.servlet.http.HttpServlet
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
-
-import static groovy.json.JsonOutput.prettyPrint
-import static groovy.json.JsonOutput.toJson
-
-class SimpleJson extends HttpServlet {
- Logger logger = LoggerFactory.getLogger(SimpleJson.class)
- @Override
- void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
- String u = request.getHeader("X-USER")
- String p = request.getHeader("X-PASS")
-
- response.contentType = "application/json"
- response.outputStream.write(prettyPrint(
- toJson([
- username: u ?: "john.smith",
- password: p ?: "testing1234"
- ])
- ).bytes)
- }
-}
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/rest/handlers/SimpleJsonArray.groovy b/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/rest/handlers/SimpleJsonArray.groovy
deleted file mode 100644
index 6b63dd6879..0000000000
--- a/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/rest/handlers/SimpleJsonArray.groovy
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.nifi.lookup.rest.handlers
-
-import javax.servlet.http.HttpServlet
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
-
-import static groovy.json.JsonOutput.prettyPrint
-import static groovy.json.JsonOutput.toJson
-
-class SimpleJsonArray extends HttpServlet {
- @Override
- void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
- response.contentType = "application/json"
- response.outputStream.write(prettyPrint(
- toJson([[
- username: "john.smith",
- password: "testing1234"
- ],
- [
- username: "jane.doe",
- password: "testing7890"
- ]])
- ).bytes)
- }
-}
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/rest/handlers/VerbTest.groovy b/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/rest/handlers/VerbTest.groovy
deleted file mode 100644
index 821274b86c..0000000000
--- a/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/groovy/org/apache/nifi/lookup/rest/handlers/VerbTest.groovy
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.nifi.lookup.rest.handlers
-
-import org.apache.nifi.util.StringUtils
-import org.slf4j.Logger
-import org.slf4j.LoggerFactory
-
-import javax.servlet.http.HttpServlet
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
-
-import static groovy.json.JsonOutput.prettyPrint
-import static groovy.json.JsonOutput.toJson
-import static org.junit.jupiter.api.Assertions.assertFalse
-import static org.junit.jupiter.api.Assertions.assertNotNull
-
-class VerbTest extends HttpServlet {
- Logger logger = LoggerFactory.getLogger(VerbTest.class)
-
- void doDelete(HttpServletRequest request, HttpServletResponse response) {
- validateBody(request)
- sendResponse(response)
- }
-
- void doPost(HttpServletRequest request, HttpServletResponse response) {
- validateBody(request)
- sendResponse(response)
- }
-
- void doPut(HttpServletRequest request, HttpServletResponse response) {
- validateBody(request)
- sendResponse(response)
- }
-
- void sendResponse(HttpServletResponse response) {
- response.contentType = "application/json"
- response.outputStream.write(prettyPrint(
- toJson([
- username: "john.smith",
- password: "testing1234"
- ])
- ).bytes)
- }
-
- void validateBody(HttpServletRequest request) {
- String needsBody = request.getHeader("needs-body")
- boolean bodyRequired = !StringUtils.isBlank(needsBody)
- String body = request.inputStream.text
- if (bodyRequired) {
- assertNotNull(body)
- assertFalse(StringUtils.isBlank(body))
- }
- }
-}
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/java/org/apache/nifi/lookup/TestRestLookupService.java b/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/java/org/apache/nifi/lookup/TestRestLookupService.java
new file mode 100644
index 0000000000..5ffdd3d63a
--- /dev/null
+++ b/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/java/org/apache/nifi/lookup/TestRestLookupService.java
@@ -0,0 +1,190 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.lookup;
+
+import okhttp3.mockwebserver.MockResponse;
+import okhttp3.mockwebserver.MockWebServer;
+import okhttp3.mockwebserver.RecordedRequest;
+import org.apache.nifi.reporting.InitializationException;
+import org.apache.nifi.serialization.RecordReader;
+import org.apache.nifi.serialization.RecordReaderFactory;
+import org.apache.nifi.serialization.record.Record;
+import org.apache.nifi.util.NoOpProcessor;
+import org.apache.nifi.util.TestRunner;
+import org.apache.nifi.util.TestRunners;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Timeout;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.io.IOException;
+import java.net.SocketTimeoutException;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Optional;
+
+import static java.net.HttpURLConnection.HTTP_OK;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.when;
+
+@Timeout(10)
+@ExtendWith(MockitoExtension.class)
+class TestRestLookupService {
+
+ private static final String SERVICE_ID = RestLookupService.class.getSimpleName();
+
+ private static final String READER_ID = RecordReaderFactory.class.getSimpleName();
+
+ private static final String ROOT_PATH = "/";
+
+ private static final String GET_METHOD = "GET";
+
+ private static final String POST_METHOD = "POST";
+
+ private static final String POST_BODY = "{}";
+
+ private static final String APPLICATION_JSON = "application/json; charset=utf-8";
+
+ private static final String CONTENT_TYPE_HEADER = "Content-Type";
+
+ private static final String TIMEOUT = "5 s";
+
+ private static final String SHORT_TIMEOUT = "100 ms";
+
+ private MockWebServer mockWebServer;
+
+ private TestRunner runner;
+
+ @Mock
+ private RecordReaderFactory recordReaderFactory;
+
+ @Mock
+ private RecordReader recordReader;
+
+ @Mock
+ private Record record;
+
+ private RestLookupService restLookupService;
+
+ @BeforeEach
+ void setRunner() throws InitializationException {
+ mockWebServer = new MockWebServer();
+
+ runner = TestRunners.newTestRunner(NoOpProcessor.class);
+
+ restLookupService = new RestLookupService();
+
+ when(recordReaderFactory.getIdentifier()).thenReturn(READER_ID);
+ runner.addControllerService(READER_ID, recordReaderFactory);
+ runner.addControllerService(SERVICE_ID, restLookupService);
+
+ final String url = mockWebServer.url(ROOT_PATH).toString();
+ runner.setProperty(restLookupService, RestLookupService.URL, url);
+ runner.setProperty(restLookupService, RestLookupService.RECORD_READER, READER_ID);
+ runner.setProperty(restLookupService, RestLookupService.PROP_CONNECT_TIMEOUT, TIMEOUT);
+ runner.setProperty(restLookupService, RestLookupService.PROP_READ_TIMEOUT, TIMEOUT);
+ }
+
+ @AfterEach
+ void shutdownServer() throws IOException {
+ mockWebServer.shutdown();
+ }
+
+ @Test
+ void testLookupSocketTimeout() {
+ runner.setProperty(restLookupService, RestLookupService.PROP_READ_TIMEOUT, SHORT_TIMEOUT);
+ runner.enableControllerService(restLookupService);
+
+ final LookupFailureException exception = assertThrows(LookupFailureException.class, () -> restLookupService.lookup(Collections.emptyMap()));
+ assertInstanceOf(SocketTimeoutException.class, exception.getCause());
+ }
+
+ @Test
+ void testLookupRecordNotPresent() throws Exception {
+ runner.enableControllerService(restLookupService);
+
+ when(recordReaderFactory.createRecordReader(any(), any(), anyLong(), any())).thenReturn(recordReader);
+ mockWebServer.enqueue(new MockResponse().setResponseCode(HTTP_OK));
+
+ final Optional recordFound = restLookupService.lookup(Collections.emptyMap());
+ assertFalse(recordFound.isPresent());
+
+ assertRecordedRequestFound();
+ }
+
+ @Test
+ void testLookupRecordFound() throws Exception {
+ runner.enableControllerService(restLookupService);
+
+ when(recordReaderFactory.createRecordReader(any(), any(), anyLong(), any())).thenReturn(recordReader);
+ when(recordReader.nextRecord()).thenReturn(record);
+ mockWebServer.enqueue(new MockResponse().setResponseCode(HTTP_OK));
+
+ final Optional recordFound = restLookupService.lookup(Collections.emptyMap());
+ assertTrue(recordFound.isPresent());
+
+ assertRecordedRequestFound();
+ }
+
+ @Test
+ void testLookupRecordFoundPostMethod() throws Exception {
+ runner.enableControllerService(restLookupService);
+
+ when(recordReaderFactory.createRecordReader(any(), any(), anyLong(), any())).thenReturn(recordReader);
+ when(recordReader.nextRecord()).thenReturn(record);
+ mockWebServer.enqueue(new MockResponse().setResponseCode(HTTP_OK));
+
+ final Map coordinates = new LinkedHashMap<>();
+ coordinates.put(RestLookupService.METHOD_KEY, POST_METHOD);
+ coordinates.put(RestLookupService.BODY_KEY, POST_BODY);
+ coordinates.put(RestLookupService.MIME_TYPE_KEY, APPLICATION_JSON);
+
+ final Optional recordFound = restLookupService.lookup(coordinates);
+ assertTrue(recordFound.isPresent());
+
+ assertPostRecordedRequestFound();
+ }
+
+ private void assertRecordedRequestFound() throws InterruptedException {
+ final RecordedRequest request = mockWebServer.takeRequest();
+
+ assertEquals(GET_METHOD, request.getMethod());
+ assertEquals(ROOT_PATH, request.getPath());
+ }
+
+ private void assertPostRecordedRequestFound() throws InterruptedException {
+ final RecordedRequest request = mockWebServer.takeRequest();
+
+ assertEquals(POST_METHOD, request.getMethod());
+ assertEquals(ROOT_PATH, request.getPath());
+ assertEquals(APPLICATION_JSON, request.getHeader(CONTENT_TYPE_HEADER));
+
+ final String body = request.getBody().readString(StandardCharsets.UTF_8);
+ assertEquals(POST_BODY, body);
+ }
+}
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/java/org/apache/nifi/lookup/db/TestDatabaseRecordLookupService.java b/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/java/org/apache/nifi/lookup/db/TestDatabaseRecordLookupService.java
new file mode 100644
index 0000000000..9539dd6772
--- /dev/null
+++ b/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/java/org/apache/nifi/lookup/db/TestDatabaseRecordLookupService.java
@@ -0,0 +1,161 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.lookup.db;
+
+import org.apache.nifi.dbcp.DBCPService;
+import org.apache.nifi.lookup.LookupFailureException;
+import org.apache.nifi.reporting.InitializationException;
+import org.apache.nifi.serialization.record.Record;
+import org.apache.nifi.util.NoOpProcessor;
+import org.apache.nifi.util.TestRunner;
+import org.apache.nifi.util.TestRunners;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.sql.Connection;
+import java.sql.JDBCType;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Optional;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(MockitoExtension.class)
+class TestDatabaseRecordLookupService {
+
+ private static final String SERVICE_ID = DatabaseRecordLookupService.class.getSimpleName();
+
+ private static final String DBCP_SERVICE_ID = DBCPService.class.getSimpleName();
+
+ private static final String TABLE_NAME = "Person";
+
+ private static final String LOOKUP_KEY_COLUMN = "Name";
+
+ private static final String LOOKUP_VALUE_COLUMN = "ID";
+
+ private static final String LOOKUP_VALUE = "12345";
+
+ private static final String LOOKUP_KEY_PROPERTY = "key";
+
+ private static final String LOOKUP_KEY = "First";
+
+ private static final String EXPECTED_STATEMENT = String.format("SELECT %s FROM %s WHERE %s = ?", LOOKUP_VALUE_COLUMN, TABLE_NAME, LOOKUP_KEY_COLUMN);
+
+ private TestRunner runner;
+
+ @Mock
+ private DBCPService dbcpService;
+
+ @Mock
+ private Connection connection;
+
+ @Mock
+ private PreparedStatement preparedStatement;
+
+ @Mock
+ private ResultSet resultSet;
+
+ @Mock
+ private ResultSetMetaData resultSetMetaData;
+
+ @Captor
+ private ArgumentCaptor statementCaptor;
+
+ private DatabaseRecordLookupService lookupService;
+
+ @BeforeEach
+ void setRunner() throws InitializationException {
+ runner = TestRunners.newTestRunner(NoOpProcessor.class);
+
+ when(dbcpService.getIdentifier()).thenReturn(DBCP_SERVICE_ID);
+ runner.addControllerService(DBCP_SERVICE_ID, dbcpService);
+ runner.enableControllerService(dbcpService);
+
+ lookupService = new DatabaseRecordLookupService();
+ runner.addControllerService(SERVICE_ID, lookupService);
+ runner.setProperty(lookupService, DatabaseRecordLookupService.DBCP_SERVICE, DBCP_SERVICE_ID);
+ runner.setProperty(lookupService, DatabaseRecordLookupService.TABLE_NAME, TABLE_NAME);
+ runner.setProperty(lookupService, DatabaseRecordLookupService.LOOKUP_KEY_COLUMN, LOOKUP_KEY_COLUMN);
+ runner.setProperty(lookupService, DatabaseRecordLookupService.LOOKUP_VALUE_COLUMNS, LOOKUP_VALUE_COLUMN);
+ }
+
+ @Test
+ void testLookupEmpty() throws LookupFailureException, SQLException {
+ runner.enableControllerService(lookupService);
+
+ setConnection();
+
+ final Map coordinates = Collections.singletonMap(LOOKUP_KEY_PROPERTY, LOOKUP_KEY);
+ final Optional lookupFound = lookupService.lookup(coordinates);
+
+ assertFalse(lookupFound.isPresent());
+ assertPreparedStatementExpected();
+ }
+
+ @Test
+ void testLookupFound() throws LookupFailureException, SQLException {
+ runner.enableControllerService(lookupService);
+
+ setConnection();
+ setResultSetMetaData();
+
+ when(resultSet.next()).thenReturn(true);
+ when(resultSet.getObject(eq(LOOKUP_VALUE_COLUMN))).thenReturn(LOOKUP_VALUE);
+
+ final Map coordinates = Collections.singletonMap(LOOKUP_KEY_PROPERTY, LOOKUP_KEY);
+ final Optional lookupFound = lookupService.lookup(coordinates);
+
+ assertTrue(lookupFound.isPresent());
+ }
+
+ private void setConnection() throws SQLException {
+ when(dbcpService.getConnection(any())).thenReturn(connection);
+ when(connection.prepareStatement(anyString())).thenReturn(preparedStatement);
+ when(preparedStatement.executeQuery()).thenReturn(resultSet);
+ when(resultSet.getMetaData()).thenReturn(resultSetMetaData);
+ }
+
+ private void setResultSetMetaData() throws SQLException {
+ final int columnIndex = 1;
+ when(resultSetMetaData.getColumnCount()).thenReturn(1);
+ when(resultSetMetaData.getColumnType(eq(columnIndex))).thenReturn(JDBCType.VARCHAR.getVendorTypeNumber());
+ when(resultSetMetaData.getColumnLabel(eq(columnIndex))).thenReturn(LOOKUP_VALUE_COLUMN);
+ when(resultSetMetaData.isNullable(eq(columnIndex))).thenReturn(ResultSetMetaData.columnNoNulls);
+ }
+
+ private void assertPreparedStatementExpected() throws SQLException {
+ verify(connection).prepareStatement(statementCaptor.capture());
+ final String statement = statementCaptor.getValue();
+ assertEquals(EXPECTED_STATEMENT, statement);
+ }
+}
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/java/org/apache/nifi/lookup/db/TestSimpleDatabaseLookupService.java b/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/java/org/apache/nifi/lookup/db/TestSimpleDatabaseLookupService.java
new file mode 100644
index 0000000000..34d700ecc9
--- /dev/null
+++ b/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/java/org/apache/nifi/lookup/db/TestSimpleDatabaseLookupService.java
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.lookup.db;
+
+import org.apache.nifi.dbcp.DBCPService;
+import org.apache.nifi.lookup.LookupFailureException;
+import org.apache.nifi.reporting.InitializationException;
+import org.apache.nifi.util.NoOpProcessor;
+import org.apache.nifi.util.TestRunner;
+import org.apache.nifi.util.TestRunners;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Optional;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(MockitoExtension.class)
+class TestSimpleDatabaseLookupService {
+
+ private static final String SERVICE_ID = SimpleDatabaseLookupService.class.getSimpleName();
+
+ private static final String DBCP_SERVICE_ID = DBCPService.class.getSimpleName();
+
+ private static final String TABLE_NAME = "Person";
+
+ private static final String LOOKUP_KEY_COLUMN = "Name";
+
+ private static final String LOOKUP_VALUE_COLUMN = "ID";
+
+ private static final String LOOKUP_VALUE = "12345";
+
+ private static final String LOOKUP_KEY_PROPERTY = "key";
+
+ private static final String LOOKUP_KEY = "First";
+
+ private static final String EXPECTED_STATEMENT = String.format("SELECT %s FROM %s WHERE %s = ?", LOOKUP_VALUE_COLUMN, TABLE_NAME, LOOKUP_KEY_COLUMN);
+
+ private TestRunner runner;
+
+ @Mock
+ private DBCPService dbcpService;
+
+ @Mock
+ private Connection connection;
+
+ @Mock
+ private PreparedStatement preparedStatement;
+
+ @Mock
+ private ResultSet resultSet;
+
+ @Captor
+ private ArgumentCaptor statementCaptor;
+
+ private SimpleDatabaseLookupService lookupService;
+
+ @BeforeEach
+ void setRunner() throws InitializationException {
+ runner = TestRunners.newTestRunner(NoOpProcessor.class);
+
+ when(dbcpService.getIdentifier()).thenReturn(DBCP_SERVICE_ID);
+ runner.addControllerService(DBCP_SERVICE_ID, dbcpService);
+ runner.enableControllerService(dbcpService);
+
+ lookupService = new SimpleDatabaseLookupService();
+ runner.addControllerService(SERVICE_ID, lookupService);
+ runner.setProperty(lookupService, SimpleDatabaseLookupService.DBCP_SERVICE, DBCP_SERVICE_ID);
+ runner.setProperty(lookupService, SimpleDatabaseLookupService.TABLE_NAME, TABLE_NAME);
+ runner.setProperty(lookupService, SimpleDatabaseLookupService.LOOKUP_KEY_COLUMN, LOOKUP_KEY_COLUMN);
+ runner.setProperty(lookupService, SimpleDatabaseLookupService.LOOKUP_VALUE_COLUMN, LOOKUP_VALUE_COLUMN);
+ }
+
+ @Test
+ void testLookupEmpty() throws LookupFailureException, SQLException {
+ runner.enableControllerService(lookupService);
+
+ setConnection();
+
+ final Map coordinates = Collections.singletonMap(LOOKUP_KEY_PROPERTY, LOOKUP_KEY);
+ final Optional lookupFound = lookupService.lookup(coordinates);
+
+ assertFalse(lookupFound.isPresent());
+ assertPreparedStatementExpected();
+ }
+
+ @Test
+ void testLookupFound() throws LookupFailureException, SQLException {
+ runner.enableControllerService(lookupService);
+
+ setConnection();
+ when(resultSet.next()).thenReturn(true);
+ when(resultSet.getObject(eq(LOOKUP_VALUE_COLUMN))).thenReturn(LOOKUP_VALUE);
+
+ final Map coordinates = Collections.singletonMap(LOOKUP_KEY_PROPERTY, LOOKUP_KEY);
+ final Optional lookupFound = lookupService.lookup(coordinates);
+
+ assertTrue(lookupFound.isPresent());
+ assertEquals(LOOKUP_VALUE, lookupFound.get());
+ assertPreparedStatementExpected();
+ }
+
+ private void setConnection() throws SQLException {
+ when(dbcpService.getConnection(any())).thenReturn(connection);
+ when(connection.prepareStatement(anyString())).thenReturn(preparedStatement);
+ when(preparedStatement.executeQuery()).thenReturn(resultSet);
+ }
+
+ private void assertPreparedStatementExpected() throws SQLException {
+ verify(connection).prepareStatement(statementCaptor.capture());
+ final String statement = statementCaptor.getValue();
+ assertEquals(EXPECTED_STATEMENT, statement);
+ }
+}
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/resources/complex.avsc b/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/resources/complex.avsc
deleted file mode 100644
index 96baf3a8a8..0000000000
--- a/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/resources/complex.avsc
+++ /dev/null
@@ -1,36 +0,0 @@
-{
- "type": "record",
- "name": "ComplexRecord",
- "fields": [
- {
- "name": "top",
- "type": {
- "type": "record",
- "name": "TopRecord",
- "fields": [
- {
- "name": "middle",
- "type": {
- "name": "MiddleRecord",
- "type": "record",
- "fields": [
- {
- "name": "inner",
- "type": {
- "type": "record",
- "name": "InnerRecord",
- "fields": [
- { "name": "username", "type": "string" },
- { "name": "password", "type": "string" },
- { "name": "email", "type": "string" }
- ]
- }
- }
- ]
- }
- }
- ]
- }
- }
- ]
-}
\ No newline at end of file
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/resources/simple.avsc b/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/resources/simple.avsc
deleted file mode 100644
index cb1bd14df9..0000000000
--- a/nifi-nar-bundles/nifi-standard-services/nifi-lookup-services-bundle/nifi-lookup-services/src/test/resources/simple.avsc
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "type": "record",
- "name": "SimpleRecord",
- "fields": [
- {
- "name": "username",
- "type": "string"
- },
- {
- "name": "password",
- "type": "string"
- }
- ]
-}
\ No newline at end of file