Skip to content

Commit

Permalink
fix serialization issues:
Browse files Browse the repository at this point in the history
- #105
- #107
- fixed how the static resources are copied, using maven tools to ensure it works on any OS.
  • Loading branch information
sterlp authored and geirsagberg committed May 22, 2024
1 parent 598ff3a commit 99a5727
Show file tree
Hide file tree
Showing 9 changed files with 129 additions and 190 deletions.
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -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
8 changes: 4 additions & 4 deletions db-scheduler-ui-frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion db-scheduler-ui-frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
}

Expand All @@ -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);
}

Expand All @@ -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();
}
}
5 changes: 5 additions & 0 deletions db-scheduler-ui/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
<url>https://github.com/bekk/db-scheduler-ui</url>

<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.github.kagkarlsson</groupId>
<artifactId>db-scheduler</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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) {
Expand Down Expand Up @@ -109,10 +120,8 @@ public List<LogModel> 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 {
Expand Down Expand Up @@ -186,13 +195,19 @@ public void setParameters(MapSqlParameterSource p) {
}
}

@RequiredArgsConstructor
public static class LogModelRowMapper implements RowMapper<LogModel> {
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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ public class QueryBuilder {

private Optional<String> orderBy = empty();

private Optional<Integer> limit = empty();

QueryBuilder(String tableName) {
this.tableName = tableName;
}
Expand All @@ -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();
}
Expand Down
Loading

0 comments on commit 99a5727

Please sign in to comment.