161 lines
5.2 KiB
Java
Executable File
161 lines
5.2 KiB
Java
Executable File
/*
|
|
* This file is part of the Wildfire Chat package.
|
|
* (c) Heavyrain2012 <[email protected]>
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
|
|
package com.xiaoleilu.loServer.action;
|
|
|
|
import com.google.gson.Gson;
|
|
import com.google.gson.GsonBuilder;
|
|
import com.xiaoleilu.loServer.RestResult;
|
|
import com.xiaoleilu.loServer.annotation.RequireAuthentication;
|
|
import com.xiaoleilu.loServer.handler.Request;
|
|
import com.xiaoleilu.loServer.handler.Response;
|
|
import io.moquette.server.config.IConfig;
|
|
import io.moquette.spi.IMessagesStore;
|
|
import io.moquette.spi.ISessionsStore;
|
|
import io.moquette.spi.impl.Utils;
|
|
import io.netty.channel.ChannelHandlerContext;
|
|
import io.netty.handler.codec.http.FullHttpRequest;
|
|
import io.netty.handler.codec.http.HttpRequest;
|
|
import io.netty.handler.codec.http.HttpResponseStatus;
|
|
import cn.wildfirechat.common.ErrorCode;
|
|
import win.liyufan.im.RateLimiter;
|
|
|
|
import java.nio.charset.StandardCharsets;
|
|
|
|
import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_SUCCESS;
|
|
import static io.moquette.BrokerConstants.*;
|
|
|
|
/**
|
|
* 请求处理接口<br>
|
|
* 当用户请求某个Path,则调用相应Action的doAction方法
|
|
* @author Looly
|
|
*
|
|
*/
|
|
|
|
abstract public class Action {
|
|
public static IMessagesStore messagesStore = null;
|
|
public static ISessionsStore sessionsStore = null;
|
|
protected static final Gson gson = new GsonBuilder().disableHtmlEscaping().create();
|
|
public ChannelHandlerContext ctx;
|
|
|
|
protected static RateLimiter adminLimiter = null;
|
|
protected static RateLimiter robotLimiter = null;
|
|
protected static RateLimiter channelLimiter = null;
|
|
|
|
public static void init(IConfig config) {
|
|
int adminRate = 10000;
|
|
int robotRate = 1000;
|
|
int channelRate = 1000;
|
|
|
|
try {
|
|
adminRate = Integer.parseInt(config.getProperty(HTTP_ADMIN_RATE_LIMIT, "10000"));
|
|
} catch (NumberFormatException e) {
|
|
|
|
}
|
|
try {
|
|
robotRate = Integer.parseInt(config.getProperty(HTTP_ROBOT_RATE_LIMIT, "1000"));
|
|
} catch (NumberFormatException e) {
|
|
|
|
}
|
|
try {
|
|
channelRate = Integer.parseInt(config.getProperty(HTTP_CHANNEL_RATE_LIMIT, "1000"));
|
|
} catch (NumberFormatException e) {
|
|
|
|
}
|
|
adminLimiter = new RateLimiter(10, adminRate);
|
|
robotLimiter = new RateLimiter(10, robotRate);
|
|
channelLimiter = new RateLimiter(10, channelRate);
|
|
}
|
|
|
|
protected class Result {
|
|
Object data;
|
|
ErrorCode errorCode;
|
|
|
|
public Result(ErrorCode errorCode) {
|
|
this.errorCode = errorCode;
|
|
}
|
|
|
|
public Result(ErrorCode errorCode, Object data) {
|
|
this.data = data;
|
|
this.errorCode = errorCode;
|
|
}
|
|
|
|
public Object getData() {
|
|
return data;
|
|
}
|
|
|
|
public ErrorCode getErrorCode() {
|
|
return errorCode;
|
|
}
|
|
}
|
|
|
|
protected interface ApiCallback {
|
|
Result onResult(byte[] response);
|
|
}
|
|
|
|
public ErrorCode preAction(Request request, Response response) {
|
|
if (getClass().getAnnotation(RequireAuthentication.class) != null) {
|
|
//do authentication
|
|
}
|
|
|
|
return ERROR_CODE_SUCCESS;
|
|
}
|
|
public boolean doAction(Request request, Response response) {
|
|
ErrorCode errorCode = preAction(request, response);
|
|
boolean isSync = true;
|
|
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
|
|
//事务逻辑有缺陷,先注释掉
|
|
// if (isTransactionAction() && !(this instanceof IMAction)) {
|
|
// DBUtil.beginTransaction();
|
|
// try {
|
|
// action(request, response);
|
|
// DBUtil.commit();
|
|
// } catch (Exception e) {
|
|
// e.printStackTrace();
|
|
// DBUtil.roolback();
|
|
// throw e;
|
|
// }
|
|
// } else {
|
|
isSync = action(request, response);
|
|
// }
|
|
} else {
|
|
response.setStatus(HttpResponseStatus.OK);
|
|
if (errorCode == null) {
|
|
errorCode = ErrorCode.ERROR_CODE_SUCCESS;
|
|
}
|
|
|
|
RestResult result = RestResult.resultOf(errorCode, errorCode.getMsg(), RestResult.resultOf(errorCode));
|
|
response.setContent(gson.toJson(result));
|
|
response.send();
|
|
}
|
|
|
|
return isSync;
|
|
}
|
|
public boolean isTransactionAction() {
|
|
return false;
|
|
}
|
|
abstract public boolean action(Request request, Response response);
|
|
|
|
protected <T> T getRequestBody(HttpRequest request, Class<T> cls) {
|
|
if (request instanceof FullHttpRequest) {
|
|
FullHttpRequest fullHttpRequest = (FullHttpRequest) request;
|
|
byte[] bytes = Utils.readBytesAndRewind(fullHttpRequest.content());
|
|
String content = new String(bytes, StandardCharsets.UTF_8);//contribute by JiaRG from github
|
|
|
|
T t = gson.fromJson(content, cls);
|
|
return t;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
protected void setResponseContent(RestResult result, Response response) {
|
|
response.setStatus(HttpResponseStatus.OK);
|
|
response.setContent(gson.toJson(result));
|
|
}
|
|
}
|