Repository: sqoop Updated Branches: refs/heads/sqoop2 d68737ecf -> 598607cde
SQOOP-2246: Sqoop2: Use jdbcProperties when creating database connection in GenericJDBCExecutor (Jarek Jarcec Cecho via Abraham Elmahrek) Project: http://git-wip-us.apache.org/repos/asf/sqoop/repo Commit: http://git-wip-us.apache.org/repos/asf/sqoop/commit/598607cd Tree: http://git-wip-us.apache.org/repos/asf/sqoop/tree/598607cd Diff: http://git-wip-us.apache.org/repos/asf/sqoop/diff/598607cd Branch: refs/heads/sqoop2 Commit: 598607cde659533f3290da34ddc78daf90c68fe2 Parents: d68737e Author: Abraham Elmahrek <[email protected]> Authored: Mon Mar 23 16:35:40 2015 -0700 Committer: Abraham Elmahrek <[email protected]> Committed: Mon Mar 23 16:35:40 2015 -0700 ---------------------------------------------------------------------- .../connector/jdbc/GenericJdbcExecutor.java | 72 +++++++++++++++++--- .../connector/jdbc/GenericJdbcExtractor.java | 9 +-- .../jdbc/GenericJdbcFromInitializer.java | 17 +---- .../sqoop/connector/jdbc/GenericJdbcLoader.java | 6 +- .../connector/jdbc/GenericJdbcToDestroyer.java | 9 +-- .../jdbc/GenericJdbcToInitializer.java | 16 +---- .../connector/jdbc/GenericJdbcExecutorTest.java | 14 +++- .../jdbc/GenericJdbcTestConstants.java | 17 +++++ .../sqoop/connector/jdbc/TestExtractor.java | 3 +- .../connector/jdbc/TestFromInitializer.java | 3 +- .../apache/sqoop/connector/jdbc/TestLoader.java | 3 +- .../sqoop/connector/jdbc/TestToInitializer.java | 3 +- 12 files changed, 105 insertions(+), 67 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/sqoop/blob/598607cd/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcExecutor.java ---------------------------------------------------------------------- diff --git a/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcExecutor.java b/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcExecutor.java index 5af34a5..a5cd715 100644 --- a/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcExecutor.java +++ b/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcExecutor.java @@ -19,9 +19,11 @@ package org.apache.sqoop.connector.jdbc; import org.apache.log4j.Logger; import org.apache.sqoop.common.SqoopException; +import org.apache.sqoop.connector.jdbc.configuration.LinkConfig; import org.apache.sqoop.error.code.GenericJdbcConnectorError; import org.apache.sqoop.schema.Schema; import org.apache.sqoop.schema.type.Column; +import org.apache.sqoop.utils.ClassUtils; import org.joda.time.DateTime; import org.joda.time.LocalDate; import org.joda.time.LocalTime; @@ -35,25 +37,75 @@ import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import java.sql.Timestamp; +import java.util.Properties; +/** + * Database executor that is based on top of JDBC spec. + */ public class GenericJdbcExecutor { - private static final Logger LOG = - Logger.getLogger(GenericJdbcExecutor.class); + private static final Logger LOG = Logger.getLogger(GenericJdbcExecutor.class); + + /** + * Keys for JDBC properties + * + * We're following JDBC 4 spec: + * http://download.oracle.com/otn-pub/jcp/jdbc-4_1-mrel-spec/jdbc4.1-fr-spec.pdf?AuthParam=1426813649_0155f473b02dbca8bbd417dd061669d7 + */ + public static final String JDBC_PROPERTY_USERNAME = "user"; + public static final String JDBC_PROPERTY_PASSWORD = "password"; + + /** + * User configured link with credentials and such + */ + private LinkConfig linkConfig; + /** + * Internal connection object (we'll hold to it) + */ private Connection connection; + + /** + * Prepare statement + */ private PreparedStatement preparedStatement; - public GenericJdbcExecutor(String driver, String url, - String username, String password) { - try { - Class.forName(driver); - connection = DriverManager.getConnection(url, username, password); + public GenericJdbcExecutor(LinkConfig linkConfig) { + assert linkConfig != null; + assert linkConfig.connectionString != null; - } catch (ClassNotFoundException e) { - throw new SqoopException( - GenericJdbcConnectorError.GENERIC_JDBC_CONNECTOR_0000, driver, e); + // Persist link configuration for future use + this.linkConfig = linkConfig; + + // Load/register the JDBC driver to JVM + Class driverClass = ClassUtils.loadClass(linkConfig.jdbcDriver); + if(driverClass == null) { + throw new SqoopException(GenericJdbcConnectorError.GENERIC_JDBC_CONNECTOR_0000, linkConfig.jdbcDriver); + } + + // Properties that we will use for the connection + Properties properties = new Properties(); + if(linkConfig.jdbcProperties != null) { + properties.putAll(linkConfig.jdbcProperties); + } + // Propagate username and password to the properties + // + // DriverManager have two relevant API for us: + // * getConnection(url, username, password) + // * getConnection(url, properties) + // As we have to use properties, we need to use the later + // method and hence we have to persist the credentials there. + if(linkConfig.username != null) { + properties.put(JDBC_PROPERTY_USERNAME, linkConfig.username); + } + if(linkConfig.password != null) { + properties.put(JDBC_PROPERTY_PASSWORD, linkConfig.password); + } + + // Finally create the connection + try { + connection = DriverManager.getConnection(linkConfig.connectionString, properties); } catch (SQLException e) { logSQLException(e); throw new SqoopException(GenericJdbcConnectorError.GENERIC_JDBC_CONNECTOR_0001, e); http://git-wip-us.apache.org/repos/asf/sqoop/blob/598607cd/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcExtractor.java ---------------------------------------------------------------------- diff --git a/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcExtractor.java b/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcExtractor.java index 3287e16..63046c0 100644 --- a/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcExtractor.java +++ b/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcExtractor.java @@ -41,13 +41,8 @@ public class GenericJdbcExtractor extends Extractor<LinkConfiguration, FromJobCo private long rowsRead = 0; @Override - public void extract(ExtractorContext context, LinkConfiguration linkConfig, - FromJobConfiguration fromJobConfig, GenericJdbcPartition partition) { - String driver = linkConfig.linkConfig.jdbcDriver; - String url = linkConfig.linkConfig.connectionString; - String username = linkConfig.linkConfig.username; - String password = linkConfig.linkConfig.password; - GenericJdbcExecutor executor = new GenericJdbcExecutor(driver, url, username, password); + public void extract(ExtractorContext context, LinkConfiguration linkConfig, FromJobConfiguration fromJobConfig, GenericJdbcPartition partition) { + GenericJdbcExecutor executor = new GenericJdbcExecutor(linkConfig.linkConfig); String query = context.getString(GenericJdbcConnectorConstants.CONNECTOR_JDBC_FROM_DATA_SQL); String conditions = partition.getConditions(); http://git-wip-us.apache.org/repos/asf/sqoop/blob/598607cd/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcFromInitializer.java ---------------------------------------------------------------------- diff --git a/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcFromInitializer.java b/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcFromInitializer.java index 6ad2cab..df517bd 100644 --- a/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcFromInitializer.java +++ b/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcFromInitializer.java @@ -47,7 +47,8 @@ public class GenericJdbcFromInitializer extends Initializer<LinkConfiguration, F @Override public void initialize(InitializerContext context, LinkConfiguration linkConfig, FromJobConfiguration fromJobConfig) { - configureJdbcProperties(context.getContext(), linkConfig, fromJobConfig); + executor = new GenericJdbcExecutor(linkConfig.linkConfig); + try { configurePartitionProperties(context.getContext(), linkConfig, fromJobConfig); configureTableProperties(context.getContext(), linkConfig, fromJobConfig); @@ -67,7 +68,7 @@ public class GenericJdbcFromInitializer extends Initializer<LinkConfiguration, F @Override public Schema getSchema(InitializerContext context, LinkConfiguration linkConfig, FromJobConfiguration fromJobConfig) { - configureJdbcProperties(context.getContext(), linkConfig, fromJobConfig); + executor = new GenericJdbcExecutor(linkConfig.linkConfig); String schemaName = fromJobConfig.fromJobConfig.tableName; if(schemaName == null) { @@ -115,18 +116,6 @@ public class GenericJdbcFromInitializer extends Initializer<LinkConfiguration, F } } - private void configureJdbcProperties(MutableContext context, LinkConfiguration linkConfig, FromJobConfiguration fromJobConfig) { - String driver = linkConfig.linkConfig.jdbcDriver; - String url = linkConfig.linkConfig.connectionString; - String username = linkConfig.linkConfig.username; - String password = linkConfig.linkConfig.password; - - assert driver != null; - assert url != null; - - executor = new GenericJdbcExecutor(driver, url, username, password); - } - private void configurePartitionProperties(MutableContext context, LinkConfiguration linkConfig, FromJobConfiguration jobConf) throws SQLException { // Assertions that should be valid (verified via validator) assert (jobConf.fromJobConfig.tableName != null && jobConf.fromJobConfig.sql == null) || http://git-wip-us.apache.org/repos/asf/sqoop/blob/598607cd/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcLoader.java ---------------------------------------------------------------------- diff --git a/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcLoader.java b/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcLoader.java index ab1ac86..22b726e 100644 --- a/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcLoader.java +++ b/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcLoader.java @@ -32,11 +32,7 @@ public class GenericJdbcLoader extends Loader<LinkConfiguration, ToJobConfigurat @Override public void load(LoaderContext context, LinkConfiguration linkConfig, ToJobConfiguration toJobConfig) throws Exception{ - String driver = linkConfig.linkConfig.jdbcDriver; - String url = linkConfig.linkConfig.connectionString; - String username = linkConfig.linkConfig.username; - String password = linkConfig.linkConfig.password; - GenericJdbcExecutor executor = new GenericJdbcExecutor(driver, url, username, password); + GenericJdbcExecutor executor = new GenericJdbcExecutor(linkConfig.linkConfig); executor.setAutoCommit(false); String sql = context.getString(GenericJdbcConnectorConstants.CONNECTOR_JDBC_TO_DATA_SQL); executor.beginBatch(sql); http://git-wip-us.apache.org/repos/asf/sqoop/blob/598607cd/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcToDestroyer.java ---------------------------------------------------------------------- diff --git a/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcToDestroyer.java b/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcToDestroyer.java index e381651..b9f7e7f 100644 --- a/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcToDestroyer.java +++ b/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcToDestroyer.java @@ -41,13 +41,8 @@ public class GenericJdbcToDestroyer extends Destroyer<LinkConfiguration, ToJobCo } } - private void moveDataToDestinationTable(LinkConfiguration linkConfig, - boolean success, String stageTableName, String tableName) { - GenericJdbcExecutor executor = - new GenericJdbcExecutor(linkConfig.linkConfig.jdbcDriver, - linkConfig.linkConfig.connectionString, - linkConfig.linkConfig.username, - linkConfig.linkConfig.password); + private void moveDataToDestinationTable(LinkConfiguration linkConfig, boolean success, String stageTableName, String tableName) { + GenericJdbcExecutor executor = new GenericJdbcExecutor(linkConfig.linkConfig); try { if(success) { LOG.info("Job completed, transferring data from stage fromTable to " + http://git-wip-us.apache.org/repos/asf/sqoop/blob/598607cd/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcToInitializer.java ---------------------------------------------------------------------- diff --git a/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcToInitializer.java b/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcToInitializer.java index 400c0f2..c2515a5 100644 --- a/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcToInitializer.java +++ b/connector/connector-generic-jdbc/src/main/java/org/apache/sqoop/connector/jdbc/GenericJdbcToInitializer.java @@ -44,7 +44,7 @@ public class GenericJdbcToInitializer extends Initializer<LinkConfiguration, ToJ @Override public void initialize(InitializerContext context, LinkConfiguration linkConfig, ToJobConfiguration toJobConfig) { - configureJdbcProperties(context.getContext(), linkConfig, toJobConfig); + executor = new GenericJdbcExecutor(linkConfig.linkConfig); try { configureTableProperties(context.getContext(), linkConfig, toJobConfig); } finally { @@ -61,7 +61,7 @@ public class GenericJdbcToInitializer extends Initializer<LinkConfiguration, ToJ @Override public Schema getSchema(InitializerContext context, LinkConfiguration linkConfig, ToJobConfiguration toJobConfig) { - configureJdbcProperties(context.getContext(), linkConfig, toJobConfig); + executor = new GenericJdbcExecutor(linkConfig.linkConfig); String schemaName = toJobConfig.toJobConfig.tableName; @@ -109,18 +109,6 @@ public class GenericJdbcToInitializer extends Initializer<LinkConfiguration, ToJ } } - private void configureJdbcProperties(MutableContext context, LinkConfiguration linkConfig, ToJobConfiguration toJobConfig) { - String driver = linkConfig.linkConfig.jdbcDriver; - String url = linkConfig.linkConfig.connectionString; - String username = linkConfig.linkConfig.username; - String password = linkConfig.linkConfig.password; - - assert driver != null; - assert url != null; - - executor = new GenericJdbcExecutor(driver, url, username, password); - } - private void configureTableProperties(MutableContext context, LinkConfiguration linkConfig, ToJobConfiguration toJobConfig) { String dataSql; http://git-wip-us.apache.org/repos/asf/sqoop/blob/598607cd/connector/connector-generic-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/GenericJdbcExecutorTest.java ---------------------------------------------------------------------- diff --git a/connector/connector-generic-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/GenericJdbcExecutorTest.java b/connector/connector-generic-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/GenericJdbcExecutorTest.java index c3b8171..01e77a3 100644 --- a/connector/connector-generic-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/GenericJdbcExecutorTest.java +++ b/connector/connector-generic-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/GenericJdbcExecutorTest.java @@ -17,6 +17,8 @@ */ package org.apache.sqoop.connector.jdbc; +import org.apache.sqoop.common.SqoopException; +import org.apache.sqoop.connector.jdbc.configuration.LinkConfig; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @@ -33,8 +35,7 @@ public class GenericJdbcExecutorTest { public GenericJdbcExecutorTest() { table = getClass().getSimpleName().toUpperCase(); emptyTable = table + "_EMPTY"; - executor = new GenericJdbcExecutor(GenericJdbcTestConstants.DRIVER, - GenericJdbcTestConstants.URL, null, null); + executor = new GenericJdbcExecutor(GenericJdbcTestConstants.LINK_CONFIG); } @BeforeMethod(alwaysRun = true) @@ -59,6 +60,15 @@ public class GenericJdbcExecutorTest { } } + @Test(expectedExceptions = SqoopException.class) + public void testUnknownDriver() { + LinkConfig linkConfig = new LinkConfig(); + linkConfig.jdbcDriver = "net.jarcec.driver.MyAwesomeDatabase"; + linkConfig.connectionString = "jdbc:awesome:"; + + new GenericJdbcExecutor(linkConfig); + } + @Test public void testDeleteTableData() throws Exception { executor.deleteTableData(table); http://git-wip-us.apache.org/repos/asf/sqoop/blob/598607cd/connector/connector-generic-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/GenericJdbcTestConstants.java ---------------------------------------------------------------------- diff --git a/connector/connector-generic-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/GenericJdbcTestConstants.java b/connector/connector-generic-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/GenericJdbcTestConstants.java index 67ba5bf..5a5e9ce 100644 --- a/connector/connector-generic-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/GenericJdbcTestConstants.java +++ b/connector/connector-generic-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/GenericJdbcTestConstants.java @@ -17,9 +17,26 @@ */ package org.apache.sqoop.connector.jdbc; +import org.apache.sqoop.connector.jdbc.configuration.LinkConfig; + public class GenericJdbcTestConstants { + /** + * Testing Driver + */ public static final String DRIVER = "org.apache.derby.jdbc.EmbeddedDriver"; + + /** + * Testing database (in memory derby) + */ public static final String URL = "jdbc:derby:memory:TESTDB;create=true"; + /** + * Test link configuration + */ + public static final LinkConfig LINK_CONFIG = new LinkConfig(); + static { + LINK_CONFIG.jdbcDriver = DRIVER; + LINK_CONFIG.connectionString = URL; + } } http://git-wip-us.apache.org/repos/asf/sqoop/blob/598607cd/connector/connector-generic-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/TestExtractor.java ---------------------------------------------------------------------- diff --git a/connector/connector-generic-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/TestExtractor.java b/connector/connector-generic-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/TestExtractor.java index 803d37b..dd6bb27 100644 --- a/connector/connector-generic-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/TestExtractor.java +++ b/connector/connector-generic-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/TestExtractor.java @@ -59,8 +59,7 @@ public class TestExtractor { @BeforeMethod(alwaysRun = true) public void setUp() { - executor = new GenericJdbcExecutor(GenericJdbcTestConstants.DRIVER, - GenericJdbcTestConstants.URL, null, null); + executor = new GenericJdbcExecutor(GenericJdbcTestConstants.LINK_CONFIG); if (!executor.existTable(tableName)) { executor.executeUpdate("CREATE TABLE " http://git-wip-us.apache.org/repos/asf/sqoop/blob/598607cd/connector/connector-generic-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/TestFromInitializer.java ---------------------------------------------------------------------- diff --git a/connector/connector-generic-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/TestFromInitializer.java b/connector/connector-generic-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/TestFromInitializer.java index e9c8d41..c80fd32 100644 --- a/connector/connector-generic-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/TestFromInitializer.java +++ b/connector/connector-generic-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/TestFromInitializer.java @@ -61,8 +61,7 @@ public class TestFromInitializer { @BeforeMethod(alwaysRun = true) public void setUp() { - executor = new GenericJdbcExecutor(GenericJdbcTestConstants.DRIVER, - GenericJdbcTestConstants.URL, null, null); + executor = new GenericJdbcExecutor(GenericJdbcTestConstants.LINK_CONFIG); String fullTableName = executor.delimitIdentifier(schemaName) + "." + executor.delimitIdentifier(tableName); if (!executor.existTable(tableName)) { http://git-wip-us.apache.org/repos/asf/sqoop/blob/598607cd/connector/connector-generic-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/TestLoader.java ---------------------------------------------------------------------- diff --git a/connector/connector-generic-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/TestLoader.java b/connector/connector-generic-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/TestLoader.java index 2479f89..3a73691 100644 --- a/connector/connector-generic-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/TestLoader.java +++ b/connector/connector-generic-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/TestLoader.java @@ -69,8 +69,7 @@ public class TestLoader { @BeforeMethod(alwaysRun = true) public void setUp() { - executor = new GenericJdbcExecutor(GenericJdbcTestConstants.DRIVER, - GenericJdbcTestConstants.URL, null, null); + executor = new GenericJdbcExecutor(GenericJdbcTestConstants.LINK_CONFIG); if (!executor.existTable(tableName)) { executor.executeUpdate("CREATE TABLE " http://git-wip-us.apache.org/repos/asf/sqoop/blob/598607cd/connector/connector-generic-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/TestToInitializer.java ---------------------------------------------------------------------- diff --git a/connector/connector-generic-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/TestToInitializer.java b/connector/connector-generic-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/TestToInitializer.java index a61de7d..17bac77 100644 --- a/connector/connector-generic-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/TestToInitializer.java +++ b/connector/connector-generic-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/TestToInitializer.java @@ -59,8 +59,7 @@ public class TestToInitializer { @BeforeMethod(alwaysRun = true) public void setUp() { - executor = new GenericJdbcExecutor(GenericJdbcTestConstants.DRIVER, - GenericJdbcTestConstants.URL, null, null); + executor = new GenericJdbcExecutor(GenericJdbcTestConstants.LINK_CONFIG); String fullTableName = executor.delimitIdentifier(schemaName) + "." + executor.delimitIdentifier(tableName); if (!executor.existTable(tableName)) {
