mirror of
https://gitee.com/BDWare/front-base
synced 2025-01-09 17:34:01 +00:00
initial commit
This commit is contained in:
parent
454ee4d5c9
commit
2cf6886649
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
|||||||
|
/build
|
||||||
# Compiled class file
|
# Compiled class file
|
||||||
*.class
|
*.class
|
||||||
|
|
||||||
|
33
build.gradle
Normal file
33
build.gradle
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
plugins {
|
||||||
|
id 'java'
|
||||||
|
id 'java-library'
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
main {
|
||||||
|
java {
|
||||||
|
srcDirs 'src/main/src', 'src/main/thirdparty', 'src/main/test'
|
||||||
|
}
|
||||||
|
resources {
|
||||||
|
srcDir 'src/main/resources'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
test {
|
||||||
|
java {
|
||||||
|
srcDir 'src/test/java'
|
||||||
|
}
|
||||||
|
resources {
|
||||||
|
srcDir 'src/test/resources'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
api project (":common")
|
||||||
|
api 'io.netty:netty-all:4.1.52.Final'
|
||||||
|
api 'io.netty:netty-tcnative-boringssl-static:2.0.41.Final'
|
||||||
|
api 'org.apache.logging.log4j:log4j-core:2.14.1'
|
||||||
|
api 'org.apache.logging.log4j:log4j-api:2.14.1'
|
||||||
|
api 'com.google.code.gson:gson:2.8.8'
|
||||||
|
|
||||||
|
testImplementation 'junit:junit:4.13.2'
|
||||||
|
}
|
52
src/main/src/org/bdware/server/ByteHexUtil.java
Normal file
52
src/main/src/org/bdware/server/ByteHexUtil.java
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package org.bdware.server;
|
||||||
|
|
||||||
|
public class ByteHexUtil {
|
||||||
|
protected static final char[] hexArray = "0123456789ABCDEF".toCharArray();
|
||||||
|
// lower ascii only
|
||||||
|
private static final int[] HEX_TO_INT =
|
||||||
|
new int[]{
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0-15
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 16-31
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 32-47
|
||||||
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, // 48-63
|
||||||
|
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 64-79
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 80-95
|
||||||
|
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 96-111
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 // 111-127
|
||||||
|
};
|
||||||
|
|
||||||
|
public static byte[] decode(String s) {
|
||||||
|
char[] c = s.toCharArray();
|
||||||
|
int len = c.length;
|
||||||
|
byte[] data = new byte[len / 2];
|
||||||
|
for (int i = 0; i < len; i += 2) {
|
||||||
|
data[i / 2] = (byte) (((HEX_TO_INT[(int) c[i]]) << 4) + HEX_TO_INT[(int) c[i + 1]]);
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String encode(byte[] bytes) {
|
||||||
|
char[] hexChars = new char[bytes.length * 2];
|
||||||
|
int v;
|
||||||
|
for (int j = 0; j < bytes.length; j++) {
|
||||||
|
v = bytes[j] & 0xFF;
|
||||||
|
hexChars[j * 2] = hexArray[v >>> 4];
|
||||||
|
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
|
||||||
|
}
|
||||||
|
return new String(hexChars);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String byteArrayToHexString(byte[] byteArray) {
|
||||||
|
if (byteArray == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
char[] hexArray = "0123456789ABCDEF".toCharArray();
|
||||||
|
char[] hexChars = new char[byteArray.length * 2];
|
||||||
|
for (int j = 0; j < byteArray.length; j++) {
|
||||||
|
int v = byteArray[j] & 0xFF;
|
||||||
|
hexChars[j * 2] = hexArray[v >>> 4];
|
||||||
|
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
|
||||||
|
}
|
||||||
|
return new String(hexChars);
|
||||||
|
}
|
||||||
|
}
|
108
src/main/src/org/bdware/server/CMDConf.java
Normal file
108
src/main/src/org/bdware/server/CMDConf.java
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
package org.bdware.server;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to represent configurations from cmd
|
||||||
|
*
|
||||||
|
* @author Kaidong Wu
|
||||||
|
*/
|
||||||
|
public class CMDConf {
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger(CMDConf.class);
|
||||||
|
|
||||||
|
public String cmi = "";
|
||||||
|
public String debug = "";
|
||||||
|
public boolean disableDoRepo = false;
|
||||||
|
public boolean disableLocalLhs = false;
|
||||||
|
public String doipCertPath = "";
|
||||||
|
public String doipLhsAddress = "";
|
||||||
|
public int doipPort = -1;
|
||||||
|
public String doipUserHandle = "";
|
||||||
|
public boolean enableEventPersistence = false;
|
||||||
|
public String enableSsl = "./ssl/chained.pem:./ssl/domain.pem";
|
||||||
|
public String ip = "127.0.0.1";
|
||||||
|
public boolean isLAN = true;
|
||||||
|
public boolean overwrite = false;
|
||||||
|
public int servicePort = 18005;
|
||||||
|
public String textFileSuffixes = ".yjs,.json,.txt,.css,.js,.html,.md,.conf,.csv";
|
||||||
|
// BDLedger可执行文件,若在服务器上运行请使用bdledger_linux
|
||||||
|
public String withBdledgerClient = "./runnable/bdledger_mac";
|
||||||
|
public boolean withBdledgerServer = false;
|
||||||
|
|
||||||
|
public static CMDConf parseConf(String confPath) {
|
||||||
|
CMDConf ret = null;
|
||||||
|
File conf = new File(confPath);
|
||||||
|
if (conf.exists()) {
|
||||||
|
try (BufferedReader br = new BufferedReader(new FileReader(conf))) {
|
||||||
|
StringBuilder sbl = new StringBuilder();
|
||||||
|
String temp;
|
||||||
|
while (null != (temp = br.readLine())) {
|
||||||
|
sbl.append(temp);
|
||||||
|
}
|
||||||
|
ret = new Gson().fromJson(sbl.toString(), CMDConf.class);
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
LOGGER.warn("parsing configure from file failed!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (null == ret) {
|
||||||
|
LOGGER.warn("use default configure");
|
||||||
|
return new CMDConf();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CMDConf parseArgs(String[] args) {
|
||||||
|
for (String arg : args) {
|
||||||
|
if (null == arg || !arg.startsWith("-")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String[] cmdArg = arg.split("=");
|
||||||
|
String[] cmdArgName = cmdArg[0].substring(1).split("-");
|
||||||
|
StringBuilder sbl = new StringBuilder(cmdArgName[0]);
|
||||||
|
for (int i = 1; i < cmdArgName.length; ++i) {
|
||||||
|
sbl.append(cmdArgName[i].substring(0, 1).toUpperCase())
|
||||||
|
.append(cmdArgName[i].substring(1));
|
||||||
|
}
|
||||||
|
String fieldName = sbl.toString();
|
||||||
|
try {
|
||||||
|
Field field = CMDConf.class.getDeclaredField(fieldName);
|
||||||
|
if (field.getType().equals(String.class)) {
|
||||||
|
field.set(this, cmdArg[1]);
|
||||||
|
} else if (field.getType().equals(Integer.TYPE)) {
|
||||||
|
field.set(this, Integer.parseInt(cmdArg[1]));
|
||||||
|
} else {
|
||||||
|
field.set(this, true);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.warn("cmd arg " + fieldName + " invalid! " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.doipPort == -1) {
|
||||||
|
this.doipPort = this.servicePort + 2;
|
||||||
|
}
|
||||||
|
if (this.cmi.isEmpty() || !this.cmi.replaceAll("[^\\s]+", "").isEmpty()) {
|
||||||
|
this.cmi = String.valueOf(System.currentTimeMillis());
|
||||||
|
this.overwrite = true;
|
||||||
|
LOGGER.info("create default cmi");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(String path) {
|
||||||
|
try {
|
||||||
|
this.overwrite = false;
|
||||||
|
BufferedWriter bw = new BufferedWriter(new FileWriter(path));
|
||||||
|
bw.write(new Gson().toJson(this));
|
||||||
|
bw.flush();
|
||||||
|
bw.close();
|
||||||
|
LOGGER.info("write new configure");
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.warn("write failed!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
99
src/main/src/org/bdware/server/Entry.java
Normal file
99
src/main/src/org/bdware/server/Entry.java
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
package org.bdware.server;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
|
||||||
|
|
||||||
|
public class Entry {
|
||||||
|
//release 地址:47.93.86.250 root:i1235813
|
||||||
|
public static void main(String[] args) {
|
||||||
|
try {
|
||||||
|
if (args == null || args.length < 2) {
|
||||||
|
printUsage();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (args[0]) {
|
||||||
|
case "CM":
|
||||||
|
case "ContractManager":
|
||||||
|
Thread t1 = new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
// JavaContractServiceGrpcServer.init();
|
||||||
|
} catch (Exception e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
t1.start();
|
||||||
|
|
||||||
|
Thread t2 = new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
String s = null;
|
||||||
|
try {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
Process p = Runtime.getRuntime().exec("./bdledger_go");
|
||||||
|
|
||||||
|
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
||||||
|
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
|
||||||
|
|
||||||
|
// read the output from the command
|
||||||
|
System.out.println("Here is the standard output of the command:\n");
|
||||||
|
while ((s = stdInput.readLine()) != null) {
|
||||||
|
System.out.println(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
// read any errors from the attempted command
|
||||||
|
System.out.println("Here is the standard error of the command (if any):\n");
|
||||||
|
while ((s = stdError.readLine()) != null) {
|
||||||
|
System.out.println(s);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
t2.start();
|
||||||
|
//CMHttpServer.start(getPort(args));
|
||||||
|
break;
|
||||||
|
case "NC":
|
||||||
|
case "NodeCenter":
|
||||||
|
//NodeCenterServer.start(getPort(args));
|
||||||
|
break;
|
||||||
|
case "Index":
|
||||||
|
// IndexServer.start(getPort(args));
|
||||||
|
default:
|
||||||
|
printUsage();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
printUsage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void printUsage() {
|
||||||
|
System.out.println(
|
||||||
|
"Usage: java -jar bdserver.jar [Module] [Port]\n Example1: java -jar bdserver.jar CM 18000\n Example2: java -jar bdserver.jar NodeCenter 18001");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getPort(String[] args) {
|
||||||
|
if (args.length >= 2)
|
||||||
|
return Integer.parseInt(args[1]);
|
||||||
|
switch (args[0]) {
|
||||||
|
case "CM":
|
||||||
|
case "ContractManager":
|
||||||
|
return 18000;
|
||||||
|
case "NC":
|
||||||
|
case "NodeCenter":
|
||||||
|
return 18001;
|
||||||
|
case "Index":
|
||||||
|
return 1614;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
20
src/main/src/org/bdware/server/action/Action.java
Normal file
20
src/main/src/org/bdware/server/action/Action.java
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package org.bdware.server.action;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
public @interface Action {
|
||||||
|
boolean httpAccess() default true;
|
||||||
|
|
||||||
|
boolean websocketAccess() default true;
|
||||||
|
|
||||||
|
boolean async() default false;
|
||||||
|
|
||||||
|
long userPermission() default 0l;
|
||||||
|
|
||||||
|
String[] alias() default {};
|
||||||
|
}
|
173
src/main/src/org/bdware/server/action/ActionExecutor.java
Normal file
173
src/main/src/org/bdware/server/action/ActionExecutor.java
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
package org.bdware.server.action;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.RandomAccessFile;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
public class ActionExecutor<T, U> {
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger(ActionExecutor.class);
|
||||||
|
// ---------- use for profiling
|
||||||
|
static Map<String, Map<String, AtomicInteger>> allData = new ConcurrentHashMap<>();
|
||||||
|
public ExecutorService executor;
|
||||||
|
// private Profiler profiler = new Profiler();
|
||||||
|
public long permission;
|
||||||
|
Map<String, AtomicInteger> staticData;
|
||||||
|
private Map<String, Pair<Method, Object>> handlers;
|
||||||
|
|
||||||
|
public ActionExecutor(ExecutorService executor, Object... classes) {
|
||||||
|
this.executor = executor;
|
||||||
|
permission = 0;
|
||||||
|
initHandlers(classes);
|
||||||
|
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
|
||||||
|
String caller = stackTraceElements[2].getClassName();
|
||||||
|
caller += (int) (Math.random() * 10000);
|
||||||
|
staticData = new ConcurrentHashMap<>();
|
||||||
|
allData.putIfAbsent(caller, staticData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Set<String> getAECallerSet() {
|
||||||
|
return allData.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, AtomicInteger> getStatistic(String caller) {
|
||||||
|
return allData.get(caller);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, Map<String, AtomicInteger>> getAllData() {
|
||||||
|
return allData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public Map<String, AtomicInteger> getStaticData() {
|
||||||
|
return staticData;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------- use for profiling
|
||||||
|
private void initHandlers(Object... objects) {
|
||||||
|
handlers = new HashMap<>();
|
||||||
|
if (objects.length > 0) {
|
||||||
|
for (Object obj : objects) {
|
||||||
|
if (obj == null) continue;
|
||||||
|
Method[] methods = obj.getClass().getDeclaredMethods();
|
||||||
|
for (Method method : methods) {
|
||||||
|
if (method.getAnnotation(Action.class) != null) {
|
||||||
|
if (method.getAnnotation(Action.class).alias().length == 0) {
|
||||||
|
handlers.put(method.getName(), new Pair<>(method, obj));
|
||||||
|
if (!method.getReturnType().equals(Void.TYPE)
|
||||||
|
|| method.getParameterCount() != 2) {
|
||||||
|
LOGGER.error(
|
||||||
|
"action ret is not void:"
|
||||||
|
+ obj.getClass().getCanonicalName()
|
||||||
|
+ "-->"
|
||||||
|
+ method.getName());
|
||||||
|
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (String a : method.getAnnotation(Action.class).alias()) {
|
||||||
|
handlers.put(a, new Pair<>(method, obj));
|
||||||
|
if (!method.getReturnType().equals(Void.TYPE)
|
||||||
|
|| method.getParameterCount() != 2) {
|
||||||
|
LOGGER.error(
|
||||||
|
"action ret is not void:"
|
||||||
|
+ obj.getClass().getCanonicalName()
|
||||||
|
+ "-->"
|
||||||
|
+ method.getName());
|
||||||
|
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean checkPermission(Action a, final U args, long permission) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Pair<Method, Object>> getHandlers() {
|
||||||
|
return handlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handle(String action, final U args, final T callback)
|
||||||
|
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
||||||
|
// logger.info("[ActionExecutor] handle : "+action);
|
||||||
|
|
||||||
|
if (null != action) {
|
||||||
|
if (staticData.containsKey(action)) {
|
||||||
|
staticData.get(action).incrementAndGet();
|
||||||
|
} else {
|
||||||
|
staticData.put(action, new AtomicInteger(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// logger.debug("[ActionExecutor] handle : ");
|
||||||
|
if (!handlers.containsKey(action)) {
|
||||||
|
LOGGER.debug("unsupported action " + action);
|
||||||
|
throw new IllegalArgumentException("unsupported action " + action);
|
||||||
|
}
|
||||||
|
|
||||||
|
final Pair<Method, Object> pair = handlers.get(action);
|
||||||
|
Action actionAnnotations = pair.first.getAnnotation(Action.class);
|
||||||
|
if (!checkPermission(actionAnnotations, args, permission)) {
|
||||||
|
LOGGER.info("unauthorised action " + action);
|
||||||
|
throw new IllegalArgumentException("unauthorised action " + action);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (actionAnnotations.async()) {
|
||||||
|
executor.execute(() -> {
|
||||||
|
try {
|
||||||
|
pair.first.invoke(pair.second, args, callback);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.debug(
|
||||||
|
pair.first.getDeclaringClass().getCanonicalName()
|
||||||
|
+ "->"
|
||||||
|
+ pair.first.getName());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
pair.first.invoke(pair.second, args, callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
static class Profiler {
|
||||||
|
RandomAccessFile log;
|
||||||
|
|
||||||
|
Profiler() {
|
||||||
|
try {
|
||||||
|
log = new RandomAccessFile("./log/profile.log", "rw");
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Pair<T, U> {
|
||||||
|
T first;
|
||||||
|
U second;
|
||||||
|
|
||||||
|
public Pair(T f, U s) {
|
||||||
|
first = f;
|
||||||
|
second = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T first() {
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,83 @@
|
|||||||
|
package org.bdware.server.action;
|
||||||
|
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import io.netty.channel.ChannelFuture;
|
||||||
|
import io.netty.channel.ChannelFutureListener;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.handler.codec.http.DefaultFullHttpResponse;
|
||||||
|
import io.netty.handler.codec.http.HttpUtil;
|
||||||
|
import io.netty.handler.codec.http.HttpVersion;
|
||||||
|
import org.bdware.sc.conn.ByteUtil;
|
||||||
|
import org.bdware.sc.conn.ResultCallback;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static io.netty.handler.codec.http.HttpResponseStatus.OK;
|
||||||
|
|
||||||
|
public class HttpResultCallback extends ResultCallback implements Runnable {
|
||||||
|
protected ChannelHandlerContext ctxField;
|
||||||
|
String jsonCallback;
|
||||||
|
Map<String, String> extraHeaders = new HashMap<>();
|
||||||
|
DefaultFullHttpResponse response;
|
||||||
|
byte[] bytes;
|
||||||
|
private boolean decodeAsB64 = false;
|
||||||
|
|
||||||
|
public HttpResultCallback(ChannelHandlerContext ctx, String jsonCallback) {
|
||||||
|
ctxField = ctx;
|
||||||
|
this.jsonCallback = jsonCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResult(String ret) {
|
||||||
|
if (jsonCallback != null) {
|
||||||
|
ret = (jsonCallback + "(" + ret + ")");
|
||||||
|
}
|
||||||
|
if (ret != null && !ctxField.isRemoved()) {
|
||||||
|
bytes = null;
|
||||||
|
if (decodeAsB64)
|
||||||
|
try {
|
||||||
|
bytes = ByteUtil.decodeBASE64(ret);
|
||||||
|
} catch (Exception e) {
|
||||||
|
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||||
|
e.printStackTrace(new PrintStream(bo));
|
||||||
|
bytes = bo.toByteArray();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bytes = ret.getBytes();
|
||||||
|
}
|
||||||
|
assert bytes != null;
|
||||||
|
response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, OK, Unpooled.wrappedBuffer(bytes));
|
||||||
|
|
||||||
|
for (String key : extraHeaders.keySet())
|
||||||
|
response.headers().add(key, extraHeaders.get(key));
|
||||||
|
ctxField.channel().eventLoop().execute(this);
|
||||||
|
} // Just ignore
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addHeader(String key, String val) {
|
||||||
|
extraHeaders.put(key, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
HttpUtil.setContentLength(response, bytes.length);
|
||||||
|
ChannelFuture future = ctxField.writeAndFlush(response);
|
||||||
|
future.addListener(ChannelFutureListener.CLOSE);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDecodeBase64() {
|
||||||
|
decodeAsB64 = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
scp ./libs/front-base-0.80.jar dev@023.node.internetapi.cn:./
|
||||||
|
scp ./libs/front-base-0.80.jar dev@021.node.internetapi.cn:./
|
||||||
|
scp ./libs/front-base-0.80.jar dev@024.node.internetapi.cn:./
|
||||||
|
|
||||||
|
|
||||||
|
* */
|
16
src/main/src/org/bdware/server/action/Result.java
Normal file
16
src/main/src/org/bdware/server/action/Result.java
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package org.bdware.server.action;
|
||||||
|
|
||||||
|
public class Result {
|
||||||
|
boolean status;
|
||||||
|
String msg;
|
||||||
|
String action = null;
|
||||||
|
Object data;
|
||||||
|
String responseID;
|
||||||
|
|
||||||
|
Result() {
|
||||||
|
status = false;
|
||||||
|
msg = null;
|
||||||
|
data = "";
|
||||||
|
responseID="";
|
||||||
|
}
|
||||||
|
}
|
126
src/main/src/org/bdware/server/action/SyncResult.java
Normal file
126
src/main/src/org/bdware/server/action/SyncResult.java
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
package org.bdware.server.action;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonPrimitive;
|
||||||
|
import io.netty.util.HashedWheelTimer;
|
||||||
|
import io.netty.util.Timeout;
|
||||||
|
import io.netty.util.TimerTask;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.bdware.sc.ContractResult;
|
||||||
|
import org.bdware.sc.ContractResult.Status;
|
||||||
|
import org.bdware.sc.conn.InstrumentedResultCallback;
|
||||||
|
import org.bdware.sc.conn.ResultCallback;
|
||||||
|
import org.bdware.sc.util.JsonUtil;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
public class SyncResult {
|
||||||
|
public static final HashedWheelTimer timer = new HashedWheelTimer(
|
||||||
|
Executors.defaultThreadFactory(),
|
||||||
|
5,
|
||||||
|
TimeUnit.MILLISECONDS,
|
||||||
|
2);
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger(SyncResult.class);
|
||||||
|
public Map<String, ResultCallback> waitObj = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
public synchronized void wakeUp(String requestID, String result) {
|
||||||
|
ResultCallback ob = waitObj.get(requestID);
|
||||||
|
// TODO 难怪之前这是注释的。
|
||||||
|
waitObj.remove(requestID);
|
||||||
|
// cancel timeout
|
||||||
|
if (ob != null) {
|
||||||
|
ob.cancelTimeOut();
|
||||||
|
ob.onResult(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void instrumentWakeUp(
|
||||||
|
String requestID,
|
||||||
|
InstrumentedResultCallback instrumentedResultCallback,
|
||||||
|
JsonObject result) {
|
||||||
|
ResultCallback ob = waitObj.get(requestID);
|
||||||
|
// TODO 难怪之前这是注释的。
|
||||||
|
waitObj.remove(requestID);
|
||||||
|
// cancel timeout
|
||||||
|
if (ob != null) {
|
||||||
|
ob.cancelTimeOut();
|
||||||
|
instrumentedResultCallback.onResult(ob, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sleep(String requestID, ResultCallback cb) {
|
||||||
|
// TODO 这里有bug
|
||||||
|
sleepWithTimeout(requestID, cb, 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sleepWithTimeout(final String requestID, ResultCallback cb, int timeOut) {
|
||||||
|
if (!waitObj.containsKey(requestID)) {
|
||||||
|
CancelTask tt = new CancelTask(requestID);
|
||||||
|
Timeout timeout = timer.newTimeout(tt, timeOut, TimeUnit.SECONDS);
|
||||||
|
// logger.debug("reqID:" + requestID + " createTimeout:" + timeout);
|
||||||
|
cb.setTimeOut(timeout);
|
||||||
|
waitObj.put(requestID, cb);
|
||||||
|
} else {
|
||||||
|
LOGGER.debug("[Duplicated RequestID]" + requestID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ContractResult syncSleep(String requestID) {
|
||||||
|
ContractResultCallback cb = new ContractResultCallback();
|
||||||
|
sleep(requestID, cb);
|
||||||
|
|
||||||
|
synchronized (cb) {
|
||||||
|
try {
|
||||||
|
cb.wait(20000L);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cb.cr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canIssue() {
|
||||||
|
// TODO add flow control
|
||||||
|
int waitSize = waitObj.keySet().size();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ContractResultCallback extends ResultCallback {
|
||||||
|
ContractResult cr = new ContractResult(Status.Error, new JsonPrimitive("Timeout!!"));
|
||||||
|
int reRoute = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResult(String str) {
|
||||||
|
cr = JsonUtil.fromJson(str, ContractResult.class);
|
||||||
|
synchronized (this) {
|
||||||
|
this.notifyAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getReRouteCount() {
|
||||||
|
return reRoute;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void incReRouteCount() {
|
||||||
|
reRoute++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CancelTask implements TimerTask {
|
||||||
|
String requestID;
|
||||||
|
|
||||||
|
CancelTask(String requestID) {
|
||||||
|
this.requestID = requestID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run(Timeout timeout) {
|
||||||
|
ContractResult cr = new ContractResult(Status.Error, new JsonPrimitive("Timeout!"));
|
||||||
|
wakeUp(requestID, JsonUtil.toJson(cr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,61 @@
|
|||||||
|
package org.bdware.server.http;
|
||||||
|
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import io.netty.channel.*;
|
||||||
|
import io.netty.handler.codec.http.*;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.bdware.server.action.HttpResultCallback;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.RandomAccessFile;
|
||||||
|
|
||||||
|
import static io.netty.handler.codec.http.HttpResponseStatus.OK;
|
||||||
|
|
||||||
|
public class FileDownloaderCallback extends HttpResultCallback {
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger(FileDownloaderCallback.class);
|
||||||
|
HttpRequest req;
|
||||||
|
|
||||||
|
public FileDownloaderCallback(ChannelHandlerContext ctx, HttpRequest req) {
|
||||||
|
super(ctx, null);
|
||||||
|
this.req = req;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onResult(final String filePath) {
|
||||||
|
try {
|
||||||
|
final RandomAccessFile file = new RandomAccessFile(filePath, "r");
|
||||||
|
HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
|
||||||
|
// 设置文件格式内容
|
||||||
|
response.headers().set(HttpHeaderNames.CONTENT_TYPE, "application/x-msdownload");
|
||||||
|
response.headers().set(HttpHeaderNames.CONTENT_DISPOSITION,
|
||||||
|
"attachment;filename=" + new File(filePath).getName());
|
||||||
|
HttpUtil.setKeepAlive(response, HttpUtil.isKeepAlive(req));
|
||||||
|
HttpUtil.setContentLength(response, file.length());
|
||||||
|
LOGGER.debug("FileLength:" + file.length());
|
||||||
|
ctxField.write(response);
|
||||||
|
ChannelFuture future = ctxField.write(new DefaultFileRegion(file.getChannel(), 0, file.length()),
|
||||||
|
ctxField.newProgressivePromise());
|
||||||
|
ctxField.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
|
||||||
|
future.addListener(new ChannelProgressiveFutureListener() {
|
||||||
|
@Override
|
||||||
|
public void operationProgressed(ChannelProgressiveFuture future, long progress, long total) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void operationComplete(ChannelProgressiveFuture future) throws Exception {
|
||||||
|
file.close();
|
||||||
|
LOGGER.debug("delete file " + filePath + ": " + new File(filePath).delete());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!HttpUtil.isKeepAlive(req))
|
||||||
|
future.addListener(ChannelFutureListener.CLOSE);
|
||||||
|
ctxField.flush();
|
||||||
|
} catch (Exception e) {
|
||||||
|
DefaultFullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, OK,
|
||||||
|
Unpooled.wrappedBuffer("File Not Found".getBytes()));
|
||||||
|
ChannelFuture f = ctxField.writeAndFlush(response);
|
||||||
|
f.addListener(ChannelFutureListener.CLOSE);
|
||||||
|
ctxField.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
157
src/main/src/org/bdware/server/http/HttpFileHandleAdapter.java
Normal file
157
src/main/src/org/bdware/server/http/HttpFileHandleAdapter.java
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
package org.bdware.server.http;
|
||||||
|
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import io.netty.channel.ChannelFuture;
|
||||||
|
import io.netty.channel.ChannelFutureListener;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.channel.SimpleChannelInboundHandler;
|
||||||
|
import io.netty.handler.codec.http.*;
|
||||||
|
import io.netty.handler.stream.ChunkedFile;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileFilter;
|
||||||
|
import java.io.RandomAccessFile;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;
|
||||||
|
|
||||||
|
public class HttpFileHandleAdapter extends SimpleChannelInboundHandler<FullHttpRequest> {
|
||||||
|
private static final Pattern ALLOWED_FILE_NAME =
|
||||||
|
Pattern.compile("[A-Za-z0-9][-_A-Za-z0-9\\.]*");
|
||||||
|
private static final Pattern INSECURE_URI = Pattern.compile(".*[<>&\"].*");
|
||||||
|
FileFilter fileFilter;
|
||||||
|
private String location;
|
||||||
|
|
||||||
|
public HttpFileHandleAdapter(String path, FileFilter fileFilter) {
|
||||||
|
location = path;
|
||||||
|
this.fileFilter = fileFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendError(ChannelHandlerContext ctx, HttpResponseStatus status) {
|
||||||
|
FullHttpResponse response =
|
||||||
|
new DefaultFullHttpResponse(
|
||||||
|
HTTP_1_1,
|
||||||
|
status,
|
||||||
|
Unpooled.wrappedBuffer(
|
||||||
|
("Failure: " + status.toString() + "\r\n").getBytes()));
|
||||||
|
response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=UTF-8");
|
||||||
|
ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void appendContentType(String path, HttpHeaders headers) {
|
||||||
|
if (path.endsWith(".html")) {
|
||||||
|
headers.set(HttpHeaderNames.CONTENT_TYPE, "text/html; charset=UTF-8");
|
||||||
|
} else if (path.endsWith(".js")) {
|
||||||
|
headers.set(HttpHeaderNames.CONTENT_TYPE, "application/x-javascript; charset=utf-8");
|
||||||
|
} else if (path.endsWith(".css")) {
|
||||||
|
headers.set(HttpHeaderNames.CONTENT_TYPE, "text/css; charset=UTF-8");
|
||||||
|
} else if (path.endsWith(".ico")) {
|
||||||
|
headers.set(HttpHeaderNames.CONTENT_TYPE, "image/x-icon;");
|
||||||
|
} else if (path.endsWith(".svg")) {
|
||||||
|
headers.set(HttpHeaderNames.CONTENT_TYPE, "text/xml;charset=utf-8");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void send100Continue(ChannelHandlerContext ctx) {
|
||||||
|
FullHttpResponse response =
|
||||||
|
new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.CONTINUE);
|
||||||
|
ctx.writeAndFlush(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String sanitizeUri(String uri) {
|
||||||
|
try {
|
||||||
|
// 使用JDK的URLDecoder进行解码
|
||||||
|
uri = URLDecoder.decode(uri, "UTF-8");
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
try {
|
||||||
|
uri = URLDecoder.decode(uri, "ISO-8859-1");
|
||||||
|
} catch (UnsupportedEncodingException e1) {
|
||||||
|
throw new Error();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!uri.startsWith("/")) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (uri.contains("..")) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// 将硬编码的文件路径
|
||||||
|
uri = uri.replace('/', File.separatorChar);
|
||||||
|
if (uri.contains(File.separator + '.')
|
||||||
|
|| uri.contains('.' + File.separator)
|
||||||
|
|| uri.startsWith(".")
|
||||||
|
|| uri.endsWith(".")
|
||||||
|
|| INSECURE_URI.matcher(uri).matches()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return System.getProperty("user.dir") + File.separator + uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request)
|
||||||
|
throws Exception {
|
||||||
|
// 获取URI
|
||||||
|
request.retain();
|
||||||
|
// System.out.println("[HttpFileHandlerAdapter]request.uri:" + request.uri());
|
||||||
|
// String[] hoString = request.duplicate().toString().split("\n");
|
||||||
|
// if (request.uri().equals("/favicon.ico")) {
|
||||||
|
// request.setUri("/SCIDE/favicon.ico");
|
||||||
|
// }
|
||||||
|
String uri = request.uri();
|
||||||
|
|
||||||
|
if (uri.contains("..")) {
|
||||||
|
sendError(ctx, HttpResponseStatus.BAD_REQUEST);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uri = uri.replaceFirst("/SCIDE", "");
|
||||||
|
uri = uri.replaceFirst("\\?.*$", "");
|
||||||
|
if (uri.equals("/") || uri.equals("./") || uri.length() == 0) {
|
||||||
|
uri = "/index.html";
|
||||||
|
}
|
||||||
|
boolean isTrue = isFile(uri);
|
||||||
|
// 根据路径地址构建文件
|
||||||
|
if (isTrue) {
|
||||||
|
String path = location + uri;
|
||||||
|
File html = new File(path);
|
||||||
|
// 状态为1xx的话,继续请求
|
||||||
|
if (HttpUtil.is100ContinueExpected(request)) {
|
||||||
|
send100Continue(ctx);
|
||||||
|
}
|
||||||
|
// 当文件不存在的时候,将资源指向NOT_FOUND
|
||||||
|
if (!html.exists() || html.isDirectory()) {
|
||||||
|
sendError(ctx, HttpResponseStatus.NOT_FOUND);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final RandomAccessFile file = new RandomAccessFile(html, "r");
|
||||||
|
HttpResponse response =
|
||||||
|
new DefaultHttpResponse(request.protocolVersion(), HttpResponseStatus.OK);
|
||||||
|
// 设置文件格式内容
|
||||||
|
appendContentType(path, response.headers());
|
||||||
|
boolean keepAlive = HttpUtil.isKeepAlive(request);
|
||||||
|
HttpUtil.setContentLength(response, file.length());
|
||||||
|
if (keepAlive) {
|
||||||
|
HttpUtil.setKeepAlive(response, true);
|
||||||
|
}
|
||||||
|
ctx.write(response);
|
||||||
|
// 同过netty的村可多File对象直接将文件写入到发送缓冲区,最后为sendFileFeature增加GenericFeatureListener,
|
||||||
|
// 如果发送完成,打印“Transfer complete”
|
||||||
|
ctx.write(new ChunkedFile(file, 0, file.length(), 512 * 1024), ctx.newPromise());
|
||||||
|
// 写入文件尾部
|
||||||
|
ChannelFuture future = ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
|
||||||
|
if (!keepAlive) {
|
||||||
|
future.addListener(ChannelFutureListener.CLOSE);
|
||||||
|
}
|
||||||
|
future.addListener(arg0 -> file.close());
|
||||||
|
} else {
|
||||||
|
sendError(ctx, HttpResponseStatus.NOT_FOUND);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isFile(String path) {
|
||||||
|
return fileFilter.accept(new File(path));
|
||||||
|
}
|
||||||
|
}
|
36
src/main/src/org/bdware/server/http/HttpMethod.java
Normal file
36
src/main/src/org/bdware/server/http/HttpMethod.java
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package org.bdware.server.http;
|
||||||
|
|
||||||
|
public enum HttpMethod {
|
||||||
|
OPTIONS,
|
||||||
|
GET,
|
||||||
|
HEAD,
|
||||||
|
POST,
|
||||||
|
PUT,
|
||||||
|
PATCH,
|
||||||
|
DELETE,
|
||||||
|
TRACE,
|
||||||
|
CONNECT;
|
||||||
|
|
||||||
|
io.netty.handler.codec.http.HttpMethod get() {
|
||||||
|
switch (this) {
|
||||||
|
case OPTIONS:
|
||||||
|
return io.netty.handler.codec.http.HttpMethod.OPTIONS;
|
||||||
|
case HEAD:
|
||||||
|
return io.netty.handler.codec.http.HttpMethod.HEAD;
|
||||||
|
case POST:
|
||||||
|
return io.netty.handler.codec.http.HttpMethod.POST;
|
||||||
|
case PUT:
|
||||||
|
return io.netty.handler.codec.http.HttpMethod.PUT;
|
||||||
|
case PATCH:
|
||||||
|
return io.netty.handler.codec.http.HttpMethod.PATCH;
|
||||||
|
case DELETE:
|
||||||
|
return io.netty.handler.codec.http.HttpMethod.DELETE;
|
||||||
|
case TRACE:
|
||||||
|
return io.netty.handler.codec.http.HttpMethod.TRACE;
|
||||||
|
case CONNECT:
|
||||||
|
return io.netty.handler.codec.http.HttpMethod.CONNECT;
|
||||||
|
default:
|
||||||
|
return io.netty.handler.codec.http.HttpMethod.GET;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
113
src/main/src/org/bdware/server/http/URIHandler.java
Normal file
113
src/main/src/org/bdware/server/http/URIHandler.java
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
package org.bdware.server.http;
|
||||||
|
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import io.netty.channel.ChannelFutureListener;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.handler.codec.http.*;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;
|
||||||
|
|
||||||
|
public class URIHandler {
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger(URIHandler.class);
|
||||||
|
Map<io.netty.handler.codec.http.HttpMethod, List<Tuple<String, Method, Object>>> handlers;
|
||||||
|
|
||||||
|
public URIHandler() {
|
||||||
|
handlers = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void register(Object obj) {
|
||||||
|
register(obj.getClass(), obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void register(Class<?> clz) {
|
||||||
|
register(clz, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void register(Class<?> clz, Object obj) {
|
||||||
|
for (Method m : clz.getDeclaredMethods()) {
|
||||||
|
URIPath path = m.getAnnotation(URIPath.class);
|
||||||
|
if (path != null) {
|
||||||
|
HttpMethod method = path.method();
|
||||||
|
List<Tuple<String, Method, Object>> handlerList = getOrCreate(method);
|
||||||
|
for (String str : path.value()) {
|
||||||
|
m.setAccessible(true);
|
||||||
|
handlerList.add(new Tuple<>(str, m, obj));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (List<Tuple<String, Method, Object>> handlerList : handlers.values()) {
|
||||||
|
sortHandlerList(handlerList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<Tuple<String, Method, Object>> getOrCreate(HttpMethod method) {
|
||||||
|
return handlers.computeIfAbsent(method.get(), k -> new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sortHandlerList(List<Tuple<String, Method, Object>> handlerList) {
|
||||||
|
handlerList.sort((o1, o2) -> {
|
||||||
|
int delta = o2.t.length() - o1.t.length();
|
||||||
|
return delta == 0 ? o1.t.compareTo(o2.t) : delta;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handle(ChannelHandlerContext ctx, FullHttpRequest msg) {
|
||||||
|
try {
|
||||||
|
List<Tuple<String, Method, Object>> handlerList = handlers.get(msg.method());
|
||||||
|
for (Tuple<String, Method, Object> t : handlerList)
|
||||||
|
if (msg.uri().startsWith(t.t)) {
|
||||||
|
t.u.invoke(t.s, ctx, msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sendUnsupported(ctx);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void printURIHandlers() {
|
||||||
|
StringBuilder sbl = new StringBuilder("URIHandlers:\n");
|
||||||
|
for (io.netty.handler.codec.http.HttpMethod m : handlers.keySet()) {
|
||||||
|
sbl.append("\t").append(m.name()).append("\n");
|
||||||
|
for (Tuple<String, Method, Object> t : handlers.get(m)) {
|
||||||
|
String className = t.u.getDeclaringClass().getSimpleName();
|
||||||
|
sbl.append("\t\t").append(t.t.isEmpty() ? "<null>" : t.t).append(" --> ")
|
||||||
|
.append(className.isEmpty() ? "null" : className)
|
||||||
|
.append(".").append(t.u.getName()).append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOGGER.info(sbl.substring(0, sbl.length() - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendUnsupported(ChannelHandlerContext ctx) {
|
||||||
|
FullHttpResponse response =
|
||||||
|
new DefaultFullHttpResponse(
|
||||||
|
HTTP_1_1,
|
||||||
|
HttpResponseStatus.BAD_REQUEST,
|
||||||
|
Unpooled.wrappedBuffer(
|
||||||
|
("Failure: " + HttpResponseStatus.BAD_REQUEST + "\r\n")
|
||||||
|
.getBytes()));
|
||||||
|
response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=UTF-8");
|
||||||
|
ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Tuple<T, U, S> {
|
||||||
|
T t;
|
||||||
|
U u;
|
||||||
|
S s;
|
||||||
|
|
||||||
|
Tuple(T t, U u, S s) {
|
||||||
|
this.t = t;
|
||||||
|
this.u = u;
|
||||||
|
this.s = s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
13
src/main/src/org/bdware/server/http/URIPath.java
Normal file
13
src/main/src/org/bdware/server/http/URIPath.java
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package org.bdware.server.http;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
public @interface URIPath {
|
||||||
|
String[] value() default {""};
|
||||||
|
HttpMethod method() default HttpMethod.GET;
|
||||||
|
}
|
9
src/main/src/org/bdware/server/nodecenter/Response.java
Normal file
9
src/main/src/org/bdware/server/nodecenter/Response.java
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package org.bdware.server.nodecenter;
|
||||||
|
|
||||||
|
public class Response {
|
||||||
|
String responseID;
|
||||||
|
public String action;
|
||||||
|
public Object data;
|
||||||
|
public long executeTime;
|
||||||
|
public boolean isPrivate;
|
||||||
|
}
|
14
src/main/src/org/bdware/server/nodecenter/ResultBack.java
Normal file
14
src/main/src/org/bdware/server/nodecenter/ResultBack.java
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package org.bdware.server.nodecenter;
|
||||||
|
|
||||||
|
public class ResultBack {
|
||||||
|
public boolean status;
|
||||||
|
public String msg;
|
||||||
|
public String action = null;
|
||||||
|
public Object data;
|
||||||
|
|
||||||
|
public ResultBack() {
|
||||||
|
status = false;
|
||||||
|
msg = null;
|
||||||
|
data = "";
|
||||||
|
}
|
||||||
|
}
|
5
src/main/src/org/bdware/server/nodecenter/UserMySQL.java
Normal file
5
src/main/src/org/bdware/server/nodecenter/UserMySQL.java
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package org.bdware.server.nodecenter;
|
||||||
|
|
||||||
|
public class UserMySQL {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,85 @@
|
|||||||
|
package org.bdware.server.nodecenter.client;
|
||||||
|
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
import org.bdware.sc.bean.ContractDesp;
|
||||||
|
import org.bdware.sc.util.JsonUtil;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class CMNodeBean {
|
||||||
|
public List<ContractDesp> contracts;
|
||||||
|
public String pubKey;
|
||||||
|
public String nodeName;
|
||||||
|
public String udpID;
|
||||||
|
public String ipPort;
|
||||||
|
public String cimanager = "";
|
||||||
|
|
||||||
|
public CMNodeBean(String publicKeyStr) {
|
||||||
|
pubKey = publicKeyStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO nodeMangerPubkey
|
||||||
|
public void updateContract(Map<String, String> json) {
|
||||||
|
String jsonStr = json.get("contracts");
|
||||||
|
contracts = JsonUtil.fromJson(jsonStr, new TypeToken<List<ContractDesp>>() {
|
||||||
|
}.getType());
|
||||||
|
// KeyValueDBUtil.instance.setValue(NCTables.NodesDB.toString(), pubKey, JsonUtil.toJson(this));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// when the center received an event, publish it to subscriber.
|
||||||
|
|
||||||
|
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 void removeCIManager(String string) {
|
||||||
|
System.out.println("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) {
|
||||||
|
System.out.println("addCIManager" + string);
|
||||||
|
this.cimanager = this.cimanager.concat(" " + string);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCIManager(String string) {
|
||||||
|
this.cimanager = string;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
93
src/main/src/org/bdware/server/permission/Permission.java
Normal file
93
src/main/src/org/bdware/server/permission/Permission.java
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
package org.bdware.server.permission;
|
||||||
|
|
||||||
|
public enum Permission {
|
||||||
|
// GetSessionID(0), GetRole(0), Login(0), // 默认权限设置为0
|
||||||
|
// ApplyRole(1 << 0), // 匿名用户申请成为节点管理员(NodePortal)角色
|
||||||
|
// NodeStateList(1 << 1), // 中心节点查看节点管理员的所管理所有节点的状态
|
||||||
|
// AuthNodeManager(1 << 2), // 授权节点管理员
|
||||||
|
// DeleteNodeManager(1 << 3), // 从网络中删除某个节点管理员
|
||||||
|
// ListAllUsers(1 << 4), // ListAllUser
|
||||||
|
// ListApplyUser(1 << 5), // ListApplyUser
|
||||||
|
// ListTrustCluster(1 << 6), // 查看可信执行集群列表
|
||||||
|
// AssignTrustedCluster(1 << 7), // 分配可信执行集群
|
||||||
|
//
|
||||||
|
// // ==================NodePotral===============
|
||||||
|
// //ApplyNodeRole(1<<6),//申请节点角色
|
||||||
|
// AuthNodeRole(1 << 8), // 授权角色
|
||||||
|
// DeleteRole(1 << 9), // 从用户角色中删除某一种角色
|
||||||
|
// ListAllAuthUsers(1 << 10), // 查看已授权用户
|
||||||
|
// ListUnAuthUsers(1 << 11), // 查看未授权用户
|
||||||
|
//
|
||||||
|
// StartContract(1 << 12), ExecuteContract(1 << 13), StopContract(1 << 14), // stop和kill一样
|
||||||
|
// UploadContract(1 << 15), // 上传合约代码(修改代码、更新合约代码、保存代码)
|
||||||
|
// DownloadContract(1 << 16), // 下载合约代码
|
||||||
|
// DeleteContract(1 << 17), // 删除合约代码
|
||||||
|
//
|
||||||
|
// ContractCodeStatisticsList(1 << 18), // 查看合约代码统计数据(合约文件大小)
|
||||||
|
// StaticAnalysis(1 << 19), // 静态分析
|
||||||
|
// ConfigureContractPermission(1 << 20), // 配置合约权限
|
||||||
|
// ContractProgressList(1L << 22L), // 查看合约进程(listContractProcess)
|
||||||
|
//
|
||||||
|
// QueryActionLog(1L << 24L), // 增加listLog(时间戳)
|
||||||
|
// QueryUserStateLog(1L << 25L), // 查看节点日志
|
||||||
|
// ListLocalNodeStatus(1L << 26L), // 节点状态(此节点)
|
||||||
|
// ListContractLog(1L << 27L), // 合约日志
|
||||||
|
//
|
||||||
|
// TimeTravel(1L << 28L), ManualDump(1L << 29L), // 手动dump
|
||||||
|
// ForkContractStatus(1L << 30L), // 合约状态从别处迁移到自己本地
|
||||||
|
// ConfigureNode(1L << 31L), // 配置节点信息
|
||||||
|
// listProjects(1L << 32L),// 合约提供者
|
||||||
|
|
||||||
|
|
||||||
|
// 新加的一些权限
|
||||||
|
// listLicence(1L<<33L)//证书列表 updateLicence权限也写成这个了,有没有必要分开
|
||||||
|
|
||||||
|
// TODO: 20205/20 需要整理权限就权限和最新的权限
|
||||||
|
|
||||||
|
// CenterManager (其他部分代码中出现的,暂未合并整理)
|
||||||
|
ApplyRole(1 << 0),
|
||||||
|
NodeStateList(1 << 1),
|
||||||
|
AuthNodeManager(1 << 2),
|
||||||
|
ListAllUsers(1 << 3),
|
||||||
|
ListApplyUser(1 << 4),
|
||||||
|
DeleteNodeManager(1 << 5),
|
||||||
|
ListTrustCluster(1 << 6),
|
||||||
|
AssignTrustedCluster(1 << 7),
|
||||||
|
QueryActionLog(1 << 8),
|
||||||
|
QueryUserStateLog(1 << 9),
|
||||||
|
|
||||||
|
// Node
|
||||||
|
ConfigureNode(1 << 10), // 其他地方代码中的权限
|
||||||
|
ManageNode(1 << 10), // 节点管理
|
||||||
|
GetNodeInfo(1 << 11), // 节点信息获取
|
||||||
|
|
||||||
|
ContractCodeStatisticsList(1 << 12), // 其他地方代码中的权限
|
||||||
|
ConfigureContractPermission(1 << 13), // 其他地方代码中的权限
|
||||||
|
EditContract(1 << 14), // 编辑合约
|
||||||
|
ListProject(1L << 15), // 查看project信息
|
||||||
|
StaticAnalysis(1L << 16), // 静态分析
|
||||||
|
Compile(1L << 17), // 编译相关及其他权限类似操作
|
||||||
|
|
||||||
|
ContractPermissionList(1L << 18), // 查看合约权限
|
||||||
|
ListContractProgress(1L << 19), // 合约进程列表
|
||||||
|
CheckContractStatus(1L << 20), // 查看合约状态(被调用多少次,占用内存等等)
|
||||||
|
TimeTravel(1L << 21), // 其他地方代码中的权限
|
||||||
|
ListContractLog(1L << 22), // 查看合约日志
|
||||||
|
ManageMemory(1L << 23), // 内存管理
|
||||||
|
CreateLedger(1L << 24), // ledger相关
|
||||||
|
|
||||||
|
ManualDump(1L << 25), // 手动dump
|
||||||
|
ManageContract(1L << 26), // 更改合约运行状态
|
||||||
|
|
||||||
|
TakeScreenShot(1L << 27);
|
||||||
|
|
||||||
|
public final long value;
|
||||||
|
|
||||||
|
Permission(long value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
43
src/main/src/org/bdware/server/permission/Role.java
Normal file
43
src/main/src/org/bdware/server/permission/Role.java
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
package org.bdware.server.permission;
|
||||||
|
|
||||||
|
public enum Role {
|
||||||
|
CenterManager(0x3ffL),
|
||||||
|
NodeManager(0xe41L),
|
||||||
|
Node(0x1L),
|
||||||
|
ContractProvider(0x3f000L),
|
||||||
|
ContractInstanceManager(0x7ff10c0L),
|
||||||
|
ContractUser(0x5c0000L),
|
||||||
|
Anonymous(0);
|
||||||
|
|
||||||
|
long value;
|
||||||
|
|
||||||
|
Role(long v) {
|
||||||
|
value = v;
|
||||||
|
};
|
||||||
|
|
||||||
|
public static Role parse(String str) {
|
||||||
|
try {
|
||||||
|
return valueOf(str);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Anonymous;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long compoundValue(String[] roles) {
|
||||||
|
long ret = 0;
|
||||||
|
if (roles != null) {
|
||||||
|
for (String role : roles) {
|
||||||
|
ret |= parse(role).value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getString(Role role) {
|
||||||
|
return role.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package org.bdware.server.ws;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.handler.codec.MessageToByteEncoder;
|
||||||
|
|
||||||
|
public class DelimiterBasedFrameEncoder extends MessageToByteEncoder<ByteBuf> {
|
||||||
|
static byte[] delimiter = "wonbifoodie".getBytes();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void encode(ChannelHandlerContext arg0, ByteBuf in, ByteBuf out) throws Exception {
|
||||||
|
// System.out.println("[DelimiterBasedFrameEncoder] write:" +
|
||||||
|
// in.readableBytes());
|
||||||
|
out.writeBytes(in);
|
||||||
|
out.writeBytes(delimiter);
|
||||||
|
}
|
||||||
|
}
|
17
src/main/src/org/bdware/server/ws/DelimiterCodec.java
Normal file
17
src/main/src/org/bdware/server/ws/DelimiterCodec.java
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package org.bdware.server.ws;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import io.netty.channel.CombinedChannelDuplexHandler;
|
||||||
|
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
|
||||||
|
|
||||||
|
public class DelimiterCodec
|
||||||
|
extends CombinedChannelDuplexHandler<
|
||||||
|
DelimiterBasedFrameDecoder, DelimiterBasedFrameEncoder> {
|
||||||
|
public DelimiterCodec() {
|
||||||
|
ByteBuf buf = Unpooled.wrappedBuffer(DelimiterBasedFrameEncoder.delimiter);
|
||||||
|
init(
|
||||||
|
new DelimiterBasedFrameDecoder(10 * 1024 * 1024, buf),
|
||||||
|
new DelimiterBasedFrameEncoder());
|
||||||
|
}
|
||||||
|
}
|
100
src/main/src/org/bdware/server/ws/WebSocketIndexPageHandler.java
Normal file
100
src/main/src/org/bdware/server/ws/WebSocketIndexPageHandler.java
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
package org.bdware.server.ws;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.ByteBufUtil;
|
||||||
|
import io.netty.channel.ChannelFuture;
|
||||||
|
import io.netty.channel.ChannelFutureListener;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.channel.ChannelPipeline;
|
||||||
|
import io.netty.channel.SimpleChannelInboundHandler;
|
||||||
|
import io.netty.handler.codec.http.DefaultFullHttpResponse;
|
||||||
|
import io.netty.handler.codec.http.FullHttpRequest;
|
||||||
|
import io.netty.handler.codec.http.FullHttpResponse;
|
||||||
|
import io.netty.handler.codec.http.HttpHeaderNames;
|
||||||
|
import io.netty.handler.codec.http.HttpRequest;
|
||||||
|
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||||
|
import io.netty.handler.codec.http.HttpUtil;
|
||||||
|
import io.netty.handler.ssl.SslHandler;
|
||||||
|
|
||||||
|
import static io.netty.handler.codec.http.HttpHeaderNames.*;
|
||||||
|
import static io.netty.handler.codec.http.HttpMethod.*;
|
||||||
|
import static io.netty.handler.codec.http.HttpResponseStatus.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Outputs index page content.
|
||||||
|
*/
|
||||||
|
public class WebSocketIndexPageHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
|
||||||
|
|
||||||
|
private final String websocketPath;
|
||||||
|
|
||||||
|
public WebSocketIndexPageHandler(String websocketPath) {
|
||||||
|
this.websocketPath = websocketPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Override
|
||||||
|
protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) throws Exception {
|
||||||
|
// Handle a bad request.
|
||||||
|
if (!req.getUri().startsWith("/SCIDE/SCExecutor")) {
|
||||||
|
sendHttpResponse(ctx, req,
|
||||||
|
new DefaultFullHttpResponse(req.protocolVersion(), NOT_FOUND, ctx.alloc().buffer(0)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!req.decoderResult().isSuccess()) {
|
||||||
|
sendHttpResponse(ctx, req,
|
||||||
|
new DefaultFullHttpResponse(req.protocolVersion(), BAD_REQUEST, ctx.alloc().buffer(0)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow only GET methods.
|
||||||
|
if (!GET.equals(req.method())) {
|
||||||
|
sendHttpResponse(ctx, req,
|
||||||
|
new DefaultFullHttpResponse(req.protocolVersion(), FORBIDDEN, ctx.alloc().buffer(0)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send the index page
|
||||||
|
if ("/SCIDE/SCExecutor/".equals(req.uri()) || "/SCIDE/SCExecutor/index.html".equals(req.uri())) {
|
||||||
|
String webSocketLocation = getWebSocketLocation(ctx.pipeline(), req, websocketPath);
|
||||||
|
ByteBuf content = WebSocketServerIndexPage.getContent(webSocketLocation);
|
||||||
|
FullHttpResponse res = new DefaultFullHttpResponse(req.protocolVersion(), OK, content);
|
||||||
|
res.headers().set(CONTENT_TYPE, "text/html; charset=UTF-8");
|
||||||
|
HttpUtil.setContentLength(res, content.readableBytes());
|
||||||
|
sendHttpResponse(ctx, req, res);
|
||||||
|
} else {
|
||||||
|
sendHttpResponse(ctx, req,
|
||||||
|
new DefaultFullHttpResponse(req.protocolVersion(), NOT_FOUND, ctx.alloc().buffer(0)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
|
||||||
|
cause.printStackTrace();
|
||||||
|
ctx.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void sendHttpResponse(ChannelHandlerContext ctx, FullHttpRequest req, FullHttpResponse res) {
|
||||||
|
// Generate an error page if response getStatus code is not OK (200).
|
||||||
|
HttpResponseStatus responseStatus = res.status();
|
||||||
|
if (responseStatus.code() != 200) {
|
||||||
|
ByteBufUtil.writeUtf8(res.content(), responseStatus.toString());
|
||||||
|
HttpUtil.setContentLength(res, res.content().readableBytes());
|
||||||
|
}
|
||||||
|
// Send the response and close the connection if necessary.
|
||||||
|
boolean keepAlive = HttpUtil.isKeepAlive(req) && responseStatus.code() == 200;
|
||||||
|
HttpUtil.setKeepAlive(res, keepAlive);
|
||||||
|
ChannelFuture future = ctx.writeAndFlush(res);
|
||||||
|
if (!keepAlive) {
|
||||||
|
future.addListener(ChannelFutureListener.CLOSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getWebSocketLocation(ChannelPipeline cp, HttpRequest req, String path) {
|
||||||
|
String protocol = "ws";
|
||||||
|
if (cp.get(SslHandler.class) != null) {
|
||||||
|
// SSL in use so use Secure WebSockets
|
||||||
|
protocol = "wss";
|
||||||
|
}
|
||||||
|
return protocol + "://" + req.headers().get(HttpHeaderNames.HOST) + path;
|
||||||
|
}
|
||||||
|
}
|
105
src/main/src/org/bdware/server/ws/WebSocketServerIndexPage.java
Normal file
105
src/main/src/org/bdware/server/ws/WebSocketServerIndexPage.java
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
package org.bdware.server.ws;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
|
||||||
|
/** Generates the demo HTML page which is served at http://localhost:8080/ */
|
||||||
|
public final class WebSocketServerIndexPage {
|
||||||
|
|
||||||
|
private static final String NEWLINE = "\r\n";
|
||||||
|
|
||||||
|
public static ByteBuf getContent(String webSocketLocation) {
|
||||||
|
String str =
|
||||||
|
"<html><head><title>Web Socket Test</title></head>"
|
||||||
|
+ NEWLINE
|
||||||
|
+ "<body>"
|
||||||
|
+ NEWLINE
|
||||||
|
+ "<script type=\"text/javascript\">"
|
||||||
|
+ NEWLINE
|
||||||
|
+ "var socket;"
|
||||||
|
+ NEWLINE
|
||||||
|
+ "if (!window.WebSocket) {"
|
||||||
|
+ NEWLINE
|
||||||
|
+ " window.WebSocket = window.MozWebSocket;"
|
||||||
|
+ NEWLINE
|
||||||
|
+ '}'
|
||||||
|
+ NEWLINE
|
||||||
|
+ "if (window.WebSocket) {"
|
||||||
|
+ NEWLINE
|
||||||
|
+ " socket = new WebSocket(\""
|
||||||
|
+ webSocketLocation
|
||||||
|
+ "\");"
|
||||||
|
+ NEWLINE
|
||||||
|
+ " socket.onmessage = function(event) {"
|
||||||
|
+ NEWLINE
|
||||||
|
+ " var ta = document.getElementById('responseText');"
|
||||||
|
+ NEWLINE
|
||||||
|
+ " ta.value = ta.value + '\\n' + event.data"
|
||||||
|
+ NEWLINE
|
||||||
|
+ " };"
|
||||||
|
+ NEWLINE
|
||||||
|
+ " socket.onopen = function(event) {"
|
||||||
|
+ NEWLINE
|
||||||
|
+ " var ta = document.getElementById('responseText');"
|
||||||
|
+ NEWLINE
|
||||||
|
+ " ta.value = \"Web Socket opened!\";"
|
||||||
|
+ NEWLINE
|
||||||
|
+ " };"
|
||||||
|
+ NEWLINE
|
||||||
|
+ " socket.onclose = function(event) {"
|
||||||
|
+ NEWLINE
|
||||||
|
+ " var ta = document.getElementById('responseText');"
|
||||||
|
+ NEWLINE
|
||||||
|
+ " ta.value = ta.value + \"Web Socket closed\"; "
|
||||||
|
+ NEWLINE
|
||||||
|
+ " };"
|
||||||
|
+ NEWLINE
|
||||||
|
+ "} else {"
|
||||||
|
+ NEWLINE
|
||||||
|
+ " alert(\"Your browser does not support Web Socket.\");"
|
||||||
|
+ NEWLINE
|
||||||
|
+ '}'
|
||||||
|
+ NEWLINE
|
||||||
|
+ NEWLINE
|
||||||
|
+ "function send(message) {"
|
||||||
|
+ NEWLINE
|
||||||
|
+ " if (!window.WebSocket) { return; }"
|
||||||
|
+ NEWLINE
|
||||||
|
+ " if (socket.readyState == WebSocket.OPEN) {"
|
||||||
|
+ NEWLINE
|
||||||
|
+ " socket.send(message);"
|
||||||
|
+ NEWLINE
|
||||||
|
+ " } else {"
|
||||||
|
+ NEWLINE
|
||||||
|
+ " alert(\"The socket is not open.\");"
|
||||||
|
+ NEWLINE
|
||||||
|
+ " }"
|
||||||
|
+ NEWLINE
|
||||||
|
+ '}'
|
||||||
|
+ NEWLINE
|
||||||
|
+ "</script>"
|
||||||
|
+ NEWLINE
|
||||||
|
+ "<form onsubmit=\"return false;\">"
|
||||||
|
+ NEWLINE
|
||||||
|
+ "<input type=\"text\" name=\"message\" value=\"Hello, World!\"/>"
|
||||||
|
+ "<input type=\"button\" value=\"Send Web Socket Data\""
|
||||||
|
+ NEWLINE
|
||||||
|
+ " onclick=\"send(this.form.message.value)\" />"
|
||||||
|
+ NEWLINE
|
||||||
|
+ "<h3>Output</h3>"
|
||||||
|
+ NEWLINE
|
||||||
|
+ "<textarea id=\"responseText\" style=\"width:500px;height:300px;\"></textarea>"
|
||||||
|
+ NEWLINE
|
||||||
|
+ "</form>"
|
||||||
|
+ NEWLINE
|
||||||
|
+ "</body>"
|
||||||
|
+ NEWLINE
|
||||||
|
+ "</html>"
|
||||||
|
+ NEWLINE;
|
||||||
|
return Unpooled.wrappedBuffer(str.getBytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
private WebSocketServerIndexPage() {
|
||||||
|
// Unused
|
||||||
|
}
|
||||||
|
}
|
8
src/main/src/resources/log4j.properties
Normal file
8
src/main/src/resources/log4j.properties
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
### 设置###
|
||||||
|
log4j.rootLogger = 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)%n
|
60
src/main/thirdparty/org/bdware/server/IndexServer.java
vendored
Normal file
60
src/main/thirdparty/org/bdware/server/IndexServer.java
vendored
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
package org.bdware.server;
|
||||||
|
|
||||||
|
|
||||||
|
import io.netty.bootstrap.ServerBootstrap;
|
||||||
|
import io.netty.channel.Channel;
|
||||||
|
import io.netty.channel.ChannelInitializer;
|
||||||
|
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.stream.ChunkedWriteHandler;
|
||||||
|
import org.bdware.server.http.IndexHttpHandler;
|
||||||
|
|
||||||
|
public class IndexServer {
|
||||||
|
final String PATH = "/Index";
|
||||||
|
private final int port;
|
||||||
|
|
||||||
|
private IndexServer(int port) {
|
||||||
|
this.port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
// NodeCenterServer.start(18001);
|
||||||
|
start(1614);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void start(int port) throws Exception {
|
||||||
|
System.out.println("[IndexServer] start at:" + port);
|
||||||
|
new IndexServer(port).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void start() throws Exception {
|
||||||
|
|
||||||
|
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
|
||||||
|
EventLoopGroup workerGroup = new NioEventLoopGroup();
|
||||||
|
try {
|
||||||
|
|
||||||
|
final IndexHttpHandler serverHandler = new IndexHttpHandler();
|
||||||
|
ServerBootstrap b = new ServerBootstrap();
|
||||||
|
b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).localAddress(port)
|
||||||
|
.childHandler(new ChannelInitializer<SocketChannel>() {
|
||||||
|
@Override
|
||||||
|
protected void initChannel(SocketChannel arg0) throws Exception {
|
||||||
|
arg0.pipeline().addLast(new HttpServerCodec()).addLast(new HttpObjectAggregator(65536))
|
||||||
|
.addLast(new ChunkedWriteHandler()).addLast(serverHandler);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Channel ch = b.bind(port).sync().channel();
|
||||||
|
ch.closeFuture().sync();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
bossGroup.shutdownGracefully();
|
||||||
|
workerGroup.shutdownGracefully();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
230
src/main/thirdparty/org/bdware/server/action/IndexAction.java
vendored
Normal file
230
src/main/thirdparty/org/bdware/server/action/IndexAction.java
vendored
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
package org.bdware.server.action;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import org.bdware.sc.conn.ResultCallback;
|
||||||
|
import org.bdware.sc.index.LenVarTimeSerialIndex2;
|
||||||
|
import org.bdware.sc.util.HashUtil;
|
||||||
|
import org.bdware.sc.util.JsonUtil;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class IndexAction {
|
||||||
|
|
||||||
|
static final String MISSING_ARGUMENT = "{\"status\":\"Errorr\",\"data\":\"missing arguments\"}";
|
||||||
|
static Map<String, LenVarTimeSerialIndex2> fileMap = new HashMap<>();
|
||||||
|
|
||||||
|
public IndexAction() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Action(async = true)
|
||||||
|
public void createFile(JsonObject args, final ResultCallback resultCallback) {
|
||||||
|
if (!args.has("file")) {
|
||||||
|
resultCallback.onResult(MISSING_ARGUMENT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!args.has("dataLength")) {
|
||||||
|
resultCallback.onResult(MISSING_ARGUMENT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
String fileName = "./" + args.get("file").getAsString();
|
||||||
|
File f = new File(fileName + ".datasize");
|
||||||
|
FileOutputStream fout = new FileOutputStream(f);
|
||||||
|
int dataLength = args.get("dataLength").getAsInt();
|
||||||
|
for (int i = 0; i < dataLength; i++)
|
||||||
|
fout.write(1);
|
||||||
|
fout.close();
|
||||||
|
// LenVarTimeSerialIndex2 index = getIndexFile(fileName);
|
||||||
|
resultCallback.onResult(
|
||||||
|
"{\"status\":\"Success\",\"dataLength\":" + dataLength + ",\".datasize\":" + f.length() + "}");
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||||
|
e.printStackTrace(new PrintStream(bo));
|
||||||
|
resultCallback.onResult(bo.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Action(async = true)
|
||||||
|
public void index(JsonObject args, final ResultCallback resultCallback) {
|
||||||
|
if (!args.has("content")) {
|
||||||
|
resultCallback.onResult(MISSING_ARGUMENT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!args.has("file")) {
|
||||||
|
resultCallback.onResult(MISSING_ARGUMENT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
LenVarTimeSerialIndex2 index = getIndexFile(args.get("file").getAsString());
|
||||||
|
String content = args.get("content").getAsString();
|
||||||
|
long ret = index.index(HashUtil.str16ToBytes(content));
|
||||||
|
resultCallback.onResult("{\"status\":\"Success\",\"date\":" + ret + "}");
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||||
|
e.printStackTrace(new PrintStream(bo));
|
||||||
|
resultCallback.onResult(bo.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Action(async = true)
|
||||||
|
public void dataSize(JsonObject args, final ResultCallback resultCallback) {
|
||||||
|
if (!args.has("file")) {
|
||||||
|
resultCallback.onResult(MISSING_ARGUMENT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
LenVarTimeSerialIndex2 index = getIndexFile(args.get("file").getAsString());
|
||||||
|
|
||||||
|
resultCallback.onResult("{\"dataSize\":" + index.dataSize + ",\"fileSize\":" + index.fileSize + "}");
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||||
|
e.printStackTrace(new PrintStream(bo));
|
||||||
|
resultCallback.onResult(bo.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Action(async = true)
|
||||||
|
public void requestByTime(JsonObject args, final ResultCallback resultCallback) {
|
||||||
|
if (!args.has("file")) {
|
||||||
|
resultCallback.onResult(MISSING_ARGUMENT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!args.has("startTime")) {
|
||||||
|
resultCallback.onResult(MISSING_ARGUMENT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!args.has("endTime")) {
|
||||||
|
resultCallback.onResult(MISSING_ARGUMENT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
LenVarTimeSerialIndex2 index = getIndexFile(args.get("file").getAsString());
|
||||||
|
long startTime = args.get("startTime").getAsLong();
|
||||||
|
long endTime = args.get("endTime").getAsLong();
|
||||||
|
List<byte[]> result = index.requestByTime(startTime, endTime);
|
||||||
|
returnSuccess(resultCallback, result);
|
||||||
|
} catch (Exception e) {
|
||||||
|
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||||
|
e.printStackTrace(new PrintStream(bo));
|
||||||
|
resultCallback.onResult(bo.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void returnSuccess(ResultCallback resultCallback, List<byte[]> result) {
|
||||||
|
Response r = new Response();
|
||||||
|
r.status = "Success";
|
||||||
|
r.list = new ArrayList<>();
|
||||||
|
for (byte[] bytes : result) {
|
||||||
|
r.list.add(new Data(bytes));
|
||||||
|
}
|
||||||
|
resultCallback.onResult(JsonUtil.toJson(r));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Action(async = true)
|
||||||
|
public void request(JsonObject args, final ResultCallback resultCallback) {
|
||||||
|
if (!args.has("file")) {
|
||||||
|
resultCallback.onResult(MISSING_ARGUMENT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!args.has("offset")) {
|
||||||
|
resultCallback.onResult(MISSING_ARGUMENT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!args.has("count")) {
|
||||||
|
resultCallback.onResult(MISSING_ARGUMENT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
LenVarTimeSerialIndex2 index = getIndexFile(args.get("file").getAsString());
|
||||||
|
long offset = args.get("offset").getAsLong();
|
||||||
|
int count = args.get("count").getAsInt();
|
||||||
|
List<byte[]> result = index.request(offset, count);
|
||||||
|
|
||||||
|
returnSuccess(resultCallback, result);
|
||||||
|
} catch (Exception e) {
|
||||||
|
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||||
|
e.printStackTrace(new PrintStream(bo));
|
||||||
|
resultCallback.onResult(bo.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Action(async = true)
|
||||||
|
public void getSize(JsonObject args, final ResultCallback resultCallback) {
|
||||||
|
if (!args.has("file")) {
|
||||||
|
resultCallback.onResult(MISSING_ARGUMENT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
LenVarTimeSerialIndex2 index = getIndexFile(args.get("file").getAsString());
|
||||||
|
int size = (int) index.size();
|
||||||
|
resultCallback.onResult("{\"status\":\"Success\",\"size\":" + size + "}");
|
||||||
|
} catch (Exception e) {
|
||||||
|
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||||
|
e.printStackTrace(new PrintStream(bo));
|
||||||
|
resultCallback.onResult(bo.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private LenVarTimeSerialIndex2 getIndexFile(String str) {
|
||||||
|
LenVarTimeSerialIndex2 indexFile = fileMap.get(str);
|
||||||
|
if (indexFile == null) {
|
||||||
|
indexFile = new LenVarTimeSerialIndex2(str);
|
||||||
|
fileMap.put(str, indexFile);
|
||||||
|
}
|
||||||
|
return indexFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Action(async = true)
|
||||||
|
public void manullyIndex(JsonObject args, final ResultCallback resultCallback) {
|
||||||
|
if (!args.has("date")) {
|
||||||
|
resultCallback.onResult(MISSING_ARGUMENT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!args.has("content")) {
|
||||||
|
resultCallback.onResult(MISSING_ARGUMENT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!args.has("file")) {
|
||||||
|
resultCallback.onResult(MISSING_ARGUMENT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
LenVarTimeSerialIndex2 index = getIndexFile(args.get("file").getAsString());
|
||||||
|
long date = Long.parseLong(args.get("date").getAsString());
|
||||||
|
String content = args.get("content").getAsString();
|
||||||
|
index.manullyIndex(date, HashUtil.str16ToBytes(content));
|
||||||
|
resultCallback.onResult("{\"status\":\"Success\"}");
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||||
|
e.printStackTrace(new PrintStream(bo));
|
||||||
|
resultCallback.onResult(bo.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Response {
|
||||||
|
String status;
|
||||||
|
List<Data> list;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Data {
|
||||||
|
long date;
|
||||||
|
String data;
|
||||||
|
|
||||||
|
public Data(byte[] bytes) {
|
||||||
|
date = HashUtil.bytes2Long(bytes);
|
||||||
|
data = HashUtil.byteArray2Str(bytes, 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
157
src/main/thirdparty/org/bdware/server/http/IndexHttpHandler.java
vendored
Normal file
157
src/main/thirdparty/org/bdware/server/http/IndexHttpHandler.java
vendored
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
package org.bdware.server.http;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
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.util.JsonUtil;
|
||||||
|
import org.bdware.server.action.ActionExecutor;
|
||||||
|
import org.bdware.server.action.HttpResultCallback;
|
||||||
|
import org.bdware.server.action.IndexAction;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
import static io.netty.handler.codec.http.HttpResponseStatus.OK;
|
||||||
|
|
||||||
|
@Sharable
|
||||||
|
public class IndexHttpHandler 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(IndexHttpHandler.class);
|
||||||
|
private static ActionExecutor<ResultCallback, JsonObject> actionExecutor = new ActionExecutor<>(
|
||||||
|
Executors.newFixedThreadPool(5), new IndexAction());
|
||||||
|
|
||||||
|
public IndexHttpHandler() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void channelReadComplete(ChannelHandlerContext ctx) {
|
||||||
|
ctx.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Override
|
||||||
|
public void channelRead0(ChannelHandlerContext ctx, HttpObject msg) {
|
||||||
|
if (msg instanceof FullHttpRequest) {
|
||||||
|
handleHttpRequest(ctx, (FullHttpRequest) msg);
|
||||||
|
} else {
|
||||||
|
LOGGER.info("[Ignore] " + msg.getClass().getCanonicalName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest msg) {
|
||||||
|
if (!msg.uri().startsWith("/SCIDE/Index")) {
|
||||||
|
try {
|
||||||
|
DefaultFullHttpResponse fullResponse = new DefaultFullHttpResponse(msg.getProtocolVersion(), OK,
|
||||||
|
Unpooled.wrappedBuffer(UNSUPPORTED_HTTP_METHOD.getBytes()));
|
||||||
|
ChannelFuture f = ctx.write(fullResponse);
|
||||||
|
f.addListener(ChannelFutureListener.CLOSE);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
HttpRequest req = (HttpRequest) msg;
|
||||||
|
FullHttpResponse fullResponse = null;
|
||||||
|
io.netty.handler.codec.http.HttpMethod method = req.getMethod();
|
||||||
|
if (method.equals(HttpMethod.GET)) {
|
||||||
|
QueryStringDecoder decoderQuery = new QueryStringDecoder(req.getUri());
|
||||||
|
Map<String, List<String>> parame = decoderQuery.parameters();
|
||||||
|
JsonObject transfomedParam = new JsonObject();
|
||||||
|
for (String key : parame.keySet()) {
|
||||||
|
List<String> val = parame.get(key);
|
||||||
|
if (val != null)
|
||||||
|
transfomedParam.addProperty(key, val.get(0));
|
||||||
|
}
|
||||||
|
handleReq(transfomedParam, ctx, req);
|
||||||
|
return;
|
||||||
|
} else if (method.equals(HttpMethod.POST)) {
|
||||||
|
ByteBuf content = msg.content();
|
||||||
|
byte[] reqContent = new byte[content.readableBytes()];
|
||||||
|
content.readBytes(reqContent);
|
||||||
|
String strContent;
|
||||||
|
try {
|
||||||
|
strContent = new String(reqContent, "UTF-8");
|
||||||
|
JsonObject map = new JsonParser().parse(strContent).getAsJsonObject();
|
||||||
|
handleReq(map, ctx, req);
|
||||||
|
return;
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fullResponse = new DefaultFullHttpResponse(req.getProtocolVersion(), OK,
|
||||||
|
Unpooled.wrappedBuffer(UNSUPPORTED_HTTP_METHOD.getBytes()));
|
||||||
|
}
|
||||||
|
ChannelFuture f = ctx.write(fullResponse);
|
||||||
|
f.addListener(ChannelFutureListener.CLOSE);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleReq(JsonObject map, ChannelHandlerContext ctx, HttpRequest req) {
|
||||||
|
try {
|
||||||
|
byte[] ret = null;
|
||||||
|
String action = null;
|
||||||
|
if (!map.has("action")) {
|
||||||
|
ret = UNSUPPORTED_ACTION.getBytes();
|
||||||
|
DefaultFullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, OK,
|
||||||
|
Unpooled.wrappedBuffer(ret));
|
||||||
|
ChannelFuture f = ctx.write(response);
|
||||||
|
f.addListener(ChannelFutureListener.CLOSE);
|
||||||
|
return;
|
||||||
|
} else
|
||||||
|
action = map.get("action").getAsString();
|
||||||
|
if (action != null) {
|
||||||
|
HttpResultCallback cb;
|
||||||
|
if (action.equals("downloadContract")) {
|
||||||
|
cb = new FileDownloaderCallback(ctx, req);
|
||||||
|
} else if (map.has("callback")) {
|
||||||
|
cb = new HttpResultCallback(ctx, map.get("callback").getAsString());
|
||||||
|
cb.addHeader("Content-Type", "application/json");
|
||||||
|
} else {
|
||||||
|
cb = new HttpResultCallback(ctx, null);
|
||||||
|
cb.addHeader("Content-Type", "application/json");
|
||||||
|
}
|
||||||
|
if (map.get("action").getAsString().equals("downloadUUID"))
|
||||||
|
cb.addHeader("content-disposition", "attachment;filename=encodeduuid.key");
|
||||||
|
|
||||||
|
actionExecutor.handle(action, map, cb);
|
||||||
|
}
|
||||||
|
} 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<String, String>();
|
||||||
|
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) {
|
||||||
|
cause.printStackTrace();
|
||||||
|
ctx.close();
|
||||||
|
}
|
||||||
|
}
|
49
src/test/java/org/bdware/server/http/URIHandlerTest.java
Normal file
49
src/test/java/org/bdware/server/http/URIHandlerTest.java
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package org.bdware.server.http;
|
||||||
|
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.handler.codec.http.FullHttpRequest;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class URIHandlerTest {
|
||||||
|
URIHandler handler;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void init() {
|
||||||
|
handler = new URIHandler();
|
||||||
|
handler.register(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@URIPath(
|
||||||
|
method = HttpMethod.OPTIONS,
|
||||||
|
value = {"/"})
|
||||||
|
public void h1(ChannelHandlerContext ctx, FullHttpRequest request) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
@URIPath(
|
||||||
|
method = HttpMethod.GET,
|
||||||
|
value = {"/SCIDE/ABC/", "/SCIDE/CEEEE"})
|
||||||
|
public void h2(ChannelHandlerContext ctx, FullHttpRequest request) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
@URIPath(
|
||||||
|
method = HttpMethod.GET,
|
||||||
|
value = {"/"})
|
||||||
|
public void h3(ChannelHandlerContext ctx, FullHttpRequest request) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
@URIPath(
|
||||||
|
method = HttpMethod.GET,
|
||||||
|
value = {"/client"})
|
||||||
|
public void h4(ChannelHandlerContext ctx, FullHttpRequest request) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
System.out.println(handler);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,91 @@
|
|||||||
|
package org.bdware.server.permission.test;
|
||||||
|
|
||||||
|
import org.bdware.server.permission.Permission;
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
|
|
||||||
|
import static org.bdware.server.permission.Permission.*;
|
||||||
|
|
||||||
|
public class PermissionTest {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
EnumSet<Permission> setCenterManager = EnumSet.noneOf(Permission.class);
|
||||||
|
// 为了便于生成五种角色的Permission 可以用一串set.add()。然后打印出来。
|
||||||
|
// 中心管理员
|
||||||
|
setCenterManager.add(ApplyRole);
|
||||||
|
setCenterManager.add(NodeStateList);
|
||||||
|
setCenterManager.add(AuthNodeManager);
|
||||||
|
setCenterManager.add(ListAllUsers);
|
||||||
|
setCenterManager.add(ListApplyUser);
|
||||||
|
setCenterManager.add(DeleteNodeManager);
|
||||||
|
setCenterManager.add(ListTrustCluster);
|
||||||
|
setCenterManager.add(AssignTrustedCluster);
|
||||||
|
setCenterManager.add(QueryActionLog);// 增加listLog(时间戳)
|
||||||
|
setCenterManager.add(QueryUserStateLog);// 查看节点日志
|
||||||
|
long CenterManager = 0L;
|
||||||
|
for (Permission p : setCenterManager) {
|
||||||
|
CenterManager |= p.getValue();
|
||||||
|
}
|
||||||
|
System.out.println("[centerManager]" + String.format("0x%xL", CenterManager));
|
||||||
|
EnumSet<Permission> setNodeManager = EnumSet.noneOf(Permission.class);
|
||||||
|
// 节点管理员
|
||||||
|
setNodeManager.add(ApplyRole);
|
||||||
|
setNodeManager.add(ListTrustCluster);
|
||||||
|
setNodeManager.add(QueryUserStateLog);
|
||||||
|
setNodeManager.add(ConfigureNode);
|
||||||
|
setNodeManager.add(ManageNode);
|
||||||
|
setNodeManager.add(GetNodeInfo);
|
||||||
|
setCenterManager.add(TakeScreenShot);
|
||||||
|
long NodeManager = 0L;//2248150849
|
||||||
|
for (Permission p : setNodeManager) {
|
||||||
|
NodeManager |= p.getValue();
|
||||||
|
}
|
||||||
|
System.out.println("[NodeManager]" + String.format("0x%xL", NodeManager) + " " + NodeManager);
|
||||||
|
|
||||||
|
EnumSet<Permission> setContractProvider = EnumSet.noneOf(Permission.class);
|
||||||
|
// 合约提供者
|
||||||
|
setContractProvider.add(ContractCodeStatisticsList);
|
||||||
|
setContractProvider.add(ConfigureContractPermission);
|
||||||
|
setContractProvider.add(EditContract);
|
||||||
|
setContractProvider.add(ListProject);
|
||||||
|
setContractProvider.add(StaticAnalysis);
|
||||||
|
setContractProvider.add(Compile);
|
||||||
|
long ContractProvider = 0L;
|
||||||
|
for (Permission p : setContractProvider) {
|
||||||
|
ContractProvider |= p.getValue();
|
||||||
|
}
|
||||||
|
System.out.println("[ContractProvider]" + String.format("0x%xL", ContractProvider));
|
||||||
|
EnumSet<Permission> ContractInstanceManager = EnumSet.noneOf(Permission.class);
|
||||||
|
// 合约管理者
|
||||||
|
ContractInstanceManager.add(AssignTrustedCluster);
|
||||||
|
ContractInstanceManager.add(ListTrustCluster);
|
||||||
|
ContractInstanceManager.add(ContractCodeStatisticsList);
|
||||||
|
ContractInstanceManager.add(StaticAnalysis);
|
||||||
|
ContractInstanceManager.add(ContractPermissionList);
|
||||||
|
ContractInstanceManager.add(ListContractProgress);
|
||||||
|
ContractInstanceManager.add(CheckContractStatus);
|
||||||
|
ContractInstanceManager.add(ListContractLog);
|
||||||
|
ContractInstanceManager.add(TimeTravel);
|
||||||
|
ContractInstanceManager.add(ManualDump);
|
||||||
|
ContractInstanceManager.add(ManageMemory);
|
||||||
|
ContractInstanceManager.add(ManageContract);
|
||||||
|
ContractInstanceManager.add(CreateLedger);
|
||||||
|
ContractInstanceManager.add(Compile);
|
||||||
|
long ContractInstanceManagerVAL = 0L;
|
||||||
|
for (Permission p : ContractInstanceManager) {
|
||||||
|
ContractInstanceManagerVAL |= p.getValue();
|
||||||
|
}
|
||||||
|
System.out.println("[ContractInstanceManager]" + String.format("0x%xL", ContractInstanceManagerVAL));
|
||||||
|
|
||||||
|
EnumSet<Permission> ContractUser = EnumSet.noneOf(Permission.class);
|
||||||
|
// 合约使用者
|
||||||
|
ContractUser.add(ListContractProgress);
|
||||||
|
ContractUser.add(ContractPermissionList);
|
||||||
|
ContractUser.add(CheckContractStatus);
|
||||||
|
ContractUser.add(ListContractLog);
|
||||||
|
long ContractUserVAL = 0L;
|
||||||
|
for (Permission p : ContractUser) {
|
||||||
|
ContractUserVAL |= p.getValue();
|
||||||
|
}
|
||||||
|
System.out.println("[ContractUser]" + String.format("0x%xL", ContractUserVAL));
|
||||||
|
}
|
||||||
|
}
|
84
src/test/java/org/bdware/server/test/BDLedgerClient.java
Normal file
84
src/test/java/org/bdware/server/test/BDLedgerClient.java
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
package org.bdware.server.test;
|
||||||
|
|
||||||
|
import com.google.protobuf.ByteString;
|
||||||
|
import org.bdware.bdledger.api.grpc.Client;
|
||||||
|
import org.bdware.bdledger.api.grpc.pb.CommonProto;
|
||||||
|
import org.bdware.bdledger.api.grpc.pb.LedgerProto;
|
||||||
|
import org.bdware.bdledger.api.grpc.pb.QueryProto;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
|
||||||
|
public class BDLedgerClient {
|
||||||
|
private Client client;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void initClient() {
|
||||||
|
//
|
||||||
|
client = new Client("39.104.201.40", 21121);
|
||||||
|
System.out.println(client.getLedgersSync().getLedgersList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String byteArray2Str(byte[] byteArray, int offset) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (int j = offset; j < byteArray.length; j++) {
|
||||||
|
byte b = byteArray[j];
|
||||||
|
int i = ((int) b) & 0xff;
|
||||||
|
sb.append(String.format("%x%x", i >> 4, i & 0xf));
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createLedger() {
|
||||||
|
client.createLedger("default");
|
||||||
|
}
|
||||||
|
|
||||||
|
static SecureRandom random = new SecureRandom((System.currentTimeMillis() + "").getBytes());
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void send() {
|
||||||
|
String mockedFrom = "0xb60e8dd61c5d32be8058bb8eb970870f07233155";
|
||||||
|
|
||||||
|
LedgerProto.SendTransactionResponse ret2 =
|
||||||
|
client.sendTransactionSync(
|
||||||
|
"default",
|
||||||
|
CommonProto.TransactionType.MESSAGE,
|
||||||
|
mockedFrom,
|
||||||
|
random.nextLong(),
|
||||||
|
mockedFrom,
|
||||||
|
"Hellooooo".getBytes(StandardCharsets.UTF_8));
|
||||||
|
ByteString hash = ret2.getHash();
|
||||||
|
System.out.println("[BDLedgerClient] hash:" + byteArray2Str(hash.toByteArray(), 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void countBlock() {
|
||||||
|
// http://069.node.internetapi.cn:21030/SCIDE/CMManager?action=queryDataByHash&hash=30f0b38a845bc3280f0bafa93b2034c8bc494637
|
||||||
|
// "ea508a07b79afc03c94a84ff190ca29f1153ef75"
|
||||||
|
// cb304919522a4acd8f2b23fadf993829ac40795a
|
||||||
|
QueryProto.GetBlocksResponse blocks =
|
||||||
|
client.getBlocksSync(
|
||||||
|
"default",
|
||||||
|
System.currentTimeMillis() - 23L * 3600L * 1000L,
|
||||||
|
QueryProto.IncludeTransactions.FULL);
|
||||||
|
System.out.println("BlockCount:" + blocks.getBlocksCount());
|
||||||
|
// GetTransactionByHashResponse result = client.getTransactionByHashSync("test",
|
||||||
|
// "30f0b38a845bc3280f0bafa93b2034c8bc494637");
|
||||||
|
// ByteString bytes = result.getTransaction().getData();
|
||||||
|
// System.out.println(new String(bytes.toByteArray()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void queryTransaction() {
|
||||||
|
// test2 31b50daa8d607c673af5ef449a4d78c70bf952d4
|
||||||
|
// bdcontract cb304919522a4acd8f2b23fadf993829ac40795a
|
||||||
|
QueryProto.GetTransactionByHashResponse result =
|
||||||
|
client.getTransactionByHashSync(
|
||||||
|
"default", "78bf9fb27963b26bf2f8d558f20bf44559178b67");
|
||||||
|
ByteString bytes = result.getTransaction().getData();
|
||||||
|
System.out.println(new String(bytes.toByteArray()));
|
||||||
|
}
|
||||||
|
}
|
14
src/test/java/org/bdware/server/test/ByteHexUtilTest.java
Normal file
14
src/test/java/org/bdware/server/test/ByteHexUtilTest.java
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package org.bdware.server.test;
|
||||||
|
|
||||||
|
import org.bdware.server.ByteHexUtil;
|
||||||
|
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
|
||||||
|
public class ByteHexUtilTest {
|
||||||
|
public static void main(String[] args) throws UnsupportedEncodingException {
|
||||||
|
String str = "ecb2b0fd0e38b8dbe7cbe1e61ab15afca00da3ba";
|
||||||
|
byte[] bytes = ByteHexUtil.decode(str);
|
||||||
|
System.out.println(URLEncoder.encode("inu3ASBLQE9Pj+hNQjORuK9Amfs=", "utf-8"));
|
||||||
|
}
|
||||||
|
}
|
96
src/test/java/org/bdware/server/test/CMHttpTest.java
Normal file
96
src/test/java/org/bdware/server/test/CMHttpTest.java
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
package org.bdware.server.test;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
public class CMHttpTest {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// ManagerActionsTest();
|
||||||
|
CMActionTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CMActionTest() {
|
||||||
|
//http_load
|
||||||
|
String host = "http://127.0.0.1:18000/SCIDE/CMManager?action=";
|
||||||
|
String url1 = host + "ping";
|
||||||
|
System.out.println(httpGet(url1));
|
||||||
|
url1 = host + "listContractProcess";
|
||||||
|
System.out.println(httpGet(url1));
|
||||||
|
url1 = host + "writeDyjs&target=test1120.dyjs&contractID=123&content=empty";
|
||||||
|
System.out.println(httpGet(url1));
|
||||||
|
url1 = host + "executeContract&contractID=BDCoin&operation=totalSupply&arg=en";
|
||||||
|
System.out.println(httpGet(url1));
|
||||||
|
url1 = host + "getCodeByID&contractID=DORepo";
|
||||||
|
System.out.println(httpGet(url1));
|
||||||
|
url1 = host + "getPublicKey";
|
||||||
|
System.out.println(httpGet(url1));
|
||||||
|
url1 = host + "dumpContract&contractID=DORepo&target=dumTest.dyjs";
|
||||||
|
System.out.println(httpGet(url1));
|
||||||
|
url1 = host + "loadMemory&contractID=DORepo&target=dumTest.dyjs";
|
||||||
|
System.out.println(httpGet(url1));
|
||||||
|
url1 = host + "killContractProcess&contractID=abc";
|
||||||
|
System.out.println(httpGet(url1));
|
||||||
|
url1 = host + "killAllContract";
|
||||||
|
System.out.println(httpGet(url1));
|
||||||
|
url1 = host + "startContractBatched&fileList=" + URLEncoder.encode("[\"algorithmExample.yjs\",\"AAA.yjs\"]");
|
||||||
|
System.out.println(httpGet(url1));
|
||||||
|
// url1 = host + "startContractInTempZips";
|
||||||
|
// System.out.println(httpGet(url1));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ManagerActionsTest() {
|
||||||
|
String host = "http://127.0.0.1:18000/SCIDE/CMManager?action=";
|
||||||
|
String url1 = host + "getEncodedUUID";
|
||||||
|
System.out.println(httpGet(url1));
|
||||||
|
url1 = host + "downloadUUID";
|
||||||
|
System.out.println(httpGet(url1));
|
||||||
|
url1 = host + "updateConfig&key=projectDir&val="
|
||||||
|
+ URLEncoder.encode("/Users/huaqiancai/java_workspace/SmartContract/contractExamples");
|
||||||
|
System.out.println(httpGet(url1));
|
||||||
|
url1 = host + "loadConfig";
|
||||||
|
System.out.println(httpGet(url1));
|
||||||
|
url1 = host + "getLicenceExpiredDate";
|
||||||
|
System.out.println(httpGet(url1));
|
||||||
|
url1 = host + "generatePrivateKey";
|
||||||
|
System.out.println(httpGet(url1));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Result {
|
||||||
|
int resposeCode;
|
||||||
|
String response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String httpGet(String str) {
|
||||||
|
System.out.println("JavaScriptEntry httpGet:" + str);
|
||||||
|
Result r = new Result();
|
||||||
|
try {
|
||||||
|
URL url = new URL(str);
|
||||||
|
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||||
|
r.resposeCode = connection.getResponseCode();
|
||||||
|
InputStream input = connection.getInputStream();
|
||||||
|
Scanner sc = new Scanner(input);
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (; sc.hasNextLine();) {
|
||||||
|
sb.append(sc.nextLine()).append("\n");
|
||||||
|
}
|
||||||
|
sc.close();
|
||||||
|
r.response = sb.toString();
|
||||||
|
return new Gson().toJson(r);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
r.resposeCode = 505;
|
||||||
|
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||||
|
e.printStackTrace(new PrintStream(bo));
|
||||||
|
r.response = bo.toString();
|
||||||
|
return new Gson().toJson(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
21
src/test/java/org/bdware/server/test/GsonParseTest.java
Normal file
21
src/test/java/org/bdware/server/test/GsonParseTest.java
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package org.bdware.server.test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
import org.bdware.sc.bean.ContractDesp;
|
||||||
|
|
||||||
|
public class GsonParseTest {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
String jsonStr = "{\"action\":\"updateContract\",\"contracts\":\"[{\\\"contractID\\\":\\\"-1306108766\\\",\\\"contractName\\\":\\\"EventSuberAtCHQ\\\",\\\"events\\\":[\\\"def\\\"],\\\"exportedFunctions\\\":[{\\\"annotations\\\":[{\\\"type\\\":\\\"LogType\\\",\\\"args\\\":[\\\"\\\\\\\"Arg\\\\\\\"\\\"]}],\\\"functionName\\\":\\\"init\\\"},{\\\"annotations\\\":[{\\\"type\\\":\\\"LogType\\\",\\\"args\\\":[\\\"\\\\\\\"Arg\\\\\\\"\\\"]}],\\\"functionName\\\":\\\"handler\\\"}]}]\"}\n";
|
||||||
|
JsonObject jo = new JsonParser().parse(jsonStr).getAsJsonObject();
|
||||||
|
List<ContractDesp> contracts = new Gson().fromJson(jo.get("contracts").getAsString(),
|
||||||
|
new TypeToken<List<ContractDesp>>() {
|
||||||
|
}.getType());
|
||||||
|
System.out.println(new GsonBuilder().setPrettyPrinting().create().toJson(contracts));
|
||||||
|
}
|
||||||
|
}
|
111
src/test/java/org/bdware/server/test/HttpPostFormTest.java
Normal file
111
src/test/java/org/bdware/server/test/HttpPostFormTest.java
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
package org.bdware.server.test;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class HttpPostFormTest {
|
||||||
|
|
||||||
|
public static void postForm(String url, Map<String, String> params) {
|
||||||
|
|
||||||
|
String responseMessage = "";
|
||||||
|
StringBuffer response = new StringBuffer();
|
||||||
|
HttpURLConnection httpConnection = null;
|
||||||
|
OutputStreamWriter out = null;
|
||||||
|
BufferedReader reader = null;
|
||||||
|
try {
|
||||||
|
URL urlPost = new URL(url);
|
||||||
|
httpConnection = (HttpURLConnection) urlPost.openConnection();
|
||||||
|
httpConnection.setDoOutput(true);
|
||||||
|
httpConnection.setDoInput(true);
|
||||||
|
httpConnection.setRequestMethod("POST");
|
||||||
|
httpConnection.setUseCaches(false);
|
||||||
|
httpConnection.setInstanceFollowRedirects(true);
|
||||||
|
httpConnection.setRequestProperty("Connection", "Keep-Alive");
|
||||||
|
httpConnection.setRequestProperty("Charset", "UTF-8");
|
||||||
|
// 设置边界
|
||||||
|
String BOUNDARY = "----------" + System.currentTimeMillis();
|
||||||
|
// httpConnection.setRequestProperty("Content-Type", "multipart/form-data;
|
||||||
|
// boundary=" + BOUNDARY);
|
||||||
|
httpConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;boundary=" + BOUNDARY);
|
||||||
|
|
||||||
|
// 连接,从postUrl.openConnection()至此的配置必须要在connect之前完成,
|
||||||
|
// 要注意的是connection.getOutputStream会隐含的进行connect。
|
||||||
|
// 实际上只是建立了一个与服务器的tcp连接,并没有实际发送http请求。
|
||||||
|
|
||||||
|
httpConnection.connect();
|
||||||
|
out = new OutputStreamWriter(httpConnection.getOutputStream(), "UTF-8");
|
||||||
|
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
int count = params.size();
|
||||||
|
for (String key : params.keySet()) {
|
||||||
|
sb.append(key + "=" + URLEncoder.encode(params.get(key)));
|
||||||
|
count--;
|
||||||
|
if (count > 0)
|
||||||
|
sb.append("&");
|
||||||
|
}
|
||||||
|
out.write(sb.toString());
|
||||||
|
System.out.println("send_url:" + url);
|
||||||
|
System.out.println("send_data:" + sb.toString());
|
||||||
|
// flush and close
|
||||||
|
out.flush();
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (null != out) {
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
if (null != reader) {
|
||||||
|
reader.close();
|
||||||
|
}
|
||||||
|
if (null != httpConnection) {
|
||||||
|
httpConnection.disconnect();
|
||||||
|
}
|
||||||
|
} catch (Exception e2) {
|
||||||
|
e2.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
reader = new BufferedReader(new InputStreamReader(httpConnection.getInputStream(), "UTF-8"));
|
||||||
|
while ((responseMessage = reader.readLine()) != null) {
|
||||||
|
response.append(responseMessage);
|
||||||
|
response.append("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!"failure".equals(response.toString())) {
|
||||||
|
System.out.println("success");
|
||||||
|
} else {
|
||||||
|
System.out.println("failue");
|
||||||
|
}
|
||||||
|
// 将该url的配置信息缓存起来
|
||||||
|
System.out.println(response.toString());
|
||||||
|
System.out.println(httpConnection.getResponseCode());
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
String url = "http://47.106.38.23:13081/register";
|
||||||
|
|
||||||
|
Map<String, String> params = new HashMap<String, String>();
|
||||||
|
String sucFix = System.currentTimeMillis() + "_ContractLog";
|
||||||
|
params.put("DOI", "86.5000.470/" + sucFix);
|
||||||
|
params.put("Description", "Contract Log");
|
||||||
|
params.put("Interface", "");
|
||||||
|
params.put("Address", "");
|
||||||
|
params.put("PublicKey", "");
|
||||||
|
params.put("Signature", "");
|
||||||
|
// http://47.106.38.23:8080/idsystem/doDetail.html?doi=86.5000.470/1570626378959_ContractLog
|
||||||
|
postForm(url, params);
|
||||||
|
}
|
||||||
|
}
|
8
src/test/java/org/bdware/server/test/LongParseTest.java
Normal file
8
src/test/java/org/bdware/server/test/LongParseTest.java
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package org.bdware.server.test;
|
||||||
|
|
||||||
|
public class LongParseTest {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
String str = "6151".toUpperCase();
|
||||||
|
Long.parseUnsignedLong(str, 16);
|
||||||
|
}
|
||||||
|
}
|
84
src/test/java/org/bdware/server/test/NCHttpTest.java
Normal file
84
src/test/java/org/bdware/server/test/NCHttpTest.java
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
package org.bdware.server.test;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
public class NCHttpTest {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// ManagerActionsTest();
|
||||||
|
CMActionTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CMActionTest() {
|
||||||
|
String host = "http://127.0.0.1:18001/SCIDE/NodeCenter?action=";
|
||||||
|
String url1 = host + "ping";
|
||||||
|
System.out.println(httpGet(url1));
|
||||||
|
url1 = host + "setNodeID";
|
||||||
|
System.out.println(httpGet(url1));
|
||||||
|
url1 = host + "listCMInfo";
|
||||||
|
System.out.println(httpGet(url1));
|
||||||
|
url1 = host + "updateContract";
|
||||||
|
System.out.println(httpGet(url1));
|
||||||
|
|
||||||
|
url1 = host + "executeContractOnOtherNodes&requestID=33333&contractRequest={\"contractID\":\"BDCoin\",\"action\":\"totalSupply\",\"arg\":\"n\"}";
|
||||||
|
System.out.println(httpGet(url1));
|
||||||
|
// url1 = host + "startContractInTempZips";
|
||||||
|
// System.out.println(httpGet(url1));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ManagerActionsTest() {
|
||||||
|
String host = "http://127.0.0.1:18000/SCIDE/CMManager?action=";
|
||||||
|
String url1 = host + "getEncodedUUID";
|
||||||
|
System.out.println(httpGet(url1));
|
||||||
|
url1 = host + "downloadUUID";
|
||||||
|
System.out.println(httpGet(url1));
|
||||||
|
url1 = host + "updateConfig&key=projectDir&val="
|
||||||
|
+ URLEncoder.encode("/Users/huaqiancai/java_workspace/SmartContract/contractExamples");
|
||||||
|
System.out.println(httpGet(url1));
|
||||||
|
url1 = host + "loadConfig";
|
||||||
|
System.out.println(httpGet(url1));
|
||||||
|
url1 = host + "getLicenceExpiredDate";
|
||||||
|
System.out.println(httpGet(url1));
|
||||||
|
url1 = host + "generatePrivateKey";
|
||||||
|
System.out.println(httpGet(url1));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Result {
|
||||||
|
int resposeCode;
|
||||||
|
String response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String httpGet(String str) {
|
||||||
|
System.out.println("JavaScriptEntry httpGet:" + str);
|
||||||
|
Result r = new Result();
|
||||||
|
try {
|
||||||
|
URL url = new URL(str);
|
||||||
|
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||||
|
r.resposeCode = connection.getResponseCode();
|
||||||
|
InputStream input = connection.getInputStream();
|
||||||
|
Scanner sc = new Scanner(input);
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (; sc.hasNextLine();) {
|
||||||
|
sb.append(sc.nextLine()).append("\n");
|
||||||
|
}
|
||||||
|
sc.close();
|
||||||
|
r.response = sb.toString();
|
||||||
|
return new Gson().toJson(r);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
r.resposeCode = 505;
|
||||||
|
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||||
|
e.printStackTrace(new PrintStream(bo));
|
||||||
|
r.response = bo.toString();
|
||||||
|
return new Gson().toJson(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
19
src/test/java/org/bdware/server/test/StringTest.java
Normal file
19
src/test/java/org/bdware/server/test/StringTest.java
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package org.bdware.server.test;
|
||||||
|
|
||||||
|
public class StringTest {
|
||||||
|
public static void main(String[] arg) {
|
||||||
|
// String str = "\\manifest.json\\dadad\\daaa";
|
||||||
|
// System.out.println(str.replaceAll("\\\\", (byte)"/"));
|
||||||
|
byte[] arr = new byte[] { (byte) 0x1, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x2, (byte) 0xff, (byte) 0xff,
|
||||||
|
(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x89, (byte) 0x7f, (byte) 0x51, (byte) 0x8c, (byte) 0x50,
|
||||||
|
(byte) 0xbb, (byte) 0xd0, (byte) 0x7f, (byte) 0xff, (byte) 0xff, (byte) 0xe9, (byte) 0xf4, (byte) 0xf8,
|
||||||
|
(byte) 0xfc, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x4, (byte) 0xff, (byte) 0xff, (byte) 0xff,
|
||||||
|
(byte) 0xff, (byte) 0xff, (byte) 0x89, (byte) 0x7f, (byte) 0x51, (byte) 0x8c, (byte) 0x3e, (byte) 0xf4,
|
||||||
|
(byte) 0x8, (byte) 0x40, (byte) 0x9f, (byte) 0x84, (byte) 0x50, (byte) 0xbb, (byte) 0xd0, (byte) 0x7f,
|
||||||
|
(byte) 0xff, (byte) 0xff, (byte) 0xe9, (byte) 0xf4, (byte) 0xf8, (byte) 0xfc, (byte) 0xf8, (byte) 0xfc,
|
||||||
|
(byte) 0x0 };
|
||||||
|
System.out.println(new String(arr));
|
||||||
|
String str = "042668227e8283cc132863cf7b83489f81056c87a19f878515d6787db7f86da7145ae05926b8e8053e59f93afdddc8705d7e17a5293b60a124a2e842d3c77cf74f";
|
||||||
|
System.out.println(str.hashCode());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user