Create Project

This commit is contained in:
yanzg
2018-05-18 16:30:47 +08:00
commit cb55bd3603
97 changed files with 2648 additions and 0 deletions

132
pom.xml Normal file
View File

@@ -0,0 +1,132 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.pangdly</groupId>
<artifactId>Http.Netty</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Http.Netty</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- for maven compiler plugin -->
<maven.compiler.plugin.version>3.7.0</maven.compiler.plugin.version>
<maven.surefire.plugin.version>2.20.1</maven.surefire.plugin.version>
<maven.jar.plugin.version>3.0.2</maven.jar.plugin.version>
<maven.dependency.plugin.version>3.0.0</maven.dependency.plugin.version>
<maven.deploy.plugin.version>2.8.2</maven.deploy.plugin.version>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- stormragetech libs -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.16</version>
</dependency>
<!-- common libs -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>
<!-- httpserver libs -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.6</version>
</dependency>
<!-- netty libs -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.15.Final</version>
</dependency>
<!-- spring libs -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<!-- protocol libs -->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.38</version>
</dependency>
<!-- log4j2 libs -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-web</artifactId>
<version>2.7</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.compiler.plugin.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${file.encoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven.surefire.plugin.version}</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>${maven.deploy.plugin.version}</version>
</plugin>
</plugins>
</build>
<distributionManagement>
<repository>
<id>nexus-releases</id>
<name>Nexus Releases Repository</name>
<url>http://192.168.0.99:8081/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>nexus-snapshots</id>
<name>Nexus Snapshots Repository</name>
<url>http://192.168.0.99:8081/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
</project>

View File

