From d7725721fdda7516748ef094c89b967703236518 Mon Sep 17 00:00:00 2001 From: Sean Flanigan Date: Mon, 13 Apr 2015 16:03:07 +1000 Subject: [PATCH 1/7] Ensure tables use InnoDB engine on MySQL --- .../db/changelogs/db.changelog-3.6.xml | 112 ++++++++++++++++++ .../db/changelogs/db.changelog-3.7.xml | 3 + 2 files changed, 115 insertions(+) diff --git a/zanata-war/src/main/resources/db/changelogs/db.changelog-3.6.xml b/zanata-war/src/main/resources/db/changelogs/db.changelog-3.6.xml index 336aae6ad0..bc527cfebb 100644 --- a/zanata-war/src/main/resources/db/changelogs/db.changelog-3.6.xml +++ b/zanata-war/src/main/resources/db/changelogs/db.changelog-3.6.xml @@ -30,4 +30,116 @@ referencedTableName = "HProject" referencedColumnNames = "id"/> + + + Ensure InnoDB for HIterationGroup + ALTER TABLE HIterationGroup ENGINE = INNODB + + + Ensure InnoDB for HIterationGroup_Maintainer + ALTER TABLE HIterationGroup_Maintainer ENGINE = INNODB + + + Ensure InnoDB for HIterationGroup_ProjectIteration + ALTER TABLE HIterationGroup_ProjectIteration ENGINE = INNODB + + + Ensure InnoDB for HCredentials + ALTER TABLE HCredentials ENGINE = INNODB + + + Ensure InnoDB for HProject_AllowedRole + ALTER TABLE HProject_AllowedRole ENGINE = INNODB + + + Ensure InnoDB for HRoleAssignmentRule + ALTER TABLE HRoleAssignmentRule ENGINE = INNODB + + + Ensure InnoDB for HCopyTransOptions + ALTER TABLE HCopyTransOptions ENGINE = INNODB + + + Ensure InnoDB for HRawDocument + ALTER TABLE HRawDocument ENGINE = INNODB + + + Ensure InnoDB for HDocument_RawDocument + ALTER TABLE HDocument_RawDocument ENGINE = INNODB + + + Ensure InnoDB for HDocumentUpload + ALTER TABLE HDocumentUpload ENGINE = INNODB + + + Ensure InnoDB for HDocumentUploadPart + ALTER TABLE HDocumentUploadPart ENGINE = INNODB + + + Ensure InnoDB for HAccountOption + ALTER TABLE HAccountOption ENGINE = INNODB + + + Ensure InnoDB for HPersonEmailValidationKey + ALTER TABLE HPersonEmailValidationKey ENGINE = INNODB + + + Ensure InnoDB for HProject_Validation + ALTER TABLE HProject_Validation ENGINE = INNODB + + + Ensure InnoDB for HProjectIteration_Validation + ALTER TABLE HProjectIteration_Validation ENGINE = INNODB + + + Ensure InnoDB for TransMemory + ALTER TABLE TransMemory ENGINE = INNODB + + + Ensure InnoDB for TransMemory_Metadata + ALTER TABLE TransMemory_Metadata ENGINE = INNODB + + + Ensure InnoDB for TransMemoryUnit + ALTER TABLE TransMemoryUnit ENGINE = INNODB + + + Ensure InnoDB for TransMemoryUnitVariant + ALTER TABLE TransMemoryUnitVariant ENGINE = INNODB + + + Ensure InnoDB for HTextFlowTargetReviewComment + ALTER TABLE HTextFlowTargetReviewComment ENGINE = INNODB + + + + + + + SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES + WHERE TABLE_SCHEMA = SCHEMA() + AND ENGINE = 'InnoDB' + AND TABLE_NAME='Activity'; + + + Ensure InnoDB for Activity + ALTER TABLE Activity ENGINE = INNODB + + + Ensure InnoDB for IterationGroup_Locale + ALTER TABLE IterationGroup_Locale ENGINE = INNODB + + + Ensure InnoDB for WebHook + ALTER TABLE WebHook ENGINE = INNODB + + + Ensure InnoDB for DATABASECHANGELOG + ALTER TABLE DATABASECHANGELOG ENGINE = INNODB + + + Ensure InnoDB for DATABASECHANGELOGLOCK + ALTER TABLE DATABASECHANGELOGLOCK ENGINE = INNODB + + diff --git a/zanata-war/src/main/resources/db/changelogs/db.changelog-3.7.xml b/zanata-war/src/main/resources/db/changelogs/db.changelog-3.7.xml index 5f7b437f58..4e8b728784 100644 --- a/zanata-war/src/main/resources/db/changelogs/db.changelog-3.7.xml +++ b/zanata-war/src/main/resources/db/changelogs/db.changelog-3.7.xml @@ -10,4 +10,7 @@ + + From 81581f0162e012a61c754cb4ca96167aff0e1c16 Mon Sep 17 00:00:00 2001 From: Sean Flanigan Date: Mon, 13 Apr 2015 16:03:38 +1000 Subject: [PATCH 2/7] Add Liquibase extension to ensure InnoDB engine for new tables --- .../ext/CreateTableGeneratorInnoDB.java | 119 ++++++++++++++++++ .../db/changelogs/db.changelog-1.0.xml | 9 -- 2 files changed, 119 insertions(+), 9 deletions(-) create mode 100644 zanata-war/src/main/java/liquibase/sqlgenerator/ext/CreateTableGeneratorInnoDB.java diff --git a/zanata-war/src/main/java/liquibase/sqlgenerator/ext/CreateTableGeneratorInnoDB.java b/zanata-war/src/main/java/liquibase/sqlgenerator/ext/CreateTableGeneratorInnoDB.java new file mode 100644 index 0000000000..4faf156142 --- /dev/null +++ b/zanata-war/src/main/java/liquibase/sqlgenerator/ext/CreateTableGeneratorInnoDB.java @@ -0,0 +1,119 @@ +/* + * Copyright 2015, Red Hat, Inc. and individual contributors as indicated by the + * @author tags. See the copyright.txt file in the distribution for a full + * listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF + * site: http://www.fsf.org. + */ +package liquibase.sqlgenerator.ext; + +import liquibase.database.Database; +import liquibase.database.core.MySQLDatabase; +import liquibase.exception.UnexpectedLiquibaseException; +import liquibase.exception.ValidationErrors; +import liquibase.logging.LogFactory; +import liquibase.logging.Logger; +import liquibase.sql.Sql; +import liquibase.sql.UnparsedSql; +import liquibase.sqlgenerator.SqlGeneratorChain; +import liquibase.sqlgenerator.core.CreateTableGenerator; +import liquibase.statement.core.CreateTableStatement; +import liquibase.structure.DatabaseObject; + +import java.util.Collection; + +/** + * A create table statement generator to force the use of the InnoDB engine + * on MySQL/MariaDB, unless the engine has already been specified by other + * means (eg modifySql). + *

+ * Note: SqlGenerator implementations must live in package + * "liquibase.sqlgenerator.ext" to be automatically registered. + *

+ * + * @author Sean Flanigan sflaniga@redhat.com + */ +@SuppressWarnings("unused") +public class CreateTableGeneratorInnoDB extends CreateTableGenerator { + + @Override + public boolean supports(CreateTableStatement statement, Database database) { + // NB this will include MariaDB (with Liquibase 3.4+) + return database instanceof MySQLDatabase; + } + + @Override + public int getPriority() { + // Higher priority than the built-ins + return PRIORITY_DATABASE + 1; + } + + @Override + public ValidationErrors validate(CreateTableStatement createTableStatement, + Database database, SqlGeneratorChain sqlGeneratorChain) { + return sqlGeneratorChain.validate(createTableStatement, database); + } + + @Override + public Sql[] generateSql(CreateTableStatement statement, Database database, + SqlGeneratorChain sqlGeneratorChain) { + Logger log = LogFactory.getLogger(); + + boolean foundCreateTable = false; + Sql[] sqls = sqlGeneratorChain.generateSql(statement, database).clone(); + + // Append " ENGINE=INNODB" to CREATE TABLE unless ENGINE already + // specified. This is clumsy, but Liquibase doesn't have seem + // to have any better hooks for this. + for (int i = 0; i < sqls.length; i++) { + Sql sql = sqls[i]; + String sqlText = sql.toSql(); + String sqlUpper = sqlText.trim().toUpperCase(); + if (sqlUpper.startsWith("CREATE TABLE ")) { + foundCreateTable = true; + + if (!(sqlUpper.contains(" ENGINE ") || sqlUpper + .contains(" ENGINE="))) { + log.info("Adding ENGINE=INNODB to generated SQL for table " + + statement.getTableName()); + sqlText += " ENGINE=INNODB "; + DatabaseObject[] objects = toArray( + sql.getAffectedDatabaseObjects()); + sqls[i] = + new UnparsedSql(sqlText, sql.getEndDelimiter(), + objects); + } else { + log.info("SQL for CREATE TABLE already contains ENGINE for table " + + statement.getTableName()); + } + } + } + if (!foundCreateTable) { + throw new UnexpectedLiquibaseException( + "CREATE TABLE not found; unable to ensure ENGINE=INNODB for table " + + statement.getTableName()); + } + return sqls; + } + + private DatabaseObject[] toArray( + Collection objects) { + return objects.toArray( + new DatabaseObject[objects.size()]); + } + +} diff --git a/zanata-war/src/main/resources/db/changelogs/db.changelog-1.0.xml b/zanata-war/src/main/resources/db/changelogs/db.changelog-1.0.xml index db6c1518f0..747f34eb83 100644 --- a/zanata-war/src/main/resources/db/changelogs/db.changelog-1.0.xml +++ b/zanata-war/src/main/resources/db/changelogs/db.changelog-1.0.xml @@ -18,13 +18,4 @@ h2 baseline schema - - - Set session's default storage engine to INNODB (mysql ver > 5.5) - SET storage_engine=InnoDB - - - Set session's default storage engine to INNODB (mysql ver < 5.5) - SET default_storage_engine=InnoDB - From 292493d61bcd8068af132d0532a680c2b4205b84 Mon Sep 17 00:00:00 2001 From: Sean Flanigan Date: Mon, 13 Apr 2015 16:10:04 +1000 Subject: [PATCH 3/7] Update release notes --- docs/release-notes.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/release-notes.md b/docs/release-notes.md index b7dd50df97..1d186e41a7 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -1,3 +1,17 @@ +## 3.6.3 + +
Bugfixes
+* [1207575](https://bugzilla.redhat.com/show_bug.cgi?id=1207575) - Zanata still creates MyISAM (not InnoDB) tables in some cases + +----------------------- + +## 3.6.2 + +
Bugfixes
+* [1206018](https://bugzilla.redhat.com/show_bug.cgi?id=1206018) - RichFaces: Remote Command Execution via insufficient EL parameter sanitization + +----------------------- + ## 3.6.1
Bugfixes
From 0f36c37da09b92b9268e2c0871d235a61642de89 Mon Sep 17 00:00:00 2001 From: Sean Flanigan Date: Thu, 16 Apr 2015 15:28:09 +1000 Subject: [PATCH 4/7] Check that all tables are InnoDB on every start --- .../db/changelogs/db.changelog-validations.xml | 18 ++++++++++++++++++ .../src/main/resources/db/db.changelog.xml | 4 +++- 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 zanata-war/src/main/resources/db/changelogs/db.changelog-validations.xml diff --git a/zanata-war/src/main/resources/db/changelogs/db.changelog-validations.xml b/zanata-war/src/main/resources/db/changelogs/db.changelog-validations.xml new file mode 100644 index 0000000000..4f1d16f003 --- /dev/null +++ b/zanata-war/src/main/resources/db/changelogs/db.changelog-validations.xml @@ -0,0 +1,18 @@ + + + + + + + SELECT count(*) FROM information_schema.tables + WHERE TABLE_SCHEMA = SCHEMA() AND engine != 'InnoDB' + + + Check that all tables are InnoDB + + + diff --git a/zanata-war/src/main/resources/db/db.changelog.xml b/zanata-war/src/main/resources/db/db.changelog.xml index cf5824a14c..1d49801c8e 100644 --- a/zanata-war/src/main/resources/db/db.changelog.xml +++ b/zanata-war/src/main/resources/db/db.changelog.xml @@ -40,10 +40,12 @@ - + + From 83fc0e8a59f13b7d495eab808427031267a48cb7 Mon Sep 17 00:00:00 2001 From: Sean Flanigan Date: Mon, 20 Apr 2015 11:53:18 +1000 Subject: [PATCH 5/7] Add meaningful error message when precondition fails --- .../resources/db/changelogs/db.changelog-validations.xml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/zanata-war/src/main/resources/db/changelogs/db.changelog-validations.xml b/zanata-war/src/main/resources/db/changelogs/db.changelog-validations.xml index 4f1d16f003..118ad9f40b 100644 --- a/zanata-war/src/main/resources/db/changelogs/db.changelog-validations.xml +++ b/zanata-war/src/main/resources/db/changelogs/db.changelog-validations.xml @@ -4,9 +4,13 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.0.xsd"> + - + SELECT count(*) FROM information_schema.tables WHERE TABLE_SCHEMA = SCHEMA() AND engine != 'InnoDB' From db9cdde5518f934d7f7bc9d6e505caf82a7be933 Mon Sep 17 00:00:00 2001 From: Sean Flanigan Date: Tue, 21 Apr 2015 13:51:33 +1000 Subject: [PATCH 6/7] Move Liquibase extension to separate jar to ensure activation --- pom.xml | 7 ++++ zanata-liquibase/pom.xml | 32 +++++++++++++++++++ .../ext/CreateTableGeneratorInnoDB.java | 4 +-- zanata-war/pom.xml | 5 +++ 4 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 zanata-liquibase/pom.xml rename {zanata-war/src/main/java/liquibase/sqlgenerator => zanata-liquibase/src/main/java/liquibase}/ext/CreateTableGeneratorInnoDB.java (97%) diff --git a/pom.xml b/pom.xml index 0410336674..5180c71c1e 100644 --- a/pom.xml +++ b/pom.xml @@ -368,6 +368,12 @@ ${project.version} + + org.zanata + zanata-liquibase + ${project.version} + + com.google.gwt gwt-dev @@ -1396,6 +1402,7 @@ + zanata-liquibase zanata-model zanata-war zanata-test-war diff --git a/zanata-liquibase/pom.xml b/zanata-liquibase/pom.xml new file mode 100644 index 0000000000..0e2dcab0b3 --- /dev/null +++ b/zanata-liquibase/pom.xml @@ -0,0 +1,32 @@ + + + + server + org.zanata + 3.6.3-SNAPSHOT + + 4.0.0 + + zanata-liquibase + + + + + maven-surefire-plugin + + false + + + + + + + + org.liquibase + liquibase-core + + + + diff --git a/zanata-war/src/main/java/liquibase/sqlgenerator/ext/CreateTableGeneratorInnoDB.java b/zanata-liquibase/src/main/java/liquibase/ext/CreateTableGeneratorInnoDB.java similarity index 97% rename from zanata-war/src/main/java/liquibase/sqlgenerator/ext/CreateTableGeneratorInnoDB.java rename to zanata-liquibase/src/main/java/liquibase/ext/CreateTableGeneratorInnoDB.java index 4faf156142..1db47f6a97 100644 --- a/zanata-war/src/main/java/liquibase/sqlgenerator/ext/CreateTableGeneratorInnoDB.java +++ b/zanata-liquibase/src/main/java/liquibase/ext/CreateTableGeneratorInnoDB.java @@ -18,7 +18,7 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF * site: http://www.fsf.org. */ -package liquibase.sqlgenerator.ext; +package liquibase.ext; import liquibase.database.Database; import liquibase.database.core.MySQLDatabase; @@ -41,7 +41,7 @@ * means (eg modifySql). *

* Note: SqlGenerator implementations must live in package - * "liquibase.sqlgenerator.ext" to be automatically registered. + * "liquibase.ext" (or similar) to be automatically registered. *

* * @author Sean Flanigan
+ + org.zanata + zanata-liquibase + + org.zanata zanata-common-util From c69d8ecaa1682274534a437e4f4ccb2b308152ef Mon Sep 17 00:00:00 2001 From: Sean Flanigan Date: Tue, 21 Apr 2015 13:54:17 +1000 Subject: [PATCH 7/7] Add Liquibase extension which logs changes before executing --- .../liquibase/ext/MySQLDatabaseWithLog.java | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 zanata-liquibase/src/main/java/liquibase/ext/MySQLDatabaseWithLog.java diff --git a/zanata-liquibase/src/main/java/liquibase/ext/MySQLDatabaseWithLog.java b/zanata-liquibase/src/main/java/liquibase/ext/MySQLDatabaseWithLog.java new file mode 100644 index 0000000000..fdf270934f --- /dev/null +++ b/zanata-liquibase/src/main/java/liquibase/ext/MySQLDatabaseWithLog.java @@ -0,0 +1,75 @@ +/* + * Copyright 2015, Red Hat, Inc. and individual contributors as indicated by the + * @author tags. See the copyright.txt file in the distribution for a full + * listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF + * site: http://www.fsf.org. + */ +package liquibase.ext; + + +import liquibase.change.Change; +import liquibase.changelog.ChangeSet; +import liquibase.changelog.DatabaseChangeLog; +import liquibase.database.Database; +import liquibase.database.core.MySQLDatabase; +import liquibase.exception.LiquibaseException; +import liquibase.exception.RollbackImpossibleException; +import liquibase.exception.ValidationErrors; +import liquibase.logging.LogFactory; +import liquibase.logging.Logger; +import liquibase.sql.Sql; +import liquibase.sql.visitor.SqlVisitor; +import liquibase.sqlgenerator.SqlGeneratorChain; +import liquibase.sqlgenerator.core.AbstractSqlGenerator; +import liquibase.statement.SqlStatement; +import liquibase.util.StreamUtil; + +import java.io.StringWriter; +import java.util.List; + + +/** + * A slightly modified MySQLDatabase which simply logs each change before + * executing. + *

+ * Note: SqlGenerator implementations must live in package + * "liquibase.ext" (or similar) to be automatically registered. + *

+ * + * @author Sean Flanigan
sflaniga@redhat.com + */ +@SuppressWarnings("unused") +public class MySQLDatabaseWithLog extends MySQLDatabase { + + @Override + public int getPriority() { + // Higher priority than the built-ins + return PRIORITY_DATABASE; + } + + @Override + public void executeStatements(Change change, DatabaseChangeLog changeLog, + List sqlVisitors) throws LiquibaseException { + if (getConnection() != null) { + // don't log if running offline + Logger log = LogFactory.getLogger(); + log.info("Executing " + change.getClass().getSimpleName()); + } + super.executeStatements(change, changeLog, sqlVisitors); + } +}