From 99a5727e8ec82a7743f2a9448d579b45ab6f6282 Mon Sep 17 00:00:00 2001 From: Paul Sterl Date: Tue, 14 May 2024 12:06:55 +0200 Subject: [PATCH] fix serialization issues: - https://github.com/bekk/db-scheduler-ui/issues/105 - https://github.com/bekk/db-scheduler-ui/issues/107 - fixed how the static resources are copied, using maven tools to ensure it works on any OS. --- .gitignore | 10 ++ db-scheduler-ui-frontend/package-lock.json | 8 +- db-scheduler-ui-frontend/package.json | 1 - .../autoconfigure/UiApiAutoConfiguration.java | 24 ++-- db-scheduler-ui/pom.xml | 5 + .../bekk/dbscheduler/ui/model/LogModel.java | 91 +------------ .../bekk/dbscheduler/ui/service/LogLogic.java | 41 ++++-- .../dbscheduler/ui/util/QueryBuilder.java | 17 +-- pom.xml | 122 +++++++++--------- 9 files changed, 129 insertions(+), 190 deletions(-) diff --git a/.gitignore b/.gitignore index fd90c30b..89aad622 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,13 @@ replay_pid* *.DS_Store /db-scheduler-ui/src/main/resources/templates/index.html /db-scheduler-ui/src/main/resources/templates/db-scheduler-ui/index.html + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +.dbeaver diff --git a/db-scheduler-ui-frontend/package-lock.json b/db-scheduler-ui-frontend/package-lock.json index e943b064..05634a84 100644 --- a/db-scheduler-ui-frontend/package-lock.json +++ b/db-scheduler-ui-frontend/package-lock.json @@ -31,7 +31,7 @@ "@vitejs/plugin-react": "^4.0.3", "eslint": "^8.47.0", "eslint-config-prettier": "^9.0.0", - "eslint-import-resolver-vite": "^1.3.0", + "eslint-import-resolver-vite": "^1.3.2", "eslint-plugin-import": "^2.28.1", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.4.3", @@ -3461,9 +3461,9 @@ } }, "node_modules/eslint-import-resolver-vite": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-vite/-/eslint-import-resolver-vite-1.3.0.tgz", - "integrity": "sha512-iHew6o9T8gwuaPV/IeMbi+1rLw5knJFjiECiC7BU4Ej+3L5gzU+3X2LsYn4Mhumn09qhTXZb8kx3VoJqZSKOJQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-vite/-/eslint-import-resolver-vite-1.3.2.tgz", + "integrity": "sha512-Oi8Dqif2b4Da4pkXhvjxJvS093vOTftnHljZMwEsxXnyoh9K9cx5DKK4ShFfjvnoiCr6cGTPDEoAcvKZinaa4Q==", "dev": true, "engines": { "node": ">=12", diff --git a/db-scheduler-ui-frontend/package.json b/db-scheduler-ui-frontend/package.json index 10476426..a2ba9d92 100644 --- a/db-scheduler-ui-frontend/package.json +++ b/db-scheduler-ui-frontend/package.json @@ -6,7 +6,6 @@ "scripts": { "dev": "vite", "build": "tsc && vite build", - "postbuild": "mkdir -p dist/db-scheduler-ui && mv dist/* dist/db-scheduler-ui/ 2>/dev/null || true", "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "preview": "vite preview" }, diff --git a/db-scheduler-ui-starter/src/main/java/no/bekk/dbscheduler/uistarter/autoconfigure/UiApiAutoConfiguration.java b/db-scheduler-ui-starter/src/main/java/no/bekk/dbscheduler/uistarter/autoconfigure/UiApiAutoConfiguration.java index 3206a159..8da58bd3 100644 --- a/db-scheduler-ui-starter/src/main/java/no/bekk/dbscheduler/uistarter/autoconfigure/UiApiAutoConfiguration.java +++ b/db-scheduler-ui-starter/src/main/java/no/bekk/dbscheduler/uistarter/autoconfigure/UiApiAutoConfiguration.java @@ -14,6 +14,8 @@ package no.bekk.dbscheduler.uistarter.autoconfigure; import com.github.kagkarlsson.scheduler.Scheduler; +import com.github.kagkarlsson.scheduler.boot.config.DbSchedulerCustomizer; +import com.github.kagkarlsson.scheduler.serializer.Serializer; import javax.sql.DataSource; import no.bekk.dbscheduler.ui.controller.LogController; import no.bekk.dbscheduler.ui.controller.TaskController; @@ -36,21 +38,21 @@ public class UiApiAutoConfiguration { private static final Logger logger = LoggerFactory.getLogger(UiApiAutoConfiguration.class); @Value("${db-scheduler-ui.taskdata:true}") - public boolean showTaskData; + boolean showTaskData; - public UiApiAutoConfiguration() { + UiApiAutoConfiguration() { logger.info("UiApiAutoConfiguration created"); } @Bean @ConditionalOnMissingBean - public Caching caching() { + Caching caching() { return new Caching(); } @Bean @ConditionalOnMissingBean - public TaskLogic taskLogic(Scheduler scheduler, Caching caching) { + TaskLogic taskLogic(Scheduler scheduler, Caching caching) { return new TaskLogic(scheduler, caching, showTaskData); } @@ -61,13 +63,17 @@ public TaskLogic taskLogic(Scheduler scheduler, Caching caching) { name = "history", havingValue = "true", matchIfMissing = false) - public LogLogic logLogic(DataSource dataSource) { - return new LogLogic(dataSource, showTaskData); + LogLogic logLogic(DataSource dataSource, Caching caching, DbSchedulerCustomizer customizer) { + return new LogLogic( + dataSource, + customizer.serializer().orElse(Serializer.DEFAULT_JAVA_SERIALIZER), + caching, + showTaskData); } @Bean @ConditionalOnMissingBean - public TaskController taskController(TaskLogic taskLogic) { + TaskController taskController(TaskLogic taskLogic) { return new TaskController(taskLogic); } @@ -78,13 +84,13 @@ public TaskController taskController(TaskLogic taskLogic) { name = "history", havingValue = "true", matchIfMissing = false) - public LogController logController(LogLogic logLogic) { + LogController logController(LogLogic logLogic) { return new LogController(logLogic); } @Bean @ConditionalOnMissingBean - public UIController uiController() { + UIController uiController() { return new UIController(); } } diff --git a/db-scheduler-ui/pom.xml b/db-scheduler-ui/pom.xml index 2c1d2f7a..a39f39f2 100644 --- a/db-scheduler-ui/pom.xml +++ b/db-scheduler-ui/pom.xml @@ -15,6 +15,11 @@ https://github.com/bekk/db-scheduler-ui + + org.projectlombok + lombok + true + com.github.kagkarlsson db-scheduler diff --git a/db-scheduler-ui/src/main/java/no/bekk/dbscheduler/ui/model/LogModel.java b/db-scheduler-ui/src/main/java/no/bekk/dbscheduler/ui/model/LogModel.java index 87cdc355..78de3b39 100644 --- a/db-scheduler-ui/src/main/java/no/bekk/dbscheduler/ui/model/LogModel.java +++ b/db-scheduler-ui/src/main/java/no/bekk/dbscheduler/ui/model/LogModel.java @@ -13,11 +13,12 @@ */ package no.bekk.dbscheduler.ui.model; -import com.fasterxml.jackson.databind.ObjectMapper; -import java.io.IOException; import java.time.Instant; -import org.springframework.util.SerializationUtils; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +@RequiredArgsConstructor +@Getter public class LogModel { private final Long id; private final String taskName; @@ -30,88 +31,4 @@ public class LogModel { private final String exceptionClass; private final String exceptionMessage; private final String exceptionStackTrace; - - private static final ObjectMapper objectMapper = new ObjectMapper(); - - public LogModel( - Long id, - String taskName, - String taskInstance, - byte[] inputTaskData, - Instant timeStarted, - Instant timeFinished, - boolean succeeded, - Long durationMs, - String exceptionClass, - String exceptionMessage, - String exceptionStackTrace) { - this.id = id; - this.taskName = taskName; - this.taskInstance = taskInstance; - this.taskData = stringTaskData(inputTaskData); - this.timeStarted = timeStarted; - this.timeFinished = timeFinished; - this.succeeded = succeeded; - this.durationMs = durationMs; - this.exceptionClass = exceptionClass; - this.exceptionMessage = exceptionMessage; - this.exceptionStackTrace = exceptionStackTrace; - } - - private Object stringTaskData(byte[] inputTaskData) { - try { - if (inputTaskData != null) { - Object dataclass = SerializationUtils.deserialize(inputTaskData); - String serializedData = objectMapper.writeValueAsString(dataclass); - return objectMapper.readValue(serializedData, Object.class); - } - } catch (IOException e) { - throw new RuntimeException(e); - } - return null; - } - - public String getTaskInstance() { - return taskInstance; - } - - public String getTaskName() { - return taskName; - } - - public Object getTaskData() { - return taskData; - } - - public Long getId() { - return id; - } - - public Instant getTimeStarted() { - return timeStarted; - } - - public Instant getTimeFinished() { - return timeFinished; - } - - public boolean isSucceeded() { - return succeeded; - } - - public Long getDurationMs() { - return durationMs; - } - - public String getExceptionClass() { - return exceptionClass; - } - - public String getExceptionMessage() { - return exceptionMessage; - } - - public String getExceptionStackTrace() { - return exceptionStackTrace; - } } diff --git a/db-scheduler-ui/src/main/java/no/bekk/dbscheduler/ui/service/LogLogic.java b/db-scheduler-ui/src/main/java/no/bekk/dbscheduler/ui/service/LogLogic.java index f27d97f5..554193db 100644 --- a/db-scheduler-ui/src/main/java/no/bekk/dbscheduler/ui/service/LogLogic.java +++ b/db-scheduler-ui/src/main/java/no/bekk/dbscheduler/ui/service/LogLogic.java @@ -13,18 +13,25 @@ */ package no.bekk.dbscheduler.ui.service; +import com.github.kagkarlsson.scheduler.serializer.Serializer; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.time.Instant; -import java.util.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import javax.sql.DataSource; -import no.bekk.dbscheduler.ui.model.*; +import lombok.RequiredArgsConstructor; +import no.bekk.dbscheduler.ui.model.GetLogsResponse; +import no.bekk.dbscheduler.ui.model.LogModel; +import no.bekk.dbscheduler.ui.model.LogPollResponse; +import no.bekk.dbscheduler.ui.model.TaskDetailsRequestParams; +import no.bekk.dbscheduler.ui.model.TaskRequestParams; import no.bekk.dbscheduler.ui.util.AndCondition; import no.bekk.dbscheduler.ui.util.Caching; import no.bekk.dbscheduler.ui.util.QueryBuilder; import no.bekk.dbscheduler.ui.util.QueryUtils; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; @@ -34,14 +41,18 @@ public class LogLogic { private final NamedParameterJdbcTemplate namedParameterJdbcTemplate; - private static boolean showData; private static final int DEFAULT_LIMIT = 500; - @Autowired private Caching caching; + private final Caching caching; + private final LogModelRowMapper logModelRowMapper; - @Autowired - public LogLogic(DataSource dataSource, boolean showData) { + public LogLogic(DataSource dataSource, Serializer serializer, Caching caching, boolean showData) { this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource); - this.showData = showData; + // currently we have no paging in the UI + this.namedParameterJdbcTemplate.getJdbcTemplate().setMaxRows(DEFAULT_LIMIT); + this.caching = caching; + this.logModelRowMapper = + new LogModelRowMapper( + showData, serializer == null ? Serializer.DEFAULT_JAVA_SERIALIZER : serializer); } public GetLogsResponse getLogs(TaskDetailsRequestParams requestParams) { @@ -109,10 +120,8 @@ public List getLogsDirectlyFromDB(TaskDetailsRequestParams requestPara queryBuilder.orderBy(requestParams.isAsc() ? "time_finished desc" : "time_finished asc"); - queryBuilder.limit(DEFAULT_LIMIT); - return namedParameterJdbcTemplate.query( - queryBuilder.getQuery(), queryBuilder.getParameters(), new LogModelRowMapper()); + queryBuilder.getQuery(), queryBuilder.getParameters(), logModelRowMapper); } private static class TimeCondition implements AndCondition { @@ -186,13 +195,19 @@ public void setParameters(MapSqlParameterSource p) { } } + @RequiredArgsConstructor public static class LogModelRowMapper implements RowMapper { + private final boolean showData; + private final Serializer serializer; @Override public LogModel mapRow(ResultSet rs, int rowNum) throws SQLException { - byte[] taskData = null; + Object taskData = null; if (showData) { - taskData = rs.getBytes("task_data"); + final byte[] bytes = rs.getBytes("task_data"); + if (bytes != null) { + taskData = serializer.deserialize(Object.class, bytes); + } } return new LogModel( diff --git a/db-scheduler-ui/src/main/java/no/bekk/dbscheduler/ui/util/QueryBuilder.java b/db-scheduler-ui/src/main/java/no/bekk/dbscheduler/ui/util/QueryBuilder.java index b2ad4af6..c8f56ea0 100644 --- a/db-scheduler-ui/src/main/java/no/bekk/dbscheduler/ui/util/QueryBuilder.java +++ b/db-scheduler-ui/src/main/java/no/bekk/dbscheduler/ui/util/QueryBuilder.java @@ -28,8 +28,6 @@ public class QueryBuilder { private Optional orderBy = empty(); - private Optional limit = empty(); - QueryBuilder(String tableName) { this.tableName = tableName; } @@ -48,23 +46,16 @@ public QueryBuilder orderBy(String orderBy) { return this; } - public QueryBuilder limit(int limit) { - this.limit = Optional.of(limit); - return this; - } - public String getQuery() { StringBuilder s = new StringBuilder(); - s.append("select * from ").append(tableName); + s.append("SELECT * FROM ").append(tableName); if (!andConditions.isEmpty()) { - s.append(" where "); - s.append(andConditions.stream().map(AndCondition::getQueryPart).collect(joining(" and "))); + s.append(" WHERE "); + s.append(andConditions.stream().map(AndCondition::getQueryPart).collect(joining(" AND "))); } - orderBy.ifPresent(o -> s.append(" order by ").append(o)); - - limit.ifPresent(l -> s.append(" limit ").append(l)); + orderBy.ifPresent(o -> s.append(" ORDER BY ").append(o)); return s.toString(); } diff --git a/pom.xml b/pom.xml index 7e0dde19..7284c1c2 100644 --- a/pom.xml +++ b/pom.xml @@ -1,7 +1,7 @@ + xmlns="http://maven.apache.org/POM/4.0.0" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 no.bekk.db-scheduler-ui db-scheduler-ui-parent @@ -17,8 +17,8 @@ 11 11 11 - 2.7.15 - 12.5.0 + 2.7.18 + 14.0.0 UTF-8 @@ -148,17 +148,18 @@ src/main/java/**/*.java - src/test/java/**/*.java + src/test/java/**/*.java 1.17.0 - - - - - + + + + + @@ -260,10 +261,23 @@ + + org.apache.maven.plugins + maven-clean-plugin + + + + frontend/node_modules + db-scheduler-ui/src/main/resources/static + db-scheduler-ui/src/main/resources/templates + + + + org.codehaus.mojo exec-maven-plugin - 3.0.0 + 3.2.0 false @@ -294,67 +308,49 @@ ./db-scheduler-ui-frontend + + + + maven-resources-plugin + 3.3.1 + - create-static-folder - generate-resources - - exec - - - mkdir - - -p - db-scheduler-ui/src/main/resources/static - - - - - create-template-folder - generate-resources - - exec - - - mkdir - - -p - - db-scheduler-ui/src/main/resources/templates/db-scheduler-ui - - - - - - copy-index-file - generate-resources + copy-files-to-backend + process-classes - exec + copy-resources - mv - - - db-scheduler-ui-frontend/dist/db-scheduler-ui/index.html - - - db-scheduler-ui/src/main/resources/templates/db-scheduler-ui/ - - + UTF-8 + db-scheduler-ui/src/main/resources/static/db-scheduler-ui + + + db-scheduler-ui-frontend/dist + + **/*.html + + + + - copy-frontend-files - generate-resources + copy-template-files + process-classes - exec + copy-resources - cp - - -r - db-scheduler-ui-frontend/dist/. - db-scheduler-ui/src/main/resources/static/ - + UTF-8 + db-scheduler-ui/src/main/resources/templates/db-scheduler-ui + + + db-scheduler-ui-frontend/dist + + **/*.html + + + @@ -422,4 +418,4 @@ - + \ No newline at end of file