You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by ke...@apache.org on 2020/03/30 16:04:25 UTC

[skywalking] branch master updated: [BugFix] Fix wrong H2 column type (#4593)

This is an automated email from the ASF dual-hosted git repository.

kezhenxu94 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking.git


The following commit(s) were added to refs/heads/master by this push:
     new b28b811  [BugFix] Fix wrong H2 column type (#4593)
b28b811 is described below

commit b28b811af79af504abd5dede1e4605843d887ec3
Author: kezhenxu94 <ke...@apache.org>
AuthorDate: Tue Mar 31 00:04:17 2020 +0800

    [BugFix] Fix wrong H2 column type (#4593)
    
    MEDIUMTEXT in H2 is CLOB in JDBC type, and casting it to `String` causes `ClassCastException`
---
 .../oap/server/core/storage/model/INewModel.java   |  2 +-
 .../server/core/storage/model/StorageModels.java   | 14 ++--
 .../storage/plugin/jdbc/h2/dao/H2SQLExecutor.java  | 86 +++++++++++-----------
 .../plugin/jdbc/h2/dao/H2TableInstaller.java       |  2 +-
 .../plugin/jdbc/mysql/MySQLTableInstaller.java     |  9 +++
 5 files changed, 60 insertions(+), 53 deletions(-)

diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/INewModel.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/INewModel.java
index fab2194..15df48e 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/INewModel.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/INewModel.java
@@ -30,5 +30,5 @@ public interface INewModel extends Service {
      *
      * @return the created new model
      */
-    Model add(Class aClass, int scopeId, Storage storage, boolean record);
+    Model add(Class<?> aClass, int scopeId, Storage storage, boolean record);
 }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/StorageModels.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/StorageModels.java
index 4d87142..1632468 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/StorageModels.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/StorageModels.java
@@ -43,7 +43,7 @@ public class StorageModels implements IModelManager, INewModel, IModelOverride {
     }
 
     @Override
-    public Model add(Class aClass, int scopeId, Storage storage, boolean record) {
+    public Model add(Class<?> aClass, int scopeId, Storage storage, boolean record) {
         // Check this scope id is valid.
         DefaultScopeDefine.nameOf(scopeId);
 
@@ -67,7 +67,7 @@ public class StorageModels implements IModelManager, INewModel, IModelOverride {
         return model;
     }
 
-    private void retrieval(Class clazz,
+    private void retrieval(Class<?> clazz,
                            String modelName,
                            List<ModelColumn> modelColumns,
                            List<ExtraQueryIndex> extraQueryIndices) {
@@ -100,12 +100,10 @@ public class StorageModels implements IModelManager, INewModel, IModelOverride {
                     Collections.addAll(indexDefinitions, field.getAnnotation(MultipleQueryUnifiedIndex.class).value());
                 }
 
-                indexDefinitions.forEach(indexDefinition -> {
-                    extraQueryIndices.add(new ExtraQueryIndex(
-                        column.columnName(),
-                        indexDefinition.withColumns()
-                    ));
-                });
+                indexDefinitions.forEach(indexDefinition -> extraQueryIndices.add(new ExtraQueryIndex(
+                    column.columnName(),
+                    indexDefinition.withColumns()
+                )));
             }
         }
 
diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2SQLExecutor.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2SQLExecutor.java
index 494f17a..bd26cd3 100644
--- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2SQLExecutor.java
+++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2SQLExecutor.java
@@ -45,60 +45,60 @@ public class H2SQLExecutor {
 
     private static final Logger logger = LoggerFactory.getLogger(H2SQLExecutor.class);
 
-    protected List<StorageData> getByIDs(JDBCHikariCPClient h2Client, String modelName, String[] ids,
-        StorageBuilder storageBuilder) throws IOException {
-
-        try (Connection connection = h2Client.getConnection()) {
-            /*
-             * Although H2 database or other database support createArrayOf and setArray operate.
-             * But Mysql 5.1.44 driver doesn't.
-             */
-            String param = ArrayParamBuilder.build(ids);
-
-            try (ResultSet rs = h2Client.executeQuery(connection, "SELECT * FROM " + modelName + " WHERE id in (" + param + ")")) {
-                List<StorageData> storageDataList = new ArrayList<>();
-                StorageData storageData;
-                do {
-                    storageData = toStorageData(rs, modelName, storageBuilder);
-                    if (storageData != null) {
-                        storageDataList.add(storageData);
-                    }
+    protected <T extends StorageData> List<StorageData> getByIDs(JDBCHikariCPClient h2Client,
+                                                                 String modelName,
+                                                                 String[] ids,
+                                                                 StorageBuilder<T> storageBuilder) throws IOException {
+        /*
+         * Although H2 database or other database support createArrayOf and setArray operate.
+         * But Mysql 5.1.44 driver doesn't.
+         */
+        String param = ArrayParamBuilder.build(ids);
+
+        try (Connection connection = h2Client.getConnection();
+             ResultSet rs = h2Client.executeQuery(
+                 connection, "SELECT * FROM " + modelName + " WHERE id in (" + param + ")")) {
+            List<StorageData> storageDataList = new ArrayList<>();
+            StorageData storageData;
+            do {
+                storageData = toStorageData(rs, modelName, storageBuilder);
+                if (storageData != null) {
+                    storageDataList.add(storageData);
                 }
-                while (storageData != null);
-
-                return storageDataList;
             }
+            while (storageData != null);
+
+            return storageDataList;
         } catch (SQLException | JDBCClientException e) {
             throw new IOException(e.getMessage(), e);
         }
     }
 
-    protected StorageData getByID(JDBCHikariCPClient h2Client, String modelName, String id,
-        StorageBuilder storageBuilder) throws IOException {
-        try (Connection connection = h2Client.getConnection()) {
-            try (ResultSet rs = h2Client.executeQuery(connection, "SELECT * FROM " + modelName + " WHERE id = ?", id)) {
-                return toStorageData(rs, modelName, storageBuilder);
-            }
+    protected <T extends StorageData> StorageData getByID(JDBCHikariCPClient h2Client, String modelName, String id,
+                                  StorageBuilder<T> storageBuilder) throws IOException {
+        try (Connection connection = h2Client.getConnection();
+             ResultSet rs = h2Client.executeQuery(connection, "SELECT * FROM " + modelName + " WHERE id = ?", id)) {
+            return toStorageData(rs, modelName, storageBuilder);
         } catch (SQLException | JDBCClientException e) {
             throw new IOException(e.getMessage(), e);
         }
     }
 
     protected StorageData getByColumn(JDBCHikariCPClient h2Client, String modelName, String columnName, Object value,
-        StorageBuilder storageBuilder) throws IOException {
-        try (Connection connection = h2Client.getConnection()) {
-            try (ResultSet rs = h2Client.executeQuery(connection, "SELECT * FROM " + modelName + " WHERE " + columnName + " = ?", value)) {
-                return toStorageData(rs, modelName, storageBuilder);
-            }
+                                      StorageBuilder<? extends StorageData> storageBuilder) throws IOException {
+        try (Connection connection = h2Client.getConnection();
+             ResultSet rs = h2Client.executeQuery(
+                 connection, "SELECT * FROM " + modelName + " WHERE " + columnName + " = ?", value)) {
+            return toStorageData(rs, modelName, storageBuilder);
         } catch (SQLException | JDBCClientException e) {
             throw new IOException(e.getMessage(), e);
         }
     }
 
     protected StorageData toStorageData(ResultSet rs, String modelName,
-        StorageBuilder storageBuilder) throws SQLException {
+                                        StorageBuilder<? extends StorageData> storageBuilder) throws SQLException {
         if (rs.next()) {
-            Map data = new HashMap();
+            Map<String, Object> data = new HashMap<>();
             List<ModelColumn> columns = TableMetaInfo.get(modelName).getColumns();
             for (ModelColumn column : columns) {
                 data.put(column.getColumnName().getName(), rs.getObject(column.getColumnName().getStorageName()));
@@ -109,11 +109,11 @@ public class H2SQLExecutor {
     }
 
     protected int getEntityIDByID(JDBCHikariCPClient h2Client, String entityColumnName, String modelName, String id) {
-        try (Connection connection = h2Client.getConnection()) {
-            try (ResultSet rs = h2Client.executeQuery(connection, "SELECT " + entityColumnName + " FROM " + modelName + " WHERE ID=?", id)) {
-                while (rs.next()) {
-                    return rs.getInt(ServiceInstanceInventory.SEQUENCE);
-                }
+        try (Connection connection = h2Client.getConnection();
+             ResultSet rs = h2Client.executeQuery(
+                 connection, "SELECT " + entityColumnName + " FROM " + modelName + " WHERE ID=?", id)) {
+            if (rs.next()) {
+                return rs.getInt(ServiceInstanceInventory.SEQUENCE);
             }
         } catch (SQLException | JDBCClientException e) {
             logger.error(e.getMessage(), e);
@@ -121,8 +121,8 @@ public class H2SQLExecutor {
         return Const.NONE;
     }
 
-    protected SQLExecutor getInsertExecutor(String modelName, StorageData metrics,
-        StorageBuilder storageBuilder) throws IOException {
+    protected <T extends StorageData> SQLExecutor getInsertExecutor(String modelName, T metrics,
+                                                                    StorageBuilder<T> storageBuilder) throws IOException {
         Map<String, Object> objectMap = storageBuilder.data2Map(metrics);
 
         SQLBuilder sqlBuilder = new SQLBuilder("INSERT INTO " + modelName + " VALUES");
@@ -149,8 +149,8 @@ public class H2SQLExecutor {
         return new SQLExecutor(sqlBuilder.toString(), param);
     }
 
-    protected SQLExecutor getUpdateExecutor(String modelName, StorageData metrics,
-        StorageBuilder storageBuilder) throws IOException {
+    protected <T extends StorageData> SQLExecutor getUpdateExecutor(String modelName, T metrics,
+                                                                    StorageBuilder<T> storageBuilder) throws IOException {
         Map<String, Object> objectMap = storageBuilder.data2Map(metrics);
 
         SQLBuilder sqlBuilder = new SQLBuilder("UPDATE " + modelName + " SET ");
diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2TableInstaller.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2TableInstaller.java
index cb172ce..07e5971 100644
--- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2TableInstaller.java
+++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2TableInstaller.java
@@ -92,7 +92,7 @@ public class H2TableInstaller extends ModelInstaller {
         } else if (String.class.equals(type)) {
             return "VARCHAR(" + column.getLength() + ")";
         } else if (IntKeyLongValueHashMap.class.equals(type)) {
-            return "MEDIUMTEXT";
+            return "VARCHAR(20000)";
         } else if (byte[].class.equals(type)) {
             return "MEDIUMTEXT";
         } else {
diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/MySQLTableInstaller.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/MySQLTableInstaller.java
index c444863..47fbb78 100644
--- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/MySQLTableInstaller.java
+++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/MySQLTableInstaller.java
@@ -22,6 +22,7 @@ import java.sql.Connection;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.skywalking.oap.server.core.analysis.metrics.IntKeyLongValueHashMap;
 import org.apache.skywalking.oap.server.core.storage.StorageException;
 import org.apache.skywalking.oap.server.core.storage.model.ExtraQueryIndex;
 import org.apache.skywalking.oap.server.core.storage.model.Model;
@@ -101,4 +102,12 @@ public class MySQLTableInstaller extends H2TableInstaller {
             createIndex(client, connection, model, tableIndexSQL);
         }
     }
+
+    @Override
+    protected String getColumnType(final ModelColumn column) {
+        if (IntKeyLongValueHashMap.class.equals(column.getType())) {
+            return "MEDIUMTEXT";
+        }
+        return super.getColumnType(column);
+    }
 }