diff --git a/.gitignore b/.gitignore index a1c2a23..8c1f6c6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,23 +1,15 @@ -# Compiled class file -*.class - -# Log file -*.log - -# BlueJ files -*.ctxt - -# Mobile Tools for Java (J2ME) -.mtj.tmp/ - -# Package Files # -*.jar -*.war -*.nar -*.ear -*.zip -*.tar.gz -*.rar - -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml -hs_err_pid* +/BDWareProjectDir +/ContractDB +/ContractManagerDB +/log +/rocksdb +/repoConf.json +/ContractTemplate +/CMI +/mTest +/manager.key +/WebContent/ +/runnable +cmconfig.json* +/build/ +*/build/* \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..c03d60a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,15 @@ +FROM openjdk:8 + +ARG GOPRIVATE=bdware.org/* +ARG GOPROXY=https://goproxy.cn + +LABEL maintainer="caihuaqian@internetapi.cn" +LABEL org.bdware.version="1.5.0" +LABEL org.bdware.version.isproduction="false" +LABEL org.bdware.release-date="2021-08-09" + +COPY ./output /bdcontract +WORKDIR /bdcontract +VOLUME /bdcontract/ContractManagerDB /bdcontract/rocksdb /bdcontract/ContractDB /bdcontract/BDWareProjectDir +ENTRYPOINT ["java"] +CMD ["-Dfile.encoding=UTF-8", "-Djava.library.path='./dynamicLibrary'", "-cp", "./libs/*:bdagent.jar", "org.bdware.server.CMHttpServer"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..134bc39 --- /dev/null +++ b/README.md @@ -0,0 +1,56 @@ +## Docker镜像制作 +把`Dockerfile`放到一个目录,同时把编译好的`bdagent-lite.zip`放到同一目录,并解压、制作镜像: +``` +c07e0791-4e37-422b-86e4-31307cd803f1 +cd ./build/output/ +cp ../../Dockerfile ./ +docker build -t bdwaas/bdcontract:tag +docker push bdwaas/bdcontract:tag +docker push +``` + + +## 笔记待梳理(监听端口与EventGroup) + +### 服务端 + +1) port: http & websocket server port +2) port+1: tcp server port + httpServer与tcpServer 共用同一组EventLoopGroup, boss group CMHttpServer.workergroup + workerGroup对应的异步线程池:ContractManagerFrameHandler.executorService + +3) port+2: doip server port + ContractRepositoryMain是自己有一组workergroup + +4) port+3: prometheus server port + prometheus自己管理newFixedThreadPool(5) + +5) ContractManager本地监听端口:1615+X + ServiceServer里面,独立的workerGroup/bossGroup + ServiceServer.executor + + +### 客户端 + +1) TCP连接NodeCenter + Bootstrap都在CMActions里面实例化,独立声明的EventLoopGroup group = new NioEventLoopGroup()。 + ContractManagerFrameHandler.executorService + +2) TCP连接其他Master + 每个连接一个Bootstrap + b.group(CMHttpServer.workerGroup)直接是与http/tcp/Server的worker Group。 + MasterClientFrameHandler.executorService + + +是网络忙还是计算忙? +是只在发端控制?还是收发一起控制? +对于单个节点的视角 +TCPClient发前流量控制检查,->TCPServer收到后强保障 +* 当前版本:仅在Http端控制队列长度 +* 0331周计划版本:在CMHttpServer.workerGroup控制? +* 需要理清异步线程池。 + +## 线程池 + +ContractManager.executor是一个可扩容线程池,front-agent中所有线程执行需求都可以合并进去。 +合并时,建议按照自己的线程执行需求对核心线程数(ContractManager.executor构造函数的第一个参数)进行增加,并适量提高最大线程数(第二个参数)。 \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..e53d4ae --- /dev/null +++ b/build.gradle @@ -0,0 +1,186 @@ +plugins { + id 'java' + id 'application' +} + +mainClassName = 'org.bdware.server.CMHttpServer' + +application { + mainClass = mainClassName + applicationDefaultJvmArgs = ['-Dfile.encoding=UTF-8', '-Djava.library.path="./dynamicLibrary"'] +} + +sourceSets { + main { + java { + srcDir 'src/main/java' + } + resources { + srcDir 'src/main/resources' + } + } + test { + java { + srcDir 'src/test/java' + } + resources { + srcDir 'src/test/resources' + } + } +} + +dependencies { + implementation project(":cm") + implementation project(":mockjava") + implementation project(":front-base") + implementation 'io.prometheus:simpleclient_httpserver:0.12.0' + testImplementation 'junit:junit:4.13.2' +} +compileJava { + options.compilerArgs<<"-Xlint:unchecked" +} +jar { + String libs = '' + configurations.runtimeClasspath.each { + libs = libs + " libs/" + it.name + } + + manifest { + attributes 'Manifest-Version': project.version + attributes 'Main-Class': mainClassName + attributes 'Class-Path': libs + } +} + +tasks.processResources.setDuplicatesStrategy(DuplicatesStrategy.INCLUDE) + +task copyScript(type: Copy) { + from("../script/") { + include 'cmstart.sh' + include 'cmstop.sh' + include 'cmconfig.json.template' + include 'killContracts.sh' + } + into "./build/output" + println("copyScript done !") +} + +task copyScriptBDLedger(type: Copy) { + from("../script/") { + include 'cmstart.sh' + include 'cmconfig.json' + include 'cmstartbdledger.sh' + include 'cmstop.sh' + include 'cmconfig.json.template' + include 'killContracts.sh' + include 'updateContract.sh' + include 'installClusterWithBdledger.sh' + } + into "./build/output" + println("copyScript done !") +} + +task copySsl(type: Copy) { + from './ssl' + into './build/output/ssl' +} + +task copyDynamicLibrary(type: Copy) { + from './dynamicLibrary/' + into './build/output/dynamicLibrary' +} + +task copyLibs(type: Copy, dependsOn: ["copyScript", 'copySsl']) { + from configurations.runtimeClasspath + into "./build/output/libs/" +} + +//task copyJar(type: Exec, dependsOn: [":agent-backend:jar", ":agent-backend:copyLibs", ":agent-backend:copyDynamicLibrary"]) { +// println("copyJar start") +// commandLine "cp", "./build/libs/$project.name-${project.version}.jar", "./build/output/bdagent.jar" +//} + +task copyJar(type: Copy, dependsOn: [":agent-backend:jar", ":agent-backend:copyLibs", ":agent-backend:copyDynamicLibrary"]) { + from "./build/libs/$project.name-${project.version}.jar" + into "./build/output" + rename { String fileName -> "bdagent.jar" } + doFirst { + println "copyJar start" + } +} + +task copyBDWareProjectDir(type: Copy, dependsOn: [":agent-backend:copyJar", ":agent-backend:copyDockerfile"]) { + from "./contracts" + into "./build/output/BDWareProjectDir/public" +} + +task copyWebContent(type: Copy) { + from("./WebContent") { + exclude 'ide/BaaSOnlineIDE.html' + exclude 'ide/.idea/' + exclude 'ide/.gitignore' + exclude 'client/BaaSClient.html' + exclude 'client/README.md' + exclude 'client/.idea/' + exclude 'client/.gitignore' + } + into "./build/output/WebContent" +} + +task copyDockerfile(type: Copy) { + from "./Dockerfile" + into "./build/" +} + +//task copyCP(type: Copy, dependsOn: ":cp:buildBundle") { +// from "../cp/build/output" +// into "./build/output" +//} + +task copyKeys(type: Copy) { + from "./keys" + into "./build/output/keys" +} + +task buildBDServerZip(type: Zip, dependsOn: [ ":agent-backend:copyWebContent", + ":agent-backend:copyBDWareProjectDir", ":agent-backend:copyScript", + ":agent-backend:copyJar", ":agent-backend:copyLibs", ":agent-backend:copyKeys"]) { + from './build/output/' + duplicatesStrategy = DuplicatesStrategy.INCLUDE + archiveFileName = 'bdserver.zip' + destinationDirectory = file('build/') +} + +task buildBDServerZipLite(type: Zip, dependsOn: [ ":agent-backend:copyWebContent", + ":agent-backend:copyBDWareProjectDir", ":agent-backend:copyScript", + ":agent-backend:copyJar", ":agent-backend:copyLibs", ":agent-backend:copyKeys"]) { + from('./build/output/') { + exclude 'BDWareProjectDir/public/**' + exclude 'WebContent/doc/' + } + duplicatesStrategy = DuplicatesStrategy.INCLUDE + archiveFileName = 'bdserver-lite.zip' + destinationDirectory = file('build/') +} + +task buildBDServerZipUpdate(type: Zip, dependsOn: [":agent-backend:copyCP", ":agent-backend:copyWebContent", + ":agent-backend:copyBDWareProjectDir", ":agent-backend:copyScript", + ":agent-backend:copyJar", ":agent-backend:copyLibs", ":agent-backend:copyKeys"]) { + from('./build/output/') { + include '*.jar' + include 'libs/' + include 'WebContent/' + exclude 'WebContent/doc/' + } + duplicatesStrategy = DuplicatesStrategy.INCLUDE + archiveFileName = 'bdserver-update.zip' + destinationDirectory = file('build/') +} + +task buildWebContentZip(type: Zip, dependsOn: [":agent-backend:copyCP", ":agent-backend:copyWebContent"]) { + from "./build/output/WebContent" + duplicatesStrategy = DuplicatesStrategy.INCLUDE + archiveFileName = 'AgentWebContent.zip' + destinationDirectory = file('build/') +} + diff --git a/contracts/AnnotationSample/AnnotationExample.yjs b/contracts/AnnotationSample/AnnotationExample.yjs new file mode 100644 index 0000000..4f54bdc --- /dev/null +++ b/contracts/AnnotationSample/AnnotationExample.yjs @@ -0,0 +1,19 @@ +@Access("verified") +@LogType("Arg", "IO") +@LogLocation("lo") +@Description("这是个使用注解的合约示例,只有一个方法") +contract AnnotationExample{ + @LogType("Branch") + @Description("计算score之和,参数示例: [{\"score\":20},{\"score\":20}]") + export function main(arg){ + point = JSON.parse(arg); + var s = 0; + print(point[0].score); + print(point.length); + for (var i = 0; i < point.length; i++){ + s += point[i].score / 1.0; + } + print("ss= " + s); + return s; + } +} diff --git a/contracts/AnnotationSample/manifest.json b/contracts/AnnotationSample/manifest.json new file mode 100644 index 0000000..bc6aa53 --- /dev/null +++ b/contracts/AnnotationSample/manifest.json @@ -0,0 +1,3 @@ +{ + "main": "AnnotationExample.yjs" +} \ No newline at end of file diff --git a/contracts/AppDataAnalysis/DataAnalysis.yjs b/contracts/AppDataAnalysis/DataAnalysis.yjs new file mode 100644 index 0000000..894cead --- /dev/null +++ b/contracts/AppDataAnalysis/DataAnalysis.yjs @@ -0,0 +1,299 @@ +import "loadResource.yjs" +contract AppDataContract{ + function onCreate(arg){ + var ret = + executeContract("AppDataSource","apply","我是数据分析合约,合约名称DataAnalysis"); + print("onCreate:"+ret); + return ret; + } + export function getMainFrame(arg){ + return "/html/main.html"; + } + + export function connectDBAndQueryChengjiao(args) { + args = JSON.parse(args); + if (args["type"] == "chengjiao") { + //TODO change! + if (this.ret_chengjiao != null && this.ret_chengjiao[args["district"]] != null) { + print("find!"); + return JSON.stringify(this.ret_chengjiao[args["district"]]); + } + if (this.houselist_chengjiao == null || this.districtDict_chengjiao == null || this.bussinessDict_chengjiao == null) { + this.houselist_chengjiao = []; + var houselist = this.houselist_chengjiao; + var districtDict = { + }; + var pattern = /朝阳|西城|丰台|海淀|密云|东城|昌平|怀柔|大兴|通州|房山|石景山|平谷|顺义|延庆|门头沟/g; + var bussinessDict2 = { + }; + for (var i = 0; i < houselist.length; i++) { + var addr = houselist[i]["district"]; + var district = addr.match(pattern); + if (district == null) + continue; + district = district[0]; + if (district.length > 5) + continue; + if (districtDict[district] == null) + districtDict[district] = []; + if (bussinessDict2[district] == null) + bussinessDict2[district] = { + }; + var buss = houselist[i]["bussiness"]; + if (bussinessDict2[district][buss] == null) + bussinessDict2[district][buss] = []; + var item = {}; + if (houselist[i]["price"] == null || houselist[i]["area"] == null) + continue; + if (houselist[i]["roomNum"] == null) + continue; + var unitPrice = houselist[i]["price"].replace("挂牌", "").replace("万", ""); + unitPrice = parseInt(unitPrice); + houselist[i]["price"] = unitPrice; + item["price"] = unitPrice; + item["roomNum"] = houselist[i]["roomNum"]; + item["area"] = parseInt(houselist[i]["area"].replace("平米", "")); + houselist[i]["area"] = item["area"]; + item["district"] = houselist[i]["district"]; + item["bussiness"] = houselist[i]["bussiness"]; + item["buildingAge"] = houselist[i]["buildingAge"].replace("塔结合", "").replace("年建板", "").replace("楼", ""); + districtDict[district].push(item); + bussinessDict2[district][buss].push(item); + } + districtDict["延庆"] = []; + districtDict["怀柔"] = []; + bussinessDict2["延庆"] = { + }; + bussinessDict2["怀柔"] = { + }; + this.districtDict_chengjiao = districtDict; + var districtnames = Object.keys(districtDict); + var bussinessDict = { + }; + for (var i = 0; i < districtnames.length; i++) { + var district = districtnames[i]; + bussinessDict[district] = { + }; + var desc = function (a, b) { + return (bussinessDict2[district][a].length < bussinessDict2[district][b].length) ? 1 : -1; + }; + var bussnames = (Object.keys(bussinessDict2[district])).sort(desc); + var len = bussnames.length; + if (len > 20) + len = 20; + for (j = 0; j < len; j++) { + bussinessDict[district][bussnames[j]] = bussinessDict2[district][bussnames[j]]; + } + } + this.bussinessDict_chengjiao = bussinessDict; + } + var houselist = this.houselist_chengjiao; + var districtDict = this.districtDict_chengjiao; + var bussinessDict = this.bussinessDict_chengjiao; + var districtkeys = Object.keys(districtDict); + var fig1 = []; + for (var j = 0; j < districtkeys.length; j++) { + var key = districtkeys[j]; + var item = { + } + var name = key + "区"; + if (key == "延庆" || key == "密云") + name = key + "县"; + item["name"] = name; + item["value"] = { + }; + item["value"]["num"] = districtDict[key].length; + var sumPrice = 0; + for (var i = 0; i < districtDict[key].length; i++) { + if (districtDict[key][i]["price"] >= 0 && districtDict[key][i]["price"] <= 10000000) + sumPrice += districtDict[key][i]["price"]; + } + var avgPrice = 0; + if (districtDict[key].length > 0) { + avgPrice = sumPrice / districtDict[key].length; + } + item["value"]["avgPrice"] = avgPrice.toFixed(2); + fig1.push(item); + } + var houselist2 = houselist; + if (args["district"] != "" && districtDict[args["district"]] != null) { + houselist2 = districtDict[args["district"]]; + } + var fig2 = []; + var priceInterval = ["<200w", "200-400w", "400-600w", "600-800w", "800-1000w", ">1000w"]; + var houseNum = [0, 0, 0, 0, 0, 0, 0]; + for (var i = 0; i < houselist2.length; i++) { + if (houselist2[i]["price"] < 200) { + houseNum[0] += 1; + } + if (houselist2[i]["price"] >= 200 && houselist2[i]["price"] < 400) { + houseNum[1] += 1; + } + if (houselist2[i]["price"] >= 400 && houselist2[i]["price"] < 600) { + houseNum[2] += 1; + } + if (houselist2[i]["price"] >= 600 && houselist2[i]["price"] < 800) { + houseNum[3] += 1; + } + if (houselist2[i]["price"] >= 800 && houselist2[i]["price"] < 1000) { + houseNum[4] += 1; + } + if (houselist2[i]["price"] >= 1000) { + houseNum[5] += 1; + } + } + var cnt = 0; + for (var i = 0; i < priceInterval.length; i++) { + var item = { + }; + cnt += houseNum[i]; + item["name"] = priceInterval[i]; + item["value"] = cnt; + fig2.push(item); + } + var districtDict2 = districtDict; + if (args["district"] != "" && districtDict[args["district"]] != null) { + districtDict2 = bussinessDict[args["district"]]; + districtkeys = Object.keys(bussinessDict[args["district"]]); + } + var fig3 = []; + var tmpList = []; + var desc = function (x, y) { + return (x["value"] < y["value"]) ? 1 : -1; + } + for (var i = 0; i < districtkeys.length; i++) { + var item = { + "name": districtkeys[i]}; + item["value"] = districtDict2[districtkeys[i]].length; + if (item["value"] >= 0 && item["value"] < 10000000000) + tmpList.push(item); + } + tmpList.sort(desc); + var len = tmpList.length; + if (len > 50) len = 50; + for (var i = 0; i < len; i++) { + fig3.push(tmpList[i]); + } + var fig4 = []; + var roomTypeName = ["一居", "二居", "三居", "四居及以上"]; + var areaSizeName = ["50m2以下", "50-80m2", "80-110m2", "110-150m2", "150-300m2", ">300m2"]; + var priceName = ["<200w", "200-400w", "400-600w", "600-800w", "800-1000w", ">1000w"]; + var yearName = ["<5年", "5-10年", "10-15年", "15-20年", "20-30年", ">30年"]; + for (var k = 0; k < districtkeys.length; k++) { + var district = districtkeys[k]; + var districtItem = { + "name": district}; + districtItem["value"] = { + "roomType": [], "areaSize": [], "price": [], "age": []}; + var roomTypeNum = [0, 0, 0, 0]; + var areaSizeNum = [0, 0, 0, 0, 0, 0]; + var priceNum = [0, 0, 0, 0, 0, 0]; + var yearNum = [0, 0, 0, 0, 0, 0]; + for (var j = 0; j < districtDict2[district].length; j++) { + var house = districtDict2[district][j]; + var flag = false; + if (house["roomNum"].match("1室") != null) { + roomTypeNum[0] += 1; + flag = true; + } + if (house["roomNum"].match("2室") != null) { + roomTypeNum[1] += 1; + flag = true; + } + if (house["roomNum"].match("3室") != null) { + roomTypeNum[2] += 1; + flag = true; + } + if (flag == false) { + roomTypeNum[3] += 1; + } + if (house["area"] < 50) + areaSizeNum[0] += 1; + if (house["area"] >= 50 && house["area"] < 80) + areaSizeNum[1] += 1; + if (house["area"] >= 80 && house["area"] < 110) + areaSizeNum[2] += 1; + if (house["area"] >= 110 && house["area"] < 150) + areaSizeNum[3] += 1; + if (house["area"] >= 150 && house["area"] < 300) + areaSizeNum[4] += 1; + if (house["area"] >= 300) + areaSizeNum[5] += 1; + if (house["price"] < 200) + priceNum[0] += 1; + if (house["price"] >= 200 && house["price"] < 400) + priceNum[1] += 1; + if (house["price"] >= 400 && house["price"] < 800) + priceNum[2] += 1; + if (house["price"] >= 800 && house["price"] < 1000) + priceNum[3] += 1; + if (house["price"] >= 1000) + priceNum[4] += 1; + var age = 2019 - house["buildingAge"]; + if (age < 5) + yearNum[0] += 1; + if (age >= 5 && age < 10) + yearNum[1] += 1; + if (age >= 10 && age < 15) + yearNum[2] += 1; + if (age >= 15 && age < 20) + yearNum[3] += 1; + if (age >= 20 && age < 30) + yearNum[4] += 1; + if (age >= 30) + yearNum[5] += 1; + } + for (var i = 0; i < roomTypeName.length; i++) { + var item = { + }; + item["name"] = roomTypeName[i]; + item["value"] = roomTypeNum[i]; + districtItem["value"]["roomType"].push(item); + } + for (var i = 0; i < areaSizeName.length; i++) { + var item = { + }; + item["name"] = areaSizeName[i]; + item["value"] = areaSizeNum[i]; + districtItem["value"]["areaSize"].push(item); + } + for (var i = 0; i < priceNum.length; i++) { + var item = { + }; + item["name"] = priceName[i]; + item["value"] = priceNum[i]; + districtItem["value"]["price"].push(item); + } + for (var i = 0; i < yearNum.length; i++) { + var item = { + }; + item["name"] = yearName[i]; + item["value"] = yearNum[i]; + districtItem["value"]["age"].push(item); + } + fig4.push(districtItem); + } + if (this.ret_chengjiao == null) + this.ret_chengjiao = { + }; + var res = { + }; + res["fig1"] = fig1; + res["fig2"] = fig2; + res["fig3"] = fig3; + res["fig4"] = fig4; + if (this.ret_chengjiao[args["district"]] == null) + this.ret_chengjiao[args["district"]] = res; + return JSON.stringify(res); + } + else + return null; + } + export function connectDBAndQuery(args) { + print("args:" + args); + var result = executeContract("AppDataSource","connectDBAndQuery",args); + var obj = JSON.parse(result); + print(result); + return obj.result; + } +} diff --git a/contracts/AppDataAnalysis/html/main.html b/contracts/AppDataAnalysis/html/main.html new file mode 100644 index 0000000..04158cd --- /dev/null +++ b/contracts/AppDataAnalysis/html/main.html @@ -0,0 +1,16 @@ +