parent
02dc2a4caa
commit
443c946e55
@ -1,69 +1,34 @@
|
|||||||
package com.xxl.job.admin.controller;
|
package com.xxl.job.admin.controller;
|
||||||
|
|
||||||
import com.xxl.job.admin.controller.annotation.PermessionLimit;
|
import com.xxl.job.admin.controller.annotation.PermessionLimit;
|
||||||
|
import com.xxl.job.admin.core.schedule.XxlJobDynamicScheduler;
|
||||||
import com.xxl.job.core.biz.AdminBiz;
|
import com.xxl.job.core.biz.AdminBiz;
|
||||||
import com.xxl.job.core.rpc.codec.RpcRequest;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
import com.xxl.job.core.rpc.codec.RpcResponse;
|
|
||||||
import com.xxl.job.core.rpc.netcom.NetComServerFactory;
|
|
||||||
import com.xxl.job.core.rpc.serialize.HessianSerializer;
|
|
||||||
import com.xxl.job.core.util.HttpClientUtil;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by xuxueli on 17/5/10.
|
* Created by xuxueli on 17/5/10.
|
||||||
*/
|
*/
|
||||||
@Controller
|
@Controller
|
||||||
public class JobApiController {
|
public class JobApiController implements InitializingBean {
|
||||||
private static Logger logger = LoggerFactory.getLogger(JobApiController.class);
|
|
||||||
|
|
||||||
private RpcResponse doInvoke(HttpServletRequest request) {
|
|
||||||
try {
|
|
||||||
// deserialize request
|
|
||||||
byte[] requestBytes = HttpClientUtil.readBytes(request);
|
|
||||||
if (requestBytes == null || requestBytes.length==0) {
|
|
||||||
RpcResponse rpcResponse = new RpcResponse();
|
|
||||||
rpcResponse.setError("RpcRequest byte[] is null");
|
|
||||||
return rpcResponse;
|
|
||||||
}
|
|
||||||
RpcRequest rpcRequest = (RpcRequest) HessianSerializer.deserialize(requestBytes, RpcRequest.class);
|
|
||||||
|
|
||||||
// invoke
|
@Override
|
||||||
RpcResponse rpcResponse = NetComServerFactory.invokeService(rpcRequest, null);
|
public void afterPropertiesSet() throws Exception {
|
||||||
return rpcResponse;
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error(e.getMessage(), e);
|
|
||||||
|
|
||||||
RpcResponse rpcResponse = new RpcResponse();
|
|
||||||
rpcResponse.setError("Server-error:" + e.getMessage());
|
|
||||||
return rpcResponse;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(AdminBiz.MAPPING)
|
@RequestMapping(AdminBiz.MAPPING)
|
||||||
@PermessionLimit(limit=false)
|
@PermessionLimit(limit=false)
|
||||||
public void api(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
public void api(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
|
||||||
|
XxlJobDynamicScheduler.invokeAdminService(request, response);
|
||||||
// invoke
|
|
||||||
RpcResponse rpcResponse = doInvoke(request);
|
|
||||||
|
|
||||||
// serialize response
|
|
||||||
byte[] responseBytes = HessianSerializer.serialize(rpcResponse);
|
|
||||||
|
|
||||||
response.setContentType("text/html;charset=utf-8");
|
|
||||||
response.setStatus(HttpServletResponse.SC_OK);
|
|
||||||
//baseRequest.setHandled(true);
|
|
||||||
|
|
||||||
OutputStream out = response.getOutputStream();
|
|
||||||
out.write(responseBytes);
|
|
||||||
out.flush();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,92 +0,0 @@
|
|||||||
package com.xxl.job.core.rpc.codec;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* request
|
|
||||||
* @author xuxueli 2015-10-29 19:39:12
|
|
||||||
*/
|
|
||||||
public class RpcRequest implements Serializable{
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
private String serverAddress;
|
|
||||||
private long createMillisTime;
|
|
||||||
private String accessToken;
|
|
||||||
|
|
||||||
private String className;
|
|
||||||
private String methodName;
|
|
||||||
private Class<?>[] parameterTypes;
|
|
||||||
private Object[] parameters;
|
|
||||||
|
|
||||||
|
|
||||||
public String getServerAddress() {
|
|
||||||
return serverAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setServerAddress(String serverAddress) {
|
|
||||||
this.serverAddress = serverAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getCreateMillisTime() {
|
|
||||||
return createMillisTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCreateMillisTime(long createMillisTime) {
|
|
||||||
this.createMillisTime = createMillisTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAccessToken() {
|
|
||||||
return accessToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAccessToken(String accessToken) {
|
|
||||||
this.accessToken = accessToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getClassName() {
|
|
||||||
return className;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setClassName(String className) {
|
|
||||||
this.className = className;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMethodName() {
|
|
||||||
return methodName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMethodName(String methodName) {
|
|
||||||
this.methodName = methodName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Class<?>[] getParameterTypes() {
|
|
||||||
return parameterTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setParameterTypes(Class<?>[] parameterTypes) {
|
|
||||||
this.parameterTypes = parameterTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object[] getParameters() {
|
|
||||||
return parameters;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setParameters(Object[] parameters) {
|
|
||||||
this.parameters = parameters;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "RpcRequest{" +
|
|
||||||
"serverAddress='" + serverAddress + '\'' +
|
|
||||||
", createMillisTime=" + createMillisTime +
|
|
||||||
", accessToken='" + accessToken + '\'' +
|
|
||||||
", className='" + className + '\'' +
|
|
||||||
", methodName='" + methodName + '\'' +
|
|
||||||
", parameterTypes=" + Arrays.toString(parameterTypes) +
|
|
||||||
", parameters=" + Arrays.toString(parameters) +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
package com.xxl.job.core.rpc.codec;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* response
|
|
||||||
* @author xuxueli 2015-10-29 19:39:54
|
|
||||||
*/
|
|
||||||
public class RpcResponse implements Serializable{
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
private String error;
|
|
||||||
private Object result;
|
|
||||||
|
|
||||||
public boolean isError() {
|
|
||||||
return error != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getError() {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setError(String error) {
|
|
||||||
this.error = error;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object getResult() {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setResult(Object result) {
|
|
||||||
this.result = result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "NettyResponse [error=" + error
|
|
||||||
+ ", result=" + result + "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,81 +0,0 @@
|
|||||||
package com.xxl.job.core.rpc.netcom;
|
|
||||||
|
|
||||||
import com.xxl.job.core.rpc.codec.RpcRequest;
|
|
||||||
import com.xxl.job.core.rpc.codec.RpcResponse;
|
|
||||||
import com.xxl.job.core.rpc.netcom.jetty.client.JettyClient;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.factory.FactoryBean;
|
|
||||||
|
|
||||||
import java.lang.reflect.InvocationHandler;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.lang.reflect.Proxy;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* rpc proxy
|
|
||||||
* @author xuxueli 2015-10-29 20:18:32
|
|
||||||
*/
|
|
||||||
public class NetComClientProxy implements FactoryBean<Object> {
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(NetComClientProxy.class);
|
|
||||||
|
|
||||||
// ---------------------- config ----------------------
|
|
||||||
private Class<?> iface;
|
|
||||||
private String serverAddress;
|
|
||||||
private String accessToken;
|
|
||||||
private JettyClient client = new JettyClient();
|
|
||||||
public NetComClientProxy(Class<?> iface, String serverAddress, String accessToken) {
|
|
||||||
this.iface = iface;
|
|
||||||
this.serverAddress = serverAddress;
|
|
||||||
this.accessToken = accessToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getObject() throws Exception {
|
|
||||||
return Proxy.newProxyInstance(Thread.currentThread()
|
|
||||||
.getContextClassLoader(), new Class[] { iface },
|
|
||||||
new InvocationHandler() {
|
|
||||||
@Override
|
|
||||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
|
||||||
|
|
||||||
// filter method like "Object.toString()"
|
|
||||||
if (Object.class.getName().equals(method.getDeclaringClass().getName())) {
|
|
||||||
logger.error(">>>>>>>>>>> xxl-rpc proxy class-method not support [{}.{}]", method.getDeclaringClass().getName(), method.getName());
|
|
||||||
throw new RuntimeException("xxl-rpc proxy class-method not support");
|
|
||||||
}
|
|
||||||
|
|
||||||
// request
|
|
||||||
RpcRequest request = new RpcRequest();
|
|
||||||
request.setServerAddress(serverAddress);
|
|
||||||
request.setCreateMillisTime(System.currentTimeMillis());
|
|
||||||
request.setAccessToken(accessToken);
|
|
||||||
request.setClassName(method.getDeclaringClass().getName());
|
|
||||||
request.setMethodName(method.getName());
|
|
||||||
request.setParameterTypes(method.getParameterTypes());
|
|
||||||
request.setParameters(args);
|
|
||||||
|
|
||||||
// send
|
|
||||||
RpcResponse response = client.send(request);
|
|
||||||
|
|
||||||
// valid response
|
|
||||||
if (response == null) {
|
|
||||||
throw new Exception("Network request fail, response not found.");
|
|
||||||
}
|
|
||||||
if (response.isError()) {
|
|
||||||
throw new RuntimeException(response.getError());
|
|
||||||
} else {
|
|
||||||
return response.getResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public Class<?> getObjectType() {
|
|
||||||
return iface;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public boolean isSingleton() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,84 +0,0 @@
|
|||||||
package com.xxl.job.core.rpc.netcom;
|
|
||||||
|
|
||||||
import com.xxl.job.core.biz.model.ReturnT;
|
|
||||||
import com.xxl.job.core.rpc.codec.RpcRequest;
|
|
||||||
import com.xxl.job.core.rpc.codec.RpcResponse;
|
|
||||||
import com.xxl.job.core.rpc.netcom.jetty.server.JettyServer;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.cglib.reflect.FastClass;
|
|
||||||
import org.springframework.cglib.reflect.FastMethod;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* netcom init
|
|
||||||
* @author xuxueli 2015-10-31 22:54:27
|
|
||||||
*/
|
|
||||||
public class NetComServerFactory {
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(NetComServerFactory.class);
|
|
||||||
|
|
||||||
// ---------------------- server start ----------------------
|
|
||||||
JettyServer server = new JettyServer();
|
|
||||||
public void start(int port, String ip, String appName) throws Exception {
|
|
||||||
server.start(port, ip, appName);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------- server destroy ----------------------
|
|
||||||
public void destroy(){
|
|
||||||
server.destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------- server instance ----------------------
|
|
||||||
/**
|
|
||||||
* init local rpc service map
|
|
||||||
*/
|
|
||||||
private static Map<String, Object> serviceMap = new HashMap<String, Object>();
|
|
||||||
private static String accessToken;
|
|
||||||
public static void putService(Class<?> iface, Object serviceBean){
|
|
||||||
serviceMap.put(iface.getName(), serviceBean);
|
|
||||||
}
|
|
||||||
public static void setAccessToken(String accessToken) {
|
|
||||||
NetComServerFactory.accessToken = accessToken;
|
|
||||||
}
|
|
||||||
public static RpcResponse invokeService(RpcRequest request, Object serviceBean) {
|
|
||||||
if (serviceBean==null) {
|
|
||||||
serviceBean = serviceMap.get(request.getClassName());
|
|
||||||
}
|
|
||||||
if (serviceBean == null) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
RpcResponse response = new RpcResponse();
|
|
||||||
|
|
||||||
if (System.currentTimeMillis() - request.getCreateMillisTime() > 180000) {
|
|
||||||
response.setResult(new ReturnT<String>(ReturnT.FAIL_CODE, "The timestamp difference between admin and executor exceeds the limit."));
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
if (accessToken!=null && accessToken.trim().length()>0 && !accessToken.trim().equals(request.getAccessToken())) {
|
|
||||||
response.setResult(new ReturnT<String>(ReturnT.FAIL_CODE, "The access token[" + request.getAccessToken() + "] is wrong."));
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
Class<?> serviceClass = serviceBean.getClass();
|
|
||||||
String methodName = request.getMethodName();
|
|
||||||
Class<?>[] parameterTypes = request.getParameterTypes();
|
|
||||||
Object[] parameters = request.getParameters();
|
|
||||||
|
|
||||||
FastClass serviceFastClass = FastClass.create(serviceClass);
|
|
||||||
FastMethod serviceFastMethod = serviceFastClass.getMethod(methodName, parameterTypes);
|
|
||||||
|
|
||||||
Object result = serviceFastMethod.invoke(serviceBean, parameters);
|
|
||||||
|
|
||||||
response.setResult(result);
|
|
||||||
} catch (Throwable t) {
|
|
||||||
t.printStackTrace();
|
|
||||||
response.setError(t.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
package com.xxl.job.core.rpc.netcom.jetty.client;
|
|
||||||
|
|
||||||
import com.xxl.job.core.rpc.codec.RpcRequest;
|
|
||||||
import com.xxl.job.core.rpc.codec.RpcResponse;
|
|
||||||
import com.xxl.job.core.rpc.serialize.HessianSerializer;
|
|
||||||
import com.xxl.job.core.util.HttpClientUtil;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* jetty client
|
|
||||||
* @author xuxueli 2015-11-24 22:25:15
|
|
||||||
*/
|
|
||||||
public class JettyClient {
|
|
||||||
private static Logger logger = LoggerFactory.getLogger(JettyClient.class);
|
|
||||||
|
|
||||||
public RpcResponse send(RpcRequest request) throws Exception {
|
|
||||||
try {
|
|
||||||
// serialize request
|
|
||||||
byte[] requestBytes = HessianSerializer.serialize(request);
|
|
||||||
|
|
||||||
// reqURL
|
|
||||||
String reqURL = request.getServerAddress();
|
|
||||||
if (reqURL!=null && reqURL.toLowerCase().indexOf("http")==-1) {
|
|
||||||
reqURL = "http://" + request.getServerAddress() + "/"; // IP:PORT, need parse to url
|
|
||||||
}
|
|
||||||
|
|
||||||
// remote invoke
|
|
||||||
byte[] responseBytes = HttpClientUtil.postRequest(reqURL, requestBytes);
|
|
||||||
if (responseBytes == null || responseBytes.length==0) {
|
|
||||||
RpcResponse rpcResponse = new RpcResponse();
|
|
||||||
rpcResponse.setError("Network request fail, RpcResponse byte[] is null");
|
|
||||||
return rpcResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
// deserialize response
|
|
||||||
RpcResponse rpcResponse = (RpcResponse) HessianSerializer.deserialize(responseBytes, RpcResponse.class);
|
|
||||||
return rpcResponse;
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error(e.getMessage(), e);
|
|
||||||
|
|
||||||
RpcResponse rpcResponse = new RpcResponse();
|
|
||||||
rpcResponse.setError("Network request error: " + e.getMessage());
|
|
||||||
return rpcResponse;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,92 +0,0 @@
|
|||||||
package com.xxl.job.core.rpc.netcom.jetty.server;
|
|
||||||
|
|
||||||
import com.xxl.job.core.thread.ExecutorRegistryThread;
|
|
||||||
import com.xxl.job.core.thread.TriggerCallbackThread;
|
|
||||||
import org.eclipse.jetty.server.Connector;
|
|
||||||
import org.eclipse.jetty.server.Handler;
|
|
||||||
import org.eclipse.jetty.server.Server;
|
|
||||||
import org.eclipse.jetty.server.ServerConnector;
|
|
||||||
import org.eclipse.jetty.server.handler.HandlerCollection;
|
|
||||||
import org.eclipse.jetty.util.thread.ExecutorThreadPool;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* rpc jetty server
|
|
||||||
* @author xuxueli 2015-11-19 22:29:03
|
|
||||||
*/
|
|
||||||
public class JettyServer {
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(JettyServer.class);
|
|
||||||
|
|
||||||
private Server server;
|
|
||||||
private Thread thread;
|
|
||||||
public void start(final int port, final String ip, final String appName) throws Exception {
|
|
||||||
thread = new Thread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
|
|
||||||
// The Server
|
|
||||||
server = new Server(new ExecutorThreadPool(1000));
|
|
||||||
|
|
||||||
// HTTP connector
|
|
||||||
ServerConnector connector = new ServerConnector(server);
|
|
||||||
if (ip!=null && ip.trim().length()>0) {
|
|
||||||
//connector.setHost(ip); // The network interface this connector binds to as an IP address or a hostname. If null or 0.0.0.0, then bind to all interfaces.
|
|
||||||
}
|
|
||||||
connector.setPort(port);
|
|
||||||
server.setConnectors(new Connector[]{connector});
|
|
||||||
|
|
||||||
// Set a handler
|
|
||||||
HandlerCollection handlerc =new HandlerCollection();
|
|
||||||
handlerc.setHandlers(new Handler[]{new JettyServerHandler()});
|
|
||||||
server.setHandler(handlerc);
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Start server
|
|
||||||
server.start();
|
|
||||||
logger.info(">>>>>>>>>>> xxl-job jetty server start success at port:{}.", port);
|
|
||||||
|
|
||||||
// Start Registry-Server
|
|
||||||
ExecutorRegistryThread.getInstance().start(port, ip, appName);
|
|
||||||
|
|
||||||
// Start Callback-Server
|
|
||||||
TriggerCallbackThread.getInstance().start();
|
|
||||||
|
|
||||||
server.join(); // block until thread stopped
|
|
||||||
logger.info(">>>>>>>>>>> xxl-rpc server join success, netcon={}, port={}", JettyServer.class.getName(), port);
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error(e.getMessage(), e);
|
|
||||||
} finally {
|
|
||||||
//destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
thread.setDaemon(true); // daemon, service jvm, user thread leave >>> daemon leave >>> jvm leave
|
|
||||||
thread.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void destroy() {
|
|
||||||
|
|
||||||
// destroy Registry-Server
|
|
||||||
ExecutorRegistryThread.getInstance().toStop();
|
|
||||||
|
|
||||||
// destroy Callback-Server
|
|
||||||
TriggerCallbackThread.getInstance().toStop();
|
|
||||||
|
|
||||||
// destroy server
|
|
||||||
if (server != null) {
|
|
||||||
try {
|
|
||||||
server.stop();
|
|
||||||
server.destroy();
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error(e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (thread.isAlive()) {
|
|
||||||
thread.interrupt();
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.info(">>>>>>>>>>> xxl-rpc server destroy success, netcon={}", JettyServer.class.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,68 +0,0 @@
|
|||||||
package com.xxl.job.core.rpc.netcom.jetty.server;
|
|
||||||
|
|
||||||
import com.xxl.job.core.rpc.codec.RpcRequest;
|
|
||||||
import com.xxl.job.core.rpc.codec.RpcResponse;
|
|
||||||
import com.xxl.job.core.rpc.netcom.NetComServerFactory;
|
|
||||||
import com.xxl.job.core.rpc.serialize.HessianSerializer;
|
|
||||||
import com.xxl.job.core.util.HttpClientUtil;
|
|
||||||
import org.eclipse.jetty.server.Request;
|
|
||||||
import org.eclipse.jetty.server.handler.AbstractHandler;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* jetty handler
|
|
||||||
* @author xuxueli 2015-11-19 22:32:36
|
|
||||||
*/
|
|
||||||
public class JettyServerHandler extends AbstractHandler {
|
|
||||||
private static Logger logger = LoggerFactory.getLogger(JettyServerHandler.class);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
|
|
||||||
|
|
||||||
// invoke
|
|
||||||
RpcResponse rpcResponse = doInvoke(request);
|
|
||||||
|
|
||||||
// serialize response
|
|
||||||
byte[] responseBytes = HessianSerializer.serialize(rpcResponse);
|
|
||||||
|
|
||||||
response.setContentType("text/html;charset=utf-8");
|
|
||||||
response.setStatus(HttpServletResponse.SC_OK);
|
|
||||||
baseRequest.setHandled(true);
|
|
||||||
|
|
||||||
OutputStream out = response.getOutputStream();
|
|
||||||
out.write(responseBytes);
|
|
||||||
out.flush();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private RpcResponse doInvoke(HttpServletRequest request) {
|
|
||||||
try {
|
|
||||||
// deserialize request
|
|
||||||
byte[] requestBytes = HttpClientUtil.readBytes(request);
|
|
||||||
if (requestBytes == null || requestBytes.length==0) {
|
|
||||||
RpcResponse rpcResponse = new RpcResponse();
|
|
||||||
rpcResponse.setError("RpcRequest byte[] is null");
|
|
||||||
return rpcResponse;
|
|
||||||
}
|
|
||||||
RpcRequest rpcRequest = (RpcRequest) HessianSerializer.deserialize(requestBytes, RpcRequest.class);
|
|
||||||
|
|
||||||
// invoke
|
|
||||||
RpcResponse rpcResponse = NetComServerFactory.invokeService(rpcRequest, null);
|
|
||||||
return rpcResponse;
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error(e.getMessage(), e);
|
|
||||||
|
|
||||||
RpcResponse rpcResponse = new RpcResponse();
|
|
||||||
rpcResponse.setError("Server-error:" + e.getMessage());
|
|
||||||
return rpcResponse;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,62 +0,0 @@
|
|||||||
package com.xxl.job.core.rpc.serialize;
|
|
||||||
|
|
||||||
import com.caucho.hessian.io.Hessian2Input;
|
|
||||||
import com.caucho.hessian.io.Hessian2Output;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* hessian serialize
|
|
||||||
* @author xuxueli 2015-9-26 02:53:29
|
|
||||||
*/
|
|
||||||
public class HessianSerializer {
|
|
||||||
|
|
||||||
public static <T> byte[] serialize(T obj){
|
|
||||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
|
||||||
Hessian2Output ho = new Hessian2Output(os);
|
|
||||||
try {
|
|
||||||
ho.writeObject(obj);
|
|
||||||
ho.flush();
|
|
||||||
byte[] result = os.toByteArray();
|
|
||||||
return result;
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new IllegalStateException(e.getMessage(), e);
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
ho.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new IllegalStateException(e.getMessage(), e);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
os.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new IllegalStateException(e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> Object deserialize(byte[] bytes, Class<T> clazz) {
|
|
||||||
ByteArrayInputStream is = new ByteArrayInputStream(bytes);
|
|
||||||
Hessian2Input hi = new Hessian2Input(is);
|
|
||||||
try {
|
|
||||||
Object result = hi.readObject();
|
|
||||||
return result;
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new IllegalStateException(e.getMessage(), e);
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
hi.close();
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new IllegalStateException(e.getMessage(), e);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
is.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new IllegalStateException(e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,110 +0,0 @@
|
|||||||
package com.xxl.job.core.util;
|
|
||||||
|
|
||||||
import org.apache.http.HttpEntity;
|
|
||||||
import org.apache.http.HttpResponse;
|
|
||||||
import org.apache.http.client.config.RequestConfig;
|
|
||||||
import org.apache.http.client.methods.HttpPost;
|
|
||||||
import org.apache.http.entity.ByteArrayEntity;
|
|
||||||
import org.apache.http.entity.ContentType;
|
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
|
||||||
import org.apache.http.impl.client.HttpClients;
|
|
||||||
import org.apache.http.util.EntityUtils;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* httpclient util
|
|
||||||
* @author xuxueli 2015-10-31 19:50:41
|
|
||||||
*/
|
|
||||||
public class HttpClientUtil {
|
|
||||||
private static Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* post request
|
|
||||||
*/
|
|
||||||
public static byte[] postRequest(String reqURL, byte[] data) throws Exception {
|
|
||||||
byte[] responseBytes = null;
|
|
||||||
|
|
||||||
HttpPost httpPost = new HttpPost(reqURL);
|
|
||||||
//CloseableHttpClient httpClient = HttpClients.createDefault();
|
|
||||||
CloseableHttpClient httpClient = HttpClients.custom().disableAutomaticRetries().build(); // disable retry
|
|
||||||
|
|
||||||
try {
|
|
||||||
// init post
|
|
||||||
/*if (params != null && !params.isEmpty()) {
|
|
||||||
List<NameValuePair> formParams = new ArrayList<NameValuePair>();
|
|
||||||
for (Map.Entry<String, String> entry : params.entrySet()) {
|
|
||||||
formParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
|
|
||||||
}
|
|
||||||
httpPost.setEntity(new UrlEncodedFormEntity(formParams, "UTF-8"));
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// timeout
|
|
||||||
RequestConfig requestConfig = RequestConfig.custom()
|
|
||||||
.setConnectionRequestTimeout(10000)
|
|
||||||
.setSocketTimeout(10000)
|
|
||||||
.setConnectTimeout(10000)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
httpPost.setConfig(requestConfig);
|
|
||||||
|
|
||||||
// data
|
|
||||||
if (data != null) {
|
|
||||||
httpPost.setEntity(new ByteArrayEntity(data, ContentType.DEFAULT_BINARY));
|
|
||||||
}
|
|
||||||
// do post
|
|
||||||
HttpResponse response = httpClient.execute(httpPost);
|
|
||||||
HttpEntity entity = response.getEntity();
|
|
||||||
if (null != entity) {
|
|
||||||
responseBytes = EntityUtils.toByteArray(entity);
|
|
||||||
EntityUtils.consume(entity);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw e;
|
|
||||||
} finally {
|
|
||||||
httpPost.releaseConnection();
|
|
||||||
try {
|
|
||||||
httpClient.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
logger.error(e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return responseBytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* read bytes from http request
|
|
||||||
* @param request
|
|
||||||
* @return
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public static final byte[] readBytes(HttpServletRequest request) throws IOException {
|
|
||||||
request.setCharacterEncoding("UTF-8");
|
|
||||||
int contentLen = request.getContentLength();
|
|
||||||
InputStream is = request.getInputStream();
|
|
||||||
if (contentLen > 0) {
|
|
||||||
int readLen = 0;
|
|
||||||
int readLengthThisTime = 0;
|
|
||||||
byte[] message = new byte[contentLen];
|
|
||||||
try {
|
|
||||||
while (readLen != contentLen) {
|
|
||||||
readLengthThisTime = is.read(message, readLen, contentLen - readLen);
|
|
||||||
if (readLengthThisTime == -1) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
readLen += readLengthThisTime;
|
|
||||||
}
|
|
||||||
return message;
|
|
||||||
} catch (IOException e) {
|
|
||||||
logger.error(e.getMessage(), e);
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new byte[] {};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,135 +0,0 @@
|
|||||||
package com.xxl.job.core.util;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.NetworkInterface;
|
|
||||||
import java.net.UnknownHostException;
|
|
||||||
import java.util.Enumeration;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get ip
|
|
||||||
*
|
|
||||||
* @author xuxueli 2016-5-22 11:38:05
|
|
||||||
*/
|
|
||||||
public class IpUtil {
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(IpUtil.class);
|
|
||||||
|
|
||||||
private static final String ANYHOST = "0.0.0.0";
|
|
||||||
private static final String LOCALHOST = "127.0.0.1";
|
|
||||||
public static final Pattern IP_PATTERN = Pattern.compile("\\d{1,3}(\\.\\d{1,3}){3,5}$");
|
|
||||||
|
|
||||||
private static volatile String LOCAL_ADDRESS = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* valid address
|
|
||||||
* @param address
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
private static boolean isValidAddress(InetAddress address) {
|
|
||||||
if (address == null || address.isLoopbackAddress() || address.isLinkLocalAddress()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
String name = address.getHostAddress();
|
|
||||||
return (name != null
|
|
||||||
&& ! ANYHOST.equals(name)
|
|
||||||
&& ! LOCALHOST.equals(name)
|
|
||||||
&& IP_PATTERN.matcher(name).matches());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get first valid addredd
|
|
||||||
*
|
|
||||||
* @return InetAddress
|
|
||||||
*/
|
|
||||||
private static InetAddress getFirstValidAddress() {
|
|
||||||
|
|
||||||
// NetworkInterface address
|
|
||||||
try {
|
|
||||||
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
|
|
||||||
if (interfaces != null) {
|
|
||||||
while (interfaces.hasMoreElements()) {
|
|
||||||
try {
|
|
||||||
NetworkInterface network = interfaces.nextElement();
|
|
||||||
Enumeration<InetAddress> addresses = network.getInetAddresses();
|
|
||||||
if (addresses != null) {
|
|
||||||
while (addresses.hasMoreElements()) {
|
|
||||||
try {
|
|
||||||
InetAddress address = addresses.nextElement();
|
|
||||||
if (isValidAddress(address)) {
|
|
||||||
return address;
|
|
||||||
}
|
|
||||||
} catch (Throwable e) {
|
|
||||||
logger.error("Failed to retriving ip address, " + e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Throwable e) {
|
|
||||||
logger.error("Failed to retriving ip address, " + e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Throwable e) {
|
|
||||||
logger.error("Failed to retriving ip address, " + e.getMessage(), e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// getLocalHost address
|
|
||||||
try {
|
|
||||||
InetAddress localAddress = InetAddress.getLocalHost();
|
|
||||||
if (isValidAddress(localAddress)) {
|
|
||||||
return localAddress;
|
|
||||||
}
|
|
||||||
} catch (Throwable e) {
|
|
||||||
logger.error("Failed to retriving ip address, " + e.getMessage(), e);
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.error("Could not get local host ip address, will use 127.0.0.1 instead.");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get address
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
private static String getAddress() {
|
|
||||||
if (LOCAL_ADDRESS != null) {
|
|
||||||
return LOCAL_ADDRESS;
|
|
||||||
}
|
|
||||||
InetAddress localAddress = getFirstValidAddress();
|
|
||||||
LOCAL_ADDRESS = localAddress.getHostAddress();
|
|
||||||
return LOCAL_ADDRESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get ip
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
public static String getIp(){
|
|
||||||
return getAddress();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get ip:port
|
|
||||||
*
|
|
||||||
* @param port
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
public static String getIpPort(int port){
|
|
||||||
String ip = getIp();
|
|
||||||
if (ip==null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return ip.concat(":").concat(String.valueOf(port));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) throws UnknownHostException {
|
|
||||||
System.out.println(getIp());
|
|
||||||
System.out.println(getIpPort(8080));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,70 +0,0 @@
|
|||||||
package com.xxl.job.core.util;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.ServerSocket;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* net util
|
|
||||||
*
|
|
||||||
* @author xuxueli 2017-11-29 17:00:25
|
|
||||||
*/
|
|
||||||
public class NetUtil {
|
|
||||||
private static Logger logger = LoggerFactory.getLogger(NetUtil.class);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* find avaliable port
|
|
||||||
*
|
|
||||||
* @param defaultPort
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static int findAvailablePort(int defaultPort) {
|
|
||||||
int portTmp = defaultPort;
|
|
||||||
while (portTmp < 65535) {
|
|
||||||
if (!isPortUsed(portTmp)) {
|
|
||||||
return portTmp;
|
|
||||||
} else {
|
|
||||||
portTmp++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
portTmp = defaultPort--;
|
|
||||||
while (portTmp > 0) {
|
|
||||||
if (!isPortUsed(portTmp)) {
|
|
||||||
return portTmp;
|
|
||||||
} else {
|
|
||||||
portTmp--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new IllegalStateException("no available port.");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* check port used
|
|
||||||
*
|
|
||||||
* @param port
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static boolean isPortUsed(int port) {
|
|
||||||
boolean used = false;
|
|
||||||
ServerSocket serverSocket = null;
|
|
||||||
try {
|
|
||||||
serverSocket = new ServerSocket(port);
|
|
||||||
used = false;
|
|
||||||
} catch (IOException e) {
|
|
||||||
logger.debug(">>>>>>>>>>> xxl-job, port[{}] is in use.", port);
|
|
||||||
used = true;
|
|
||||||
} finally {
|
|
||||||
if (serverSocket != null) {
|
|
||||||
try {
|
|
||||||
serverSocket.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
logger.info("");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return used;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in new issue