mirror of https://github.com/apache/nifi.git
NIFI-12057 Refactored Groovy tests to Java in nifi-lookup-services
Signed-off-by: Joseph Witt <joewitt@apache.org>
This commit is contained in:
parent
ea4c2055d6
commit
591c323f0a
|
@ -127,6 +127,10 @@
|
|||
<version>2.7</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>mockwebserver</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-mock</artifactId>
|
||||
|
@ -154,34 +158,6 @@
|
|||
<artifactId>nifi-schema-registry-service-api</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-servlet</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.derby</groupId>
|
||||
<artifactId>derby</artifactId>
|
||||
<version>${derby.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.derby</groupId>
|
||||
<artifactId>derbytools</artifactId>
|
||||
<version>${derby.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-json</artifactId>
|
||||
<version>${nifi.groovy.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
|
@ -190,8 +166,6 @@
|
|||
<artifactId>apache-rat-plugin</artifactId>
|
||||
<configuration>
|
||||
<excludes combine.children="append">
|
||||
<exclude>src/test/resources/complex.avsc</exclude>
|
||||
<exclude>src/test/resources/simple.avsc</exclude>
|
||||
<exclude>src/test/resources/test.csv</exclude>
|
||||
<exclude>src/test/resources/test_sep_escape_comment.csv</exclude>
|
||||
<exclude>src/test/resources/test_Windows-31J.csv</exclude>
|
||||
|
|
|
@ -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<RecordField> 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<String,Object>() {{
|
||||
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<String, Object> getCoordinates(String mimeType, String method) {
|
||||
def retVal = [:] as Map<String, Object>
|
||||
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()
|
||||
}
|
||||
}
|
|
@ -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<PropertyDescriptor> getSupportedPropertyDescriptors() {
|
||||
List<PropertyDescriptor> propDescs = new ArrayList<>()
|
||||
propDescs.add(CLIENT_SERVICE)
|
||||
return propDescs
|
||||
}
|
||||
}
|
|
@ -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<Record> 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<String, String> 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<Record> 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<Record> property2 = lookupService.lookup(Collections.singletonMap("key", "1"))
|
||||
assertEquals(1, property2.get().getAsInt("VAL1"))
|
||||
assertEquals("World", property2.get().getAsString("VAL2"))
|
||||
|
||||
// Key not found
|
||||
final Optional<Record> 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<Record> property1 = lookupService.lookup(Collections.singletonMap("key", "0"))
|
||||
assertNull(property1.get().getAsInt("VAL1"), "Should be null but is not")
|
||||
|
||||
final Optional<Record> property2 = lookupService.lookup(Collections.singletonMap("key", "1"))
|
||||
assertEquals(1, property2.get().getAsInt("VAL1"))
|
||||
|
||||
// Key not found
|
||||
final Optional<Record> 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<Record> property1 = lookupService.lookup(Collections.singletonMap("key", "1"))
|
||||
assertEquals(1, property1.get().getAsInt("VAL1"))
|
||||
assertEquals("World", property1.get().getAsString("VAL2"))
|
||||
|
||||
final Optional<Record> property2 = lookupService.lookup(Collections.singletonMap("key", "1"))
|
||||
assertEquals(1, property2.get().getAsInt("VAL1"))
|
||||
assertEquals("World", property2.get().getAsString("VAL2"))
|
||||
|
||||
final Optional<Record> property3 = lookupService.lookup(Collections.singletonMap("key", "0"))
|
||||
assertNull(property3.get().getAsInt("VAL1"))
|
||||
assertEquals("Hello", property3.get().getAsString("VAL2"))
|
||||
|
||||
final Optional<Record> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<Record> 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<String, String> 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<String> property1 = lookupService.lookup(Collections.singletonMap("key", "0"))
|
||||
assertFalse(property1.isPresent())
|
||||
// Key not found
|
||||
final Optional<String> 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<String> 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<String> property1 = lookupService.lookup(Collections.singletonMap("key", "1"))
|
||||
assertEquals("1", property1.get())
|
||||
final Optional<String> 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<String> property2 = lookupService.lookup(Collections.singletonMap("key", "1"))
|
||||
assertEquals("World", property2.get())
|
||||
|
||||
final Optional<String> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<String, List<String>> getHeaders() {
|
||||
headers.toMultimap()
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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"
|
||||
])
|
||||
))
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<Record> 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<Record> 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<String, Object> 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<Record> 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);
|
||||
}
|
||||
}
|
|
@ -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<String> 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<String, Object> coordinates = Collections.singletonMap(LOOKUP_KEY_PROPERTY, LOOKUP_KEY);
|
||||
final Optional<Record> 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<String, Object> coordinates = Collections.singletonMap(LOOKUP_KEY_PROPERTY, LOOKUP_KEY);
|
||||
final Optional<Record> 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);
|
||||
}
|
||||
}
|
|
@ -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<String> 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<String, Object> coordinates = Collections.singletonMap(LOOKUP_KEY_PROPERTY, LOOKUP_KEY);
|
||||
final Optional<String> 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<String, Object> coordinates = Collections.singletonMap(LOOKUP_KEY_PROPERTY, LOOKUP_KEY);
|
||||
final Optional<String> 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);
|
||||
}
|
||||
}
|
|
@ -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" }
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
{
|
||||
"type": "record",
|
||||
"name": "SimpleRecord",
|
||||
"fields": [
|
||||
{
|
||||
"name": "username",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "password",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue