Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions hadoop-hdds/common/src/main/resources/ozone-default.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2354,7 +2354,7 @@
</property>
<property>
<name>ozone.recon.sql.db.driver</name>
<value>org.sqlite.JDBC</value>
<value>org.apache.derby.jdbc.EmbeddedDriver</value>
<tag>OZONE, RECON</tag>
<description>
Database driver class name available on the
Expand All @@ -2363,7 +2363,7 @@
</property>
<property>
<name>ozone.recon.sql.db.jdbc.url</name>
<value>jdbc:sqlite:${ozone.recon.db.dir}/ozone_recon_sqlite.db</value>
<value>jdbc:derby:${ozone.recon.db.dir}/ozone_recon_derby.db</value>
<tag>OZONE, RECON</tag>
<description>
Ozone Recon SQL database jdbc url.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -804,8 +804,8 @@ protected void configureRecon() throws IOException {
.getAbsolutePath());
conf.set(OZONE_RECON_SCM_DB_DIR,
tempNewFolder.getAbsolutePath());
conf.set(OZONE_RECON_SQL_DB_JDBC_URL, "jdbc:sqlite:" +
tempNewFolder.getAbsolutePath() + "/ozone_recon_sqlite.db");
conf.set(OZONE_RECON_SQL_DB_JDBC_URL, "jdbc:derby:" +
tempNewFolder.getAbsolutePath() + "/ozone_recon_derby.db");

conf.set(OZONE_RECON_HTTP_ADDRESS_KEY, "0.0.0.0:0");
conf.set(OZONE_RECON_DATANODE_ADDRESS_KEY, "0.0.0.0:0");
Expand Down
6 changes: 3 additions & 3 deletions hadoop-ozone/recon-codegen/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@
<artifactId>hadoop-ozone-common</artifactId>
</dependency>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.25.2</version>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<version>10.14.2.0</version>
</dependency>
<dependency>
<groupId>com.google.inject.extensions</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,19 @@
*/
package org.hadoop.ozone.recon.codegen;

import static org.hadoop.ozone.recon.codegen.SqlDbUtils.DERBY_DRIVER_CLASS;
import static org.hadoop.ozone.recon.codegen.SqlDbUtils.createNewDerbyDatabase;

import java.io.File;
import java.nio.file.Paths;
import java.sql.SQLException;
import java.util.Set;

import javax.sql.DataSource;

import org.apache.commons.io.FileUtils;
import org.apache.derby.jdbc.EmbeddedDataSource;
import org.apache.hadoop.util.Time;
import org.hadoop.ozone.recon.schema.ReconSchemaDefinition;
import org.jooq.codegen.GenerationTool;
import org.jooq.meta.jaxb.Configuration;
Expand All @@ -35,7 +41,6 @@
import org.jooq.meta.jaxb.Target;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sqlite.SQLiteDataSource;

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
Expand All @@ -55,10 +60,11 @@ public class JooqCodeGenerator {
private static final Logger LOG =
LoggerFactory.getLogger(JooqCodeGenerator.class);

private static final String SQLITE_DB =
System.getProperty("java.io.tmpdir") + "/recon-generated-schema";
private static final String JDBC_URL = "jdbc:sqlite:" + SQLITE_DB;

private static final String DB = Paths.get(
System.getProperty("java.io.tmpdir"),
"recon-generated-schema-" + Time.monotonicNow()).toString();
public static final String RECON_SCHEMA_NAME = "RECON";
private static final String JDBC_URL = "jdbc:derby:" + DB;
private final Set<ReconSchemaDefinition> allDefinitions;

@Inject
Expand All @@ -82,20 +88,18 @@ private void generateSourceCode(String outputDir) throws Exception {
Configuration configuration =
new Configuration()
.withJdbc(new Jdbc()
.withDriver("org.sqlite.JDBC")
.withDriver(DERBY_DRIVER_CLASS)
.withUrl(JDBC_URL)
.withUser("sa")
.withPassword("sa"))
.withSchema(RECON_SCHEMA_NAME))
.withGenerator(new Generator()
.withDatabase(new Database()
.withName("org.jooq.meta.sqlite.SQLiteDatabase")
.withName("org.jooq.meta.derby.DerbyDatabase")
.withOutputSchemaToDefault(true)
.withIncludeTables(true)
.withIncludePrimaryKeys(true))
.withGenerate(new Generate()
.withDaos(true)
.withEmptyCatalogs(true)
.withEmptySchemas(true))
.withEmptyCatalogs(true))
.withStrategy(new Strategy().withName(
"org.hadoop.ozone.recon.codegen.TableNamingStrategy"))
.withTarget(new Target()
Expand All @@ -109,20 +113,25 @@ private void generateSourceCode(String outputDir) throws Exception {
* Provider for embedded datasource.
*/
static class LocalDataSourceProvider implements Provider<DataSource> {
private static SQLiteDataSource db;

private static EmbeddedDataSource dataSource;
static {
db = new SQLiteDataSource();
db.setUrl(JDBC_URL);
try {
createNewDerbyDatabase(JDBC_URL, RECON_SCHEMA_NAME);
} catch (Exception e) {
LOG.error("Error creating Recon Derby DB.", e);
}
dataSource = new EmbeddedDataSource();
dataSource.setDatabaseName(DB);
dataSource.setUser(RECON_SCHEMA_NAME);
}

@Override
public DataSource get() {
return db;
return dataSource;
}

static void cleanup() {
FileUtils.deleteQuietly(new File(SQLITE_DB));
FileUtils.deleteQuietly(new File(DB));
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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.hadoop.ozone.recon.codegen;

import org.apache.hadoop.hdds.conf.Config;
import org.apache.hadoop.hdds.conf.ConfigGroup;
import org.apache.hadoop.hdds.conf.ConfigTag;
import org.apache.hadoop.hdds.conf.ConfigType;

/**
* The configuration class for the Recon SQL DB.
*/
@ConfigGroup(prefix = "ozone.recon.sql.db")
public class ReconSqlDbConfig {

@Config(key = "jooq.dialect",
type = ConfigType.STRING,
defaultValue = "",
tags = { ConfigTag.STORAGE, ConfigTag.RECON, ConfigTag.OZONE },
description = "Recon internally uses Jooq to talk to its SQL DB. By " +
"default, we support Derby and Sqlite out of the box. Please refer " +
"to https://www.jooq.org/javadoc/latest/org" +
".jooq/org/jooq/SQLDialect.html to specify different dialect."
)
private String sqlDbDialect;

public String getSqlDbDialect() {
return sqlDbDialect;
}

public void setSqlDbDialect(String sqlDbDialect) {
this.sqlDbDialect = sqlDbDialect;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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.hadoop.ozone.recon.codegen;

import static org.jooq.impl.DSL.count;

import java.io.IOException;
import java.io.OutputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.function.BiPredicate;

import org.jooq.exception.DataAccessException;
import org.jooq.impl.DSL;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Constants and Helper functions for Recon SQL related stuff.
*/
public final class SqlDbUtils {

public final static String DERBY_DRIVER_CLASS =
"org.apache.derby.jdbc.EmbeddedDriver";
public final static String SQLITE_DRIVER_CLASS = "org.sqlite.JDBC";
public final static String DERBY_DISABLE_LOG_METHOD =
SqlDbUtils.class.getName() + ".disableDerbyLogFile";

private static final Logger LOG =
LoggerFactory.getLogger(SqlDbUtils.class);

private SqlDbUtils() {
}

/**
* Create new Derby Database with URL and schema name.
* @param jdbcUrl JDBC url.
* @param schemaName Schema name
* @throws ClassNotFoundException on not finding driver class.
* @throws SQLException on SQL exception.
*/
public static void createNewDerbyDatabase(String jdbcUrl, String schemaName)
throws ClassNotFoundException, SQLException {
System.setProperty("derby.stream.error.method",
DERBY_DISABLE_LOG_METHOD);
Class.forName(DERBY_DRIVER_CLASS);
try(Connection connection = DriverManager.getConnection(jdbcUrl
+ ";user=" + schemaName
+ ";create=true")) {
LOG.info("Created derby database at {}.", jdbcUrl);
}
}

/**
* Used to suppress embedded derby database logging.
* @return No-Op output stream.
*/
public static OutputStream disableDerbyLogFile(){
return new OutputStream() {
public void write(int b) throws IOException {
// Ignore all log messages
}
};
}

/**
* Helper function to check if table exists through JOOQ.
*/
public static final BiPredicate<Connection, String> TABLE_EXISTS_CHECK =
(conn, tableName) -> {
try {
DSL.using(conn).select(count()).from(tableName).execute();
} catch (DataAccessException ex) {
LOG.info(ex.getMessage());
return false;
}
LOG.info("{} table already exists, skipping creation.", tableName);
return true;
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

package org.hadoop.ozone.recon.schema;

import static org.hadoop.ozone.recon.codegen.SqlDbUtils.TABLE_EXISTS_CHECK;

import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.jooq.DSLContext;
Expand All @@ -35,9 +37,9 @@
public class ContainerSchemaDefinition implements ReconSchemaDefinition {

public static final String CONTAINER_HISTORY_TABLE_NAME =
"container_history";
"CONTAINER_HISTORY";
public static final String MISSING_CONTAINERS_TABLE_NAME =
"missing_containers";
"MISSING_CONTAINERS";
private static final String CONTAINER_ID = "container_id";
private final DataSource dataSource;
private DSLContext dslContext;
Expand All @@ -51,8 +53,12 @@ public class ContainerSchemaDefinition implements ReconSchemaDefinition {
public void initializeSchema() throws SQLException {
Connection conn = dataSource.getConnection();
dslContext = DSL.using(conn);
createContainerHistoryTable();
createMissingContainersTable();
if (!TABLE_EXISTS_CHECK.test(conn, CONTAINER_HISTORY_TABLE_NAME)) {
createContainerHistoryTable();
}
if (!TABLE_EXISTS_CHECK.test(conn, MISSING_CONTAINERS_TABLE_NAME)) {
createMissingContainersTable();
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

package org.hadoop.ozone.recon.schema;

import static org.hadoop.ozone.recon.codegen.SqlDbUtils.TABLE_EXISTS_CHECK;

import java.sql.Connection;
import java.sql.SQLException;

Expand All @@ -37,7 +39,7 @@
public class ReconTaskSchemaDefinition implements ReconSchemaDefinition {

public static final String RECON_TASK_STATUS_TABLE_NAME =
"recon_task_status";
"RECON_TASK_STATUS";
private final DataSource dataSource;

@Inject
Expand All @@ -48,7 +50,9 @@ public class ReconTaskSchemaDefinition implements ReconSchemaDefinition {
@Override
public void initializeSchema() throws SQLException {
Connection conn = dataSource.getConnection();
createReconTaskStatus(conn);
if (!TABLE_EXISTS_CHECK.test(conn, RECON_TASK_STATUS_TABLE_NAME)) {
createReconTaskStatus(conn);
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

package org.hadoop.ozone.recon.schema;

import static org.hadoop.ozone.recon.codegen.SqlDbUtils.TABLE_EXISTS_CHECK;

import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.jooq.impl.DSL;
Expand All @@ -33,7 +35,7 @@
@Singleton
public class StatsSchemaDefinition implements ReconSchemaDefinition {

public static final String GLOBAL_STATS_TABLE_NAME = "global_stats";
public static final String GLOBAL_STATS_TABLE_NAME = "GLOBAL_STATS";
private final DataSource dataSource;

@Inject
Expand All @@ -44,7 +46,9 @@ public class StatsSchemaDefinition implements ReconSchemaDefinition {
@Override
public void initializeSchema() throws SQLException {
Connection conn = dataSource.getConnection();
createGlobalStatsTable(conn);
if (!TABLE_EXISTS_CHECK.test(conn, GLOBAL_STATS_TABLE_NAME)) {
createGlobalStatsTable(conn);
}
}

/**
Expand Down
Loading