@@ -0,0 +1,16 @@
package com.pangdly.annotation;
import java.lang.annotation.*;
/**
* description: //TODO
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Action {
String value() default "className";
}

View File

@@ -0,0 +1,27 @@
package com.pangdly.annotation;
/**
* description: //TODO
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
public enum ContentType {
JSON("application/json");
// FORM("application/x-www-form-urlencoded");
private String value;
ContentType(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}

View File

@@ -0,0 +1,24 @@
package com.pangdly.annotation;
import java.lang.annotation.*;
/**
* description: //TODO
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
@Target(ElementType.METHOD)
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Mapping {
public String url() default "/";
public RequestType method() default RequestType.POST;
public ResponseType response() default ResponseType.JSON;
public String encode() default "UTF-8";
}

View File

@@ -0,0 +1,20 @@
package com.pangdly.annotation;
import java.lang.annotation.*;
/**
* description: //TODO
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
@Documented
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface PathParam {
String name() default "";
boolean ness() default false;
}

View File

@@ -0,0 +1,27 @@
package com.pangdly.annotation;
/**
* description: //TODO
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
public enum RequestType {
GET("GET"),
POST("POST");
private String value;
RequestType(String value) {
this.value = value;
}
public String getValue() {
return this.value;
}
public void setValue(String value) {
this.value = value;
}
}

View File

@@ -0,0 +1,27 @@
package com.pangdly.annotation;
/**
* description: //TODO
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
public enum ResponseType {
JSON("application/json"),
// XML("text/xml"),
// TEXT("text/plain"),
// HTML("text/html"),
ERROR("text/plain");
ResponseType(String value) {
this.value = value;
}
private String value;
public String getValue() {
return value;
}
}

View File

@@ -0,0 +1,29 @@
package com.pangdly.arthas.codec;
import com.pangdly.annotation.RequestType;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
/**
* description: http request object
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ArthasHttpRequest implements Serializable {
private static final long serialVersionUID = 191929180123034366L;
private RequestType type;
private Map<String, String> get;
private Map<String, List<String>> post;
private String token;
}

View File

@@ -0,0 +1,13 @@
package com.pangdly.arthas.codec;
import com.pangdly.exception.ArthasException;
/**
* description: http request decode interface
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
public interface ArthasHttpRequestDecode {
ArthasHttpRequest process() throws ArthasException;
}

View File

@@ -0,0 +1,114 @@
package com.pangdly.arthas.codec;
import com.pangdly.arthas.dispatcher.DataCache;
import com.pangdly.annotation.Mapping;
import com.pangdly.annotation.RequestType;
import com.pangdly.constant.Constant;
import com.pangdly.exception.ArthasException;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.QueryStringDecoder;
import org.apache.commons.codec.CharEncoding;
import java.lang.reflect.Method;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* description: http request decode handler implement
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
public class ArthasHttpRequestDecodeHandler implements ArthasHttpRequestDecode {
private final Method method;
public ArthasHttpRequestDecodeHandler(Method method) {
this.method = method;
}
@Override
public ArthasHttpRequest process() throws ArthasException {
if (RequestType.GET.equals(type(method))) {
return get();
} else {
return post(RequestType.POST);
}
}
private ArthasHttpRequest get() throws ArthasException {
HttpRequest request = (HttpRequest) DataCache.getData();
if (null != paramsInUri(request.uri())) {
//Map<String, String> params = paramsInUri(request.uri());
String token = request.headers().get("token");
return new ArthasHttpRequest(RequestType.GET, paramsInUri(request.uri()), null, token);
} else {
return new ArthasHttpRequest();
}
}
private ArthasHttpRequest post(RequestType type) throws ArthasException {
FullHttpRequest request = (FullHttpRequest) DataCache.getData();
//request.headers().add("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept,token");
String token = request.headers().get("token");
Map<String, String> getParam = paramsInUri(request.uri());
Map<String, List<String>> postParam = new QueryStringDecoder(request.content().toString(Charset.forName(CharEncoding.UTF_8)), false).parameters();
return new ArthasHttpRequest(type, getParam, postParam, token);
}
private RequestType type(Method method) throws ArthasException {
HttpRequest request = (HttpRequest) DataCache.getData();
String hm = request.method().name();
String dm = method.getDeclaredAnnotation(Mapping.class).method().getValue();
//if (null == hm || null == dm || (!dm.equals("") && !dm.equals(hm))) {
if (null == hm || null == dm || dm.equals("")) {
throw new ArthasException(Constant.CODC_ERR_CODE, Constant.CODC_REQ_TYPE, ArthasException.APP_ERR);
} else if (RequestType.GET.getValue().equals(dm)) {
return RequestType.GET;
} else {
return RequestType.POST;
}
}
private Map<String, String> paramsInUri(String uri) throws ArthasException {
if (null != uri && uri.length() > 0) {
String params = uriSplit(uri);
return null == params ? null : paramSplit(params);
} else {
return null;
}
}
private String uriSplit(String uri) throws ArthasException {
String[] arr = uri.split("\\?");
if (arr.length != 2) {
return null;
} else {
return arr[1];
}
}
private Map<String, String> paramSplit(String params) {
Map<String, String> map = new HashMap<>();
String[] arr = params.split("&");
Arrays.stream(arr).forEach((param) -> {
String[] pa = param.split("=");
if (pa.length == 2) {
map.put(pa[0], pa[1]);
}
});
return map;
}
}

View File

@@ -0,0 +1,13 @@
package com.pangdly.arthas.codec;
import io.netty.handler.codec.http.FullHttpResponse;
/**
* description: http response encode interface
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
public interface ArthasHttpResponseEncode {
FullHttpResponse process();
}

View File

@@ -0,0 +1,61 @@
package com.pangdly.arthas.codec;
import com.pangdly.annotation.ResponseType;
import com.pangdly.constant.Constant;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpVersion;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.log4j.Log4j2;
/**
* description: http response encode implement
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
@Log4j2
@Data
@AllArgsConstructor
public class ArthasHttpResponseEncodeHandler implements ArthasHttpResponseEncode {
private String data;
private ResponseType type;
@Override
public FullHttpResponse process() {
return ResponseHandler.handle(data, type);
}
private static class ResponseHandler {
static FullHttpResponse handle(String data, ResponseType type) {
if (null == data || null == type) {
data = "server error !!!";
type = ResponseType.ERROR;
}
log.info("ArthasHttpResponseEncodeHandler.ResponseHandler.handle()->data:{}", data);
ByteBuf buf = Unpooled.wrappedBuffer(data.getBytes());
log.info("ArthasHttpResponseEncodeHandler.ResponseHandler.handle()->buf:{}", buf);
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, buf);
response.headers()
.add(Constant.CONTENT_TYPE, type.getValue())
.add(Constant.CONTENT_LENGTH, String.valueOf(buf.readableBytes()));
log.info("ArthasHttpResponseEncodeHandler.ResponseHandler.handle()->response:{}", response);
return response;
}
}
public static void main(String[] args) {
ArthasHttpResponseEncodeHandler handler = new ArthasHttpResponseEncodeHandler("nihao", ResponseType.JSON);
log.info(ResponseType.JSON.getValue());
log.info(handler.process());
}
}

View File

@@ -0,0 +1,37 @@
package com.pangdly.arthas.dispatcher;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.HttpServerExpectContinueHandler;
import io.netty.handler.ssl.SslContext;
/**
* description: arthas channel initializer, initialize netty channel
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
public class ArthasChannelInitializer extends ChannelInitializer<SocketChannel> {
private final SslContext ssl;
public ArthasChannelInitializer(SslContext ssl) {
this.ssl = ssl;
}
@Override
protected void initChannel(SocketChannel channel) {
ChannelPipeline pipeline = channel.pipeline();
if (null != ssl) {
pipeline.addLast(ssl.newHandler(channel.alloc()));
}
pipeline.addLast(new HttpServerCodec());
pipeline.addLast(new HttpObjectAggregator(1024 * 1024 * 64));
pipeline.addLast(new HttpServerExpectContinueHandler());
pipeline.addLast(new ArthasHttpHandler());
}
}

View File

@@ -0,0 +1,64 @@
package com.pangdly.arthas.dispatcher;
import com.pangdly.constant.Constant;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpUtil;
import lombok.extern.log4j.Log4j2;
/**
* description: Arthas channel handler, recieve request and response result
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
@Log4j2
public class ArthasHttpHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelReadComplete(ChannelHandlerContext ctx) {
ctx.flush();
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
long start = System.currentTimeMillis();
if (msg instanceof HttpRequest) {
// initialize channel and request
// cache the data to ThreadLocal
//
HttpRequest request = (HttpRequest) msg;
DataCache.setData(msg);
FullHttpResponse response = new ArthasProcessHandler().process();
boolean keepAlive = HttpUtil.isKeepAlive(request);
if (!keepAlive) {
ctx.write(response).addListener(ChannelFutureListener.CLOSE);
} else {
response.headers().set("Access-Control-Allow-Origin", "*");
response.headers().set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept,token");
response.headers().set(Constant.CONNECTION, Constant.KEEP_ALIVE);
ctx.write(response);
}
log.info("---------------------------------------------------------------");
log.info("READ: {}", ctx.channel());
log.info("URL: {}", request.uri().split("\\?")[0]);
log.info("RESPONSE: {}", response);
log.info("READ: complete | COST: {} | RESPONSE: {}", System.currentTimeMillis() - start, response.status());
log.info("---------------------------------------------------------------\n\n");
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
log.error("netty handler http request occur error, excepion: {}", cause.getStackTrace().toString());
ctx.close();
}
}

View File

@@ -0,0 +1,14 @@
package com.pangdly.arthas.dispatcher;
import com.pangdly.exception.ArthasException;
import io.netty.handler.codec.http.FullHttpResponse;
/**
* description: http request handle process interface
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
public interface ArthasProcess {
FullHttpResponse process() throws ArthasException;
}

View File

@@ -0,0 +1,109 @@
package com.pangdly.arthas.dispatcher;
import com.pangdly.arthas.codec.ArthasHttpResponseEncodeHandler;
import com.pangdly.annotation.ResponseType;
import com.pangdly.constant.Constant;
import com.pangdly.exception.ArthasException;
import com.pangdly.arthas.process.context.Context;
import com.pangdly.arthas.process.context.XmlConfigFileActionContext;
import com.pangdly.arthas.process.factory.ActionWrapper;
import com.pangdly.arthas.process.proxy.Proxy;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpRequest;
import lombok.extern.log4j.Log4j2;
/**
* description: http request handler process implement
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
@Log4j2
@SuppressWarnings("rawtypes")
public class ArthasProcessHandler implements ArthasProcess {
private static Context context;
private String path;
private String name;
public void init(String name) {
name = null == name ? "" : name;
context = new XmlConfigFileActionContext(name);
}
@Override
public FullHttpResponse process() {
// if context is null, initialize it
//
if (null == context) {
name = null == name ? "" : name;
context = new XmlConfigFileActionContext(name);
}
// handle request
//
String result = "";
ResponseType type = null;
HttpRequest request = (HttpRequest) DataCache.getData();
path = request.uri();
try {
// handle request
//
result = proxy().execute();
log.info("ArthasProcessHandler()----result({})", result);
type = wrapper().getResponse();
//handle response and return
//
return new ArthasHttpResponseEncodeHandler(result, type).process();
} catch (ArthasException e) {
log.error("handle http request throw exception, cause: {}", e.toString());
// initialize error response and return
//
result = Constant.ERR_MSG;
type = ResponseType.ERROR;
return new ArthasHttpResponseEncodeHandler(result, type).process();
} catch (Exception e) {
log.error("handle http request throw exception, cause: {}", e.toString());
// initialize error response and return
//
result = Constant.ERR_MSG;
type = ResponseType.ERROR;
return new ArthasHttpResponseEncodeHandler(result, type).process();
} finally {
log.info("------------------------------------------------------------");
log.info("TYPE: {}", type);
log.info("CONTENT: {}", result);
}
}
private Proxy proxy() throws ArthasException {
Proxy proxy = context.getProxy(wrapper());
if (null == proxy) {
throw new ArthasException(Constant.DISP_ERR_CODE, Constant.DISP_PROX_MSG, ArthasException.APP_ERR);
}
return proxy;
}
private ActionWrapper wrapper() throws ArthasException {
if (null == path || path.length() <= 0) {
throw new ArthasException(Constant.DISP_ERR_CODE, Constant.DISP_WRAP_MSG, ArthasException.APP_ERR);
}
ActionWrapper wrapper;
try {
wrapper = context.getWrapper(path);
} catch (Exception e) {
throw new ArthasException(Constant.DISP_ERR_CODE, Constant.DISP_WRAP_MSG, ArthasException.APP_ERR);
}
if (null == wrapper) {
throw new ArthasException(Constant.DISP_ERR_CODE, Constant.DISP_WRAP_MSG, ArthasException.APP_ERR);
}
return wrapper;
}
}

View File

@@ -0,0 +1,22 @@
package com.pangdly.arthas.dispatcher;
/**
* description: ThreadLocal object
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
public class DataCache {
private static final ThreadLocal<Object> localData = new ThreadLocal<>();
static void setData(Object obj) {
localData.set(obj);
}
public static Object getData() {
return localData.get();
}
}

View File

@@ -0,0 +1,75 @@
package com.pangdly.arthas.process.context;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
import com.pangdly.arthas.process.factory.ActionWrapper;
import com.pangdly.annotation.Mapping;
import com.pangdly.util.ArthasUtil;
import com.pangdly.util.SpringUtil;
import lombok.extern.log4j.Log4j2;
/**
* description: context base initializer
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
@Log4j2
@SuppressWarnings("rawtypes")
abstract class ActionContext {
@SuppressWarnings("unchecked")
Map<String, ActionWrapper<?>> wrapperMap(List<String> names) {
// get the value of class whole name in package
// set the value into list
//
List<String> list = new ArrayList<>();
names.forEach(name -> ArthasUtil.findFilesInPackage(name, list));
log.info("the class file list is {}", list);
// init the action wrapper of the classes
// set the value into the map
//
Map<String, ActionWrapper<?>> map = new HashMap<>();
list.forEach((String entry) -> {
try {
Class clazz = Class.forName(entry);
Method[] methods = clazz.getDeclaredMethods();
if (null == methods || methods.length <= 0) {
return;
}
Predicate<Method> predicate = m -> (null == m || null == m.getAnnotation(Mapping.class)) ? false : true;
Arrays.stream(methods).filter(predicate).forEach((Method method) -> {
try {
ActionWrapper wrapper = new ActionWrapper();
if (null != SpringUtil.getContext()) {
wrapper.setAction(SpringUtil.getBean(clazz));
} else {
wrapper.setAction(clazz.newInstance());
}
wrapper.setName(clazz.getName());
wrapper.setTarget(method.getAnnotation(Mapping.class).url());
wrapper.setType(method.getAnnotation(Mapping.class).method());
wrapper.setResponse(method.getAnnotation(Mapping.class).response());
wrapper.setMethod(method);
map.put(method.getAnnotation(Mapping.class).url(), wrapper);
} catch (Exception e) {
log.error("Server error!!! {}", e);
}
});
} catch (Exception e) {
e.printStackTrace();
}
});
return map;
}
}

View File

@@ -0,0 +1,23 @@
package com.pangdly.arthas.process.context;
import com.pangdly.arthas.process.factory.ActionWrapper;
import com.pangdly.arthas.process.proxy.Proxy;
/**
* description: context initialize interface
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
@SuppressWarnings("rawtypes")
public interface Context {
Proxy getProxy(ActionWrapper action);
ActionWrapper getWrapper(String path) throws Exception;
Object getAction(String name) throws Exception;
Object getAction(String name, Class<?> type) throws Exception;
}

View File

@@ -0,0 +1,55 @@
package com.pangdly.arthas.process.context;
import com.pangdly.arthas.process.factory.ActionFactory;
import com.pangdly.arthas.process.factory.ActionWrapper;
import com.pangdly.arthas.process.factory.AwareActionFactory;
import com.pangdly.arthas.process.invocation.ActionInvoke;
import com.pangdly.arthas.process.proxy.FactoryProxy;
import com.pangdly.arthas.process.proxy.Proxy;
import com.pangdly.exception.ArthasException;
import com.pangdly.util.ArthasUtil;
import com.pangdly.util.Assert;
import lombok.extern.log4j.Log4j2;
/**
* description: initalize context from xml config file
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
@Log4j2
@SuppressWarnings("rawtypes")
public class XmlConfigFileActionContext extends ActionContext implements Context {
private ActionFactory factory;
public XmlConfigFileActionContext(String name) {
Assert.notNull(name, "file name cannot be null !!!");
factory = new AwareActionFactory(wrapperMap(ArthasUtil.parsePackage(name)));
log.info("action factory is: {}", factory.toString());
}
@SuppressWarnings("unchecked")
@Override
public Proxy getProxy(ActionWrapper action) {
Proxy proxy = new FactoryProxy(action);
proxy.setInvoke(new ActionInvoke(proxy));
return proxy;
}
@Override
public ActionWrapper getWrapper(String path) throws ArthasException {
return factory.getWrapper(path);
}
@Override
public Object getAction(String name) throws ArthasException {
return factory.getAction(name);
}
@Override
public Object getAction(String name, Class<?> clazz) throws ArthasException {
return factory.getAction(name, clazz);
}
}

View File

@@ -0,0 +1,21 @@
package com.pangdly.arthas.process.factory;
import com.pangdly.exception.ArthasException;
/**
* description: action factory interface
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
public interface ActionFactory {
ActionWrapper<?> getWrapper(String path) throws ArthasException;
Object getAction(String name) throws ArthasException;
<T> T getAction(String name, Class<T> clazz) throws ArthasException;
boolean containsAction(String name);
}

View File

@@ -0,0 +1,29 @@
package com.pangdly.arthas.process.factory;
import com.pangdly.annotation.RequestType;
import com.pangdly.annotation.ResponseType;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.lang.reflect.Method;
/**
* description: action wrapper
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ActionWrapper<T> {
private T action;
private Method method;
private String name;
private String target;
private RequestType type;
private ResponseType response;
}

View File

@@ -0,0 +1,69 @@
package com.pangdly.arthas.process.factory;
import java.util.Map;
import com.pangdly.constant.Constant;
import com.pangdly.exception.ArthasException;
import com.pangdly.util.Assert;
/**
* description: action wrapper factory
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
public class AwareActionFactory implements ActionFactory {
private Map<String, ActionWrapper<?>> actions;
public AwareActionFactory(Map<String, ActionWrapper<?>> actions) {
Assert.notNull(actions, "Map cannot be null !!!");
this.actions = actions;
}
@Override
public ActionWrapper<?> getWrapper(String path) throws ArthasException {
for (String key : actions.keySet()) {
if (path.contains(key)) {
return actions.get(key);
}
}
throw new ArthasException(Constant.PROC_ERR_CODE, Constant.PROC_NO_WRAP, ArthasException.APP_ERR);
}
@Override
public Object getAction(String name) throws ArthasException {
if (containsAction(name)) {
return actions.get(name).getAction();
} else {
throw new ArthasException(Constant.PROC_ERR_CODE, Constant.PROC_NO_WRAP, ArthasException.APP_ERR);
}
}
@SuppressWarnings("unchecked")
@Override
public <T> T getAction(String name, Class<T> clazz) throws ArthasException {
if (containsAction(name)) {
ActionWrapper<T> wrapper = (ActionWrapper<T>) actions.get(name);
if (clazz.getName().equals(wrapper.getName())) {
return wrapper.getAction();
} else {
throw new ArthasException(Constant.PROC_ERR_CODE, Constant.PROC_NO_WRAP, ArthasException.APP_ERR);
}
} else {
throw new ArthasException(Constant.PROC_ERR_CODE, Constant.PROC_NO_WRAP, ArthasException.APP_ERR);
}
}
@Override
public boolean containsAction(String name) {
return null != actions && actions.keySet().stream().filter(key -> key.equals(name)).count() > 0;
}
@Override
public String toString() {
return "AwareActionFactory{" +
"actions=" + actions +
'}';
}
}

View File

@@ -0,0 +1,41 @@
package com.pangdly.arthas.process.invocation;
import com.pangdly.arthas.codec.ArthasHttpRequestDecodeHandler;
import com.pangdly.constant.Constant;
import com.pangdly.exception.ArthasException;
import com.pangdly.util.Assert;
import com.pangdly.arthas.process.proxy.Proxy;
import com.pangdly.arthas.serialize.ArthasHttpRequestSerializeHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* description: action invoker implements interface
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
@SuppressWarnings("rawtypes")
public class ActionInvoke implements Invoke {
private Proxy proxy;
public ActionInvoke(Proxy proxy) {
Assert.notNull(proxy, "FactoryProxy cannot be null !!!");
this.proxy = proxy;
proxy.setInvoke(this);
}
@Override
public String invoke() throws ArthasException {
try {
Method method = proxy.getMethod();
Object[] target = new ArthasHttpRequestSerializeHandler(method, new ArthasHttpRequestDecodeHandler(method).process()).handle();
return (String) proxy.getMethod().invoke(proxy.getAction(), target);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new ArthasException(Constant.PROC_ERR_CODE, Constant.PROC_ERR_INVOK, ArthasException.APP_ERR);
}
}
}

View File

@@ -0,0 +1,11 @@
package com.pangdly.arthas.process.invocation;
/**
* description: invoke action interface
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
public interface Invoke {
String invoke() throws Exception;
}

View File

@@ -0,0 +1,53 @@
package com.pangdly.arthas.process.proxy;
import java.lang.reflect.Method;
import com.pangdly.arthas.process.factory.ActionWrapper;
import com.pangdly.arthas.process.invocation.ActionInvoke;
import com.pangdly.exception.ArthasException;
import com.pangdly.util.Assert;
/**
* description: factory proxy implement
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
@SuppressWarnings("rawtypes")
public class FactoryProxy<T> implements Proxy {
private ActionWrapper<T> wrapper;
private ActionInvoke invoke;
public FactoryProxy(ActionWrapper<T> wrapper) {
Assert.notNull(wrapper, "ActionWrapper cannot be null !!!");
this.wrapper = wrapper;
}
@Override
public T getAction() {
return wrapper.getAction();
}
@Override
public Method getMethod() {
return wrapper.getMethod();
}
@Override
public void setInvoke(ActionInvoke invoke) {
this.invoke = invoke;
}
@Override
public String execute() {
try {
return invoke.invoke();
} catch (ArthasException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "FactoryProxy.execute error";
}
}

View File

@@ -0,0 +1,23 @@
package com.pangdly.arthas.process.proxy;
import com.pangdly.exception.ArthasException;
import com.pangdly.arthas.process.invocation.ActionInvoke;
import java.lang.reflect.Method;
/**
* description: proxy interface
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
public interface Proxy<T> {
T getAction();
Method getMethod();
void setInvoke(ActionInvoke invoke);
String execute() throws ArthasException;
}

View File

@@ -0,0 +1,164 @@
package com.pangdly.arthas.serialize;
import com.pangdly.arthas.codec.ArthasHttpRequest;
import com.pangdly.annotation.PathParam;
import com.pangdly.constant.Constant;
import com.pangdly.exception.ArthasException;
import com.pangdly.util.Assert;
import com.pangdly.arthas.serialize.convertor.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* description: http request serialize handeler implements ArthasSerialize
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
public class ArthasHttpRequestSerializeHandler implements ArthasSerialize {
private final Method method;
private final ArthasHttpRequest request;
public ArthasHttpRequestSerializeHandler(Method method, ArthasHttpRequest request) {
Assert.notNull(method, "Method cannot be null !!!");
Assert.notNull(request, "ArthasHttpRequest cannot be null !!!");
this.method = method;
this.request = request;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public Object[] handle() throws ArthasException {
// get method parameters count
// intialize Object array
//
List<MethodParam> params = methodParam(method);
Object[] target = new Object[params.size()];
if (params.size() > 0) {
for (int i = 0; i < params.size(); i++) {
// get method parameter object from list
//
MethodParam param = params.get(i);
if (param.getIsPath()) {
// POST
if(null != request.getPost() && !request.getPost().isEmpty()) {
String v = "";
if("data".equals(param.getName())) {
v = request.getPost().keySet().toString();
Convertor<?> conv = new PrimitiveConvertor<>(v, param.getClazz());
target[i] = conv.convert();
} else if("token".equals(param.getName())){
target[i] = request.getToken();
}else {
List<String> vlist = request.getPost().get(param.getName());
for (String string : vlist) {
Convertor<?> conv = new PrimitiveConvertor<>(string, param.getClazz());
target[i] = conv.convert();
}
}
}
// GET
// uri contains parameters
//
if (null != request.getGet() && !request.getGet().isEmpty()) {
String v = request.getGet().get(param.getName());
if (param.getNess() && (null == v || v.length() <= 0)) {
throw new ArthasException(Constant.SERI_ERR_CODE, Constant.SERI_NESS_MSG,
ArthasException.APP_ERR);
}
if (null != v && v.length() > 0) {
Convertor<?> conv = new PrimitiveConvertor<>(v, param.getClazz());
target[i] = conv.convert();
}
}
} else {
// post content contains parameters
// convert array to parameter
//
if (ConvertProcessor.isArray(param.getClazz())) {
List<String> v = request.getPost().get(param.getName());
if (null != v && v.size() > 0) {
Convertor<?> conv = new ArrayConvertor<>(v, param.getClazz());
target[i] = conv.convert();
}
}
// convert model to parmeter
//
else {
Convertor conv = new ModelConvertor(request.getPost(), param.getClazz());
target[i] = conv.convert();
}
}
}
}
return target;
}
private List<MethodParam> methodParam(Method method) {
// initialize params list, if method is null, return blank list directly
//
List<MethodParam> params = new ArrayList<>();
if (null == method) {
return params;
}
Arrays.stream(method.getParameters())
.forEach(p -> {
PathParam xObject = (PathParam) p.getDeclaredAnnotationsByType(PathParam.class)[0];
System.out.println(xObject);
if (null != p.getDeclaredAnnotationsByType(PathParam.class) && p.getDeclaredAnnotationsByType(PathParam.class).length > 0) {
// add uri parameter
params.add(new MethodParam(getAnno(p).name(), getAnno(p).ness(), p.getType()));
} else {
// add post parameter
params.add(new MethodParam(p.getType(), false));
}
});
return params;
}
private PathParam getAnno(Parameter parameter) {
return parameter.getAnnotation(PathParam.class);
}
// inner class
// model for parameter
//
@Data
@AllArgsConstructor
private static class MethodParam {
private String name;
private Boolean ness;
private Class<?> clazz;
private Boolean isPath;
MethodParam(Class<?> clazz, Boolean isPath) {
this.clazz = clazz;
this.isPath = isPath;
}
MethodParam(String name, Boolean ness, Class<?> clazz) {
this.name = name;
this.ness = ness;
this.clazz = clazz;
this.isPath = true;
}
}
}

View File

@@ -0,0 +1,13 @@
package com.pangdly.arthas.serialize;
import com.pangdly.exception.ArthasException;
/**
* description: arthas serialize interface
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
public interface ArthasSerialize {
Object[] handle() throws ArthasException;
}

View File

@@ -0,0 +1,56 @@
package com.pangdly.arthas.serialize.convertor;
import java.lang.reflect.Array;
import java.util.List;
import com.pangdly.constant.Constant;
import com.pangdly.exception.ArthasException;
import com.pangdly.util.Assert;
/**
* description: array convertor, implements interface Convertor
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
@SuppressWarnings("rawtypes")
public class ArrayConvertor<T> implements Convertor {
private List<String> v;
private Class<T> c;
private T target;
public ArrayConvertor(List<String> v, Class<T> c) throws ArthasException {
Assert.notNull(v, "the value can not be null !!!");
Assert.notNull(c, "the target type can not be null !!!");
this.v = v;
this.c = c;
conv();
}
@SuppressWarnings("unchecked")
private void conv() throws ArthasException {
if (!ConvertProcessor.isArray(c)) {
throw new ArthasException(Constant.CONV_ERR_CODE, Constant.CONV_NOT_ARRAY, ArthasException.APP_ERR);
}
Class<?> type = c.getComponentType();
int length = v.size();
Object o = Array.newInstance(type, length);
for (int i = 0; i < length; i++) {
if (type.equals(String.class)) {
Array.set(o, i, v.get(i));
} else {
Convertor<?> con = new PrimitiveConvertor<>(v.get(i), type);
Array.set(o, i, con.convert());
}
}
target = (T) o;
}
@Override
public T convert() throws ArthasException {
return target;
}
}

View File

@@ -0,0 +1,178 @@
package com.pangdly.arthas.serialize.convertor;
import com.pangdly.constant.Constant;
import com.pangdly.exception.ArthasException;
import com.pangdly.util.Assert;
import lombok.extern.log4j.Log4j2;
import java.math.BigDecimal;
/**
* description: convertor executor
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
@Log4j2
@SuppressWarnings("rawtypes")
public class ConvertProcessor<T> implements Convertor {
private Class<T> clazz;
private Object value;
private T t;
public ConvertProcessor(Class<T> clazz, Object value) throws ArthasException {
Assert.notNull(clazz, "Class<T> clazz can not be null !!!");
Assert.notNull(value, "Map<String,String> map can not be null !!!");
this.clazz = clazz;
this.value = value;
conv();
}
private void conv() throws ArthasException {
long start = System.currentTimeMillis();
switch (classType()) {
case ConvertorType.PRIMITIVE:
convToPrimitive();
break;
case ConvertorType.ARRAY:
t = null;
break;
case ConvertorType.LOCAL:
// TODO
break;
case ConvertorType.ILLEGAL:
throw new ArthasException("123", "123", ArthasException.APP_ERR);
}
log.debug("conv cost {}", System.currentTimeMillis() - start);
}
private int classType() {
return type(clazz);
}
private void convToPrimitive() throws ArthasException {
if (isInt()) {
convToInt();
} else if (isLong()) {
convToLong();
} else if (isDouble()) {
convToDouble();
} else if (isBoolean()) {
convToBoolean();
} else if (isDecimal()) {
convToDecimal();
} else if (isString()) {
value();
} else {
throw new ArthasException(Constant.CONV_ERR_CODE, Constant.CONV_NOT_PRIMITIVE, ArthasException.APP_ERR);
}
}
private int type(Class<?> clazz) {
try {
if (isPrimitive(clazz)) {
return ConvertorType.PRIMITIVE;
} else if (isArray(clazz)) {
return ConvertorType.ARRAY;
} else if (isIllegal(clazz)) {
return ConvertorType.ILLEGAL;
} else {
return ConvertorType.LOCAL;
}
} catch (Exception e) {
log.error("verify type occur excption !!! excption: {}", e);
return ConvertorType.ILLEGAL;
}
}
static boolean isPrimitive(Class<?> clazz) {
for (Class<?> c : ConvertorType.PRIMITIVE_TYPE) {
if (c.equals(clazz)) {
return true;
}
}
return false;
}
public static boolean isArray(Class<?> clazz) {
if (clazz.isArray()) {
for (Class<?> c : ConvertorType.ARRAY_TYPE) {
if (c.equals(clazz)) {
return true;
}
}
}
return false;
}
private static boolean isIllegal(Class<?> clazz) {
return clazz.isInterface() || clazz.isEnum() || clazz.isAnnotation();
}
private boolean isInt() {
return clazz.equals(int.class) || clazz.equals(Integer.class);
}
private boolean isLong() {
return clazz.equals(long.class) || clazz.equals(Long.class);
}
private boolean isDouble() {
return clazz.equals(double.class) || clazz.equals(Double.class);
}
private boolean isBoolean() {
return clazz.equals(boolean.class) || clazz.equals(Boolean.class);
}
private boolean isDecimal() {
return clazz.equals(BigDecimal.class);
}
private boolean isString() {
return clazz.equals(String.class);
}
private int convToInt() throws ArthasException {
checkString();
return Integer.valueOf(value());
}
private long convToLong() throws ArthasException {
checkString();
return Long.valueOf(value());
}
private double convToDouble() throws ArthasException {
checkString();
return Double.valueOf(value());
}
private boolean convToBoolean() throws ArthasException {
checkString();
return Boolean.valueOf(value());
}
private BigDecimal convToDecimal() throws ArthasException {
checkString();
return new BigDecimal(value());
}
private String value() {
return (String) value;
}
private void checkString() throws ArthasException {
if (!value.getClass().equals(String.class)) {
throw new ArthasException(Constant.CONV_ERR_CODE, Constant.CONV_NOT_STRING, ArthasException.APP_ERR);
}
}
@Override
public T convert() throws ArthasException {
return this.t;
}
}

View File

@@ -0,0 +1,13 @@
package com.pangdly.arthas.serialize.convertor;
import com.pangdly.exception.ArthasException;
/**
* description: convertor interface
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
public interface Convertor<T> {
T convert() throws ArthasException;
}

View File

@@ -0,0 +1,83 @@
package com.pangdly.arthas.serialize.convertor;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;
/**
* description: parameter type object, type handle
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
public class ConvertorType {
private ConvertorType() {
}
static final int PRIMITIVE = 1;
static final int ARRAY = 2;
static final int LOCAL = 3;
static final int ILLEGAL = 4;
static final Class<?>[] PRIMITIVE_TYPE = {
String.class,
boolean.class,
byte.class,
short.class,
int.class,
long.class,
float.class,
double.class,
char.class,
Boolean.class,
Byte.class,
Short.class,
Integer.class,
Long.class,
Float.class,
Double.class,
Character.class,
BigInteger.class,
BigDecimal.class
};
static final Class<?>[] ARRAY_TYPE = {
String[].class,
boolean[].class,
byte[].class,
short[].class,
int[].class,
long[].class,
float[].class,
double[].class,
char[].class,
Boolean[].class,
Byte[].class,
Short[].class,
Integer[].class,
Long[].class,
Float[].class,
Double[].class,
Character[].class,
BigInteger[].class,
BigDecimal[].class
};
@SuppressWarnings("unused")
private static final Map<Class<?>, Object> PRIMITIVE_DEFAULTS = new HashMap<Class<?>, Object>() {
private static final long serialVersionUID = 5753182096254727686L;
{
put(boolean.class, false);
put(byte.class, (byte) 0);
put(short.class, (short) 0);
put(char.class, (char) 0);
put(int.class, 0);
put(long.class, 0L);
put(float.class, 0.0f);
put(double.class, 0.0);
}
};
}

View File

@@ -0,0 +1,82 @@
package com.pangdly.arthas.serialize.convertor;
import com.pangdly.constant.Constant;
import com.pangdly.exception.ArthasException;
import com.pangdly.util.Assert;
import lombok.extern.log4j.Log4j2;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
/**
* description: model convertor
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
@Log4j2
@SuppressWarnings("rawtypes")
public class ModelConvertor<T> implements Convertor {
private Map<String, List<String>> v;
private Class<T> c;
private T target;
public ModelConvertor(Map<String, List<String>> v, Class<T> c) throws ArthasException {
Assert.notNull(v, "the convert source value can not be null !!!");
Assert.notNull(c, "the convert target class type can not be null !!!");
this.v = v;
this.c = c;
conv();
}
private void conv() throws ArthasException {
try {
target = c.newInstance();
} catch (Exception e) {
throw new ArthasException(Constant.CONV_ERR_CODE, Constant.CONV_ERR_MODLE, ArthasException.SYS_ERR, e);
}
Field[] fields = target.getClass().getDeclaredFields();
for (Field f : fields) {
String key = f.getName();
f.setAccessible(true);
if (ConvertProcessor.isArray(f.getType())) {
List<String> value = v.get(key);
if (null == value || value.size() <= 0) {
continue;
}
Convertor<?> con = new ArrayConvertor<>(value, f.getType());
try {
f.set(target, con.convert());
} catch (IllegalAccessException e) {
throw new ArthasException(Constant.CONV_ERR_CODE, Constant.CONV_ERR_MODLE, ArthasException.SYS_ERR, e);
}
} else if (ConvertProcessor.isPrimitive(f.getType())) {
if (null == v.get(key) || v.get(key).size() <= 0) {
continue;
}
String value = v.get(key).get(0);
if (null == value) {
continue;
}
@SuppressWarnings("unchecked")
Convertor<?> con = new PrimitiveConvertor(value, f.getType());
try {
f.set(target, con.convert());
} catch (IllegalAccessException e) {
throw new ArthasException(Constant.CONV_ERR_CODE, Constant.CONV_ERR_MODLE, ArthasException.SYS_ERR, e);
}
} else {
log.info("type is {}, the model serialize only support primitive and array type !!!", f.getType());
}
}
}
@Override
public T convert() throws ArthasException {
return target;
}
}

View File

@@ -0,0 +1,102 @@
package com.pangdly.arthas.serialize.convertor;
import java.math.BigDecimal;
import com.pangdly.constant.Constant;
import com.pangdly.exception.ArthasException;
import com.pangdly.util.Assert;
/**
* description: primitive convertor
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
@SuppressWarnings("rawtypes")
public class PrimitiveConvertor<T> implements Convertor {
private final String v;
private final Class<T> c;
private T t;
public PrimitiveConvertor(String v, Class<T> c) throws ArthasException {
Assert.notNull(v, "the value can not be null !!!");
Assert.notNull(c, "the target type can not be null !!!");
this.v = v;
this.c = c;
conv();
}
@SuppressWarnings("unchecked")
private void conv() throws ArthasException {
if (isInt()) {
t = (T) convToInt();
} else if (isLong()) {
t = (T) convToLong();
} else if (isDouble()) {
t = (T) convToDouble();
} else if (isBoolean()) {
t = (T) convToBoolean();
} else if (isDecimal()) {
t = (T) convToDecimal();
} else if (isString()) {
t = (T) v;
} else {
throw new ArthasException(Constant.CONV_ERR_CODE, Constant.CONV_NOT_PRIMITIVE, ArthasException.APP_ERR);
}
}
private boolean isInt() throws ArthasException {
return c.equals(int.class) || c.equals(Integer.class);
}
private boolean isLong() throws ArthasException {
return c.equals(long.class) || c.equals(Long.class);
}
private boolean isDouble() throws ArthasException {
return c.equals(double.class) || c.equals(Double.class);
}
private boolean isBoolean() throws ArthasException {
return c.equals(boolean.class) || c.equals(Boolean.class);
}
private boolean isDecimal() throws ArthasException {
return c.equals(BigDecimal.class);
}
private boolean isString() throws ArthasException {
return c.equals(String.class);
}
private Object convToInt() throws ArthasException {
return Integer.valueOf(v);
}
private Object convToLong() throws ArthasException {
return Long.valueOf(v);
}
private Object convToDouble() throws ArthasException {
return Double.valueOf(v);
}
private Object convToBoolean() throws ArthasException {
return Boolean.valueOf(v);
}
private Object convToDecimal() throws ArthasException {
return new BigDecimal(v);
}
@Override
public T convert() throws ArthasException {
return t;
}
}

View File

@@ -0,0 +1,51 @@
package com.pangdly.constant;
/**
* description: //TODO
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
public class Constant {
public final static String ARTHAS_SERVER = "server";
public final static String SERVER_THREAD_COUNT = "count";
public final static String SERVER_PROT = "port";
public final static int DEFAULT_THREAD_COUNT = 1;
public final static int DEFAULT_PORT = 10880;
public final static String ACTION_ELEMENT = "action";
public final static String BASE_PACKAGE_ATTRIBUTE = "base-package";
public final static String CONTENT_TYPE = "Content-Type";
public final static String CONTENT_LENGTH = "Content-Length";
public final static String CONNECTION = "Connection";
public final static String KEEP_ALIVE = "keep-alive";
public final static String CONNECTION_CLOSE = "close";
public final static String ERR_CODE = "9999";
public final static String ERR_MSG = "server is busytry it later please !!!";
public final static String CODC_ERR_CODE = "9001";
public final static String CODC_REQ_TYPE = "request type is illegal !!!";
public final static String DISP_ERR_CODE = "9002";
public final static String DISP_PROX_MSG = "process get proxy failed !!!";
public final static String DISP_WRAP_MSG = "process get wrapper failed !!!";
public final static String PROC_ERR_CODE = "9003";
public final static String PROC_NO_WRAP = "action is not exist !!!";
public final static String PROC_ERR_INVOK = "invoke action failed !!!";
public final static String SERI_ERR_CODE = "9004";
public final static String SERI_NESS_MSG = "parameter in uri is necessarycannot be null !!!";
public final static String CONV_ERR_CODE = "9005";
public final static String CONV_NOT_ARRAY = "the parameter is not type of Array !!!";
public final static String CONV_NOT_PRIMITIVE = "the parameter is not type of primitive !!!";
public final static String CONV_NOT_STRING = "the parameter is not type of String !!!";
public final static String CONV_NOT_DATE = "date format is illegal !!!";
public final static String CONV_ERR_MODLE = "convert to model failed !!!";
}

View File

@@ -0,0 +1,69 @@
package com.pangdly.exception;
import lombok.extern.log4j.Log4j2;
/**
* description: //TODO
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
@SuppressWarnings({"serial", "unused"})
@Log4j2
public class ArthasException extends Exception {
public final static int SYS_ERR = 0;
public final static int APP_ERR = 1;
private String code;
private String message;
private int level = APP_ERR;
private Throwable cause;
private ArthasException() {
super();
}
public ArthasException(String code, String message, int level) {
super(message);
this.code = code;
this.message = message;
this.level = level;
}
public ArthasException(String code, String message, int level, Throwable cause) {
super(message);
this.code = code;
this.message = message;
this.level = level;
this.cause = cause;
}
public void setCode(String code) {
this.code = code;
}
public void setMessage(String message) {
this.message = message;
}
public void setLevel(int level) {
this.level = level;
}
public void setCause(Throwable cause) {
this.cause = cause;
}
@Override
public String toString() {
return "ArthasException{" +
"code='" + code + '\'' +
", message='" + message + '\'' +
", level=" + (SYS_ERR == level ? "SYS" : "APP") +
((SYS_ERR == level) ? (", cause=" + cause) : "") +
'}';
}
}

View File

@@ -0,0 +1,88 @@
package com.pangdly.server;
import com.pangdly.util.ArthasUtil;
import com.pangdly.util.SpringUtil;
import com.pangdly.arthas.dispatcher.ArthasChannelInitializer;
import com.pangdly.arthas.dispatcher.ArthasProcessHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import lombok.extern.log4j.Log4j2;
import org.springframework.context.ApplicationContext;
import java.net.InetAddress;
import javax.rmi.CORBA.Util;
/**
* description: server initialize method
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
@Log4j2
public class HttpServer {
private static final boolean SSL = System.getProperty("ssl") != null;
private final String name;
private final ApplicationContext context;
public HttpServer(String name, ApplicationContext context) {
this.name = name;
this.context = context;
}
public void run() throws Exception {
if (null != context) {
SpringUtil util = new SpringUtil();
util.setContext(context);
}
final SslContext ssl;
final int[] server = ArthasUtil.parseServerParameter(name);
final int count = server[0];
final int port = server[1];
if (SSL) {
SelfSignedCertificate ssc = new SelfSignedCertificate();
ssl = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build();
} else {
ssl = null;
}
// initialize arthas context
//
new ArthasProcessHandler().init(name);
// initialize arthas netty service
//
EventLoopGroup bossGroup = new NioEventLoopGroup(count);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.option(ChannelOption.SO_BACKLOG, 1024)
.childOption(ChannelOption.SO_KEEPALIVE, true)
.childOption(ChannelOption.TCP_NODELAY, true);
bootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ArthasChannelInitializer(ssl));
Channel ch = bootstrap.bind(port).sync().channel();
log.info("HTTP Server: {}://{}:{}\n\n", SSL ? "https" : "http", InetAddress.getLocalHost().getHostAddress(), port);
ch.closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}

View File

@@ -0,0 +1,221 @@
package com.pangdly.util;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLDecoder;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import com.pangdly.annotation.Action;
import com.pangdly.constant.Constant;
import com.pangdly.exception.ArthasException;
import lombok.extern.log4j.Log4j2;
@SuppressWarnings({"resource", "rawtypes", "unchecked"})
@Log4j2
public class ArthasUtil {
public static Date strToDate(String source, String format) {
DateFormat df = new SimpleDateFormat(format);
try {
return df.parse(source);
} catch (ParseException e) {
log.error("convert string to date is failed, exception is [ {} ]", e.getMessage());
return null;
}
}
public static void findFilesInPackage(String packageName, List<String> classes) {
String packageDirName = packageDir(packageName);
if (null == packageDirName) {
// TODO
return;
}
if (packageDirName.contains("jar!")) {
String[] names = packageDirName.trim().substring(5).split("!");
try {
JarFile jar = new JarFile(names[0].trim());
Enumeration<JarEntry> entries = jar.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
String fileName = entry.getName().replace("/", ".").trim();
if (fileName.contains(packageName) && fileName.contains(".class")) {
try {
Class c = Class.forName(fileName.substring(0, fileName.length() - 6));
if (null != c.getAnnotation(Action.class)) {
classes.add(fileName.substring(0, fileName.length() - 6));
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
} else {
File dir = new File(packageDirName);
if (!dir.exists() || !dir.isDirectory()) {
return;
}
File[] files = dir.listFiles((File file) -> {
if (file.isDirectory())
return true;
if (file.isFile()) {
String fileName = file.getName();
if (fileName.endsWith(".class")) {
try {
Class c = Class.forName(packageName + "." + fileName.substring(0, fileName.length() - 6));
if (null != c.getAnnotation(Action.class)) {
return true;
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
return false;
});
if (null == files) {
return;
}
for (File file : files) {
if (file.isDirectory()) {
findFilesInPackage(packageName + "." + file.getName(), classes);
}
if (file.isFile()) {
classes.add(packageName + "." + file.getName().substring(0, file.getName().length() - 6));
}
}
}
}
private static String packageDir(String packageName) {
if (null == packageName) {
// TODO
return null;
}
URL url = Thread.currentThread().getContextClassLoader().getResource(packageName.replace(".", "/"));
log.debug("the url is {}", url);
if (url == null || url.getFile() == null) {
// TODO
return null;
}
try {
String path;
if (System.getProperty("os.name").toLowerCase().contains("window")) {
path = url.getPath().substring(1, url.getPath().length());
} else {
path = url.getPath();
}
return URLDecoder.decode(path, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static InputStream parse(String name) {
InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream(name);
return stream;
}
public static int[] parseServerParameter(String name) {
try {
Document document = new SAXReader().read(parse(name));
Element element = document.getRootElement().element(Constant.ARTHAS_SERVER);
String count = element.attributeValue(Constant.SERVER_THREAD_COUNT);
String port = element.attributeValue(Constant.SERVER_PROT);
return new int[]{null == count ? Constant.DEFAULT_THREAD_COUNT : Integer.valueOf(count), null == port ? Constant.DEFAULT_PORT : Integer.valueOf(port)};
} catch (Exception e) {
return new int[]{Constant.DEFAULT_THREAD_COUNT, Constant.DEFAULT_PORT,};
}
}
public static List<String> parsePackage(String name) {
List<String> namespaces = new ArrayList<>();
Document document;
try {
document = new SAXReader().read(parse(name));
if (null == document) {
return namespaces;
}
Element root = document.getRootElement();
Iterator<Element> it = root.elementIterator();
while (it.hasNext()) {
Element element = it.next();
if (element.getName().equals(Constant.ACTION_ELEMENT)) {
namespaces.add(element.attributeValue(Constant.BASE_PACKAGE_ATTRIBUTE));
}
}
return namespaces;
} catch (DocumentException e) {
e.printStackTrace();
// TODO: to add error handle
return namespaces;
}
}
public static Map<String, String> paramsInUri(String uri) throws ArthasException {
if (null == uri || uri.length() <= 0) {
return null;
}
String params = uriSplit(uri);
if (null == params) {
return null;
}
return paramSplit(params);
}
private static String uriSplit(String uri) throws ArthasException {
String[] arr = uri.split("\\?");
if (arr.length != 2) {
// TODO: discribe exception
throw new ArthasException("123", "123", ArthasException.APP_ERR);
}
return arr[1];
}
private static Map<String, String> paramSplit(String params) {
Map<String, String> map = new HashMap<String, String>();
String[] arr = params.split("&");
Arrays.stream(arr).forEach((String param) -> {
String[] pa = param.split("=");
if (pa.length == 2) {
map.put(pa[0], pa[1]);
}
});
return map;
}
}

View File

@@ -0,0 +1,17 @@
package com.pangdly.util;
/**
* description: //TODO
*
* @author: Xue Bin
* @version: 1.0.0-SNAPSHOT
*/
public abstract class Assert {
public static void notNull(Object object, String message) {
if (null == object) {
throw new IllegalArgumentException(message);
}
}
}

View File

@@ -0,0 +1,28 @@
package com.pangdly.util;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class SpringUtil implements ApplicationContextAware {
private static ApplicationContext context;
public static ApplicationContext getContext() {
return context;
}
//@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
public static <T> T getBean(Class<T> clazz) {
return context.getBean(clazz);
}
public void setContext(ApplicationContext applicationContext) {
context = applicationContext;
}
}

View File

@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
日志说明:
1请根据实际情况配置各项参数
2需要注意日志文件备份数和日志文件大小注意预留目录空间
3实际部署的时候backupFilePatch变量需要修改成linux目录
-->
<configuration status="OFF">
<Properties>
<Property name="fileName">http.netty.log</Property>
<Property name="backupFilePatch">/mnt/default_logs</Property>
</Properties>
<!--先定义所有的appender-->
<appenders>
<!--这个输出控制台的配置-->
<Console name="Console" target="SYSTEM_OUT">
<!--控制台只输出level及以上级别的信息onMatch其他的直接拒绝onMismatch-->
<ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY"/>
<!--这个都知道是输出日志的格式-->
<PatternLayout pattern="%date{yyyy-MM-dd HH:mm:ss.SSS} [%level] [%thread] [%file:%line] - %msg%n"/>
</Console>
<!--这个会打印出所有的信息每次大小超过size则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
<RollingFile name="notifyLog" fileName="${backupFilePatch}${fileName}"
filePattern="${backupFilePatch}$${date:yyyy-MM}/app-%d{yyyyMMddHHmmssSSS}.log.gz">
<PatternLayout
pattern="%date{yyyy-MM-dd HH:mm:ss.SSS} [%level] [%thread] [%file:%line] - %msg%n"/>
<!-- 日志文件大小 -->
<SizeBasedTriggeringPolicy size="20MB"/>
<!-- 最多保留文件数 -->
<DefaultRolloverStrategy max="20"/>
</RollingFile>
</appenders>
<!--然后定义logger只有定义了logger并引入的appenderappender才会生效-->
<loggers>
<logger name="org.springframework.core" level="info">
</logger>
<logger name="org.springframework.beans" level="info">
</logger>
<logger name="org.springframework.context" level="info">
</logger>
<!--建立一个默认的root的logger-->
<Logger name="com.stormragetech" level="debug" additivity="true">
<AppenderRef ref="StormragetechLog"/>
</Logger>
<Root level="info">
<AppenderRef ref="Console"/>
</Root>
</loggers>
</configuration>

View File

@@ -0,0 +1,38 @@
package com.pangdly.Http.Netty;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Unit test for simple App.
*/
public class AppTest
extends TestCase
{
/**
* Create the test case
*
* @param testName name of the test case
*/
public AppTest( String testName )
{
super( testName );
}
/**
* @return the suite of tests being tested
*/
public static Test suite()
{
return new TestSuite( AppTest.class );
}
/**
* Rigourous Test :-)
*/
public void testApp()
{
assertTrue( true );
}
}

Binary file not shown.

View File

@@ -0,0 +1,5 @@
Manifest-Version: 1.0
Built-By: Administrator
Build-Jdk: 1.8.0_112
Created-By: Maven Integration for Eclipse

View File

@@ -0,0 +1,7 @@
#Generated by Maven Integration for Eclipse
#Tue Dec 26 20:54:25 CST 2017
version=0.0.1-SNAPSHOT
groupId=com.pangdly
m2e.projectName=Http.Netty
m2e.projectLocation=F\:\\workspace-for big data\\Http.Netty
artifactId=Http.Netty

View File

@@ -0,0 +1,132 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.pangdly</groupId>
<artifactId>Http.Netty</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Http.Netty</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- for maven compiler plugin -->
<maven.compiler.plugin.version>3.7.0</maven.compiler.plugin.version>
<maven.surefire.plugin.version>2.20.1</maven.surefire.plugin.version>
<maven.jar.plugin.version>3.0.2</maven.jar.plugin.version>
<maven.dependency.plugin.version>3.0.0</maven.dependency.plugin.version>
<maven.deploy.plugin.version>2.8.2</maven.deploy.plugin.version>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- stormragetech libs -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.16</version>
</dependency>
<!-- common libs -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>
<!-- httpserver libs -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.6</version>
</dependency>
<!-- netty libs -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.15.Final</version>
</dependency>
<!-- spring libs -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<!-- protocol libs -->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.38</version>
</dependency>
<!-- log4j2 libs -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-web</artifactId>
<version>2.7</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.compiler.plugin.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${file.encoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven.surefire.plugin.version}</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>${maven.deploy.plugin.version}</version>
</plugin>
</plugins>
</build>
<distributionManagement>
<repository>
<id>nexus-releases</id>
<name>Nexus Releases Repository</name>
<url>http://192.168.0.99:8081/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>nexus-snapshots</id>
<name>Nexus Snapshots Repository</name>
<url>http://192.168.0.99:8081/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
</project>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

