Commit fb6b2334 by inrgihc

代码问题优化

parent 6f4e0eaf
...@@ -10,7 +10,9 @@ ...@@ -10,7 +10,9 @@
package com.gitee.sqlrest.common.dto; package com.gitee.sqlrest.common.dto;
import java.io.Serializable; import java.io.Serializable;
import java.sql.Connection;
import java.util.List; import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
...@@ -39,4 +41,5 @@ public class ProductContext implements Serializable { ...@@ -39,4 +41,5 @@ public class ProductContext implements Serializable {
private Function<String, Pair<String, String>> adapter; private Function<String, Pair<String, String>> adapter;
private String pageSql; private String pageSql;
private ThreeConsumer<Integer, Integer, List<Object>> pageConsumer; private ThreeConsumer<Integer, Integer, List<Object>> pageConsumer;
private Consumer<Connection> executeBeforeQuery;
} }
...@@ -11,6 +11,8 @@ package com.gitee.sqlrest.common.enums; ...@@ -11,6 +11,8 @@ package com.gitee.sqlrest.common.enums;
import com.gitee.sqlrest.common.dto.ProductContext; import com.gitee.sqlrest.common.dto.ProductContext;
import com.gitee.sqlrest.common.dto.ThreeConsumer; import com.gitee.sqlrest.common.dto.ThreeConsumer;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import lombok.Getter; import lombok.Getter;
...@@ -310,6 +312,15 @@ public enum ProductTypeEnum { ...@@ -310,6 +312,15 @@ public enum ProductTypeEnum {
parameters.add(size); parameters.add(size);
parameters.add((page - 1) * size); parameters.add((page - 1) * size);
} }
)
.executeBeforeQuery(
connection -> {
try (Statement statement = connection.createStatement()) {
statement.execute("set hive.resultset.use.unique.column.names=false");
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
).build()), ).build()),
/** /**
......
// Copyright tang. All rights reserved.
// https://gitee.com/inrgihc/sqlrest
//
// Use of this source code is governed by a BSD-style license
//
// Author: tang (inrgihc@126.com)
// Date : 2024/3/31
// Location: beijing , china
/////////////////////////////////////////////////////////////
package com.gitee.sqlrest.common.model;
@FunctionalInterface
public interface ThrowableRunnable {
void run() throws Exception;
}
// Copyright tang. All rights reserved.
// https://gitee.com/inrgihc/sqlrest
//
// Use of this source code is governed by a BSD-style license
//
// Author: tang (inrgihc@126.com)
// Date : 2024/3/31
// Location: beijing , china
/////////////////////////////////////////////////////////////
package com.gitee.sqlrest.common.util;
import com.gitee.sqlrest.common.model.ThrowableRunnable;
import lombok.experimental.UtilityClass;
@UtilityClass
public class LambdaUtils {
public static void ifDo(boolean condition, ThrowableRunnable action) {
if (condition) {
try {
action.run();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
public static void ifDoMayThrow(boolean condition, ThrowableRunnable action) throws Exception {
action.run();
}
public static void ifDoIgnoreThrow(boolean condition, ThrowableRunnable action) {
try {
action.run();
} catch (Exception ignore) { // NOSORNA
}
}
public static void ifDoElse(boolean condition, ThrowableRunnable trueAction, ThrowableRunnable falseAction) {
try {
if (condition) {
trueAction.run();
} else {
falseAction.run();
}
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
}
...@@ -13,6 +13,7 @@ import com.fasterxml.jackson.annotation.JsonFormat; ...@@ -13,6 +13,7 @@ import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.Map;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
...@@ -43,6 +44,9 @@ public class ApiAccessLogBasicResponse { ...@@ -43,6 +44,9 @@ public class ApiAccessLogBasicResponse {
@ApiModelProperty("应用名称") @ApiModelProperty("应用名称")
private String clientApp; private String clientApp;
@ApiModelProperty("请求入参")
private Map<String, Object> parameters;
@ApiModelProperty("错误异常") @ApiModelProperty("错误异常")
private String exception; private String exception;
......
...@@ -82,6 +82,7 @@ public class ApiExecuteService { ...@@ -82,6 +82,7 @@ public class ApiExecuteService {
try { try {
List<ItemParam> invalidArgs = new ArrayList<>(); List<ItemParam> invalidArgs = new ArrayList<>();
Map<String, Object> paramValues = mergeParameters(request, config.getParams(), invalidArgs); Map<String, Object> paramValues = mergeParameters(request, config.getParams(), invalidArgs);
RequestParamLogger.set(paramValues);
if (invalidArgs.size() > 0) { if (invalidArgs.size() > 0) {
throw new CommonException(ResponseErrorCode.ERROR_INVALID_ARGUMENT, convertInvalidArgs(invalidArgs)); throw new CommonException(ResponseErrorCode.ERROR_INVALID_ARGUMENT, convertInvalidArgs(invalidArgs));
} }
......
// Copyright tang. All rights reserved.
// https://gitee.com/inrgihc/sqlrest
//
// Use of this source code is governed by a BSD-style license
//
// Author: tang (inrgihc@126.com)
// Date : 2024/3/31
// Location: beijing , china
/////////////////////////////////////////////////////////////
package com.gitee.sqlrest.core.exec;
import java.util.Map;
public class RequestParamLogger {
private static final ThreadLocal<Map<String, Object>> threadLocal = new ThreadLocal<>();
public static void set(Map<String, Object> requestParams) {
threadLocal.set(requestParams);
}
public static Map<String, Object> getAndClear() {
Map<String, Object> r = threadLocal.get();
threadLocal.remove();
return r;
}
}
...@@ -11,6 +11,7 @@ package com.gitee.sqlrest.core.exec.engine.impl; ...@@ -11,6 +11,7 @@ package com.gitee.sqlrest.core.exec.engine.impl;
import com.gitee.sqlrest.common.enums.NamingStrategyEnum; import com.gitee.sqlrest.common.enums.NamingStrategyEnum;
import com.gitee.sqlrest.common.enums.ProductTypeEnum; import com.gitee.sqlrest.common.enums.ProductTypeEnum;
import com.gitee.sqlrest.common.util.LambdaUtils;
import com.gitee.sqlrest.core.exec.engine.AbstractExecutorEngine; import com.gitee.sqlrest.core.exec.engine.AbstractExecutorEngine;
import com.gitee.sqlrest.core.util.PageSizeUtils; import com.gitee.sqlrest.core.util.PageSizeUtils;
import com.gitee.sqlrest.core.util.SqlJdbcUtils; import com.gitee.sqlrest.core.util.SqlJdbcUtils;
...@@ -19,7 +20,6 @@ import com.gitee.sqlrest.template.SqlMeta; ...@@ -19,7 +20,6 @@ import com.gitee.sqlrest.template.SqlMeta;
import com.gitee.sqlrest.template.XmlSqlTemplate; import com.gitee.sqlrest.template.XmlSqlTemplate;
import com.zaxxer.hikari.HikariDataSource; import com.zaxxer.hikari.HikariDataSource;
import java.sql.Connection; import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
...@@ -36,8 +36,9 @@ public class SqlExecutorService extends AbstractExecutorEngine { ...@@ -36,8 +36,9 @@ public class SqlExecutorService extends AbstractExecutorEngine {
public List<Object> execute(List<ApiContextEntity> scripts, Map<String, Object> params, NamingStrategyEnum strategy) { public List<Object> execute(List<ApiContextEntity> scripts, Map<String, Object> params, NamingStrategyEnum strategy) {
List<Object> dataList = new ArrayList<>(); List<Object> dataList = new ArrayList<>();
try (Connection connection = this.dataSource.getConnection()) { try (Connection connection = this.dataSource.getConnection()) {
boolean supportsTx = connection.getMetaData().supportsTransactions();
try { try {
connection.setAutoCommit(false); LambdaUtils.ifDo(supportsTx, () -> connection.setAutoCommit(false));
for (ApiContextEntity sql : scripts) { for (ApiContextEntity sql : scripts) {
XmlSqlTemplate template = new XmlSqlTemplate(sql.getSqlText()); XmlSqlTemplate template = new XmlSqlTemplate(sql.getSqlText());
SqlMeta sqlMeta = template.process(params); SqlMeta sqlMeta = template.process(params);
...@@ -48,14 +49,10 @@ public class SqlExecutorService extends AbstractExecutorEngine { ...@@ -48,14 +49,10 @@ public class SqlExecutorService extends AbstractExecutorEngine {
dataList.add(result); dataList.add(result);
} }
} }
connection.commit(); LambdaUtils.ifDo(supportsTx, () -> connection.commit());
return dataList; return dataList;
} catch (Exception e) { } catch (Exception e) {
try { LambdaUtils.ifDoIgnoreThrow(supportsTx, () -> connection.rollback());
connection.rollback();
} catch (SQLException se) {
log.warn("Failed to call jdbc Connection::rollback(): {}", se.getMessage(), se);
}
throw e; throw e;
} }
} catch (RuntimeException e) { } catch (RuntimeException e) {
......
...@@ -9,12 +9,12 @@ ...@@ -9,12 +9,12 @@
///////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////
package com.gitee.sqlrest.core.executor; package com.gitee.sqlrest.core.executor;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import com.gitee.sqlrest.common.enums.OnOffEnum; import com.gitee.sqlrest.common.enums.OnOffEnum;
import com.gitee.sqlrest.core.dto.NameValueBaseResponse; import com.gitee.sqlrest.core.dto.NameValueBaseResponse;
import com.gitee.sqlrest.core.dto.TestAlarmConfigRequest; import com.gitee.sqlrest.core.dto.TestAlarmConfigRequest;
import com.gitee.sqlrest.core.dto.UpdateAlarmConfigRequest; import com.gitee.sqlrest.core.dto.UpdateAlarmConfigRequest;
import com.gitee.sqlrest.core.util.AlarmModelUtils;
import com.gitee.sqlrest.persistence.dao.UnifyAlarmDao; import com.gitee.sqlrest.persistence.dao.UnifyAlarmDao;
import com.gitee.sqlrest.persistence.entity.UnifyAlarmEntity; import com.gitee.sqlrest.persistence.entity.UnifyAlarmEntity;
import java.util.ArrayList; import java.util.ArrayList;
...@@ -52,18 +52,7 @@ public class UnifyAlarmOpsService { ...@@ -52,18 +52,7 @@ public class UnifyAlarmOpsService {
} }
public List<NameValueBaseResponse> getExampleDataModel() { public List<NameValueBaseResponse> getExampleDataModel() {
Map<String, String> dataModel = new HashMap<>(8); Map<String, String> dataModel = AlarmModelUtils.getExampleModel();
dataModel.put("path", "/api/test/create");
dataModel.put("method", "POST");
dataModel.put("contentType", "application/json");
dataModel.put("name", "test interface for create");
dataModel.put("description", "this is description!");
dataModel.put("open", "false");
dataModel.put("clientKey", "test");
dataModel.put("ipAddr", "127.0.0.1");
dataModel.put("userAgent", "sqlrest");
dataModel.put("exception", "this is test alarm message");
List<NameValueBaseResponse> lists = new ArrayList<>(); List<NameValueBaseResponse> lists = new ArrayList<>();
dataModel.forEach((k, v) -> lists.add(NameValueBaseResponse.builder().key(k).value(v).build())); dataModel.forEach((k, v) -> lists.add(NameValueBaseResponse.builder().key(k).value(v).build()));
return lists; return lists;
...@@ -91,7 +80,7 @@ public class UnifyAlarmOpsService { ...@@ -91,7 +80,7 @@ public class UnifyAlarmOpsService {
NameValueBaseResponse::getKey, NameValueBaseResponse::getKey,
NameValueBaseResponse::getValue, NameValueBaseResponse::getValue,
(a, b) -> b)); (a, b) -> b));
dataModel.put("accessTime", DateUtil.now()); AlarmModelUtils.setBeforeTestAlarm(dataModel);
handleAlarm(config, dataModel); handleAlarm(config, dataModel);
} }
......
...@@ -19,8 +19,10 @@ import com.gitee.sqlrest.common.exception.ResponseErrorCode; ...@@ -19,8 +19,10 @@ import com.gitee.sqlrest.common.exception.ResponseErrorCode;
import com.gitee.sqlrest.common.exception.UnAuthorizedException; import com.gitee.sqlrest.common.exception.UnAuthorizedException;
import com.gitee.sqlrest.common.exception.UnPermissionException; import com.gitee.sqlrest.common.exception.UnPermissionException;
import com.gitee.sqlrest.common.util.TokenUtils; import com.gitee.sqlrest.common.util.TokenUtils;
import com.gitee.sqlrest.core.exec.RequestParamLogger;
import com.gitee.sqlrest.core.executor.UnifyAlarmOpsService; import com.gitee.sqlrest.core.executor.UnifyAlarmOpsService;
import com.gitee.sqlrest.core.servlet.ClientTokenService; import com.gitee.sqlrest.core.servlet.ClientTokenService;
import com.gitee.sqlrest.core.util.AlarmModelUtils;
import com.gitee.sqlrest.core.util.ServletUtils; import com.gitee.sqlrest.core.util.ServletUtils;
import com.gitee.sqlrest.persistence.dao.ApiAssignmentDao; import com.gitee.sqlrest.persistence.dao.ApiAssignmentDao;
import com.gitee.sqlrest.persistence.entity.AccessRecordEntity; import com.gitee.sqlrest.persistence.entity.AccessRecordEntity;
...@@ -28,12 +30,9 @@ import com.gitee.sqlrest.persistence.entity.ApiAssignmentEntity; ...@@ -28,12 +30,9 @@ import com.gitee.sqlrest.persistence.entity.ApiAssignmentEntity;
import com.gitee.sqlrest.persistence.mapper.AccessRecordMapper; import com.gitee.sqlrest.persistence.mapper.AccessRecordMapper;
import com.google.common.base.Charsets; import com.google.common.base.Charsets;
import java.io.IOException; import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.Filter; import javax.servlet.Filter;
import javax.servlet.FilterChain; import javax.servlet.FilterChain;
...@@ -54,7 +53,8 @@ public class AuthenticationFilter implements Filter { ...@@ -54,7 +53,8 @@ public class AuthenticationFilter implements Filter {
private static final ExecutorService alarmExecutor = ExecutorBuilder.create() private static final ExecutorService alarmExecutor = ExecutorBuilder.create()
.setCorePoolSize(Runtime.getRuntime().availableProcessors()) .setCorePoolSize(Runtime.getRuntime().availableProcessors())
.useArrayBlockingQueue(4096) .useArrayBlockingQueue(8912)
.setHandler(new CallerRunsPolicy())
.build(); .build();
@Resource @Resource
...@@ -157,12 +157,12 @@ public class AuthenticationFilter implements Filter { ...@@ -157,12 +157,12 @@ public class AuthenticationFilter implements Filter {
final long accessTime = accessRecordEntity.getDuration(); final long accessTime = accessRecordEntity.getDuration();
final int httpStatus = response.getStatus(); final int httpStatus = response.getStatus();
accessRecordEntity.setDuration(System.currentTimeMillis() - accessRecordEntity.getDuration()); accessRecordEntity.setDuration(System.currentTimeMillis() - accessRecordEntity.getDuration());
CompletableFuture accessRecordEntity.setParameters(RequestParamLogger.getAndClear());
.runAsync(() -> finishRecord(apiConfigEntity, accessRecordEntity, httpStatus, accessTime), alarmExecutor); alarmExecutor.submit(() -> doRecord(apiConfigEntity, accessRecordEntity, httpStatus, accessTime));
} }
} }
private void finishRecord(ApiAssignmentEntity apiConfigEntity, AccessRecordEntity accessRecord, int httpStatus, private void doRecord(ApiAssignmentEntity apiConfigEntity, AccessRecordEntity accessRecord, int httpStatus,
long accessTimestamp) { long accessTimestamp) {
accessRecordMapper.insert(accessRecord); accessRecordMapper.insert(accessRecord);
if (httpStatus == HttpServletResponse.SC_OK) { if (httpStatus == HttpServletResponse.SC_OK) {
...@@ -172,21 +172,7 @@ public class AuthenticationFilter implements Filter { ...@@ -172,21 +172,7 @@ public class AuthenticationFilter implements Filter {
return; return;
} }
SimpleDateFormat sdFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Map<String, String> dataModel = AlarmModelUtils.getBusinessModel(apiConfigEntity, accessRecord, accessTimestamp);
Map<String, String> dataModel = new HashMap<>(8);
dataModel.put("path", accessRecord.getPath());
dataModel.put("method", apiConfigEntity.getMethod().name());
dataModel.put("contentType", apiConfigEntity.getContentType());
dataModel.put("name", apiConfigEntity.getName());
dataModel.put("description", StringUtils.defaultString(apiConfigEntity.getDescription()));
dataModel.put("open", apiConfigEntity.getOpen().toString());
dataModel.put("clientKey", StringUtils.defaultString(accessRecord.getClientKey()));
dataModel.put("ipAddr", StringUtils.defaultString(accessRecord.getIpAddr()));
dataModel.put("userAgent", StringUtils.defaultString(accessRecord.getUserAgent()));
dataModel.put("exception", StringUtils.defaultString(accessRecord.getException()));
dataModel.put("accessTime", sdFormatter.format(new Date(accessTimestamp)));
unifyAlarmOpsService.triggerAlarm(dataModel); unifyAlarmOpsService.triggerAlarm(dataModel);
} }
......
...@@ -76,6 +76,7 @@ public class OverviewService { ...@@ -76,6 +76,7 @@ public class OverviewService {
.ipAddr(record.getIpAddr()) .ipAddr(record.getIpAddr())
.userAgent(record.getUserAgent()) .userAgent(record.getUserAgent())
.clientApp(map.get(record.getClientKey())) .clientApp(map.get(record.getClientKey()))
.parameters(record.getParameters())
.exception(record.getException()) .exception(record.getException())
.createTime(record.getCreateTime()) .createTime(record.getCreateTime())
.build() .build()
......
// Copyright tang. All rights reserved.
// https://gitee.com/inrgihc/sqlrest
//
// Use of this source code is governed by a BSD-style license
//
// Author: tang (inrgihc@126.com)
// Date : 2024/3/31
// Location: beijing , china
/////////////////////////////////////////////////////////////
package com.gitee.sqlrest.core.util;
import cn.hutool.core.date.DateUtil;
import com.gitee.sqlrest.persistence.entity.AccessRecordEntity;
import com.gitee.sqlrest.persistence.entity.ApiAssignmentEntity;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import lombok.experimental.UtilityClass;
import org.apache.commons.lang3.StringUtils;
@UtilityClass
public class AlarmModelUtils {
private static final ThreadLocal<SimpleDateFormat> threadLocal = ThreadLocal
.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
public static Map<String, String> getExampleModel() {
Map<String, String> dataModel = new HashMap<>(8);
dataModel.put("path", "/api/test/create");
dataModel.put("method", "POST");
dataModel.put("contentType", "application/json");
dataModel.put("name", "test interface for create");
dataModel.put("description", "this is description!");
dataModel.put("open", "false");
dataModel.put("clientKey", "test");
dataModel.put("ipAddr", "127.0.0.1");
dataModel.put("userAgent", "sqlrest");
dataModel.put("exception", "this is test alarm message");
return dataModel;
}
public static void setBeforeTestAlarm(Map<String, String> dataModel) {
dataModel.put("accessTime", DateUtil.now());
}
public static Map<String, String> getBusinessModel(
ApiAssignmentEntity apiConfigEntity, AccessRecordEntity accessRecord, long accessTimestamp) {
Map<String, String> dataModel = new HashMap<>(8);
dataModel.put("path", accessRecord.getPath());
dataModel.put("method", apiConfigEntity.getMethod().name());
dataModel.put("contentType", apiConfigEntity.getContentType());
dataModel.put("name", apiConfigEntity.getName());
dataModel.put("description", StringUtils.defaultString(apiConfigEntity.getDescription()));
dataModel.put("open", apiConfigEntity.getOpen().toString());
dataModel.put("clientKey", StringUtils.defaultString(accessRecord.getClientKey()));
dataModel.put("ipAddr", StringUtils.defaultString(accessRecord.getIpAddr()));
dataModel.put("userAgent", StringUtils.defaultString(accessRecord.getUserAgent()));
dataModel.put("exception", StringUtils.defaultString(accessRecord.getException()));
dataModel.put("accessTime", threadLocal.get().format(new Date(accessTimestamp)));
return dataModel;
}
}
...@@ -11,6 +11,7 @@ package com.gitee.sqlrest.core.util; ...@@ -11,6 +11,7 @@ package com.gitee.sqlrest.core.util;
import com.gitee.sqlrest.common.enums.NamingStrategyEnum; import com.gitee.sqlrest.common.enums.NamingStrategyEnum;
import com.gitee.sqlrest.common.enums.ProductTypeEnum; import com.gitee.sqlrest.common.enums.ProductTypeEnum;
import com.gitee.sqlrest.common.util.LambdaUtils;
import com.gitee.sqlrest.core.exec.SqlExecuteLogger; import com.gitee.sqlrest.core.exec.SqlExecuteLogger;
import com.gitee.sqlrest.template.SqlMeta; import com.gitee.sqlrest.template.SqlMeta;
import java.sql.Connection; import java.sql.Connection;
...@@ -21,6 +22,8 @@ import java.util.ArrayList; ...@@ -21,6 +22,8 @@ import java.util.ArrayList;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
...@@ -32,7 +35,7 @@ public class SqlJdbcUtils { ...@@ -32,7 +35,7 @@ public class SqlJdbcUtils {
private static final int QUERY_TIMEOUT = 300; private static final int QUERY_TIMEOUT = 300;
public static Function<String, String> getConverter(NamingStrategyEnum strategy) { public static Function<String, String> getConverter(NamingStrategyEnum strategy) {
return (null == strategy) ? Function.identity() : strategy.getFunction(); return Objects.isNull(strategy) ? Function.identity() : strategy.getFunction();
} }
public static Object execute(ProductTypeEnum productType, Connection connection, SqlMeta sqlMeta, public static Object execute(ProductTypeEnum productType, Connection connection, SqlMeta sqlMeta,
...@@ -40,12 +43,12 @@ public class SqlJdbcUtils { ...@@ -40,12 +43,12 @@ public class SqlJdbcUtils {
List<Object> paramValues = sqlMeta.getParameter(); List<Object> paramValues = sqlMeta.getParameter();
boolean isQuerySql = sqlMeta.isQuerySQL(); boolean isQuerySql = sqlMeta.isQuerySQL();
String sql = isQuerySql ? productType.getPageSql(sqlMeta.getSql(), page, size) : sqlMeta.getSql(); String sql = isQuerySql ? productType.getPageSql(sqlMeta.getSql(), page, size) : sqlMeta.getSql();
Consumer<Connection> executeBeforeQuery = productType.getContext().getExecuteBeforeQuery();
LambdaUtils.ifDo(Objects.nonNull(executeBeforeQuery), () -> executeBeforeQuery.accept(connection));
PreparedStatement statement = connection.prepareStatement(sql); PreparedStatement statement = connection.prepareStatement(sql);
statement.setQueryTimeout(QUERY_TIMEOUT); statement.setQueryTimeout(QUERY_TIMEOUT);
statement.setFetchSize(isMySqlConnection(connection) ? Integer.MIN_VALUE : size); statement.setFetchSize(isMySqlConnection(connection) ? Integer.MIN_VALUE : size);
if (isQuerySql) { LambdaUtils.ifDo(isQuerySql, () -> productType.getPageConsumer().accept(page, size, paramValues));
productType.getPageConsumer().accept(page, size, paramValues);
}
for (int i = 1; i <= paramValues.size(); i++) { for (int i = 1; i <= paramValues.size(); i++) {
statement.setObject(i, paramValues.get(i - 1)); statement.setObject(i, paramValues.get(i - 1));
} }
...@@ -93,5 +96,4 @@ public class SqlJdbcUtils { ...@@ -93,5 +96,4 @@ public class SqlJdbcUtils {
return false; return false;
} }
} }
} }
...@@ -659,14 +659,6 @@ ...@@ -659,14 +659,6 @@
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作"
v-if="!isOnlyShowDetail"
min-width="15%">
<template slot-scope="scope">
<el-link icon="el-icon-delete"
@click="deleteDebugParamsItem(scope.$index)"></el-link>
</template>
</el-table-column>
</el-table> </el-table>
</el-col> </el-col>
</el-row> </el-row>
...@@ -1635,9 +1627,6 @@ export default { ...@@ -1635,9 +1627,6 @@ export default {
this.showDebugDrawer = true this.showDebugDrawer = true
} }
}, },
deleteDebugParamsItem: function (index) {
this.debugParams.splice(index, 1);
},
addArrayValuesItem: function (row) { addArrayValuesItem: function (row) {
row.arrayValues.push(''); row.arrayValues.push('');
}, },
......
...@@ -226,17 +226,17 @@ ...@@ -226,17 +226,17 @@
<el-table-column label="地址" <el-table-column label="地址"
prop="ipAddr" prop="ipAddr"
:show-overflow-tooltip="true" :show-overflow-tooltip="true"
min-width="20%"> min-width="15%">
</el-table-column> </el-table-column>
<el-table-column label="HTTP状态" <el-table-column label="状态码"
prop="status" prop="status"
:show-overflow-tooltip="true" :show-overflow-tooltip="true"
min-width="10%"> min-width="12%">
</el-table-column> </el-table-column>
<el-table-column label="耗时(毫秒)" <el-table-column label="耗时ms"
prop="duration" prop="duration"
:show-overflow-tooltip="true" :show-overflow-tooltip="true"
min-width="15%"> min-width="12%">
</el-table-column> </el-table-column>
<el-table-column label="调用方" <el-table-column label="调用方"
prop="clientApp" prop="clientApp"
...@@ -246,7 +246,21 @@ ...@@ -246,7 +246,21 @@
<el-table-column label="UserAgent" <el-table-column label="UserAgent"
prop="userAgent" prop="userAgent"
:show-overflow-tooltip="true" :show-overflow-tooltip="true"
min-width="15%">
</el-table-column>
<el-table-column label="查看"
min-width="20%"> min-width="20%">
<template slot-scope="scope">
<el-link class="btn-text"
type="primary"
@click="handleShowParam(scope.$index, scope.row)">入参</el-link>
<label v-if="scope.row.exception"
class="btn-style">&nbsp;|&nbsp;</label>
<el-link class="btn-text"
v-if="scope.row.exception"
type="primary"
@click="handleShowException(scope.$index, scope.row)">异常</el-link>
</template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<div class="page" <div class="page"
...@@ -263,11 +277,42 @@ ...@@ -263,11 +277,42 @@
</el-tabs> </el-tabs>
</div> </div>
</div> </div>
<el-dialog title="接口请求入参"
:visible.sync="showParamDialogVisible"
:showClose="false">
<json-viewer :value="requestParameters"
:expand-depth=10
copyable
boxed
sort></json-viewer>
<div slot="footer"
class="dialog-footer">
<el-button type="info"
@click="showParamDialogVisible = false">关 闭</el-button>
</div>
</el-dialog>
<el-dialog title="接口异常信息"
:visible.sync="showExceptDialogVisible"
:showClose="false">
<el-input type="textarea"
:rows="20"
:spellcheck="false"
v-model="exeptionText"></el-input>
<div slot="footer"
class="dialog-footer">
<el-button type="info"
@click="showExceptDialogVisible = false">关 闭</el-button>
</div>
</el-dialog>
</el-card> </el-card>
</template> </template>
<script> <script>
import '@/assets/sysicon/iconfont.js' import '@/assets/sysicon/iconfont.js'
import JsonViewer from 'vue-json-viewer';
export default { export default {
data () { data () {
...@@ -308,8 +353,13 @@ export default { ...@@ -308,8 +353,13 @@ export default {
currentAccessPageNum: 1, currentAccessPageNum: 1,
currentAccessPageSize: 10, currentAccessPageSize: 10,
totalAccessItemCount: 0, totalAccessItemCount: 0,
showParamDialogVisible: false,
requestParameters: null,
showExceptDialogVisible: false,
exeptionText: null,
}; };
}, },
components: { JsonViewer },
mounted () { mounted () {
window.addEventListener('resize', this.initResize); window.addEventListener('resize', this.initResize);
this.initResize(); this.initResize();
...@@ -532,6 +582,14 @@ export default { ...@@ -532,6 +582,14 @@ export default {
} }
}); });
}, },
handleShowParam: function (index, row) {
this.requestParameters = row.parameters;
this.showParamDialogVisible = true;
},
handleShowException: function (index, row) {
this.exeptionText = row.exception;
this.showExceptDialogVisible = true;
},
handleSizeChange: function (pageSize) { handleSizeChange: function (pageSize) {
this.currentPageSize = pageSize; this.currentPageSize = pageSize;
this.reloadInterfaceList() this.reloadInterfaceList()
...@@ -623,4 +681,14 @@ export default { ...@@ -623,4 +681,14 @@ export default {
font-size: 13px; font-size: 13px;
padding: 2px; padding: 2px;
} }
.btn-style {
color: #e9e9f3;
}
.btn-text {
font-size: 12px;
color: #6873ce;
}
</style> </style>
...@@ -13,3 +13,5 @@ databaseChangeLog: ...@@ -13,3 +13,5 @@ databaseChangeLog:
file: classpath:db/changelog/log-v1.2.2.yaml file: classpath:db/changelog/log-v1.2.2.yaml
- include: - include:
file: classpath:db/changelog/log-v1.3.1.yaml file: classpath:db/changelog/log-v1.3.1.yaml
- include:
file: classpath:db/changelog/log-v1.4.1.yaml
\ No newline at end of file
databaseChangeLog:
- changeSet:
id: 1.4.1
author: sqlrest
runOnChange: false
changes:
- sqlFile:
encoding: UTF-8
path: db/migration/V1_4_1__system-ddl.sql
ALTER TABLE `SQLREST_ACCESS_RECORD`
MODIFY COLUMN `exception` longtext DEFAULT NULL COMMENT '错误日志' AFTER `api_id`,
ADD COLUMN `parameters` longtext DEFAULT NULL COMMENT '请求入参' AFTER `api_id`;
<!DOCTYPE html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>SQLREST工具</title><link href=/static/css/app.c56cd828f1ea67415f269cea66eb599c.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=/static/js/manifest.0ea232aa506478d9e821.js></script><script type=text/javascript src=/static/js/vendor.a6ebeac16c85a178c5e7.js></script><script type=text/javascript src=/static/js/app.2c1ec8f3a08d363c1c13.js></script></body></html> <!DOCTYPE html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>SQLREST工具</title><link href=/static/css/app.9ba04d178315df50a5f4fb989ce06c76.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=/static/js/manifest.724bfd6d8007e626ac38.js></script><script type=text/javascript src=/static/js/vendor.a6ebeac16c85a178c5e7.js></script><script type=text/javascript src=/static/js/app.2c1ec8f3a08d363c1c13.js></script></body></html>
\ No newline at end of file \ No newline at end of file
...@@ -13,3 +13,5 @@ databaseChangeLog: ...@@ -13,3 +13,5 @@ databaseChangeLog:
file: classpath:pg/changelog/log-v1.2.2.yaml file: classpath:pg/changelog/log-v1.2.2.yaml
- include: - include:
file: classpath:pg/changelog/log-v1.3.1.yaml file: classpath:pg/changelog/log-v1.3.1.yaml
- include:
file: classpath:pg/changelog/log-v1.4.1.yaml
\ No newline at end of file
databaseChangeLog:
- changeSet:
id: 1.4.1
author: sqlrest
runOnChange: false
changes:
- sqlFile:
encoding: UTF-8
path: pg/migration/V1_4_1__system-ddl.sql
ALTER TABLE SQLREST_ACCESS_RECORD ADD COLUMN "parameters" text default null;
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
!function(e){var n=window.webpackJsonp;window.webpackJsonp=function(r,f,a){for(var o,d,b,i=0,u=[];i<r.length;i++)d=r[i],c[d]&&u.push(c[d][0]),c[d]=0;for(o in f)Object.prototype.hasOwnProperty.call(f,o)&&(e[o]=f[o]);for(n&&n(r,f,a);u.length;)u.shift()();if(a)for(i=0;i<a.length;i++)b=t(t.s=a[i]);return b};var r={},c={28:0};function t(n){if(r[n])return r[n].exports;var c=r[n]={i:n,l:!1,exports:{}};return e[n].call(c.exports,c,c.exports,t),c.l=!0,c.exports}t.e=function(e){var n=c[e];if(0===n)return new Promise(function(e){e()});if(n)return n[2];var r=new Promise(function(r,t){n=c[e]=[r,t]});n[2]=r;var f=document.getElementsByTagName("head")[0],a=document.createElement("script");a.type="text/javascript",a.charset="utf-8",a.async=!0,a.timeout=12e4,t.nc&&a.setAttribute("nonce",t.nc),a.src=t.p+"static/js/"+e+"."+{0:"7c8226b7a63740af231c",1:"e25df47f04ee43bfc49e",2:"7a542807ad5499534f0b",3:"776d791724a8de12ff9e",4:"f8494b8dd039413f79c8",5:"404ff5302fc6ee181ee9",6:"8f85de06573e2a5f9562",7:"061807fe4716131f26f8",8:"c4a2e9952c298efc080c",9:"313072ac394fc9349d2f",10:"0591dbe3e75f89e4c00e",11:"9ccf6e8ba19ce146e66b",12:"d26d5fe93a45bd5c6eaa",13:"bfc06db76836c228f491",14:"b74db4e8e5c2f13b4c43",15:"d8a7cd9843e13fa1b5eb",16:"9a6082d7311beb531ffe",17:"ca3a537c0792f7b8e00f",18:"5096122498e2cfe23bfa",19:"492e3884353940300fa9",20:"7ac0693f49a00ab51b3e",21:"1056a6edefc50b64f16b",22:"0a5f684edcb8df816a5d",23:"93251b045354cc966a59",24:"61c786230b6da7b9ddc7",25:"b0986b0eaecd37184d01"}[e]+".js";var o=setTimeout(d,12e4);function d(){a.onerror=a.onload=null,clearTimeout(o);var n=c[e];0!==n&&(n&&n[1](new Error("Loading chunk "+e+" failed.")),c[e]=void 0)}return a.onerror=a.onload=d,f.appendChild(a),r},t.m=e,t.c=r,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},t.p="/",t.oe=function(e){throw console.error(e),e}}([]);
//# sourceMappingURL=manifest.0ea232aa506478d9e821.js.map
\ No newline at end of file
!function(e){var n=window.webpackJsonp;window.webpackJsonp=function(r,f,a){for(var o,d,b,i=0,u=[];i<r.length;i++)d=r[i],t[d]&&u.push(t[d][0]),t[d]=0;for(o in f)Object.prototype.hasOwnProperty.call(f,o)&&(e[o]=f[o]);for(n&&n(r,f,a);u.length;)u.shift()();if(a)for(i=0;i<a.length;i++)b=c(c.s=a[i]);return b};var r={},t={28:0};function c(n){if(r[n])return r[n].exports;var t=r[n]={i:n,l:!1,exports:{}};return e[n].call(t.exports,t,t.exports,c),t.l=!0,t.exports}c.e=function(e){var n=t[e];if(0===n)return new Promise(function(e){e()});if(n)return n[2];var r=new Promise(function(r,c){n=t[e]=[r,c]});n[2]=r;var f=document.getElementsByTagName("head")[0],a=document.createElement("script");a.type="text/javascript",a.charset="utf-8",a.async=!0,a.timeout=12e4,c.nc&&a.setAttribute("nonce",c.nc),a.src=c.p+"static/js/"+e+"."+{0:"1e9dbf4280bc4e974d1e",1:"e25df47f04ee43bfc49e",2:"7a542807ad5499534f0b",3:"776d791724a8de12ff9e",4:"f8494b8dd039413f79c8",5:"404ff5302fc6ee181ee9",6:"8f85de06573e2a5f9562",7:"061807fe4716131f26f8",8:"c4a2e9952c298efc080c",9:"313072ac394fc9349d2f",10:"0591dbe3e75f89e4c00e",11:"9ccf6e8ba19ce146e66b",12:"d26d5fe93a45bd5c6eaa",13:"273a9f8bb4b4f6d81eca",14:"b74db4e8e5c2f13b4c43",15:"d8a7cd9843e13fa1b5eb",16:"9a6082d7311beb531ffe",17:"ca3a537c0792f7b8e00f",18:"5096122498e2cfe23bfa",19:"492e3884353940300fa9",20:"7ac0693f49a00ab51b3e",21:"1056a6edefc50b64f16b",22:"0a5f684edcb8df816a5d",23:"93251b045354cc966a59",24:"61c786230b6da7b9ddc7",25:"b0986b0eaecd37184d01"}[e]+".js";var o=setTimeout(d,12e4);function d(){a.onerror=a.onload=null,clearTimeout(o);var n=t[e];0!==n&&(n&&n[1](new Error("Loading chunk "+e+" failed.")),t[e]=void 0)}return a.onerror=a.onload=d,f.appendChild(a),r},c.m=e,c.c=r,c.d=function(e,n,r){c.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},c.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return c.d(n,"a",n),n},c.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},c.p="/",c.oe=function(e){throw console.error(e),e}}([]);
//# sourceMappingURL=manifest.724bfd6d8007e626ac38.js.map
\ No newline at end of file
...@@ -14,7 +14,9 @@ import com.baomidou.mybatisplus.annotation.IdType; ...@@ -14,7 +14,9 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.gitee.sqlrest.persistence.handler.ParamMapHandler;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.Map;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
...@@ -51,6 +53,9 @@ public class AccessRecordEntity { ...@@ -51,6 +53,9 @@ public class AccessRecordEntity {
@TableField("api_id") @TableField("api_id")
private Long apiId; private Long apiId;
@TableField(value = "parameters", typeHandler = ParamMapHandler.class)
private Map<String, Object> parameters;
@TableField("exception") @TableField("exception")
private String exception; private String exception;
......
// Copyright tang. All rights reserved.
// https://gitee.com/inrgihc/sqlrest
//
// Use of this source code is governed by a BSD-style license
//
// Author: tang (inrgihc@126.com)
// Date : 2024/3/31
// Location: beijing , china
/////////////////////////////////////////////////////////////
package com.gitee.sqlrest.persistence.handler;
import com.fasterxml.jackson.core.type.TypeReference;
import com.gitee.sqlrest.persistence.util.JsonUtils;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
public class ParamMapHandler extends BaseTypeHandler<Map<String, Object>> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Map<String, Object> value, JdbcType jdbcType)
throws SQLException {
ps.setString(i, map2string(value));
}
@Override
public Map<String, Object> getNullableResult(ResultSet rs, String columnName) throws SQLException {
return string2map(rs.getString(columnName));
}
@Override
public Map<String, Object> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return string2map(rs.getString(columnIndex));
}
@Override
public Map<String, Object> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return string2map(cs.getString(columnIndex));
}
private String map2string(Map<String, Object> map) {
if (map == null || map.isEmpty()) {
return null;
}
return JsonUtils.toJsonString(map);
}
private Map<String, Object> string2map(String str) {
if (str == null || str.isEmpty()) {
return new HashMap<>(2);
}
return JsonUtils.toBeanType(str, new TypeReference<Map<String, Object>>() {
});
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment