From f475e3120003d2449faf3ad1242c20fd9e6d0344 Mon Sep 17 00:00:00 2001 From: Xinyi <627572337@qq.com> Date: Thu, 29 Dec 2016 10:10:24 +0800 Subject: [PATCH] create --- .gitignore | 4 ++++ pom.xml | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main/java/com/peony/netty/Application.java | 24 ++++++++++++++++++++++++ src/main/java/com/peony/netty/HttpServer.java | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/main/java/com/peony/netty/controller/BaseController.java | 7 +++++++ src/main/java/com/peony/netty/controller/DocContentController.java | 32 ++++++++++++++++++++++++++++++++ src/main/java/com/peony/netty/controller/DocHtmlController.java | 31 +++++++++++++++++++++++++++++++ src/main/java/com/peony/netty/controller/DocUrlController.java | 27 +++++++++++++++++++++++++++ src/main/java/com/peony/netty/handler/HttpServerHandler.java | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ src/main/java/com/peony/netty/http/Request.java | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main/java/com/peony/netty/http/Response.java | 20 ++++++++++++++++++++ src/main/java/com/peony/netty/service/DocContentService.java | 32 ++++++++++++++++++++++++++++++++ src/main/java/com/peony/netty/service/DocHtmlService.java | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/main/java/com/peony/netty/service/DocUrlService.java | 30 ++++++++++++++++++++++++++++++ src/main/java/com/peony/netty/util/ByteBufToBytes.java | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/main/java/com/peony/netty/util/HbaseFileSystem.java | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main/java/com/peony/netty/web/PathMatchResult.java | 33 +++++++++++++++++++++++++++++++++ src/main/java/com/peony/netty/web/Route.java | 11 +++++++++++ src/main/java/com/peony/netty/web/UriAdapter.java | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main/resources/logback.xml | 28 ++++++++++++++++++++++++++++ 20 files changed, 838 insertions(+), 0 deletions(-) create mode 100644 .gitignore create mode 100644 pom.xml create mode 100644 src/main/java/com/peony/netty/Application.java create mode 100644 src/main/java/com/peony/netty/HttpServer.java create mode 100644 src/main/java/com/peony/netty/controller/BaseController.java create mode 100644 src/main/java/com/peony/netty/controller/DocContentController.java create mode 100644 src/main/java/com/peony/netty/controller/DocHtmlController.java create mode 100644 src/main/java/com/peony/netty/controller/DocUrlController.java create mode 100644 src/main/java/com/peony/netty/handler/HttpServerHandler.java create mode 100644 src/main/java/com/peony/netty/http/Request.java create mode 100644 src/main/java/com/peony/netty/http/Response.java create mode 100644 src/main/java/com/peony/netty/service/DocContentService.java create mode 100644 src/main/java/com/peony/netty/service/DocHtmlService.java create mode 100644 src/main/java/com/peony/netty/service/DocUrlService.java create mode 100644 src/main/java/com/peony/netty/util/ByteBufToBytes.java create mode 100644 src/main/java/com/peony/netty/util/HbaseFileSystem.java create mode 100644 src/main/java/com/peony/netty/web/PathMatchResult.java create mode 100644 src/main/java/com/peony/netty/web/Route.java create mode 100644 src/main/java/com/peony/netty/web/UriAdapter.java create mode 100644 src/main/resources/logback.xml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ceaaf71 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +target/ +*.iml +logs/ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..5df16c0 --- /dev/null +++ b/pom.xml @@ -0,0 +1,108 @@ + + + 4.0.0 + + com.peony + crawler-netty + 1.0-SNAPSHOT + + + + io.netty + netty-all + 4.0.25.Final + + + + junit + junit + 4.12 + + + + org.slf4j + slf4j-api + 1.7.21 + + + + org.slf4j + log4j-over-slf4j + 1.7.21 + + + + ch.qos.logback + logback-core + 1.1.7 + + + + ch.qos.logback + logback-classic + 1.1.7 + + + + com.peony.crawler + crawler-util + 0.0.1-SNAPSHOT + + + + org.apache.hbase + hbase-client + 1.2.2 + + + org.slf4j + slf4j-log4j12 + + + + + + com.qingcloud.qingstor + qingstor + 1.0-SNAPSHOT + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.7 + 1.7 + UTF-8 + + + + maven-assembly-plugin + + + jar-with-dependencies + + + + com.peony.netty.Application + + + + + + make-assembly + package + + single + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/peony/netty/Application.java b/src/main/java/com/peony/netty/Application.java new file mode 100644 index 0000000..a335263 --- /dev/null +++ b/src/main/java/com/peony/netty/Application.java @@ -0,0 +1,24 @@ +package com.peony.netty; + +import com.peony.netty.controller.DocContentController; +import com.peony.netty.controller.DocHtmlController; +import com.peony.netty.http.Request; +import com.peony.netty.http.Response; +import com.peony.netty.web.Route; + +import static com.peony.netty.web.UriAdapter.get; + +public class Application { + public static void main(String[] args) throws Exception { + HttpServer server = new HttpServer(); + get("hello", new Route() { + @Override + public Object handle(Request request, Response response) { + return "Hello World 你好"; + } + }); + new DocContentController().routes(); + new DocHtmlController().routes(); + server.start(8000); + } +} diff --git a/src/main/java/com/peony/netty/HttpServer.java b/src/main/java/com/peony/netty/HttpServer.java new file mode 100644 index 0000000..c9de06c --- /dev/null +++ b/src/main/java/com/peony/netty/HttpServer.java @@ -0,0 +1,44 @@ +package com.peony.netty; + +import com.peony.netty.handler.HttpServerHandler; +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelOption; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.handler.codec.http.HttpRequestDecoder; +import io.netty.handler.codec.http.HttpResponseEncoder; + +public class HttpServer { + public void start(int port) throws Exception { + EventLoopGroup bossGroup = new NioEventLoopGroup(); + EventLoopGroup workerGroup = new NioEventLoopGroup(); + try { + ServerBootstrap b = new ServerBootstrap(); + b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class) + .childHandler(new ChannelInitializer() { + @Override + public void initChannel(SocketChannel ch) throws Exception { + // server端发送的是httpResponse,所以要使用HttpResponseEncoder进行编码 + ch.pipeline().addLast(new HttpResponseEncoder()); + // server端接收到的是httpRequest,所以要使用HttpRequestDecoder进行解码 + ch.pipeline().addLast(new HttpRequestDecoder()); + ch.pipeline().addLast(new HttpServerHandler()); + } + }) + .option(ChannelOption.SO_BACKLOG, 128) + .childOption(ChannelOption.SO_KEEPALIVE, true); + + // 绑定端口,开始接收进来的连接 + ChannelFuture f = b.bind(port).sync(); + // 等待服务器 socket 关闭 。 + f.channel().closeFuture().sync(); + } finally { + workerGroup.shutdownGracefully(); + bossGroup.shutdownGracefully(); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/peony/netty/controller/BaseController.java b/src/main/java/com/peony/netty/controller/BaseController.java new file mode 100644 index 0000000..2d60eb4 --- /dev/null +++ b/src/main/java/com/peony/netty/controller/BaseController.java @@ -0,0 +1,7 @@ +package com.peony.netty.controller; + +interface BaseController { + + void routes(); + +} diff --git a/src/main/java/com/peony/netty/controller/DocContentController.java b/src/main/java/com/peony/netty/controller/DocContentController.java new file mode 100644 index 0000000..9e275a6 --- /dev/null +++ b/src/main/java/com/peony/netty/controller/DocContentController.java @@ -0,0 +1,32 @@ +package com.peony.netty.controller; + +import com.peony.netty.http.Request; +import com.peony.netty.http.Response; +import com.peony.netty.service.DocContentService; +import com.peony.netty.web.Route; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static com.peony.netty.web.UriAdapter.get; + +public class DocContentController implements BaseController { + private Logger logger = LoggerFactory.getLogger(DocContentController.class); + + @Override + public void routes() { + final DocContentService docContentService = new DocContentService(); + get("content/:id", new Route() { + @Override + public Object handle(Request req, Response res) { + String id = req.params("id"); + logger.info("获取到的Id: " + id); +// String depress = req.queryParams("depress"); +// if (depress == null) { +// depress = "true"; +// } + String content = docContentService.get(id, true); + return "content " + content; + } + }); + } +} diff --git a/src/main/java/com/peony/netty/controller/DocHtmlController.java b/src/main/java/com/peony/netty/controller/DocHtmlController.java new file mode 100644 index 0000000..86ef002 --- /dev/null +++ b/src/main/java/com/peony/netty/controller/DocHtmlController.java @@ -0,0 +1,31 @@ +package com.peony.netty.controller; + +import com.peony.netty.http.Request; +import com.peony.netty.http.Response; +import com.peony.netty.service.DocHtmlService; +import com.peony.netty.web.Route; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static com.peony.netty.web.UriAdapter.get; + +public class DocHtmlController implements BaseController { + private Logger logger = LoggerFactory.getLogger(DocHtmlController.class); + + @Override + public void routes() { + final DocHtmlService docHtmlService = new DocHtmlService(); + get("html/:id", new Route() { + @Override + public Object handle(Request req, Response resp) { + String id = req.params("id"); +// String depress = req.queryParams("depress"); +// if (depress == null) { +// depress = "true"; +// } + String html = docHtmlService.get(id, true); + return "html " + html; + } + }); + } +} diff --git a/src/main/java/com/peony/netty/controller/DocUrlController.java b/src/main/java/com/peony/netty/controller/DocUrlController.java new file mode 100644 index 0000000..b3232e8 --- /dev/null +++ b/src/main/java/com/peony/netty/controller/DocUrlController.java @@ -0,0 +1,27 @@ +package com.peony.netty.controller; + +import com.peony.netty.http.Request; +import com.peony.netty.http.Response; +import com.peony.netty.service.DocUrlService; +import com.peony.netty.web.Route; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static com.peony.netty.web.UriAdapter.get; + +public class DocUrlController implements BaseController { + private Logger logger = LoggerFactory.getLogger(DocUrlController.class); + + @Override + public void routes() { + final DocUrlService docUrlService = DocUrlService.getInstance(); + get("url/:id", new Route() { + @Override + public Object handle(Request req, Response resp) { + String id = req.params("id"); + String url = docUrlService.get(id); + return "url " + url; + } + }); + } +} diff --git a/src/main/java/com/peony/netty/handler/HttpServerHandler.java b/src/main/java/com/peony/netty/handler/HttpServerHandler.java new file mode 100644 index 0000000..c657e65 --- /dev/null +++ b/src/main/java/com/peony/netty/handler/HttpServerHandler.java @@ -0,0 +1,49 @@ +package com.peony.netty.handler; + +import com.peony.netty.util.ByteBufToBytes; +import com.peony.netty.web.UriAdapter; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.handler.codec.http.DefaultFullHttpResponse; +import io.netty.handler.codec.http.FullHttpResponse; +import io.netty.handler.codec.http.HttpHeaders; +import io.netty.handler.codec.http.HttpRequest; + +import static io.netty.handler.codec.http.HttpHeaders.Names.*; +import static io.netty.handler.codec.http.HttpResponseStatus.NOT_FOUND; +import static io.netty.handler.codec.http.HttpResponseStatus.OK; +import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; + +public class HttpServerHandler extends ChannelInboundHandlerAdapter { + + private ByteBufToBytes reader; + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) { + if (msg instanceof HttpRequest) { + HttpRequest request = (HttpRequest) msg; +// System.out.println("User-Agent: " + request.headers().get("User-Agent")); + + FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK); + boolean success = UriAdapter.adapter(request.getUri(), request, response); + if (success) { + response.setStatus(OK); + } else { + response.setStatus(NOT_FOUND); + } + response.headers().set(CONTENT_TYPE, "text/plain; charset=utf-8"); +// response.headers().set(CONTENT_TYPE, "text/html; charset=UTF-8"); + response.headers().set(CONTENT_LENGTH, response.content().readableBytes()); + response.headers().set(CONNECTION, HttpHeaders.Values.KEEP_ALIVE); + ctx.write(response); + ctx.flush(); + } + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { + // 当出现异常就关闭连接 + cause.printStackTrace(); + ctx.close(); + } +} diff --git a/src/main/java/com/peony/netty/http/Request.java b/src/main/java/com/peony/netty/http/Request.java new file mode 100644 index 0000000..aa54356 --- /dev/null +++ b/src/main/java/com/peony/netty/http/Request.java @@ -0,0 +1,64 @@ +package com.peony.netty.http; + +import com.peony.netty.web.PathMatchResult; +import com.peony.util.StringUtils; +import io.netty.handler.codec.http.HttpRequest; + +import java.util.Map; + +public class Request { + + private HttpRequest request; + private Map params; + private PathMatchResult pathMatchResult; + private String[] customPaths; + + public Request(HttpRequest request) { + this.request = request; + } + + public HttpRequest getRequest() { + return request; + } + + public void setRequest(HttpRequest request) { + this.request = request; + } + + public Map getParams() { + return params; + } + + public void setParams(Map params) { + this.params = params; + } + + public PathMatchResult getPathMatchResult() { + return pathMatchResult; + } + + public String[] getCustomPaths() { + return customPaths; + } + + public void setCustomPath(String[] customPaths) { + this.customPaths = customPaths; + } + + public void setPathMatchResult(PathMatchResult pathMatchResult) { + this.pathMatchResult = pathMatchResult; + if (params == null) { + this.params = pathMatchResult.getParams(); + } + if (customPaths == null) { + this.customPaths = pathMatchResult.getCustomPaths(); + } + } + + public String params(String key) { + if (StringUtils.isEmpty(key) || params == null) { + return null; + } + return params.get(key); + } +} diff --git a/src/main/java/com/peony/netty/http/Response.java b/src/main/java/com/peony/netty/http/Response.java new file mode 100644 index 0000000..35395f6 --- /dev/null +++ b/src/main/java/com/peony/netty/http/Response.java @@ -0,0 +1,20 @@ +package com.peony.netty.http; + +import io.netty.handler.codec.http.HttpResponse; + +public class Response { + + private HttpResponse response; + + public Response(HttpResponse response) { + this.response = response; + } + + public HttpResponse getResponse() { + return response; + } + + public void setResponse(HttpResponse response) { + this.response = response; + } +} diff --git a/src/main/java/com/peony/netty/service/DocContentService.java b/src/main/java/com/peony/netty/service/DocContentService.java new file mode 100644 index 0000000..314e59e --- /dev/null +++ b/src/main/java/com/peony/netty/service/DocContentService.java @@ -0,0 +1,32 @@ +package com.peony.netty.service; + +import com.peony.netty.util.HbaseFileSystem; +import org.apache.hadoop.hbase.TableName; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DocContentService { + + private static DocContentService instance = new DocContentService(); + private final TableName tableContent = TableName.valueOf("doc"); + private Logger logger = LoggerFactory.getLogger(DocContentService.class); + private HbaseFileSystem fileSystem = HbaseFileSystem.getInstance(); + + public static DocContentService getInstance() { + return instance; + } + + public String get(String id, boolean depress) { + String content = null; + try { + content = fileSystem.get(id, tableContent, depress); + if (content == null) { + logger.warn("查询id: " + id + " 正文为空"); + return null; + } + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + return content; + } +} diff --git a/src/main/java/com/peony/netty/service/DocHtmlService.java b/src/main/java/com/peony/netty/service/DocHtmlService.java new file mode 100644 index 0000000..35e8e8f --- /dev/null +++ b/src/main/java/com/peony/netty/service/DocHtmlService.java @@ -0,0 +1,44 @@ +package com.peony.netty.service; + +import com.peony.netty.util.HbaseFileSystem; +import com.peony.util.StringUtils; +import com.qingcloud.qingstor.Qingstor; +import org.apache.hadoop.hbase.TableName; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DocHtmlService { + + private static DocHtmlService instance = new DocHtmlService(); + private final TableName tableContent = TableName.valueOf("doc_html"); + private final String bucketHtml = "doc-html"; + private Logger logger = LoggerFactory.getLogger(DocHtmlService.class); + private HbaseFileSystem fileSystem = HbaseFileSystem.getInstance(); + + public static DocHtmlService getInstance() { + return instance; + } + + public String get(String id, boolean depress) { + String html = null; + try { +// html = fileSystem.get(id, tableContent, depress); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + if (StringUtils.isEmpty(html)) { + try { + String htmlCompress = Qingstor.getObject(bucketHtml, id); + html = depress ? StringUtils.depressString(htmlCompress) : htmlCompress; + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + } + if (html == null) { + logger.warn("查询id: " + id + " HTML为空"); + return null; + } + return html; + } + +} diff --git a/src/main/java/com/peony/netty/service/DocUrlService.java b/src/main/java/com/peony/netty/service/DocUrlService.java new file mode 100644 index 0000000..de109b4 --- /dev/null +++ b/src/main/java/com/peony/netty/service/DocUrlService.java @@ -0,0 +1,30 @@ +package com.peony.netty.service; + +import com.peony.netty.util.HbaseFileSystem; +import com.peony.util.StringUtils; +import org.apache.hadoop.hbase.TableName; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DocUrlService { + + private static DocUrlService instance = new DocUrlService(); + private final TableName tableUrl = TableName.valueOf("doc_url"); + private Logger logger = LoggerFactory.getLogger(DocUrlService.class); + private HbaseFileSystem fileSystem = HbaseFileSystem.getInstance(); + + public static DocUrlService getInstance() { + return instance; + } + + public String get(String id) { + String url = null; + try { + url = new String(fileSystem.get(id, tableUrl), StringUtils.CHARSET); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + return url; + } + +} diff --git a/src/main/java/com/peony/netty/util/ByteBufToBytes.java b/src/main/java/com/peony/netty/util/ByteBufToBytes.java new file mode 100644 index 0000000..24db74b --- /dev/null +++ b/src/main/java/com/peony/netty/util/ByteBufToBytes.java @@ -0,0 +1,44 @@ +package com.peony.netty.util; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; + +public class ByteBufToBytes { + private ByteBuf temp; + + private boolean end = true; + + public ByteBufToBytes(int length) { + temp = Unpooled.buffer(length); + } + + public void reading(ByteBuf datas) { + datas.readBytes(temp, datas.readableBytes()); + if (this.temp.writableBytes() != 0) { + end = false; + } else { + end = true; + } + } + + public boolean isEnd() { + return end; + } + + public byte[] readFull() { + if (end) { + byte[] contentByte = new byte[this.temp.readableBytes()]; + this.temp.readBytes(contentByte); + this.temp.release(); + return contentByte; + } else { + return null; + } + } + + public byte[] read(ByteBuf datas) { + byte[] bytes = new byte[datas.readableBytes()]; + datas.readBytes(bytes); + return bytes; + } +} \ No newline at end of file diff --git a/src/main/java/com/peony/netty/util/HbaseFileSystem.java b/src/main/java/com/peony/netty/util/HbaseFileSystem.java new file mode 100644 index 0000000..3e459ea --- /dev/null +++ b/src/main/java/com/peony/netty/util/HbaseFileSystem.java @@ -0,0 +1,122 @@ +package com.peony.netty.util; + +import com.peony.util.StringUtils; +import com.peony.util.SystemProps; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hbase.HBaseConfiguration; +import org.apache.hadoop.hbase.TableName; +import org.apache.hadoop.hbase.client.*; +import org.apache.hadoop.hbase.util.Bytes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class HbaseFileSystem { + + private static final Logger logger = LoggerFactory.getLogger(HbaseFileSystem.class); + private static final int BATCH = SystemProps.getIntProperty("batch", 100); + private static final int CACAHING = SystemProps.getIntProperty("caching", 1000); + + private String clientPort = "2181"; + private String quorum = "192.168.3.37,192.168.3.38,192.168.3.39"; + // private String master = "192.168.10.15"; + private String master = "60000"; + // private String parent = "/hbase/hbs-aqtb2h1b"; + private String parent = "/hbase/hbs-gxjpkf8z"; + + private byte[] familyName = Bytes.toBytes("content"); + + private Connection connection; + + private HbaseFileSystem() { + Configuration config = HBaseConfiguration.create(); + config.set("hbase.zookeeper.property.clientPort", SystemProps.getProperty("clientPort", clientPort)); + config.set("hbase.zookeeper.quorum", SystemProps.getProperty("quorum", quorum)); + config.set("hbase.master", SystemProps.getProperty("master", master)); + config.set("zookeeper.znode.parent", SystemProps.getProperty("parent", parent)); + try { + connection = ConnectionFactory.createConnection(config); + } catch (IOException e) { + logger.error("创建到hbase的连接失败", e); + } + } + + public byte[] get(String id, TableName tableName) throws Exception { + Table table = connection.getTable(tableName); + Get get = new Get(Bytes.toBytes(id)); + Result rs = table.get(get); + if (rs.isEmpty()) { + return null; + } + byte[] data = rs.getValue(familyName, null); + if (data == null) { + return null; + } + return data; + } + + public String get(String id, TableName tableName, boolean depress) throws Exception { + byte[] bytes = get(id, tableName); + if (bytes == null) { + return null; + } + if (depress) { + return new String(StringUtils.depress(bytes), StringUtils.CHARSET); + } else { + return StringUtils.encodeBase64String(bytes); + } + } + + public ResultScanner scan(TableName tableName) throws Exception { + Table table = connection.getTable(tableName); + Scan scan = new Scan(); + scan.addFamily(familyName); + scan.setMaxVersions(1); + scan.setCaching(CACAHING); + scan.setBatch(BATCH); + return table.getScanner(scan); + } + + public boolean add(String id, String content, boolean replace, TableName tableName) throws Exception { + Table table = connection.getTable(tableName); + Get get = new Get(Bytes.toBytes(id)); + get.addColumn(familyName, null); + if (!replace && table.exists(get)) { + logger.debug("file exists in hbase, id: {}", id); + return false; + } + Put put = new Put(Bytes.toBytes(id)); + byte[] data = org.apache.commons.codec.binary.StringUtils.getBytesUnchecked(content, StringUtils.CHARSET); + put.addColumn(familyName, null, data); + table.put(put); + return true; + } + + public boolean delete(String id, TableName tableName) throws IOException { + List ids = new ArrayList<>(); + ids.add(id); + return delete(ids, tableName); + } + + public boolean delete(List ids, TableName tableName) throws IOException { + Table table = connection.getTable(tableName); + List deletes = new ArrayList<>(); + for (String id : ids) { + Delete delete = new Delete(Bytes.toBytes(id)); + delete.addFamily(familyName); + deletes.add(delete); + } + table.delete(deletes); + return true; + } + + private static final HbaseFileSystem instance = new HbaseFileSystem(); + + public static HbaseFileSystem getInstance() { + return instance; + } + +} diff --git a/src/main/java/com/peony/netty/web/PathMatchResult.java b/src/main/java/com/peony/netty/web/PathMatchResult.java new file mode 100644 index 0000000..d747edf --- /dev/null +++ b/src/main/java/com/peony/netty/web/PathMatchResult.java @@ -0,0 +1,33 @@ +package com.peony.netty.web; + +import java.util.Map; + +public class PathMatchResult { + private boolean success; + private String[] customPaths; + private Map params; + + public boolean success() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public String[] getCustomPaths() { + return customPaths; + } + + public void setCustomPaths(String[] customPaths) { + this.customPaths = customPaths; + } + + public Map getParams() { + return params; + } + + public void setParams(Map params) { + this.params = params; + } +} \ No newline at end of file diff --git a/src/main/java/com/peony/netty/web/Route.java b/src/main/java/com/peony/netty/web/Route.java new file mode 100644 index 0000000..d4b51d3 --- /dev/null +++ b/src/main/java/com/peony/netty/web/Route.java @@ -0,0 +1,11 @@ +package com.peony.netty.web; + +import com.peony.netty.http.Request; +import com.peony.netty.http.Response; + + +public interface Route { + + Object handle(Request request, Response response); + +} \ No newline at end of file diff --git a/src/main/java/com/peony/netty/web/UriAdapter.java b/src/main/java/com/peony/netty/web/UriAdapter.java new file mode 100644 index 0000000..17dd030 --- /dev/null +++ b/src/main/java/com/peony/netty/web/UriAdapter.java @@ -0,0 +1,84 @@ +package com.peony.netty.web; + +import com.peony.netty.http.Request; +import com.peony.netty.http.Response; +import io.netty.buffer.Unpooled; +import io.netty.handler.codec.http.FullHttpResponse; +import io.netty.handler.codec.http.HttpRequest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.net.URI; +import java.util.*; + +public class UriAdapter { + + private static Logger logger = LoggerFactory.getLogger(UriAdapter.class); + private static Map routeMap = new HashMap<>(); + + + public static void get(final String path, final Route route) { + String[] paths = path.split("/"); + routeMap.put(paths, route); + } + + public static boolean adapter(String uri, HttpRequest request, FullHttpResponse response) { + URI u = URI.create(uri); + String path = u.getPath(); + logger.info("path: " + u.getPath() + " query: " + u.getQuery()); + for (Map.Entry entry : routeMap.entrySet()) { + String[] key = entry.getKey(); + Route route = entry.getValue(); + PathMatchResult pathMatchResult = pathMatch(key, path); + if (pathMatchResult.success()) { + logger.info("匹配成功: " + Arrays.toString(pathMatchResult.getCustomPaths()) + " uri: " + path); + for (Map.Entry param : pathMatchResult.getParams().entrySet()) { + logger.info("匹配参数: " + param.getKey() + " : " + param.getValue()); + } + Request req = new Request(request); + Response resp = new Response(response); + req.setPathMatchResult(pathMatchResult); + Object handle = route.handle(req, resp); + if (handle instanceof String) { + String content = (String) handle; + response.content().writeBytes(Unpooled.wrappedBuffer(content.getBytes())); + } + return true; + } + } + logger.warn("匹配失败:" + path); + return false; + } + + + public static PathMatchResult pathMatch(String[] customPaths, String path) { + PathMatchResult pathMatchResult = new PathMatchResult(); + String[] paths = path.substring(1).split("/"); + List pathList = new ArrayList<>(); + for (String subPath: paths) { + pathList.add(subPath); + } + if (pathList.size() != customPaths.length) { + pathMatchResult.setSuccess(false); + return pathMatchResult; + } + Map params = new HashMap<>(); + for (int i = 0; i < customPaths.length; i++) { + String s = pathList.get(i); + String customPath = customPaths[i]; + if (customPath.startsWith(":")) { + params.put(customPath.substring(1), s); + } else if (!customPath.equals(s)) { + pathMatchResult.setSuccess(false); + return pathMatchResult; + } + if (i == customPaths.length - 1) { + pathMatchResult.setCustomPaths(customPaths); + pathMatchResult.setParams(params); + } + } + pathMatchResult.setSuccess(true); + return pathMatchResult; + } + +} diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml new file mode 100644 index 0000000..5d2a8a2 --- /dev/null +++ b/src/main/resources/logback.xml @@ -0,0 +1,28 @@ + + + + + + + ${CONSOLE_LOG_PATTERN} + utf8 + + + + + ./logs/netty.log + + ./logs/netty.%d{yyyy-MM-dd}.log + 30 + 50GB + + + ${CONSOLE_LOG_PATTERN} + + + + + + + + \ No newline at end of file -- libgit2 0.21.2