mirror of
https://gitee.com/ssssssss-team/magic-api.git
synced 2026-06-09 10:23:53 +08:00
WebSocket集群处理。
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
package org.ssssssss.magicapi.spring.boot.starter;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* 集群配置
|
||||
* @since 1.2.0
|
||||
@@ -14,7 +16,7 @@ public class ClusterConfig {
|
||||
/**
|
||||
* 实例ID,集群环境下,要保证每台机器不同。默认启动后随机生成uuid
|
||||
*/
|
||||
private String instanceId;
|
||||
private String instanceId = UUID.randomUUID().toString();
|
||||
|
||||
/**
|
||||
* redis 通道
|
||||
|
||||
@@ -120,6 +120,8 @@ public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketCon
|
||||
*/
|
||||
private final ObjectProvider<List<MagicFunction>> magicFunctionsProvider;
|
||||
|
||||
private final ObjectProvider<MagicNotifyService> magicNotifyServiceProvider;
|
||||
|
||||
private final Environment environment;
|
||||
|
||||
private final MagicCorsFilter magicCorsFilter = new MagicCorsFilter();
|
||||
@@ -145,6 +147,7 @@ public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketCon
|
||||
ObjectProvider<List<ColumnMapperProvider>> columnMapperProvidersProvider,
|
||||
ObjectProvider<List<MagicFunction>> magicFunctionsProvider,
|
||||
ObjectProvider<RestTemplate> restTemplateProvider,
|
||||
ObjectProvider<MagicNotifyService> magicNotifyServiceProvider,
|
||||
ObjectProvider<AuthorizationInterceptor> authorizationInterceptorProvider,
|
||||
Environment environment,
|
||||
ApplicationContext applicationContext
|
||||
@@ -158,6 +161,7 @@ public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketCon
|
||||
this.columnMapperProvidersProvider = columnMapperProvidersProvider;
|
||||
this.magicFunctionsProvider = magicFunctionsProvider;
|
||||
this.restTemplateProvider = restTemplateProvider;
|
||||
this.magicNotifyServiceProvider = magicNotifyServiceProvider;
|
||||
this.authorizationInterceptorProvider = authorizationInterceptorProvider;
|
||||
this.environment = environment;
|
||||
this.applicationContext = applicationContext;
|
||||
@@ -352,9 +356,8 @@ public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketCon
|
||||
ResultProvider resultProvider,
|
||||
MagicDynamicDataSource magicDynamicDataSource,
|
||||
MagicFunctionManager magicFunctionManager,
|
||||
MagicNotifyService magicNotifyService,
|
||||
Resource workspace) {
|
||||
return new DefaultMagicAPIService(mappingHandlerMapping, apiServiceProvider, functionServiceProvider, groupServiceProvider, resultProvider, magicDynamicDataSource, magicFunctionManager, magicNotifyService, properties.getClusterConfig().getInstanceId(), workspace, properties.isThrowException());
|
||||
return new DefaultMagicAPIService(mappingHandlerMapping, apiServiceProvider, functionServiceProvider, groupServiceProvider, resultProvider, magicDynamicDataSource, magicFunctionManager, magicNotifyServiceProvider.getObject(), properties.getClusterConfig().getInstanceId(), workspace, properties.isThrowException());
|
||||
}
|
||||
|
||||
private void setupSpringSecurity() {
|
||||
@@ -584,9 +587,10 @@ public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketCon
|
||||
public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
|
||||
String web = properties.getWeb();
|
||||
if (web != null) {
|
||||
WebSocketHandlerRegistration registration = webSocketHandlerRegistry.addHandler(new MagicWebSocketDispatcher(Arrays.asList(
|
||||
MagicWebSocketDispatcher dispatcher = new MagicWebSocketDispatcher(properties.getClusterConfig().getInstanceId(),magicNotifyServiceProvider.getObject(), Arrays.asList(
|
||||
new MagicDebugHandler()
|
||||
)), web + "/console");
|
||||
));
|
||||
WebSocketHandlerRegistration registration = webSocketHandlerRegistry.addHandler(dispatcher, web + "/console");
|
||||
if (properties.isSupportCrossDomain()) {
|
||||
registration.setAllowedOrigins("*");
|
||||
}
|
||||
|
||||
@@ -3,9 +3,12 @@ package org.ssssssss.magicapi.config;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.socket.TextMessage;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
import org.ssssssss.magicapi.model.Constants;
|
||||
import org.ssssssss.magicapi.model.MagicConsoleSession;
|
||||
import org.ssssssss.magicapi.model.MagicNotify;
|
||||
import org.ssssssss.magicapi.provider.MagicNotifyService;
|
||||
import org.ssssssss.magicapi.utils.JsonUtils;
|
||||
import org.ssssssss.script.MagicScriptDebugContext;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
@@ -13,60 +16,84 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class WebSocketSessionManager {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(WebSocketSessionManager.class);
|
||||
private static final Logger logger = LoggerFactory.getLogger(WebSocketSessionManager.class);
|
||||
|
||||
private static final Map<String, WebSocketSession> SESSION = new ConcurrentHashMap<>();
|
||||
private static final Map<String, MagicConsoleSession> SESSION = new ConcurrentHashMap<>();
|
||||
|
||||
public static void add(WebSocketSession session) {
|
||||
private static MagicNotifyService magicNotifyService;
|
||||
|
||||
private static String instanceId;
|
||||
|
||||
public static void add(MagicConsoleSession session) {
|
||||
SESSION.put(session.getId(), session);
|
||||
}
|
||||
|
||||
public static void remove(WebSocketSession session) {
|
||||
SESSION.remove(session.getId());
|
||||
public static void remove(MagicConsoleSession session) {
|
||||
if(session.getId() != null){
|
||||
remove(session.getId());
|
||||
}
|
||||
}
|
||||
|
||||
public static void remove(String sessionId) {
|
||||
SESSION.remove(sessionId);
|
||||
}
|
||||
|
||||
public static void sendBySessionId(String sessionId, MessageType messageType, Object... values) {
|
||||
WebSocketSession session = findSession(sessionId);
|
||||
if (session != null) {
|
||||
StringBuilder builder = new StringBuilder(messageType.name().toLowerCase());
|
||||
if (values != null) {
|
||||
for (int i = 0, len = values.length; i < len; i++) {
|
||||
builder.append(",");
|
||||
Object value = values[i];
|
||||
if (i + 1 < len || value instanceof CharSequence || value instanceof Number) {
|
||||
builder.append(value);
|
||||
} else {
|
||||
builder.append(JsonUtils.toJsonString(value));
|
||||
}
|
||||
MagicConsoleSession session = findSession(sessionId);
|
||||
StringBuilder builder = new StringBuilder(messageType.name().toLowerCase());
|
||||
if (values != null) {
|
||||
for (int i = 0, len = values.length; i < len; i++) {
|
||||
builder.append(",");
|
||||
Object value = values[i];
|
||||
if (i + 1 < len || value instanceof CharSequence || value instanceof Number) {
|
||||
builder.append(value);
|
||||
} else {
|
||||
builder.append(JsonUtils.toJsonString(value));
|
||||
}
|
||||
}
|
||||
try {
|
||||
session.sendMessage(new TextMessage(builder.toString()));
|
||||
} catch (IOException e) {
|
||||
logger.error("发送WebSocket消息失败", e);
|
||||
}
|
||||
}
|
||||
if (session != null && session.writeable()) {
|
||||
sendBySession(session, builder.toString());
|
||||
} else if(magicNotifyService != null){
|
||||
// 通知其他机器去发送消息
|
||||
magicNotifyService.sendNotify(new MagicNotify(instanceId, Constants.NOTIFY_WS_S_C, sessionId, builder.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Session中的属性
|
||||
*/
|
||||
public static <T> T getSessionAttribute(String sessionId, String key) {
|
||||
WebSocketSession session = findSession(sessionId);
|
||||
public static void sendBySessionId(String sessionId, String content){
|
||||
MagicConsoleSession session = findSession(sessionId);
|
||||
if (session != null) {
|
||||
return (T) session.getAttributes().get(key);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void setSessionAttribute(String sessionId, String key, Object value) {
|
||||
WebSocketSession session = findSession(sessionId);
|
||||
if (session != null) {
|
||||
session.getAttributes().put(key, value);
|
||||
sendBySession(session, content);
|
||||
}
|
||||
}
|
||||
|
||||
private static WebSocketSession findSession(String sessionId) {
|
||||
return SESSION.values().stream().filter(it -> sessionId.equals(it.getAttributes().get(Constants.WS_DEBUG_SESSION_KEY))).findFirst().orElse(null);
|
||||
public static void sendBySession(MagicConsoleSession session, String content){
|
||||
try {
|
||||
session.getWebSocketSession().sendMessage(new TextMessage(content));
|
||||
} catch (IOException e) {
|
||||
logger.error("发送WebSocket消息失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static MagicConsoleSession findSession(String sessionId) {
|
||||
return SESSION.get(sessionId);
|
||||
}
|
||||
|
||||
public static void setMagicNotifyService(MagicNotifyService magicNotifyService) {
|
||||
WebSocketSessionManager.magicNotifyService = magicNotifyService;
|
||||
}
|
||||
|
||||
public static void setInstanceId(String instanceId) {
|
||||
WebSocketSessionManager.instanceId = instanceId;
|
||||
}
|
||||
|
||||
public static void createSession(String sessionId, MagicScriptDebugContext debugContext){
|
||||
MagicConsoleSession consoleSession = SESSION.get(sessionId);
|
||||
if(consoleSession == null){
|
||||
consoleSession = new MagicConsoleSession(sessionId, debugContext);
|
||||
SESSION.put(sessionId, consoleSession);
|
||||
}else{
|
||||
consoleSession.setMagicScriptDebugContext(debugContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,47 +1,57 @@
|
||||
package org.ssssssss.magicapi.controller;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
import org.ssssssss.magicapi.config.Message;
|
||||
import org.ssssssss.magicapi.config.MessageType;
|
||||
import org.ssssssss.magicapi.model.Constants;
|
||||
import org.ssssssss.magicapi.config.WebSocketSessionManager;
|
||||
import org.ssssssss.magicapi.model.MagicConsoleSession;
|
||||
import org.ssssssss.script.MagicScriptDebugContext;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
|
||||
public class MagicDebugHandler {
|
||||
|
||||
/**
|
||||
* 设置会话ID
|
||||
* 只在本机处理。
|
||||
*/
|
||||
@Message(MessageType.SET_SESSION_ID)
|
||||
public void setSessionId(WebSocketSession session, String sessionId) {
|
||||
if(StringUtils.isNotBlank(sessionId)){
|
||||
session.getAttributes().put(Constants.WS_DEBUG_SESSION_KEY, sessionId);
|
||||
}
|
||||
public void setSessionId(MagicConsoleSession session, String sessionId) {
|
||||
WebSocketSessionManager.remove(session);
|
||||
session.setId(sessionId);
|
||||
WebSocketSessionManager.add(session);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置断点
|
||||
* 当本机没有该Session时,通知其他机器处理
|
||||
*/
|
||||
@Message(MessageType.SET_BREAKPOINT)
|
||||
public void setBreakPoint(WebSocketSession session, String breakpoints) {
|
||||
if(StringUtils.isNotBlank(breakpoints)){
|
||||
MagicScriptDebugContext context = (MagicScriptDebugContext) session.getAttributes().get(Constants.WS_DEBUG_MAGIC_SCRIPT_CONTEXT);
|
||||
public boolean setBreakPoint(MagicConsoleSession session, String breakpoints) {
|
||||
MagicScriptDebugContext context = session.getMagicScriptDebugContext();
|
||||
if (context != null) {
|
||||
context.setBreakpoints(Stream.of(breakpoints.split(",")).map(Integer::valueOf).collect(Collectors.toList()));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复断点
|
||||
* 当本机没有该Session时,通知其他机器处理
|
||||
*/
|
||||
@Message(MessageType.RESUME_BREAKPOINT)
|
||||
public void resumeBreakpoint(WebSocketSession session, String stepInto) {
|
||||
MagicScriptDebugContext context = (MagicScriptDebugContext) session.getAttributes().get(Constants.WS_DEBUG_MAGIC_SCRIPT_CONTEXT);
|
||||
context.setStepInto("1".equals(stepInto));
|
||||
try {
|
||||
context.singal();
|
||||
} catch (InterruptedException ignored) {
|
||||
public boolean resumeBreakpoint(MagicConsoleSession session, String stepInto) {
|
||||
MagicScriptDebugContext context = session.getMagicScriptDebugContext();
|
||||
if (context != null) {
|
||||
context.setStepInto("1".equals(stepInto));
|
||||
try {
|
||||
context.singal();
|
||||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,10 @@ import org.springframework.web.socket.WebSocketSession;
|
||||
import org.springframework.web.socket.handler.TextWebSocketHandler;
|
||||
import org.ssssssss.magicapi.config.Message;
|
||||
import org.ssssssss.magicapi.config.WebSocketSessionManager;
|
||||
import org.ssssssss.magicapi.model.Constants;
|
||||
import org.ssssssss.magicapi.model.MagicConsoleSession;
|
||||
import org.ssssssss.magicapi.model.MagicNotify;
|
||||
import org.ssssssss.magicapi.provider.MagicNotifyService;
|
||||
import org.ssssssss.magicapi.utils.JsonUtils;
|
||||
import org.ssssssss.script.reflection.MethodInvoker;
|
||||
|
||||
@@ -20,9 +24,17 @@ public class MagicWebSocketDispatcher extends TextWebSocketHandler {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(MagicWebSocketDispatcher.class);
|
||||
|
||||
private final Map<String, MethodInvoker> handlers = new HashMap<>();
|
||||
private static final Map<String, MethodInvoker> handlers = new HashMap<>();
|
||||
|
||||
public MagicWebSocketDispatcher(List<Object> websocketMessageHandlers) {
|
||||
private final String instanceId;
|
||||
|
||||
private final MagicNotifyService magicNotifyService;
|
||||
|
||||
public MagicWebSocketDispatcher(String instanceId, MagicNotifyService magicNotifyService, List<Object> websocketMessageHandlers) {
|
||||
this.instanceId = instanceId;
|
||||
this.magicNotifyService = magicNotifyService;
|
||||
WebSocketSessionManager.setMagicNotifyService(magicNotifyService);
|
||||
WebSocketSessionManager.setInstanceId(instanceId);
|
||||
websocketMessageHandlers.forEach(websocketMessageHandler ->
|
||||
Stream.of(websocketMessageHandler.getClass().getDeclaredMethods())
|
||||
.forEach(method -> handlers.put(method.getAnnotation(Message.class).value().name().toLowerCase(), new MethodInvoker(method, websocketMessageHandler)))
|
||||
@@ -30,51 +42,64 @@ public class MagicWebSocketDispatcher extends TextWebSocketHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
|
||||
WebSocketSessionManager.add(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
|
||||
WebSocketSessionManager.remove(session);
|
||||
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
|
||||
MagicConsoleSession.remove(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleTextMessage(WebSocketSession session, TextMessage message) {
|
||||
MagicConsoleSession consoleSession = MagicConsoleSession.from(session);
|
||||
Object returnValue = findHandleAndInvoke(consoleSession, message.getPayload());
|
||||
// 如果未成功处理消息,则通知其他机器去处理消息
|
||||
if (Boolean.FALSE.equals(returnValue)) {
|
||||
magicNotifyService.sendNotify(new MagicNotify(instanceId, Constants.NOTIFY_WS_C_S, consoleSession.getId(), message.getPayload()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static Object findHandleAndInvoke(MagicConsoleSession session, String payload) {
|
||||
// messageType[, data][,data]
|
||||
String payload = message.getPayload();
|
||||
int index = payload.indexOf(",");
|
||||
String msgType = index == -1 ? payload : payload.substring(0, index);
|
||||
MethodInvoker invoker = handlers.get(msgType);
|
||||
if (invoker != null) {
|
||||
Object returnValue;
|
||||
try {
|
||||
Class<?>[] pTypes = invoker.getParameterTypes();
|
||||
int pCount = pTypes.length;
|
||||
if (pCount == 0) {
|
||||
invoker.invoke0(null, null);
|
||||
returnValue = invoker.invoke0(null, null);
|
||||
} else {
|
||||
Object[] pValues = new Object[pCount];
|
||||
for (int i = 0; i < pCount; i++) {
|
||||
Class<?> pType = pTypes[i];
|
||||
if (pType == WebSocketSession.class) {
|
||||
if (pType == MagicConsoleSession.class) {
|
||||
pValues[i] = session;
|
||||
} else if (pType == String.class) {
|
||||
int subIndex = payload.indexOf(",", index + 1);
|
||||
if (subIndex > -1) {
|
||||
pValues[i] = payload.substring(index + 1, index = subIndex);
|
||||
} else if(index > -1){
|
||||
} else if (index > -1) {
|
||||
pValues[i] = payload.substring(index + 1);
|
||||
}
|
||||
} else {
|
||||
pValues[i] = JsonUtils.readValue(payload, pType);
|
||||
}
|
||||
}
|
||||
invoker.invoke0(null, null, pValues);
|
||||
returnValue = invoker.invoke0(null, null, pValues);
|
||||
}
|
||||
return returnValue;
|
||||
} catch (Throwable e) {
|
||||
logger.error("WebSocket消息处理出错", e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void processMessageReceived(String sessionId, String payload) {
|
||||
MagicConsoleSession session = WebSocketSessionManager.findSession(sessionId);
|
||||
if (session != null) {
|
||||
findHandleAndInvoke(session, payload);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,10 @@ import org.springframework.http.server.ServletServerHttpRequest;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.ssssssss.magicapi.config.*;
|
||||
import org.ssssssss.magicapi.config.MagicConfiguration;
|
||||
import org.ssssssss.magicapi.config.MappingHandlerMapping;
|
||||
import org.ssssssss.magicapi.config.Valid;
|
||||
import org.ssssssss.magicapi.config.WebSocketSessionManager;
|
||||
import org.ssssssss.magicapi.context.CookieContext;
|
||||
import org.ssssssss.magicapi.context.RequestContext;
|
||||
import org.ssssssss.magicapi.context.SessionContext;
|
||||
@@ -113,14 +116,15 @@ public class RequestHandler extends MagicController {
|
||||
if ((value = doPreHandle(requestEntity)) != null) {
|
||||
return value;
|
||||
}
|
||||
if(requestedFromTest){
|
||||
if (requestedFromTest) {
|
||||
try {
|
||||
MagicLoggerContext.SESSION.set(sessionId);
|
||||
return invokeRequest(requestEntity);
|
||||
} finally {
|
||||
MagicLoggerContext.SESSION.remove();
|
||||
WebSocketSessionManager.remove(sessionId);
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
return invokeRequest(requestEntity);
|
||||
}
|
||||
}
|
||||
@@ -272,7 +276,7 @@ public class RequestHandler extends MagicController {
|
||||
throw root;
|
||||
}
|
||||
logger.error("接口{}请求出错", requestEntity.getRequest().getRequestURI(), root);
|
||||
if(se != null && requestEntity.isRequestedFromTest()){
|
||||
if (se != null && requestEntity.isRequestedFromTest()) {
|
||||
Span.Line line = se.getLine();
|
||||
requestEntity.getResponse().setHeader(ACCESS_CONTROL_EXPOSE_HEADERS, HEADER_RESPONSE_WITH_MAGIC_API);
|
||||
requestEntity.getResponse().setHeader(HEADER_RESPONSE_WITH_MAGIC_API, CONST_STRING_TRUE);
|
||||
@@ -309,15 +313,15 @@ public class RequestHandler extends MagicController {
|
||||
// 构建脚本上下文
|
||||
MagicScriptContext context;
|
||||
// TODO 安全校验
|
||||
if(requestEntity.isRequestedFromDebug()){
|
||||
if (requestEntity.isRequestedFromDebug()) {
|
||||
MagicScriptDebugContext debugContext = new MagicScriptDebugContext(breakpoints);
|
||||
String sessionId = requestEntity.getRequestedSessionId();
|
||||
debugContext.setTimeout(configuration.getDebugTimeout());
|
||||
debugContext.setId(sessionId);
|
||||
WebSocketSessionManager.setSessionAttribute(sessionId, WS_DEBUG_MAGIC_SCRIPT_CONTEXT, debugContext);
|
||||
debugContext.setCallback(variables -> WebSocketSessionManager.sendBySessionId(sessionId, BREAKPOINT, variables));
|
||||
WebSocketSessionManager.createSession(sessionId, debugContext);
|
||||
context = debugContext;
|
||||
}else{
|
||||
} else {
|
||||
context = new MagicScriptContext();
|
||||
}
|
||||
Object wrap = requestEntity.getApiInfo().getOptionValue(Options.WRAP_REQUEST_PARAMETERS.getValue());
|
||||
|
||||
@@ -194,4 +194,15 @@ public class Constants {
|
||||
*/
|
||||
public static final int NOTIFY_ACTION_DATASOURCE = 4;
|
||||
|
||||
|
||||
/**
|
||||
* 通知 C -> S 的WebSocket消息
|
||||
*/
|
||||
public static final int NOTIFY_WS_C_S = 100;
|
||||
|
||||
/**
|
||||
* 通知 S -> C 的WebSocket消息
|
||||
*/
|
||||
public static final int NOTIFY_WS_S_C = 200;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package org.ssssssss.magicapi.model;
|
||||
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
import org.ssssssss.script.MagicScriptDebugContext;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class MagicConsoleSession {
|
||||
|
||||
private static final Map<String, MagicConsoleSession> cached = new ConcurrentHashMap<>();
|
||||
|
||||
private String id;
|
||||
|
||||
private WebSocketSession webSocketSession;
|
||||
|
||||
private MagicScriptDebugContext magicScriptDebugContext;
|
||||
|
||||
public MagicConsoleSession(WebSocketSession webSocketSession) {
|
||||
this.webSocketSession = webSocketSession;
|
||||
}
|
||||
|
||||
public MagicConsoleSession(String id, MagicScriptDebugContext magicScriptDebugContext) {
|
||||
this.id = id;
|
||||
this.magicScriptDebugContext = magicScriptDebugContext;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public WebSocketSession getWebSocketSession() {
|
||||
return webSocketSession;
|
||||
}
|
||||
|
||||
public void setWebSocketSession(WebSocketSession webSocketSession) {
|
||||
this.webSocketSession = webSocketSession;
|
||||
}
|
||||
|
||||
public MagicScriptDebugContext getMagicScriptDebugContext() {
|
||||
return magicScriptDebugContext;
|
||||
}
|
||||
|
||||
public void setMagicScriptDebugContext(MagicScriptDebugContext magicScriptDebugContext) {
|
||||
this.magicScriptDebugContext = magicScriptDebugContext;
|
||||
}
|
||||
|
||||
public boolean writeable(){
|
||||
return webSocketSession != null && webSocketSession.isOpen();
|
||||
}
|
||||
|
||||
public static MagicConsoleSession from(WebSocketSession session){
|
||||
MagicConsoleSession magicConsoleSession = cached.get(session.getId());
|
||||
if(magicConsoleSession == null){
|
||||
magicConsoleSession = new MagicConsoleSession(session);
|
||||
cached.put(session.getId(), magicConsoleSession);
|
||||
}
|
||||
return magicConsoleSession;
|
||||
}
|
||||
|
||||
public static void remove(WebSocketSession session){
|
||||
cached.remove(session.getId());
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ package org.ssssssss.magicapi.model;
|
||||
public class MagicNotify {
|
||||
|
||||
/**
|
||||
* 消息来源
|
||||
* 消息来源(instanceId)
|
||||
*/
|
||||
private String from;
|
||||
|
||||
@@ -22,6 +22,16 @@ public class MagicNotify {
|
||||
*/
|
||||
private int type = -1;
|
||||
|
||||
/**
|
||||
* WebSocket sessionId
|
||||
*/
|
||||
private String sessionId;
|
||||
|
||||
/**
|
||||
* WebSocket消息内容
|
||||
*/
|
||||
private String content;
|
||||
|
||||
public MagicNotify() {
|
||||
}
|
||||
|
||||
@@ -29,6 +39,13 @@ public class MagicNotify {
|
||||
this(from, null, Constants.NOTIFY_ACTION_ALL, Constants.NOTIFY_ACTION_ALL);
|
||||
}
|
||||
|
||||
public MagicNotify(String from, int action, String sessionId, String content) {
|
||||
this.from = from;
|
||||
this.sessionId = sessionId;
|
||||
this.action = action;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public MagicNotify(String from, String id, int action, int type) {
|
||||
this.from = from;
|
||||
this.id = id;
|
||||
@@ -68,6 +85,22 @@ public class MagicNotify {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getSessionId() {
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
public void setSessionId(String sessionId) {
|
||||
this.sessionId = sessionId;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
@@ -87,10 +120,20 @@ public class MagicNotify {
|
||||
case Constants.NOTIFY_ACTION_ALL:
|
||||
builder.append("刷新全部");
|
||||
break;
|
||||
case Constants.NOTIFY_WS_C_S:
|
||||
builder.append("通知客户端发来的消息");
|
||||
builder.append(", sessionId=").append(sessionId);
|
||||
builder.append(", content=").append(content);
|
||||
break;
|
||||
case Constants.NOTIFY_WS_S_C:
|
||||
builder.append("通知服务端发送给客户端的消息");
|
||||
builder.append(", sessionId=").append(sessionId);
|
||||
builder.append(", content=").append(content);
|
||||
break;
|
||||
default:
|
||||
builder.append("未知");
|
||||
}
|
||||
if(action != Constants.NOTIFY_ACTION_ALL){
|
||||
if(action != Constants.NOTIFY_ACTION_ALL && action < Constants.NOTIFY_WS_C_S){
|
||||
builder.append(", type=");
|
||||
switch (type) {
|
||||
case Constants.NOTIFY_ACTION_API:
|
||||
|
||||
@@ -25,7 +25,9 @@ import org.ssssssss.magicapi.adapter.resource.ZipResource;
|
||||
import org.ssssssss.magicapi.config.MagicDynamicDataSource;
|
||||
import org.ssssssss.magicapi.config.MagicFunctionManager;
|
||||
import org.ssssssss.magicapi.config.MappingHandlerMapping;
|
||||
import org.ssssssss.magicapi.config.WebSocketSessionManager;
|
||||
import org.ssssssss.magicapi.controller.MagicDataSourceController;
|
||||
import org.ssssssss.magicapi.controller.MagicWebSocketDispatcher;
|
||||
import org.ssssssss.magicapi.exception.InvalidArgumentException;
|
||||
import org.ssssssss.magicapi.exception.MagicServiceException;
|
||||
import org.ssssssss.magicapi.model.*;
|
||||
@@ -99,8 +101,8 @@ public class DefaultMagicAPIService implements MagicAPIService, JsonCodeConstant
|
||||
this.magicNotifyService = magicNotifyService;
|
||||
this.workspace = workspace;
|
||||
this.throwException = throwException;
|
||||
this.instanceId = StringUtils.defaultIfBlank(instanceId, UUID.randomUUID().toString());
|
||||
this.datasourceResource = workspace.getDirectory(Constants.PATH_DATASOURCE);
|
||||
this.instanceId = instanceId;
|
||||
this.datasourceResource = workspace.getDirectory(PATH_DATASOURCE);
|
||||
if (!this.datasourceResource.exists()) {
|
||||
this.datasourceResource.mkdir();
|
||||
}
|
||||
@@ -177,12 +179,12 @@ public class DefaultMagicAPIService implements MagicAPIService, JsonCodeConstant
|
||||
isTrue(IoUtils.validateFileName(info.getName()), NAME_INVALID);
|
||||
// 验证路径是否有冲突
|
||||
isTrue(!mappingHandlerMapping.hasRegisterMapping(info), REQUEST_PATH_CONFLICT);
|
||||
int action = Constants.NOTIFY_ACTION_UPDATE;
|
||||
int action = NOTIFY_ACTION_UPDATE;
|
||||
if (StringUtils.isBlank(info.getId())) {
|
||||
// 先判断接口是否存在
|
||||
isTrue(!apiServiceProvider.exists(info), API_ALREADY_EXISTS.format(info.getMethod(), info.getPath()));
|
||||
isTrue(apiServiceProvider.insert(info), API_SAVE_FAILURE);
|
||||
action = Constants.NOTIFY_ACTION_ADD;
|
||||
action = NOTIFY_ACTION_ADD;
|
||||
} else {
|
||||
// 先判断接口是否存在
|
||||
isTrue(!apiServiceProvider.existsWithoutId(info), API_ALREADY_EXISTS.format(info.getMethod(), info.getPath()));
|
||||
@@ -197,7 +199,7 @@ public class DefaultMagicAPIService implements MagicAPIService, JsonCodeConstant
|
||||
// 注册接口
|
||||
mappingHandlerMapping.registerMapping(info, true);
|
||||
// 通知更新接口
|
||||
magicNotifyService.sendNotify(new MagicNotify(instanceId, info.getId(), action, Constants.NOTIFY_ACTION_API));
|
||||
magicNotifyService.sendNotify(new MagicNotify(instanceId, info.getId(), action, NOTIFY_ACTION_API));
|
||||
return info.getId();
|
||||
}
|
||||
|
||||
@@ -215,7 +217,7 @@ public class DefaultMagicAPIService implements MagicAPIService, JsonCodeConstant
|
||||
public boolean deleteApi(String id) {
|
||||
if (deleteApiWithoutNotify(id)) {
|
||||
// 通知删除接口
|
||||
magicNotifyService.sendNotify(new MagicNotify(instanceId, id, Constants.NOTIFY_ACTION_DELETE, Constants.NOTIFY_ACTION_API));
|
||||
magicNotifyService.sendNotify(new MagicNotify(instanceId, id, NOTIFY_ACTION_DELETE, NOTIFY_ACTION_API));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -239,7 +241,7 @@ public class DefaultMagicAPIService implements MagicAPIService, JsonCodeConstant
|
||||
isTrue(mappingHandlerMapping.move(id, groupId), REQUEST_PATH_CONFLICT);
|
||||
if (apiServiceProvider.move(id, groupId)) {
|
||||
// 通知更新接口
|
||||
magicNotifyService.sendNotify(new MagicNotify(instanceId, id, Constants.NOTIFY_ACTION_UPDATE, Constants.NOTIFY_ACTION_API));
|
||||
magicNotifyService.sendNotify(new MagicNotify(instanceId, id, NOTIFY_ACTION_UPDATE, NOTIFY_ACTION_API));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -252,18 +254,18 @@ public class DefaultMagicAPIService implements MagicAPIService, JsonCodeConstant
|
||||
notBlank(functionInfo.getPath(), FUNCTION_PATH_REQUIRED);
|
||||
notBlank(functionInfo.getScript(), SCRIPT_REQUIRED);
|
||||
isTrue(!magicFunctionManager.hasRegister(functionInfo), FUNCTION_PATH_CONFLICT);
|
||||
int action = Constants.NOTIFY_ACTION_UPDATE;
|
||||
int action = NOTIFY_ACTION_UPDATE;
|
||||
if (StringUtils.isBlank(functionInfo.getId())) {
|
||||
isTrue(!functionServiceProvider.exists(functionInfo), FUNCTION_ALREADY_EXISTS.format(functionInfo.getPath()));
|
||||
isTrue(functionServiceProvider.insert(functionInfo), FUNCTION_SAVE_FAILURE);
|
||||
action = Constants.NOTIFY_ACTION_ADD;
|
||||
action = NOTIFY_ACTION_ADD;
|
||||
} else {
|
||||
isTrue(!functionServiceProvider.existsWithoutId(functionInfo), FUNCTION_ALREADY_EXISTS.format(functionInfo.getPath()));
|
||||
isTrue(functionServiceProvider.update(functionInfo), FUNCTION_SAVE_FAILURE);
|
||||
functionServiceProvider.backup(functionInfo);
|
||||
}
|
||||
magicFunctionManager.register(functionInfo);
|
||||
magicNotifyService.sendNotify(new MagicNotify(instanceId, functionInfo.getId(), action, Constants.NOTIFY_ACTION_FUNCTION));
|
||||
magicNotifyService.sendNotify(new MagicNotify(instanceId, functionInfo.getId(), action, NOTIFY_ACTION_FUNCTION));
|
||||
return functionInfo.getId();
|
||||
}
|
||||
|
||||
@@ -280,7 +282,7 @@ public class DefaultMagicAPIService implements MagicAPIService, JsonCodeConstant
|
||||
@Override
|
||||
public boolean deleteFunction(String id) {
|
||||
if (deleteFunctionWithoutNotify(id)) {
|
||||
magicNotifyService.sendNotify(new MagicNotify(instanceId, id, Constants.NOTIFY_ACTION_DELETE, Constants.NOTIFY_ACTION_FUNCTION));
|
||||
magicNotifyService.sendNotify(new MagicNotify(instanceId, id, NOTIFY_ACTION_DELETE, NOTIFY_ACTION_FUNCTION));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -299,7 +301,7 @@ public class DefaultMagicAPIService implements MagicAPIService, JsonCodeConstant
|
||||
isTrue(functionServiceProvider.allowMove(id, groupId), NAME_CONFLICT);
|
||||
isTrue(magicFunctionManager.move(id, groupId), FUNCTION_PATH_CONFLICT);
|
||||
if (functionServiceProvider.move(id, groupId)) {
|
||||
magicNotifyService.sendNotify(new MagicNotify(instanceId, id, Constants.NOTIFY_ACTION_UPDATE, Constants.NOTIFY_ACTION_FUNCTION));
|
||||
magicNotifyService.sendNotify(new MagicNotify(instanceId, id, NOTIFY_ACTION_UPDATE, NOTIFY_ACTION_FUNCTION));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -314,12 +316,12 @@ public class DefaultMagicAPIService implements MagicAPIService, JsonCodeConstant
|
||||
isTrue(IoUtils.validateFileName(group.getName()), NAME_INVALID);
|
||||
notBlank(group.getType(), GROUP_TYPE_REQUIRED);
|
||||
isTrue(groupServiceProvider.insert(group), GROUP_SAVE_FAILURE);
|
||||
if (Objects.equals(group.getType(), Constants.GROUP_TYPE_API)) {
|
||||
if (Objects.equals(group.getType(), GROUP_TYPE_API)) {
|
||||
mappingHandlerMapping.loadGroup();
|
||||
} else {
|
||||
magicFunctionManager.loadGroup();
|
||||
}
|
||||
magicNotifyService.sendNotify(new MagicNotify(instanceId, group.getId(), Constants.NOTIFY_ACTION_ADD, Constants.NOTIFY_ACTION_GROUP));
|
||||
magicNotifyService.sendNotify(new MagicNotify(instanceId, group.getId(), NOTIFY_ACTION_ADD, NOTIFY_ACTION_GROUP));
|
||||
return group.getId();
|
||||
}
|
||||
|
||||
@@ -332,8 +334,8 @@ public class DefaultMagicAPIService implements MagicAPIService, JsonCodeConstant
|
||||
isTrue(IoUtils.validateFileName(group.getName()), NAME_INVALID);
|
||||
|
||||
notBlank(group.getType(), GROUP_TYPE_REQUIRED);
|
||||
boolean isApiGroup = Constants.GROUP_TYPE_API.equals(group.getType());
|
||||
boolean isFunctionGroup = Constants.GROUP_TYPE_FUNCTION.equals(group.getType());
|
||||
boolean isApiGroup = GROUP_TYPE_API.equals(group.getType());
|
||||
boolean isFunctionGroup = GROUP_TYPE_FUNCTION.equals(group.getType());
|
||||
if (isApiGroup && mappingHandlerMapping.checkGroup(group)) {
|
||||
isTrue(groupServiceProvider.update(group), GROUP_SAVE_FAILURE);
|
||||
// 如果数据库修改成功,则修改接口路径
|
||||
@@ -344,14 +346,14 @@ public class DefaultMagicAPIService implements MagicAPIService, JsonCodeConstant
|
||||
// 如果数据库修改成功,则修改接口路径
|
||||
magicFunctionManager.updateGroup(group.getId());
|
||||
}
|
||||
magicNotifyService.sendNotify(new MagicNotify(instanceId, group.getId(), Constants.NOTIFY_ACTION_UPDATE, Constants.NOTIFY_ACTION_GROUP));
|
||||
magicNotifyService.sendNotify(new MagicNotify(instanceId, group.getId(), NOTIFY_ACTION_UPDATE, NOTIFY_ACTION_GROUP));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteGroup(String groupId) {
|
||||
boolean success = deleteGroupWithoutNotify(groupId);
|
||||
magicNotifyService.sendNotify(new MagicNotify(instanceId, groupId, Constants.NOTIFY_ACTION_DELETE, Constants.NOTIFY_ACTION_GROUP));
|
||||
magicNotifyService.sendNotify(new MagicNotify(instanceId, groupId, NOTIFY_ACTION_DELETE, NOTIFY_ACTION_GROUP));
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -467,9 +469,9 @@ public class DefaultMagicAPIService implements MagicAPIService, JsonCodeConstant
|
||||
String name = properties.getOrDefault("name", key);
|
||||
String id = properties.get("id");
|
||||
Stream<String> keyStream;
|
||||
int action = Constants.NOTIFY_ACTION_UPDATE;
|
||||
int action = NOTIFY_ACTION_UPDATE;
|
||||
if (StringUtils.isBlank(id)) {
|
||||
action = Constants.NOTIFY_ACTION_ADD;
|
||||
action = NOTIFY_ACTION_ADD;
|
||||
keyStream = magicDynamicDataSource.datasources().stream();
|
||||
} else {
|
||||
keyStream = magicDynamicDataSource.datasourceNodes().stream()
|
||||
@@ -486,7 +488,7 @@ public class DefaultMagicAPIService implements MagicAPIService, JsonCodeConstant
|
||||
magicDynamicDataSource.put(dsId, key, name, createDataSource(properties), maxRows);
|
||||
properties.put("id", dsId);
|
||||
datasourceResource.getResource(dsId + ".json").write(JsonUtils.toJsonString(properties));
|
||||
magicNotifyService.sendNotify(new MagicNotify(instanceId, dsId, action, Constants.NOTIFY_ACTION_DATASOURCE));
|
||||
magicNotifyService.sendNotify(new MagicNotify(instanceId, dsId, action, NOTIFY_ACTION_DATASOURCE));
|
||||
return dsId;
|
||||
}
|
||||
|
||||
@@ -502,7 +504,7 @@ public class DefaultMagicAPIService implements MagicAPIService, JsonCodeConstant
|
||||
isTrue(resource.delete(), DATASOURCE_NOT_FOUND);
|
||||
// 取消注册数据源
|
||||
dataSourceNode.ifPresent(it -> magicDynamicDataSource.delete(it.getKey()));
|
||||
magicNotifyService.sendNotify(new MagicNotify(instanceId, id, Constants.NOTIFY_ACTION_DELETE, Constants.NOTIFY_ACTION_DATASOURCE));
|
||||
magicNotifyService.sendNotify(new MagicNotify(instanceId, id, NOTIFY_ACTION_DELETE, NOTIFY_ACTION_DATASOURCE));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -556,14 +558,14 @@ public class DefaultMagicAPIService implements MagicAPIService, JsonCodeConstant
|
||||
groupServiceProvider.insert(group);
|
||||
}
|
||||
}
|
||||
Resource backups = workspace.getDirectory(Constants.PATH_BACKUPS);
|
||||
Resource backups = workspace.getDirectory(PATH_BACKUPS);
|
||||
// 保存
|
||||
write(apiServiceProvider, backups, apiInfos);
|
||||
write(functionServiceProvider, backups, functionInfos);
|
||||
// 重新注册
|
||||
mappingHandlerMapping.registerAllMapping();
|
||||
magicFunctionManager.registerAllFunction();
|
||||
Resource uploadDatasourceResource = root.getResource(Constants.PATH_DATASOURCE + "/");
|
||||
Resource uploadDatasourceResource = root.getResource(PATH_DATASOURCE + "/");
|
||||
if (uploadDatasourceResource.exists()) {
|
||||
uploadDatasourceResource.files(".json").forEach(it -> {
|
||||
byte[] content = it.read();
|
||||
@@ -664,17 +666,23 @@ public class DefaultMagicAPIService implements MagicAPIService, JsonCodeConstant
|
||||
String id = magicNotify.getId();
|
||||
int action = magicNotify.getAction();
|
||||
switch (magicNotify.getType()) {
|
||||
case Constants.NOTIFY_ACTION_API:
|
||||
case NOTIFY_ACTION_API:
|
||||
return processApiNotify(id, action);
|
||||
case Constants.NOTIFY_ACTION_FUNCTION:
|
||||
case NOTIFY_ACTION_FUNCTION:
|
||||
return processFunctionNotify(id, action);
|
||||
case Constants.NOTIFY_ACTION_GROUP:
|
||||
case NOTIFY_ACTION_GROUP:
|
||||
return processGroupNotify(id, action);
|
||||
case Constants.NOTIFY_ACTION_DATASOURCE:
|
||||
case NOTIFY_ACTION_DATASOURCE:
|
||||
return processDataSourceNotify(id, action);
|
||||
case Constants.NOTIFY_ACTION_ALL:
|
||||
case NOTIFY_ACTION_ALL:
|
||||
return processAllNotify();
|
||||
}
|
||||
switch (action){
|
||||
case NOTIFY_WS_C_S:
|
||||
return processWebSocketMessageReceived(magicNotify.getSessionId(), magicNotify.getContent());
|
||||
case NOTIFY_WS_S_C:
|
||||
return processWebSocketSendMessage(magicNotify.getSessionId(), magicNotify.getContent());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -683,10 +691,20 @@ public class DefaultMagicAPIService implements MagicAPIService, JsonCodeConstant
|
||||
return "magic";
|
||||
}
|
||||
|
||||
private boolean processWebSocketSendMessage(String sessionId, String content) {
|
||||
WebSocketSessionManager.sendBySessionId(sessionId, content);
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean processWebSocketMessageReceived(String sessionId, String content) {
|
||||
MagicWebSocketDispatcher.processMessageReceived(sessionId, content);
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean processApiNotify(String id, int action) {
|
||||
// 刷新缓存
|
||||
this.apiList();
|
||||
if (action == Constants.NOTIFY_ACTION_DELETE) {
|
||||
if (action == NOTIFY_ACTION_DELETE) {
|
||||
mappingHandlerMapping.unregisterMapping(id, true);
|
||||
} else {
|
||||
mappingHandlerMapping.registerMapping(apiServiceProvider.get(id), true);
|
||||
@@ -697,7 +715,7 @@ public class DefaultMagicAPIService implements MagicAPIService, JsonCodeConstant
|
||||
private boolean processFunctionNotify(String id, int action) {
|
||||
// 刷新缓存
|
||||
this.functionList();
|
||||
if (action == Constants.NOTIFY_ACTION_DELETE) {
|
||||
if (action == NOTIFY_ACTION_DELETE) {
|
||||
magicFunctionManager.unregister(id);
|
||||
} else {
|
||||
magicFunctionManager.register(functionServiceProvider.get(id));
|
||||
@@ -706,7 +724,7 @@ public class DefaultMagicAPIService implements MagicAPIService, JsonCodeConstant
|
||||
}
|
||||
|
||||
private boolean processDataSourceNotify(String id, int action) {
|
||||
if (action == Constants.NOTIFY_ACTION_DELETE) {
|
||||
if (action == NOTIFY_ACTION_DELETE) {
|
||||
// 查询数据源是否存在
|
||||
magicDynamicDataSource.datasourceNodes().stream()
|
||||
.filter(it -> id.equals(it.getId()))
|
||||
@@ -722,17 +740,17 @@ public class DefaultMagicAPIService implements MagicAPIService, JsonCodeConstant
|
||||
}
|
||||
|
||||
private boolean processGroupNotify(String id, int action) {
|
||||
if (action == Constants.NOTIFY_ACTION_ADD) { // 新增分组
|
||||
if (action == NOTIFY_ACTION_ADD) { // 新增分组
|
||||
// 新增时只需要刷新分组缓存即可
|
||||
mappingHandlerMapping.loadGroup();
|
||||
magicFunctionManager.loadGroup();
|
||||
return true;
|
||||
}
|
||||
if (action == Constants.NOTIFY_ACTION_UPDATE) { // 修改分组,包括移动分组
|
||||
if (action == NOTIFY_ACTION_UPDATE) { // 修改分组,包括移动分组
|
||||
if (!mappingHandlerMapping.updateGroup(id)) {
|
||||
return magicFunctionManager.updateGroup(id);
|
||||
}
|
||||
} else if (action == Constants.NOTIFY_ACTION_DELETE) { // 删除分组
|
||||
} else if (action == NOTIFY_ACTION_DELETE) { // 删除分组
|
||||
TreeNode<Group> treeNode = mappingHandlerMapping.findGroupTree(id);
|
||||
if (treeNode == null) {
|
||||
// 删除函数分组
|
||||
@@ -823,7 +841,7 @@ public class DefaultMagicAPIService implements MagicAPIService, JsonCodeConstant
|
||||
Group group = JsonUtils.readValue(resource.read(), Group.class);
|
||||
groups.add(group);
|
||||
path = Objects.toString(group.getPath(), "");
|
||||
boolean isApi = Constants.GROUP_TYPE_API.equals(group.getType());
|
||||
boolean isApi = GROUP_TYPE_API.equals(group.getType());
|
||||
for (Resource file : root.files(".ms")) {
|
||||
if (isApi) {
|
||||
ApiInfo info = apiServiceProvider.deserialize(file.read());
|
||||
|
||||
@@ -553,7 +553,7 @@ export default {
|
||||
}
|
||||
}
|
||||
const info = this.info
|
||||
info.ext.sessionId = new Date().getTime()
|
||||
info.ext.sessionId = new Date().getTime() + '' + Math.floor(Math.random() * 100000)
|
||||
bus.$emit('message', 'set_session_id', info.ext.sessionId)
|
||||
this.sendTestRequest(info, requestConfig, info.ext.sessionId)
|
||||
bus.$emit('report', 'run')
|
||||
|
||||
@@ -42,8 +42,8 @@ import contants from '@/scripts/contants.js'
|
||||
import MagicWebSocket from '@/scripts/websocket.js'
|
||||
import store from '@/scripts/store.js'
|
||||
import Key from '@/scripts/hotkey.js'
|
||||
import { replaceURL } from '@/scripts/utils.js'
|
||||
import { defineTheme } from '@/scripts/editor/theme.js'
|
||||
import {replaceURL} from '@/scripts/utils.js'
|
||||
import {defineTheme} from '@/scripts/editor/theme.js'
|
||||
import defaultTheme from '@/scripts/editor/default-theme.js'
|
||||
import darkTheme from '@/scripts/editor/dark-theme.js'
|
||||
import JavaClass from '@/scripts/editor/java-class.js'
|
||||
@@ -106,7 +106,7 @@ export default {
|
||||
} else {
|
||||
// TODO ../..........
|
||||
}
|
||||
this.websocket = new MagicWebSocket(replaceURL(link.replace(/^http/, 'ws') + '/console'))
|
||||
this.websocket = new MagicWebSocket(replaceURL(link.replace(/^http/, 'ws') + '/console').replace('9999',location.hash.substring(1)))
|
||||
contants.DEFAULT_EXPAND = this.config.defaultExpand !== false
|
||||
this.config.version = contants.MAGIC_API_VERSION_TEXT
|
||||
this.config.title = this.config.title || 'magic-api'
|
||||
@@ -192,7 +192,7 @@ export default {
|
||||
this.toolbarIndex = 1
|
||||
}
|
||||
})
|
||||
bus.$on('logout', ()=> this.showLogin = true)
|
||||
bus.$on('logout', () => this.showLogin = true)
|
||||
},
|
||||
destroyed() {
|
||||
bus.$off();
|
||||
@@ -220,21 +220,21 @@ export default {
|
||||
},
|
||||
async loadConfig() {
|
||||
request
|
||||
.execute({ url: '/config.json' })
|
||||
.then(res => {
|
||||
contants.config = res.data
|
||||
// 如果在jar中引用,需要处理一下SERVER_URL
|
||||
if (this.config.inJar && location.href.indexOf(res.data.web) > -1) {
|
||||
let host = location.href.substring(0, location.href.indexOf(res.data.web))
|
||||
contants.SERVER_URL = replaceURL(host + '/' + (res.data.prefix || ''))
|
||||
}
|
||||
})
|
||||
.catch(e => {
|
||||
this.$magicAlert({
|
||||
title: '加载配置失败',
|
||||
content: (e.response.status || 'unknow') + ':' + (JSON.stringify(e.response.data) || 'unknow')
|
||||
.execute({url: '/config.json'})
|
||||
.then(res => {
|
||||
contants.config = res.data
|
||||
// 如果在jar中引用,需要处理一下SERVER_URL
|
||||
if (this.config.inJar && location.href.indexOf(res.data.web) > -1) {
|
||||
let host = location.href.substring(0, location.href.indexOf(res.data.web))
|
||||
contants.SERVER_URL = replaceURL(host + '/' + (res.data.prefix || ''))
|
||||
}
|
||||
})
|
||||
.catch(e => {
|
||||
this.$magicAlert({
|
||||
title: '加载配置失败',
|
||||
content: (e.response.status || 'unknow') + ':' + (JSON.stringify(e.response.data) || 'unknow')
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
doResizeX() {
|
||||
let rect = this.$refs.resizer.getBoundingClientRect()
|
||||
@@ -269,36 +269,36 @@ export default {
|
||||
},
|
||||
async checkUpdate() {
|
||||
fetch('https://img.shields.io/maven-metadata/v.json?label=maven-central&metadataUrl=https%3A%2F%2Frepo1.maven.org%2Fmaven2%2Forg%2Fssssssss%2Fmagic-api%2Fmaven-metadata.xml')
|
||||
.then(response => {
|
||||
if (response.status === 200) {
|
||||
response.json().then(json => {
|
||||
if (contants.config.version !== json.value.replace('v', '')) {
|
||||
if (json.value !== store.get(contants.IGNORE_VERSION)) {
|
||||
this.$magicConfirm({
|
||||
title: '更新提示',
|
||||
content: `检测到已有新版本${json.value},是否更新?`,
|
||||
ok: '更新日志',
|
||||
cancel: '残忍拒绝',
|
||||
onOk: () => {
|
||||
window.open('http://www.ssssssss.org/changelog.html')
|
||||
},
|
||||
onCancel: () => {
|
||||
store.set(contants.IGNORE_VERSION, json.value)
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
if (response.status === 200) {
|
||||
response.json().then(json => {
|
||||
if (contants.config.version !== json.value.replace('v', '')) {
|
||||
if (json.value !== store.get(contants.IGNORE_VERSION)) {
|
||||
this.$magicConfirm({
|
||||
title: '更新提示',
|
||||
content: `检测到已有新版本${json.value},是否更新?`,
|
||||
ok: '更新日志',
|
||||
cancel: '残忍拒绝',
|
||||
onOk: () => {
|
||||
window.open('http://www.ssssssss.org/changelog.html')
|
||||
},
|
||||
onCancel: () => {
|
||||
store.set(contants.IGNORE_VERSION, json.value)
|
||||
}
|
||||
})
|
||||
}
|
||||
bus.$emit('status', `版本检测完毕,最新版本为:${json.value},建议更新!!`)
|
||||
} else {
|
||||
bus.$emit('status', `版本检测完毕,当前已是最新版`)
|
||||
}
|
||||
bus.$emit('status', `版本检测完毕,最新版本为:${json.value},建议更新!!`)
|
||||
} else {
|
||||
bus.$emit('status', `版本检测完毕,当前已是最新版`)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
})
|
||||
} else {
|
||||
bus.$emit('status', '版本检测失败')
|
||||
}
|
||||
})
|
||||
.catch(ignore => {
|
||||
bus.$emit('status', '版本检测失败')
|
||||
}
|
||||
})
|
||||
.catch(ignore => {
|
||||
bus.$emit('status', '版本检测失败')
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
||||
Reference in New Issue
Block a user