diff --git a/build.gradle b/build.gradle index e605686..f916de5 100644 --- a/build.gradle +++ b/build.gradle @@ -41,8 +41,8 @@ dependencies { implementation 'io.grpc:grpc-all:1.43.1' implementation 'org.apache.velocity:velocity-engine-core:2.3' implementation 'com.nimbusds:nimbus-jose-jwt:9.10' - implementation 'org.bdware.doip:doip-sdk:1.5.1' - implementation 'org.bdware.doip:doip-audit-tool:1.4.3' + implementation 'org.bdware.doip:doip-sdk:1.5.5' + implementation 'org.bdware.doip:doip-audit-tool:1.5.1' implementation 'org.bdware.doip:bdosclient:0.1.0' implementation fileTree(dir: 'lib', include: '*.jar') testImplementation 'junit:junit:4.13.2' diff --git a/src/main/java/org/bdware/server/CMHttpServer.java b/src/main/java/org/bdware/server/CMHttpServer.java index 79efeb4..74ff8d7 100644 --- a/src/main/java/org/bdware/server/CMHttpServer.java +++ b/src/main/java/org/bdware/server/CMHttpServer.java @@ -49,10 +49,12 @@ import java.lang.reflect.Field; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; +import java.util.Arrays; import java.util.Date; -import java.util.Objects; +import java.util.List; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +import java.util.regex.Pattern; public class CMHttpServer { private static final Logger LOGGER = LogManager.getLogger(CMHttpServer.class); @@ -167,21 +169,7 @@ public class CMHttpServer { private static void startByPath(JsonObject jo) { String path = jo.get("path").getAsString(); - if (path.indexOf('*') != -1) { - int split = Math.max(path.lastIndexOf('/'), 0); - String dirPath = path.substring(0, split), filePath = path.substring(split); - String[] fileName = - (filePath.startsWith("/") ? filePath.substring(1) : filePath).split("\\*"); - File dir = new File(dirPath); - for (File file : Objects.requireNonNull(dir.listFiles())) { - LOGGER.warn(file.getName()); - if (file.getName().startsWith(fileName[0]) - && file.getName().endsWith(fileName[fileName.length - 1])) { - path = file.getAbsolutePath(); - break; - } - } - } + path = findNewestYPK(path); File f = new File(path); if (!f.getName().endsWith(".ypk") || !f.exists()) return; @@ -197,6 +185,71 @@ public class CMHttpServer { ContractManager.instance.startContract(c); } + private static String findNewestYPK(String path) { + File toParse = new File(path); + if (!toParse.exists()) { + File dir = toParse.getParentFile(); + String fileName = toParse.getName(); + Pattern pattern = Pattern.compile(fileName); + if (dir.isDirectory() && dir.exists()) { + File[] available = dir.listFiles((f) -> { + String name = f.getName(); + return pattern.matcher(name).matches(); + }); + List result = Arrays.asList(available); + return findNewestFile(result).getAbsolutePath(); + } + } + return path; + } + + public static File findNewestFile(List files) { + File newestFile = null; + String newestVersion = null; + for (File file : files) { + String fileName = file.getName(); + String version = extractVersion(fileName); + + if (newestVersion == null || compareVersions(version, newestVersion) > 0) { + newestFile = file; + newestVersion = version; + } + } + return newestFile; + } + + private static String extractVersion(String fileName) { + // Assuming the version is between the last '-' and the last '.' + int lastDashIndex = fileName.lastIndexOf('-'); + int lastDotIndex = fileName.lastIndexOf('.'); + if (lastDashIndex == -1 || lastDotIndex == -1 || lastDashIndex >= lastDotIndex) { + throw new IllegalArgumentException("Invalid file name format: " + fileName); + } + return fileName.substring(lastDashIndex + 1, lastDotIndex); + } + + public static int compareVersions(String v1, String v2) { + String[] parts1 = v1.split("\\."); + String[] parts2 = v2.split("\\."); + + int length = Math.max(parts1.length, parts2.length); + + for (int i = 0; i < length; i++) { + int num1 = i < parts1.length ? Integer.parseInt(parts1[i]) : 0; + int num2 = i < parts2.length ? Integer.parseInt(parts2[i]) : 0; + + if (num1 < num2) { + return -1; + } + if (num1 > num2) { + return 1; + } + } + + return 0; // Both versions are equal + } + + private static String[] parseStrAsList(String str) { if (str == null) { return new String[] {}; @@ -318,8 +371,8 @@ public class CMHttpServer { ContractRepositoryMain.start(); final CMHttpHandler serverHandler = new CMHttpHandler(); EventLoopGroup bossGroup = new NioEventLoopGroup(1); - NettyConnectServerHandler trafficSharp = - new NettyConnectServerHandler(new AtomicInteger(0)); + // NettyConnectServerHandler trafficSharp = + // new NettyConnectServerHandler(new AtomicInteger(0)); try { ServerBootstrap b1 = new ServerBootstrap(); b1.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT); @@ -330,7 +383,8 @@ public class CMHttpServer { if (sslContext != null) { arg0.pipeline().addLast(new OptionalSslHandler(sslContext)); } - arg0.pipeline().addLast(trafficSharp).addLast(new HttpServerCodec()) + arg0.pipeline()// .addLast(trafficSharp) + .addLast(new HttpServerCodec()) .addLast(new HttpObjectAggregator(10 * 1024 * 1024)) .addLast(new WebSocketServerProtocolHandler(PATH, null, true)) .addLast(new ChunkedWriteHandler()).addLast(serverHandler) diff --git a/src/main/java/org/bdware/server/CongestionControl.java b/src/main/java/org/bdware/server/CongestionControl.java index c28390e..93c3db1 100644 --- a/src/main/java/org/bdware/server/CongestionControl.java +++ b/src/main/java/org/bdware/server/CongestionControl.java @@ -21,7 +21,7 @@ public class CongestionControl { public static int maxMasterServerLoad = 0; // configurations - public static int maxHttpConnCount = 100; + public static int maxHttpConnCount = 1000; // TODO remove sync call of executeOnOthreNode public static void httpCControl(ChannelHandlerContext ctx) { diff --git a/src/main/java/org/bdware/server/action/FileActions.java b/src/main/java/org/bdware/server/action/FileActions.java index dbc7a8b..1edb9ba 100644 --- a/src/main/java/org/bdware/server/action/FileActions.java +++ b/src/main/java/org/bdware/server/action/FileActions.java @@ -302,7 +302,7 @@ public class FileActions { fout = fileMap.get(target.getAbsolutePath()); try { fout.close(); - } catch (IOException e) { + } catch (Exception e) { e.printStackTrace(); } fileMap.remove(target.getAbsolutePath()); diff --git a/src/main/java/org/bdware/server/http/CMHttpHandler.java b/src/main/java/org/bdware/server/http/CMHttpHandler.java index 2f0b3e4..994311b 100644 --- a/src/main/java/org/bdware/server/http/CMHttpHandler.java +++ b/src/main/java/org/bdware/server/http/CMHttpHandler.java @@ -322,6 +322,7 @@ public class CMHttpHandler extends SimpleChannelInboundHandler { LOGGER.warn("catch exception in " + parseCtx2String(ctx) + ": " + cause.getClass().getSimpleName()); LOGGER.debug(ExceptionUtil.exceptionToString(cause)); + cause.printStackTrace(); // ctx.close(); } diff --git a/src/main/java/org/bdware/server/http/DOIPOverHttpHandler.java b/src/main/java/org/bdware/server/http/DOIPOverHttpHandler.java index 5e5ec7a..6a9e8dd 100644 --- a/src/main/java/org/bdware/server/http/DOIPOverHttpHandler.java +++ b/src/main/java/org/bdware/server/http/DOIPOverHttpHandler.java @@ -1,5 +1,6 @@ package org.bdware.server.http; +import com.google.gson.Gson; import com.google.gson.JsonObject; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelFuture; @@ -13,6 +14,7 @@ import io.netty.util.concurrent.GenericFutureListener; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.bdware.sc.ContractMeta; +import org.bdware.sc.YPKResourceManager; import org.bdware.sc.conn.ResultCallback; import org.bdware.sc.util.JsonUtil; import org.bdware.server.action.CMActions; @@ -21,7 +23,6 @@ import org.zz.gmhelper.SM2Util; import java.io.*; import java.net.URLDecoder; import java.util.*; -import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; @@ -49,11 +50,20 @@ public class DOIPOverHttpHandler { lastModified.remove(str); zf.close(); } catch (Exception e) { - + e.printStackTrace(); } } } + @URIPath({"/HTTPStat/"}) + public void getHTTPStat(ChannelHandlerContext ctx, FullHttpRequest request) { + FullHttpResponse response = + new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.OK, Unpooled.wrappedBuffer( + new Gson().toJson(DOIPOverHttpStatics.httpRecords).getBytes())); + response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=UTF-8"); + ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); + } + @URIPath({"/contracts/", "/DOIP/"}) public void mockDOIP(ChannelHandlerContext ctx, FullHttpRequest request) { try { @@ -188,6 +198,7 @@ public class DOIPOverHttpHandler { return; } + private void sendAssets(JsonObject arg, ChannelHandlerContext ctx) throws Exception { ContractMeta meta = CMActions.manager.statusRecorder .getContractMeta(arg.get("contractID").getAsString()); @@ -196,15 +207,25 @@ public class DOIPOverHttpHandler { return; } String path = arg.get("argument").getAsString(); - ZipFile zipFile = getZipFileFromPool(meta.contract.getScriptStr()); - ZipEntry zipEntry = zipFile.getEntry(path); - if (zipEntry == null) { - HttpFileHandleAdapter.sendError(ctx, HttpResponseStatus.NOT_FOUND); - return; + String dir = YPKResourceManager.getUnzipDir(meta.contract); + File toSend = new File(dir, path); + if (!toSend.exists()) { + if (YPKResourceManager.existYPK(meta.contract)) { + YPKResourceManager.unzipYPK(meta.contract); + } else { + HttpFileHandleAdapter.sendError(ctx, HttpResponseStatus.NOT_FOUND); + return; + } } - InputStream in = zipFile.getInputStream(zipEntry); + InputStream in = YPKResourceManager.getCachedStream(meta.contract, path); + DOIPOverHttpStatics.Records httpRecords = new DOIPOverHttpStatics.Records(); + httpRecords.start = System.currentTimeMillis(); + httpRecords.url = path; + DOIPOverHttpStatics.httpRecords.add(httpRecords); HttpResponse response = new DefaultHttpResponse(HTTP_1_1, HttpResponseStatus.OK); HttpFileHandleAdapter.appendContentType(path, response.headers()); + // HttpHeaders headers = response.headers(); + // headers.set(HttpHeaderNames.CACHE_CONTROL, "public, max-age=2592000"); ctx.write(response); ChannelFuture future = ctx.writeAndFlush(new ChunkedStream(in)); future.addListener(new GenericFutureListener>() { @@ -212,6 +233,9 @@ public class DOIPOverHttpHandler { public void operationComplete(Future arg0) throws Exception { ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT); in.close(); + httpRecords.end = System.currentTimeMillis(); + httpRecords.dur = httpRecords.end - httpRecords.start; + ctx.close(); } }); // 写入文件尾部 @@ -219,7 +243,7 @@ public class DOIPOverHttpHandler { return; } - private ZipFile getZipFileFromPool(String scriptStr) throws Exception { + private synchronized ZipFile getZipFileFromPool(String scriptStr) throws Exception { try { ZipFile cachedFile = zipFilePool.get(scriptStr); if (cachedFile == null) { diff --git a/src/main/java/org/bdware/server/http/DOIPOverHttpStatics.java b/src/main/java/org/bdware/server/http/DOIPOverHttpStatics.java new file mode 100644 index 0000000..ace889e --- /dev/null +++ b/src/main/java/org/bdware/server/http/DOIPOverHttpStatics.java @@ -0,0 +1,15 @@ +package org.bdware.server.http; + +import java.util.ArrayList; +import java.util.List; + +public class DOIPOverHttpStatics { + public static List httpRecords = new ArrayList(); + + static class Records { + long start; + long end; + long dur; + String url; + } +} diff --git a/src/main/java/org/bdware/units/NetworkManager.java b/src/main/java/org/bdware/units/NetworkManager.java index cdb3d80..108571e 100644 --- a/src/main/java/org/bdware/units/NetworkManager.java +++ b/src/main/java/org/bdware/units/NetworkManager.java @@ -117,7 +117,7 @@ public class NetworkManager { } } catch (Exception e) { // e.printStackTrace(); - LOGGER.warn("connecting to node center failed! " + e.getMessage()); + // LOGGER.warn("connecting to node center failed! " + e.getMessage()); } }, 4, 30 + (int) (20 * Math.random()), TimeUnit.SECONDS); }