Create Project
This commit is contained in:
132
pom.xml
Normal file
132
pom.xml
Normal 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>
|
||||
16
src/main/java/com/pangdly/annotation/Action.java
Normal file
16
src/main/java/com/pangdly/annotation/Action.java
Normal 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";
|
||||
}
|
||||
27
src/main/java/com/pangdly/annotation/ContentType.java
Normal file
27
src/main/java/com/pangdly/annotation/ContentType.java
Normal 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;
|
||||
}
|
||||
}
|
||||
24
src/main/java/com/pangdly/annotation/Mapping.java
Normal file
24
src/main/java/com/pangdly/annotation/Mapping.java
Normal 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";
|
||||
|
||||
}
|
||||
20
src/main/java/com/pangdly/annotation/PathParam.java
Normal file
20
src/main/java/com/pangdly/annotation/PathParam.java
Normal 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;
|
||||
|
||||
}
|
||||
27
src/main/java/com/pangdly/annotation/RequestType.java
Normal file
27
src/main/java/com/pangdly/annotation/RequestType.java
Normal 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;
|
||||
}
|
||||
}
|
||||
27
src/main/java/com/pangdly/annotation/ResponseType.java
Normal file
27
src/main/java/com/pangdly/annotation/ResponseType.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
22
src/main/java/com/pangdly/arthas/dispatcher/DataCache.java
Normal file
22
src/main/java/com/pangdly/arthas/dispatcher/DataCache.java
Normal 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();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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 +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
23
src/main/java/com/pangdly/arthas/process/proxy/Proxy.java
Normal file
23
src/main/java/com/pangdly/arthas/process/proxy/Proxy.java
Normal 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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
51
src/main/java/com/pangdly/constant/Constant.java
Normal file
51
src/main/java/com/pangdly/constant/Constant.java
Normal 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 busy,try 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 necessary,cannot 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 !!!";
|
||||
|
||||
}
|
||||
69
src/main/java/com/pangdly/exception/ArthasException.java
Normal file
69
src/main/java/com/pangdly/exception/ArthasException.java
Normal 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) : "") +
|
||||
'}';
|
||||
}
|
||||
|
||||
}
|
||||
88
src/main/java/com/pangdly/server/HttpServer.java
Normal file
88
src/main/java/com/pangdly/server/HttpServer.java
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
221
src/main/java/com/pangdly/util/ArthasUtil.java
Normal file
221
src/main/java/com/pangdly/util/ArthasUtil.java
Normal 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;
|
||||
}
|
||||
}
|
||||
17
src/main/java/com/pangdly/util/Assert.java
Normal file
17
src/main/java/com/pangdly/util/Assert.java
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
28
src/main/java/com/pangdly/util/SpringUtil.java
Normal file
28
src/main/java/com/pangdly/util/SpringUtil.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
53
src/main/resources/log4j2.xml
Normal file
53
src/main/resources/log4j2.xml
Normal 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并引入的appender,appender才会生效-->
|
||||
<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>
|
||||
38
src/test/java/com/pangdly/Http/Netty/AppTest.java
Normal file
38
src/test/java/com/pangdly/Http/Netty/AppTest.java
Normal 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 );
|
||||
}
|
||||
}
|
||||
BIN
target/Http.Netty-0.0.1-SNAPSHOT.jar
Normal file
BIN
target/Http.Netty-0.0.1-SNAPSHOT.jar
Normal file
Binary file not shown.
5
target/classes/META-INF/MANIFEST.MF
Normal file
5
target/classes/META-INF/MANIFEST.MF
Normal file
@@ -0,0 +1,5 @@
|
||||
Manifest-Version: 1.0
|
||||
Built-By: Administrator
|
||||
Build-Jdk: 1.8.0_112
|
||||
Created-By: Maven Integration for Eclipse
|
||||
|
||||
@@ -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
|
||||
132
target/classes/META-INF/maven/com.pangdly/Http.Netty/pom.xml
Normal file
132
target/classes/META-INF/maven/com.pangdly/Http.Netty/pom.xml
Normal 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>
|
||||
BIN
target/classes/com/pangdly/annotation/Action.class
Normal file
BIN
target/classes/com/pangdly/annotation/Action.class
Normal file
Binary file not shown.
BIN
target/classes/com/pangdly/annotation/ContentType.class
Normal file
BIN
target/classes/com/pangdly/annotation/ContentType.class
Normal file
Binary file not shown.
BIN
target/classes/com/pangdly/annotation/Mapping.class
Normal file
BIN
target/classes/com/pangdly/annotation/Mapping.class
Normal file
Binary file not shown.
BIN
target/classes/com/pangdly/annotation/PathParam.class
Normal file
BIN
target/classes/com/pangdly/annotation/PathParam.class
Normal file
Binary file not shown.
BIN
target/classes/com/pangdly/annotation/RequestType.class
Normal file
BIN
target/classes/com/pangdly/annotation/RequestType.class
Normal file
Binary file not shown.
BIN
target/classes/com/pangdly/annotation/ResponseType.class
Normal file
BIN
target/classes/com/pangdly/annotation/ResponseType.class
Normal file
Binary file not shown.
BIN
target/classes/com/pangdly/arthas/codec/ArthasHttpRequest.class
Normal file
BIN
target/classes/com/pangdly/arthas/codec/ArthasHttpRequest.class
Normal file
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.
BIN
target/classes/com/pangdly/arthas/dispatcher/ArthasProcess.class
Normal file
BIN
target/classes/com/pangdly/arthas/dispatcher/ArthasProcess.class
Normal file
Binary file not shown.
Binary file not shown.
BIN
target/classes/com/pangdly/arthas/dispatcher/DataCache.class
Normal file
BIN
target/classes/com/pangdly/arthas/dispatcher/DataCache.class
Normal file
Binary file not shown.
Binary file not shown.
BIN
target/classes/com/pangdly/arthas/process/context/Context.class
Normal file
BIN
target/classes/com/pangdly/arthas/process/context/Context.class
Normal file
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.
BIN
target/classes/com/pangdly/arthas/process/proxy/Proxy.class
Normal file
BIN
target/classes/com/pangdly/arthas/process/proxy/Proxy.class
Normal file
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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
target/classes/com/pangdly/constant/Constant.class
Normal file
BIN
target/classes/com/pangdly/constant/Constant.class
Normal file
Binary file not shown.
BIN
target/classes/com/pangdly/exception/ArthasException.class
Normal file
BIN
target/classes/com/pangdly/exception/ArthasException.class
Normal file
Binary file not shown.
BIN
target/classes/com/pangdly/server/HttpServer.class
Normal file
BIN
target/classes/com/pangdly/server/HttpServer.class
Normal file
Binary file not shown.
BIN
target/classes/com/pangdly/util/ArthasUtil.class
Normal file
BIN
target/classes/com/pangdly/util/ArthasUtil.class
Normal file
Binary file not shown.
BIN
target/classes/com/pangdly/util/Assert.class
Normal file
BIN
target/classes/com/pangdly/util/Assert.class
Normal file
Binary file not shown.
BIN
target/classes/com/pangdly/util/SpringUtil.class
Normal file
BIN
target/classes/com/pangdly/util/SpringUtil.class
Normal file
Binary file not shown.
53
target/classes/log4j2.xml
Normal file
53
target/classes/log4j2.xml
Normal 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并引入的appender,appender才会生效-->
|
||||
<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>
|
||||
5
target/maven-archiver/pom.properties
Normal file
5
target/maven-archiver/pom.properties
Normal 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
|
||||
@@ -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
|
||||
@@ -0,0 +1 @@
|
||||
F:\workspace-for big data\Http.Netty\src\test\java\com\pangdly\Http\Netty\AppTest.java
|
||||
BIN
target/test-classes/com/pangdly/Http/Netty/AppTest.class
Normal file
BIN
target/test-classes/com/pangdly/Http/Netty/AppTest.class
Normal file
Binary file not shown.
Reference in New Issue
Block a user