53
target/classes/log4j2.xml Normal file
View File

@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
日志说明:
1请根据实际情况配置各项参数
2需要注意日志文件备份数和日志文件大小注意预留目录空间
3实际部署的时候backupFilePatch变量需要修改成linux目录
-->
<configuration status="OFF">
<Properties>
<Property name="fileName">http.netty.log</Property>
<Property name="backupFilePatch">/mnt/default_logs</Property>
</Properties>
<!--先定义所有的appender-->
<appenders>
<!--这个输出控制台的配置-->
<Console name="Console" target="SYSTEM_OUT">
<!--控制台只输出level及以上级别的信息onMatch其他的直接拒绝onMismatch-->
<ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY"/>
<!--这个都知道是输出日志的格式-->
<PatternLayout pattern="%date{yyyy-MM-dd HH:mm:ss.SSS} [%level] [%thread] [%file:%line] - %msg%n"/>
</Console>
<!--这个会打印出所有的信息每次大小超过size则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
<RollingFile name="notifyLog" fileName="${backupFilePatch}${fileName}"
filePattern="${backupFilePatch}$${date:yyyy-MM}/app-%d{yyyyMMddHHmmssSSS}.log.gz">
<PatternLayout
pattern="%date{yyyy-MM-dd HH:mm:ss.SSS} [%level] [%thread] [%file:%line] - %msg%n"/>
<!-- 日志文件大小 -->
<SizeBasedTriggeringPolicy size="20MB"/>
<!-- 最多保留文件数 -->
<DefaultRolloverStrategy max="20"/>
</RollingFile>
</appenders>
<!--然后定义logger只有定义了logger并引入的appenderappender才会生效-->
<loggers>
<logger name="org.springframework.core" level="info">
</logger>
<logger name="org.springframework.beans" level="info">
</logger>
<logger name="org.springframework.context" level="info">
</logger>
<!--建立一个默认的root的logger-->
<Logger name="com.stormragetech" level="debug" additivity="true">
<AppenderRef ref="StormragetechLog"/>
</Logger>
<Root level="info">
<AppenderRef ref="Console"/>
</Root>
</loggers>
</configuration>

