initial commit

This commit is contained in:
CaiHQ 2021-09-26 13:01:04 +08:00
parent ec08043ed3
commit eebbe9d791
78 changed files with 8028 additions and 18 deletions

30
.gitignore vendored
View File

@ -1,18 +1,12 @@
# Build and Release Folders
bin-debug/
bin-release/
[Oo]bj/
[Bb]in/
# Other files and folders
.settings/
# Executables
*.swf
*.air
*.ipa
*.apk
# Project files, i.e. `.project`, `.actionScriptProperties` and `.flexProperties`
# should NOT be excluded as they contain compiler settings and other important
# information for Eclipse / Flash Builder.
/NodeCenterDB/
/ssl
/rocksdb
/repoConf.json
/ncFile.txt
/handleRecords/*
/handleRecords
/router-frontend/WebContent/client
/router-frontend/WebContent/client/
/log
/ncconfig.json*
/WebContent

15
Dockerfile Normal file
View File

@ -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 /bdcluster
WORKDIR /bdcluster
VOLUME /bdcluster/NodeCenterDB /bdcluster/rocksdb
ENTRYPOINT ["java"]
CMD ["-Dfile.encoding=UTF-8", "-cp", "./libs/*:bdcluster.jar", "org.bdware.server.NodeCenterServer", "-service-port=21040", "-do-repo-ip=localhost","-do-repo-port=21042", "-enable-ssl=./ssl/chained.pem:./ssl/domain.pem"]

6
README.md Normal file
View File

@ -0,0 +1,6 @@
## Docker镜像制作
把`Dockerfile`放到一个目录,同时把编译好的`bdcluster.zip`放到同一目录,并解压、制作镜像:
```
unzip -d ./bdserver/ bdcluster.zip
docker build -t bdware/bdcluster .
```

121
build.gradle Normal file
View File

@ -0,0 +1,121 @@
plugins {
id 'java'
id 'application'
}
mainClassName = 'org.bdware.server.NodeCenterServer'
application {
mainClass = mainClassName
applicationDefaultJvmArgs = ['-Dfile.encoding=UTF-8']
}
dependencies {
implementation project(":front-base")
// https://mvnrepository.com/artifact/com.jianggujin/IKAnalyzer-lucene
implementation 'com.jianggujin:IKAnalyzer-lucene:8.0.0'
// https://mvnrepository.com/artifact/org.apache.lucene/lucene-core
implementation 'org.apache.lucene:lucene-core:8.9.0'
// https://mvnrepository.com/artifact/org.apache.lucene/lucene-queryparser
implementation 'org.apache.lucene:lucene-queryparser:8.9.0'
// https://mvnrepository.com/artifact/org.apache.lucene/lucene-analyzers-common
implementation 'org.apache.lucene:lucene-analyzers-common:8.9.0'
// https://mvnrepository.com/artifact/org.apache.lucene/lucene-backward-codecs
implementation 'org.apache.lucene:lucene-backward-codecs:8.9.0'
implementation 'org.apache.lucene:lucene-analyzers-smartcn:8.9.0'
testImplementation 'junit:junit:4.13.2'
}
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.dependsOn(":web-client:copyToCluster")
tasks.processResources.setDuplicatesStrategy(DuplicatesStrategy.INCLUDE)
task copyScript(type: Copy) {
from("../script/") {
include 'ncstart.sh'
include 'ncstop.sh'
include 'ncconfig.json.template'
include 'updateCluster.sh'
}
into "./build/output"
println("copyScript done !")
}
task copySsl(type: Copy) {
from './ssl'
into './build/output/ssl'
}
task copyLibs(type: Copy, dependsOn: ["copyScript", 'copySsl']) {
from configurations.runtimeClasspath
into "./build/output/libs/"
}
//task copyJar(type: Exec, dependsOn: [":front-cluster:jar", ":front-cluster:copyLibs"]) {
// println("copyJar start")
// commandLine "cp", "./build/libs/$project.name-$version" + ".jar", "./build/output/bdcluster.jar"
//}
task copyJar(type: Copy, dependsOn: [":front-cluster:jar", ":front-cluster:copyLibs"]) {
from "./build/libs/$project.name-${project.version}.jar"
into "./build/output"
rename { String fileName -> "bdcluster.jar" }
doFirst {
println "copyJar start"
}
}
task copyWebContent(type: Copy) {
from("./WebContent") {
exclude 'client/BaaSClient.html'
exclude 'client/README.md'
exclude 'client/.idea/'
exclude 'client/.gitignore'
exclude '.idea/'
}
into "./build/output/WebContent"
}
task buildBDServerClusterZip(type: Zip, dependsOn: [":front-cluster:copyWebContent", ":front-cluster:copyScript",
":front-cluster:copyJar"]) {
from './build/output/'
duplicatesStrategy = DuplicatesStrategy.INCLUDE
archiveFileName = 'bdserver-cluster.zip'
destinationDirectory = file('build/')
}
task buildBDClusterZip(type: Zip, dependsOn: [":front-cluster:buildBDServerClusterZip"]) {
from('./build/output/') {
include("libs/*")
include("bdcluster.jar")
}
duplicatesStrategy = DuplicatesStrategy.INCLUDE
archiveFileName = 'bdcluster.zip'
destinationDirectory = file('build/')
}
task buildWebContentZip(type: Zip, dependsOn: [":front-cluster:copyWebContent"]) {
from "./build/output/WebContent"
duplicatesStrategy = DuplicatesStrategy.INCLUDE
archiveFileName = 'ClusterWebContent.zip'
destinationDirectory = file('build/')
}
task buildBundle(dependsOn: [":front-cluster:buildBDClusterZip", ":front-cluster:buildWebContentZip"]) {
doLast {
println "buildBundle in ./build/output/ successfully"
}
}

View File

@ -0,0 +1,86 @@
package org.bdware.sc.udp;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class UDPMessage implements Serializable {
private static final long serialVersionUID = -8103830946473687985L;
int isPart = 0;
public UDPMessageType type;
public int id; // 要标记sender
int order;
int requestID;
byte[] content;
public UDPMessage() {
}
public void setIsPart(boolean isPart) {
this.isPart = isPart ? 1 : 0;
}
public void setContent(byte[] content) {
this.content = content;
}
public byte[] getContent() {
return content;
}
static int Len = 6000;// 1000
public List<UDPMessage> split() {
List<UDPMessage> splited = new ArrayList<>();
// System.out.println("[UDPMessage split] content.length" + content.length);
if (content.length < Len) {
splited.add(this);
return splited;
}
for (int i = 0; i < content.length; i += Len) {
UDPMessage msg = new UDPMessage();
msg.isPart = 1;
msg.id = this.id;
msg.order = i / Len;
if (i + Len > content.length) {
msg.content = new byte[content.length - i];
System.arraycopy(content, i, msg.content, 0, content.length - i);
} else {
msg.content = new byte[Len];
System.arraycopy(content, i, msg.content, 0, Len);
}
splited.add(msg);
}
return splited;
}
public byte[] toByteArray() {
try {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream output;
output = new ObjectOutputStream(bo);
output.writeObject(this);
return bo.toByteArray();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static UDPMessage parse(byte[] data, int len) {
try {
ByteArrayInputStream bi = new ByteArrayInputStream(data);
ObjectInputStream input = new ObjectInputStream(bi);
return (UDPMessage) input.readObject();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}

View File

@ -0,0 +1,7 @@
package org.bdware.sc.udp;
import java.io.Serializable;
public enum UDPMessageType implements Serializable {
shakeHand, request, reply
}

View File

@ -0,0 +1,20 @@
package org.bdware.sc.udp;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import org.bdware.sc.conn.Node;
public class UDPNode extends Node {
public UDPNode(SocketAddress addr) {
this.addr = addr;
}
public int id;
public long lastUpdatedTime;
public SocketAddress addr;
public String getAddr() {
InetSocketAddress inet4 = (InetSocketAddress) addr;
return inet4.getHostString() + ":" + inet4.getPort();
}
}

View File

@ -0,0 +1,207 @@
package org.bdware.server;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.Channel;
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.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.ssl.OptionalSslHandler;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.stream.ChunkedWriteHandler;
import org.apache.commons.io.FileUtils;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.config.Configurator;
import org.bdware.sc.DoConfig;
import org.bdware.sc.db.KeyValueDBUtil;
import org.bdware.sc.db.MultiIndexTimeRocksDBUtil;
import org.bdware.server.irp.LocalLHSProxy;
import org.bdware.server.nodecenter.*;
import org.bdware.server.ws.DelimiterCodec;
import java.io.File;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
public class NodeCenterServer {
public static final String PATH = "/NodeCenterWS";
private static final String CONFIG_PATH = "ncconfig.json";
private static final Logger LOGGER = LogManager.getLogger(NodeCenterServer.class);
public static MultiIndexTimeRocksDBUtil nodeHttpLogDB =
new MultiIndexTimeRocksDBUtil("./NodeCenterDB", NCTables.NodeHttpLog.toString());
public static MultiIndexTimeRocksDBUtil nodeTcpLogDB =
new MultiIndexTimeRocksDBUtil("./NodeCenterDB", NCTables.NodeTcpLog.toString());
public static ExecutorService threadPool;
public static ScheduledExecutorService scheduledThreadPool =
Executors.newScheduledThreadPool(8);
static SslContext sslContext = null;
// static byte[] delimiter = "wonbifoodie".getBytes();
static {
KeyValueDBUtil.setupNC();
//TimeDBUtil.setupNC();
Configurator.setLevel(
"io.netty.handler.codec.http.websocketx.WebSocket08FrameDecoder",
Level.OFF);
Configurator.setLevel(
"io.netty.handler.codec.http.websocketx.WebSocket08FrameEncoder",
Level.OFF);
}
public static void parseConf(CMDConf cmdConf) {
LocalLHSProxy.port = cmdConf.doipPort;
LocalLHSProxy.enabled = true;
if (cmdConf.disableDoRepo) {
DoConfig.callContractUsingDOI = false;
}
if (cmdConf.disableLocalLhs) {
LocalLHSProxy.enabled = false;
}
if (!cmdConf.enableSsl.isEmpty()) {
try {
String[] filePaths = cmdConf.enableSsl.split(":");
File chainedFile = new File(filePaths[0]), keyFile = new File(filePaths[1]);
if (chainedFile.exists() && keyFile.exists()) {
sslContext = SslContextBuilder.forServer(chainedFile, keyFile).build();
}
LOGGER.debug("Enable ssl, path: " + chainedFile.getPath());
} catch (Exception e) {
LOGGER.warn("Enabling SSL failed.");
e.printStackTrace();
}
}
if (cmdConf.debug != null) {
if (!cmdConf.debug.isEmpty()) {
try {
String[] classes = cmdConf.debug.split(",");
for (String clz : classes) {
Configurator.setLevel(clz, Level.DEBUG);
LOGGER.warn("set debug: " + clz);
}
} catch (Exception e) {
LOGGER.warn(e.getMessage());
}
}
}
if (cmdConf.overwrite) {
cmdConf.write(CONFIG_PATH);
}
}
public static void main(String[] args) throws Exception {
File confFile = new File(CONFIG_PATH);
File confTemplate = new File(CONFIG_PATH + ".template");
if (!confTemplate.exists()) {
CMDConf conf = new CMDConf();
conf.write(confTemplate.getAbsolutePath());
}
if (!confFile.exists() && confTemplate.exists()) {
FileUtils.copyFile(confTemplate, confFile);
}
CMDConf cmf = CMDConf.parseConf(CONFIG_PATH).parseArgs(args);
parseConf(cmf);
if (LocalLHSProxy.enabled) {
threadPool = Executors.newSingleThreadExecutor();
threadPool.execute(() -> {
try {
LocalLHSProxy.start();
} catch (Exception e) {
LOGGER.error("local LHS proxy failed: " + e.getMessage());
}
});
}
listenSocket(cmf.servicePort + 1);
OtherNCProxy.instance.init();
startHttp(cmf.servicePort);
//System.out.println("PORT"+cmf.servicePort);
}
public static void listenSocket(int port) throws Exception {
LOGGER.info("listen socket at " + port);
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap b = new ServerBootstrap();
b.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 100)
.localAddress(port)
.childHandler(
new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel arg0) {
arg0.pipeline()
.addLast(new DelimiterCodec())
.addLast(new NodeCenterFrameHandler());
}
});
b.bind(port).sync().channel();
}
public static void startHttp(int port) {
LOGGER.info("start at: " + port);
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
ControlledChannelInitializer initializer = new ControlledChannelInitializer();
b.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.localAddress(port)
.childHandler(initializer);
final Channel ch = b.bind(port).sync().channel();
ch.closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
public static void start(int port) {
try {
listenSocket(port + 1);
NCUDPRunner.mainPort = port + 2;
startHttp(port);
} catch (Exception e) {
e.printStackTrace();
}
}
static class ControlledChannelInitializer extends ChannelInitializer<SocketChannel> {
NCHttpHandler handler = new NCHttpHandler();
@Override
protected void initChannel(SocketChannel arg0) {
if (sslContext != null) {
arg0.pipeline().addLast(new OptionalSslHandler(sslContext));
} else {
LOGGER.warn("disable ssl");
}
arg0.pipeline()
.addLast(new HttpServerCodec())
.addLast(new HttpObjectAggregator(65536))
.addLast(new WebSocketServerProtocolHandler(PATH, null, true))
.addLast(new ChunkedWriteHandler())
.addLast(handler)
.addLast(new NodeCenterWSFrameHandler());
}
}
}

View File

@ -0,0 +1,148 @@
package org.bdware.server.action;
import com.google.gson.reflect.TypeToken;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bdware.sc.conn.ResultCallback;
import org.bdware.sc.util.JsonUtil;
import org.bdware.server.nodecenter.CMNode;
import org.bdware.server.nodecenter.NodeCenterActions;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
public class DistributeCallback extends ResultCallback {
private static final Logger LOGGER = LogManager.getLogger(DistributeCallback.class);
String sponsorPubkey;// 发起节点的
Map<String, String> nodes;
String pubKey; //发起节点的用户公钥
String signature; // 发起节点的
int count; // 集群中几个节点已成功启动
ResultCallback res; // 返回给Node
String fileName; // ypk的文件名
int index;
String distributeID; //发起节点的分发id
public DistributeCallback(String ss, String sponID, Map<String, String> n, ResultCallback re, String p, String s) {
distributeID = ss;
count = 0;
index = 1;
this.res = re;
this.pubKey = p;
this.signature = p;
this.sponsorPubkey = sponID;
this.nodes = n;
}
// 向集群中没有合约项目的节点发送合约
public void distributeContractProject(String filePath, String isPrivate) {
LOGGER.debug("[DistributeCallback] distributeContractProject : position----5" + filePath);
File f = new File(filePath);
fileName = f.getName();
LOGGER.debug("[DistributeCallback] distributeContractProject : fileName=" + fileName);
LOGGER.debug("[DistributeCallback] nodeNames: " + JsonUtil.toJson(nodes));
for (String ID : nodes.keySet()) {
if (ID.equals(sponsorPubkey))
continue;
CMNode node = NodeCenterActions.nodeInfos.get(ID);
node.connection.sendProject(filePath, isPrivate, pubKey, this);
}
}
public void NCreceive(String progress) {
Map<String, String> ret2 = new HashMap<>();
ret2.put("action", "onDistributeContract");
ret2.put("progress", "NC is receiving ypk from sponsor,progress is " + progress + "%.");
Map<String, String> map = new HashMap<>();
map.put("action", "onDistribute");
map.put("content", JsonUtil.toJson(ret2));
map.put("distributeID", distributeID);
res.onResult(JsonUtil.toJson(map));
}
public void onDistribute(String progress) {
Map<String, String> ret2 = new HashMap<>();
ret2.put("action", "onDistributeContract");
ret2.put(
"progress",
"NC is sending ypk to NO."
+ index
+ " node in the units,progress is "
+ progress
+ "%.");
if (progress.equals("100.00")) index++;
Map<String, String> map = new HashMap<>();
map.put("action", "onDistribute");
map.put("distributeID", distributeID);
map.put("content", JsonUtil.toJson(ret2));
res.onResult(JsonUtil.toJson(map));
}
public void onReceive(Map<String, String> map) {
LOGGER.debug("[DistributeCallback] onReceive : position----9");
String progress = map.get("progress");
if (progress.equals("100")) {
Map<String, String> args = new HashMap<>();
args.put("fileName", fileName);
args.put("pubKey", pubKey);
args.put("signature", signature);
count++;
LOGGER.debug(count + "个节点已收完成" + " 总共有" + nodes.size() + " 个节点");
if (count == nodes.size()) {
// res返回给前端合约分发完成
Map<String, String> ret2 = new HashMap<>();
ret2.put("action", "onDistributeFinish");
ret2.put("progress", "100%");
Map<String, String> map_send = new HashMap<>();
map_send.put("action", "onDistribute");
map_send.put("over", "true");
map_send.put("distributeID", distributeID);
map_send.put("content", JsonUtil.toJson(ret2));
res.onResult(JsonUtil.toJson(map_send));
//NC delete file
File file = new File("./temp/stateFiles/" + fileName);
if (file.exists() && file.isFile())
file.delete();
}
}
}
@Override
public void onResult(String str) {
LOGGER.debug("[DistributeCallback] str=" + str);
Map<String, String> map = JsonUtil.fromJson(str, new TypeToken<Map<String, String>>() {
}.getType());
NodeCenterActions.sync.sleepWithTimeout(map.get("requestID"), this, 60);
String operation = map.get("operation");
switch (operation) {
case "NCreceive":
NCreceive(map.get("progress"));
break;
case "distribute":
distributeContractProject(map.get("receiveFileName"), map.get("isPrivate"));
break;
case "onDistribute":
onDistribute(map.get("progress"));
break;
case "onReceive":
onReceive(map);
break;
default:
LOGGER.debug("[DistributeCallback] undefined operation " + operation);
}
}
}

View File

@ -0,0 +1,172 @@
package org.bdware.server.action;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bdware.sc.ContractResult;
import org.bdware.sc.conn.ResultCallback;
import org.bdware.sc.util.JsonUtil;
import org.bdware.server.nodecenter.CMNode;
import org.bdware.server.nodecenter.ContractExecutor;
import org.bdware.server.nodecenter.MultiPointContractInfo;
import org.bdware.server.nodecenter.NodeCenterActions;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
public class RequestAllExecutor implements ContractExecutor {
private static final Logger LOGGER = LogManager.getLogger(RequestAllExecutor.class);
MultiPointContractInfo info;
int resultCount;
public RequestAllExecutor(MultiPointContractInfo minfo, int count) {
info = minfo;
resultCount = count;
}
public ResultCallback createResultCallback(
final String requestID, final ResultCallback originalCb, int count, String contractID) {
return new Collector(requestID, originalCb, count, contractID);
}
//only for test ADSP
// public ResultCallback createResultCallback(
// final String requestID, final ResultCallback originalCb, int count,String contractID,String seq) {
// ResultCallback collector = new Collector(requestID, originalCb, count,contractID,seq);
// return collector;
// }
public void sendRequest(String req, ResultCallback collector) {
List<String> nodes = info.members;
for (String node : nodes) {
CMNode cmNode = NodeCenterActions.nodeInfos.get(node);
if (cmNode == null) {
collector.onResult(
"{\"status\":\"Error\",\"result\":\"node "
+ node
+ " offline\",\"action\":\"onExecuteContractTrustfully\"}");
} else {
cmNode.connection.controller.sendMsg(req);
}
}
}
@Override
public void execute(String requestID, ResultCallback rc, String req) {
JsonObject jo2 = JsonParser.parseString(req).getAsJsonObject();
String id = jo2.get("contractID").getAsString();
//only for test ADSP
// ResultCallback collector = createResultCallback(requestID, rc, resultCount,id,jo2.get("seq").getAsString());
ResultCallback collector = createResultCallback(requestID, rc, resultCount, id);
//TODO NC.sync?有问题
NodeCenterActions.sync.sleep(requestID, collector);
sendRequest(req, collector);
}
static class Collector extends ResultCallback {
String contractID;
int total;
String requestID;
AtomicInteger count = new AtomicInteger(0);
//only for testADSP
// boolean flag = true; //true表示还没在文件中记录这次调用结果
// String seq;
// Map<String,Integer> res = new ConcurrentHashMap<String,Integer>();
//only for test ADSP
// public Collector(String reqID, ResultCallback callback, int c,String id,String seq2) {
// total = c;
// requestID = reqID;
// commiter = callback;
// contractID = id;
// seq = seq2;
// }
ResultCallback committer;
public Collector(String reqID, ResultCallback callback, int c, String id) {
total = c;
requestID = reqID;
committer = callback;
contractID = id;
}
@Override
public void onResult(String str) {
JsonObject obj = JsonParser.parseString(str).getAsJsonObject();
obj.remove("action");
obj.addProperty("action", "onExecuteContractTrustfully");
obj.addProperty("seqNum", count.getAndIncrement());
obj.addProperty("total", total);
//NodeCenterActions.recoverMap.get(nodePubKey).get(contractID).lastExeSeq++;
if (committer != null)
committer.onResult(obj.toString());
if (count.get() < total) {
NodeCenterActions.sync.sleepWithTimeout(requestID, this, 10);
}
String name = "null";
if (obj.has("nodeID")) {
String nodePubKey = obj.get("nodeID").getAsString();
CMNode node = NodeCenterActions.nodeInfos.get(nodePubKey);
name = node.nodeName;
}
LOGGER.debug("收到第 " + count.get() + " 个节点 " + name + " 回复 : " + obj);
if (obj.has("data")) {
String data = obj.get("data").getAsString();
ContractResult cr = JsonUtil.fromJson(data, ContractResult.class);
//only for testADSP
// if(TestADSP.getFlag()){
// String r = cr.result;
// if(!res.containsKey(r)){
// res.put(r,0);
// }
// int former = res.get(r);
// res.put(r,++former);
// for(String s : res.keySet()){
// if(res.get(s) > total / 2 && flag){
// //写入文件
// File file = new File(TestADSP.resultPath);
// synchronized (file){
// try {
// FileWriter fw = new FileWriter(file, true);
// PrintWriter pw = new PrintWriter(fw);
// pw.println(seq + " " + r);
// pw.flush();
// fw.flush();
// pw.close();
// fw.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
// flag = false;
// }
// }
// }
/* if (cr.status == ContractResult.Status.Error) { //TODO 规范Status的使用 改成 ==Statuc.Error才恢复
String nodePubKey = obj.get("nodeID").getAsString();
if(NodeCenterActions.recoverMap.containsKey(nodePubKey)){
ContractRecord record = NodeCenterActions.recoverMap.get(nodePubKey).get(contractID);
if(record.recoverFlag == RecoverFlag.Fine){
record.recoverFlag = RecoverFlag.ToRecover;
MasterActions.restartContracts(nodePubKey);
}
}
}*/
}
}
}
}

View File

@ -0,0 +1,56 @@
package org.bdware.server.action;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bdware.sc.conn.ResultCallback;
import org.bdware.server.nodecenter.CMNode;
import org.bdware.server.nodecenter.ContractExecutor;
import org.bdware.server.nodecenter.MultiPointContractInfo;
import org.bdware.server.nodecenter.NodeCenterActions;
import java.util.concurrent.atomic.AtomicInteger;
public class RequestOnceExecutor implements ContractExecutor {
private static final Logger LOGGER = LogManager.getLogger(RequestOnceExecutor.class);
MultiPointContractInfo info;
AtomicInteger order = new AtomicInteger(0);
public RequestOnceExecutor(MultiPointContractInfo minfo) {
info = minfo;
}
@Override
public void execute(String requestID, ResultCallback rc, String req) {
JsonObject jo2 = (new JsonParser()).parse(req).getAsJsonObject();
String contractID = jo2.get("contractID").getAsString();
ResultCallback cb =
new ResultCallback() {
@Override
public void onResult(String str) {
LOGGER.debug(str);
JsonObject jo = (new JsonParser()).parse(str).getAsJsonObject();
jo.remove("action");
jo.addProperty("action", "onExecuteResult");
LOGGER.debug(jo.toString());
rc.onResult(jo.toString());
}
};
NodeCenterActions.sync.sleep(requestID, cb);
for (int i = 0; i < info.members.size(); i++) {
int size = info.members.size();
String nodeID = info.members.get(order.incrementAndGet() % size);
CMNode cmNode = NodeCenterActions.nodeInfos.get(nodeID);
if (cmNode != null) {
cmNode.connection.controller.sendMsg(req);
return;
}
}
rc.onResult(
"{\"status\":\"Error\",\"result\":\"all nodes "
+ " offline\",\"action\":\"onExecuteContract\"}");
}
}

