/* (c) 2017 Open Source Geospatial Foundation - all rights reserved * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.opensearch.eo; import static org.geoserver.opensearch.eo.store.OpenSearchAccess.EO_NAMESPACE; import static org.geoserver.opensearch.eo.store.OpenSearchAccess.ProductClass.*; import static org.hamcrest.Matchers.equalToIgnoringCase; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.Serializable; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.geoserver.opensearch.eo.store.JDBCOpenSearchAccess; import org.geoserver.opensearch.eo.store.OpenSearchAccess; import org.geotools.data.DataAccessFinder; import org.geotools.data.DataStoreFinder; import org.geotools.data.Transaction; import org.geotools.feature.NameImpl; import org.geotools.jdbc.JDBCDataStore; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.opengis.feature.type.FeatureType; import org.opengis.feature.type.Name; import org.opengis.feature.type.PropertyDescriptor; public class JDBCOpenSearchAccessTest { public static final String TEST_NAMESPACE = "http://www.test.com/os/eo"; private static JDBCDataStore h2; private static OpenSearchAccess osAccess; @BeforeClass public static void setupStore() throws IOException, SQLException { Map<String, Serializable> params = new HashMap<>(); params.put("dbtype", "h2"); File dbFolder = new File("./target/oseo_db_store_test"); FileUtils.deleteQuietly(dbFolder); dbFolder.mkdir(); File dbFile = new File(dbFolder, "oseo_db_store_test"); params.put("database", dbFile.getAbsolutePath()); h2 = (JDBCDataStore) DataStoreFinder.getDataStore(params); JDBCOpenSearchAccessTest.populateTestDatabase(h2); Name name = new NameImpl("test", "jdbcStore"); SerializableDefaultRepository repository = new SerializableDefaultRepository(); repository.register(name, h2); // create the OpenSeach wrapper store params = new HashMap<>(); params.put("dbtype", "opensearch-eo-jdbc"); params.put("store", "test:jdbcStore"); params.put("namespace", TEST_NAMESPACE); params.put("repository", repository); osAccess = (OpenSearchAccess) DataAccessFinder.getDataStore(params); } public static void populateTestDatabase(JDBCDataStore h2) throws SQLException, IOException { try (Connection conn = h2.getConnection(Transaction.AUTO_COMMIT); Statement st = conn.createStatement()) { // setup for fast import // SET CACHE_SIZE (a large cache is faster) st.execute("SET LOG 0"); st.execute("SET LOCK_MODE 0 "); st.execute("SET UNDO_LOG 0"); st.execute("SET CACHE_SIZE 512000"); JDBCOpenSearchAccessTest.createTables(conn); JDBCOpenSearchAccessTest.populateCollections(conn); JDBCOpenSearchAccessTest.populateProducts(conn); } } @AfterClass public static void tearDownStore() { osAccess.dispose(); h2.dispose(); } private static List<String> loadScriptCommands(String scriptLocation) throws IOException { // grab all non comment, non empty lines try (InputStream is = JDBCOpenSearchAccess.class.getResourceAsStream(scriptLocation)) { List<String> lines = IOUtils.readLines(is).stream().map(l -> l.trim()) .filter(l -> !l.startsWith("--") && !l.isEmpty()).collect(Collectors.toList()); // regroup them into statements List<String> statements = new ArrayList<String>(); String buffer = null; for (String line : lines) { if (buffer == null) { buffer = line; } else { buffer = buffer + "\n" + line; } if (line.trim().endsWith(";")) { statements.add(buffer); buffer = null; } } return statements; } } /** * Takes the postgis.sql creation script, adapts it and runs it on H2 */ static void createTables(Connection conn) throws SQLException, IOException { List<String> statements = loadScriptCommands("/postgis.sql"); try (Statement st = conn.createStatement();) { for (String statement : statements) { /* Skip statements H2 does not support */ if (statement.contains("GIST") || statement.contains("create extension")) { continue; } if (statement.contains("geography(Polygon, 4326)")) { statement = statement.replace("geography(Polygon, 4326)", "POLYGON"); } st.execute(statement); } // add spatial indexes st.execute( "CALL AddGeometryColumn(SCHEMA(), 'COLLECTION', 'footprint', 4326, 'POLYGON', 2)"); st.execute("CALL CreateSpatialIndex(SCHEMA(), 'COLLECTION', 'footprint', 4326)"); st.execute( "CALL AddGeometryColumn(SCHEMA(), 'PRODUCT', 'footprint', 4326, 'POLYGON', 2)"); st.execute("CALL CreateSpatialIndex(SCHEMA(), 'PRODUCT', 'footprint', 4326)"); } } /** * Adds the collection data into the H2 database */ static void populateCollections(Connection conn) throws SQLException, IOException { runScript("/collection_h2_data.sql", conn); } /** * Adds the product data into the H2 database */ static void populateProducts(Connection conn) throws SQLException, IOException { runScript("/product_h2_data.sql", conn); } private static void runScript(String script, Connection conn) throws IOException, SQLException { List<String> statements = loadScriptCommands(script); try (Statement st = conn.createStatement();) { for (String statement : statements) { st.execute(statement); } } } @Test public void testCollectionFeatureType() throws Exception { // check expected name FeatureType schema = osAccess.getCollectionSource().getSchema(); Name name = schema.getName(); assertEquals(TEST_NAMESPACE, name.getNamespaceURI()); assertThat(name.getLocalPart(), equalToIgnoringCase("collection")); // test the schema assertPropertyNamespace(schema, "wavelength", EO_NAMESPACE); } @Test public void testProductFeatureType() throws Exception { // check expected name FeatureType schema = osAccess.getProductSource().getSchema(); Name name = schema.getName(); assertEquals(TEST_NAMESPACE, name.getNamespaceURI()); assertThat(name.getLocalPart(), equalToIgnoringCase("product")); // get the schema assertPropertyNamespace(schema, "cloudCover", OPTICAL.getNamespace()); assertPropertyNamespace(schema, "track", EOP_GENERIC.getNamespace()); assertPropertyNamespace(schema, "polarisationMode", RADAR.getNamespace()); } private void assertPropertyNamespace(FeatureType schema, String name, String namespaceURI) { PropertyDescriptor wl = schema.getDescriptor(name); assertNotNull(wl); assertEquals(namespaceURI, wl.getName().getNamespaceURI()); } }