View File

@@ -0,0 +1,5 @@
#Generated by Maven
#Mon Dec 11 13:09:25 CST 2017
version=0.0.1-SNAPSHOT
groupId=com.pangdly
artifactId=Http.Netty

View File

@@ -0,0 +1,40 @@
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\annotation\ContentType.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\arthas\codec\ArthasHttpResponseEncode.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\arthas\codec\ArthasHttpRequestDecodeHandler.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\arthas\process\context\Context.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\arthas\process\factory\AwareActionFactory.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\arthas\serialize\convertor\ModelConvertor.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\arthas\process\context\ActionContext.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\arthas\process\factory\ActionFactory.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\arthas\codec\ArthasHttpRequestDecode.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\arthas\process\invocation\ActionInvoke.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\arthas\process\invocation\Invoke.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\util\Assert.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\arthas\codec\ArthasHttpResponseEncodeHandler.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\arthas\dispatcher\ArthasHttpHandler.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\arthas\process\context\XmlConfigFileActionContext.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\annotation\Action.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\arthas\dispatcher\ArthasProcess.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\arthas\serialize\convertor\ConvertProcessor.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\exception\ArthasException.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\annotation\PathParam.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\arthas\dispatcher\DataCache.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\arthas\serialize\ArthasSerialize.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\arthas\serialize\convertor\ArrayConvertor.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\arthas\serialize\ArthasHttpRequestSerializeHandler.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\arthas\process\factory\ActionWrapper.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\arthas\process\proxy\FactoryProxy.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\annotation\Mapping.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\server\HttpServer.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\annotation\RequestType.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\util\ArthasUtil.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\util\SpringUtil.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\annotation\ResponseType.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\arthas\serialize\convertor\PrimitiveConvertor.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\arthas\serialize\convertor\Convertor.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\constant\Constant.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\arthas\dispatcher\ArthasProcessHandler.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\arthas\serialize\convertor\ConvertorType.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\arthas\dispatcher\ArthasChannelInitializer.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\arthas\codec\ArthasHttpRequest.java
F:\workspace-for big data\Http.Netty\src\main\java\com\pangdly\arthas\process\proxy\Proxy.java

View File

@@ -0,0 +1 @@
F:\workspace-for big data\Http.Netty\src\test\java\com\pangdly\Http\Netty\AppTest.java