View File

@ -0,0 +1,82 @@
package org.bdware.server.action;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bdware.sc.ContractResult;
import org.bdware.sc.conn.ResultCallback;
import org.bdware.sc.util.JsonUtil;
import org.bdware.server.nodecenter.CMNode;
import org.bdware.server.nodecenter.ContractExecutor;
import org.bdware.server.nodecenter.MultiPointContractInfo;
import org.bdware.server.nodecenter.NodeCenterActions;
import java.util.concurrent.atomic.AtomicInteger;
public class ResponseOnceExecutor implements ContractExecutor {
private static final Logger LOGGER = LogManager.getLogger(ResponseOnceExecutor.class);
MultiPointContractInfo info;
AtomicInteger order = new AtomicInteger(0);
public ResponseOnceExecutor(MultiPointContractInfo minfo) {
info = minfo;
}
@Override
public void execute(String requestID, ResultCallback rc, String req) {
executeInternal(requestID, rc, req, 2);
}
private void executeInternal(String requestID, ResultCallback rc, String req, int count) {
JsonObject jo2 = (new JsonParser()).parse(req).getAsJsonObject();
String contractID = jo2.get("contractID").getAsString();
// TODO 标注失效节点是否选择重新迁移
ResultCallback cb =
new ResultCallback() {
@Override
public void onResult(String str) {
LOGGER.debug(str);
JsonObject jo = (new JsonParser()).parse(str).getAsJsonObject();
jo.remove("action");
jo.addProperty("action", "onExecuteResult");
LOGGER.debug(jo.toString());
if (jo.has("data")) {
String data = jo.get("data").getAsString();
ContractResult cr = JsonUtil.fromJson(data, ContractResult.class);
if (cr.status != ContractResult.Status.Success && count > 0) {
executeInternal(requestID, rc, req, count - 1);
} else
rc.onResult(jo.toString());
} else {
JsonObject jo2 = new JsonObject();
jo2.addProperty("action", "onExecuteResult");
jo.remove("action");
jo2.addProperty("data", jo.toString());
rc.onResult(jo2.toString());
}
}
};
NodeCenterActions.sync.sleepWithTimeout(requestID, cb, 5);
if (!sendOnce(req))
rc.onResult(
"{\"status\":\"Error\",\"data\":\"{\\\"status\\\":\\\"Error\\\",\\\"result\\\":\\\"all nodes offline\\\"}\",\"action\":\"onExecuteContract\"}");
}
private boolean sendOnce(String req) {
JsonObject jo2 = (new JsonParser()).parse(req).getAsJsonObject();
String contractID = jo2.get("contractID").getAsString();
for (int i = 0; i < info.members.size(); i++) {
int size = info.members.size();
String nodeID = info.members.get(order.incrementAndGet() % size);
CMNode cmNode = NodeCenterActions.nodeInfos.get(nodeID);
if (cmNode != null) {
cmNode.connection.controller.sendMsg(req);
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,123 @@
package org.bdware.server.irp;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bdware.sc.util.JsonUtil;
import org.rocksdb.Options;
import org.rocksdb.RocksDB;
import org.rocksdb.RocksDBException;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.net.URLDecoder;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
public class LocalLHSProxy {
private static final Logger LOGGER = LogManager.getLogger(LocalLHSProxy.class);
public static String PREFIX = "86.5000.470/";
public static int port = 18007;
public static boolean enabled = false;
public static RocksDB db;
static RegisterHandler registerHandler;
static {
RocksDB.loadLibrary();
}
public static void main(String[] args) throws Exception {
start();
}
public static void start() throws IOException, RocksDBException {
String dbPath = "./handleRecords/";
Options rockopts = new Options().setCreateIfMissing(true);
rockopts.useFixedLengthPrefixExtractor(15);
LOGGER.info("actual rocksdb path: " + new File(dbPath).getAbsolutePath());
File lock = new File(dbPath, "LOCK");
if (lock.exists()) {
LOGGER.trace("remove file " + lock.getAbsolutePath() + ": " + lock.delete());
}
db = RocksDB.open(rockopts, dbPath);
registerHandler = new RegisterHandler(db);
LOGGER.info("listen to " + port);
HttpServer server = HttpServer.create(new InetSocketAddress(port), 0);
server.createContext("/test", new TestHandler());
server.createContext("/resolve", new ResolveHandler());
server.createContext("/local/", registerHandler);
server.createContext("/view", new ViewHandler(db));
server.start();
}
private static Map<String, String> formData2Dic(String formData) {
Map<String, String> result = new HashMap<>();
if (formData == null || formData.trim().length() == 0) {
return result;
}
final String[] items = formData.split("&");
Arrays.stream(items)
.forEach(
item -> {
final String[] keyAndVal = item.split("=");
if (keyAndVal.length == 2) {
try {
final String key = URLDecoder.decode(keyAndVal[0], "utf8");
final String val = URLDecoder.decode(keyAndVal[1], "utf8");
result.put(key, val);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
});
return result;
}
static class TestHandler implements HttpHandler {
@Override
public void handle(HttpExchange exchange) {
String response = "hello world";
try {
exchange.sendResponseHeaders(200, 0);
OutputStream os = exchange.getResponseBody();
os.write(response.getBytes());
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
static class ResolveHandler implements HttpHandler {
@Override
public void handle(HttpExchange exchange) {
try {
// 获得查询字符串(get)
String queryString = exchange.getRequestURI().getQuery();
Map<String, String> queryStringInfo = formData2Dic(queryString);
String id = queryStringInfo.get("identifier");
Map<String, String> respMap;
respMap = registerHandler.handleResolve(queryStringInfo);
respMap.forEach((k, v) -> {
LOGGER.debug(k + "->" + v);
});
exchange.getResponseHeaders().add("Access-Control-Allow-Origin", "*");
exchange.sendResponseHeaders(200, 0);
OutputStream os = exchange.getResponseBody();
os.write(JsonUtil.toJson(respMap).getBytes());
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

View File

@ -0,0 +1,246 @@
package org.bdware.server.irp;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import org.apache.commons.io.IOUtils;
import org.bdware.sc.util.JsonUtil;
import org.rocksdb.RocksDB;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
public class RegisterHandler implements HttpHandler {
RocksDB db;
String dbPath = "./handleRecords/";
public RegisterHandler(RocksDB rocksDB) {
db = rocksDB;
}
public Map<String, String> HandleRequest(Map<String, String> postInfo) {
Map<String, String> respMap = new HashMap<>();
String action = postInfo.get("action");
switch (action) {
case "resolve":
respMap = handleResolve(postInfo);
break;
case "register":
case "forceRegister":
respMap = handleRegister(postInfo);
break;
case "unregister":
case "forceDelete":
respMap = handleUnRegister(postInfo);
break;
case "reregister":
respMap = handleReregister(postInfo);
break;
default:
System.out.println("error response");
}
return respMap;
}
public Map<String, String> handleRegister(Map<String, String> reqMap) {
Map<String, String> respMap = new HashMap<>();
String type;
switch (reqMap.get("hrType")) {
case "do":
type = "do.";
ViewHandler.handleRecordCount.doCount++;
break;
case "dou":
type = "dou.";
ViewHandler.handleRecordCount.userCount++;
break;
case "doip":
type = "doip.";
ViewHandler.handleRecordCount.repoCount++;
break;
default:
type = "ukw.";
break;
}
String identifier = LocalLHSProxy.PREFIX + type + geneRandomID() + "_bdw";
reqMap.remove("action");
reqMap.remove("hrType");
reqMap.put("identifier", identifier);
String handleRecord = JsonUtil.toJson(reqMap);
try {
db.put(identifier.getBytes(), handleRecord.getBytes());
System.out.println("successful update do, identifier: " + identifier);
respMap.put("identifier", identifier);
respMap.put("status", "1");
respMap.put("response", "register DO success, identifier: " + identifier);
ViewHandler.addRegister();
} catch (Exception e) {
e.printStackTrace();
respMap.put("status", "0");
respMap.put("response", "respond failed from LHS");
}
return respMap;
}
public Map<String, String> handleReregister(Map<String, String> reqMap) {
Map<String, String> respMap = new HashMap<>();
String identifier;
if (reqMap.get("identifier") != null) identifier = reqMap.get("identifier");
else {
respMap.put("status", "0");
respMap.put("response", "identifier not found");
return respMap;
}
try {
reqMap.remove("action");
reqMap.remove("hrType");
String handleRecord = JsonUtil.toJson(reqMap);
if (db.get(identifier.getBytes()) == null) {
String idType;
if ((identifier.split("/")).length > 2)
idType = identifier.split("/")[1].split("\\.")[0];
else
idType = identifier.split("\\.")[0];
switch (idType) {
case "do":
ViewHandler.handleRecordCount.doCount++;
break;
case "dou":
ViewHandler.handleRecordCount.userCount++;
break;
case "doip":
ViewHandler.handleRecordCount.repoCount++;
break;
default:
break;
}
} else {
db.delete(identifier.getBytes());
}
db.put(identifier.getBytes(), handleRecord.getBytes());
System.out.println("successful update do, identifier: " + identifier);
respMap.put("identifier", identifier);
respMap.put("status", "1");
respMap.put("response", "reRegister DO success, identifier: " + identifier);
} catch (Exception e) {
e.printStackTrace();
respMap.put("status", "0");
respMap.put("response", "unregister failed: " + e.getMessage());
}
return respMap;
}
public Map<String, String> handleUnRegister(Map<String, String> reqMap) {
Map<String, String> respMap = new HashMap<>();
String identifier;
if (reqMap.get("identifier") != null) identifier = reqMap.get("identifier");
else {
respMap.put("status", "0");
respMap.put("response", "identifier not found");
return respMap;
}
try {
switch (identifier.split("\\.")[2]) {
case "470/do":
ViewHandler.handleRecordCount.doCount--;
break;
case "470/doip":
ViewHandler.handleRecordCount.repoCount--;
break;
case "470/dou":
ViewHandler.handleRecordCount.userCount--;
break;
}
db.delete(identifier.getBytes());
respMap.put("status", "1");
respMap.put("response", "success delete: " + identifier);
ViewHandler.addDelete();
} catch (Exception e) {
e.printStackTrace();
respMap.put("status", "0");
respMap.put("response", "unregister failed: " + e.getMessage());
}
return respMap;
}
public Map<String, String> handleResolve(Map<String, String> reqMap) {
Map<String, String> respMap = new HashMap<>();
String identifier;
if (reqMap.get("identifier") != null) identifier = reqMap.get("identifier");
else {
respMap.put("status", "0");
respMap.put("response", "identifier not found");
return respMap;
}
try {
if (db.get(identifier.getBytes()) == null) {
respMap.put("status", "0");
respMap.put("response", "not exist");
return respMap;
}
String result = new String(db.get(identifier.getBytes()));
respMap = JsonUtil.fromJson(result, HashMap.class);
ViewHandler.addResolve();
} catch (Exception e) {
e.printStackTrace();
respMap.put("status", "0");
respMap.put("response", "resolve failed: " + e.getMessage());
}
return respMap;
}
public String geneRandomID() {
String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
Random random = new Random();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10; i++) {
int number = random.nextInt(62);
sb.append(str.charAt(number));
}
return sb.toString();
}
@Override
public void handle(HttpExchange exchange) throws IOException {
Map<String, String> respMap;
try {
//获得表单提交数据(post)
String postString = IOUtils.toString(exchange.getRequestBody());
Map<String, String> postInfo = formData2Dic(postString);
respMap = HandleRequest(postInfo);
exchange.sendResponseHeaders(200, 0);
OutputStream os = exchange.getResponseBody();
os.write(JsonUtil.toJson(respMap).getBytes());
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public Map<String, String> formData2Dic(String formData) {
Map<String, String> result = new HashMap<>();
if (formData == null || formData.trim().length() == 0) {
return result;
}
final String[] items = formData.split("&");
Arrays.stream(items).forEach(item -> {
final String[] keyAndVal = item.split("=");
if (keyAndVal.length == 2) {
try {
final String key = URLDecoder.decode(keyAndVal[0], "utf8");
final String val = URLDecoder.decode(keyAndVal[1], "utf8");
result.put(key, val);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
});
return result;
}
}

View File

@ -0,0 +1,11 @@
package org.bdware.server.irp;
public class StatisticsByDay {
int resolveStatics;
int deleteStatics;
int registerStatics;
public StatisticsByDay(){
registerStatics = resolveStatics = deleteStatics = 0;
}
}

View File

@ -0,0 +1,257 @@
package org.bdware.server.irp;
import com.google.gson.reflect.TypeToken;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bdware.sc.util.JsonUtil;
import org.bdware.server.NodeCenterServer;
import org.rocksdb.ReadOptions;
import org.rocksdb.RocksDB;
import org.rocksdb.RocksDBException;
import org.rocksdb.RocksIterator;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
public class ViewHandler implements HttpHandler {
public static final String STATISTICS_KEY = "STATISTICS";
public static final String COUNT_KEY = "COUNT";
private static final Logger LOGGER = LogManager.getLogger(ViewHandler.class);
public static HashMap<String, StatisticsByDay> lhsStatics = new HashMap<>();
public static HandleRecordCount handleRecordCount;
RocksDB db;
public ViewHandler(RocksDB rocksDB) throws RocksDBException {
db = rocksDB;
loadFromDB();
NodeCenterServer.scheduledThreadPool.scheduleWithFixedDelay(
() -> {
try {
saveToDB();
} catch (RocksDBException e) {
LOGGER.error("saving to DB failed! " + e.getMessage());
}
},
0,
1,
TimeUnit.SECONDS);
}
public static String getToday() {
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
Date date = new Date(System.currentTimeMillis());
return formatter.format(date);
}
public static void addResolve() {
String todayDate = ViewHandler.getToday();
if (lhsStatics.get(todayDate) == null) {
StatisticsByDay statisticsByDay = new StatisticsByDay();
statisticsByDay.resolveStatics++;
lhsStatics.put(todayDate, statisticsByDay);
} else {
lhsStatics.get(todayDate).resolveStatics++;
}
}
public static void addRegister() {
String todayDate = ViewHandler.getToday();
if (lhsStatics.get(todayDate) == null) {
StatisticsByDay statisticsByDay = new StatisticsByDay();
statisticsByDay.registerStatics++;
lhsStatics.put(todayDate, statisticsByDay);
} else {
lhsStatics.get(todayDate).registerStatics++;
}
}
public static void addDelete() {
String todayDate = ViewHandler.getToday();
if (lhsStatics.get(todayDate) == null) {
StatisticsByDay statisticsByDay = new StatisticsByDay();
statisticsByDay.deleteStatics++;
lhsStatics.put(todayDate, statisticsByDay);
} else {
lhsStatics.get(todayDate).deleteStatics++;
}
}
@Override
public void handle(HttpExchange httpExchange) throws IOException {
Map<String, Object> respMap;
try {
//获得表单提交数据(post)
String postString = httpExchange.getRequestURI().getQuery();
Map<String, String> params = formData2Dic(postString);
respMap = HandleRequest(params);
httpExchange.getResponseHeaders().add("Access-Control-Allow-Origin", "*");
httpExchange.sendResponseHeaders(200, 0);
OutputStream os = httpExchange.getResponseBody();
os.write(JsonUtil.toJson(respMap).getBytes());
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private Map<String, Object> HandleRequest(Map<String, String> postInfo) {
Map<String, Object> respMap = new HashMap<>();
String action = postInfo.get("action");
switch (action) {
case "count":
respMap = getLHSCount();
break;
case "statistics":
respMap = getLHSStatics(postInfo);
break;
default:
System.out.println("error response");
}
return respMap;
}
private void loadFromDB() throws RocksDBException {
byte[] statisticBytes = db.get(STATISTICS_KEY.getBytes());
if (statisticBytes == null) {
lhsStatics = new HashMap<>();
} else {
lhsStatics = JsonUtil.fromJson(new String(statisticBytes), new TypeToken<HashMap<String, StatisticsByDay>>() {
}.getType());
}
byte[] countBytes = db.get(COUNT_KEY.getBytes());
if (countBytes == null) {
handleRecordCount = new HandleRecordCount();
handleRecordCount.doCount = handleRecordCount.repoCount = handleRecordCount.userCount = 0;
} else {
handleRecordCount = JsonUtil.fromJson(new String(countBytes), HandleRecordCount.class);
}
}
private void saveToDB() throws RocksDBException {
String statisticStr = JsonUtil.toJson(lhsStatics);
db.put(STATISTICS_KEY.getBytes(), statisticStr.getBytes());
String countStr = JsonUtil.toJson(handleRecordCount);
db.put(COUNT_KEY.getBytes(), countStr.getBytes());
}
public Map<String, Object> getLHSStatics(Map<String, String> postInfo) {
if (postInfo.containsKey("day")) {
return getLHSStaticsWithTime(postInfo);
}
HashMap<String, Object> respMap = new HashMap<>();
for (String key : lhsStatics.keySet()) {
respMap.put(key + "", JsonUtil.toJson(lhsStatics.get(key)));
}
return respMap;
}
public Map<String, Object> getLHSStaticsWithTime(Map<String, String> postInfo) {
long day = Long.parseLong(postInfo.get("day"));
LOGGER.info(day);
List<Integer> resolve = new ArrayList<>();
List<Integer> delete = new ArrayList<>();
List<Integer> register = new ArrayList<>();
for (int i = 0; i < day; i++) {
resolve.add(0);
delete.add(0);
register.add(0);
}
long interval = 24 * 60 * 60 * 1000; //一天
long cur = System.currentTimeMillis();
long startTime = cur - day * interval;
// logger.info(JsonUtil.toJson(lhsStatics));
try {
for (String k : lhsStatics.keySet()) {
long time = new SimpleDateFormat("yyyyMMdd").parse(k).getTime();
if (time < startTime || time > cur) {
continue;
}
int index = (int) ((time - startTime) / interval);
//logger.info(index);
resolve.set(index, resolve.get(index) + lhsStatics.get(k).resolveStatics);
delete.set(index, delete.get(index) + lhsStatics.get(k).deleteStatics);
register.set(index, register.get(index) + lhsStatics.get(k).registerStatics);
}
} catch (ParseException e) {
e.printStackTrace();
}
HashMap<String, Object> respMap = new HashMap<>();
respMap.put("resolve", resolve);
respMap.put("delete", delete);
respMap.put("register", register);
return respMap;
}
public Map<String, Object> getLHSCount() {
HashMap<String, Object> respMap = new HashMap<>();
respMap.put("repoCount", String.valueOf(handleRecordCount.repoCount));
respMap.put("doCount", String.valueOf(handleRecordCount.doCount));
ReadOptions readOptions = new ReadOptions().setPrefixSameAsStart(true);
RocksIterator it1 = db.newIterator(readOptions);
ArrayList<String> doIDList = new ArrayList<>();
it1.seek("86.5000.470/do.".getBytes());
int total = 0;
while (it1.isValid() && total < 10) {
doIDList.add(new String(it1.key()));
total++;
it1.next();
}
it1.close();
RocksIterator it2 = db.newIterator(readOptions);
ArrayList<String> repoIDList = new ArrayList<>();
it2.seek("86.5000.470/doip.".getBytes());
total = 0;
while (it2.isValid() && total < 10) {
repoIDList.add(new String(it2.key()));
total++;
it2.next();
}
respMap.put("repoIDList", repoIDList);
respMap.put("doIDList", doIDList);
return respMap;
}
public Map<String, String> formData2Dic(String formData) {
Map<String, String> result = new HashMap<>();
if (formData == null || formData.trim().length() == 0) {
return result;
}
final String[] items = formData.split("&");
Arrays.stream(items).forEach(item -> {
final String[] keyAndVal = item.split("=");
if (keyAndVal.length == 2) {
try {
final String key = URLDecoder.decode(keyAndVal[0], "utf8");
final String val = URLDecoder.decode(keyAndVal[1], "utf8");
result.put(key, val);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
});
return result;
}
static class HandleRecordCount {
int repoCount;
int doCount;
int userCount;
}
}

View File

@ -0,0 +1,146 @@
package org.bdware.server.nodecenter;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bdware.sc.bean.ContractDesp;
import org.bdware.sc.db.KeyValueDBUtil;
import java.util.List;
public class CMNode {
private static final Logger LOGGER = LogManager.getLogger(CMNode.class);
// public List<ContractDesp> contracts;
public volatile List<ContractDesp> contracts; // 有路由信息
public transient NodeCenterActions connection;
public String pubKey;
public String nodeName;
public String udpID;
public String ipPort;
public int events;
public String cimanager = "";
public String peerID;
public String masterAddress; // 这个节点如果作为master的地址例如18010的这个值就是18011
public int contractVersion;
public CMNode(NodeCenterActions nodeCenterController, String pubKey) {
connection = nodeCenterController;
this.pubKey = pubKey;
}
// TODO nodeMangerPubkey
public void updateContract(List<ContractDesp> cons, int version) {
contracts = cons;
contractVersion = version;
for (ContractDesp desp : cons) {
KeyValueDBUtil.instance.setValue(
NCTables.ContractMeta.toString(), desp.contractID, desp.contractName);
}
}
public void sendEMsg(String msg) {
connection.controller.sendEMsg(msg);
}
public String formatContractName(String contractIDOrName) {
if (null != contracts) {
for (ContractDesp desp : contracts) {
if (desp.contractID.equals(contractIDOrName)
|| desp.contractName.equals(contractIDOrName)) {
return desp.contractName;
}
}
}
return null;
}
public boolean containsContract(String contractIDOrName) {
if (null != contracts) {
for (ContractDesp desp : contracts) {
if (desp.contractID.equals(contractIDOrName)
|| desp.contractName.equals(contractIDOrName)) return true;
}
}
return false;
}
public boolean containsEvent(String contractIDOrName, String event) {
if (null != contracts) {
for (ContractDesp desp : contracts) {
if (desp.contractID.equals(contractIDOrName)
|| desp.contractName.equals(contractIDOrName)) {
if (desp.events.containsKey(event)) {
return true;
}
}
}
}
return false;
}
public boolean checkAlive() {
if (null == connection) {
return false;
}
try {
if (!connection.controller.isOpen()) {
LOGGER.info("node " + nodeName + "(" + pubKey.substring(0, 5) + ") may be offline!");
// System.out.println(
// new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
// .format(new Date(System.currentTimeMillis()))
// + "[ADSP][CMNode] isAlive : "
// + nodeName
// + " not open!"
// + "\n");
return doubleCheckAlive();
} else {
return true;
}
} catch (Exception e) {
LOGGER.error("checking alive failed! " + e.getMessage());
}
return false;
}
private boolean doubleCheckAlive() {
try {
// Thread.sleep(3000L);
Thread.sleep(500L);
if (connection.controller.isOpen()) {
LOGGER.info("node " + nodeName + "(" + pubKey.substring(0, 5) + ") is online!");
return true;
}
} catch (Exception e) {
LOGGER.error("checking alive failed! " + e.getMessage());
}
LOGGER.info("node " + nodeName + "(" + pubKey.substring(0, 5) + ") may be offline!");
return false;
}
public void removeCIManager(String string) {
LOGGER.debug("removeCIManager" + string);
int start = this.cimanager.indexOf(string);
if (start > 0) {
this.cimanager =
this.cimanager
.substring(0, start)
.concat(this.cimanager.substring(start + 130));
}
}
public void addCIManager(String string) {
LOGGER.debug("addCIManager" + string);
this.cimanager = this.cimanager.concat(" " + string);
}
public void setCIManager(String string) {
this.cimanager = string;
}
public void setPeerID(String string) {
this.peerID = string;
}
public void setIpPort(String string) {
this.ipPort = string;
}
}

View File

@ -0,0 +1,7 @@
package org.bdware.server.nodecenter;
import org.bdware.sc.conn.ResultCallback;
public interface ContractExecutor {
public void execute(String requestID, ResultCallback rc, String req);
}

View File

@ -0,0 +1,15 @@
package org.bdware.server.nodecenter;
import java.util.HashMap;
import java.util.Map;
//NC
public class ElectMasterTimeRecorder {
public static Long startElect; //NC开始选举
public static Long findNewMaster; //NC选出新master
public static String newMaster;
public static Long changeMasterFinish; //新master在NC上更新路由信息
public static Map nodeFindMasterCrash = new HashMap<String,Long>(); //nodeID,electMaster调用时间
}

View File

@ -0,0 +1,186 @@
package org.bdware.server.nodecenter;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bdware.sc.conn.ResultCallback;
import org.bdware.sc.db.KeyValueDBUtil;
import org.bdware.sc.db.MultiIndexTimeDBUtilIntf;
import org.bdware.sc.util.JsonUtil;
import org.bdware.server.NodeCenterServer;
import org.bdware.server.action.Action;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
// CenterPortal的所有日志和统计数据
public class LogActions {
private static final Logger LOGGER = LogManager.getLogger(LogActions.class);
NCManagerAction managerAction;
public LogActions(NCManagerAction managerAction) {
this.managerAction = managerAction;
}
private void queryInternal(
String actResp,
MultiIndexTimeDBUtilIntf db,
JsonObject json,
ResultCallback resultCallback) {
long start = System.currentTimeMillis();
Map<String, Object> ret = new HashMap<>();
if (!json.has("start")) {
ret.put("action", actResp);
ret.put("data", new ArrayList<>());
resultCallback.onResult(JsonUtil.toJson(ret));
return;
}
long startTime = json.get("start").getAsLong();
long endTime = System.currentTimeMillis();
if (json.has("end")) {
endTime = json.get("end").getAsLong();
}
String[] category = new String[]{null};
if (json.has("category")) {
category = json.get("category").getAsString().split(",");
}
Map<String, Object> data = new HashMap<>();
for (String str : category) {
List<JsonObject> array = db.queryByDateAsJson(str, startTime, endTime);
if (str == null) data.put("primary", array);
else data.put(str, array);
}
ret.put("action", actResp);
ret.put("data", data);
if (json.has("requestID")) {
ret.put("responseID", json.get("requestID"));
}
resultCallback.onResult(JsonUtil.toJson(ret));
long end = System.currentTimeMillis();
LOGGER.debug("[queryInternal:time]" + (end - start));
}
private void countLogByCategoryInternal(
String actResp,
MultiIndexTimeDBUtilIntf db,
JsonObject json,
ResultCallback resultCallback) {
Map<String, Object> ret = new HashMap<>();
if (!json.has("start")) {
ret.put("action", actResp);
ret.put("data", new ArrayList<>());
resultCallback.onResult(JsonUtil.toJson(ret));
return;
}
long startTime = json.get("start").getAsLong();
long endTime = System.currentTimeMillis();
if (json.has("end")) {
endTime = json.get("end").getAsLong();
}
long interval = json.get("interval").getAsLong();
String[] category = new String[]{null};
if (json.has("category")) {
category = json.get("category").getAsString().split(",");
}
JsonObject data = new JsonObject();
for (String str : category) {
JsonArray array = db.countInInterval(str, startTime, interval, endTime);
if (str == null) data.add("primary", array);
else data.add(str, array);
}
ret.put("action", actResp);
ret.put("data", data);
if (json.has("requestID")) {
ret.put("responseID", json.get("requestID"));
}
resultCallback.onResult(JsonUtil.toJson(ret));
}
@Action(userPermission = 1 << 8, async = true)
public void queryActionLog(JsonObject json, ResultCallback resultCallback) {
queryInternal("onQueryActionLog", NodeCenterServer.nodeHttpLogDB, json, resultCallback);
}
@Action(userPermission = 1 << 8, async = true)
public void countActionLogByCategory(JsonObject json, ResultCallback resultCallback) {
countLogByCategoryInternal(
"onCountActionLogByCategory", NodeCenterServer.nodeHttpLogDB, json, resultCallback);
}
@Action(userPermission = 1 << 8, async = true)
public void queryCMLog(JsonObject json, ResultCallback resultCallback) {
queryInternal("onQueryCMLog", NodeCenterServer.nodeTcpLogDB, json, resultCallback);
}
@Action(userPermission = 1 << 8, async = true)
public void countCMLogByCategory(JsonObject json, ResultCallback resultCallback) {
countLogByCategoryInternal(
"onCountCMLogByCategory", NodeCenterServer.nodeTcpLogDB, json, resultCallback);
}
@Action(userPermission = 1 << 9)
public void queryUserStat(JsonObject json, ResultCallback resultCallback) {
long start = System.currentTimeMillis();
long userList = KeyValueDBUtil.instance.getCount(NCTables.NodeUser.toString());
long applylist = KeyValueDBUtil.instance.getCount(NCTables.ApplyRole.toString());
resultCallback.onResult(
"{\"action\":\"onQueryUserStat\",\"userListCount\":"
+ userList
+ ",\"applyListCount\":"
+ applylist
+ "}");
long end = System.currentTimeMillis();
LOGGER.debug("[queryUserStat:time]" + (end - start));
}
@Action(userPermission = 1 << 9, async = true)
public void listNodes(JsonObject json, ResultCallback resultCallback) {
long start = System.currentTimeMillis();
final String pubKey = managerAction.pubKey;
LOGGER.debug("[listNodes] managerAction.pubKey " + pubKey);
Map<String, CMNode> nodeinfos = NodeCenterActions.nodeInfos; // 所有在线节点?
final Map<String, CMNode> cinodeinfos = new HashMap<>();
List<String> dbnodes = KeyValueDBUtil.instance.getKeys(NCTables.NodesDB.toString());
List<CMNode> onlineNodes = new ArrayList<>();
Map<String, Object> ret = new HashMap<>();
if (KeyValueDBUtil.instance
.getValue(NCTables.ConfigDB.toString(), "__CenterManager__")
.contains(pubKey)) {
LOGGER.debug("is center manager");
LOGGER.debug("dbnodes " + dbnodes.toString());
for (CMNode node : nodeinfos.values()) {
LOGGER.debug("Offline node " + node.nodeName + node.pubKey);
if (dbnodes.contains(node.pubKey)) {
dbnodes.remove(node.pubKey);
LOGGER.debug("Delete Online node " + node.pubKey);
onlineNodes.add(node);
}
}
ret.put("action", "onListNodes");
ret.put("online", onlineNodes);
ret.put("offline", dbnodes);
resultCallback.onResult(JsonUtil.toJson(ret));
return;
}
for (Map.Entry<String, CMNode> entry : nodeinfos.entrySet()) {
LOGGER.debug("Key = " + entry.getKey() + ", Value = " + entry.getValue());
String cimanager = entry.getValue().cimanager;
if (!cimanager.contains(pubKey)) {
cinodeinfos.put(entry.getKey(), entry.getValue());
}
}
ret.put("action", "onListNodes");
ret.put("online", cinodeinfos);
ret.put("offline", new ArrayList<String>());
// 合约管理员看不到offline nodes
resultCallback.onResult(JsonUtil.toJson(ret));
long end = System.currentTimeMillis();
LOGGER.debug("[listNodes:time]" + (end - start));
}
}

View File

@ -0,0 +1,289 @@
package org.bdware.server.nodecenter;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bdware.sc.units.RequestCache;
import org.bdware.server.NodeCenterServer;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
public class MasterActions {
private static final Logger LOGGER = LogManager.getLogger(MasterActions.class);
// TODO 定期清缓存
public static Map<String, RequestCache> requestCache =
new ConcurrentHashMap<>(); // key is contractID,only for requestAll type contract
static {
NodeCenterServer.scheduledThreadPool.scheduleWithFixedDelay(
() -> {
boolean flag = clearCache();
if (flag) {
try {
Thread.sleep(10000L);
} catch (InterruptedException e) {
LOGGER.error("sleeping is interrupted! " + e.getMessage());
}
}
},
0,
0,
TimeUnit.SECONDS);
}
public NodeCenterFrameHandler controller;
public MasterActions(NodeCenterFrameHandler nodeCenterFrameHandler) {
controller = nodeCenterFrameHandler;
}
// judge the just online node whwther need to restart contracts,send the contracts'info
/* public static void restartContracts(String nodePubKey){
if(!NodeCenterActions.recoverMap.containsKey(nodePubKey)){
return;
}
System.out.println("开始恢复节点" + NodeCenterActions.nodeinfos.get(nodePubKey).nodeName);
// 恢复该节点的每一个集群运行的合约
for (ContractRecord record : NodeCenterActions.recoverMap.get(nodePubKey).values()) {
String contractID = record.contractID;
if (record.recoverFlag != RecoverFlag.ToRecover)
continue;
Map<String, String> req = new HashMap<String, String>();
req.put("action", "queryUnitStatus");
req.put("contractID", contractID);
CMNode cmNode = NodeCenterActions.nodeinfos.get(nodePubKey);
cmNode.connection.controller.sendMsg(gson.toJson(req));
}
}*/
/* @Action(async = true)
public void onQueryUnitStatus(Map<String, String> args, final ResultCallback rc) {
String mode = args.get("mode");
String nodeID = args.get("nodeID");
String contractID = args.get("contractID");
ContractRecord record = NodeCenterActions.recoverMap.get(nodeID).get(contractID);
logger.debug("节点" + NodeCenterActions.nodeinfos.get(args.get("nodeID")).nodeName + "崩溃前模式为" + mode);
if(mode.equals(ContractUnitStatus.CommonMode.toString())){
restartFromCommonMode(nodeID,record);
}else if(mode.equals(ContractUnitStatus.StableMode.toString())){
restartFromStableMode(nodeID,record);
}
}*/
// 当StableMode的节点的lastExeSeq和集群相差超过10时通过CommonNode的恢复方式恢复
/* @Action(async = true)
public void restartByCommonNode(Map<String, String> args, final ResultCallback rc){
String nodeID = args.get("nodeID");
String contractID = args.get("contractID");
ContractRecord record = NodeCenterActions.recoverMap.get(nodeID).get(contractID);
restartFromCommonMode(nodeID,record);
}*/
/*
public static void restartFromCommonMode(String nodePubKey,ContractRecord record){
logger.debug("从CommonMode中恢复:");
String contractID = record.contractID;
record.recoverFlag = RecoverFlag.Recovering;
//先发消息让恢复节点的该合约收到消息后只加入队列不dealRequests
Map<String, String> request = new HashMap<>();
request.put("action", "setRecovering");
request.put("contractID",contractID);
CMNode node = NodeCenterActions.nodeinfos.get(nodePubKey);
node.connection.controller.sendMsg(gson.toJson(request));
//System.out.println("第一步 : [NodeCeterActions] restartContracts 开始处理合约 contractID=" + contractID);
if (NodeCenterActions.contractID2Members.containsKey(contractID)) {
// 在nodeinfos中找节点该节点的pubKey在pubKeys中
MultiPointContractInfo info = NodeCenterActions.contractID2Members.get(contractID);
CMNode cmNode = null;
for (int i = 0; i < info.members.size(); i++) {
int size = info.members.size();
String tempNodeID = info.members.get(record.order.incrementAndGet() % size);
if(NodeCenterActions.nodeinfos.containsKey(tempNodeID))
cmNode = NodeCenterActions.nodeinfos.get(tempNodeID);
else continue;
//System.out.println("查询节点 " + cmNode.nodeName);
if (cmNode != null && !cmNode.pubKey.equals(nodePubKey)) {
//System.out.println("第二步 : [NodeCenterActions] 找到一个依赖恢复节点,其节点名为 " + cmNode.nodeName);
Map<String, String> req = new HashMap<String, String>();
req.put("action", "dumpCurrentState");
req.put("contractID", contractID);
req.put("targetNodePubkey", nodePubKey);
// NC向该节点发送请求让其存储自身当前状态并发给NC
cmNode.connection.controller.sendMsg(gson.toJson(req));
return;
}
}
if(cmNode == null){
logger.debug("[NodeCenterActions] Can't find a recover rely node!");
}
}
}
*/
// TODO
/* public static void restartFromStableMode(String nodePubkey,ContractRecord record){
logger.debug("从StableMode中恢复:");
String contractID = record.contractID;
record.recoverFlag = RecoverFlag.Recovering;
//先发消息让恢复节点的该合约收到消息后只加入队列不dealRequests
Map<String, String> request = new HashMap<>();
request.put("action", "setRecovering");
request.put("contractID",contractID);
request.put("mode", ContractUnitStatus.StableMode.toString());
int lastExeSeq = NodeCenterActions.contractID2Members.get(contractID).ai.get() - 1;
request.put("lastExeSeq",lastExeSeq + "");
CMNode node = NodeCenterActions.nodeinfos.get(nodePubkey);
node.connection.controller.sendMsg(gson.toJson(request));
}*/
/* public static void unitModeCheck(String contractID){
MultiPointContractInfo mpci = NodeCenterActions.contractID2Members.get(contractID);
int total = 0,online = 0;
for(String nodeId : mpci.members){
if(NodeCenterActions.nodeinfos.containsKey(nodeId)){
online++;
}
total++;
}
logger.debug("合约" + contractID + "的集群,上线节点有" + online + "个,总共节点有" + total + "个. Math.ceil(total / 2)=" + Math.ceil((double)total / 2) + " online > Math.ceil(total / 2)" + (online > Math.ceil(total / 2)) + " mpci.unitStatus=" + mpci.unitStatus);
if(online > Math.ceil((double)total / 2) && mpci.unitStatus == ContractUnitStatus.StableMode){
logger.debug("合约" + contractID + "的集群更改模式为" + ContractUnitStatus.CommonMode.toString());
Map<String, String> req = new HashMap<String, String>();
req.put("action", "changeUnitStatus");
req.put("contractID", contractID);
req.put("mode",ContractUnitStatus.CommonMode.toString());
for(String nodeId : mpci.members){
if(NodeCenterActions.nodeinfos.containsKey(nodeId)){
CMNode cmNode = NodeCenterActions.nodeinfos.get(nodeId);
logger.debug("发消息给节点 " + cmNode.nodeName + " 设置合约" + contractID + "的集群模式为CommonMode");
cmNode.connection.controller.sendMsg(gson.toJson(req));
}
}
mpci.unitStatus = ContractUnitStatus.CommonMode;
}else if(online <= Math.ceil((double)total / 2) && mpci.unitStatus == ContractUnitStatus.CommonMode){
logger.debug("合约" + contractID + "的集群更改模式为" + ContractUnitStatus.StableMode.toString());
Map<String, String> req = new HashMap<String, String>();
req.put("action", "changeUnitStatus");
req.put("contractID", contractID);
req.put("mode",ContractUnitStatus.StableMode.toString());
for(String nodeId : mpci.members){
if(NodeCenterActions.nodeinfos.containsKey(nodeId)){
CMNode cmNode = NodeCenterActions.nodeinfos.get(nodeId);
Map<String,String> map = NodeCenterActions.recoverMap.get(nodeId).get(contractID).members;
req.put("membersStr",JsonUtil.toJson(map)); //ContractRecord's members
logger.debug("发消息给节点 " + cmNode.nodeName + " 设置合约" + contractID + "的集群模式为StableMode");
cmNode.connection.controller.sendMsg(gson.toJson(req));
}
}
mpci.unitStatus = ContractUnitStatus.StableMode;
//将ContractRecord中members发给集群中节点
}
}*/
/* @Action(async = true)
public void recoverFinish(Map<String, String> args, final ResultCallback rc) {
ContractRecord cr = NodeCenterActions.recoverMap.get(args.get("nodeID")).get(args.get("contractID"));
logger.debug("节点" + NodeCenterActions.nodeinfos.get(args.get("nodeID")).nodeName + "恢复完成!");
if(cr.recoverFlag == RecoverFlag.Recovering)
cr.recoverFlag = RecoverFlag.Fine;
logger.debug("恢复完成,需要检查合约" + args.get("contractID") + "的集群运行模式");
unitModeCheck(args.get("contractID"));
}*/
static boolean clearCache() {
if (requestCache.isEmpty()) return true;
// final long time = System.currentTimeMillis() - 60000L; //60s
// requestCache.entrySet()
// .removeIf(
// entry -> {
// RequestCache cache = entry.getValue();
// if (cache == null) return true;
// return cache.getTime() < time;
// });
//
// return false;
// 对每个合约只保存最近RESERVED个请求
// for(RequestCache rc : requestCache.values()){
// int delete = rc.size() - RequestCache.RESERVED,count = 0;
// if(delete > 0){
// synchronized (rc){
// for(Iterator<Integer> iterator = rc.requests.keySet().iterator();
// iterator.hasNext(); ) {
// Integer key = iterator.next();
// if(count < delete){
// iterator.remove();
// count++;
// }
// }
// }
// }
// }
return false;
}
static RequestCache getCache(String contractID) {
if (contractID != null) {
RequestCache cache = requestCache.get(contractID);
if (cache != null) return cache;
else {
LOGGER.debug("[NodeCenterActions] create requestcache:" + contractID);
RequestCache reqc = new RequestCache();
requestCache.put(contractID, reqc);
return reqc;
}
}
return null;
}
/* @Action(async = true)
public void sendCachedRequests(Map<String, String> args, final ResultCallback rc) {
String contractID = args.get("contractID");
int start = Integer.parseInt(args.get("start"));
int end = Integer.parseInt(args.get("end"));
RequestCache cache = getCache(contractID);
for(int i = start + 1;i < end;i++){
if(cache == null || !cache.containsKey(i)){
//this node crash
String nodeID = args.get("nodeID");
MasterActions.restartContracts(nodeID);
}
JsonObject jo = cache.get(i);
if(jo == null){
logger.debug("在NC中第 " + i + "个请求已经被清,无法发给恢复节点!");
}else
controller.sendMsg(JsonUtil.toJson(jo));
logger.debug("NC发送第 " + i + " " + jo.get("seq").getAsString() + " 个请求给Node");
}
}*/
}

View File

@ -0,0 +1,553 @@
package org.bdware.server.nodecenter;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.CharArraySet;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.WordlistLoader;
import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.*;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.*;
import org.apache.lucene.store.FSDirectory;
import org.bdware.sc.bean.ContractDesp;
import org.bdware.sc.conn.ResultCallback;
import org.bdware.sc.util.JsonUtil;
import org.bdware.server.action.Action;
import org.bdware.server.nodecenter.searchresult.ContractMeta;
import org.bdware.server.nodecenter.searchresult.ResultModel;
import org.wltea.analyzer.lucene.IKAnalyzer;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
public class MetaIndexAction { // public static IndexWriter indexWriter;
private static final Logger LOGGER = LogManager.getLogger(MetaIndexAction.class);
// public static IndexSearcher indexSearcher;
// public static TopDocs topDocs;
// public static Query query;
// public static QueryParser queryParser;
// public static Analyzer analyzer;
// public static IndexWriterConfig config;
// public static List<Document> docList = new ArrayList<>();
public static FSDirectory indexDir;
public static Integer PAGE_SIZE = 10;
public static Integer page;
public static boolean isEmpty = false;
public static NodeCenterFrameHandler controller;
// public MetaIndexAction(NodeCenterFrameHandler nodeCenterFrameHandler) {
// controller = nodeCenterFrameHandler;
// }
private static IndexWriter indexWriter;
static {
initIndex();
}
private static void initIndex() {
try {
File dir = new File("./NodeCenterDB/MetaIndex");
if (!dir.exists()) {
LOGGER.info("make metaIndex dir ");
dir.mkdirs();
isEmpty = true;
}
indexDir = FSDirectory.open(Paths.get(dir.toURI()));
// Analyzer analyzer = new StandardAnalyzer();
Analyzer analyzer = new IKAnalyzer();
IndexWriterConfig config = new IndexWriterConfig(analyzer);
indexWriter = new IndexWriter(indexDir, config);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void updateContractsIndex(List<ContractDesp> contracts, ResultCallback rc)
throws IOException {
IndexReader indexReader = null;
for (ContractDesp thisDesp : contracts) {
JsonObject req = new JsonObject();
if (!isEmpty) {
try {
indexReader = DirectoryReader.open(indexDir);
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
LOGGER.debug(thisDesp.contractName + "--> try to index");
Query query = new TermQuery(new Term("contractID", thisDesp.contractID));
TopDocs docs = indexSearcher.search(query, 10);
LOGGER.debug(docs.scoreDocs);
if (null != thisDesp.contractName && (docs.scoreDocs == null || docs.scoreDocs.length == 0)) {
req.addProperty("action", "requestReadMe");
req.addProperty("contractID", thisDesp.contractID);
rc.onResult(req.toString());
LOGGER.info("contract " + thisDesp.contractName + " --> actually to index");
continue;
}
} catch (Exception e) {
LOGGER.warn("getting index failed! " + e.getMessage());
}
}
req.addProperty("action", "requestReadMe");
req.addProperty("contractID", thisDesp.contractID);
rc.onResult(req.toString());
LOGGER.info("contract " + thisDesp.contractName + " --> actually to index");
}
if (null != indexReader) {
indexReader.close();
}
}
public static String accuSearch(String keyword) {
try {
DirectoryReader indexReader = DirectoryReader.open(indexDir);
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
Term t = new Term("contractID", keyword);
Query query = new TermQuery(t);
TopDocs docs = indexSearcher.search(query, 10);
return docs.scoreDocs.length + "";
} catch (Exception e) {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
e.printStackTrace(new PrintStream(bo));
return bo.toString();
}
}
public static void delIndexbyCID(JsonObject jo) {
try {
if (!jo.has("contractID")) return;
String contractID = jo.get("contractID").getAsString();
LOGGER.info("contractID:" + contractID + "-->actually to delete");
indexWriter.deleteDocuments(new Term("contractID", contractID));
indexWriter.commit();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void delIndexbyOwner(JsonObject jo) {
try {
if (!jo.has("owner")) return;
String owner = jo.get("owner").getAsString();
LOGGER.info("owner:" + owner + "-->actually to delete");
indexWriter.deleteDocuments(new Term("owner", owner));
indexWriter.commit();
} catch (IOException e) {
e.printStackTrace();
}
}
public static String search(JsonObject searchReq) {
try {
if (!searchReq.has("searchType")) {
return "missing arguments";
}
switch (searchReq.get("searchType").getAsString()) {
case "getMetabyCID":
return getMetabyCID(searchReq);
case "getMetabyOwner":
return getMetabyOwner(searchReq);
case "getMetabyPubkey":
return getMetabyPubkey(searchReq);
case "getMetabyReadme":
return getMetabyReadme(searchReq);
default:
return "no such search type";
}
// if (searchReq != null) {
// logger.info(searchReq.get("pubkey").getAsString() + "---->start
// search");
// DirectoryReader indexReader = DirectoryReader.open(indexDir);
// IndexSearcher indexSearcher = new IndexSearcher(indexReader);
// BooleanQuery.Builder queryBuilder = new BooleanQuery.Builder();
// reandler(searchReq, queryBuilder);
// BooleanQuery searchQuery = queryBuilder.build();
// TopDocs docs = indexSearcher.search(searchQuery, 10);
// return docs.scoreDocs.length + "";
// }
// else return "0";
} catch (Exception e) {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
e.printStackTrace(new PrintStream(bo));
return bo.toString();
}
}
public static String getMetabyReadme(JsonObject jo) {
try {
if (!jo.has("keyword")) return "missing arguments: keyword";
if (!jo.has("page")) page = 1;
else page = jo.get("page").getAsInt();
if (page <= 0) page = 1;
if (jo.has("pageSize")) PAGE_SIZE = jo.get("pageSize").getAsInt();
String keyword = jo.get("keyword").getAsString();
// Analyzer analyzer = new StandardAnalyzer();
Analyzer analyzer = new IKAnalyzer();
QueryParser queryParser = new QueryParser("readmeStr", analyzer);
Query rmQuery = queryParser.parse(keyword);
DirectoryReader indexReader = DirectoryReader.open(indexDir);
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
TopDocs docs = indexSearcher.search(rmQuery, 1000);
// Document document = null ;
// if (docs.scoreDocs!=null&& docs.scoreDocs.length>0) {
// document = indexSearcher.doc(docs.scoreDocs[0].doc);
// ContractMeta contractMeta = new ContractMeta();
// contractMeta.setContractID(document.get("contractID"));
// contractMeta.setOwner(document.get("owner"));
// contractMeta.setPubkey(document.get("pubkey"));
// contractMeta.setReadmeStr(document.get("readmeStr"));
// String rs = JsonUtil.toJson(contractMeta);
// return rs;
// }
ResultModel resultModel = null;
if (docs.scoreDocs != null && docs.scoreDocs.length > 0)
resultModel = paginate(docs, indexReader);
if (resultModel != null) {
String rs = JsonUtil.toJson(resultModel);
return rs;
}
return "not found";
} catch (Exception e) {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
e.printStackTrace(new PrintStream(bo));
return bo.toString();
}
}
private static String getMetabyPubkey(JsonObject jo) {
try {
if (!jo.has("pubkey")) return "missing arguments: pubkey";
if (!jo.has("page")) page = 1;
else page = jo.get("page").getAsInt();
if (page <= 0) page = 1;
String pubkey = jo.get("pubkey").getAsString();
DirectoryReader indexReader = DirectoryReader.open(indexDir);
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
Query query = new TermQuery(new Term("pubkey", pubkey));
TopDocs docs = indexSearcher.search(query, 10);
// Document document = null;
// if (docs.scoreDocs!=null&& docs.scoreDocs.length>0) {
// document = indexSearcher.doc(docs.scoreDocs[0].doc);
// ContractMeta contractMeta = new ContractMeta();
// contractMeta.setContractID(document.get("contractID"));
// contractMeta.setOwner(document.get("owner"));
// contractMeta.setPubkey(document.get("pubkey"));
// contractMeta.setReadmeStr(document.get("readmeStr"));
// String rs = JsonUtil.toJson(contractMeta);
// return rs;
// }
ResultModel resultModel = null;
if (docs.scoreDocs != null && docs.scoreDocs.length > 0)
resultModel = paginate(docs, indexReader);
if (resultModel != null) {
String rs = JsonUtil.toJson(resultModel);
return rs;
}
return "not found";
} catch (Exception e) {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
e.printStackTrace(new PrintStream(bo));
return bo.toString();
}
}
private static String getMetabyCID(JsonObject jo) {
System.out.println("getMetabyCID" + jo.toString());
try {
if (!jo.has("contractID")) return "missing arguments: contractID";
if (!jo.has("page")) page = 1;
else page = jo.get("page").getAsInt();
if (page <= 0) page = 1;
String contractID = jo.get("contractID").getAsString();
DirectoryReader indexReader = DirectoryReader.open(indexDir);
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
Query query = new TermQuery(new Term("contractID", contractID));
TopDocs docs = indexSearcher.search(query, 10);
// Document document = null;
// if (docs.scoreDocs!=null&& docs.scoreDocs.length>0) {
// document = indexSearcher.doc(docs.scoreDocs[0].doc);
// ContractMeta contractMeta = new ContractMeta();
// contractMeta.setContractID(document.get("contractID"));
// contractMeta.setOwner(document.get("owner"));
// contractMeta.setPubkey(document.get("pubkey"));
// contractMeta.setReadmeStr(document.get("readmeStr"));
// String rs = JsonUtil.toJson(contractMeta);
// return rs;
// }
ResultModel resultModel = null;
if (docs.scoreDocs != null && docs.scoreDocs.length > 0)
resultModel = paginate(docs, indexReader);
if (resultModel != null) {
String rs = JsonUtil.toJson(resultModel);
return rs;
}
return "not found";
} catch (Exception e) {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
e.printStackTrace(new PrintStream(bo));
return bo.toString();
}
}
private static String getMetabyOwner(JsonObject jo) {
try {
if (!jo.has("owner")) return "missing arguments: owner";
if (!jo.has("page")) page = 1;
else page = jo.get("page").getAsInt();
if (page <= 0) page = 1;
if (jo.has("pageSize")) PAGE_SIZE = jo.get("pageSize").getAsInt();
String owner = jo.get("owner").getAsString();
DirectoryReader indexReader = DirectoryReader.open(indexDir);
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
Query query = new TermQuery(new Term("owner", owner));
TopDocs docs = indexSearcher.search(query, 1000);
// Document document = null;
// if (docs.scoreDocs!=null&& docs.scoreDocs.length>0) {
// document = indexSearcher.doc(docs.scoreDocs[0].doc);
// ContractMeta contractMeta = new ContractMeta();
// contractMeta.setContractID(document.get("contractID"));
// contractMeta.setOwner(document.get("owner"));
// contractMeta.setPubkey(document.get("pubkey"));
// contractMeta.setReadmeStr(document.get("readmeStr"));
// String rs = JsonUtil.toJson(contractMeta);
// return rs;
// }
ResultModel resultModel = null;
if (docs.scoreDocs != null && docs.scoreDocs.length > 0)
resultModel = paginate(docs, indexReader);
if (resultModel != null) {
String rs = JsonUtil.toJson(resultModel);
return rs;
}
return "not found";
} catch (Exception e) {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
e.printStackTrace(new PrintStream(bo));
return bo.toString();
}
}
public static void reqHandler(JsonObject req, BooleanQuery.Builder query)
throws ParseException {
if (req.get("contractID").getAsString() != null) {
query.add(
new FuzzyQuery(new Term("contractID", req.get("contractID").getAsString())),
BooleanClause.Occur.SHOULD);
}
if (req.get("owner").getAsString() != null) {
query.add(
new FuzzyQuery(new Term("owner", req.get("owner").getAsString())),
BooleanClause.Occur.SHOULD);
}
if (req.get("pubkey").getAsString() != null) {
query.add(
new PrefixQuery(new Term("pubkey", req.get("pubkey").getAsString())),
BooleanClause.Occur.SHOULD);
}
if (req.get("readmeStr").getAsString() != null) {
Analyzer analyzer = new StandardAnalyzer();
QueryParser queryParser = new QueryParser("name", analyzer);
Query rmQuery = queryParser.parse(req.get("readmeStr").getAsString());
query.add(rmQuery, BooleanClause.Occur.SHOULD);
}
}
public static ResultModel paginate(TopDocs docs, IndexReader reader) throws IOException {
ResultModel resultModel = new ResultModel();
Integer start = (page - 1) * PAGE_SIZE;
Integer end = page * PAGE_SIZE;
resultModel.setContractCount(docs.totalHits.value);
ScoreDoc[] scoreDocs = docs.scoreDocs;
List<ContractMeta> contractMetaList = new ArrayList<>();
if (scoreDocs != null) {
for (int i = start; i < scoreDocs.length && i < end; i++) {
Document document = reader.document(scoreDocs[i].doc);
ContractMeta contractMeta = new ContractMeta();
contractMeta.setContractID(document.get("contractID"));
contractMeta.setStatus(document.get("status"));
contractMeta.setOwner(document.get("owner"));
contractMeta.setPubkey(document.get("pubkey"));
contractMeta.setReadmeStr(document.get("readmeStr"));
contractMeta.setNodeAddr(document.get("nodeAddr"));
contractMeta.setPngUrl(document.get("pngUrl"));
contractMeta.setName(document.get("name"));
contractMeta.setDoi(document.get("doi"));
contractMeta.setBuildTime(Long.parseLong(document.get("buildTime")));
contractMeta.setDoip("DOIP://86.470.5000/" + document.get("name"));
contractMetaList.add(contractMeta);
}
}
resultModel.setContractMetaList(contractMetaList);
resultModel.setCurPage(page);
Long pageCount =
docs.totalHits.value % PAGE_SIZE > 0
? (docs.totalHits.value) / PAGE_SIZE + 1
: (docs.totalHits.value) / PAGE_SIZE;
resultModel.setPageCount(pageCount);
return resultModel;
}
@Action(async = true, userPermission = 1L)
public synchronized void onRequestReadMe(JsonObject json, ResultCallback rc)
throws IOException {
// try {
// Thread.sleep(2000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
CMNode node = NodeCenterActions.nodeInfos.get(controller.pubKey);
String nodeAddr = getNodeAddr(node.masterAddress);
String name = json.get("name").getAsString();
// /DOIP/Hello1/assets/logo.png
// String nodeAddr="127.0.0.1:21030";
String pngUrl = "http://" + nodeAddr + "/DOIP/" + name + "/assets/logo.png";
System.out.println(
"node.masterAddress: "
+ node.masterAddress
+ "=========="
+ "nodeAddr: "
+ nodeAddr);
System.out.println("name: " + name + "pngUrl: " + pngUrl);
String contractID = json.get("contractID").getAsString();
String status = json.get("status").getAsString();
String owner = json.get("owner").getAsString();
String pubkey = json.get("pubkey").getAsString();
String readmeStr = json.get("readmeStr").getAsString();
String doi = json.get("doi").getAsString();
String buildTime = String.valueOf(json.get("buildTime").getAsLong());
Document document = new Document();
document.add(new StringField("contractID", contractID, Field.Store.YES));
document.add(new StringField("status", status, Field.Store.YES));
document.add(new StringField("owner", owner, Field.Store.YES));
document.add(new StringField("pubkey", pubkey, Field.Store.YES));
document.add(new TextField("readmeStr", readmeStr, Field.Store.YES));
document.add(new StringField("nodeAddr", nodeAddr, Field.Store.YES));
document.add(new StringField("pngUrl", pngUrl, Field.Store.YES));
document.add(new StringField("name", name, Field.Store.YES));
document.add(new StringField("doi", doi, Field.Store.YES));
document.add(new StringField("buildTime", buildTime, Field.Store.YES));
LOGGER.info("Index Meta:" + contractID + " str:" + readmeStr);
LOGGER.info("name:" + name + "=>" + "doi:" + doi + "=>" + "buildTime:" + buildTime);
indexWriter.addDocument(document);
indexWriter.commit();
isEmpty = false;
// TODO @fanbo 更新lucene
}
private String getNodeAddr(String masterAddress) {
String[] temp = masterAddress.split(":");
temp[1] = String.valueOf(Integer.parseInt(temp[1]) - 1);
String nodeAddr = temp[0] + ":" + temp[1];
return nodeAddr;
}
@Action(async = true, userPermission = 1L)
public void getMetabyReadme(JsonObject json, ResultCallback rc) {
String result = getMetabyReadme(json);
JsonObject object = new JsonObject();
if (json.has("requestID")) object.add("responseID", json.get("requestID"));
System.out.println("zzzResult" + result);
object.add("result", JsonParser.parseString(result));
object.addProperty("action", "getMetabyReadme");
rc.onResult(object.toString());
}
@Action(async = true, userPermission = 1L)
public void segmentWord(JsonObject json, ResultCallback rc) throws IOException {
//Analyzer analyzer = new IKAnalyzer(true);
CharArraySet stopWords = CharArraySet.unmodifiableSet(WordlistLoader.getWordSet(new InputStreamReader(Objects.requireNonNull(MetaIndexAction.class.getClassLoader().getResourceAsStream(
"org/bdware/server/stopwords.txt")), StandardCharsets.UTF_8)));
Analyzer analyzer = new SmartChineseAnalyzer(stopWords);
JsonObject object = new JsonObject();
String words = "我喜欢区块链,我想试用一下这个,我是做大数据处理的,我是科技局的管理员"; // 从json拿
TokenStream stream = null;
if (json.has("requestID")) object.add("responseID", json.get("requestID"));
try {
stream = analyzer.tokenStream("myfield", words);
CharTermAttribute charTermAtt = stream.addAttribute(CharTermAttribute.class);
stream.reset();
int count = 0;
while (stream.incrementToken()) {
object.addProperty("" + count++, charTermAtt.toString());
System.out.println(charTermAtt.toString());
}
stream.end();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
rc.onResult(object.toString());
try {
stream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@Action(async = true, userPermission = 1L)
public void getMetabyCID(JsonObject json, ResultCallback rc) {
String result = getMetabyCID(json);
JsonObject object = new JsonObject();
if (json.has("requestID")) object.add("responseID", json.get("requestID"));
object.add("result", JsonParser.parseString(result));
object.addProperty("action", "getMetabyCID");
rc.onResult(object.toString());
}
@Action(async = true, userPermission = 1L)
public void getMetabyOwner(JsonObject json, ResultCallback rc) {
String result = getMetabyOwner(json);
JsonObject object = new JsonObject();
if (json.has("requestID")) object.add("responseID", json.get("requestID"));
object.add("result", JsonParser.parseString(result));
object.addProperty("action", "getMetabyOwner");
rc.onResult(object.toString());
}
@Action(async = true, userPermission = 1L)
public void getMetabyPubkey(JsonObject json, ResultCallback rc) {
String result = getMetabyPubkey(json);
JsonObject object = new JsonObject();
if (json.has("requestID")) object.add("responseID", json.get("requestID"));
object.add("result", JsonParser.parseString(result));
object.addProperty("action", "getMetabyPubkey");
rc.onResult(object.toString());
}
@Action(async = true, userPermission = 1L)
public void delIndexbyCID(JsonObject json, ResultCallback rc) {
delIndexbyCID(json);
}
@Action(async = true, userPermission = 1L)
public void delIndexbyOwner(JsonObject json, ResultCallback rc) {
delIndexbyOwner(json);
}
}

View File

@ -0,0 +1,19 @@
package org.bdware.server.nodecenter;
import org.bdware.sc.bean.ContractExecType;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
public class MultiPointContractInfo {
public List<String> members; //pubKey
public ContractExecType type;
AtomicInteger ai = new AtomicInteger();
public transient ContractExecutor rcf;
public String getNextSeq(){
System.out.println("MultiPointContractInfo获得下一个序号" + (ai.get() + 1));
return ai.getAndIncrement() + "";
}
}

View File

@ -0,0 +1,86 @@
package org.bdware.server.nodecenter;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bdware.sc.bean.OtherNCInfo;
import org.bdware.sc.conn.ResultCallback;
import org.bdware.sc.util.JsonUtil;
import org.bdware.server.action.Action;
import org.bouncycastle.crypto.CryptoException;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
import org.zz.gmhelper.SM2Util;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class NCClientActions {
private static final Logger LOGGER = LogManager.getLogger(NCClientActions.class);
private final NCClientHandler handler;
public NCClientActions(NCClientHandler h) {
handler = h;
}
@Action
public void onSessionID(JsonObject json, ResultCallback cb) {
LOGGER.info("[NCClientActions] onSessionID : ");
Map<String, String> map = new HashMap<>();
LOGGER.debug("[onSessionID]:" + json.toString());
map.put("action", "getNCConnectPermission");
map.put("id", OtherNCProxy.instance.sm2.getPublicKeyStr());
byte[] signature = "no signature".getBytes();
try {
signature = SM2Util.sign(OtherNCProxy.instance.sm2.getPrivateKeyParameter(), (OtherNCProxy.instance.sm2.getPublicKeyStr() + json.get("session").getAsString())
.getBytes());
} catch (CryptoException e) {
e.printStackTrace();
}
map.put("signature", ByteUtils.toHexString(signature));
sendMsg(JsonUtil.toJson(map));
}
@Action
public void onGetNCConnectPermission(JsonObject json, ResultCallback resultCallback) {
LOGGER.info("[NCClientActions] onGetNCConnectPermission : ");
if (json.get("data").getAsString().equals("success")) {
handler.hasPermission = true;
LOGGER.info("[NCClientActions] onGetNCConnectPermission : permission true");
}
}
@Action
public void receiveUpdate(JsonObject json, ResultCallback resultCallback) {
LOGGER.info("[NCClientActions] receiveUpdate : ");
List<OtherNCInfo> info = new ArrayList<OtherNCInfo>();
if (json.has("empty")) {
LOGGER.info("receive from NC ,do not have any cp.");
} else {
info = JsonUtil.fromJson(json.get("contracts").getAsString(), new TypeToken<List<OtherNCInfo>>() {
}.getType());
}
LOGGER.info(JsonUtil.toJson(info));
String id = json.get("id").getAsString();
OtherNCProxy.instance.updateOtherNCInfo(id, info);
String add = json.get("address").getAsString();
LOGGER.info("[NCClientActinos] close connect " + add);
OtherNCProxy.instance.connList.get(add).close();
}
public void sendMsg(String str) {
try {
handler.sendMsg(str);
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,114 @@
package org.bdware.server.nodecenter;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bdware.sc.conn.ResultCallback;
import org.bdware.sc.util.JsonUtil;
import org.bdware.server.action.ActionExecutor;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class NCClientHandler extends SimpleChannelInboundHandler<Object> {
private static final Logger LOGGER = LogManager.getLogger(NCClientHandler.class);
static ExecutorService executorService = Executors.newFixedThreadPool(5);
public boolean hasPermission; //是否在目标NC上有权限
public NCClientActions actions;
Channel channel;
ActionExecutor<ResultCallback, JsonObject> ae;
ChannelHandlerContext ctx;
private boolean isConnected;
public NCClientHandler() {
actions = new NCClientActions(this);
ae = new ActionExecutor<>(executorService, actions);
isConnected = false;
hasPermission = false;
}
@Override
public void channelActive(ChannelHandlerContext ctx) {
channel = ctx.channel();
isConnected = true;
this.ctx = ctx;
Map<String, String> getSession = new HashMap<>();
getSession.put("action", "getSessionID");
sendMsg(JsonUtil.toJson(getSession));
LOGGER.debug("[NCClientHandler] getSessionID:" + JsonUtil.toJson(getSession));
}
@Override
public void channelInactive(ChannelHandlerContext ctx) {
isConnected = false;
hasPermission = false;
try {
channel.close();
channel = null;
} catch (Exception e) {
}
}
public synchronized void sendMsg(String msg) {
channel.writeAndFlush(Unpooled.wrappedBuffer(msg.getBytes()));
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf bb = (ByteBuf) msg;
try {
final JsonObject arg =
new JsonParser()
.parse(new InputStreamReader(new ByteBufInputStream(bb)))
.getAsJsonObject();
if (arg.has("action")) {
final String action = arg.get("action").getAsString();
ae.handle(
action,
arg,
new ResultCallback() {
@Override
public void onResult(String str) {
sendMsg(str);
}
});
}
} catch (java.lang.IllegalArgumentException e) {
LOGGER.debug("[NCClientHandler] can't handle action:" + e.getMessage());
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
System.err.println("[NCClientHandler] catchException");
cause.printStackTrace();
}
public void close() {
try {
isConnected = false;
if (channel != null) channel.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
channel = null;
}
}
public boolean isOpen() {
return ctx != null && ctx.channel().isOpen();
}
}

View File

@ -0,0 +1,210 @@
package org.bdware.server.nodecenter;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bdware.sc.bean.ContractDesp;
import org.bdware.sc.util.JsonUtil;
import org.bdware.server.NodeCenterServer;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
public class NCElectMasterUtil {
public static final Map<String, ElectInfo> electInfos = new ConcurrentHashMap<>(); //key is contractID
private static final Logger LOGGER = LogManager.getLogger(NCElectMasterUtil.class);
public static class ElectInfo {
final long delay = 5000;
final AtomicBoolean startElect = new AtomicBoolean(false);
String formerMaster;
String uniNumber;
long lastTime = System.currentTimeMillis();
int onlineNum; //除旧的master之外的在线节点数
String contractID;
String mems; //执行这个合约的所有节点的pubKey
private Map<String, Integer> nodeID2LastExe = new ConcurrentHashMap<>(); //key is nodeID
private Timer timer;
public ElectInfo(String m, String con, String members, String uni) {
formerMaster = m;
contractID = con;
mems = members;
uniNumber = uni;
String[] mem = members.split(",");
/* try {
Thread.sleep(2000); //让NC发现崩溃节点
} catch (InterruptedException e) {
e.printStackTrace();
}*/
for (String memID : mem) {
if (memID == null || memID.length() == 0)
continue;
if (NodeCenterActions.nodeInfos.containsKey(memID) && !memID.equals(formerMaster)) {
onlineNum++;
}
}
NodeCenterServer.scheduledThreadPool.scheduleWithFixedDelay(
() -> {
// cancel the election if no nodes find the master's crash in delay + 2 seconds
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd.HH:mm:ss.SSS");
if (System.currentTimeMillis() - lastTime > (delay + 15000)) {
LOGGER.info("lastTime=" + df.format(lastTime) + " cancel the election");
cancel();
}
// start timeout election
// if (electInfos.containsKey(contractID) && nodeID2LastExe.size() == onlineNum) {
// elect();
// }
},
delay + 1500,
delay + 1500,
TimeUnit.MILLISECONDS);
//timer.schedule(task, dealy + 2000);
LOGGER.info("new election of contract " + contractID + " is added to electInfos, " +
onlineNum + " node is online");
}
public void cancel() {
if (timer != null) {
timer.cancel();
timer = null;
}
if (electInfos.containsKey(contractID)) {
electInfos.remove(contractID);
}
}
public synchronized void put(String nodeID, int lastExe, String master, String mem2, String uniNum) {
LOGGER.info("put nodeID=" + nodeID);
//确保该合约某时只能有一个选举,其他的选举请求被忽略
if (!master.equals(formerMaster)) {
LOGGER.debug("[NCElectMasterUtil] master error!");
return;
}
if (nodeID.equals(formerMaster)) {
LOGGER.debug("former master voted,error!");
return;
}
if (master.equals("null")) {
LOGGER.info("uniNum=" + uniNum + " uniNumber=" + uniNumber);
if (!uniNum.equals(uniNumber)) {
LOGGER.debug("already has re-elect process when master is null");
return;
}
}
long now = System.currentTimeMillis();
//认为是一个新的选举之前的作废
if (now - lastTime > delay) {
LOGGER.info("[NCElectMasterUtil] time error!");
cancel();
synchronized (electInfos) {
//electInfos.remove(contractID);
NCElectMasterUtil.electInfos.put(contractID, new ElectInfo(master, contractID, mem2, uniNum));
ElectInfo eleInfo = electInfos.get(contractID);
eleInfo.put(nodeID, lastExe, master, mem2, uniNum);
}
return;
}
lastTime = now;
nodeID2LastExe.put(nodeID, lastExe);
LOGGER.info("[ElectInfo] 加入合约 " + contractID + " 的选举信息节点" + nodeID.substring(0, 5));
if (nodeID2LastExe.size() == onlineNum) {
cancel();
elect();
}
}
public synchronized void elect() {
LOGGER.info("[ElectInfo] 开始选举");
ElectMasterTimeRecorder.startElect = System.currentTimeMillis();
synchronized (startElect) {
startElect.set(true);
}
//更新路由信息这个合约的master暂时为null
if (NodeCenterActions.nodeInfos.containsKey(formerMaster)) {
CMNode node = NodeCenterActions.nodeInfos.get(formerMaster);
if (node != null) {
synchronized (node) {
for (ContractDesp cd : node.contracts) {
if (cd.contractID.equals(contractID) || cd.contractName.equals(contractID)) {
cd.setIsMaster(false);
LOGGER.debug("设置节点 " + node.pubKey.substring(0, 5) + " 的合约 " + contractID + " isMaster=" + false);
break;
}
}
}
}
}
int maxExeSeq = Integer.MIN_VALUE;
String newMaster = "";
for (String id : nodeID2LastExe.keySet()) {
if (nodeID2LastExe.get(id) > maxExeSeq) {
newMaster = id;
}
}
LOGGER.info("[NCElectMasterUtil] 选举出新的master " + newMaster);
cancel();
//electInfos.remove(contractID);
//通知新的master让它发起重连操作并在所有节点重连成功之后开启master的恢复
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
LOGGER.info("开始计算需要连接新master的都有哪些节点:");
StringBuilder onlineMems = new StringBuilder(); //不包含旧的master
for (String memID : nodeID2LastExe.keySet()) {
if (memID == null || memID.length() == 0)
continue;
LOGGER.info("[NCElectMasterUtil] 查看节点 " + memID.substring(0, 5) + " 是否还在线");
if (NodeCenterActions.nodeInfos.containsKey(memID)) {
if (memID.equals(formerMaster))
continue;
LOGGER.info("onlineMems中加入 " + memID.substring(0, 5));
if (onlineMems.toString().equals("")) {
onlineMems = new StringBuilder(memID);
} else {
onlineMems.append(",");
onlineMems.append(memID);
}
}
}
ElectMasterTimeRecorder.findNewMaster = System.currentTimeMillis();
ElectMasterTimeRecorder.newMaster = newMaster;
LOGGER.info("通知新的master让它发起重连操作 " + onlineMems);
CMNode masterNode = NodeCenterActions.nodeInfos.get(newMaster);
Map<String, String> req = new HashMap<>();
req.put("action", "newMasterStart");
req.put("members", mems);
req.put("onlineMems", onlineMems.toString());
req.put("contractID", contractID);
req.put("formerMaster", formerMaster);
masterNode.connection.controller.sendMsg(JsonUtil.toJson(req));
}
}
}

View File

@ -0,0 +1,330 @@
package org.bdware.server.nodecenter;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bdware.sc.conn.ResultCallback;
import org.bdware.sc.db.KeyValueDBUtil;
import org.bdware.sc.util.ExceptionUtil;
import org.bdware.sc.util.JsonUtil;
import org.bdware.server.NodeCenterServer;
import org.bdware.server.action.Action;
import org.bdware.server.action.ActionExecutor;
import org.bdware.server.action.HttpResultCallback;
import org.bdware.server.http.HttpFileHandleAdapter;
import org.bdware.server.http.URIHandler;
import org.bdware.server.http.URIPath;
import org.bdware.server.permission.Role;
import org.zz.gmhelper.SM2Util;
import java.io.*;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import static io.netty.handler.codec.http.HttpResponseStatus.OK;
@Sharable
public class NCHttpHandler extends SimpleChannelInboundHandler<HttpObject> {
private static final String PARAM_ACTION = "action";
private static final String UNSUPPORTED_HTTP_METHOD = "{\"msg\":\"unsupported http method\"}";
private static final String UNSUPPORTED_ACTION = "{\"msg\":\"unsupported action\"}";
private static final Logger LOGGER = LogManager.getLogger(NCHttpHandler.class);
private static final ActionExecutor<ResultCallback, JsonObject> actionExecutor =
new ActionExecutor<ResultCallback, JsonObject>(
NodeCenterFrameHandler.executorService, new NodeCenterActions(null)) {
@Override
public boolean checkPermission(Action a, JsonObject arg, long per) {
boolean flag = a.httpAccess();
long val = a.userPermission(); // 使用者必须达到的permission
long permission = arg.get("permission").getAsLong();
LOGGER.debug("permission" + permission);
LOGGER.debug("htttttttttttttp--userpermission:" + val);
LOGGER.debug("htttttttttttttp--permission:" + per); // 现有的permission
boolean flag2 = false; // 启动http权限后应改为false
String status = "refuse";
String action = arg.get("action").getAsString();
if (val == 0) {
flag2 = true;
} else {
flag2 = (permission & val) == val;
}
if (flag && flag2) {
status = "accept";
}
String pubkey = "anonymity";
if (arg.has("pubKey")) {
pubkey = arg.get("pubKey").getAsString();
}
NodeCenterServer.nodeHttpLogDB.put(
action,
"{\"action\":\""
+ action
+ "\",\"pubKey\":\""
+ pubkey
+ "\",\"date\":"
+ System.currentTimeMillis()
+ "}");
LOGGER.debug("[NCHttpHandler] flag = " + flag + " flag2 = " + flag2);
return flag && flag2;
}
};
static TypeToken<Map<String, String>> token = new TypeToken<Map<String, String>>() {};
private final HttpFileHandleAdapter fileAdapter;
// public static ExecutorService executor = Executors.newFixedThreadPool(5);
public AtomicInteger counter = new AtomicInteger(0);
private URIHandler handler;
public NCHttpHandler() {
FileFilter fileFilter = pathname -> !pathname.getAbsolutePath().contains("..");
fileAdapter =
new HttpFileHandleAdapter(new File("./WebContent/").getAbsolutePath(), fileFilter) {
@URIPath("/")
public void loadFile(ChannelHandlerContext ctx, FullHttpRequest req)
throws Exception {
super.channelRead0(ctx, req);
}
};
handler = new URIHandler();
handler.register(this);
handler.register(fileAdapter);
handler.printURIHandlers();
}
public static ActionExecutor<ResultCallback, JsonObject> getActionExecutor() {
return actionExecutor;
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) {
ctx.flush();
}
@URIPath({"/NodeCenter", "/SCIDE/SCExecutor", "/SCIDE/CMManager", "/SCIDE/SCManager"})
public void parseGetAndHandle(ChannelHandlerContext ctx, FullHttpRequest req) {
QueryStringDecoder decoderQuery = new QueryStringDecoder(req.uri());
Map<String, List<String>> params = decoderQuery.parameters();
JsonObject map = new JsonObject();
for (String key : params.keySet()) {
List<String> val = params.get(key);
if (val != null) map.addProperty(key, val.get(0));
}
String uri = URLDecoder.decode(req.uri()).split("\\?")[1];
int index = uri.lastIndexOf('&');
String str = uri;
if (index != -1) {
str = uri.substring(0, index);
}
injectPermission(map, str);
handleReq(map, ctx);
}
@URIPath(
method = org.bdware.server.http.HttpMethod.POST,
value = {"/NodeCenter", "/SCIDE/SCExecutor", "/SCIDE/CMManager", "/SCIDE/SCManager"})
public void parsePostAndHandle(ChannelHandlerContext ctx, FullHttpRequest req)
throws UnsupportedEncodingException {
ByteBuf content = req.content();
JsonObject map =
JsonParser.parseReader(new InputStreamReader(new ByteBufInputStream(content)))
.getAsJsonObject();
// FIXME 感觉不太对劲
String uri = URLDecoder.decode(req.uri(), "utf-8").split("\\?")[1];
int index = uri.lastIndexOf('&');
String str = uri;
if (index != -1) {
str = uri.substring(0, index);
}
injectPermission(map, str);
handleReq(map, ctx);
}
private JsonObject parseArgInQuery(FullHttpRequest request) {
QueryStringDecoder decoderQuery = new QueryStringDecoder(request.uri());
Map<String, List<String>> parameters = decoderQuery.parameters();
JsonObject transformedParam = new JsonObject();
for (String key : parameters.keySet()) {
List<String> val = parameters.get(key);
if (val != null) transformedParam.addProperty(key, val.get(0));
}
return transformedParam;
}
@URIPath(
method = org.bdware.server.http.HttpMethod.GET,
value = {"/doip"})
public void handleDOIP(ChannelHandlerContext ctx, FullHttpRequest req) {
ByteBuf content = req.content();
JsonObject map = parseArgInQuery(req);
// FIXME 感觉不太对劲
String uri = URLDecoder.decode(req.uri()).split("\\?")[1];
int index = uri.lastIndexOf('&');
String str = uri;
if (index != -1) {
str = uri.substring(0, index);
}
injectPermission(map, str);
DefaultFullHttpResponse response =
new DefaultFullHttpResponse(
HttpVersion.HTTP_1_1,
OK,
Unpooled.wrappedBuffer(MetaIndexAction.search(map).getBytes()));
ChannelFuture f = ctx.write(response);
f.addListener(ChannelFutureListener.CLOSE);
// TODO @fanbo Http查询接口需支持各类查询按owner/按关键词/....
}
@Override
public void channelRead0(ChannelHandlerContext ctx, HttpObject msg) {
// logger.debug("[NCHttpHandler] TID:" + Thread.currentThread().getId() +
// msg.toString());
if (msg instanceof FullHttpRequest) {
FullHttpRequest request = (FullHttpRequest) msg;
handler.handle(ctx, request);
}
}
public String getRole(String pubKey) {
try {
String ret =
KeyValueDBUtil.instance.getValue(
NCTables.ConfigDB.toString(), "__CenterManager__");
if (ret != null && ret.length() > 0) {
boolean isCenterManager = (ret.equals(pubKey)); // 表示此节点是否是平台管理员
ret = KeyValueDBUtil.instance.getValue(NCTables.NodeUser.toString(), pubKey);
String role = "";
if (isCenterManager) {
role = "CenterManager,";
}
if (null != ret && !ret.isEmpty()) {
role += ret;
}
if (role.endsWith(",")) {
role = role.substring(0, role.length() - 1);
} else if (role.isEmpty()) {
role = Role.Anonymous.name();
}
return role;
}
return Role.Anonymous.name();
} catch (Exception e) {
e.printStackTrace();
return Role.Anonymous.name();
}
}
private void injectPermission(JsonObject map, String str) {
if (map.has("pubKey")) {
String pubkey = map.get("pubKey").getAsString();
boolean verify = SM2Util.plainStrVerify(pubkey, str, map.get("sign").getAsString());
LOGGER.debug("[CMHttpHandler] HTTP POST 请求验签为 " + verify);
if (verify) {
// 查permission
String ret = getRole(pubkey);
long permission;
if (ret != null && ret.length() > 0) {
permission = 0x86000d41L | Role.compoundValue(ret.split(","));
} else {
permission = Role.compoundValue(ret.split(","));
}
map.addProperty("permission", permission + "");
LOGGER.debug("[CMHttpHandler] http 请求查看用户权限为 : " + permission);
} else {
map.addProperty("permission", 0 + "");
}
} else {
map.addProperty("permission", 0 + "");
}
}
private void handleReq(final JsonObject map, final ChannelHandlerContext ctx) {
try {
map.addProperty("fromHttp", "true");
String ret = null;
String action = null;
if (!map.has("action")) {
ret = UNSUPPORTED_ACTION;
} else {
action = map.get("action").getAsString();
}
if (action != null) {
HttpResultCallback cb;
if (action.equals("takeScreenshot")) {
cb = new HttpResultCallback(ctx, map.get("callback").getAsString());
cb.setDecodeBase64();
cb.addHeader("Content-type", "image/png");
} else if (action.equals("executeContract")) {
cb = new HttpResultCallback(ctx, map.get("callback").getAsString());
cb.addHeader("charset", "utf-8");
cb.addHeader("Content-type", "text/plain");
} else {
if (map.has("callback"))
cb = new HttpResultCallback(ctx, map.get("callback").getAsString());
else cb = new HttpResultCallback(ctx, null);
cb.addHeader("charset", "utf-8");
cb.addHeader("Content-type", "application/json");
}
actionExecutor.handle(action, map, cb);
} else {
DefaultFullHttpResponse response =
new DefaultFullHttpResponse(
HttpVersion.HTTP_1_1, OK, Unpooled.wrappedBuffer(ret.getBytes()));
ChannelFuture f = ctx.write(response);
f.addListener(ChannelFutureListener.CLOSE);
}
} catch (IllegalArgumentException e) {
DefaultFullHttpResponse response =
new DefaultFullHttpResponse(
HttpVersion.HTTP_1_1,
OK,
Unpooled.wrappedBuffer(e.getMessage().getBytes()));
ChannelFuture f = ctx.write(response);
f.addListener(ChannelFutureListener.CLOSE);
} catch (Exception e) {
Map<String, String> ret = new HashMap<>();
ByteArrayOutputStream bo = new ByteArrayOutputStream();
e.printStackTrace(new PrintStream(bo));
ret.put("msg", bo.toString());
DefaultFullHttpResponse response =
new DefaultFullHttpResponse(
HttpVersion.HTTP_1_1,
OK,
Unpooled.wrappedBuffer(JsonUtil.toJson(ret).getBytes()));
ChannelFuture f = ctx.write(response);
f.addListener(ChannelFutureListener.CLOSE);
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
LOGGER.warn("catch exception in " + this + ": " + cause.getClass().getSimpleName());
LOGGER.debug(ExceptionUtil.exceptionToString(cause));
ctx.close();
}
}

View File

@ -0,0 +1,473 @@
package org.bdware.server.nodecenter;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import io.netty.util.internal.StringUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bdware.sc.Jedion.KV;
import org.bdware.sc.conn.ByteUtil;
import org.bdware.sc.conn.ResultCallback;
import org.bdware.sc.db.KeyValueDBUtil;
import org.bdware.sc.encrypt.HardwareInfo;
import org.bdware.sc.util.JsonUtil;
import org.bdware.server.action.Action;
import org.bdware.server.permission.Role;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
import org.zz.gmhelper.BCECUtil;
import org.zz.gmhelper.SM2Util;
import java.text.SimpleDateFormat;
import java.util.*;
// CenterPortal用户管理相关
public class NCManagerAction {
// key为centerManager的数据表示平台管理员(中心管理员)
public static final String centerManger = "__CenterManager__";
static final String Licence = "__LICENCE___";
static final ECPublicKeyParameters licencePub =
BCECUtil.createECPublicKeyFromStrParameters(
"04844412ecb77b07d5ad7097c488ae9dff1013b310d2311f8bd84c491642011e1a6a7041bae8c2ad75da29c27e320bd430abc723cf6bcb0490afc82cc26e6d5637",
SM2Util.CURVE,
SM2Util.DOMAIN_PARAMS);
private static final Logger LOGGER = LogManager.getLogger(NCManagerAction.class);
String sessionID = null;
String pubKey;
Random random = new Random();
private NodeCenterWSFrameHandler handler;
public NCManagerAction(NodeCenterWSFrameHandler nodeCenterWSFrameHandler) {
this.handler = nodeCenterWSFrameHandler;
pubKey = null;
}
public static boolean isCenterManager(String pubkey) {
String ret = KeyValueDBUtil.instance.getValue(NCTables.ConfigDB.toString(), centerManger);
LOGGER.debug("centerManger: " + ret);
return !StringUtil.isNullOrEmpty(ret)
&& !StringUtil.isNullOrEmpty(pubkey)
&& pubkey.equals(ret);
}
@Action(userPermission = 0)
public void getNodeSessionID(JsonObject json, ResultCallback resultCallback) {
getSessionID(json, resultCallback);
}
@Action(userPermission = 0)
public void getSessionID(JsonObject json, ResultCallback resultCallback) {
long start = System.currentTimeMillis();
sessionID = random.nextLong() + "_session";
Map<String, String> result = new HashMap<>();
result.put("action", "onSessionID");
result.put("session", sessionID);
resultCallback.onResult(JsonUtil.toJson(result));
long end = System.currentTimeMillis();
LOGGER.debug("time:" + (end - start) + "data:" + JsonUtil.toJson(result));
}
@Action(userPermission = 0)
public void getNodeRole(JsonObject json, ResultCallback resultCallback) {
getRole(json, resultCallback);
}
@Action(userPermission = 0)
public void getManagerPubkey(JsonObject json, ResultCallback resultCallback) {
String ret = KeyValueDBUtil.instance.getValue(NCTables.ConfigDB.toString(), centerManger);
resultCallback.onResult("{\"action\":\"onGetManagerPubkey\",\"data\":\"" + ret + "\"}");
}
public void getRole(JsonObject json, ResultCallback resultCallback) {
if (pubKey == null) {
resultCallback.onResult(
"{\"action\":\"onLogin\",\"data\":\"" + Role.Anonymous.name() + "\"}");
return;
}
try {
String ret =
KeyValueDBUtil.instance.getValue(NCTables.ConfigDB.toString(), centerManger);
if (ret != null && ret.length() > 0) {
boolean isCenterManager = (ret.equals(pubKey)); // 表示此节点是否是平台管理员
ret = KeyValueDBUtil.instance.getValue(NCTables.NodeUser.toString(), pubKey);
String role = "";
if (isCenterManager) {
role = "CenterManager,";
}
if (null != ret && !ret.isEmpty()) {
role += ret;
}
if (role.endsWith(",")) {
role = role.substring(0, role.length() - 1);
} else if (role.isEmpty()) {
role = Role.Anonymous.name();
}
handler.setPermission(Role.compoundValue(role.split(",")));
resultCallback.onResult("{\"action\":\"onLogin\",\"data\":\"" + role + "\"}");
} else {
KeyValueDBUtil.instance.setValue(
NCTables.ConfigDB.toString(), centerManger, pubKey);
handler.setPermission(0x30000ffL);
resultCallback.onResult("{\"action\":\"onLogin\",\"data\":\"CenterManager\"}");
}
} catch (Exception e) {
e.printStackTrace();
resultCallback.onResult(
"{\"action\":\"onLogin\",\"data\":\"" + Role.Anonymous.name() + "\"}");
}
}
@Action(userPermission = 0)
public void login(JsonObject json, ResultCallback resultCallback) {
long start = System.currentTimeMillis();
if (sessionID == null) {
resultCallback.onResult(
"{\"action\":\"onLogin\",\"data\":\"" + Role.Anonymous.name() + "\"}");
return;
}
String signature = json.get("signature").getAsString();
String pubKey = json.get("pubKey").getAsString();
boolean result = SM2Util.plainStrVerify(pubKey, sessionID, signature);
LOGGER.debug("session:" + (sessionID));
if (result) {
this.pubKey = pubKey;
LOGGER.debug("设置公钥" + pubKey);
getRole(json, resultCallback);
} else {
resultCallback.onResult(
"{\"action\":\"onLogin\",\"data\":\"" + Role.Anonymous.name() + "\"}");
}
long end = System.currentTimeMillis();
LOGGER.debug("time:" + (end - start));
}
@Action(userPermission = 0)
public void applyRole(JsonObject json, ResultCallback resultCallback) {
long start = System.currentTimeMillis();
if (pubKey == null) {
resultCallback.onResult("{\"action\":\"onApplyRole\",\"data\":\"missing pubKey\"}");
return;
}
if (json.has("role")) {
Role role = Role.parse(json.get("role").getAsString());
if (role != Role.Anonymous) {
applyAtDB(role, resultCallback, start);
return;
}
}
resultCallback.onResult("{\"action\":\"onApplyRole\",\"data\":\"failed\"}");
}
@Action(userPermission = 1 << 6)
public void addNode(JsonObject json, ResultCallback resultCallback) {
try {
KeyValueDBUtil.instance.setValue(
NCTables.NodeUser.toString(),
json.get("nodePubKey").getAsString(),
Role.Node.toString());
KeyValueDBUtil.instance.setValue(
NCTables.NodeTime.toString(),
json.get("nodePubKey").getAsString(),
Long.toString(new Date().getTime()));
resultCallback.onResult("{\"action\":\"onAddNodes\",\"data\":\"success\"}");
} catch (Exception e) {
e.printStackTrace();
resultCallback.onResult("{\"action\":\"onAddNodes\",\"data\":\"failed\"}");
}
}
private void applyAtDB(Role role, ResultCallback resultCallback, long start) {
String str = KeyValueDBUtil.instance.getValue(NCTables.ApplyRole.toString(), pubKey);
String already = KeyValueDBUtil.instance.getValue(NCTables.NodeUser.toString(), pubKey);
if (already != null && already.contains(role.toString())) {
resultCallback.onResult("{\"action\":\"onApplyRole\",\"data\":\"already has!\"}");
return;
}
if (str == null || str.length() == 0) {
KeyValueDBUtil.instance.setValue(NCTables.ApplyRole.toString(), pubKey, role.name());
KeyValueDBUtil.instance.setValue(
NCTables.ApplyTime.toString(), pubKey, Long.toString(new Date().getTime()));
} else {
if (!str.contains(role.name())) {
KeyValueDBUtil.instance.setValue(
NCTables.ApplyRole.toString(), pubKey, str + "," + role.name());
KeyValueDBUtil.instance.setValue(
NCTables.ApplyTime.toString(), pubKey, Long.toString(new Date().getTime()));
}
}
resultCallback.onResult("{\"action\":\"onApplyRole\",\"data\":\"success\"}");
}
@Action(userPermission = 1 << 3)
public void listAllUsers(JsonObject json, ResultCallback resultCallback) {
List<KV> kv = KeyValueDBUtil.instance.getKeyValues(NCTables.NodeUser.toString());
List<KV> time = KeyValueDBUtil.instance.getKeyValues(NCTables.NodeTime.toString());
Map<String, Object> ret = new HashMap<>();
ResultBack result = new ResultBack();
ret.put("kv", kv);
ret.put("time", time);
result.action = "onListAllUsers";
result.data = ret;
resultCallback.onResult(JsonUtil.toJson(result));
}
@Action(userPermission = 1 << 2)
public void authNodeManager(JsonObject json, ResultCallback resultCallback) {
long start = System.currentTimeMillis();
String pubKey = json.get("pubKey").getAsString();
boolean isAccept = json.get("isAccept").getAsBoolean();
LOGGER.debug("[NCManagerAction] " + json.toString());
if (pubKey == null || pubKey.length() == 0) {
resultCallback.onResult(
"{\"action\":\"onAuthNodeManager\",\"data\":\"missing pubKey\"}");
return;
}
if (!isAccept) {
KeyValueDBUtil.instance.delete(NCTables.ApplyRole.toString(), pubKey);
KeyValueDBUtil.instance.delete(NCTables.ApplyTime.toString(), pubKey);
resultCallback.onResult("{\"action\":\"onAuthNodeManager\",\"data\":\"success\"}");
return;
}
String already = KeyValueDBUtil.instance.getValue(NCTables.NodeUser.toString(), pubKey);
String roles = KeyValueDBUtil.instance.getValue(NCTables.ApplyRole.toString(), pubKey);
if (roles == null || roles.length() == 0) {
resultCallback.onResult("{\"action\":\"onAuthNodeManager\",\"data\":\"empty apply\"}");
return;
}
if (already != null && already.length() > 0) {
already += "," + roles;
} else {
already = roles;
}
KeyValueDBUtil.instance.setValue(NCTables.NodeUser.toString(), pubKey, already);
KeyValueDBUtil.instance.setValue(
NCTables.NodeTime.toString(), pubKey, Long.toString(new Date().getTime()));
KeyValueDBUtil.instance.delete(NCTables.ApplyRole.toString(), pubKey);
KeyValueDBUtil.instance.delete(NCTables.ApplyTime.toString(), pubKey);
resultCallback.onResult("{\"action\":\"onAuthNodeManager\",\"data\":\"success\"}");
long end = System.currentTimeMillis();
LOGGER.debug("[authNodeManager:time]" + (end - start));
}
@Action(userPermission = 1 << 4)
public void listApplyList(JsonObject json, ResultCallback resultCallback) {
long start = System.currentTimeMillis();
List<KV> kv = KeyValueDBUtil.instance.getKeyValues(NCTables.ApplyRole.toString());
List<KV> time = KeyValueDBUtil.instance.getKeyValues(NCTables.ApplyTime.toString());
Map<String, Object> ret = new HashMap<>();
ret.put("kv", kv);
ret.put("time", time);
ResultBack result = new ResultBack();
result.action = "onListApplyList";
result.data = ret;
resultCallback.onResult(JsonUtil.toJson(result));
long end = System.currentTimeMillis();
LOGGER.debug("[listApplyList:time]" + (end - start));
}
@Action(userPermission = 1 << 5)
public void delete(JsonObject json, ResultCallback resultCallback) {
String pubKey = json.get("pubKey").getAsString();
KeyValueDBUtil.instance.delete(NCTables.NodeUser.toString(), pubKey);
KeyValueDBUtil.instance.delete(NCTables.NodeTime.toString(), pubKey);
resultCallback.onResult("{\"action\":\"onDelete\",\"data\":\"success\"}");
}
@Action(userPermission = 1 << 4)
public void listLicence(JsonObject json, ResultCallback resultCallback) {
long start = System.currentTimeMillis();
String licence = KeyValueDBUtil.instance.getValue(NCTables.ConfigDB.toString(), Licence);
if (licence == null || licence.length() == 0) {
resultCallback.onResult(
"{\"action\":\"onListLicence\",\"nodeCount\":" + 0 + ",\"dueDate\":\"已过期\"}");
return;
}
json = JsonParser.parseString(licence).getAsJsonObject();
String sign = json.get("sign").getAsString();
String content = json.get("content").getAsString();
if (StringUtil.isNullOrEmpty(sign) || StringUtil.isNullOrEmpty(content)) {
resultCallback.onResult(
"{\"action\":\"onListLicence\",\"nodeCount\":0,\"dueDate\":\"已过期\"}");
return;
}
long expiredDate;
long nodeCount;
try {
JsonObject jo = JsonParser.parseString(content).getAsJsonObject();
nodeCount = jo.get("nodeCount").getAsLong();
expiredDate = jo.get("expiredDate").getAsLong();
} catch (Exception e) {
resultCallback.onResult(
"{\"action\":\"onListLicence\",\"nodeCount\":0,\"dueDate\":\"已过期\"}");
return;
}
if (expiredDate == 0 || nodeCount == 0) {
resultCallback.onResult(
"{\"action\":\"onListLicence\",\"nodeCount\":0,\"dueDate\":\"已过期\"}");
return;
}
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
boolean verify =
SM2Util.verify(licencePub, content.getBytes(), ByteUtils.fromHexString(sign));
if (verify) {
resultCallback.onResult(
"{\"action\":\"onListLicence\",\"nodeCount\":"
+ nodeCount
+ ",\"dueDate\":\""
+ format.format(new Date(expiredDate))
+ "\"}");
long end = System.currentTimeMillis();
LOGGER.debug("[listLicence:time]" + (end - start));
} else {
resultCallback.onResult(
"{\"action\":\"onListLicence\",\"nodeCount\":0,\"dueDate\":\"已过期\"}");
long end = System.currentTimeMillis();
LOGGER.debug("[listLicence:time]" + (end - start));
}
}
@Action(userPermission = 1L << 2L)
public void updateLicence(JsonObject json, ResultCallback resultCallback) {
long start = System.currentTimeMillis();
String sign = json.get("sign").getAsString();
String content = json.get("content").getAsString();
if (StringUtil.isNullOrEmpty(sign) || StringUtil.isNullOrEmpty(content)) {
resultCallback.onResult(
"{\"action\":\"onUpdateLicence\",\"data\":\"missing signature or content\"}");
return;
}
long expiredDate;
long nodeCount;
String uuid;
try {
JsonObject jo = JsonParser.parseString(content).getAsJsonObject();
nodeCount = jo.get("nodeCount").getAsLong();
expiredDate = jo.get("expiredDate").getAsLong();
uuid = jo.get("uuid").getAsString();
} catch (Exception e) {
resultCallback.onResult("{\"action\":\"onUpdateLicence\",\"data\":\"content error\"}");
return;
}
if (expiredDate == 0 || nodeCount == 0) {
resultCallback.onResult(
"{\"action\":\"onUpdateLicence\",\"data\":\"parse expiredDate/nodeCount error\"}");
return;
}
if (!uuid.equals(
ByteUtil.encodeBASE64(HardwareInfo.getCPUID().getBytes()).replaceAll("\n", ""))) {
resultCallback.onResult(
"{\"action\":\"onUpdateLicence\",\"data\":\"invalid licence\"}");
return;
}
boolean verify =
SM2Util.verify(licencePub, content.getBytes(), ByteUtils.fromHexString(sign));
if (verify) {
KeyValueDBUtil.instance.setValue(
NCTables.ConfigDB.toString(), Licence, json.toString());
resultCallback.onResult("{\"action\":\"onUpdateLicence\",\"data\":\"success\"}");
long end = System.currentTimeMillis();
LOGGER.debug("[listLicence:time]" + (end - start));
return;
} else resultCallback.onResult("{\"action\":\"onUpdateLicence\",\"data\":\"failed\"}");
long end = System.currentTimeMillis();
LOGGER.debug("[updateLicence:time]" + (end - start));
}
@Action(userPermission = 1 << 9)
public void getOtherNC(JsonObject json, ResultCallback resultCallback) {
Map<String, String> result = new HashMap<>();
result.put("action", "onGetOtherNC");
String s = OtherNCProxy.instance.getOtherNCs().replace(";", " ");
result.put("address", s);
resultCallback.onResult(JsonUtil.toJson(result));
}
// 改为NodeManager权限
@Action(userPermission = 1 << 9)
public void changeOtherNC(JsonObject json, ResultCallback resultCallback) {
String add = json.get("data").getAsString().replace(" ", ";");
String s = OtherNCProxy.instance.setOtherNCs(add).replace(";", " ");
Map<String, String> result = new HashMap<>();
result.put("action", "onGetOtherNC");
result.put("address", s);
resultCallback.onResult(JsonUtil.toJson(result));
}
// NodeManager权限
@Action(userPermission = 1 << 9)
public void changeNCFile(JsonObject json, ResultCallback resultCallback) {
String add = json.get("data").getAsString();
String s = OtherNCProxy.instance.setNCFile(add);
Map<String, String> result = new HashMap<>();
result.put("action", "onGetNCFile");
result.put("fileName", s);
resultCallback.onResult(JsonUtil.toJson(result));
}
@Action(userPermission = 1 << 9)
public void getNCFile(JsonObject json, ResultCallback resultCallback) {
String s = OtherNCProxy.instance.getNCFile();
Map<String, String> result = new HashMap<>();
result.put("action", "onGetNCFile");
result.put("fileName", s);
resultCallback.onResult(JsonUtil.toJson(result));
}
// TODO 迁移合约实例从节点A将合约M的实例迁移到节点B的权限?
/*
* now only support Sole contract type
*/
@Action(userPermission = 0)
public void transferContractInstance(JsonObject json, ResultCallback resultCallback) {
LOGGER.info("transferContractInstance");
String node1ID = json.get("node1ID").getAsString();
String node2ID = json.get("node2ID").getAsString();
String contractID = json.get("contractID").getAsString();
CMNode node1 = NodeCenterActions.nodeInfos.get(node1ID);
if (node1 == null) {
LOGGER.info("node1 " + node1ID + " is null!");
return;
}
if (node2ID == null) {
LOGGER.info("node2 " + node1ID + " is null!");
return;
}
if (node1ID.equals(node2ID)) {
LOGGER.info("node1 and node2 is the same node.");
return;
}
Map<String, String> request = new HashMap<>();
request.put("action", "transferInstance");
request.put("contractID", contractID);
request.put("nodeID", node2ID);
CMNode node2 = NodeCenterActions.nodeInfos.get(node2ID);
if (node2 == null) {
LOGGER.info("node " + node2ID + " is null!");
return;
}
request.put("address", node2.masterAddress);
node1.connection.controller.sendMsg(JsonUtil.toJson(request));
Map<String, String> result = new HashMap<>();
result.put("action", "onTransfer");
result.put(
"data",
"now start transfer contract "
+ contractID
+ " from node:"
+ node1ID
+ " to node:"
+ node2ID);
resultCallback.onResult(JsonUtil.toJson(result));
}
}

View File

@ -0,0 +1,21 @@
package org.bdware.server.nodecenter;
public enum NCTables {
NodeUser,
NodeTime,
ApplyRole,
ApplyTime,
NodeHttpLog,
ContractMeta,
ConfigDB,
NodeTcpLog,
NodesDB,
TrustUnitsDB,
OtherNCs,
NCFile,
ApplyNodeManager;
public String toString() {
return "NC_" + super.toString();
}
}

View File

@ -0,0 +1,122 @@
package org.bdware.server.nodecenter;
import com.google.gson.JsonObject;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bdware.sc.conn.ResultCallback;
import org.bdware.sc.udp.UDPMessage;
import org.bdware.sc.udp.UDPNode;
import org.bdware.sc.util.JsonUtil;
import org.bdware.server.action.Action;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class NCUDPRunner extends Thread {
private static final Logger LOGGER = LogManager.getLogger(NCUDPRunner.class);
public static int mainPort;
public ExecutorService executor = Executors.newFixedThreadPool(5);
public int port;
boolean ready = false;
Map<Integer, org.bdware.sc.udp.UDPNode> id2IP;
private DatagramSocket socket;
public NCUDPRunner(Map<Integer, UDPNode> id2ip2) {
// TODO Auto-generated constructor stub
this.id2IP = id2ip2;
}
public void run() {
// TimerTask task = new TimerTask() {
//
// @Override
// public void run(Timeout arg0) throws Exception {
// Set<Integer> nodes = new HashSet<Integer>();
// for (Integer i:id2IP.keySet()) {
// UDPNode node = id2IP.get(i);
// if (System.currentTimeMillis()-node.lastUpdatedTime<60*1000) {
// nodes.remove(i);
// }
// }
// for (Integer i:nodes)
// node.re
// }
// };
id2IP = new HashMap<Integer, UDPNode>();
int startPort = mainPort;
while (true) {
try {
socket = new DatagramSocket(startPort);
break;
} catch (Exception e) {
startPort++;
}
}
this.port = startPort;
ready = true;
while (true) {
try {
final DatagramPacket request = new DatagramPacket(new byte[1024], 1024);
socket.receive(request);
final UDPMessage msg = UDPMessage.parse(request.getData(), request.getLength());
executor.execute(() -> {
try {
onUDPMessage(msg, request);
} catch (Exception e) {
System.err.println("Excpetion in:" + port);
e.printStackTrace();
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void onUDPMessage(UDPMessage msg, DatagramPacket request) {
switch (msg.type) {
case shakeHand:
LOGGER.debug(
"[NCUDPRunner] shakeHand:"
+ request.getAddress().getHostAddress()
+ ":"
+ request.getPort());
id2IP.put(msg.id, new UDPNode(request.getSocketAddress()));
default:
}
}
@Action
public void listUDPNodes(JsonObject json, ResultCallback rc) {
Map<String, String> ret = new HashMap<String, String>();
ret.put("action", "onListUDPNodes");
for (Integer i : id2IP.keySet()) {
UDPNode node = id2IP.get(i);
InetSocketAddress address = (InetSocketAddress) (node.addr);
ret.put("id_" + i, address.getHostString() + ":" + address.getPort());
}
ret.put("udpPort", port + "");
rc.onResult(JsonUtil.toJson(ret));
}
public String getUDPAddr(Integer udpid) {
LOGGER.debug(udpid);
UDPNode node = id2IP.get(udpid);
if (node != null) {
InetSocketAddress address = (InetSocketAddress) (node.addr);
return address.getHostString() + ":" + address.getPort();
}
return null;
}
public void remove(String udpID) {
id2IP.remove(Integer.valueOf(udpID));
}
}

View File

@ -0,0 +1,5 @@
package org.bdware.server.nodecenter;
public class NameAndID {
String name,id;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,168 @@
package org.bdware.server.nodecenter;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bdware.sc.conn.ResultCallback;
import org.bdware.sc.util.JsonUtil;
import org.bdware.server.NodeCenterServer;
import org.bdware.server.action.Action;
import org.bdware.server.action.ActionExecutor;
import java.io.ByteArrayOutputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class NodeCenterFrameHandler extends SimpleChannelInboundHandler<Object> {
private static final Logger LOGGER = LogManager.getLogger(LogActions.class);
static ExecutorService executorService = Executors.newFixedThreadPool(10);
public String pubKey;
NodeCenterActions actions;
MasterActions masterActions;
ActionExecutor<ResultCallback, JsonObject> ae;
ChannelHandlerContext ctx;
public NodeCenterFrameHandler() {
actions = new NodeCenterActions(this);
MetaIndexAction.controller = this;
// TODO 添加那个UnitAction.
ae =
new ActionExecutor<ResultCallback, JsonObject>(
executorService, actions, new MetaIndexAction()) {
@Override
public boolean checkPermission(
Action a, final JsonObject args, long permission) {
long val = a.userPermission();
boolean flag;
String status = "refuse";
String action = args.get("action").getAsString();
if (val == 0) {
flag = true;
status = "accept";
} else if ((permission & val) == val) {
flag = true;
status = "accept";
} else {
flag = false;
}
if (!action.contains("checkAlive"))
NodeCenterServer.nodeTcpLogDB.put(
action,
"{\"action\":\""
+ action
+ "\",\"pubKey\":\""
+ pubKey
+ "\",\"status\":\""
+ status
+ "\",\"date\":"
+ System.currentTimeMillis()
+ "}");
return flag;
}
};
LOGGER.info("create NodeCenterFrameHandler instance succeed!");
}
public void setPermission(long l) {
ae.permission = l;
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, Object frame) {
this.ctx = ctx;
JsonObject map;
try {
map =
JsonParser.parseReader(
new InputStreamReader(new ByteBufInputStream((ByteBuf) frame)))
.getAsJsonObject();
} catch (Exception e) {
LOGGER.error("can't handle msg! " + e.getMessage());
return;
}
Response response;
try {
final String action = map.get("action").getAsString();
// System.out.println("[NodeCenterFramHandler] handle:" + action);
ae.handle(
action,
map,
new ResultCallback() {
@Override
public void onResult(String ret) {
sendMsg(ret);
}
});
} catch (IllegalArgumentException e) {
response = new Response();
response.action = "onException";
response.data = e.getMessage();
LOGGER.error(JsonUtil.toJson(response));
} catch (Exception e) {
e.printStackTrace();
ByteArrayOutputStream bo = new ByteArrayOutputStream();
e.printStackTrace(new PrintStream(bo));
response = new Response();
response.action = "onException";
String[] strs = bo.toString().split("\n");
StringBuilder ret = new StringBuilder();
int count = 0;
for (String s : strs) {
if (s.contains("sun.reflect")
|| s.contains("java.lang.reflect")
|| s.contains("org.apache")
|| s.contains("java.util")
|| s.contains("java.lang")
|| s.contains("io.netty")) {
continue;
}
ret.append(s);
ret.append("\n");
if (count++ > 10) {
break;
}
}
response.data = ret.toString();
LOGGER.error(JsonUtil.toJson(response));
}
}
public void sendMsg(String json) {
if (ctx != null) {
// System.out.println("[NodeCenterFrame send] TID:" + Thread.currentThread().getId() + "
// isOpen:"
// + ctx.channel().isOpen() + " isActive:" + ctx.channel().isActive() + " -->" + json);
ByteBuf buf = Unpooled.wrappedBuffer(json.getBytes());
ctx.channel().writeAndFlush(buf);
}
}
public void sendEMsg(String msg) {
Response r = new Response();
r.action = "receiveEMsg";
r.data = msg;
sendMsg(JsonUtil.toJson(r));
}
public boolean isOpen() {
return ctx.channel().isOpen();
}
static class Response {
public String cid;
public String analysisResult;
String responseID;
String action;
Object data;
long executeTime;
}
}

View File

@ -0,0 +1,171 @@
package org.bdware.server.nodecenter;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bdware.sc.conn.ResultCallback;
import org.bdware.sc.util.JsonUtil;
import org.bdware.server.NodeCenterServer;
import org.bdware.server.action.Action;
import org.bdware.server.action.ActionExecutor;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class NodeCenterWSFrameHandler extends SimpleChannelInboundHandler<WebSocketFrame> {
public static ExecutorService executorService = Executors.newFixedThreadPool(10);
private static final Logger LOGGER = LogManager.getLogger(NodeCenterWSFrameHandler.class);
StringBuilder dataCache = new StringBuilder();
ActionExecutor<ResultCallback, JsonObject> ae;
private ChannelHandlerContext ctx;
private NCManagerAction managerAction;
private LogActions logActions;
private UnitActions unitActions;
public NodeCenterWSFrameHandler() {
managerAction = new NCManagerAction(this);
logActions = new LogActions(managerAction);
unitActions = new UnitActions(managerAction);
ae =
new ActionExecutor<ResultCallback, JsonObject>(
executorService, managerAction, logActions, unitActions, new MetaIndexAction(), new TracingAction()) {
@Override
public boolean checkPermission(Action a, JsonObject arg, long permission) {
// Permission userPermission = a.userPermission();
// long val=userPermission.getValue();
long val = a.userPermission();
String pubKey = managerAction.pubKey;
String action = arg.get("action").getAsString();
LOGGER.debug("permission" + permission);
LOGGER.debug("userPermission" + val);
NodeCenterServer.nodeHttpLogDB.put(
action,
"{\"action\":\""
+ action
+ "\",\"pubKey\":\""
+ pubKey
+ "\",\"date\":"
+ System.currentTimeMillis()
+ "}");
// if (val == 0) return true;
// return true;
if ((permission & val) == val) {
return true;
} else return false;
}
};
}
public ActionExecutor getAE() {
return ae;
}
@Override
protected void channelRead0(final ChannelHandlerContext ctx, WebSocketFrame frame)
throws Exception {
// ping and pong frames already handled
if (frame instanceof TextWebSocketFrame) {
// Send the uppercase string back.
this.ctx = ctx;
String request = ((TextWebSocketFrame) frame).text();
LOGGER.debug("[Websocket receive]" + request);
JsonObject map = null;
try {
map = new JsonParser().parse(request).getAsJsonObject();
} catch (Exception e) {
Response response = new Response();
response.action = "onException";
response.data = "msg is not JSON format";
ctx.channel().writeAndFlush(new TextWebSocketFrame(JsonUtil.toJson(response)));
return;
}
Response response = new Response();
response.action = "sendNextSegment";
try {
boolean isSegment = false;
if (map.has("isSegment")) isSegment = map.get("isSegment").getAsBoolean();
if (isSegment) {
dataCache.append(map.get("data").getAsString());
response = new Response();
response.action = "sendNextSegment";
ctx.channel()
.writeAndFlush(new TextWebSocketFrame(JsonUtil.toJson(response)));
return;
} else {
if (dataCache.length() > 0) {
dataCache.append(map.get("data").getAsString());
String dataStr = dataCache.toString();
LOGGER.debug("[WebSocketFrame] DataString:" + dataStr);
map = new JsonParser().parse(dataStr).getAsJsonObject();
dataCache = new StringBuilder();
}
}
String action = map.get("action").getAsString();
ae.handle(
action,
map,
new ResultCallback() {
@Override
public void onResult(String ret) {
if (ret != null)
ctx.channel().writeAndFlush(new TextWebSocketFrame(ret));
}
});
} catch (IllegalArgumentException e) {
response = new Response();
response.action = "onException";
response.data = e.getMessage();
ctx.channel().writeAndFlush(new TextWebSocketFrame((JsonUtil.toJson(response))));
return;
} catch (Exception e) {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
e.printStackTrace();
e.printStackTrace(new PrintStream(bo));
response = new Response();
response.action = "onException";
String[] strs = bo.toString().split("\n");
String ret = "";
int count = 0;
for (String s : strs) {
if (s.contains("sun.reflect")) continue;
if (s.contains("java.lang.reflect")) continue;
if (s.contains("org.apache")) continue;
if (s.contains("java.util")) continue;
if (s.contains("java.lang")) continue;
if (s.contains("io.netty")) continue;
ret += s;
ret += "\n";
if (count++ > 5) break;
}
response.data = ret;
ctx.channel().writeAndFlush(new TextWebSocketFrame(JsonUtil.toJson(response)));
}
} else {
Response response = new Response();
response.action = "onException";
response.data = "unsupported frame";
ctx.channel().writeAndFlush(new TextWebSocketFrame((JsonUtil.toJson(response))));
return;
}
}
public void sendMsg(String json) {
LOGGER.debug("[WebSocketFrameHandler] sendMsg:" + json);
ctx.channel().writeAndFlush(new TextWebSocketFrame(json));
}
public void setPermission(long i) {
ae.permission = i;
}
}

View File

@ -0,0 +1,287 @@
package org.bdware.server.nodecenter;
import com.google.gson.JsonObject;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bdware.sc.bean.ContractDesp;
import org.bdware.sc.bean.ContractExecType;
import org.bdware.sc.bean.OtherNCInfo;
import org.bdware.sc.db.KeyValueDBUtil;
import org.bdware.sc.util.JsonUtil;
import org.bdware.server.NodeCenterServer;
import org.bdware.server.ws.DelimiterCodec;
import org.zz.gmhelper.SM2KeyPair;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
public class OtherNCProxy {
private static final Logger LOGGER = LogManager.getLogger(OtherNCProxy.class);
public static OtherNCProxy instance = new OtherNCProxy();
private final TreeMap<String, List<OtherNCInfo>> otherNodeCenterInfos = new TreeMap<>(); //key为NC节点的pubkey(非一致的)
public Map<String, NCConnector> connList = new ConcurrentHashMap<>(); //连接别的NC key为ip:port
public Set<String> ncAdds = ConcurrentHashMap.newKeySet(); //其他NC的ip:port
public SM2KeyPair sm2; //NC证书
private OtherNCProxy() {
}
// 从DB中加载OtherNC和NCFile的信息
public void init() {
LOGGER.debug("[OtherNCProxy] init : ");
loadOtherNCs();
LOGGER.debug("load other ncs");
loadNCFile();
LOGGER.debug("load nc file");
periodUpdate();
LOGGER.debug("period update");
LOGGER.info("OtherNCProxy init done!");
}
public void periodUpdate() {
NodeCenterServer.scheduledThreadPool.scheduleWithFixedDelay(
() -> {
},
0,
30,
TimeUnit.SECONDS);
}
public void loadOtherNCs() {
LOGGER.debug("loadOtherNCs : ");
String res = getOtherNCs();
if (res != null && !res.equals("")) {
String[] strArr = res.split(";");
ncAdds.clear();
ncAdds.addAll(Arrays.asList(strArr));
LOGGER.debug("now ncAdds contains: ");
for (String s : strArr) {
LOGGER.debug(s);
}
if (ncAdds.isEmpty()) {
KeyValueDBUtil.instance.setValue(NCTables.OtherNCs.toString(), "address", "");
}
} else {
ncAdds.clear();
}
}
// 配置一致的NC证书
public void loadNCFile() {
LOGGER.debug("loadNCFile");
String fileAdd = getNCFile();
if (fileAdd != null && !fileAdd.isEmpty()) {
LOGGER.debug("NCFile path = " + fileAdd);
File file = new File(fileAdd);
if (!file.exists()) {
LOGGER.warn("file not exists!");
KeyValueDBUtil.instance.setValue(NCTables.NCFile.toString(), "filePath", "");
return;
}
String keyPairStr = null;
try {
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
String s;
while (null != (s = br.readLine())) {
keyPairStr = s;
}
fr.close();
br.close();
} catch (IOException e) {
e.printStackTrace();
}
if (keyPairStr == null) {
LOGGER.warn("import ket pair form NCFile is null!");
return;
}
LOGGER.info("import ket pair from NCFile : " + keyPairStr);
sm2 = SM2KeyPair.fromJson(keyPairStr);
} else {
sm2 = null;
}
}
public String getOtherNCs() {
return KeyValueDBUtil.instance.getValue(NCTables.OtherNCs.toString(), "address");
}
public String getNCFile() {
return KeyValueDBUtil.instance.getValue(NCTables.NCFile.toString(), "filePath");
}
//配置其他NC
public String setOtherNCs(String add) {
LOGGER.debug("setOtherNC: " + add);
KeyValueDBUtil.instance.setValue(NCTables.OtherNCs.toString(), "address", add);
loadOtherNCs();
return getOtherNCs();
}
//配置NC文件
public String setNCFile(String fileName) {
LOGGER.debug("setNCFIle: " + fileName);
KeyValueDBUtil.instance.setValue(NCTables.NCFile.toString(), "filePath", fileName);
loadNCFile();
return getNCFile();
}
//本地更新
public void updateOtherNCInfo(String nodePubkey, List<OtherNCInfo> list) {
LOGGER.debug("updateOtherNCInfo: ");
synchronized (otherNodeCenterInfos) {
otherNodeCenterInfos.put(nodePubkey, list);
LOGGER.debug("update route nodePubkey=" + nodePubkey + " list=" + JsonUtil.toJson(list));
}
}
//通过合约id或name在别的nc上查询信息
public String search(String id) {
LOGGER.debug("search : " + id);
synchronized (otherNodeCenterInfos) {
for (String pubKey : otherNodeCenterInfos.keySet()) {
List<OtherNCInfo> list = otherNodeCenterInfos.get(pubKey);
for (OtherNCInfo info : list) {
if (info.contractID.equals(id) || info.contractName.equals(id)) {
LOGGER.debug("[OtherNCProxy] find contract " + id + "pubKey is " + pubKey + " master is " + info.master + " from other NC route info");
return pubKey + ";" + info.master;
}
}
}
return null;
}
}
//向其他NC发起同步
public void requestUpdate() {
LOGGER.debug("sendUpdate: ");
for (String add : instance.ncAdds) {
try {
instance.connectToNC(add);
} catch (Exception e) {
LOGGER.error("NC " + add + " can not be connected! " + e.getMessage());
connList.get(add).close();
continue;
}
JsonObject args = new JsonObject();
args.addProperty("action", "requestRouteInfo");
args.addProperty("address", add);
connList.get(add).sendMsg(JsonUtil.toJson(args));
}
}
public List<OtherNCInfo> getInfo() {
LOGGER.debug("getInfo: ");
List<OtherNCInfo> list = new ArrayList<>();
for (Map.Entry<String, CMNode> stringCMNodeEntry : NodeCenterActions.nodeInfos.entrySet()) {
CMNode node = stringCMNodeEntry.getValue();
if (null == node.contracts)
continue;
for (ContractDesp desp : node.contracts) {
if (desp.type == ContractExecType.Sole || desp.getIsMaster()) {
list.add(new OtherNCInfo(desp.contractID, desp.contractName, node.masterAddress));
}
}
}
return list;
}
public void connectToNC(String target) throws InterruptedException {
LOGGER.debug("connectToNC: ");
if (target == null || !target.contains(":")) {
LOGGER.error("connectToNC failed, target nc address is illegal! target=" + target);
return;
}
final Bootstrap b = new Bootstrap();
b.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000);
EventLoopGroup group = new NioEventLoopGroup();
b.group(group);
NCConnector conn = new NCConnector(target, b, new NCClientHandler());
connList.put(target, conn);
b.channel(NioSocketChannel.class)
.handler(
new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ChannelPipeline p = ch.pipeline();
p.addLast(new DelimiterCodec()).addLast(conn.handler);
}
});
if (!conn.handler.isOpen()) {
String[] ipAndPort = target.split(":");
b.connect(ipAndPort[0], Integer.parseInt(ipAndPort[1]))
.sync()
.channel();
}
reconnect(target);
}
public void reconnect(String target) throws InterruptedException {
LOGGER.debug("reconnect: ");
if (!connList.containsKey(target))
return;
NCConnector conn = connList.get(target);
if (!conn.handler.isOpen()) {
String[] ipAndPort = conn.ipAndPort.split(":");
conn.bootstrap
.connect(ipAndPort[0], Integer.parseInt(ipAndPort[1]))
.sync()
.channel();
}
}
static class NCConnector {
Bootstrap bootstrap;
NCClientHandler handler;
String ipAndPort;
public NCConnector(String s, Bootstrap b, NCClientHandler h) {
bootstrap = b;
handler = h;
ipAndPort = s;
}
public void sendMsg(String s) {
handler.sendMsg(s);
}
public void close() {
handler.close();
OtherNCProxy.instance.connList.remove(ipAndPort);
}
}
}

View File

@ -0,0 +1,61 @@
package org.bdware.server.nodecenter;
import com.google.gson.JsonObject;
import com.google.gson.JsonArray;
import org.bdware.sc.bean.ContractDesp;
import org.bdware.sc.conn.ResultCallback;
import org.bdware.server.action.Action;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
public class TracingAction {
private static JsonObject getDependentContract(JsonObject jo) {
//考虑多层依赖
JsonObject result = new JsonObject();
JsonArray beDependent = new JsonArray();
String contractName = jo.get("contractName").getAsString();
try {
if (!jo.has("contractName")) {
result.addProperty("exception", "missing arguments: contractName");
return result;
}
JsonArray dependencies = new JsonArray();
for (CMNode node : NodeCenterActions.nodeInfos.values()) {
for (ContractDesp desp : node.contracts) {
if (desp.contractName.equals(contractName)) {
if (desp.dependentContracts != null) {
for (String val : desp.dependentContracts)
dependencies.add(val);
}
} else {
if (desp.dependentContracts != null && desp.dependentContracts.contains(contractName)) {
beDependent.add(desp.contractName);
}
}
}
}
result.add("dependencies", dependencies);
result.add("beDependent", beDependent);
return result;
} catch (Exception e) {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
e.printStackTrace(new PrintStream(bo));
result.addProperty("exception", bo.toString());
return result;
}
}
@Action(async = true)
public void getDependentContract(JsonObject json, ResultCallback rc) {
JsonObject result = getDependentContract(json);
JsonObject jo = new JsonObject();
if (json.has("requestID"))
jo.add("responseID", json.get("requestID"));
jo.add("result", result);
jo.addProperty("action", "onGetDependentContract");
rc.onResult(jo.toString());
}
}

View File

@ -0,0 +1,407 @@
package org.bdware.server.nodecenter;
import com.google.gson.JsonObject;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bdware.sc.Jedion.KV;
import org.bdware.sc.bean.ContractDesp;
import org.bdware.sc.conn.ResultCallback;
import org.bdware.sc.db.KeyValueDBUtil;
import org.bdware.sc.util.JsonUtil;
import org.bdware.server.action.Action;
import java.util.*;
public class UnitActions {
private static final Logger LOGGER = LogManager.getLogger(UnitActions.class);
private final NCManagerAction managerAction;
public UnitActions(NCManagerAction managerAction) {
this.managerAction = managerAction;
}
private static String convertContractName(String contractID) {
ContractDesp desp = NodeCenterActions.getContractByName(contractID);
if (desp != null) return desp.contractID;
return contractID;
}
/**
* 显示当前用户可见的集群
*
* @param json
* @param resultCallback
*/
@Action(userPermission = 1 << 6, async = true)
public void listTrustUnits(JsonObject json, ResultCallback resultCallback) {
long start = System.currentTimeMillis();
final String pubKey = managerAction.pubKey;
Map<String, Object> ret = new HashMap<>();
List<KV> allunits = KeyValueDBUtil.instance.getKeyValues(NCTables.TrustUnitsDB.toString());
if (pubKey != null
&& KeyValueDBUtil.instance
.getValue(NCTables.ConfigDB.toString(), "__CenterManager__")
.contains(pubKey)) {
LOGGER.debug("is center manager");
ret.put("action", "onListTrustUnits");
ret.put("data", allunits);
LOGGER.debug("[listTrustUnits] " + JsonUtil.toJson(ret));
resultCallback.onResult(JsonUtil.toJson(ret));
long end = System.currentTimeMillis();
LOGGER.debug("[listTrustUnits:time]" + (end - start));
return;
}
// 合约管理者获取自己创建的units
Iterator<KV> it = allunits.iterator();
List<KV> ciunits = new ArrayList<>();
while (it.hasNext()) {
KV kv = it.next();
if (kv.key.contains(pubKey)) {
ciunits.add(kv);
}
}
ret.put("action", "onListTrustUnits");
ret.put("data", ciunits);
LOGGER.debug("[listTrustUnits] " + JsonUtil.toJson(ret));
resultCallback.onResult(JsonUtil.toJson(ret));
long end = System.currentTimeMillis();
LOGGER.debug("[listTrustUnits:time]" + (end - start));
}
@Action(userPermission = 1 << 6, async = true)
public void createTrustUnit(JsonObject json, ResultCallback resultCallback) {
final String pubKey = managerAction.pubKey;
LOGGER.debug("[createTrustUnit] " + json.get("data").toString());
KeyValueDBUtil.instance.setValue(
NCTables.TrustUnitsDB.toString(),
pubKey + "_" + json.get("msg").getAsString(),
json.get("data").toString());
Map<String, Object> ret = new HashMap<>();
ret.put("action", "onCreateTrustUnit");
ret.put("status", "Success");
resultCallback.onResult(JsonUtil.toJson(ret));
}
@Action(userPermission = 1 << 6, async = true)
public void deleteTrustUnit(JsonObject json, ResultCallback resultCallback) {
// final String pubKey = managerAction.pubKey;
LOGGER.debug(
"[deleteTrustUnit] before"
+ KeyValueDBUtil.instance.getValue(
NCTables.TrustUnitsDB.toString(), json.get("data").getAsString()));
KeyValueDBUtil.instance.delete(
NCTables.TrustUnitsDB.toString(), json.get("data").getAsString());
LOGGER.debug(
"[deleteTrustUnit] after"
+ KeyValueDBUtil.instance.getValue(
NCTables.TrustUnitsDB.toString(), json.get("data").getAsString()));
Map<String, Object> ret = new HashMap<>();
ret.put("action", "onDeleteTrustUnit");
ret.put("status", "Success");
resultCallback.onResult(JsonUtil.toJson(ret));
}
// @Action(async = true)
// public void executeContract(JsonObject args, final ResultCallback rc) {
// executeContractTrustfully(args, rc);
// }
@Action(async = true, userPermission = 1L << 6)
public void getNodeTrustUnits(JsonObject json, ResultCallback resultCallback) {
String nodeID = json.get("data").getAsString();
List<KV> allunits = KeyValueDBUtil.instance.getKeyValues(NCTables.TrustUnitsDB.toString());
Iterator<KV> it = allunits.iterator();
List<KV> nodeunits = new ArrayList<KV>();
while (it.hasNext()) {
KV kv = it.next();
if (kv.value.contains(nodeID)) {
nodeunits.add(kv);
}
}
Map<String, Object> ret = new HashMap<>();
ret.put("action", "onGetNodeTrustUnits");
ret.put("data", nodeunits);
resultCallback.onResult(JsonUtil.toJson(ret));
}
// @Action(async = true, userPermission = 0)
// public void executeContractTrustfully(JsonObject args, final ResultCallback rc) {
// String contractID = args.get("contractID").getAsString();
//
// contractID = convertContractName(contractID);
//
// args.remove("contractID");
// args.addProperty("contractID", contractID);
// String requestID;
// if (!args.has("requestID")) {
// requestID = System.currentTimeMillis() + "_" + (int) (Math.random() * 10000);
// args.addProperty("requestID", requestID);
// } else requestID = args.get("requestID").getAsString();
// args.remove("action");
// args.addProperty("action", "executeContractTrustfully");
// MultiPointContractInfo mInfo = NodeCenterActions.contractID2Members.get(contractID);
// args.addProperty("seq", mInfo.getNextSeq());
// args.addProperty("needSeq", ContractType.needSeq(mInfo.type));
// List<String> nodes = mInfo.members;
// logger.debug("tid:" + Thread.currentThread().getId() + " contractID:" + contractID);
// if (nodes == null) {
// rc.onResult(
// "{\"status\":\"Error\",\"result\":\"can't locate contract\",\"action\":\"onExecuteContractTrustfully\"}");
// } else {
// mInfo.rcf.execute(requestID, rc, JsonUtil.toJson(args));
// }
//
// // add request cache,only for requestAll type contract
// if (ContractType.needSeq(mInfo.type)) {
// RequestCache reqc = NodeCenterActions.getCache(contractID);
// reqc.put(args.get("seq").getAsString(), args);
// }
// }
//only for test ADSP
// public static void testExecuteContract(JsonObject args, final ResultCallback rc) {
// String contractID = args.get("contractID").getAsString();
//
// contractID = convertContractName(contractID);
//
// args.remove("contractID");
// args.addProperty("contractID", contractID);
// String requestID;
// if (!args.has("requestID")) {
// requestID = System.currentTimeMillis() + "_" + (int) (Math.random() * 10000);
// args.addProperty("requestID", requestID);
// } else requestID = args.get("requestID").getAsString();
// args.remove("action");
// args.addProperty("action", "executeContractTrustfully");
// MultiPointContractInfo mInfo = NodeCenterActions.contractID2Members.get(contractID);
// System.out.println("mInfo是空吗" + mInfo == null);
//
// args.addProperty("seq", mInfo.getNextSeq());
// args.addProperty("needSeq", ContractType.needSeq(mInfo.type));
// List<String> nodes = mInfo.members;
// logger.debug("tid:" + Thread.currentThread().getId() + " contractID:" + contractID);
// if (nodes == null) {
// rc.onResult(
// "{\"status\":\"Error\",\"result\":\"can't locate contract\",\"action\":\"onExecuteContractTrustfully\"}");
// } else {
// mInfo.rcf.execute(requestID, rc, JsonUtil.toJson(args));
// }
//
// //add request cache,only for requestAll type contract
// if(ContractType.needSeq(mInfo.type)){
// RequestCache reqc = NodeCenterActions.getCache(contractID);
// reqc.put(args.get("seq").getAsString(),args);
// }
// }
@Action(async = true, userPermission = 1L << 6)
public void listContractProcess(JsonObject args, final ResultCallback rc) {
Map<String, Object> ret = new HashMap<>();
ret.put("action", "onListContractProcess");
List<ContractDesp> info = new ArrayList<>();
LOGGER.debug(
"[contracts] "
+ JsonUtil.toPrettyJson(NodeCenterActions.nodeInfos));
LOGGER.debug(
"[cid2Nodes]"
+ JsonUtil.toPrettyJson(NodeCenterActions.contractID2Members));
for (String key : NodeCenterActions.contractID2Members.keySet()) {
ContractDesp desp = NodeCenterActions.getContractByID(key);
if (desp != null) info.add(desp);
}
ret.put("data", JsonUtil.toJson(info));
rc.onResult(JsonUtil.toJson(ret));
}
@Action(userPermission = 1 << 6, async = true)
public void listMultiPointContractProcess(JsonObject json, ResultCallback resultCallback) {
Map<String, Object> ret = new HashMap<>();
ret.put("action", "onListMultiPointContractProcess");
List<ContractDesp> info = new ArrayList<>();
LOGGER.debug(
"[contracts] "
+ JsonUtil.toPrettyJson(NodeCenterActions.nodeInfos));
LOGGER.debug(
"[cid2Nodes]"
+ JsonUtil.toPrettyJson(NodeCenterActions.contractID2Members));
for (String key : NodeCenterActions.contractID2Members.keySet()) {
ContractDesp desp = NodeCenterActions.getContractByID(key);
if (desp != null) info.add(desp);
}
ret.put("data", JsonUtil.toJson(info));
resultCallback.onResult(JsonUtil.toJson(ret));
}
@Action(userPermission = 1 << 6, async = true)
public void stopMultiPointContractProcess(JsonObject json, ResultCallback resultCallback) {
String contractID = json.get("contractID").getAsString();
MultiPointContractInfo info = NodeCenterActions.contractID2Members.get(contractID);
NodeCenterActions.contractID2Members.remove(contractID);
String req = "{\"action\":\"killContractProcess\",\"contractID\":\"" + contractID + "\"}";
for (String member : info.members) {
CMNode node;
node = NodeCenterActions.nodeInfos.get(member);
node.connection.controller.sendMsg(req);
}
listMultiPointContractProcess(json, resultCallback);
}
// @Action(async = true, userPermission = 1L << 6)
// public void startContractMultiPoint(JsonObject args, final ResultCallback rc) {
// Map<String, String> request = new HashMap<String, String>();
// Contract contract = new Contract();
// if (args.has("type")) {
// contract.setType(ContractType.valueOf(args.get("type").getAsString()));
// }
//
// // this multiPointContractInfo problem
// MultiPointContractInfo multiPointContractInfo = new MultiPointContractInfo();
// multiPointContractInfo.type = contract.getType();
//
// logger.debug("startContractMultiPoint:");
// logger.debug(JsonUtil.toPrettyJson(args));
// if (args.has("script")) contract.setScript(args.get("script").getAsString());
// else if (args.has("path")) contract.setScript(args.get("path").getAsString());
// else if (args.has("projectName"))
// contract.setScript("/" + args.get("projectName").getAsString());
// // contract.setScript("/" + args.get("projectName").getAsString() + "/manifest.json");
//
// SM2 sm2 = new SM2();
// SM2KeyPair sm2Key = sm2.generateKeyPair();
// contract.setID(sm2Key.getPublicKeyStr().hashCode() + "");
// contract.setKey(sm2Key.getPrivateKey().toString(16));
// contract.setPublicKey(sm2Key.getPublicKeyStr());
//
// contract.setNodeCenterRepoDOI(DOIPMainServer4NC.repoIdentifier);
// // 多点合约部署时由NC预先注册一个DOI以备使用
// if (DoConfig.openContractDORegister) {
// try {
// HandleService hs = new HandleService(HandleServiceUtils.hrRegister);
// String tmpDOI = hs.registerContract(DOIPMainServer4NC.repoIdentifier);
// if (tmpDOI == "" || tmpDOI == null)
// contract.setDOI("RegisterFailed");
// else
// contract.setDOI(tmpDOI);
// }
// catch (Exception e) {
// e.printStackTrace();
// contract.setDOI("RegisterFailed");
// }
// }
//
// String[] nodeNames =
// args.get("peersID").getAsString().split(","); // all nodes' peerID in the unit
// Set<String> nodeNameSet = new HashSet<>(); // nodes' peerID
// for (String str : nodeNames) {
// if (str != null && str.length() > 0) nodeNameSet.add(str);
// }
//
// List<String> udpids = new ArrayList<>(); // nodes' udpID in the unit
//
// for (CMNode node : NodeCenterActions.nodeinfos.values()) {
// if (nodeNameSet.contains(node.nodeName)) {
// udpids.add(node.udpID);
// }
// }
// final long curr = System.currentTimeMillis();
// String requestID = curr + "_" + (int) (Math.random() * 10000);
// NodeCenterActions.ResultCollector collector =
// new NodeCenterActions.ResultCollector(
// requestID,
// new ResultCallback() {
// @Override
// public void onResult(String str) {
// Map<String, String> ret = new HashMap<>();
// ret.put("action", "onStartContractTrustfullyResult");
// ret.put("data", str);
// ret.put("executionTime", (System.currentTimeMillis() - curr) + "");
// rc.onResult(JsonUtil.toJson(ret));
// }
// },
// udpids.size());
// NodeCenterActions.sync.sleepWithTimeout(requestID, collector, 20);
//
// // ArrayList<String> udpids=gson.fromJson(args.get("members"),
// // new TypeToken<ArrayList<String>>(){}.getType());
// Map<String, String> members = new HashMap<>(); // nodes' <udpID,udpAddress>
// for (int i = 0; i < udpids.size(); i++) {
// members.put(
// udpids.get(i),
// NodeCenterActions.runner.getUDPAddr(Integer.valueOf(udpids.get(i)))
// + ":"
// + (i == 0)); // regard the first node as the master in the unit
// }
//
// List<String> nodes = new ArrayList<>(); // nodes' pubKey
// for (CMNode node : NodeCenterActions.nodeinfos.values()) {
// if (nodeNameSet.contains(node.nodeName)) {
// nodes.add(node.pubKey);
// }
// }
//
// request.put("memberStr", JsonUtil.toJson(members));
// request.put("isPrivate", args.get("isPrivate").getAsString());
// request.put("pubKey", managerAction.pubKey);
// request.put("action", "startContractTrustfully");
// request.put("requestID", requestID);
// multiPointContractInfo.members = nodes;
//
// contract.setNumOfCopies(1);
// switch (multiPointContractInfo.type) {
// case Sole:
// logger.debug("Can't support Solo in multi-point mode");
// return;
// case RequestOnce:
// multiPointContractInfo.rcf = new RequestOnceExecutor(multiPointContractInfo);
// break;
// case ResponseOnce:
// multiPointContractInfo.rcf = new ResponseOnceExecutor(multiPointContractInfo);
// break;
// case RequestAllResponseFirst:
// multiPointContractInfo.rcf = new RequestAllExecutor(multiPointContractInfo, 1);
// contract.setNumOfCopies(nodes.size());
// break;
// case RequestAllResponseHalf:
// multiPointContractInfo.rcf =
// new RequestAllExecutor(multiPointContractInfo, nodes.size() / 2 + 1);
// contract.setNumOfCopies(nodes.size());
// break;
// case RequestAllResponseAll:
// multiPointContractInfo.rcf =
// new RequestAllExecutor(multiPointContractInfo, nodes.size());
// contract.setNumOfCopies(nodes.size());
// break;
// }
// NodeCenterActions.contractID2Members.put(contract.getID(), multiPointContractInfo);
//
// request.put("contractStr", JsonUtil.toJson(contract));
// String startReq = JsonUtil.toJson(request);
// logger.debug("启动合约:" + startReq);
//
// for (String nodeID : nodes) {
// CMNode node;
// node = NodeCenterActions.nodeinfos.get(nodeID);
// node.connection.controller.sendMsg(startReq);
//
// if (!NodeCenterActions.recoverMap.containsKey(nodeID)) {
// NodeCenterActions.recoverMap.put(nodeID, new ConcurrentHashMap<>());
// }
// ContractRecord record = new ContractRecord(contract.getID());
// record.members = new HashMap<>(members);
// NodeCenterActions.recoverMap.get(nodeID).put(contract.getID(), record);
// }
//
// rc.onResult(
// "{\"status\":\"Success\",\"result\":\""
// + contract.getID()
// + "\",\"action\":\"onStartTrustfulContract\"}");
// }
private void example() {
for (CMNode node : NodeCenterActions.nodeInfos.values()) {
// node.connection.executeContractTrustfully(args, rc);
}
}
}

View File

@ -0,0 +1,104 @@
package org.bdware.server.nodecenter.searchresult;
public class ContractMeta {
private String contractID;
private String name;
private String status;
private String pubkey;
private String owner;
private String readmeStr;
private String nodeAddr;
private String pngUrl;
private String doi;
private long buildTime;
private String doip;
public String getContractID() {
return contractID;
}
public void setContractID(String contractID) {
this.contractID = contractID;
}
public String getPubkey() {
return pubkey;
}
public void setPubkey(String pubkey) {
this.pubkey = pubkey;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public String getReadmeStr() {
return readmeStr;
}
public void setReadmeStr(String readmeStr) {
this.readmeStr = readmeStr;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getNodeAddr() {
return nodeAddr;
}
public void setNodeAddr(String nodeAddr) {
this.nodeAddr = nodeAddr;
}
public String getPngUrl() {
return pngUrl;
}
public void setPngUrl(String pngUrl) {
this.pngUrl = pngUrl;
}
public String getDoi() {
return doi;
}
public void setDoi(String doi) {
this.doi = doi;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getBuildTime() {
return buildTime;
}
public void setBuildTime(long buildTime) {
this.buildTime = buildTime;
}
public String getDoip() {
return doip;
}
public void setDoip(String doip) {
this.doip = doip;
}
}

View File

@ -0,0 +1,42 @@
package org.bdware.server.nodecenter.searchresult;
import java.util.List;
public class ResultModel {
private List<ContractMeta> contractMetaList;
private Long contractCount;
private Long pageCount;
private long curPage;
public List<ContractMeta> getContractMetaList() {
return contractMetaList;
}
public void setContractMetaList(List<ContractMeta> contractMetaList) {
this.contractMetaList = contractMetaList;
}
public Long getContractCount() {
return contractCount;
}
public void setContractCount(Long contractCount) {
this.contractCount = contractCount;
}
public Long getPageCount() {
return pageCount;
}
public void setPageCount(Long pageCount) {
this.pageCount = pageCount;
}
public long getCurPage() {
return curPage;
}
public void setCurPage(long curPage) {
this.curPage = curPage;
}
}

View File

@ -0,0 +1,8 @@
### 设置###
log4j.rootLogger = info,debug,stdout
### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{HH:mm:ss.SSS} %m (%F:%L)[%M]%n

View File

@ -0,0 +1,15 @@
filter.threshold.type=ThresholdFilter
filter.threshold.level=debug
appender.console.type=Console
appender.console.name=STDOUT
appender.console.layout.type=PatternLayout
appender.console.layout.pattern=%highlight{[%-5p] %d{HH:mm:ss.SSS} %m (%F:%L)[%M]%n}{FATAL=Bright Red,ERROR=Red,WARN=Yellow,INFO=Green,DEBUG=Blue,TRACE=White}
appender.rolling.type=File
appender.rolling.name=log
appender.rolling.append=true
appender.rolling.fileName=./log/nc.log
appender.rolling.layout.type=PatternLayout
appender.rolling.layout.pattern=%d-%m%n
rootLogger.level=info
rootLogger.appenderRef.stdout.ref=STDOUT
rootLogger.appenderRef.log.ref=log

View File

@ -0,0 +1,63 @@
////////// Punctuation tokens to remove ////////////////
,
.
`
-
_
=
?
'
|
"
(
)
{
}
[
]
<
>
*
#
&
^
$
@
!
~
:
;
+
/
\
·
// the line below contains an IDEOGRAPHIC SPACE character (Used as a space in Chinese)
 
//////////////// English Stop Words ////////////////
//////////////// Chinese Stop Words ////////////////

View File

@ -0,0 +1,127 @@
package org.bdware.bdserver;
import com.google.gson.Gson;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bdware.doip.core.exception.IrpClientException;
import org.bdware.doip.core.model.handleRecord.DoHandleRecord;
import org.bdware.doip.core.model.handleRecord.DoipServiceHandleRecord;
import org.bdware.doip.core.model.handleRecord.HandleRecordBase;
import org.bdware.doip.core.utils.GlobalConfigurations;
import org.bdware.doip.endpoint.irpClient.InternalIrpClient;
import org.bdware.doip.endpoint.irpClient.IrpClient;
import org.junit.Before;
import org.junit.Test;
public class IRPTest {
private static final Logger LOGGER = LogManager.getLogger(IRPTest.class);
IrpClient client;
@Before
public void createTestClient() {
GlobalConfigurations.LHS_Address = "http://127.0.0.1:18007/";
client = new InternalIrpClient(null, "86.5000.470/dou.SUPER", GlobalConfigurations.LHS_Address);
}
@Test
public void testReslove() {
HandleRecordBase handleRecordBase = null;
try {
handleRecordBase = client.resolve("86.5000.470/doip.iZWUqzwFtY_bdw");
} catch (IrpClientException e) {
e.printStackTrace();
}
LOGGER.info(new Gson().toJson(handleRecordBase));
}
@Test
public void testRegister() {
DoHandleRecord doHr = new DoHandleRecord(GlobalConfigurations.User_Handle, "null");
DoipServiceHandleRecord doipServiceHandleRecord = new DoipServiceHandleRecord("1", "2", "3", "4", "5");
String handle = "86.5000.470/do.yWkNN8otdv_bdw";
// doHr.handle = handle;
try {
handle = client.register(doipServiceHandleRecord);
LOGGER.debug(handle);
//test resolve
HandleRecordBase handleRecordBase = client.resolve(handle);
LOGGER.info(new Gson().toJson(handleRecordBase));
} catch (IrpClientException e) {
e.printStackTrace();
}
}
@Test
public void testUnregister() {
String handle = "86.5000.470/do.A0gOqH2hup_bdw";
String resp = client.unRegister(handle);
LOGGER.info(resp);
}
@Test
public void testReRegister() {
DoHandleRecord doHr = new DoHandleRecord(GlobalConfigurations.User_Handle, "12345");
String handle = "86.5000.470/do.Y1LnYqyH5F_bdw";
doHr.handle = handle;
try {
handle = client.reRegister(doHr);
LOGGER.debug(handle);
//test resolve
HandleRecordBase handleRecordBase = client.resolve(handle);
LOGGER.debug(new Gson().toJson(handleRecordBase));
} catch (IrpClientException e) {
e.printStackTrace();
}
}
@Test
public void pumpDataIntoLhs() {
DoHandleRecord doHr = new DoHandleRecord(GlobalConfigurations.User_Handle, "null");
DoipServiceHandleRecord doipServiceHandleRecord = new DoipServiceHandleRecord("1", "2", "3", "4", "5");
String handle;
// doHr.handle = handle;
try {
for (int i = 0; i < 20; i++) {
handle = client.register(doipServiceHandleRecord);
LOGGER.info(handle);
handle = client.register(doHr);
LOGGER.info(handle);
}
// handle = client.register(doipServiceHandleRecord);
// logger.debug(handle);
// //test resolve
// HandleRecordBase handleRecordBase = client.resolve(handle);
// logger.info(new Gson().toJson(handleRecordBase));
} catch (IrpClientException e) {
e.printStackTrace();
}
}
// @Test
// public void updateUserHandleRecord(){
// if (Security.getProvider("BC") == null) {
// Security.addProvider(new BouncyCastleProvider());
// }
//
// try {
// GlobalCertifications.loadKeysFromJKS("keys/dou.SUPER.keystore", GlobalConfigurations.certPassword);
// } catch (Exception e) {
// e.printStackTrace();
// }
//
// GlobalIrpClient.useGeneralIrpClient(GlobalCertifications.localKeypair
// , GlobalConfigurations.User_Handle
// , GlobalConfigurations.LHS_Address);
//
// UserHandleRecord usr = new UserHandleRecord(JWK.getJWKFormatPK(GlobalCertifications.getGlobalKeypair().getPublic()),"SUPER USER");
// usr.handle = "86.5000.470/dou.SUPER";
// try {
// String out = client.reRegister(usr);
// logger.debug(out);
// logger.debug("Resolution: " + client.resolve(usr.handle));
// } catch (IrpClientException e) {
// e.printStackTrace();
// }
// }
}

View File

@ -0,0 +1,82 @@
package org.bdware.bdserver;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import org.bdware.sc.conn.ResultCallback;
import org.bdware.server.action.Action;
import org.bdware.server.action.ActionExecutor;
import org.bdware.server.nodecenter.NCHttpHandler;
import org.bdware.server.nodecenter.NodeCenterWSFrameHandler;
import org.bdware.server.permission.Role;
import org.junit.Test;
import java.lang.reflect.Method;
import java.util.*;
public class PermissionHelper {
static class Line {
String action;
transient long permission;
String roles;
}
@Test
public void listClusterHttpAction() {
ActionExecutor<ResultCallback, JsonObject> ae = NCHttpHandler.getActionExecutor();
Map<String, ActionExecutor.Pair<Method, Object>> handlers = ae.getHandlers();
EnumSet<Role> set = EnumSet.allOf(Role.class);
set.remove(Role.ContractInstanceManager);
set.remove(Role.ContractProvider);
set.remove(Role.ContractUser);
printActions(handlers, set);
}
@Test
public void listClusterWSAction() {
NodeCenterWSFrameHandler handler = new NodeCenterWSFrameHandler();
Map<String, ActionExecutor.Pair<Method, Object>> handlers = handler.getAE().getHandlers();
EnumSet<Role> set = EnumSet.allOf(Role.class);
set.remove(Role.ContractInstanceManager);
set.remove(Role.ContractProvider);
set.remove(Role.ContractUser);
printActions(handlers, set);
}
private void printActions(
Map<String, ActionExecutor.Pair<Method, Object>> handlers, EnumSet<Role> set) {
List<Line> lines = new ArrayList<>();
for (String str : handlers.keySet()) {
Method m = handlers.get(str).first();
Action a = m.getAnnotation(Action.class);
Line l = new Line();
lines.add(l);
l.action = str;
l.permission = a.userPermission();
l.roles = "";
for (Role r : set)
if ((r.getValue() & l.permission) == l.permission) l.roles += r.name() + ";";
if (l.roles.equals("CenterManager;NodeManager;Node;Anonymous;")) l.roles = "任意角色";
}
lines.sort(
new Comparator<Line>() {
@Override
public int compare(Line o1, Line o2) {
return o1.action.compareTo(o2.action);
}
});
lines.sort(
new Comparator<Line>() {
@Override
public int compare(Line o1, Line o2) {
return o1.roles.compareTo(o2.roles);
}
});
Gson g = new GsonBuilder().setPrettyPrinting().create();
for (Line l : lines) {
System.out.println("| " + l.action + " | | " + l.roles + " |");
}
}
}

View File

@ -0,0 +1,31 @@
package org.bdware.bdserver;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class TestServer {
private static final Logger LOGGER = LogManager.getLogger(TestServer.class);
static class TestHandler extends SimpleChannelInboundHandler<ByteBuf> {
TestHandler() {
LOGGER.info("new instance");
}
@Override
public void channelActive(ChannelHandlerContext ctx) {
LOGGER.info("active");
System.out.println("======Active=======");
ctx.channel()
.writeAndFlush("ACTIVE from Server")
.addListener(future -> LOGGER.info("Active Send Done!!"));
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) {
LOGGER.info("receive");
}
}
}

View File

@ -0,0 +1,192 @@
package org.bdware.bdserver.test;
public class TestADSP {
// public static Map<String,String> nodes = new HashMap<String,String>();
//
// private static volatile Boolean flag = false;
// private static int totalRequest = 10;
// private static int nodeCount = 5;
//
// public static String resultPath = "./testADSP/" + "result.txt";
// public static String contractID = "counter";
// public static String action = "executeContract";
// public static String pubkey = "0480204f4ef341359a5f64fcb11baf9ca2e6706ac20cba36ca83066870cf2c1d5de6df67e24e68dde7934af9b31d94a6084281db3d32d5ce42ab8f75bf799aca05";
//
// public static String operation = "count";
// public static String arg = "1";
//
// public static String priKey = "63464fa9587bbf2a022b3d655f4ed49c7d9a4249de1079d52bd5a1fec3308719";
// public static String signature = "dfd07c00c5c89fb0f901bed132db4342f49f4560f34c15878636623d2a8716a2c93ad32eeb9ee9c4f1d905df292cb4a1a27aa0171f2856848ce07cfc8022e809";
//
// public static List<String> crashSeries = new ArrayList<String>();
// public static AtomicInteger crashIndex = new AtomicInteger();
//
// public static ConcurrentSet<String> crashSet = new ConcurrentSet<String>();
// public static ConcurrentSet<String> recover = new ConcurrentSet<String>();
//
// public static TestTask tt;
// public static int period = 3000;
//
// static{
// getSig();
//
// nodes.put("zyx's book","0440023d13facddcefbd87f2bb622b1b2b6ca43eb84c0579b82450814233ce557bd7ad7852cd47f1d6df867c5413ecf3dd1954cdbf5a6da683e3a89095f091d83d");
// nodes.put("localNode1","0480f783cf63294224afbd19e175e5c7ea0c5c60ee115ed9e114fe2691eb28cc1680e5fec532d64c80d2f6b737e8b43b94d5a9c73206ac6235c50ff992133e4d38");
// nodes.put("localNode2","044e0c127e24407ee8a8abd4fe507b32b340ce9775317b8d7b5bb8e182745d6a45c57aaf867d80a5f816a7561564f9294c6aee5916f95e93c0011e16c28b9e849a");
// nodes.put("localNode3","0485040cfd94bec672bb8ba184856188963ee4ad339d247a76e2d9819f20e61bfad24ec763b1371998583f9dc0cf55c4d53cb1a2ec84c67aed1aa5203cc84fc78f");
// nodes.put("localNode4","");
// nodes.put("localNode5","");
//
//
// //生成崩溃序列
// crashSeries.clear();
// for(int i = 1;i <= totalRequest;i++){
// int temp = i % nodeCount;
// if(temp == 0)
// temp = nodeCount;
// crashSeries.add("crash localNode" + temp);
// crashSeries.add("recover localNode" + temp);
// }
//
// System.out.println("崩溃序列" + crashSeries.size());
//
// Timer timer = new Timer();
// tt = new TestTask();
// timer.schedule(tt, new Date(), period);
// }
//
// static class TestTask extends TimerTask {
// @Override
// public void run() {
// if(TestADSP.getFlag()){
// int index = TestADSP.crashIndex.getAndIncrement();
// System.out.println("[TestADSP] index=" + TestADSP.crashIndex.get());
//
// String[] crash = TestADSP.crashSeries.get(index).split(" ");
// String pubKey = convertNameToPubkey(crash[1]);
// switch (crash[0]){
// case "crash":
// if(pubKey != null){
// System.out.println("[TestADSP] 令节点 " + crash[1] + "崩溃");
// System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(System.currentTimeMillis())));
// crashSet.add(pubKey);
// }
// break;
// case "recover":
// if(pubKey != null){
// if(crashSet.contains(pubKey)){
// crashSet.remove(pubKey);
// }
// recover.add(pubKey);
// System.out.println("[TestADSP] 令节点 " + crash[1] + "上线");
// System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(System.currentTimeMillis())));
// }
// break;
// default:
// break;
// }
//
//
// try {
// Thread.sleep(period / 2);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
//
//
//
// System.out.println("[TestADSP]发起请求 " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(System.currentTimeMillis())));
// JsonObject jo = new JsonObject();
// jo.addProperty("action", TestADSP.action);
// jo.addProperty("contractID", TestADSP.contractID);
// jo.addProperty("operation", TestADSP.operation);
// jo.addProperty("arg", TestADSP.arg);
// jo.addProperty("pubkey",TestADSP.pubkey);
// jo.addProperty("signature",TestADSP.signature);
// UnitActions.testExecuteContract(jo,null);
//
// if(index == (TestADSP.crashSeries.size() - 1)){
// System.out.println("测试停止!");
// TestADSP.setFlag(false);
// //TestADSP.check();
// }
// }//if
// }
// }
//
// public static boolean getFlag(){
// boolean temp;
// synchronized (flag){
// temp = flag;
// }
// return temp;
// }
//
// public static void setFlag(boolean temp){
// synchronized (flag){
// flag = temp;
// System.out.println("[TestADSP]设置flag为" + flag);
// }
// }
//
// public static void getSig(){
// String temp = contractID + "|" + operation + "|" + arg + "|" + pubkey;
// SM2 sm2 = new SM2();
// signature = sm2.sign(temp.getBytes(),priKey).toString();
// }
//
// //查看结果输出文件
// public static void check() {
// tt.cancel();
//
// int correct = 0;
// int incorrect = 0;
// int unavailable = 0;
// int fileTotal = 0;
//
// File file = new File("./front-cluster/testADSP/result.txt");
// System.out.println(file.getAbsolutePath());
// StringBuilder result = new StringBuilder();
// try{
// BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));//构造一个BufferedReader类来读取文件
//
// String s = null;
// while((s = br.readLine())!=null){//使用readLine方法一次读一行
// if(!s.equals("")){
// fileTotal++;
// String str[] = s.split(" ");
// if(str[1].equals((Integer.parseInt(str[0]) + 1) + ".0")){
// correct++;
// }else{
// incorrect++;
// }
// }
// }
// br.close();
//
// }catch(Exception e){
// e.printStackTrace();
// }
//
// unavailable = totalRequest * 2 - fileTotal;
//
// System.out.println("共有" + totalRequest * 2 + "次请求,其中" + correct + "正确," + incorrect + "不正确," + unavailable + "不可用.");
// }
//
// public static String convertNameToPubkey(String nodeName){
// return nodes.get(nodeName);
// }
//
// public static String convertPubKeyToName(String pubkey){
// for(String key : nodes.keySet()){
// if(nodes.get(key).equals(pubkey)){
// return key;
// }
// }
// return null;
// }
//
// public static void main(String[] args){
// check();
// }
}

View File

@ -0,0 +1,84 @@
package org.bdware.bdserver.test;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.bdware.sc.http.HttpUtil;
import org.bdware.sc.util.JsonUtil;
import org.junit.Test;
import java.nio.file.Paths;
public class TestSearch {
private static final Logger LOGGER = LogManager.getLogger(TestSearch.class);
@Test
public void test() {
String url = "http://127.0.0.1:18005/doip?pubkey=04&owner=0&contractID=0&readmeStr=0";
LOGGER.info(JsonUtil.toJson(HttpUtil.httpGet(url)));
}
@Test
public void testIndexSearch() throws Exception {
//1. 创建分词器(对搜索的关键词进行分词使用)
//注意: 分词器要和创建索引的时候使用的分词器一模一样
Analyzer analyzer = new StandardAnalyzer();
//2. 创建查询对象,
//第一个参数: 默认查询域, 如果查询的关键字中带搜索的域名, 则从指定域中查询, 如果不带域名则从, 默认搜索域中查询
//第二个参数: 使用的分词器
QueryParser queryParser = new QueryParser("name", analyzer);
//3. 设置搜索关键词
// OR
Query query = queryParser.parse("华为手机");
//4. 创建Directory目录对象, 指定索引库的位置
Directory dir = FSDirectory.open(Paths.get("E:\\dir"));
//5. 创建输入流对象
IndexReader indexReader = DirectoryReader.open(dir);
//6. 创建搜索对象
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
//7. 搜索, 并返回结果
//第二个参数: 是返回多少条数据用于展示, 分页使用
TopDocs topDocs = indexSearcher.search(query, 10);
//获取查询到的结果集的总数, 打印
System.out.println("=======count=======" + topDocs.totalHits);
//8. 获取结果集
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
//9. 遍历结果集
if (scoreDocs != null) {
for (ScoreDoc scoreDoc : scoreDocs) {
//获取查询到的文档唯一标识, 文档id, 这个id是lucene在创建文档的时候自动分配的
int docID = scoreDoc.doc;
//通过文档id, 读取文档
Document doc = indexSearcher.doc(docID);
System.out.println("==================================================");
//通过域名, 从文档中获取域值
System.out.println("===id==" + doc.get("id"));
System.out.println("===name==" + doc.get("name"));
System.out.println("===price==" + doc.get("price"));
System.out.println("===image==" + doc.get("image"));
System.out.println("===brandName==" + doc.get("brandName"));
System.out.println("===categoryName==" + doc.get("categoryName"));
}
}
//10. 关闭流
}
}

View File

@ -0,0 +1,246 @@
package org.bdware.bdserver.testLucene;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.*;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.junit.Test;
import javax.json.JsonObject;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public class TestManager {
/**
* 创建索引库
*/
@Test
public void createIndexTest() throws Exception {
//1. 采集数据
SkuDao skuDao = new SkuDaoImpl();
List<Sku> skuList = skuDao.querySkuList();
//文档集合
List<Document> docList = new ArrayList<>();
for (Sku sku : skuList) {
//2. 创建文档对象
Document document = new Document();
//创建域对象并且放入文档对象中
/**
* 是否分词: 否, 因为主键分词后无意义
* 是否索引: 是, 如果根据id主键查询, 就必须索引
* 是否存储: 是, 因为主键id比较特殊, 可以确定唯一的一条数据, 在业务上一般有重要所用, 所以存储
* 存储后, 才可以获取到id具体的内容
*/
document.add(new StringField("id", sku.getId(), Field.Store.YES));
/**
* 是否分词: 是, 因为名称字段需要查询, 并且分词后有意义所以需要分词
* 是否索引: 是, 因为需要根据名称字段查询
* 是否存储: 是, 因为页面需要展示商品名称, 所以需要存储
*/
document.add(new TextField("name", sku.getName(), Field.Store.YES));
/**
* 是否分词: 是(因为lucene底层算法规定, 如果根据价格范围查询, 必须分词)
* 是否索引: 是, 需要根据价格进行范围查询, 所以必须索引
* 是否存储: 是, 因为页面需要展示价格
*/
document.add(new IntPoint("price", sku.getPrice()));
document.add(new StoredField("price", sku.getPrice()));
/**
* 是否分词: 否, 因为不查询, 所以不索引, 因为不索引所以不分词
* 是否索引: 否, 因为不需要根据图片地址路径查询
* 是否存储: 是, 因为页面需要展示商品图片
*/
document.add(new StoredField("image", sku.getImage()));
/**
* 是否分词: 否, 因为分类是专有名词, 是一个整体, 所以不分词
* 是否索引: 是, 因为需要根据分类查询
* 是否存储: 是, 因为页面需要展示分类
*/
document.add(new StringField("categoryName", sku.getCategoryName(), Field.Store.YES));
/**
* 是否分词: 否, 因为品牌是专有名词, 是一个整体, 所以不分词
* 是否索引: 是, 因为需要根据品牌进行查询
* 是否存储: 是, 因为页面需要展示品牌
*/
document.add(new StringField("brandName", sku.getBrandName(), Field.Store.YES));
//将文档对象放入到文档集合中
docList.add(document);
}
//3. 创建分词器, StandardAnalyzer标准分词器, 对英文分词效果好, 对中文是单字分词, 也就是一个字就认为是一个词.
Analyzer analyzer = new IKAnalyzer();
//4. 创建Directory目录对象, 目录对象表示索引库的位置
Directory dir = FSDirectory.open(Paths.get("E:\\dir"));
//5. 创建IndexWriterConfig对象, 这个对象中指定切分词使用的分词器
IndexWriterConfig config = new IndexWriterConfig(analyzer);
//6. 创建IndexWriter输出流对象, 指定输出的位置和使用的config初始化对象
IndexWriter indexWriter = new IndexWriter(dir, config);
//7. 写入文档到索引库
for (Document doc : docList) {
indexWriter.addDocument(doc);
}
//8. 释放资源
indexWriter.close();
}
/**
* 索引库修改操作
* @throws Exception
*/
@Test
public void updateIndexTest() throws Exception {
//需要变更成的内容
Document document = new Document();
document.add(new StringField("id", "100000003145", Field.Store.YES));
document.add(new TextField("name", "xxxx", Field.Store.YES));
document.add(new IntPoint("price", 123));
document.add(new StoredField("price", 123));
document.add(new StoredField("image", "xxxx.jpg"));
document.add(new StringField("categoryName", "手机", Field.Store.YES));
document.add(new StringField("brandName", "华为", Field.Store.YES));
//3. 创建分词器, StandardAnalyzer标准分词器, 对英文分词效果好, 对中文是单字分词, 也就是一个字就认为是一个词.
Analyzer analyzer = new StandardAnalyzer();
//4. 创建Directory目录对象, 目录对象表示索引库的位置
Directory dir = FSDirectory.open(Paths.get("E:\\dir"));
//5. 创建IndexWriterConfig对象, 这个对象中指定切分词使用的分词器
IndexWriterConfig config = new IndexWriterConfig(analyzer);
//6. 创建IndexWriter输出流对象, 指定输出的位置和使用的config初始化对象
IndexWriter indexWriter = new IndexWriter(dir, config);
//修改, 第一个参数: 修改条件, 第二个参数: 修改成的内容
indexWriter.updateDocument(new Term("id", "100000003145"), document);
//8. 释放资源
indexWriter.close();
}
/**
* 测试根据条件删除
* @throws Exception
*/
@Test
public void deleteIndexTest() throws Exception {
//3. 创建分词器, StandardAnalyzer标准分词器, 对英文分词效果好, 对中文是单字分词, 也就是一个字就认为是一个词.
Analyzer analyzer = new StandardAnalyzer();
//4. 创建Directory目录对象, 目录对象表示索引库的位置
Directory dir = FSDirectory.open(Paths.get("E:\\dir"));
//5. 创建IndexWriterConfig对象, 这个对象中指定切分词使用的分词器
IndexWriterConfig config = new IndexWriterConfig(analyzer);
//6. 创建IndexWriter输出流对象, 指定输出的位置和使用的config初始化对象
IndexWriter indexWriter = new IndexWriter(dir, config);
//测试根据条件删除
//indexWriter.deleteDocuments(new Term("id", "100000003145"));
//测试删除所有内容
indexWriter.deleteAll();
//8. 释放资源
indexWriter.close();
}
/**
* 测试创建索引速度优化
* @throws Exception
*/
@Test
public void createIndexTest2() throws Exception {
//1. 采集数据
SkuDao skuDao = new SkuDaoImpl();
List<Sku> skuList = skuDao.querySkuList();
//文档集合
List<Document> docList = new ArrayList<>();
for (Sku sku : skuList) {
//2. 创建文档对象
Document document = new Document();
document.add(new StringField("id", sku.getId(), Field.Store.YES));
document.add(new TextField("name", sku.getName(), Field.Store.YES));
document.add(new IntPoint("price", sku.getPrice()));
document.add(new StoredField("price", sku.getPrice()));
document.add(new StoredField("image", sku.getImage()));
document.add(new StringField("categoryName", sku.getCategoryName(), Field.Store.YES));
document.add(new StringField("brandName", sku.getBrandName(), Field.Store.YES));
//将文档对象放入到文档集合中
docList.add(document);
}
long start = System.currentTimeMillis();
//3. 创建分词器, StandardAnalyzer标准分词器, 对英文分词效果好, 对中文是单字分词, 也就是一个字就认为是一个词.
Analyzer analyzer = new StandardAnalyzer();
//4. 创建Directory目录对象, 目录对象表示索引库的位置
Directory dir = FSDirectory.open(Paths.get("E:\\dir"));
//5. 创建IndexWriterConfig对象, 这个对象中指定切分词使用的分词器
/**
* 没有优化 小100万条数据, 创建索引需要7725ms
*
*/
IndexWriterConfig config = new IndexWriterConfig(analyzer);
//设置在内存中多少个文档向磁盘中批量写入一次数据
//如果设置的数字过大, 会过多消耗内存, 但是会提升写入磁盘的速度
//config.setMaxBufferedDocs(500000);
//6. 创建IndexWriter输出流对象, 指定输出的位置和使用的config初始化对象
IndexWriter indexWriter = new IndexWriter(dir, config);
//设置多少给文档合并成一个段文件,数值越大索引速度越快, 搜索速度越慢; 值越小索引速度越慢, 搜索速度越快
//indexWriter.forceMerge(1000000);
//7. 写入文档到索引库
for (Document doc : docList) {
indexWriter.addDocument(doc);
}
//8. 释放资源
indexWriter.close();
long end = System.currentTimeMillis();
System.out.println("=====消耗的时间为:==========" + (end - start) + "ms");
}
private String getRmAsString(JsonObject arg) {
try {
ContractMeta meta =
CMActions.manager.statusRecorder.getContractMeta(
arg.get("contractID").getAsString());
String path = arg.get("assets/README.md").getAsString();
ZipFile zipFile = new ZipFile(new File(meta.contract.getScriptStr()));
ZipEntry zipEntry = zipFile.getEntry(path);
InputStream sc = loadAsInputStream(path);
ByteArrayOutputStream bo = new ByteArrayOutputStream();
byte[] buff = new byte[1024];
for (int k = 0; (k = sc.read(buff)) > 0; ) {
bo.write(buff, 0, k);
}
return new String(bo.toByteArray());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}

View File

@ -0,0 +1,12 @@
package org.bdware.bdserver.testLucene;
import org.bdware.server.nodecenter.MetaIndexAction;
import org.junit.Test;
public class WordSegmentationTest {
@Test
public void go(){
MetaIndexAction i = new MetaIndexAction();
i.segmentWord(null,null);
}
}

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.

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.

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.