diff --git a/.circleci/config.yml b/.circleci/config.yml
deleted file mode 100644
index d411efcbe..000000000
--- a/.circleci/config.yml
+++ /dev/null
@@ -1,67 +0,0 @@
-# Java Gradle CircleCI 2.0 configuration file
-#
-# Check https://circleci.com/docs/2.0/language-java/ for more details
-#
-version: 2
-jobs:
- build:
- working_directory: ~/web3sdk
- branches:
- only:
- - master
- - /release-2.*/
- tags:
- only:
- - /v2.*/
- docker:
- # specify the version you desire here
- - image: circleci/openjdk:8-jdk
- environment:
- POSTGRES_USER: root
- environment:
- # Customize the JVM maximum heap limit
- JVM_OPTS: -Xmx3200m
- TERM: dumb
-
- steps:
-
- - checkout
-
- # Download and cache dependencies
- - restore_cache:
- keys:
- - v1-dependencies-{{ checksum "build.gradle" }}
- # fallback to using the latest cache if no exact match is found
- - v1-dependencies-
-
- # build blockchian by build_chain.sh
- - run:
- name: fisco-bcos
- command: |
- sudo apt-get update
- sudo apt install -y openssl curl
- curl -LO https://raw.githubusercontent.com/FISCO-BCOS/FISCO-BCOS/master/tools/build_chain.sh && chmod u+x build_chain.sh
- bash <(curl -s https://raw.githubusercontent.com/FISCO-BCOS/FISCO-BCOS/master/tools/ci/download_bin.sh) -b master
- ./bin/fisco-bcos -v
- ./build_chain.sh -e bin/fisco-bcos -l "127.0.0.1:4" -p 30300,20200,8545
- cd nodes/127.0.0.1
- ./start_all.sh
-
- - run: gradle dependencies
-
- - save_cache:
- paths:
- - ~/web3sdk/.gradle
- key: v1-dependencies-{{ checksum "build.gradle" }}
-
- # run integration test for sdk
- - run:
- name: sdk
- command: |
- cp nodes/127.0.0.1/sdk/* src/test/resources/
- gradle test
- - run:
- name: Upload Coverage
- command: |
- gradle jacocoTestReport
- bash <(curl -s https://codecov.io/bash)
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 08692442a..2470caf72 100644
--- a/.gitignore
+++ b/.gitignore
@@ -39,3 +39,5 @@ gradle.properties
/src/test/resources/node.key
/src/test/java/org/fisco/bcos/temp
build.gradle.bak
+/.settings/
+.project
diff --git a/.travis.yml b/.travis.yml
index e7cb23123..ffa404f33 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,15 +1,18 @@
# safelist
branches:
- only:
- - master
- - /release-2.*/
-tags:
- only:
- - /v2.*/
+ only:
+ - /.*/
+
+matrix:
+ fast_finish: true
+ include:
+ - os: linux
+ dist: xenial
+ sudo: required
language: java
jdk:
- - oraclejdk8
+ - openjdk8
before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
@@ -23,9 +26,16 @@ cache:
before_install:
- gradle wrapper
-script:
- - ./gradlew build -x test
- - ./gradlew jacocoTestReport
-
-after_success:
- - bash <(curl -s https://codecov.io/bash)
\ No newline at end of file
+script: |
+ curl -LO https://raw.githubusercontent.com/FISCO-BCOS/FISCO-BCOS/release-2.0.0-rc3/tools/build_chain.sh && chmod u+x build_chain.sh
+ bash <(curl -s https://raw.githubusercontent.com/FISCO-BCOS/FISCO-BCOS/master/tools/ci/download_bin.sh) -b release-2.0.0-rc3
+ echo "127.0.0.1:4 agency1 1,2,3" > ipconf
+ ./build_chain.sh -e bin/fisco-bcos -f ipconf -p 30300,20200,8545 -v 2.0.0-rc3
+ ./nodes/127.0.0.1/start_all.sh
+ ./nodes/127.0.0.1/fisco-bcos -v
+ cp nodes/127.0.0.1/sdk/* src/integration-test/resources/
+ mv src/integration-test/resources/applicationContext-sample.xml src/integration-test/resources/applicationContext.xml
+ ./gradlew verifyGoogleJavaFormat
+ ./gradlew build
+ ./gradlew test
+ ./gradlew integrationTest
\ No newline at end of file
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 05c335580..25b71fda9 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -40,6 +40,18 @@ Go to [issues page](https://github.com/FISCO-BCOS/web3sdk/issues)
7. Wait the community to review the code
8. Merged !!!!
+## Code formatting
+
+The code formatting tool are described by the [google-java-format-gradle-plugin](https://github.com/sherter/google-java-format-gradle-plugin).
+
+Execute the task `googleJavaFormat` to format all *.java files in the project
+```
+./gradlew goJF
+```
+Execute the task `verifyGoogleJavaFormat` to verify that all *.java files are formatted properly
+```
+./gradlew verGJF
+```
## Continous integration
diff --git a/Changelog.md b/Changelog.md
index ebd674941..55b83706a 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -1,8 +1,28 @@
+### v2.0.0-rc3
+
+(2019-05-28)
+
+增加
+1. 提供CRUDService类,包含操作用户表的CRUD接口。
+2. 提供加载账号文件的工具管理类PEMManager和P12Manager,可以分别加载PEM格式和PKCS12格式的账戶文件。
+3. 增加集成测试,覆盖web3j api和precompile api。
+
+更新
+1. 优化日志格式,调整日志输出内容,可以更详细显示交易流程信息。
+2. 优化选择节点块高最大的节点发送交易。
+3. 支持多群组区块链前置配置。
+4. SDK配置文件中,机构属性字段修改为agencyName。
+
+* Compatibility
+
+1. 兼容rc1,rc2, rc3的节点
+
+
### v2.0.0-rc2
(2019-04-25)
-* Add
+* 增加
1. 可并行合约开发框架ParallelContract.sol
2. 并行预编译转账合约DagTransferPrecompiled的压测程序
@@ -10,7 +30,7 @@
4. CRUD合约的压测程序
5. 回滚合约的压测程序
-* Update
+* 更新
1. 在交易编码中加入chainID和groupID,以支持rc2节点的交易格式
2. sol转java,在java文件中增加了abi字段。
@@ -23,15 +43,19 @@
(2019-03-18)
-* Add
+* 增加
1. 提供多群组支持
2. 提供Spring Boot配置以及demo项目
3. 提供模块化的单元测试,新增使用示例
4. 增加Precompiled Service接口,实现对区块链相关配置的管理,及实现特定预编译合约的功能
-* Update
+* 更新
1. 同步以太坊最新代码,支持动态数组返回,支持最新0.5.x合约
2. 优化合约编译流程,无需下载solcj即可直接编译合约生成abi bin和java合约文件
3. 升级Web3j,修改Web3j接口名
+
+* Compatibility
+
+1. 兼容rc1的节点
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index e25f65362..89389943d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,11 +1,13 @@
+plugins {
+ id 'com.github.sherter.google-java-format' version '0.8'
+}
apply plugin: 'maven'
apply plugin: 'idea'
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'signing'
-apply plugin:'application'
-apply plugin: 'jacoco'
+apply plugin: 'application'
sourceCompatibility = 1.8
@@ -15,13 +17,23 @@ targetCompatibility = 1.8
// In this section you declare where to find the dependencies of your project
repositories {
- maven {
- url "http://maven.aliyun.com/nexus/content/groups/public/"
- }
- maven { url 'https://dl.bintray.com/ethereum/maven/' }
+ maven { url "http://maven.aliyun.com/nexus/content/groups/public/" }
+ maven { url 'https://dl.bintray.com/ethereum/maven/' }
mavenCentral()
}
+googleJavaFormat {
+ options style: 'AOSP'
+ source = sourceSets*.allJava
+ include '**/*.java'
+ exclude '**/temp/*.java'
+}
+
+verifyGoogleJavaFormat {
+ source = sourceSets*.allJava
+ include '**/*.java'
+ exclude '**/temp/*.java'
+}
def spring_version="4.3.18.RELEASE"
@@ -44,39 +56,44 @@ List alibaba = [
// In this section you declare the dependencies for your production and test code
dependencies {
-// compile files('lib/solcJ-all-0.4.25-gm.jar')
- //compile 'org.ethereum:solcJ-all:0.5.2'
- compile 'org.ethereum:solcJ-all:0.4.25'
- compile logger,spring,alibaba
- compile 'org.apache.commons:commons-lang3:3.1'
- compile "com.fasterxml.jackson.core:jackson-databind:2.9.6"
- compile 'io.netty:netty-all:4.1.32.Final'
+ // compile files('lib/solcJ-all-0.4.25-gm.jar')
+ // compile 'org.ethereum:solcJ-all:0.5.2'
+ compile 'org.ethereum:solcJ-all:0.4.25'
+ compile logger,spring,alibaba
+ compile 'org.apache.commons:commons-lang3:3.1'
+ compile 'com.fasterxml.jackson.core:jackson-databind:2.9.6'
+ compile 'io.netty:netty-all:4.1.32.Final'
compile 'io.netty:netty-tcnative:2.0.20.Final'
compile 'io.netty:netty-tcnative-boringssl-static:2.0.20.Final'
compile 'com.google.guava:guava:19.0'
compile 'commons-configuration:commons-configuration:1.10'
-
- // web3j
- compile 'org.apache.httpcomponents:httpclient:4.5.5',
+ // web3j
+ compile 'org.apache.httpcomponents:httpclient:4.5.5',
'org.bouncycastle:bcprov-jdk15on:1.54',
'com.lambdaworks:scrypt:1.4.0',
'com.squareup:javapoet:1.7.0',
'io.reactivex:rxjava:1.2.4',
- "io.reactivex.rxjava2:rxjava:2.2.2",
- 'com.github.jnr:jnr-unixsocket:0.15',
- 'info.picocli:picocli:3.6.0',
- "org.java-websocket:Java-WebSocket:1.3.8",
- "org.apache.commons:commons-collections4:4.0",
- "commons-io:commons-io:2.4",
- 'com.github.stefanbirkner:system-rules:1.18.0',
- 'junit:junit:4.12',
- 'org.mockito:mockito-core:2.23.0'
+ 'io.reactivex.rxjava2:rxjava:2.2.2',
+ 'com.github.jnr:jnr-unixsocket:0.15',
+ 'info.picocli:picocli:3.6.0',
+ 'org.java-websocket:Java-WebSocket:1.3.8',
+ 'org.apache.commons:commons-collections4:4.0',
+ 'commons-io:commons-io:2.4',
+ 'com.github.stefanbirkner:system-rules:1.18.0',
+ 'junit:junit:4.12',
+ 'org.mockito:mockito-core:2.23.0'
+ compile 'de.vandermeer:asciitable:0.3.2'
}
-archivesBaseName = 'web3sdk'
-group = 'org.fisco-bcos'
-version = '2.0.2'
+//archivesBaseName = 'web3sdk'
+//group = 'org.fisco-bcos'
+//version = '2.0.2'
+configurations {
+ integrationTestCompile.extendsFrom testCompile
+ integrationTestRuntime.extendsFrom testRuntime
+}
+
// for old sdk
sourceSets {
main {
@@ -88,8 +105,29 @@ sourceSets {
srcDir 'src/test/resources'
}
}
+ integrationTest {
+ java {
+ compileClasspath += main.output + test.output
+ runtimeClasspath += main.output + test.output
+ srcDir file('src/integration-test/java')
+ }
+ resources.srcDir file('src/integration-test/resources')
+ }
}
+task integrationTest(type: Test) {
+ testClassesDirs = sourceSets.integrationTest.output.classesDirs
+ classpath = sourceSets.integrationTest.runtimeClasspath
+ outputs.upToDateWhen { false }
+}
+
+check.dependsOn integrationTest
+integrationTest.mustRunAfter test
+
+check.dependsOn.remove(test)
+check.dependsOn.remove(integrationTest)
+check.dependsOn.remove(verifyGoogleJavaFormat)
+
// 1 dist jar
jar {
destinationDir file('dist/apps')
@@ -186,14 +224,4 @@ test {
// }
// }
//}
-
-jacocoTestReport {
- reports {
- xml.enabled true
- html.enabled false
- }
-}
-
-check.dependsOn jacocoTestReport
-
mainClassName = System.getProperty("exec.mainClass") ?: "org.fisco.bcos.channel.test.amop.Channel2Client"
\ No newline at end of file
diff --git a/doc/CONTRIBUTING_CN.md b/doc/CONTRIBUTING_CN.md
index 876975aac..89888f60d 100644
--- a/doc/CONTRIBUTING_CN.md
+++ b/doc/CONTRIBUTING_CN.md
@@ -40,6 +40,19 @@
7. 等待社区review这个PR
8. PR合入,特性开发完成!
+## 代码格式化
+
+代码格式化gradle插件[google-java-format-gradle-plugin](https://github.com/sherter/google-java-format-gradle-plugin).
+
+执行任务 `googleJavaFormat`格式化java文件。
+```
+./gradlew goJF
+```
+执行任务 `verifyGoogleJavaFormat`验证java文件是否格式化完成
+```
+./gradlew verGJF
+```
+
## 持续集成(CI)
持续集成框架
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 144d3ccb3..9d01c9d3f 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-5.0-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.5-all.zip
diff --git a/release_note.txt b/release_note.txt
index a4b58387a..56c2ea320 100644
--- a/release_note.txt
+++ b/release_note.txt
@@ -1 +1 @@
-v2.0.0-rc2
+v2.0.0-rc3
diff --git a/src/test/java/org/fisco/bcos/channel/test/TestBase.java b/src/integration-test/java/org/fisco/bcos/TestBase.java
similarity index 50%
rename from src/test/java/org/fisco/bcos/channel/test/TestBase.java
rename to src/integration-test/java/org/fisco/bcos/TestBase.java
index 397da0701..c122de28f 100644
--- a/src/test/java/org/fisco/bcos/channel/test/TestBase.java
+++ b/src/integration-test/java/org/fisco/bcos/TestBase.java
@@ -1,9 +1,13 @@
-package org.fisco.bcos.channel.test;
+package org.fisco.bcos;
+
+import java.math.BigInteger;
import org.fisco.bcos.channel.client.Service;
+import org.fisco.bcos.channel.test.guomi.Ok;
import org.fisco.bcos.web3j.crypto.Credentials;
import org.fisco.bcos.web3j.protocol.Web3j;
import org.fisco.bcos.web3j.protocol.channel.ChannelEthereumService;
+import org.fisco.bcos.web3j.tx.gas.StaticGasProvider;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.springframework.context.ApplicationContext;
@@ -11,28 +15,34 @@
public class TestBase {
public static ApplicationContext context = null;
- // 初始化交易签名私钥
- public Credentials credentials =
- Credentials.create("b83261efa42895c38c6c2364ca878f43e77f3cddbc922bf57d0d48070f79feb6");
+ public static Credentials credentials =
+ Credentials.create("d0fee0a4e3c545a9394965042f8f891b6e5482c212a7428ec175d6aed121353a");
protected static Web3j web3j;
+ protected static BigInteger gasPrice = new BigInteger("30000000");
+ protected static BigInteger gasLimit = new BigInteger("30000000");
+ protected static String address;
+ protected static BigInteger blockNumber;
+ protected static String blockHash;
+ protected static String txHash;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
- // 获取spring配置文件,生成上下文
- context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
- // ((ClassPathXmlApplicationContext) context).start();
+
+ context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
Service service = context.getBean(Service.class);
service.run();
- System.out.println("start...");
- System.out.println("===================================================================");
-
ChannelEthereumService channelEthereumService = new ChannelEthereumService();
channelEthereumService.setChannelService(service);
web3j = Web3j.build(channelEthereumService, service.getGroupId());
- // EthBlockNumber ethBlockNumber = web3.ethBlockNumber().send();
+
+ Ok ok = Ok.deploy(web3j, credentials, new StaticGasProvider(gasPrice, gasLimit)).send();
+ address = ok.getContractAddress();
+ blockNumber = ok.getTransactionReceipt().get().getBlockNumber();
+ blockHash = ok.getTransactionReceipt().get().getBlockHash();
+ txHash = ok.getTransactionReceipt().get().getTransactionHash();
}
@AfterClass
diff --git a/src/integration-test/java/org/fisco/bcos/contract/Ok.java b/src/integration-test/java/org/fisco/bcos/contract/Ok.java
new file mode 100644
index 000000000..afedf165d
--- /dev/null
+++ b/src/integration-test/java/org/fisco/bcos/contract/Ok.java
@@ -0,0 +1,217 @@
+package org.fisco.bcos.contract;
+
+import io.reactivex.Flowable;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import org.fisco.bcos.channel.client.TransactionSucCallback;
+import org.fisco.bcos.web3j.abi.EventEncoder;
+import org.fisco.bcos.web3j.abi.TypeReference;
+import org.fisco.bcos.web3j.abi.datatypes.Event;
+import org.fisco.bcos.web3j.abi.datatypes.Function;
+import org.fisco.bcos.web3j.abi.datatypes.Type;
+import org.fisco.bcos.web3j.abi.datatypes.generated.Uint256;
+import org.fisco.bcos.web3j.crypto.Credentials;
+import org.fisco.bcos.web3j.protocol.Web3j;
+import org.fisco.bcos.web3j.protocol.core.DefaultBlockParameter;
+import org.fisco.bcos.web3j.protocol.core.RemoteCall;
+import org.fisco.bcos.web3j.protocol.core.methods.request.BcosFilter;
+import org.fisco.bcos.web3j.protocol.core.methods.response.Log;
+import org.fisco.bcos.web3j.protocol.core.methods.response.TransactionReceipt;
+import org.fisco.bcos.web3j.tx.Contract;
+import org.fisco.bcos.web3j.tx.TransactionManager;
+import org.fisco.bcos.web3j.tx.gas.ContractGasProvider;
+
+/**
+ * Auto generated code.
+ *
+ *
Do not modify!
+ *
+ *
Please use the web3j command line tools ,
+ * or the org.fisco.bcos.web3j.codegen.SolidityFunctionWrapperGenerator in the codegen module to update.
+ *
+ *
Generated with web3j version none.
+ */
+public class Ok extends Contract {
+ private static final String BINARY =
+ "608060405234801561001057600080fd5b5060016000800160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506402540be40060006001018190555060028060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060006002600101819055506103bf806100c26000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806366c99139146100515780636d4ce63c1461007e575b600080fd5b34801561005d57600080fd5b5061007c600480360381019080803590602001909291905050506100a9565b005b34801561008a57600080fd5b506100936102e1565b6040518082815260200191505060405180910390f35b8060006001015410806100c757506002600101548160026001015401105b156100d1576102de565b8060006001015403600060010181905550806002600101600082825401925050819055507fc77b710b83d1dc3f3fafeccd08a6c469beb873b2f0975b50d1698e46b3ee5b4c816040518082815260200191505060405180910390a160046080604051908101604052806040805190810160405280600881526020017f323031373034313300000000000000000000000000000000000000000000000081525081526020016000800160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600260000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001838152509080600181540180825580915050906001820390600052602060002090600402016000909192909190915060008201518160000190805190602001906102419291906102ee565b5060208201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550606082015181600301555050505b50565b6000600260010154905090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061032f57805160ff191683800117855561035d565b8280016001018555821561035d579182015b8281111561035c578251825591602001919060010190610341565b5b50905061036a919061036e565b5090565b61039091905b8082111561038c576000816000905550600101610374565b5090565b905600a165627a7a72305820fb983c66bee66788f407721b23b10a8aae3dc9ef8f1b09e08ec6a6c0b0ec70100029";
+
+ public static final String FUNC_TRANS = "trans";
+
+ public static final String FUNC_GET = "get";
+
+ public static final Event TRANSEVENT_EVENT =
+ new Event("TransEvent", Arrays.>asList(new TypeReference() {}));;
+
+ @Deprecated
+ protected Ok(
+ String contractAddress,
+ Web3j web3j,
+ Credentials credentials,
+ BigInteger gasPrice,
+ BigInteger gasLimit) {
+ super(BINARY, contractAddress, web3j, credentials, gasPrice, gasLimit);
+ }
+
+ protected Ok(
+ String contractAddress,
+ Web3j web3j,
+ Credentials credentials,
+ ContractGasProvider contractGasProvider) {
+ super(BINARY, contractAddress, web3j, credentials, contractGasProvider);
+ }
+
+ @Deprecated
+ protected Ok(
+ String contractAddress,
+ Web3j web3j,
+ TransactionManager transactionManager,
+ BigInteger gasPrice,
+ BigInteger gasLimit) {
+ super(BINARY, contractAddress, web3j, transactionManager, gasPrice, gasLimit);
+ }
+
+ protected Ok(
+ String contractAddress,
+ Web3j web3j,
+ TransactionManager transactionManager,
+ ContractGasProvider contractGasProvider) {
+ super(BINARY, contractAddress, web3j, transactionManager, contractGasProvider);
+ }
+
+ public RemoteCall trans(BigInteger num) {
+ final Function function =
+ new Function(
+ FUNC_TRANS,
+ Arrays.asList(new org.fisco.bcos.web3j.abi.datatypes.generated.Uint256(num)),
+ Collections.>emptyList());
+ return executeRemoteCallTransaction(function);
+ }
+
+ public void trans(BigInteger num, TransactionSucCallback callback) {
+ final Function function =
+ new Function(
+ FUNC_TRANS,
+ Arrays.asList(new org.fisco.bcos.web3j.abi.datatypes.generated.Uint256(num)),
+ Collections.>emptyList());
+ asyncExecuteTransaction(function, callback);
+ }
+
+ public RemoteCall get() {
+ final Function function =
+ new Function(
+ FUNC_GET,
+ Arrays.asList(),
+ Arrays.>asList(new TypeReference() {}));
+ return executeRemoteCallSingleValueReturn(function, BigInteger.class);
+ }
+
+ public List getTransEventEvents(TransactionReceipt transactionReceipt) {
+ List valueList =
+ extractEventParametersWithLog(TRANSEVENT_EVENT, transactionReceipt);
+ ArrayList responses =
+ new ArrayList(valueList.size());
+ for (Contract.EventValuesWithLog eventValues : valueList) {
+ TransEventEventResponse typedResponse = new TransEventEventResponse();
+ typedResponse.log = eventValues.getLog();
+ typedResponse.num = (BigInteger) eventValues.getNonIndexedValues().get(0).getValue();
+ responses.add(typedResponse);
+ }
+ return responses;
+ }
+
+ public Flowable transEventEventFlowable(BcosFilter filter) {
+ return web3j
+ .logFlowable(filter)
+ .map(
+ new io.reactivex.functions.Function() {
+ @Override
+ public TransEventEventResponse apply(Log log) {
+ Contract.EventValuesWithLog eventValues =
+ extractEventParametersWithLog(TRANSEVENT_EVENT, log);
+ TransEventEventResponse typedResponse = new TransEventEventResponse();
+ typedResponse.log = log;
+ typedResponse.num =
+ (BigInteger) eventValues.getNonIndexedValues().get(0).getValue();
+ return typedResponse;
+ }
+ });
+ }
+
+ public Flowable transEventEventFlowable(
+ DefaultBlockParameter startBlock, DefaultBlockParameter endBlock) {
+ BcosFilter filter = new BcosFilter(startBlock, endBlock, getContractAddress());
+ filter.addSingleTopic(EventEncoder.encode(TRANSEVENT_EVENT));
+ return transEventEventFlowable(filter);
+ }
+
+ @Deprecated
+ public static Ok load(
+ String contractAddress,
+ Web3j web3j,
+ Credentials credentials,
+ BigInteger gasPrice,
+ BigInteger gasLimit) {
+ return new Ok(contractAddress, web3j, credentials, gasPrice, gasLimit);
+ }
+
+ @Deprecated
+ public static Ok load(
+ String contractAddress,
+ Web3j web3j,
+ TransactionManager transactionManager,
+ BigInteger gasPrice,
+ BigInteger gasLimit) {
+ return new Ok(contractAddress, web3j, transactionManager, gasPrice, gasLimit);
+ }
+
+ public static Ok load(
+ String contractAddress,
+ Web3j web3j,
+ Credentials credentials,
+ ContractGasProvider contractGasProvider) {
+ return new Ok(contractAddress, web3j, credentials, contractGasProvider);
+ }
+
+ public static Ok load(
+ String contractAddress,
+ Web3j web3j,
+ TransactionManager transactionManager,
+ ContractGasProvider contractGasProvider) {
+ return new Ok(contractAddress, web3j, transactionManager, contractGasProvider);
+ }
+
+ public static RemoteCall deploy(
+ Web3j web3j, Credentials credentials, ContractGasProvider contractGasProvider) {
+ return deployRemoteCall(Ok.class, web3j, credentials, contractGasProvider, BINARY, "");
+ }
+
+ public static RemoteCall deploy(
+ Web3j web3j, TransactionManager transactionManager, ContractGasProvider contractGasProvider) {
+ return deployRemoteCall(Ok.class, web3j, transactionManager, contractGasProvider, BINARY, "");
+ }
+
+ @Deprecated
+ public static RemoteCall deploy(
+ Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
+ return deployRemoteCall(Ok.class, web3j, credentials, gasPrice, gasLimit, BINARY, "");
+ }
+
+ @Deprecated
+ public static RemoteCall deploy(
+ Web3j web3j,
+ TransactionManager transactionManager,
+ BigInteger gasPrice,
+ BigInteger gasLimit) {
+ return deployRemoteCall(Ok.class, web3j, transactionManager, gasPrice, gasLimit, BINARY, "");
+ }
+
+ public static class TransEventEventResponse {
+ public Log log;
+
+ public BigInteger num;
+ }
+}
diff --git a/src/integration-test/java/org/fisco/bcos/contract/OkTest.java b/src/integration-test/java/org/fisco/bcos/contract/OkTest.java
new file mode 100644
index 000000000..20a7f69e5
--- /dev/null
+++ b/src/integration-test/java/org/fisco/bcos/contract/OkTest.java
@@ -0,0 +1,31 @@
+package org.fisco.bcos.contract;
+
+import static org.junit.Assert.assertTrue;
+
+import java.math.BigInteger;
+import java.util.concurrent.TimeUnit;
+
+import org.fisco.bcos.TestBase;
+import org.fisco.bcos.web3j.protocol.core.methods.response.TransactionReceipt;
+import org.fisco.bcos.web3j.tx.gas.StaticGasProvider;
+import org.junit.Test;
+
+public class OkTest extends TestBase {
+
+ @Test
+ public void testOkContract() throws Exception {
+
+ Ok ok = Ok.deploy(web3j, credentials, new StaticGasProvider(gasPrice, gasLimit)).send();
+
+ if (ok != null) {
+ TransactionReceipt receipt = ok.trans(new BigInteger("4")).send();
+ assertTrue(receipt.getBlockNumber().intValue() > 0);
+ assertTrue(receipt.getTransactionIndex().intValue() >= 0);
+ assertTrue(receipt.getGasUsed().intValue() > 0);
+ BigInteger oldBalance = ok.get().sendAsync().get(60000, TimeUnit.MILLISECONDS);
+ ok.trans(new BigInteger("4")).sendAsync().get(60000, TimeUnit.MILLISECONDS);
+ BigInteger newBalance = ok.get().sendAsync().get(60000, TimeUnit.MILLISECONDS);
+ assertTrue(newBalance.intValue() == oldBalance.intValue() + 4);
+ }
+ }
+}
diff --git a/src/integration-test/java/org/fisco/bcos/precompile/CRUDServiceTest.java b/src/integration-test/java/org/fisco/bcos/precompile/CRUDServiceTest.java
new file mode 100644
index 000000000..ce4b2fb27
--- /dev/null
+++ b/src/integration-test/java/org/fisco/bcos/precompile/CRUDServiceTest.java
@@ -0,0 +1,82 @@
+package org.fisco.bcos.precompile;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+import org.fisco.bcos.TestBase;
+import org.fisco.bcos.web3j.precompile.crud.CRUDSerivce;
+import org.fisco.bcos.web3j.precompile.crud.Condition;
+import org.fisco.bcos.web3j.precompile.crud.Entry;
+import org.fisco.bcos.web3j.precompile.crud.Table;
+import org.junit.Test;
+
+public class CRUDServiceTest extends TestBase {
+
+
+ CRUDSerivce crudSerivce = new CRUDSerivce(web3j, credentials);
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void curdTest() throws Exception {
+
+ String tableName = "t_test" + new Random().nextInt(100000);
+ String key = "name";
+ String valueFields = "item_id, item_name";
+ Table table = new Table(tableName, key, valueFields);
+
+ // create table
+ int resultCreate = crudSerivce.createTable(table);
+ assertEquals(resultCreate, 0);
+
+ // insert records
+ int insertResult = 0;
+ int num = 5;
+ for(int i = 1; i <= num; i++)
+ {
+ Entry insertEntry = table.getEntry();
+ insertEntry.put("item_id", "1");
+ insertEntry.put("item_name", "apple"+i);
+ table.setKey("fruit");
+ insertResult += crudSerivce.insert(table, insertEntry);
+ }
+ assertEquals(insertResult, num);
+
+ // select records
+ Condition condition1 = table.getCondition();
+ condition1.EQ("item_id", "1");
+ condition1.Limit(1);
+
+ List> resultSelect1 = crudSerivce.select(table, condition1);
+ assertEquals(resultSelect1.get(0).get("name"), "fruit");
+ assertEquals(resultSelect1.get(0).get("item_id"), "1");
+ assertEquals(resultSelect1.get(0).get("item_name"), "apple1");
+
+ // update records
+ Entry updateEntry = table.getEntry();
+ updateEntry.put("item_id", "1");
+ updateEntry.put("item_name", "orange");
+ Condition updateCondition = table.getCondition();
+ updateCondition.EQ("item_id", "1");
+ int updateResult = crudSerivce.update(table, updateEntry, updateCondition);
+ assertEquals(updateResult, num);
+
+ // select records
+ Condition condition2 = table.getCondition();
+ condition2.EQ("item_id", "1");
+ condition2.Limit(1);;
+ List> resultSelect2 = crudSerivce.select(table, condition2);
+ assertEquals(resultSelect2.get(0).get("name"), "fruit");
+ assertEquals(resultSelect2.get(0).get("item_id"), "1");
+ assertEquals(resultSelect2.get(0).get("item_name"), "orange");
+
+ // remove records
+ Condition removeCondition = table.getCondition();
+ removeCondition.EQ("item_id", "1");
+ int removeResult = crudSerivce.remove(table, removeCondition);
+ assertEquals(removeResult, num);
+ }
+
+}
diff --git a/src/test/java/org/fisco/bcos/channel/test/precompile/CnsServiceTest.java b/src/integration-test/java/org/fisco/bcos/precompile/CnsServiceTest.java
similarity index 97%
rename from src/test/java/org/fisco/bcos/channel/test/precompile/CnsServiceTest.java
rename to src/integration-test/java/org/fisco/bcos/precompile/CnsServiceTest.java
index ffefe498c..8c04d300f 100644
--- a/src/test/java/org/fisco/bcos/channel/test/precompile/CnsServiceTest.java
+++ b/src/integration-test/java/org/fisco/bcos/precompile/CnsServiceTest.java
@@ -1,10 +1,11 @@
-package org.fisco.bcos.channel.test.precompile;
+package org.fisco.bcos.precompile;
import static org.junit.Assert.assertEquals;
import java.math.BigInteger;
import java.security.SecureRandom;
-import org.fisco.bcos.channel.test.TestBase;
+
+import org.fisco.bcos.TestBase;
import org.fisco.bcos.channel.test.contract.Ok;
import org.fisco.bcos.web3j.crypto.Credentials;
import org.fisco.bcos.web3j.precompile.cns.CnsService;
diff --git a/src/integration-test/java/org/fisco/bcos/precompile/Common.java b/src/integration-test/java/org/fisco/bcos/precompile/Common.java
new file mode 100644
index 000000000..a040d3512
--- /dev/null
+++ b/src/integration-test/java/org/fisco/bcos/precompile/Common.java
@@ -0,0 +1,8 @@
+package org.fisco.bcos.precompile;
+
+public class Common {
+
+ public static String SUSSCESS = "{\"code\":0,\"msg\":\"success\"}";
+ public static String TABLE_NAME = "t_test";
+ public static String TX_ORIGIN = "0xf1585b8d0e08a0a00fff662e24d67ba95a438256";
+}
diff --git a/src/integration-test/java/org/fisco/bcos/precompile/ConsensusServiceTest.java b/src/integration-test/java/org/fisco/bcos/precompile/ConsensusServiceTest.java
new file mode 100644
index 000000000..06323926e
--- /dev/null
+++ b/src/integration-test/java/org/fisco/bcos/precompile/ConsensusServiceTest.java
@@ -0,0 +1,33 @@
+package org.fisco.bcos.precompile;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.List;
+
+import org.fisco.bcos.TestBase;
+import org.fisco.bcos.web3j.precompile.consensus.ConsensusService;
+import org.junit.Ignore;
+
+public class ConsensusServiceTest extends TestBase {
+
+
+ private ConsensusService consensusService = new ConsensusService(web3j, credentials);
+
+ @Ignore
+ public void addSealerAndObserverTest() throws Exception {
+
+ List sealerList1 = web3j.getSealerList().send().getSealerList();
+ String nodeId = sealerList1.get(sealerList1.size() -1);
+
+ String addObserverResult = consensusService.addObserver(nodeId);
+ assertEquals(addObserverResult, Common.SUSSCESS);
+
+ String removeNodeResult = consensusService.removeNode(nodeId);
+ assertEquals(removeNodeResult, Common.SUSSCESS);
+
+ String addSealerResult = consensusService.addSealer(nodeId);
+ assertEquals(addSealerResult, Common.SUSSCESS);
+
+ }
+
+}
diff --git a/src/integration-test/java/org/fisco/bcos/precompile/PermissionServiceTest.java b/src/integration-test/java/org/fisco/bcos/precompile/PermissionServiceTest.java
new file mode 100644
index 000000000..4f79d8250
--- /dev/null
+++ b/src/integration-test/java/org/fisco/bcos/precompile/PermissionServiceTest.java
@@ -0,0 +1,63 @@
+package org.fisco.bcos.precompile;
+
+import static org.junit.Assert.assertEquals;
+
+import org.fisco.bcos.TestBase;
+import org.fisco.bcos.web3j.precompile.exception.PrecompileMessageException;
+import org.fisco.bcos.web3j.precompile.permission.PermissionService;
+import org.junit.Test;
+
+public class PermissionServiceTest extends TestBase {
+
+
+ PermissionService permissionService = new PermissionService(web3j, credentials);
+
+ @Test(expected= PrecompileMessageException.class)
+ public void userTableManager() throws Exception {
+
+ String grantUserTableManagerResult = permissionService.grantUserTableManager("tt", Common.TX_ORIGIN);
+
+ }
+
+ @Test
+ public void deployAndCreateManager() throws Exception {
+
+ String grantDeployAndCreateManagerResult = permissionService.grantDeployAndCreateManager(Common.TX_ORIGIN);
+ assertEquals(grantDeployAndCreateManagerResult, Common.SUSSCESS);
+
+ String revokeDeployAndCreateManagerResult = permissionService.revokeDeployAndCreateManager(Common.TX_ORIGIN);
+ assertEquals(revokeDeployAndCreateManagerResult, Common.SUSSCESS);
+
+ }
+
+ @Test
+ public void nodeManager() throws Exception {
+
+ String grantNodeManagerResult = permissionService.grantNodeManager(Common.TX_ORIGIN);
+ assertEquals(grantNodeManagerResult, Common.SUSSCESS);
+
+ String revokeNodeManagerResult = permissionService.revokeNodeManager(Common.TX_ORIGIN);
+ assertEquals(revokeNodeManagerResult, Common.SUSSCESS);
+ }
+
+ @Test
+ public void cnsManager() throws Exception {
+
+ String grantCNSManagerResult = permissionService.grantCNSManager(Common.TX_ORIGIN);
+ assertEquals(grantCNSManagerResult, Common.SUSSCESS);
+
+ String revokeCNSManagerResult = permissionService.revokeCNSManager(Common.TX_ORIGIN);
+ assertEquals(revokeCNSManagerResult, Common.SUSSCESS);
+ }
+
+ @Test
+ public void sysConfigManager() throws Exception {
+
+ String grantSysConfigManagerResult = permissionService.grantSysConfigManager(Common.TX_ORIGIN);
+ assertEquals(grantSysConfigManagerResult, Common.SUSSCESS);
+
+ String revokeSysConfigManagerResult = permissionService.revokeSysConfigManager(Common.TX_ORIGIN);
+ assertEquals(revokeSysConfigManagerResult, Common.SUSSCESS);
+
+ }
+}
diff --git a/src/integration-test/java/org/fisco/bcos/precompile/SystemConfigServiceTest.java b/src/integration-test/java/org/fisco/bcos/precompile/SystemConfigServiceTest.java
new file mode 100644
index 000000000..f64de589b
--- /dev/null
+++ b/src/integration-test/java/org/fisco/bcos/precompile/SystemConfigServiceTest.java
@@ -0,0 +1,30 @@
+package org.fisco.bcos.precompile;
+
+import static org.junit.Assert.assertEquals;
+
+import org.fisco.bcos.TestBase;
+import org.fisco.bcos.web3j.precompile.config.EnumKey;
+import org.fisco.bcos.web3j.precompile.config.SystemConfigService;
+import org.junit.Test;
+
+public class SystemConfigServiceTest extends TestBase {
+
+
+ SystemConfigService systemConfigSerivce = new SystemConfigService(web3j, credentials);
+
+ @Test
+ public void setValueByKey() throws Exception {
+
+ String txCountLimit1 = "5000";
+ systemConfigSerivce.setValueByKey(EnumKey.tx_count_limit.toString(), txCountLimit1);
+ String txCountLimit2 = web3j.getSystemConfigByKey(EnumKey.tx_count_limit.toString()).send().getSystemConfigByKey();
+ assertEquals(txCountLimit1, txCountLimit2);
+
+ String txGasLimit1 = "50000000";
+ systemConfigSerivce.setValueByKey(EnumKey.tx_gas_limit.toString(), txGasLimit1);
+ String txGasLimit2 = web3j.getSystemConfigByKey(EnumKey.tx_gas_limit.toString()).send().getSystemConfigByKey();
+ assertEquals(txGasLimit1, txGasLimit2);
+
+ }
+
+}
diff --git a/src/integration-test/java/org/fisco/bcos/web3j/Web3jApITest.java b/src/integration-test/java/org/fisco/bcos/web3j/Web3jApITest.java
new file mode 100644
index 000000000..b18509e0d
--- /dev/null
+++ b/src/integration-test/java/org/fisco/bcos/web3j/Web3jApITest.java
@@ -0,0 +1,191 @@
+package org.fisco.bcos.web3j;
+
+import static org.junit.Assert.assertNotNull;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.concurrent.ExecutionException;
+
+import org.fisco.bcos.TestBase;
+import org.fisco.bcos.web3j.protocol.core.DefaultBlockParameter;
+import org.fisco.bcos.web3j.protocol.core.DefaultBlockParameterName;
+import org.fisco.bcos.web3j.protocol.core.methods.response.BcosBlock;
+import org.fisco.bcos.web3j.protocol.core.methods.response.BcosTransaction;
+import org.fisco.bcos.web3j.protocol.core.methods.response.BcosTransactionReceipt;
+import org.fisco.bcos.web3j.protocol.core.methods.response.BlockHash;
+import org.fisco.bcos.web3j.protocol.core.methods.response.BlockNumber;
+import org.fisco.bcos.web3j.protocol.core.methods.response.Code;
+import org.fisco.bcos.web3j.protocol.core.methods.response.GroupList;
+import org.fisco.bcos.web3j.protocol.core.methods.response.GroupPeers;
+import org.fisco.bcos.web3j.protocol.core.methods.response.NodeIDList;
+import org.fisco.bcos.web3j.protocol.core.methods.response.NodeVersion;
+import org.fisco.bcos.web3j.protocol.core.methods.response.ObserverList;
+import org.fisco.bcos.web3j.protocol.core.methods.response.PbftView;
+import org.fisco.bcos.web3j.protocol.core.methods.response.Peers;
+import org.fisco.bcos.web3j.protocol.core.methods.response.PendingTransactions;
+import org.fisco.bcos.web3j.protocol.core.methods.response.PendingTxSize;
+import org.fisco.bcos.web3j.protocol.core.methods.response.SealerList;
+import org.fisco.bcos.web3j.protocol.core.methods.response.SystemConfig;
+import org.fisco.bcos.web3j.protocol.core.methods.response.TotalTransactionCount;
+import org.fisco.bcos.web3j.protocol.core.methods.response.Transaction;
+import org.fisco.bcos.web3j.protocol.core.methods.response.TransactionReceipt;
+import org.junit.Test;
+
+public class Web3jApITest extends TestBase {
+
+ @Test
+ public void getNodeVersion() throws IOException {
+ NodeVersion nodeVersion = web3j.getNodeVersion().send();
+ assertNotNull(nodeVersion.getNodeVersion().getBuildTime());
+ assertNotNull(nodeVersion.getNodeVersion().getBuildType());
+ assertNotNull(nodeVersion.getNodeVersion().getGitBranch());
+ assertNotNull(nodeVersion.getNodeVersion().getGitCommit());
+ assertNotNull(nodeVersion.getNodeVersion().getVersion());
+ }
+
+ @Test
+ public void getBlockNumber() throws IOException, InterruptedException, ExecutionException {
+ BlockNumber blockNumber = web3j.getBlockNumber().send();
+ assertNotNull(blockNumber.getBlockNumber());
+ blockNumber = web3j.getBlockNumber().sendAsync().get();
+ assertNotNull(blockNumber.getBlockNumber());
+ }
+
+ @Test
+ public void getBlockNumberCache() throws IOException {
+ BigInteger blockNumberCache = web3j.getBlockNumberCache();
+ assertNotNull(blockNumberCache);
+ }
+
+ @Test
+ public void pbftView() throws Exception {
+ PbftView pbftView = web3j.getPbftView().send();
+ assertNotNull(pbftView.getPbftView());
+ }
+
+ @Test
+ public void getConsensusStatus() throws Exception {
+ String consensusStatus = web3j.getConsensusStatus().sendForReturnString();
+ assertNotNull(consensusStatus);
+ }
+
+ @Test
+ public void getSyncStatus() throws Exception {
+ String syncStatus = web3j.getSyncStatus().sendForReturnString();
+ assertNotNull(syncStatus);
+ }
+
+ @Test
+ public void peers() throws Exception {
+ Peers peers = web3j.getPeers().send();
+ assertNotNull(peers.getPeers());
+ }
+
+ @Test
+ public void groupPeers() throws Exception {
+ GroupPeers groupPeers = web3j.getGroupPeers().send();
+ assertNotNull(groupPeers.getGroupPeers());
+ }
+
+ @Test
+ public void groupList() throws Exception {
+ GroupList groupList = web3j.getGroupList().send();
+ assertNotNull(groupList.getGroupList());
+ }
+
+ @Test
+ public void getSealerList() throws Exception {
+ SealerList sealerList = web3j.getSealerList().send();
+ assertNotNull(sealerList.getSealerList());
+ }
+
+ @Test
+ public void getObserverList() throws Exception {
+ ObserverList observerList = web3j.getObserverList().send();
+ assertNotNull(observerList.getObserverList());
+ }
+
+ @Test
+ public void getNodeIDList() throws Exception {
+ NodeIDList nodeIDList = web3j.getNodeIDList().send();
+ assertNotNull(nodeIDList.getNodeIDList());
+ }
+
+ @Test
+ public void getSystemConfigByKey() throws Exception {
+ SystemConfig txCountLimit = web3j.getSystemConfigByKey("tx_count_limit").send();
+ SystemConfig txGasLimit = web3j.getSystemConfigByKey("tx_gas_limit").send();
+ assertNotNull(txCountLimit.getSystemConfigByKey());
+ assertNotNull(txGasLimit.getSystemConfigByKey());
+ }
+
+ @Test
+ public void getCode() throws Exception {
+ Code code = web3j.getCode(address, DefaultBlockParameterName.LATEST).send();
+ assertNotNull(code.getCode());
+ }
+
+ @Test
+ public void getTotalTransactionCount() throws Exception {
+ TotalTransactionCount count = web3j.getTotalTransactionCount().send();
+ assertNotNull(count.getTotalTransactionCount());
+ }
+
+ @Test
+ public void getBlockByHash() throws Exception {
+ BcosBlock bcosBlock = web3j.getBlockByHash(blockHash, true).send();
+ assertNotNull(bcosBlock.getBlock());
+ }
+
+ @Test
+ public void getBlockByNumber() throws Exception {
+ BcosBlock bcosBlock = web3j.getBlockByNumber(DefaultBlockParameter.valueOf(blockNumber), true).send();
+ assertNotNull(bcosBlock.getBlock());
+ }
+
+ @Test
+ public void getBlockHashByNumber() throws Exception {
+ BlockHash blockHash = web3j.getBlockHashByNumber(DefaultBlockParameter.valueOf(blockNumber)).send();
+ assertNotNull(blockHash.getBlockHashByNumber());
+ }
+
+ @Test
+ public void getTransactionByHash() throws Exception {
+ BcosTransaction bcosTransaction = web3j.getTransactionByHash(blockHash).send();
+ assertNotNull(bcosTransaction.getTransaction());
+ }
+
+ @Test
+ public void getTransactionByBlockNumberAndIndex() throws IOException {
+ BcosTransaction bcosTransaction = web3j.getTransactionByBlockNumberAndIndex(DefaultBlockParameter.valueOf(blockNumber), new BigInteger("0")).send();
+ Transaction transaction = bcosTransaction.getTransaction().get();
+ assertNotNull(transaction);
+ }
+
+ @Test
+ public void getTransactionByBlockHashAndIndex() throws IOException {
+ BcosTransaction bcosTransaction = web3j.getTransactionByBlockHashAndIndex(blockHash, new BigInteger("0")).send();
+ Transaction transaction = bcosTransaction.getTransaction().get();
+ assertNotNull(transaction);
+ }
+
+ @Test
+ public void getTransactionReceipt() throws IOException {
+ BcosTransactionReceipt bcosTransactionReceipt = web3j.getTransactionReceipt(txHash).send();
+ TransactionReceipt transactionReceipt = bcosTransactionReceipt.getTransactionReceipt().get();
+ assertNotNull(transactionReceipt);
+ }
+
+ @Test
+ public void getPendingTransaction() throws IOException {
+ PendingTransactions pendingTransactions = web3j.getPendingTransaction().send();
+ assertNotNull(pendingTransactions.getPendingTransactions());
+ }
+
+ @Test
+ public void getPendingTxSize() throws IOException {
+ PendingTxSize pendingTxSize = web3j.getPendingTxSize().send();
+ assertNotNull(pendingTxSize.getPendingTxSize());
+ }
+
+}
diff --git a/src/test/resources/applicationContext.xml b/src/integration-test/resources/applicationContext-sample.xml
similarity index 97%
rename from src/test/resources/applicationContext.xml
rename to src/integration-test/resources/applicationContext-sample.xml
index d2b52e245..8dea7eeb3 100644
--- a/src/test/resources/applicationContext.xml
+++ b/src/integration-test/resources/applicationContext-sample.xml
@@ -43,7 +43,7 @@
-
+
diff --git a/src/integration-test/resources/log4j.properties b/src/integration-test/resources/log4j.properties
new file mode 100644
index 000000000..b3b3284d2
--- /dev/null
+++ b/src/integration-test/resources/log4j.properties
@@ -0,0 +1,49 @@
+### set log levels ###
+log4j.rootLogger = INFO, info, error
+
+### output the TRACE level log information to the =./log/trace.log ###
+log4j.appender.trace = org.apache.log4j.DailyRollingFileAppender
+log4j.appender.trace.File = ./log/trace.log
+log4j.appender.trace.Append = true
+log4j.appender.trace.Threshold = TRACE
+log4j.appender.trace.filter.traceFilter = org.apache.log4j.varia.LevelRangeFilter
+log4j.appender.trace.filter.traceFilter.levelMin = TRACE
+log4j.appender.trace.filter.traceFilter.levelMax = TRACE
+log4j.appender.trace.layout = org.apache.log4j.PatternLayout
+log4j.appender.trace.layout.ConversionPattern = [%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C{1}.%M(%L) | %m%n
+
+### output the DEBUG level log information to the =./log/debug.log ###
+log4j.appender.debug = org.apache.log4j.DailyRollingFileAppender
+log4j.appender.debug.File = ./log/debug.log
+log4j.appender.debug.Append = true
+log4j.appender.debug.Threshold = DEBUG
+log4j.appender.debug.filter.debugFilter = org.apache.log4j.varia.LevelRangeFilter
+log4j.appender.debug.filter.debugFilter.levelMin = DEBUG
+log4j.appender.debug.filter.debugFilter.levelMax = DEBUG
+log4j.appender.debug.layout = org.apache.log4j.PatternLayout
+log4j.appender.debug.layout.ConversionPattern = [%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C{1}.%M(%L) | %m%n
+
+### output the INFO level log information to the =./log/info.log ###
+log4j.appender.info = org.apache.log4j.DailyRollingFileAppender
+log4j.appender.info.File = ./log/info.log
+log4j.appender.info.Append = true
+log4j.appender.info.Threshold = INFO
+log4j.appender.info.filter.infoFilter = org.apache.log4j.varia.LevelRangeFilter
+log4j.appender.info.filter.infoFilter.levelMin = INFO
+log4j.appender.info.filter.infoFilter.levelMax = INFO
+log4j.appender.info.layout = org.apache.log4j.PatternLayout
+log4j.appender.info.layout.ConversionPattern = [%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C{1}.%M(%L) | %m%n
+
+### output the ERROR level log information to the=./log/error.log ###
+log4j.appender.error = org.apache.log4j.DailyRollingFileAppender
+log4j.appender.error.File = ./log/error.log
+log4j.appender.error.Append = true
+log4j.appender.error.Threshold = ERROR
+log4j.appender.error.layout = org.apache.log4j.PatternLayout
+log4j.appender.error.layout.ConversionPattern = [%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C{1}.%M(%L) | %m%n
+
+###output the log information to the console ###
+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 = [%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C{1}.%M(%L) | %m%n
diff --git a/src/main/java/org/fisco/bcos/channel/client/BcosResponseCallback.java b/src/main/java/org/fisco/bcos/channel/client/BcosResponseCallback.java
new file mode 100644
index 000000000..941f04709
--- /dev/null
+++ b/src/main/java/org/fisco/bcos/channel/client/BcosResponseCallback.java
@@ -0,0 +1,34 @@
+package org.fisco.bcos.channel.client;
+
+import io.netty.util.Timeout;
+import org.fisco.bcos.channel.dto.BcosResponse;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class BcosResponseCallback {
+ private static Logger logger = LoggerFactory.getLogger(BcosResponseCallback.class);
+
+ private Timeout timeout;
+
+ public abstract void onResponse(BcosResponse response);
+
+ public void onTimeout() {
+ logger.error("Processing bcos message timeout:{}");
+
+ BcosResponse response = new BcosResponse();
+ response.setErrorCode(102);
+ response.setErrorMessage("Processing bcos message timeout");
+
+ response.setContent("");
+
+ onResponse(response);
+ }
+
+ public Timeout getTimeout() {
+ return timeout;
+ }
+
+ public void setTimeout(Timeout timeout) {
+ this.timeout = timeout;
+ }
+}
diff --git a/src/main/java/org/fisco/bcos/channel/client/ChannelPushCallback.java b/src/main/java/org/fisco/bcos/channel/client/ChannelPushCallback.java
index b70d073a3..4a7f39fd6 100644
--- a/src/main/java/org/fisco/bcos/channel/client/ChannelPushCallback.java
+++ b/src/main/java/org/fisco/bcos/channel/client/ChannelPushCallback.java
@@ -5,7 +5,7 @@
import org.slf4j.LoggerFactory;
public abstract class ChannelPushCallback {
- public abstract void onPush(ChannelPush push);
+ public abstract void onPush(ChannelPush push);
- static Logger logger = LoggerFactory.getLogger(ChannelPushCallback.class);
+ static Logger logger = LoggerFactory.getLogger(ChannelPushCallback.class);
}
diff --git a/src/main/java/org/fisco/bcos/channel/client/ChannelResponseCallback.java b/src/main/java/org/fisco/bcos/channel/client/ChannelResponseCallback.java
index 533be1883..20994579b 100644
--- a/src/main/java/org/fisco/bcos/channel/client/ChannelResponseCallback.java
+++ b/src/main/java/org/fisco/bcos/channel/client/ChannelResponseCallback.java
@@ -14,233 +14,237 @@
import org.slf4j.LoggerFactory;
public abstract class ChannelResponseCallback {
- private static Logger logger = LoggerFactory.getLogger(ChannelResponseCallback.class);
-
- public abstract void onResponseMessage(ChannelResponse response);
-
- public final void onResponse(ChannelResponse response) {
- if (response.getErrorCode() == 99) {
- logger.error("Local node error,try the next local node");
- retrySendMessage(1); // 1表示客户端错误
- } else if (response.getErrorCode() == 100) {
- logger.error("Remote node error,try the next remote node");
- retrySendMessage(2); // 2表示服务端错误,错误码可重用
- } else {
- try {
- onResponseMessage(response);
- } catch (Exception e) {
- logger.error("c:", e);
- }
-
- if (message.getSeq() != null) {
- service.getSeq2Callback().remove(message.getSeq());
- }
-
- if (timeout != null) {
- timeout.cancel();
- }
- }
- }
-
- public final void onTimeout() {
- logger.error("send message timeout:{}", message.getSeq());
-
- ChannelResponse response = new ChannelResponse();
- response.setErrorCode(102);
- response.setMessageID(message.getSeq());
- response.setErrorMessage("send message timeout");
- response.setContent("");
-
- try {
- onResponseMessage(response);
- } catch (Exception e) {
- logger.error("timeout processing error:", e);
- }
-
- service.getSeq2Callback().remove(message.getSeq());
- timeout.cancel();
- }
-
- public void retrySendMessage(Integer errorType) {
- Integer errorCode = 0;
- try {
- if (errorType == 1 || errorType == 0) {
- message.setFromNode("");
-
- // 选取客户端节点
- logger.debug("Number of local nodes:{}", fromConnectionInfos.size());
- if (fromConnectionInfos.size() > 0) {
- Random random = new SecureRandom();
- Integer index = random.nextInt(fromConnectionInfos.size());
-
- logger.debug("selected:{}", index);
-
- setFromConnection(fromConnectionInfos.get(index));
- message.setFromNode(getFromConnection().getNodeID());
-
- Boolean res = fromConnectionInfos.remove(fromConnectionInfos.get(index));
- logger.debug(
- "Number of local nodes after processing:{} {}", res, fromConnectionInfos.size());
- }
-
- if (message.getFromNode().isEmpty()) {
- // 所有节点已尝试,无法再重试了
- logger.error("All local nodes are unavailable");
-
- errorCode = 99;
- throw new Exception("All local nodes are unavailable");
+ private static Logger logger = LoggerFactory.getLogger(ChannelResponseCallback.class);
+
+ public abstract void onResponseMessage(ChannelResponse response);
+
+ public final void onResponse(ChannelResponse response) {
+ if (response.getErrorCode() == 99) {
+ logger.error("Local node error,try the next local node");
+ retrySendMessage(1); // 1表示客户端错误
+ } else if (response.getErrorCode() == 100) {
+ logger.error("Remote node error,try the next remote node");
+ retrySendMessage(2); // 2表示服务端错误,错误码可重用
+ } else {
+ try {
+ onResponseMessage(response);
+ } catch (Exception e) {
+ logger.error("c:", e);
+ }
+
+ if (message.getSeq() != null) {
+ service.getSeq2Callback().remove(message.getSeq());
+ }
+
+ if (timeout != null) {
+ timeout.cancel();
+ }
}
- }
-
- if (errorType == 2 || errorType == 0) {
- message.setToNode("");
- // 选取服务端节点
- logger.debug("Number of peer nodes:{}", toConnectionInfos.size());
- if (toConnectionInfos.size() > 0) {
- Random random = new SecureRandom();
- Integer index = random.nextInt(toConnectionInfos.size());
-
- logger.debug("selected:{}", index);
-
- setToConnection(toConnectionInfos.get(index));
- message.setToNode(getToConnection().getNodeID());
+ }
- Boolean res = toConnectionInfos.remove(toConnectionInfos.get(index));
- logger.debug(
- "Number of peer nodes after processing:{} {}", res, toConnectionInfos.size());
- }
+ public final void onTimeout() {
+ logger.error("send message timeout:{}", message.getSeq());
- if (message.getToNode().isEmpty()) {
- // 所有节点已尝试,无法再重试了
- logger.error("All peer nodes are unavailable");
+ ChannelResponse response = new ChannelResponse();
+ response.setErrorCode(102);
+ response.setMessageID(message.getSeq());
+ response.setErrorMessage("send message timeout");
+ response.setContent("");
- errorCode = 103;
- throw new Exception("All peer nodes are unavailable");
+ try {
+ onResponseMessage(response);
+ } catch (Exception e) {
+ logger.error("timeout processing error:", e);
}
- }
-
- logger.debug("try from {} send to:{}", message.getFromNode(), message.getToNode());
-
- message.setFromNode(fromConnection.getNodeID());
-
- ChannelHandlerContext ctx =
- fromChannelConnections.getNetworkConnectionByHost(
- getFromConnection().getHost(), getFromConnection().getPort());
- if (ctx != null && ctx.channel().isActive()) {
- ByteBuf out = ctx.alloc().buffer();
- message.writeHeader(out);
- message.writeExtra(out);
-
- ctx.writeAndFlush(out);
-
- logger.debug(
- "send message to "
- + fromConnection.getHost()
- + ":"
- + String.valueOf(fromConnection.getPort())
- + " success");
- } else {
- logger.error("sending node unavailable");
-
- retrySendMessage(1);
- }
- } catch (Exception e) {
- logger.error("send message exception ", e);
-
- ChannelResponse response = new ChannelResponse();
- response.setErrorCode(errorCode);
- response.setErrorMessage(e.getMessage());
-
- try {
- onResponseMessage(response);
- } catch (Exception ee) {
- logger.error("onResponseMessage error:", ee);
- }
-
- // 彻底失败后,删掉这个seq
- if (message.getSeq() != null) {
service.getSeq2Callback().remove(message.getSeq());
- }
-
- if (timeout != null) {
timeout.cancel();
- }
+ }
- return;
+ public void retrySendMessage(Integer errorType) {
+ Integer errorCode = 0;
+ try {
+ if (errorType == 1 || errorType == 0) {
+ message.setFromNode("");
+
+ // 选取客户端节点
+ logger.debug("Number of local nodes:{}", fromConnectionInfos.size());
+ if (fromConnectionInfos.size() > 0) {
+ Random random = new SecureRandom();
+ Integer index = random.nextInt(fromConnectionInfos.size());
+
+ logger.debug("selected:{}", index);
+
+ setFromConnection(fromConnectionInfos.get(index));
+ message.setFromNode(getFromConnection().getNodeID());
+
+ Boolean res = fromConnectionInfos.remove(fromConnectionInfos.get(index));
+ logger.debug(
+ "Number of local nodes after processing:{} {}",
+ res,
+ fromConnectionInfos.size());
+ }
+
+ if (message.getFromNode().isEmpty()) {
+ // 所有节点已尝试,无法再重试了
+ logger.error("All local nodes are unavailable");
+
+ errorCode = 99;
+ throw new Exception("All local nodes are unavailable");
+ }
+ }
+
+ if (errorType == 2 || errorType == 0) {
+ message.setToNode("");
+ // 选取服务端节点
+ logger.debug("Number of peer nodes:{}", toConnectionInfos.size());
+ if (toConnectionInfos.size() > 0) {
+ Random random = new SecureRandom();
+ Integer index = random.nextInt(toConnectionInfos.size());
+
+ logger.debug("selected:{}", index);
+
+ setToConnection(toConnectionInfos.get(index));
+ message.setToNode(getToConnection().getNodeID());
+
+ Boolean res = toConnectionInfos.remove(toConnectionInfos.get(index));
+ logger.debug(
+ "Number of peer nodes after processing:{} {}",
+ res,
+ toConnectionInfos.size());
+ }
+
+ if (message.getToNode().isEmpty()) {
+ // 所有节点已尝试,无法再重试了
+ logger.error("All peer nodes are unavailable");
+
+ errorCode = 103;
+ throw new Exception("All peer nodes are unavailable");
+ }
+ }
+
+ logger.debug("try from {} send to:{}", message.getFromNode(), message.getToNode());
+
+ message.setFromNode(fromConnection.getNodeID());
+
+ ChannelHandlerContext ctx =
+ fromChannelConnections.getNetworkConnectionByHost(
+ getFromConnection().getHost(), getFromConnection().getPort());
+
+ if (ctx != null && ctx.channel().isActive()) {
+ ByteBuf out = ctx.alloc().buffer();
+ message.writeHeader(out);
+ message.writeExtra(out);
+
+ ctx.writeAndFlush(out);
+
+ logger.debug(
+ "send message to "
+ + fromConnection.getHost()
+ + ":"
+ + String.valueOf(fromConnection.getPort())
+ + " success");
+ } else {
+ logger.error("sending node unavailable");
+
+ retrySendMessage(1);
+ }
+ } catch (Exception e) {
+ logger.error("send message exception ", e);
+
+ ChannelResponse response = new ChannelResponse();
+ response.setErrorCode(errorCode);
+ response.setErrorMessage(e.getMessage());
+
+ try {
+ onResponseMessage(response);
+ } catch (Exception ee) {
+ logger.error("onResponseMessage error:", ee);
+ }
+
+ // 彻底失败后,删掉这个seq
+ if (message.getSeq() != null) {
+ service.getSeq2Callback().remove(message.getSeq());
+ }
+
+ if (timeout != null) {
+ timeout.cancel();
+ }
+
+ return;
+ }
}
- }
- public ConnectionInfo getFromConnection() {
- return fromConnection;
- }
+ public ConnectionInfo getFromConnection() {
+ return fromConnection;
+ }
- public void setFromConnection(ConnectionInfo fromConnection) {
- this.fromConnection = fromConnection;
- }
+ public void setFromConnection(ConnectionInfo fromConnection) {
+ this.fromConnection = fromConnection;
+ }
- public ConnectionInfo getToConnection() {
- return toConnection;
- }
+ public ConnectionInfo getToConnection() {
+ return toConnection;
+ }
- public void setToConnection(ConnectionInfo toConnection) {
- this.toConnection = toConnection;
- }
+ public void setToConnection(ConnectionInfo toConnection) {
+ this.toConnection = toConnection;
+ }
- public List getFromConnectionInfos() {
- return fromConnectionInfos;
- }
+ public List getFromConnectionInfos() {
+ return fromConnectionInfos;
+ }
- public void setFromConnectionInfos(List fromConnectionInfos) {
- this.fromConnectionInfos = fromConnectionInfos;
- }
+ public void setFromConnectionInfos(List fromConnectionInfos) {
+ this.fromConnectionInfos = fromConnectionInfos;
+ }
- public ChannelConnections getFromChannelConnections() {
- return fromChannelConnections;
- }
+ public ChannelConnections getFromChannelConnections() {
+ return fromChannelConnections;
+ }
- public void setFromChannelConnections(ChannelConnections fromConnectionConnections) {
- this.fromChannelConnections = fromConnectionConnections;
- }
+ public void setFromChannelConnections(ChannelConnections fromConnectionConnections) {
+ this.fromChannelConnections = fromConnectionConnections;
+ }
- public List getToConnectionInfos() {
- return toConnectionInfos;
- }
+ public List getToConnectionInfos() {
+ return toConnectionInfos;
+ }
- public void setToConnectionInfos(List connectionInfos) {
- this.toConnectionInfos = connectionInfos;
- }
+ public void setToConnectionInfos(List connectionInfos) {
+ this.toConnectionInfos = connectionInfos;
+ }
- public ChannelMessage getRequest() {
- return message;
- }
+ public ChannelMessage getRequest() {
+ return message;
+ }
- public void setRequest(ChannelMessage message) {
- this.message = message;
- }
+ public void setRequest(ChannelMessage message) {
+ this.message = message;
+ }
- public Service getService() {
- return service;
- }
+ public Service getService() {
+ return service;
+ }
- public void setService(Service service) {
- this.service = service;
- }
+ public void setService(Service service) {
+ this.service = service;
+ }
- public Timeout getTimeout() {
- return timeout;
- }
+ public Timeout getTimeout() {
+ return timeout;
+ }
- public void setTimeout(Timeout timeout) {
- this.timeout = timeout;
- }
+ public void setTimeout(Timeout timeout) {
+ this.timeout = timeout;
+ }
- private ConnectionInfo fromConnection;
- private ConnectionInfo toConnection;
- private List fromConnectionInfos;
- private ChannelConnections fromChannelConnections;
- private List toConnectionInfos;
- private ChannelMessage message;
- private Service service;
- private Timeout timeout;
+ private ConnectionInfo fromConnection;
+ private ConnectionInfo toConnection;
+ private List fromConnectionInfos;
+ private ChannelConnections fromChannelConnections;
+ private List toConnectionInfos;
+ private ChannelMessage message;
+ private Service service;
+ private Timeout timeout;
}
diff --git a/src/main/java/org/fisco/bcos/channel/client/ChannelResponseCallback2.java b/src/main/java/org/fisco/bcos/channel/client/ChannelResponseCallback2.java
index 861f4eb0c..9a0d9e0d9 100644
--- a/src/main/java/org/fisco/bcos/channel/client/ChannelResponseCallback2.java
+++ b/src/main/java/org/fisco/bcos/channel/client/ChannelResponseCallback2.java
@@ -14,176 +14,176 @@
import org.slf4j.LoggerFactory;
public abstract class ChannelResponseCallback2 {
- private static Logger logger = LoggerFactory.getLogger(ChannelResponseCallback2.class);
- private ConnectionInfo fromConnection;
- private List fromConnectionInfos;
- private ChannelConnections fromChannelConnections;
- private ChannelMessage2 message;
- private Service service;
- private Timeout timeout;
-
- public abstract void onResponseMessage(ChannelResponse response);
-
- public final void onResponse(ChannelResponse response) {
- if (response.getErrorCode() == 99) {
- logger.error("Local node error,try the next local nodec");
-
- retrySendMessage(); // 1表示客户端错误
- } else {
- try {
- onResponseMessage(response);
- } catch (Exception e) {
- logger.error("response package processing error:", e);
- }
-
- if (message.getSeq() != null) {
- service.getSeq2Callback().remove(message.getSeq());
- }
-
- if (timeout != null) {
- timeout.cancel();
- }
+ private static Logger logger = LoggerFactory.getLogger(ChannelResponseCallback2.class);
+ private ConnectionInfo fromConnection;
+ private List fromConnectionInfos;
+ private ChannelConnections fromChannelConnections;
+ private ChannelMessage2 message;
+ private Service service;
+ private Timeout timeout;
+
+ public abstract void onResponseMessage(ChannelResponse response);
+
+ public final void onResponse(ChannelResponse response) {
+ if (response.getErrorCode() == 99) {
+ logger.error("Local node error,try the next local nodec");
+
+ retrySendMessage(); // 1表示客户端错误
+ } else {
+ try {
+ onResponseMessage(response);
+ } catch (Exception e) {
+ logger.error("response package processing error:", e);
+ }
+
+ if (message.getSeq() != null) {
+ service.getSeq2Callback().remove(message.getSeq());
+ }
+
+ if (timeout != null) {
+ timeout.cancel();
+ }
+ }
}
- }
- public final void onTimeout() {
- logger.error("send message timeout:{}", message.getSeq());
+ public final void onTimeout() {
+ logger.error("send message timeout:{}", message.getSeq());
- ChannelResponse response = new ChannelResponse();
- response.setErrorCode(102);
- response.setMessageID(message.getSeq());
- response.setErrorMessage("send message timeout");
- response.setContent("");
+ ChannelResponse response = new ChannelResponse();
+ response.setErrorCode(102);
+ response.setMessageID(message.getSeq());
+ response.setErrorMessage("send message timeout");
+ response.setContent("");
- try {
- onResponseMessage(response);
- } catch (Exception e) {
- logger.error("timeout processing error:", e);
- }
+ try {
+ onResponseMessage(response);
+ } catch (Exception e) {
+ logger.error("timeout processing error:", e);
+ }
- service.getSeq2Callback().remove(message.getSeq());
- timeout.cancel();
- }
-
- public void retrySendMessage() {
- Integer errorCode = 0;
- try {
- // 选取客户端节点
- logger.debug("Number of local nodes:{}", fromConnectionInfos.size());
-
- setFromConnection(null);
- if (fromConnectionInfos.size() > 0) {
- Random random = new SecureRandom();
- Integer index = random.nextInt(fromConnectionInfos.size());
-
- logger.debug("selected:{}", index);
-
- setFromConnection(fromConnectionInfos.get(index));
-
- fromConnectionInfos.remove(fromConnectionInfos.get(index));
- }
-
- if (getFromConnection() == null) {
- // 所有节点已尝试,无法再重试了
- logger.error("Failed to send message,all retry failed");
-
- errorCode = 99;
- throw new Exception("Failed to send message,all retry failed");
- }
-
- ChannelHandlerContext ctx =
- fromChannelConnections.getNetworkConnectionByHost(
- getFromConnection().getHost(), getFromConnection().getPort());
-
- if (ctx != null && ctx.channel().isActive()) {
- ByteBuf out = ctx.alloc().buffer();
- message.writeHeader(out);
- message.writeExtra(out);
-
- ctx.writeAndFlush(out);
-
- logger.debug(
- "send message to "
- + fromConnection.getHost()
- + ":"
- + String.valueOf(fromConnection.getPort())
- + " 成功");
- } else {
- logger.error("sending node unavailable");
-
- retrySendMessage();
- }
- } catch (Exception e) {
- logger.error("send message exception ", e);
-
- ChannelResponse response = new ChannelResponse();
- response.setErrorCode(errorCode);
- response.setErrorMessage(e.getMessage());
-
- try {
- onResponseMessage(response);
- } catch (Exception ee) {
- logger.error("onResponseMessage error:", ee);
- }
-
- // 彻底失败后,删掉这个seq
- if (message.getSeq() != null) {
service.getSeq2Callback().remove(message.getSeq());
- }
-
- if (timeout != null) {
timeout.cancel();
- }
+ }
- return;
+ public void retrySendMessage() {
+ Integer errorCode = 0;
+ try {
+ // 选取客户端节点
+ logger.debug("Number of local nodes:{}", fromConnectionInfos.size());
+
+ setFromConnection(null);
+ if (fromConnectionInfos.size() > 0) {
+ Random random = new SecureRandom();
+ Integer index = random.nextInt(fromConnectionInfos.size());
+
+ logger.debug("selected:{}", index);
+
+ setFromConnection(fromConnectionInfos.get(index));
+
+ fromConnectionInfos.remove(fromConnectionInfos.get(index));
+ }
+
+ if (getFromConnection() == null) {
+ // 所有节点已尝试,无法再重试了
+ logger.error("Failed to send message,all retry failed");
+
+ errorCode = 99;
+ throw new Exception("Failed to send message,all retry failed");
+ }
+
+ ChannelHandlerContext ctx =
+ fromChannelConnections.getNetworkConnectionByHost(
+ getFromConnection().getHost(), getFromConnection().getPort());
+
+ if (ctx != null && ctx.channel().isActive()) {
+ ByteBuf out = ctx.alloc().buffer();
+ message.writeHeader(out);
+ message.writeExtra(out);
+
+ ctx.writeAndFlush(out);
+
+ logger.debug(
+ "send message to "
+ + fromConnection.getHost()
+ + ":"
+ + String.valueOf(fromConnection.getPort())
+ + " 成功");
+ } else {
+ logger.error("sending node unavailable");
+
+ retrySendMessage();
+ }
+ } catch (Exception e) {
+ logger.error("send message exception ", e);
+
+ ChannelResponse response = new ChannelResponse();
+ response.setErrorCode(errorCode);
+ response.setErrorMessage(e.getMessage());
+
+ try {
+ onResponseMessage(response);
+ } catch (Exception ee) {
+ logger.error("onResponseMessage error:", ee);
+ }
+
+ // 彻底失败后,删掉这个seq
+ if (message.getSeq() != null) {
+ service.getSeq2Callback().remove(message.getSeq());
+ }
+
+ if (timeout != null) {
+ timeout.cancel();
+ }
+
+ return;
+ }
}
- }
- public ConnectionInfo getFromConnection() {
- return fromConnection;
- }
+ public ConnectionInfo getFromConnection() {
+ return fromConnection;
+ }
- public void setFromConnection(ConnectionInfo fromConnection) {
- this.fromConnection = fromConnection;
- }
+ public void setFromConnection(ConnectionInfo fromConnection) {
+ this.fromConnection = fromConnection;
+ }
- public List getFromConnectionInfos() {
- return fromConnectionInfos;
- }
+ public List getFromConnectionInfos() {
+ return fromConnectionInfos;
+ }
- public void setFromConnectionInfos(List fromConnectionInfos) {
- this.fromConnectionInfos = fromConnectionInfos;
- }
+ public void setFromConnectionInfos(List fromConnectionInfos) {
+ this.fromConnectionInfos = fromConnectionInfos;
+ }
- public ChannelConnections getFromChannelConnections() {
- return fromChannelConnections;
- }
+ public ChannelConnections getFromChannelConnections() {
+ return fromChannelConnections;
+ }
- public void setFromChannelConnections(ChannelConnections fromConnectionConnections) {
- this.fromChannelConnections = fromConnectionConnections;
- }
+ public void setFromChannelConnections(ChannelConnections fromConnectionConnections) {
+ this.fromChannelConnections = fromConnectionConnections;
+ }
- public ChannelMessage2 getRequest() {
- return message;
- }
+ public ChannelMessage2 getRequest() {
+ return message;
+ }
- public void setRequest(ChannelMessage2 message) {
- this.message = message;
- }
+ public void setRequest(ChannelMessage2 message) {
+ this.message = message;
+ }
- public Service getService() {
- return service;
- }
+ public Service getService() {
+ return service;
+ }
- public void setService(Service service) {
- this.service = service;
- }
+ public void setService(Service service) {
+ this.service = service;
+ }
- public Timeout getTimeout() {
- return timeout;
- }
+ public Timeout getTimeout() {
+ return timeout;
+ }
- public void setTimeout(Timeout timeout) {
- this.timeout = timeout;
- }
+ public void setTimeout(Timeout timeout) {
+ this.timeout = timeout;
+ }
}
diff --git a/src/main/java/org/fisco/bcos/channel/client/FiscoResponseCallback.java b/src/main/java/org/fisco/bcos/channel/client/FiscoResponseCallback.java
deleted file mode 100644
index 86d771c8f..000000000
--- a/src/main/java/org/fisco/bcos/channel/client/FiscoResponseCallback.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package org.fisco.bcos.channel.client;
-
-import io.netty.util.Timeout;
-import org.fisco.bcos.channel.dto.FiscoResponse;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public abstract class FiscoResponseCallback {
- private static Logger logger = LoggerFactory.getLogger(FiscoResponseCallback.class);
-
- private Timeout timeout;
-
- public abstract void onResponse(FiscoResponse response);
-
- public void onTimeout() {
- logger.error("Processing fisco message timeout:{}");
-
- FiscoResponse response = new FiscoResponse();
- response.setErrorCode(102);
- response.setErrorMessage("Processing fisco message timeout");
-
- response.setContent("");
-
- onResponse(response);
- }
-
- public Timeout getTimeout() {
- return timeout;
- }
-
- public void setTimeout(Timeout timeout) {
- this.timeout = timeout;
- }
-}
diff --git a/src/main/java/org/fisco/bcos/channel/client/P12Manager.java b/src/main/java/org/fisco/bcos/channel/client/P12Manager.java
new file mode 100644
index 000000000..9b2161ad4
--- /dev/null
+++ b/src/main/java/org/fisco/bcos/channel/client/P12Manager.java
@@ -0,0 +1,142 @@
+package org.fisco.bcos.channel.client;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.Security;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.interfaces.ECPrivateKey;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECPoint;
+import java.security.spec.ECPublicKeySpec;
+import java.security.spec.InvalidKeySpecException;
+import java.util.Collections;
+import org.bouncycastle.jcajce.provider.keystore.pkcs12.PKCS12KeyStoreSpi;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.fisco.bcos.web3j.crypto.ECKeyPair;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.core.io.support.ResourcePatternResolver;
+
+public class P12Manager {
+ private String p12File;
+ private final String NAME = "key";
+ private String password;
+ private KeyStore keyStore;
+ PKCS12KeyStoreSpi p12KeyStore;
+
+ public P12Manager() {
+ Security.setProperty("crypto.policy", "unlimited");
+ Security.addProvider(new BouncyCastleProvider());
+ }
+
+ public void load()
+ throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException,
+ NoSuchProviderException {
+ ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
+ keyStore = KeyStore.getInstance("PKCS12", "BC");
+ Resource keyStoreResource = resolver.getResource(p12File);
+
+ keyStore.load(keyStoreResource.getInputStream(), password.toCharArray());
+ }
+
+ public void load(InputStream in, String password)
+ throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
+ p12KeyStore.engineLoad(in, password.toCharArray());
+ }
+
+ public PrivateKey getPrivateKey(String password)
+ throws UnrecoverableKeyException, KeyStoreException, NoSuchAlgorithmException {
+ return (PrivateKey) keyStore.getKey(NAME, password.toCharArray());
+ }
+
+ public PublicKey getPublicKey(String password)
+ throws UnrecoverableKeyException, KeyStoreException, NoSuchAlgorithmException,
+ InvalidKeySpecException, NoSuchProviderException {
+ ECPrivateKey privateKey = (ECPrivateKey) getPrivateKey(password);
+
+ ECParameterSpec params = privateKey.getParams();
+
+ org.bouncycastle.jce.spec.ECParameterSpec bcSpec =
+ org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util.convertSpec(params, false);
+ org.bouncycastle.math.ec.ECPoint q = bcSpec.getG().multiply(privateKey.getS());
+ org.bouncycastle.math.ec.ECPoint bcW = bcSpec.getCurve().decodePoint(q.getEncoded(false));
+ ECPoint w =
+ new ECPoint(
+ bcW.getAffineXCoord().toBigInteger(), bcW.getAffineYCoord().toBigInteger());
+ ECPublicKeySpec keySpec = new ECPublicKeySpec(w, tryFindNamedCurveSpec(params));
+ return (PublicKey)
+ KeyFactory.getInstance(
+ "EC",
+ org.bouncycastle.jce.provider.BouncyCastleProvider.PROVIDER_NAME)
+ .generatePublic(keySpec);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static ECParameterSpec tryFindNamedCurveSpec(ECParameterSpec params) {
+ org.bouncycastle.jce.spec.ECParameterSpec bcSpec =
+ org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util.convertSpec(params, false);
+ for (Object name : Collections.list(org.bouncycastle.jce.ECNamedCurveTable.getNames())) {
+ org.bouncycastle.jce.spec.ECNamedCurveParameterSpec bcNamedSpec =
+ org.bouncycastle.jce.ECNamedCurveTable.getParameterSpec((String) name);
+ if (bcNamedSpec.getN().equals(bcSpec.getN())
+ && bcNamedSpec.getH().equals(bcSpec.getH())
+ && bcNamedSpec.getCurve().equals(bcSpec.getCurve())
+ && bcNamedSpec.getG().equals(bcSpec.getG())) {
+ return new org.bouncycastle.jce.spec.ECNamedCurveSpec(
+ bcNamedSpec.getName(),
+ bcNamedSpec.getCurve(),
+ bcNamedSpec.getG(),
+ bcNamedSpec.getN(),
+ bcNamedSpec.getH(),
+ bcNamedSpec.getSeed());
+ }
+ }
+ return params;
+ }
+
+ public Certificate getCertificate() throws KeyStoreException {
+ return keyStore.getCertificate(NAME);
+ }
+
+ public PublicKey getPublicKeyFromCertificate() throws KeyStoreException {
+ Certificate certificate = getCertificate();
+ return certificate.getPublicKey();
+ }
+
+ public ECKeyPair getECKeyPair(String password)
+ throws UnrecoverableKeyException, KeyStoreException, NoSuchAlgorithmException,
+ InvalidKeySpecException, NoSuchProviderException {
+ PrivateKey privateKey = getPrivateKey(password);
+ PublicKey publicKey = getPublicKey(password);
+
+ KeyPair keyPair = new KeyPair(publicKey, privateKey);
+
+ return ECKeyPair.create(keyPair);
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getP12File() {
+ return p12File;
+ }
+
+ public void setP12File(String p12File) {
+ this.p12File = p12File;
+ }
+}
diff --git a/src/main/java/org/fisco/bcos/channel/client/PEMManager.java b/src/main/java/org/fisco/bcos/channel/client/PEMManager.java
new file mode 100644
index 000000000..f86b8ffe9
--- /dev/null
+++ b/src/main/java/org/fisco/bcos/channel/client/PEMManager.java
@@ -0,0 +1,136 @@
+package org.fisco.bcos.channel.client;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.Security;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+import java.security.interfaces.ECPrivateKey;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECPoint;
+import java.security.spec.ECPublicKeySpec;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.util.Collections;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.util.io.pem.PemObject;
+import org.bouncycastle.util.io.pem.PemReader;
+import org.fisco.bcos.web3j.crypto.ECKeyPair;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.core.io.support.ResourcePatternResolver;
+
+public class PEMManager {
+ private PemObject pem;
+ private String pemFile;
+
+ public PEMManager() {
+ Security.setProperty("crypto.policy", "unlimited");
+ Security.addProvider(new BouncyCastleProvider());
+ }
+
+ public void load()
+ throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException,
+ NoSuchProviderException, InvalidKeySpecException {
+ ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
+ Resource pemResources = resolver.getResource(pemFile);
+
+ load(pemResources.getInputStream());
+ }
+
+ public void load(InputStream in)
+ throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException,
+ InvalidKeySpecException, NoSuchProviderException {
+ PemReader pemReader = new PemReader(new InputStreamReader(in));
+
+ pem = pemReader.readPemObject();
+ if (pem == null) {
+ throw new IOException("The file does not represent a pem account.");
+ }
+ pemReader.close();
+ }
+
+ public PrivateKey getPrivateKey()
+ throws InvalidKeySpecException, NoSuchAlgorithmException, NoSuchProviderException {
+ // PrivateKey key = KeyFactory.getInstance("EC",
+ // org.bouncycastle.jce.provider.BouncyCastleProvider.PROVIDER_NAME).generatePrivate(new
+ // X509EncodedKeySpec(pem.getContent()));
+
+ PKCS8EncodedKeySpec encodedKeySpec = new PKCS8EncodedKeySpec(pem.getContent());
+ KeyFactory keyFacotry =
+ KeyFactory.getInstance(
+ "EC", org.bouncycastle.jce.provider.BouncyCastleProvider.PROVIDER_NAME);
+ return keyFacotry.generatePrivate(encodedKeySpec);
+ }
+
+ public PublicKey getPublicKey()
+ throws InvalidKeySpecException, NoSuchAlgorithmException, NoSuchProviderException {
+ ECPrivateKey privateKey = (ECPrivateKey) getPrivateKey();
+
+ ECParameterSpec params = privateKey.getParams();
+
+ org.bouncycastle.jce.spec.ECParameterSpec bcSpec =
+ org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util.convertSpec(params, false);
+ org.bouncycastle.math.ec.ECPoint q = bcSpec.getG().multiply(privateKey.getS());
+ org.bouncycastle.math.ec.ECPoint bcW = bcSpec.getCurve().decodePoint(q.getEncoded(false));
+ ECPoint w =
+ new ECPoint(
+ bcW.getAffineXCoord().toBigInteger(), bcW.getAffineYCoord().toBigInteger());
+ ECPublicKeySpec keySpec = new ECPublicKeySpec(w, tryFindNamedCurveSpec(params));
+ return (PublicKey)
+ KeyFactory.getInstance(
+ "EC",
+ org.bouncycastle.jce.provider.BouncyCastleProvider.PROVIDER_NAME)
+ .generatePublic(keySpec);
+ }
+
+ public ECKeyPair getECKeyPair()
+ throws UnrecoverableKeyException, KeyStoreException, NoSuchAlgorithmException,
+ InvalidKeySpecException, NoSuchProviderException {
+ PrivateKey privateKey = getPrivateKey();
+ PublicKey publicKey = getPublicKey();
+
+ KeyPair keyPair = new KeyPair(publicKey, privateKey);
+
+ return ECKeyPair.create(keyPair);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static ECParameterSpec tryFindNamedCurveSpec(ECParameterSpec params) {
+ org.bouncycastle.jce.spec.ECParameterSpec bcSpec =
+ org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util.convertSpec(params, false);
+ for (Object name : Collections.list(org.bouncycastle.jce.ECNamedCurveTable.getNames())) {
+ org.bouncycastle.jce.spec.ECNamedCurveParameterSpec bcNamedSpec =
+ org.bouncycastle.jce.ECNamedCurveTable.getParameterSpec((String) name);
+ if (bcNamedSpec.getN().equals(bcSpec.getN())
+ && bcNamedSpec.getH().equals(bcSpec.getH())
+ && bcNamedSpec.getCurve().equals(bcSpec.getCurve())
+ && bcNamedSpec.getG().equals(bcSpec.getG())) {
+ return new org.bouncycastle.jce.spec.ECNamedCurveSpec(
+ bcNamedSpec.getName(),
+ bcNamedSpec.getCurve(),
+ bcNamedSpec.getG(),
+ bcNamedSpec.getN(),
+ bcNamedSpec.getH(),
+ bcNamedSpec.getSeed());
+ }
+ }
+ return params;
+ }
+
+ public String getPemFile() {
+ return pemFile;
+ }
+
+ public void setPemFile(String pemFile) {
+ this.pemFile = pemFile;
+ }
+}
diff --git a/src/main/java/org/fisco/bcos/channel/client/Service.java b/src/main/java/org/fisco/bcos/channel/client/Service.java
index 31fa326d2..fdbbab936 100644
--- a/src/main/java/org/fisco/bcos/channel/client/Service.java
+++ b/src/main/java/org/fisco/bcos/channel/client/Service.java
@@ -9,6 +9,7 @@
import io.netty.util.Timer;
import io.netty.util.TimerTask;
import java.math.BigInteger;
+import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -18,740 +19,832 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
-import org.fisco.bcos.channel.dto.*;
+import org.fisco.bcos.channel.dto.BcosMessage;
+import org.fisco.bcos.channel.dto.BcosRequest;
+import org.fisco.bcos.channel.dto.BcosResponse;
+import org.fisco.bcos.channel.dto.ChannelMessage;
+import org.fisco.bcos.channel.dto.ChannelMessage2;
+import org.fisco.bcos.channel.dto.ChannelPush;
+import org.fisco.bcos.channel.dto.ChannelPush2;
+import org.fisco.bcos.channel.dto.ChannelRequest;
+import org.fisco.bcos.channel.dto.ChannelResponse;
import org.fisco.bcos.channel.handler.ChannelConnections;
import org.fisco.bcos.channel.handler.ConnectionCallback;
import org.fisco.bcos.channel.handler.ConnectionInfo;
import org.fisco.bcos.channel.handler.GroupChannelConnectionsConfig;
+import org.fisco.bcos.channel.handler.Message;
import org.fisco.bcos.web3j.protocol.core.methods.response.TransactionReceipt;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
public class Service {
- private static Logger logger = LoggerFactory.getLogger(Service.class);
- private Integer connectSeconds = 30;
- private Integer connectSleepPerMillis = 1;
- private String orgID;
- private GroupChannelConnectionsConfig allChannelConnections;
- private ChannelPushCallback pushCallback;
- private Map seq2Callback = new ConcurrentHashMap();
- private int groupId;
- private static ObjectMapper objectMapper = new ObjectMapper();
- private BigInteger number = BigInteger.valueOf(0);
-
- /** add transaction seq callback */
- private Map seq2TransactionCallback = new ConcurrentHashMap();
-
- private Timer timeoutHandler = new HashedWheelTimer();
- private ThreadPoolTaskExecutor threadPool;
-
- private Set topics = new HashSet();
-
- public void setTopics(Set topics) {
- try {
- this.topics = topics;
- } catch (Exception e) {
- logger.error("system error", e);
- }
- }
-
- public Integer getConnectSeconds() {
- return connectSeconds;
- }
-
- public void setConnectSeconds(Integer connectSeconds) {
- this.connectSeconds = connectSeconds;
- }
-
- public Integer getConnectSleepPerMillis() {
- return connectSleepPerMillis;
- }
-
- public void setConnectSleepPerMillis(Integer connectSleepPerMillis) {
- this.connectSleepPerMillis = connectSleepPerMillis;
- }
-
- public String getOrgID() {
- return orgID;
- }
-
- public void setOrgID(String orgID) {
- this.orgID = orgID;
- }
-
- public ChannelPushCallback getPushCallback() {
- return pushCallback;
- }
-
- public void setPushCallback(ChannelPushCallback pushCallback) {
- this.pushCallback = pushCallback;
- }
-
- public GroupChannelConnectionsConfig getAllChannelConnections() {
- return allChannelConnections;
- }
-
- public void setAllChannelConnections(GroupChannelConnectionsConfig allChannelConnections) {
- this.allChannelConnections = allChannelConnections;
- }
-
- public void run() throws Exception {
- logger.debug("init ChannelService");
- int flag = 0;
- for (ChannelConnections channelConnections : allChannelConnections.getAllChannelConnections()) {
-
- if (channelConnections.getGroupId() == groupId) {
- flag = 1;
+ private static Logger logger = LoggerFactory.getLogger(Service.class);
+ private Integer connectSeconds = 30;
+ private Integer connectSleepPerMillis = 1;
+ private String orgID;
+ private String agencyName;
+ private GroupChannelConnectionsConfig allChannelConnections;
+ private ChannelPushCallback pushCallback;
+ private Map seq2Callback = new ConcurrentHashMap();
+ private int groupId;
+ private static ObjectMapper objectMapper = new ObjectMapper();
+ private BigInteger number = BigInteger.valueOf(0);
+ private ConcurrentHashMap nodeToBlockNumberMap = new ConcurrentHashMap<>();
+ /** add transaction seq callback */
+ private Map seq2TransactionCallback = new ConcurrentHashMap();
+
+ private Timer timeoutHandler = new HashedWheelTimer();
+ private ThreadPoolTaskExecutor threadPool;
+
+ private Set topics = new HashSet();
+
+ public void setTopics(Set topics) {
try {
- ConnectionCallback connectionCallback = new ConnectionCallback(topics);
- connectionCallback.setChannelService(this);
-
- channelConnections.setCallback(connectionCallback);
- channelConnections.init();
- channelConnections.setThreadPool(threadPool);
- channelConnections.startConnect();
-
- int sleepTime = 0;
- boolean running = false;
- while (true) {
- Map networkConnection =
- channelConnections.getNetworkConnections();
- for (String key : networkConnection.keySet()) {
- if (networkConnection.get(key) != null
- && networkConnection.get(key).channel().isActive()) {
- running = true;
- break;
- }
+ this.topics = topics;
+ } catch (Exception e) {
+ logger.error("system error", e);
+ }
+ }
+
+ public ConcurrentHashMap getNodeToBlockNumberMap() {
+ return nodeToBlockNumberMap;
+ }
+
+ public void setNodeToBlockNumberMap(ConcurrentHashMap nodeToBlockNumberMap) {
+ this.nodeToBlockNumberMap = nodeToBlockNumberMap;
+ }
+
+ public boolean flushTopics(List topics) {
+
+ try {
+ Message message = new Message();
+ message.setResult(0);
+ message.setType((short) 0x32); // topic设置topic消息0x32
+ message.setSeq(UUID.randomUUID().toString().replaceAll("-", ""));
+
+ message.setData(objectMapper.writeValueAsBytes(topics.toArray()));
+
+ ChannelConnections fromChannelConnections =
+ allChannelConnections
+ .getAllChannelConnections()
+ .stream()
+ .filter(x -> x.getGroupId() == groupId)
+ .findFirst()
+ .get();
+
+ if (fromChannelConnections == null) {
+ logger.error("not found and connections which orgId is:{}", orgID);
+ return false;
}
- if (running || sleepTime > connectSeconds * 1000) {
- break;
- } else {
- Thread.sleep(connectSleepPerMillis);
- sleepTime += connectSleepPerMillis;
+ for (String key : fromChannelConnections.getNetworkConnections().keySet()) {
+ ChannelHandlerContext ctx = fromChannelConnections.getNetworkConnections().get(key);
+
+ if (ctx != null && ctx.channel().isActive()) {
+ ByteBuf out = ctx.alloc().buffer();
+ message.writeHeader(out);
+ message.writeExtra(out);
+ ctx.writeAndFlush(out);
+
+ String host =
+ ((SocketChannel) ctx.channel())
+ .remoteAddress()
+ .getAddress()
+ .getHostAddress();
+ Integer port = ((SocketChannel) ctx.channel()).remoteAddress().getPort();
+
+ logger.info(
+ "try to flush seq:{} topics:{} to host:{} port :{}",
+ message.getSeq(),
+ topics,
+ host,
+ port);
+ }
}
- }
-
- if (!running) {
- logger.error("connectSeconds = " + connectSeconds);
- logger.error(
- "cannot not connect to node success, please checkout the node and the sdk config!");
- throw new Exception(
- "Init ChannelService fail!Please Refer To Link Below:https://github.com/FISCO-BCOS/web3sdk/wiki/web3sdk-debug");
- }
- } catch (InterruptedException e) {
- logger.error("system error ", e);
- Thread.currentThread().interrupt();
+
+ return true;
} catch (Exception e) {
- logger.error("system error ", e);
- throw e;
+ logger.error("flushTopics exception", e);
}
- }
+
+ return false;
}
- if (flag == 0) {
- throw new Exception("Please set the right groupId");
+
+ public Set getTopics() {
+ return this.topics;
}
- }
- public FiscoResponse sendEthereumMessage(FiscoRequest request) {
- class Callback extends FiscoResponseCallback {
- Callback() {
- try {
- semaphore.acquire(1);
+ public Integer getConnectSeconds() {
+ return connectSeconds;
+ }
- } catch (InterruptedException e) {
- logger.error("error :", e);
- Thread.currentThread().interrupt();
- }
- }
+ public void setConnectSeconds(Integer connectSeconds) {
+ this.connectSeconds = connectSeconds;
+ }
- @Override
- public void onResponse(FiscoResponse response) {
- fiscoResponse = response;
+ public Integer getConnectSleepPerMillis() {
+ return connectSleepPerMillis;
+ }
- if (fiscoResponse != null && fiscoResponse.getContent() != null) {
- logger.debug("response: {}", response.getContent());
- } else {
- logger.error("fisco error");
- }
+ public void setConnectSleepPerMillis(Integer connectSleepPerMillis) {
+ this.connectSleepPerMillis = connectSleepPerMillis;
+ }
+
+ public String getOrgID() {
+ return orgID;
+ }
+
+ public void setOrgID(String orgID) {
+ this.orgID = orgID;
+ }
+
+ public String getAgencyName() {
+ return agencyName;
+ }
+
+ public void setAgencyName(String agencyName) {
+ this.agencyName = agencyName;
+ }
+
+ public ChannelPushCallback getPushCallback() {
+ return pushCallback;
+ }
- semaphore.release();
- }
+ public void setPushCallback(ChannelPushCallback pushCallback) {
+ this.pushCallback = pushCallback;
+ }
- public FiscoResponse fiscoResponse;
- public Semaphore semaphore = new Semaphore(1, true);
- };
+ public GroupChannelConnectionsConfig getAllChannelConnections() {
+ return allChannelConnections;
+ }
- Callback callback = new Callback();
+ public void setAllChannelConnections(GroupChannelConnectionsConfig allChannelConnections) {
+ this.allChannelConnections = allChannelConnections;
+ }
+
+ public void run() throws Exception {
+ logger.debug("init ChannelService");
+ int flag = 0;
+ for (ChannelConnections channelConnections :
+ allChannelConnections.getAllChannelConnections()) {
+
+ if (channelConnections.getGroupId() == groupId) {
+ flag = 1;
+ try {
+ ConnectionCallback connectionCallback = new ConnectionCallback(topics);
+ connectionCallback.setChannelService(this);
+
+ channelConnections.setCallback(connectionCallback);
+ channelConnections.init();
+ channelConnections.setThreadPool(threadPool);
+ channelConnections.startConnect();
+
+ int sleepTime = 0;
+ boolean running = false;
+ while (true) {
+ Map networkConnection =
+ channelConnections.getNetworkConnections();
+ for (String key : networkConnection.keySet()) {
+ if (networkConnection.get(key) != null
+ && networkConnection.get(key).channel().isActive()) {
+ running = true;
+ break;
+ }
+ }
+
+ if (running || sleepTime > connectSeconds * 1000) {
+ break;
+ } else {
+ Thread.sleep(connectSleepPerMillis);
+ sleepTime += connectSleepPerMillis;
+ }
+ }
- asyncSendEthereumMessage(request, callback);
- try {
- callback.semaphore.acquire(1);
- } catch (InterruptedException e) {
- logger.error("system error:", e);
- Thread.currentThread().interrupt();
+ if (!running) {
+ logger.error("connectSeconds = " + connectSeconds);
+ logger.error(
+ "can not connect to nodes success, please checkout the node status and the sdk config!");
+ throw new Exception(
+ "Can not connect to nodes success, please checkout the node status and the sdk config!");
+ }
+ } catch (InterruptedException e) {
+ logger.error("system error ", e);
+ Thread.currentThread().interrupt();
+ } catch (Exception e) {
+ logger.error("system error ", e);
+ throw e;
+ }
+ }
+ }
+ if (flag == 0) {
+ throw new Exception("Please set the right groupId");
+ }
}
- return callback.fiscoResponse;
- }
+ public BcosResponse sendEthereumMessage(BcosRequest request) {
+ class Callback extends BcosResponseCallback {
+ Callback() {
+ try {
+ semaphore.acquire(1);
+
+ } catch (InterruptedException e) {
+ logger.error("error :", e);
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ @Override
+ public void onResponse(BcosResponse response) {
+ fiscoResponse = response;
+
+ if (fiscoResponse != null && fiscoResponse.getContent() != null) {
+ logger.debug("response: {}", response.getContent());
+ } else {
+ logger.error("fisco error");
+ }
+
+ semaphore.release();
+ }
- public FiscoResponse sendEthereumMessage(
- FiscoRequest request, TransactionSucCallback transactionSucCallback) {
- class Callback extends FiscoResponseCallback {
- public FiscoResponse ethereumResponse;
- public Semaphore semaphore = new Semaphore(1, true);
+ public BcosResponse fiscoResponse;
+ public Semaphore semaphore = new Semaphore(1, true);
+ };
- Callback() {
+ Callback callback = new Callback();
+
+ asyncSendEthereumMessage(request, callback);
try {
- semaphore.acquire(1);
+ callback.semaphore.acquire(1);
} catch (InterruptedException e) {
- logger.error("error:", e);
- Thread.currentThread().interrupt();
+ logger.error("system error:", e);
+ Thread.currentThread().interrupt();
}
- }
-
- @Override
- public void onResponse(FiscoResponse response) {
- ethereumResponse = response;
-
- logger.info("response: {}", response.getContent());
-
- semaphore.release();
- }
- }
-
- Callback callback = new Callback();
- asyncSendEthereumMessage(request, callback, transactionSucCallback);
- try {
- callback.semaphore.acquire(1);
- } catch (InterruptedException e) {
- logger.error("system error:", e);
- Thread.currentThread().interrupt();
- }
-
- return callback.ethereumResponse;
- }
-
- public void asyncSendEthereumMessage(
- FiscoRequest request,
- FiscoResponseCallback fiscoResponseCallback,
- TransactionSucCallback transactionSucCallback) {
- this.asyncSendEthereumMessage(request, fiscoResponseCallback);
- if (request.getTimeout() > 0) {
- final TransactionSucCallback callbackInner = transactionSucCallback;
- callbackInner.setTimeout(
- timeoutHandler.newTimeout(
- new TimerTask() {
- @Override
- public void run(Timeout timeout) throws Exception {
- // 处理超时逻辑
- callbackInner.onTimeout();
- // timeout时清除map的数据,所以尽管后面有回包数据,也会找不到seq->callback的关系
- seq2TransactionCallback.remove(request.getMessageID());
+
+ return callback.fiscoResponse;
+ }
+
+ public BcosResponse sendEthereumMessage(
+ BcosRequest request, TransactionSucCallback transactionSucCallback) {
+ class Callback extends BcosResponseCallback {
+ public BcosResponse ethereumResponse;
+ public Semaphore semaphore = new Semaphore(1, true);
+
+ Callback() {
+ try {
+ semaphore.acquire(1);
+ } catch (InterruptedException e) {
+ logger.error("error:", e);
+ Thread.currentThread().interrupt();
}
- },
- request.getTimeout(),
- TimeUnit.MILLISECONDS));
- this.seq2TransactionCallback.put(request.getMessageID(), callbackInner);
- } else {
- this.seq2TransactionCallback.put(request.getMessageID(), transactionSucCallback);
- }
- }
-
- public ChannelResponse sendChannelMessage2(ChannelRequest request) {
- class Callback extends ChannelResponseCallback2 {
- Callback() {
- try {
- semaphore.acquire(1);
+ }
+
+ @Override
+ public void onResponse(BcosResponse response) {
+ ethereumResponse = response;
+ semaphore.release();
+ }
+ }
+ Callback callback = new Callback();
+ asyncSendEthereumMessage(request, callback, transactionSucCallback);
+ try {
+ callback.semaphore.acquire(1);
} catch (InterruptedException e) {
- logger.error("error:", e);
- Thread.currentThread().interrupt();
+ logger.error("system error:", e);
+ Thread.currentThread().interrupt();
+ }
+
+ return callback.ethereumResponse;
+ }
+
+ public void asyncSendEthereumMessage(
+ BcosRequest request,
+ BcosResponseCallback fiscoResponseCallback,
+ TransactionSucCallback transactionSucCallback) {
+ this.asyncSendEthereumMessage(request, fiscoResponseCallback);
+ if (request.getTimeout() > 0) {
+ final TransactionSucCallback callbackInner = transactionSucCallback;
+ callbackInner.setTimeout(
+ timeoutHandler.newTimeout(
+ new TimerTask() {
+ @Override
+ public void run(Timeout timeout) throws Exception {
+ // 处理超时逻辑
+ callbackInner.onTimeout();
+ // timeout时清除map的数据,所以尽管后面有回包数据,也会找不到seq->callback的关系
+ seq2TransactionCallback.remove(request.getMessageID());
+ }
+ },
+ request.getTimeout(),
+ TimeUnit.MILLISECONDS));
+ this.seq2TransactionCallback.put(request.getMessageID(), callbackInner);
+ } else {
+ this.seq2TransactionCallback.put(request.getMessageID(), transactionSucCallback);
}
- }
+ }
- @Override
- public void onResponseMessage(ChannelResponse response) {
- channelResponse = response;
+ public ChannelResponse sendChannelMessage2(ChannelRequest request) {
+ class Callback extends ChannelResponseCallback2 {
+ Callback() {
+ try {
+ semaphore.acquire(1);
- logger.debug("response: {}", response.getContent());
-
- semaphore.release();
- }
+ } catch (InterruptedException e) {
+ logger.error("error:", e);
+ Thread.currentThread().interrupt();
+ }
+ }
- public ChannelResponse channelResponse;
- public Semaphore semaphore = new Semaphore(1, true);
- };
+ @Override
+ public void onResponseMessage(ChannelResponse response) {
+ channelResponse = response;
- Callback callback = new Callback();
+ logger.debug("response: {}", response.getContent());
- asyncSendChannelMessage2(request, callback);
- try {
- callback.semaphore.acquire(1);
- } catch (InterruptedException e) {
- logger.error("system error:", e);
- Thread.currentThread().interrupt();
- }
+ semaphore.release();
+ }
- return callback.channelResponse;
- }
+ public ChannelResponse channelResponse;
+ public Semaphore semaphore = new Semaphore(1, true);
+ };
- public void asyncSendEthereumMessage(FiscoRequest request, FiscoResponseCallback callback) {
- logger.debug("fisco message: " + request.getMessageID());
+ Callback callback = new Callback();
- Boolean sended = false;
-
- FiscoMessage fiscoMessage = new FiscoMessage();
-
- fiscoMessage.setSeq(request.getMessageID());
- fiscoMessage.setResult(0);
- fiscoMessage.setType((short) 0x12);
- fiscoMessage.setData(request.getContent().getBytes());
-
- // 选取发送节点
- try {
-
- ChannelConnections fromChannelConnections =
- allChannelConnections
- .getAllChannelConnections()
- .stream()
- .filter(x -> x.getGroupId() == groupId)
- .findFirst()
- .get();
-
- if (fromChannelConnections == null) {
- // 没有找到对应的链
- // 返回错误
- logger.error("not found:{}", orgID);
-
- throw new Exception("not found orgID");
- }
-
- ChannelHandlerContext ctx = fromChannelConnections.randomNetworkConnection();
-
- ByteBuf out = ctx.alloc().buffer();
- fiscoMessage.writeHeader(out);
- fiscoMessage.writeExtra(out);
-
- seq2Callback.put(request.getMessageID(), callback);
-
- if (request.getTimeout() > 0) {
- final FiscoResponseCallback callbackInner = callback; // ethereum名字可能会搞混,换成channel
- callback.setTimeout(
- timeoutHandler.newTimeout(
- new TimerTask() {
- FiscoResponseCallback _callback = callbackInner;
-
- @Override
- public void run(Timeout timeout) throws Exception {
- // 处理超时逻辑
- _callback.onTimeout();
- }
- },
- request.getTimeout(),
- TimeUnit.MILLISECONDS));
- }
-
- ctx.writeAndFlush(out);
-
- logger.debug(
- "send fisco message to "
- + ((SocketChannel) ctx.channel()).remoteAddress().getAddress().getHostAddress()
- + ":"
- + ((SocketChannel) ctx.channel()).remoteAddress().getPort()
- + " success");
-
- sended = true;
- } catch (Exception e) {
- logger.error("system error: " + e.getMessage());
-
- FiscoResponse response = new FiscoResponse();
- response.setErrorCode(-1);
- response.setErrorMessage(
- e.getMessage()
- + " requset send failed! Please Refer To Link Below:https://github.com/FISCO-BCOS/web3sdk/wiki/web3sdk-debug");
- response.setContent("");
- response.setMessageID(request.getMessageID());
-
- if (callback.getTimeout() != null) {
- callback.getTimeout().cancel();
- }
- callback.onResponse(response);
- }
- }
-
- public void asyncSendChannelMessage2(ChannelRequest request, ChannelResponseCallback2 callback) {
- try {
- logger.debug("ChannelRequest: " + request.getMessageID());
- callback.setService(this);
-
- ChannelMessage2 channelMessage = new ChannelMessage2();
-
- channelMessage.setSeq(request.getMessageID());
- channelMessage.setResult(0);
- channelMessage.setType((short) 0x30); // 链上链下请求0x30
- channelMessage.setData(request.getContent().getBytes());
- channelMessage.setTopic(request.getToTopic());
-
- try {
- List fromConnectionInfos = new ArrayList();
-
- // 设置发送节点
- ChannelConnections fromChannelConnections =
- allChannelConnections
- .getAllChannelConnections()
- .stream()
- .filter(x -> x.getGroupId() == groupId)
- .findFirst()
- .get();
- if (fromChannelConnections == null) {
- // 没有找到对应的链
- // 返回错误
- logger.error("not found orgID:{}", orgID);
-
- throw new Exception("not found orgID");
+ asyncSendChannelMessage2(request, callback);
+ try {
+ callback.semaphore.acquire(1);
+ } catch (InterruptedException e) {
+ logger.error("system error:", e);
+ Thread.currentThread().interrupt();
}
- fromConnectionInfos.addAll(fromChannelConnections.getConnections());
- logger.debug(
- "FromOrg:{} nodes:{}",
- request.getFromOrg(),
- fromChannelConnections.getConnections().size());
- callback.setFromChannelConnections(fromChannelConnections);
- callback.setFromConnectionInfos(fromConnectionInfos);
+ return callback.channelResponse;
+ }
- // 设置消息内容
- callback.setRequest(channelMessage);
+ public void asyncSendEthereumMessage(BcosRequest request, BcosResponseCallback callback) {
+ Boolean sended = false;
- seq2Callback.put(request.getMessageID(), callback);
+ BcosMessage bcosMessage = new BcosMessage();
- if (request.getTimeout() > 0) {
- final ChannelResponseCallback2 callbackInner = callback;
- callback.setTimeout(
- timeoutHandler.newTimeout(
- new TimerTask() {
- ChannelResponseCallback2 _callback = callbackInner;
-
- @Override
- public void run(Timeout timeout) throws Exception {
- // 处理超时逻辑
- _callback.onTimeout();
- }
- },
- request.getTimeout(),
- TimeUnit.MILLISECONDS));
- }
+ bcosMessage.setSeq(request.getMessageID());
+ bcosMessage.setResult(0);
+ bcosMessage.setType((short) 0x12);
+ bcosMessage.setData(request.getContent().getBytes());
+ // select node
+ try {
+ ChannelConnections channelConnections =
+ allChannelConnections
+ .getAllChannelConnections()
+ .stream()
+ .filter(x -> x.getGroupId() == groupId)
+ .findFirst()
+ .get();
+
+ if (channelConnections == null) {
+ if (orgID != null) {
+ logger.error("not found:{}", orgID);
+ throw new Exception("not found orgID");
+ } else {
+ logger.error("not found:{}", agencyName);
+ throw new Exception("not found agencyName");
+ }
+ }
+ ChannelHandlerContext ctx =
+ channelConnections.randomNetworkConnection(nodeToBlockNumberMap);
+
+ ByteBuf out = ctx.alloc().buffer();
+ bcosMessage.writeHeader(out);
+ bcosMessage.writeExtra(out);
+
+ seq2Callback.put(request.getMessageID(), callback);
+
+ if (request.getTimeout() > 0) {
+ final BcosResponseCallback callbackInner = callback;
+ callback.setTimeout(
+ timeoutHandler.newTimeout(
+ new TimerTask() {
+ BcosResponseCallback _callback = callbackInner;
+
+ @Override
+ public void run(Timeout timeout) throws Exception {
+ // handle timer
+ _callback.onTimeout();
+ }
+ },
+ request.getTimeout(),
+ TimeUnit.MILLISECONDS));
+ }
- callback.retrySendMessage();
- } catch (Exception e) {
- logger.error("send message fail:", e);
-
- ChannelResponse response = new ChannelResponse();
- response.setErrorCode(100);
- response.setMessageID(request.getMessageID());
- response.setErrorMessage(e.getMessage());
- response.setContent("");
-
- callback.onResponse(response);
- return;
- }
- } catch (Exception e) {
- logger.error("system error", e);
- }
- }
-
- public void sendResponseMessage(
- ChannelResponse response,
- ConnectionInfo info,
- ChannelHandlerContext ctx,
- String fromNode,
- String toNode,
- String seq) {
- try {
- ChannelMessage responseMessage = new ChannelMessage();
-
- responseMessage.setData(response.getContent().getBytes());
- responseMessage.setResult(response.getErrorCode());
- responseMessage.setSeq(seq);
- responseMessage.setType((short) 0x21); // 链上链下回包0x21
- responseMessage.setToNode(fromNode);
- responseMessage.setFromNode(toNode);
-
- ByteBuf out = ctx.alloc().buffer();
- responseMessage.writeHeader(out);
- responseMessage.writeExtra(out);
-
- ctx.writeAndFlush(out);
-
- logger.debug("response seq:{} length:{}", response.getMessageID(), out.readableBytes());
- } catch (Exception e) {
- logger.error("system error", e);
- }
- }
-
- // 链上链下二期回包
- public void sendResponseMessage2(
- ChannelResponse response, ChannelHandlerContext ctx, String seq, String topic) {
- try {
- ChannelMessage2 responseMessage = new ChannelMessage2();
-
- responseMessage.setData(response.getContent().getBytes());
- responseMessage.setResult(response.getErrorCode());
- responseMessage.setSeq(seq);
- responseMessage.setType((short) 0x31); // 链上链下二期回包0x31
- responseMessage.setTopic(topic);
-
- ByteBuf out = ctx.alloc().buffer();
- responseMessage.writeHeader(out);
- responseMessage.writeExtra(out);
-
- ctx.writeAndFlush(out);
-
- logger.debug("response seq:{} length:{}", response.getMessageID(), out.readableBytes());
- } catch (Exception e) {
- logger.error("system error:", e);
- }
- }
-
- public void onReceiveChannelMessage(ChannelHandlerContext ctx, ChannelMessage message) {
- ChannelResponseCallback callback = (ChannelResponseCallback) seq2Callback.get(message.getSeq());
- logger.debug("onReceiveChannelMessage seq:{}", message.getSeq());
-
- if (message.getType() == 0x20) { // 链上链下请求
- logger.debug("channel Message PUSH");
- if (callback != null) {
- // 清空callback再处理
- logger.debug("seq already existed,clean:{}", message.getSeq());
- seq2Callback.remove(message.getSeq());
- }
-
- try {
- ChannelPush push = new ChannelPush();
-
- if (pushCallback != null) {
- push.setService(this);
- push.setCtx(ctx);
- push.setMessageID(message.getSeq());
- push.setFromNode(message.getFromNode());
- push.setToNode(message.getToNode());
- push.setSeq(message.getSeq());
- push.setMessageID(message.getSeq());
-
- push.setContent(new String(message.getData(), 0, message.getData().length));
-
- pushCallback.onPush(push);
- } else {
- logger.error("can not push,unset push callback");
+ ctx.writeAndFlush(out);
+ sended = true;
+ SocketChannel socketChannel = (SocketChannel) ctx.channel();
+ InetSocketAddress socketAddress = socketChannel.remoteAddress();
+ logger.debug(
+ "selected node {}:{} bcos request, seq:{}",
+ socketAddress.getAddress().getHostAddress(),
+ socketAddress.getPort(),
+ bcosMessage.getSeq());
+
+ } catch (Exception e) {
+ logger.error("system error: " + e);
+
+ BcosResponse response = new BcosResponse();
+ response.setErrorCode(-1);
+ response.setErrorMessage(
+ e.getMessage()
+ + " Requset send failed! Can not connect to nodes success, please checkout the node status and the sdk config!");
+ response.setContent("");
+ response.setMessageID(request.getMessageID());
+
+ if (callback.getTimeout() != null) {
+ callback.getTimeout().cancel();
+ }
+ callback.onResponse(response);
}
- } catch (Exception e) {
- logger.error("pushCallback error:", e);
- }
- } else if (message.getType() == 0x21) { // 链上链下回包
- logger.debug("channel response:{}", message.getSeq());
- if (callback != null) {
- logger.debug("found callback response");
-
- ChannelResponse response = new ChannelResponse();
- if (message.getResult() != 0) {
- response.setErrorCode(message.getResult());
- response.setErrorMessage("response error");
+ }
+
+ public void asyncSendChannelMessage2(
+ ChannelRequest request, ChannelResponseCallback2 callback) {
+ try {
+ logger.debug("ChannelRequest: " + request.getMessageID());
+ callback.setService(this);
+
+ ChannelMessage2 channelMessage = new ChannelMessage2();
+
+ channelMessage.setSeq(request.getMessageID());
+ channelMessage.setResult(0);
+ channelMessage.setType((short) 0x30); // 链上链下请求0x30
+ channelMessage.setData(request.getContent().getBytes());
+ channelMessage.setTopic(request.getToTopic());
+
+ try {
+ List fromConnectionInfos = new ArrayList();
+
+ // 设置发送节点
+ ChannelConnections fromChannelConnections =
+ allChannelConnections
+ .getAllChannelConnections()
+ .stream()
+ .filter(x -> x.getGroupId() == groupId)
+ .findFirst()
+ .get();
+ if (fromChannelConnections == null) {
+ // 没有找到对应的链
+ // 返回错误
+ if (orgID != null) {
+ logger.error("not found:{}", orgID);
+ throw new Exception("not found orgID");
+ } else {
+ logger.error("not found:{}", agencyName);
+ throw new Exception("not found agencyName");
+ }
+ }
+ fromConnectionInfos.addAll(fromChannelConnections.getConnections());
+ logger.debug(
+ "FromOrg:{} nodes:{}",
+ request.getFromOrg(),
+ fromChannelConnections.getConnections().size());
+
+ callback.setFromChannelConnections(fromChannelConnections);
+ callback.setFromConnectionInfos(fromConnectionInfos);
+
+ // 设置消息内容
+ callback.setRequest(channelMessage);
+
+ seq2Callback.put(request.getMessageID(), callback);
+
+ if (request.getTimeout() > 0) {
+ final ChannelResponseCallback2 callbackInner = callback;
+ callback.setTimeout(
+ timeoutHandler.newTimeout(
+ new TimerTask() {
+ ChannelResponseCallback2 _callback = callbackInner;
+
+ @Override
+ public void run(Timeout timeout) throws Exception {
+ // 处理超时逻辑
+ _callback.onTimeout();
+ }
+ },
+ request.getTimeout(),
+ TimeUnit.MILLISECONDS));
+ }
+
+ callback.retrySendMessage();
+ } catch (Exception e) {
+ logger.error("send message fail:", e);
+
+ ChannelResponse response = new ChannelResponse();
+ response.setErrorCode(100);
+ response.setMessageID(request.getMessageID());
+ response.setErrorMessage(e.getMessage());
+ response.setContent("");
+
+ callback.onResponse(response);
+ return;
+ }
+ } catch (Exception e) {
+ logger.error("system error", e);
}
+ }
+
+ public void sendResponseMessage(
+ ChannelResponse response,
+ ConnectionInfo info,
+ ChannelHandlerContext ctx,
+ String fromNode,
+ String toNode,
+ String seq) {
+ try {
+ ChannelMessage responseMessage = new ChannelMessage();
+
+ responseMessage.setData(response.getContent().getBytes());
+ responseMessage.setResult(response.getErrorCode());
+ responseMessage.setSeq(seq);
+ responseMessage.setType((short) 0x21); // 链上链下回包0x21
+ responseMessage.setToNode(fromNode);
+ responseMessage.setFromNode(toNode);
+
+ ByteBuf out = ctx.alloc().buffer();
+ responseMessage.writeHeader(out);
+ responseMessage.writeExtra(out);
- response.setErrorCode(message.getResult());
- response.setMessageID(message.getSeq());
- if (message.getData() != null) {
- response.setContent(new String(message.getData()));
+ ctx.writeAndFlush(out);
+
+ logger.debug("response seq:{} length:{}", response.getMessageID(), out.readableBytes());
+ } catch (Exception e) {
+ logger.error("system error", e);
}
+ }
+
+ // 链上链下二期回包
+ public void sendResponseMessage2(
+ ChannelResponse response, ChannelHandlerContext ctx, String seq, String topic) {
+ try {
+ ChannelMessage2 responseMessage = new ChannelMessage2();
+
+ responseMessage.setData(response.getContent().getBytes());
+ responseMessage.setResult(response.getErrorCode());
+ responseMessage.setSeq(seq);
+ responseMessage.setType((short) 0x31); // 链上链下二期回包0x31
+ responseMessage.setTopic(topic);
+
+ ByteBuf out = ctx.alloc().buffer();
+ responseMessage.writeHeader(out);
+ responseMessage.writeExtra(out);
- callback.onResponse(response);
- } else {
- logger.error("can not found response callback,timeout:{}", message.getData());
- return;
- }
+ ctx.writeAndFlush(out);
+
+ logger.debug("response seq:{} length:{}", response.getMessageID(), out.readableBytes());
+ } catch (Exception e) {
+ logger.error("system error:", e);
+ }
}
- }
- public void onReceiveEthereumMessage(ChannelHandlerContext ctx, FiscoMessage message) {
- FiscoResponseCallback callback =
- (FiscoResponseCallback) seq2Callback.get(message.getSeq());
- logger.debug("FiscoResponse seq:{}", message.getSeq());
+ public void onReceiveChannelMessage(ChannelHandlerContext ctx, ChannelMessage message) {
+ ChannelResponseCallback callback =
+ (ChannelResponseCallback) seq2Callback.get(message.getSeq());
+ logger.debug("onReceiveChannelMessage seq:{}", message.getSeq());
+
+ if (message.getType() == 0x20) { // 链上链下请求
+ logger.debug("channel Message PUSH");
+ if (callback != null) {
+ // 清空callback再处理
+ logger.debug("seq already existed,clean:{}", message.getSeq());
+ seq2Callback.remove(message.getSeq());
+ }
- if (callback != null) {
- logger.debug("found callback FiscoResponse");
+ try {
+ ChannelPush push = new ChannelPush();
- if (callback.getTimeout() != null) {
- callback.getTimeout().cancel();
- }
+ if (pushCallback != null) {
+ push.setService(this);
+ push.setCtx(ctx);
+ push.setMessageID(message.getSeq());
+ push.setFromNode(message.getFromNode());
+ push.setToNode(message.getToNode());
+ push.setSeq(message.getSeq());
+ push.setMessageID(message.getSeq());
- FiscoResponse response = new FiscoResponse();
- if (message.getResult() != 0) {
- response.setErrorMessage("FiscoResponse error");
- }
+ push.setContent(new String(message.getData(), 0, message.getData().length));
- response.setErrorCode(message.getResult());
- response.setMessageID(message.getSeq());
- response.setContent(new String(message.getData()));
+ pushCallback.onPush(push);
+ } else {
+ logger.error("can not push,unset push callback");
+ }
+ } catch (Exception e) {
+ logger.error("pushCallback error:", e);
+ }
+ } else if (message.getType() == 0x21) { // 链上链下回包
+ logger.debug("channel response:{}", message.getSeq());
+ if (callback != null) {
+ logger.debug("found callback response");
+
+ ChannelResponse response = new ChannelResponse();
+ if (message.getResult() != 0) {
+ response.setErrorCode(message.getResult());
+ response.setErrorMessage("response error");
+ }
- callback.onResponse(response);
+ response.setErrorCode(message.getResult());
+ response.setMessageID(message.getSeq());
+ if (message.getData() != null) {
+ response.setContent(new String(message.getData()));
+ }
- seq2Callback.remove(message.getSeq());
- } else {
- logger.debug("no callback push message");
+ callback.onResponse(response);
+ } else {
+ logger.error("can not found response callback,timeout:{}", message.getData());
+ return;
+ }
+ }
}
- }
- public void onReceiveChannelMessage2(ChannelHandlerContext ctx, ChannelMessage2 message) {
- ChannelResponseCallback2 callback =
- (ChannelResponseCallback2) seq2Callback.get(message.getSeq());
- logger.debug("ChannelResponse seq:{}", message.getSeq());
+ public void onReceiveEthereumMessage(ChannelHandlerContext ctx, BcosMessage message) {
+ BcosResponseCallback callback = (BcosResponseCallback) seq2Callback.get(message.getSeq());
- if (message.getType() == 0x30) { // 链上链下请求
- logger.debug("channel PUSH");
- if (callback != null) {
- // 清空callback再处理
- logger.debug("seq already existed,clear:{}", message.getSeq());
- seq2Callback.remove(message.getSeq());
- }
+ if (callback != null) {
- try {
- ChannelPush2 push = new ChannelPush2();
+ if (callback.getTimeout() != null) {
+ callback.getTimeout().cancel();
+ }
- if (pushCallback != null) {
- // pushCallback.setInfo(info);
- push.setSeq(message.getSeq());
- push.setService(this);
- push.setCtx(ctx);
- push.setTopic(message.getTopic());
+ BcosResponse response = new BcosResponse();
+ if (message.getResult() != 0) {
+ response.setErrorMessage("BcosResponse error");
+ }
- push.setSeq(message.getSeq());
- push.setMessageID(message.getSeq());
- push.setContent(new String(message.getData(), 0, message.getData().length));
+ response.setErrorCode(message.getResult());
+ response.setMessageID(message.getSeq());
+ response.setContent(new String(message.getData()));
- pushCallback.onPush(push);
- } else {
- logger.error("can not push,unset push callback");
- }
- } catch (Exception e) {
- logger.error("push error:", e);
- }
- } else if (message.getType() == 0x31) { // 链上链下回包
- logger.debug("channel message:{}", message.getSeq());
- if (callback != null) {
- logger.debug("found callback response");
-
- ChannelResponse response = new ChannelResponse();
- if (message.getResult() != 0) {
- response.setErrorCode(message.getResult());
- response.setErrorMessage("response errors");
- }
+ callback.onResponse(response);
- response.setErrorCode(message.getResult());
- response.setMessageID(message.getSeq());
- if (message.getData() != null) {
- response.setContent(new String(message.getData()));
+ seq2Callback.remove(message.getSeq());
+ } else {
+ logger.debug("no callback push message");
}
-
- callback.onResponse(response);
- } else {
- logger.error("can not found response callback,timeout:{}", message.getData());
- return;
- }
}
- }
- public void onReceiveBlockNotify(ChannelHandlerContext ctx, ChannelMessage2 message) {
- try {
- String data = new String(message.getData());
- logger.debug("Receive block notify: {}", data);
- String[] split = data.split(",");
- if (split.length != 2) {
- logger.error("Block notify format error: {}", data);
- return;
- }
+ public void onReceiveChannelMessage2(ChannelHandlerContext ctx, ChannelMessage2 message) {
+ ChannelResponseCallback2 callback =
+ (ChannelResponseCallback2) seq2Callback.get(message.getSeq());
+ logger.debug("ChannelResponse seq:{}", message.getSeq());
+
+ if (message.getType() == 0x30) { // 链上链下请求
+ logger.debug("channel PUSH");
+ if (callback != null) {
+ // 清空callback再处理
+ logger.debug("seq already existed,clear:{}", message.getSeq());
+ seq2Callback.remove(message.getSeq());
+ }
+
+ try {
+ ChannelPush2 push = new ChannelPush2();
- Integer groupID = Integer.parseInt(split[0]);
+ if (pushCallback != null) {
+ // pushCallback.setInfo(info);
+ push.setSeq(message.getSeq());
+ push.setService(this);
+ push.setCtx(ctx);
+ push.setTopic(message.getTopic());
- if (!groupID.equals(getGroupId())) {
- logger.error("Received groupID[{}] not match groupID[{}]", groupID, getGroupId());
+ push.setSeq(message.getSeq());
+ push.setMessageID(message.getSeq());
+ push.setContent(new String(message.getData(), 0, message.getData().length));
- return;
- }
+ pushCallback.onPush(push);
+ } else {
+ logger.error("can not push,unset push callback");
+ }
+ } catch (Exception e) {
+ logger.error("push error:", e);
+ }
+ } else if (message.getType() == 0x31) { // 链上链下回包
+ logger.debug("channel message:{}", message.getSeq());
+ if (callback != null) {
+ logger.debug("found callback response");
+
+ ChannelResponse response = new ChannelResponse();
+ if (message.getResult() != 0) {
+ response.setErrorCode(message.getResult());
+ response.setErrorMessage("response errors");
+ }
- Integer number = Integer.parseInt(split[1]);
+ response.setErrorCode(message.getResult());
+ response.setMessageID(message.getSeq());
+ if (message.getData() != null) {
+ response.setContent(new String(message.getData()));
+ }
- if (number.compareTo(getNumber().intValue()) > 0) {
- setNumber(BigInteger.valueOf((long) number));
- }
- } catch (Exception e) {
- logger.error("Block notify error", e);
+ callback.onResponse(response);
+ } else {
+ logger.error("can not found response callback,timeout:{}", message.getData());
+ return;
+ }
+ }
}
- }
- public void onReceiveTransactionMessage(ChannelHandlerContext ctx, FiscoMessage message) {
- TransactionSucCallback callback =
- (TransactionSucCallback) seq2TransactionCallback.get(message.getSeq());
- logger.info("receive transaction success seq:{}", message.getSeq());
+ public void onReceiveBlockNotify(ChannelHandlerContext ctx, ChannelMessage2 message) {
+ try {
+ String data = new String(message.getData());
+ logger.info("Receive block notify: {}", data);
+ String[] split = data.split(",");
+ if (split.length != 2) {
+ logger.error("Block notify format error: {}", data);
+ return;
+ }
+ Integer groupID = Integer.parseInt(split[0]);
+
+ if (!groupID.equals(getGroupId())) {
+ logger.error("Received groupID[{}] not match groupID[{}]", groupID, getGroupId());
- if (callback != null) {
- logger.info("found callback transaction callback");
+ return;
+ }
+ SocketChannel socketChannel = (SocketChannel) ctx.channel();
+ String hostAddress = socketChannel.remoteAddress().getAddress().getHostAddress();
+ int port = socketChannel.remoteAddress().getPort();
+ Integer number = Integer.parseInt(split[1]);
+
+ nodeToBlockNumberMap.put(hostAddress + port, number);
+ // get max blockNumber to set blocklimit
+ Integer maxBlockNumber = number;
+ for (String key : nodeToBlockNumberMap.keySet()) {
+ int blockNumber = nodeToBlockNumberMap.get(key);
+ if (blockNumber >= maxBlockNumber) {
+ maxBlockNumber = blockNumber;
+ }
+ }
+ if (maxBlockNumber > getNumber().intValue()) {
+ setNumber(BigInteger.valueOf((long) maxBlockNumber));
+ }
+ } catch (Exception e) {
+ logger.error("Block notify error", e);
+ }
+ }
- if (callback.getTimeout() != null) {
- // 停止定时器,防止多响应一次
- callback.getTimeout().cancel();
- }
+ public void onReceiveTransactionMessage(ChannelHandlerContext ctx, BcosMessage message) {
+ TransactionSucCallback callback =
+ (TransactionSucCallback) seq2TransactionCallback.get(message.getSeq());
- try {
- TransactionReceipt receipt =
- objectMapper.readValue(message.getData(), TransactionReceipt.class);
+ if (callback != null) {
+ if (callback.getTimeout() != null) {
+ // stop timer,avoid response more once
+ callback.getTimeout().cancel();
+ }
- callback.onResponse(receipt);
- } catch (Exception e) {
- TransactionReceipt receipt = new TransactionReceipt();
- receipt.setStatus("Decode receipt error: " + e.getLocalizedMessage());
+ try {
+ TransactionReceipt receipt =
+ objectMapper.readValue(message.getData(), TransactionReceipt.class);
- callback.onResponse(receipt);
- }
+ callback.onResponse(receipt);
+ } catch (Exception e) {
+ TransactionReceipt receipt = new TransactionReceipt();
+ receipt.setStatus("Decode receipt error: " + e.getLocalizedMessage());
+
+ callback.onResponse(receipt);
+ }
- seq2TransactionCallback.remove(message.getSeq());
- } else {
- logger.info("callback is null");
+ seq2TransactionCallback.remove(message.getSeq());
+ }
}
- }
- public String newSeq() {
- return UUID.randomUUID().toString().replaceAll("-", "");
- }
+ public String newSeq() {
+ String seq = UUID.randomUUID().toString().replaceAll("-", "");
+ logger.info("New Seq" + seq);
+ return seq;
+ }
- public Map getSeq2Callback() {
- return seq2Callback;
- }
+ public Map getSeq2Callback() {
+ return seq2Callback;
+ }
- public void setSeq2Callback(Map seq2Callback) {
- this.seq2Callback = seq2Callback;
- }
+ public void setSeq2Callback(Map seq2Callback) {
+ this.seq2Callback = seq2Callback;
+ }
- public ThreadPoolTaskExecutor getThreadPool() {
- return threadPool;
- }
+ public ThreadPoolTaskExecutor getThreadPool() {
+ return threadPool;
+ }
- public void setThreadPool(ThreadPoolTaskExecutor threadPool) {
- this.threadPool = threadPool;
- }
+ public void setThreadPool(ThreadPoolTaskExecutor threadPool) {
+ this.threadPool = threadPool;
+ }
- public int getGroupId() {
- return groupId;
- }
+ public int getGroupId() {
+ return groupId;
+ }
- public void setGroupId(int groupId) {
- this.groupId = groupId;
- }
+ public void setGroupId(int groupId) {
+ this.groupId = groupId;
+ }
- public BigInteger getNumber() {
- return number;
- }
+ public BigInteger getNumber() {
+ return number;
+ }
- public void setNumber(BigInteger number) {
- this.number = number;
- }
+ public void setNumber(BigInteger number) {
+ this.number = number;
+ }
}
diff --git a/src/main/java/org/fisco/bcos/channel/client/TransactionSucCallback.java b/src/main/java/org/fisco/bcos/channel/client/TransactionSucCallback.java
index 3ddc55277..2734c783f 100644
--- a/src/main/java/org/fisco/bcos/channel/client/TransactionSucCallback.java
+++ b/src/main/java/org/fisco/bcos/channel/client/TransactionSucCallback.java
@@ -7,25 +7,25 @@
/** Created by suyuhui on 17/8/17. */
public abstract class TransactionSucCallback {
- private static Logger logger = LoggerFactory.getLogger(TransactionSucCallback.class);
+ private static Logger logger = LoggerFactory.getLogger(TransactionSucCallback.class);
- public abstract void onResponse(TransactionReceipt response);
+ public abstract void onResponse(TransactionReceipt response);
- public void onTimeout() {
- logger.error("transactionSuc timeout");
+ public void onTimeout() {
+ logger.error("transactionSuc timeout");
- TransactionReceipt receipt = new TransactionReceipt();
- receipt.setStatus("Receipt timeout");
- onResponse(receipt);
- }
+ TransactionReceipt receipt = new TransactionReceipt();
+ receipt.setStatus("Transaction receipt timeout.");
+ onResponse(receipt);
+ }
- public Timeout getTimeout() {
- return timeout;
- }
+ public Timeout getTimeout() {
+ return timeout;
+ }
- public void setTimeout(Timeout timeout) {
- this.timeout = timeout;
- }
+ public void setTimeout(Timeout timeout) {
+ this.timeout = timeout;
+ }
- private Timeout timeout;
+ private Timeout timeout;
}
diff --git a/src/main/java/org/fisco/bcos/channel/dto/BcosMessage.java b/src/main/java/org/fisco/bcos/channel/dto/BcosMessage.java
new file mode 100644
index 000000000..d9f1d58fa
--- /dev/null
+++ b/src/main/java/org/fisco/bcos/channel/dto/BcosMessage.java
@@ -0,0 +1,28 @@
+package org.fisco.bcos.channel.dto;
+
+import io.netty.buffer.ByteBuf;
+import org.fisco.bcos.channel.handler.Message;
+
+public class BcosMessage extends Message {
+ private static final long serialVersionUID = 3763237749437810546L;
+
+ public BcosMessage() {}
+
+ public BcosMessage(Message msg) {
+ length = msg.getLength();
+ type = msg.getType();
+ seq = msg.getSeq();
+ result = msg.getResult();
+ }
+
+ @Override
+ public void readExtra(ByteBuf in) {
+ data = new byte[length - Message.HEADER_LENGTH];
+ in.readBytes(data, 0, length - Message.HEADER_LENGTH);
+ }
+
+ @Override
+ public void writeExtra(ByteBuf out) {
+ out.writeBytes(data);
+ }
+}
diff --git a/src/main/java/org/fisco/bcos/channel/dto/BcosRequest.java b/src/main/java/org/fisco/bcos/channel/dto/BcosRequest.java
new file mode 100644
index 000000000..062ceefe0
--- /dev/null
+++ b/src/main/java/org/fisco/bcos/channel/dto/BcosRequest.java
@@ -0,0 +1,78 @@
+package org.fisco.bcos.channel.dto;
+
+public class BcosRequest {
+ private String keyID; // chain ID
+ private String orgApp; // org identification
+ private String version;
+ private String bankNO; // institution identification
+ private String appName; // application kinds
+
+ private String messageID;
+ private Integer timeout = 0; // ms
+
+ private String content;
+
+ public String getKeyID() {
+ return keyID;
+ }
+
+ public void setKeyID(String keyID) {
+ this.keyID = keyID;
+ }
+
+ public String getOrgApp() {
+ return orgApp;
+ }
+
+ public void setOrgApp(String orgApp) {
+ this.orgApp = orgApp;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public String getBankNO() {
+ return bankNO;
+ }
+
+ public void setBankNO(String bankNO) {
+ this.bankNO = bankNO;
+ }
+
+ public String getAppName() {
+ return appName;
+ }
+
+ public void setAppName(String appName) {
+ this.appName = appName;
+ }
+
+ public String getMessageID() {
+ return messageID;
+ }
+
+ public void setMessageID(String messageID) {
+ this.messageID = messageID;
+ }
+
+ public Integer getTimeout() {
+ return timeout;
+ }
+
+ public void setTimeout(Integer timeout) {
+ this.timeout = timeout;
+ }
+
+ public String getContent() {
+ return content;
+ }
+
+ public void setContent(String content) {
+ this.content = content;
+ }
+}
diff --git a/src/main/java/org/fisco/bcos/channel/dto/FiscoResponse.java b/src/main/java/org/fisco/bcos/channel/dto/BcosResponse.java
similarity index 96%
rename from src/main/java/org/fisco/bcos/channel/dto/FiscoResponse.java
rename to src/main/java/org/fisco/bcos/channel/dto/BcosResponse.java
index 9e3a7896a..d0029a672 100644
--- a/src/main/java/org/fisco/bcos/channel/dto/FiscoResponse.java
+++ b/src/main/java/org/fisco/bcos/channel/dto/BcosResponse.java
@@ -1,6 +1,6 @@
package org.fisco.bcos.channel.dto;
-public class FiscoResponse {
+public class BcosResponse {
private Integer errorCode;
private String errorMessage;
@@ -38,5 +38,4 @@ public String getContent() {
public void setContent(String content) {
this.content = content;
}
-
}
diff --git a/src/main/java/org/fisco/bcos/channel/dto/ChannelMessage.java b/src/main/java/org/fisco/bcos/channel/dto/ChannelMessage.java
index 1bb0642be..065f31a56 100644
--- a/src/main/java/org/fisco/bcos/channel/dto/ChannelMessage.java
+++ b/src/main/java/org/fisco/bcos/channel/dto/ChannelMessage.java
@@ -6,71 +6,71 @@
import org.slf4j.LoggerFactory;
public class ChannelMessage extends Message {
- private static Logger logger = LoggerFactory.getLogger(ChannelMessage.class);
-
- private static final long serialVersionUID = -7276897518418560354L;
-
- public ChannelMessage() {}
-
- public ChannelMessage(Message msg) {
- length = msg.getLength();
- type = msg.getType();
- seq = msg.getSeq();
- result = msg.getResult();
- }
-
- @Override
- public void readExtra(ByteBuf in) {
- logger.debug("readExtra channel package: {}", result);
- if (result == 0) {
- byte[] toNodeBytes = new byte[128];
- in.readBytes(toNodeBytes, 0, 128);
- toNode = new String(toNodeBytes);
- logger.debug("toNode: {}", toNode);
-
- byte[] fromNodeBytes = new byte[128];
- in.readBytes(fromNodeBytes, 0, 128);
- fromNode = new String(fromNodeBytes);
- logger.debug("fromNode: {}", fromNode);
-
- data = new byte[length - Message.HEADER_LENGTH - 128 - 128];
- in.readBytes(data, 0, length - Message.HEADER_LENGTH - 128 - 128);
- logger.debug("data: {} {}", data.length, data);
+ private static Logger logger = LoggerFactory.getLogger(ChannelMessage.class);
+
+ private static final long serialVersionUID = -7276897518418560354L;
+
+ public ChannelMessage() {}
+
+ public ChannelMessage(Message msg) {
+ length = msg.getLength();
+ type = msg.getType();
+ seq = msg.getSeq();
+ result = msg.getResult();
}
- }
- @Override
- public void writeHeader(ByteBuf out) {
- // 先计算总长度
- length = Message.HEADER_LENGTH + toNode.length() + fromNode.length() + data.length;
+ @Override
+ public void readExtra(ByteBuf in) {
+ logger.debug("readExtra channel package: {}", result);
+ if (result == 0) {
+ byte[] toNodeBytes = new byte[128];
+ in.readBytes(toNodeBytes, 0, 128);
+ toNode = new String(toNodeBytes);
+ logger.debug("toNode: {}", toNode);
+
+ byte[] fromNodeBytes = new byte[128];
+ in.readBytes(fromNodeBytes, 0, 128);
+ fromNode = new String(fromNodeBytes);
+ logger.debug("fromNode: {}", fromNode);
+
+ data = new byte[length - Message.HEADER_LENGTH - 128 - 128];
+ in.readBytes(data, 0, length - Message.HEADER_LENGTH - 128 - 128);
+ logger.debug("data: {} {}", data.length, data);
+ }
+ }
- super.writeHeader(out);
- }
+ @Override
+ public void writeHeader(ByteBuf out) {
+ // 先计算总长度
+ length = Message.HEADER_LENGTH + toNode.length() + fromNode.length() + data.length;
- @Override
- public void writeExtra(ByteBuf out) {
- out.writeBytes(toNode.getBytes());
- out.writeBytes(fromNode.getBytes());
+ super.writeHeader(out);
+ }
- out.writeBytes(data);
- }
+ @Override
+ public void writeExtra(ByteBuf out) {
+ out.writeBytes(toNode.getBytes());
+ out.writeBytes(fromNode.getBytes());
- public String getToNode() {
- return toNode;
- }
+ out.writeBytes(data);
+ }
- public void setToNode(String toNode) {
- this.toNode = toNode;
- }
+ public String getToNode() {
+ return toNode;
+ }
- public String getFromNode() {
- return fromNode;
- }
+ public void setToNode(String toNode) {
+ this.toNode = toNode;
+ }
- public void setFromNode(String fromNode) {
- this.fromNode = fromNode;
- }
+ public String getFromNode() {
+ return fromNode;
+ }
+
+ public void setFromNode(String fromNode) {
+ this.fromNode = fromNode;
+ }
- private String toNode;
- private String fromNode;
+ private String toNode;
+ private String fromNode;
}
diff --git a/src/main/java/org/fisco/bcos/channel/dto/ChannelMessage2.java b/src/main/java/org/fisco/bcos/channel/dto/ChannelMessage2.java
index b69362915..de9a8f4e5 100644
--- a/src/main/java/org/fisco/bcos/channel/dto/ChannelMessage2.java
+++ b/src/main/java/org/fisco/bcos/channel/dto/ChannelMessage2.java
@@ -6,58 +6,56 @@
import org.slf4j.LoggerFactory;
public class ChannelMessage2 extends Message {
- private static Logger logger = LoggerFactory.getLogger(ChannelMessage2.class);
+ private static Logger logger = LoggerFactory.getLogger(ChannelMessage2.class);
- private static final long serialVersionUID = -7276897518418560354L;
+ private static final long serialVersionUID = -7276897518418560354L;
- public ChannelMessage2() {}
+ public ChannelMessage2() {}
- public ChannelMessage2(Message msg) {
- length = msg.getLength();
- type = msg.getType();
- seq = msg.getSeq();
- result = msg.getResult();
- }
+ public ChannelMessage2(Message msg) {
+ length = msg.getLength();
+ type = msg.getType();
+ seq = msg.getSeq();
+ result = msg.getResult();
+ }
- @Override
- public void readExtra(ByteBuf in) {
- logger.debug("readExtra channel2 package: {}", result);
- if (result == 0) {
- Short topicLength = in.readUnsignedByte();
+ @Override
+ public void readExtra(ByteBuf in) {
+ if (result == 0) {
+ Short topicLength = in.readUnsignedByte();
- byte[] topicBytes = new byte[topicLength - 1];
- in.readBytes(topicBytes, 0, topicLength - 1);
- topic = new String(topicBytes);
+ byte[] topicBytes = new byte[topicLength - 1];
+ in.readBytes(topicBytes, 0, topicLength - 1);
+ topic = new String(topicBytes);
- data = new byte[length - Message.HEADER_LENGTH - topicLength];
- in.readBytes(data, 0, length - Message.HEADER_LENGTH - topicLength);
- logger.debug("data: {} {}", data.length, data);
+ data = new byte[length - Message.HEADER_LENGTH - topicLength];
+ in.readBytes(data, 0, length - Message.HEADER_LENGTH - topicLength);
+ }
}
- }
- @Override
- public void writeHeader(ByteBuf out) {
- // 先计算总长度
- length = Message.HEADER_LENGTH + 1 + topic.length() + data.length;
+ @Override
+ public void writeHeader(ByteBuf out) {
+ // total length
+ length = Message.HEADER_LENGTH + 1 + topic.length() + data.length;
- super.writeHeader(out);
- }
+ super.writeHeader(out);
+ }
- @Override
- public void writeExtra(ByteBuf out) {
- out.writeByte(1 + topic.length());
- out.writeBytes(topic.getBytes());
+ @Override
+ public void writeExtra(ByteBuf out) {
+ out.writeByte(1 + topic.length());
+ out.writeBytes(topic.getBytes());
- out.writeBytes(data);
- }
+ out.writeBytes(data);
+ }
- public String getTopic() {
- return topic;
- }
+ public String getTopic() {
+ return topic;
+ }
- public void setTopic(String toTopic) {
- this.topic = toTopic;
- }
+ public void setTopic(String toTopic) {
+ this.topic = toTopic;
+ }
- private String topic;
+ private String topic;
}
diff --git a/src/main/java/org/fisco/bcos/channel/dto/ChannelPush.java b/src/main/java/org/fisco/bcos/channel/dto/ChannelPush.java
index f6edfa816..f56749784 100644
--- a/src/main/java/org/fisco/bcos/channel/dto/ChannelPush.java
+++ b/src/main/java/org/fisco/bcos/channel/dto/ChannelPush.java
@@ -7,164 +7,164 @@
import org.slf4j.LoggerFactory;
public class ChannelPush {
- static Logger logger = LoggerFactory.getLogger(ChannelPush.class);
+ static Logger logger = LoggerFactory.getLogger(ChannelPush.class);
- public String getKeyID() {
- return keyID;
- }
+ public String getKeyID() {
+ return keyID;
+ }
- public void setKeyID(String keyID) {
- this.keyID = keyID;
- }
+ public void setKeyID(String keyID) {
+ this.keyID = keyID;
+ }
- public String getOrgApp() {
- return orgApp;
- }
+ public String getOrgApp() {
+ return orgApp;
+ }
- public void setOrgApp(String orgApp) {
- this.orgApp = orgApp;
- }
+ public void setOrgApp(String orgApp) {
+ this.orgApp = orgApp;
+ }
- public String getVersion() {
- return version;
- }
+ public String getVersion() {
+ return version;
+ }
- public void setVersion(String version) {
- this.version = version;
- }
+ public void setVersion(String version) {
+ this.version = version;
+ }
- public String getBankNO() {
- return bankNO;
- }
+ public String getBankNO() {
+ return bankNO;
+ }
- public void setBankNO(String bankNO) {
- this.bankNO = bankNO;
- }
+ public void setBankNO(String bankNO) {
+ this.bankNO = bankNO;
+ }
- public String getAppName() {
- return appName;
- }
+ public String getAppName() {
+ return appName;
+ }
- public void setAppName(String appName) {
- this.appName = appName;
- }
+ public void setAppName(String appName) {
+ this.appName = appName;
+ }
- public String getMessageID() {
- return messageID;
- }
+ public String getMessageID() {
+ return messageID;
+ }
- public void setMessageID(String messageID) {
- this.messageID = messageID;
- }
+ public void setMessageID(String messageID) {
+ this.messageID = messageID;
+ }
- public String getToOrg() {
- return toOrg;
- }
+ public String getToOrg() {
+ return toOrg;
+ }
- public void setToOrg(String toOrg) {
- this.toOrg = toOrg;
- }
+ public void setToOrg(String toOrg) {
+ this.toOrg = toOrg;
+ }
- public Integer getTimeout() {
- return timeout;
- }
+ public Integer getTimeout() {
+ return timeout;
+ }
- public void setTimeout(Integer timeout) {
- this.timeout = timeout;
- }
+ public void setTimeout(Integer timeout) {
+ this.timeout = timeout;
+ }
- public Integer getTtl() {
- return ttl;
- }
+ public Integer getTtl() {
+ return ttl;
+ }
- public void setTtl(Integer ttl) {
- this.ttl = ttl;
- }
+ public void setTtl(Integer ttl) {
+ this.ttl = ttl;
+ }
- public String getContent() {
- return content;
- }
+ public String getContent() {
+ return content;
+ }
- public void setContent(String content) {
- this.content = content;
- }
+ public void setContent(String content) {
+ this.content = content;
+ }
- public void sendResponse(ChannelResponse response) {
- logger.debug("send ChannelResponse seq:{}", response.getMessageID());
+ public void sendResponse(ChannelResponse response) {
+ logger.debug("send ChannelResponse seq:{}", response.getMessageID());
- response.setMessageID(seq);
+ response.setMessageID(seq);
- service.sendResponseMessage(response, info, ctx, fromNode, toNode, seq);
- }
+ service.sendResponseMessage(response, info, ctx, fromNode, toNode, seq);
+ }
- private String keyID; // 链ID
- private String orgApp; // 来源标识
- private String version; // 版本
- private String bankNO; // 机构标识
- private String appName; // 应用类型
+ private String keyID; // 链ID
+ private String orgApp; // 来源标识
+ private String version; // 版本
+ private String bankNO; // 机构标识
+ private String appName; // 应用类型
- private String messageID; // 消息的唯一标识id
- private String toOrg; // 目标机构标识
+ private String messageID; // 消息的唯一标识id
+ private String toOrg; // 目标机构标识
- private Integer timeout; // 超时时间(毫秒)
- private Integer ttl; // TTL
+ private Integer timeout; // 超时时间(毫秒)
+ private Integer ttl; // TTL
- private String content; // 请求包体
+ private String content; // 请求包体
- // 回包用字段
+ // 回包用字段
- public Service getService() {
- return service;
- }
+ public Service getService() {
+ return service;
+ }
- public void setService(Service service) {
- this.service = service;
- }
+ public void setService(Service service) {
+ this.service = service;
+ }
- public ConnectionInfo getInfo() {
- return info;
- }
+ public ConnectionInfo getInfo() {
+ return info;
+ }
- public void setInfo(ConnectionInfo info) {
- this.info = info;
- }
+ public void setInfo(ConnectionInfo info) {
+ this.info = info;
+ }
- public ChannelHandlerContext getCtx() {
- return ctx;
- }
+ public ChannelHandlerContext getCtx() {
+ return ctx;
+ }
- public void setCtx(ChannelHandlerContext ctx) {
- this.ctx = ctx;
- }
+ public void setCtx(ChannelHandlerContext ctx) {
+ this.ctx = ctx;
+ }
- public String getFromNode() {
- return fromNode;
- }
+ public String getFromNode() {
+ return fromNode;
+ }
- public void setFromNode(String fromNode) {
- this.fromNode = fromNode;
- }
+ public void setFromNode(String fromNode) {
+ this.fromNode = fromNode;
+ }
- public String getToNode() {
- return toNode;
- }
+ public String getToNode() {
+ return toNode;
+ }
- public void setToNode(String toNode) {
- this.toNode = toNode;
- }
+ public void setToNode(String toNode) {
+ this.toNode = toNode;
+ }
- public String getSeq() {
- return seq;
- }
+ public String getSeq() {
+ return seq;
+ }
- public void setSeq(String seq) {
- this.seq = seq;
- }
+ public void setSeq(String seq) {
+ this.seq = seq;
+ }
- private Service service;
- private ConnectionInfo info;
- private ChannelHandlerContext ctx;
- private String fromNode;
- private String toNode;
- private String seq;
+ private Service service;
+ private ConnectionInfo info;
+ private ChannelHandlerContext ctx;
+ private String fromNode;
+ private String toNode;
+ private String seq;
}
diff --git a/src/main/java/org/fisco/bcos/channel/dto/ChannelPush2.java b/src/main/java/org/fisco/bcos/channel/dto/ChannelPush2.java
index cacfa43ad..82f5eac66 100644
--- a/src/main/java/org/fisco/bcos/channel/dto/ChannelPush2.java
+++ b/src/main/java/org/fisco/bcos/channel/dto/ChannelPush2.java
@@ -6,62 +6,62 @@
import org.slf4j.LoggerFactory;
public class ChannelPush2 extends ChannelPush {
- static Logger logger = LoggerFactory.getLogger(ChannelPush2.class);
+ static Logger logger = LoggerFactory.getLogger(ChannelPush2.class);
- public String getContent() {
- return content;
- }
+ public String getContent() {
+ return content;
+ }
- public void setContent(String content) {
- this.content = content;
- }
+ public void setContent(String content) {
+ this.content = content;
+ }
- public String getTopic() {
- return topic;
- }
+ public String getTopic() {
+ return topic;
+ }
- public void setTopic(String topic) {
- this.topic = topic;
- }
+ public void setTopic(String topic) {
+ this.topic = topic;
+ }
- public void sendResponse(ChannelResponse response) {
- logger.debug("send ChannelResponse seq:{}", response.getMessageID());
+ public void sendResponse(ChannelResponse response) {
+ logger.debug("send ChannelResponse seq:{}", response.getMessageID());
- response.setMessageID(seq);
+ response.setMessageID(seq);
- service.sendResponseMessage2(response, ctx, seq, topic);
- }
+ service.sendResponseMessage2(response, ctx, seq, topic);
+ }
- private String content; // 请求包体
- private String topic;
+ private String content; // 请求包体
+ private String topic;
- // 回包用字段
+ // 回包用字段
- public Service getService() {
- return service;
- }
+ public Service getService() {
+ return service;
+ }
- public void setService(Service service) {
- this.service = service;
- }
+ public void setService(Service service) {
+ this.service = service;
+ }
- public ChannelHandlerContext getCtx() {
- return ctx;
- }
+ public ChannelHandlerContext getCtx() {
+ return ctx;
+ }
- public void setCtx(ChannelHandlerContext ctx) {
- this.ctx = ctx;
- }
+ public void setCtx(ChannelHandlerContext ctx) {
+ this.ctx = ctx;
+ }
- public String getSeq() {
- return seq;
- }
+ public String getSeq() {
+ return seq;
+ }
- public void setSeq(String seq) {
- this.seq = seq;
- }
+ public void setSeq(String seq) {
+ this.seq = seq;
+ }
- private Service service;
- private ChannelHandlerContext ctx;
- private String seq;
+ private Service service;
+ private ChannelHandlerContext ctx;
+ private String seq;
}
diff --git a/src/main/java/org/fisco/bcos/channel/dto/ChannelRequest.java b/src/main/java/org/fisco/bcos/channel/dto/ChannelRequest.java
index a7e997846..168fd767f 100644
--- a/src/main/java/org/fisco/bcos/channel/dto/ChannelRequest.java
+++ b/src/main/java/org/fisco/bcos/channel/dto/ChannelRequest.java
@@ -2,106 +2,106 @@
public class ChannelRequest {
- public String getFromOrg() {
- return fromOrg;
- }
+ public String getFromOrg() {
+ return fromOrg;
+ }
- public void setFromOrg(String keyID) {
- this.fromOrg = keyID;
- }
+ public void setFromOrg(String keyID) {
+ this.fromOrg = keyID;
+ }
- public String getOrgApp() {
- return orgApp;
- }
+ public String getOrgApp() {
+ return orgApp;
+ }
- public void setOrgApp(String orgApp) {
- this.orgApp = orgApp;
- }
+ public void setOrgApp(String orgApp) {
+ this.orgApp = orgApp;
+ }
- public String getVersion() {
- return version;
- }
+ public String getVersion() {
+ return version;
+ }
- public void setVersion(String version) {
- this.version = version;
- }
+ public void setVersion(String version) {
+ this.version = version;
+ }
- public String getBankNO() {
- return bankNO;
- }
+ public String getBankNO() {
+ return bankNO;
+ }
- public void setBankNO(String bankNO) {
- this.bankNO = bankNO;
- }
+ public void setBankNO(String bankNO) {
+ this.bankNO = bankNO;
+ }
- public String getAppName() {
- return appName;
- }
+ public String getAppName() {
+ return appName;
+ }
- public void setAppName(String appName) {
- this.appName = appName;
- }
+ public void setAppName(String appName) {
+ this.appName = appName;
+ }
- public String getMessageID() {
- return messageID;
- }
+ public String getMessageID() {
+ return messageID;
+ }
- public void setMessageID(String messageID) {
- this.messageID = messageID;
- }
+ public void setMessageID(String messageID) {
+ this.messageID = messageID;
+ }
- public String getToOrg() {
- return toOrg;
- }
+ public String getToOrg() {
+ return toOrg;
+ }
- public void setToOrg(String toOrg) {
- this.toOrg = toOrg;
- }
+ public void setToOrg(String toOrg) {
+ this.toOrg = toOrg;
+ }
- public String getToTopic() {
- return toTopic;
- }
+ public String getToTopic() {
+ return toTopic;
+ }
- public void setToTopic(String toTopic) {
- this.toTopic = toTopic;
- }
+ public void setToTopic(String toTopic) {
+ this.toTopic = toTopic;
+ }
- public Integer getTimeout() {
- return timeout;
- }
+ public Integer getTimeout() {
+ return timeout;
+ }
- public void setTimeout(Integer timeout) {
- this.timeout = timeout;
- }
+ public void setTimeout(Integer timeout) {
+ this.timeout = timeout;
+ }
- public Integer getTtl() {
- return ttl;
- }
+ public Integer getTtl() {
+ return ttl;
+ }
- public void setTtl(Integer ttl) {
- this.ttl = ttl;
- }
+ public void setTtl(Integer ttl) {
+ this.ttl = ttl;
+ }
- public String getContent() {
- return content;
- }
+ public String getContent() {
+ return content;
+ }
- public void setContent(String content) {
- this.content = content;
- }
+ public void setContent(String content) {
+ this.content = content;
+ }
- private String fromOrg; // 链ID
- private String orgApp; // 来源标识
- private String version; // 版本
- private String bankNO; // 机构标识
- private String appName; // 应用类型
+ private String fromOrg; // 链ID
+ private String orgApp; // 来源标识
+ private String version; // 版本
+ private String bankNO; // 机构标识
+ private String appName; // 应用类型
- private String messageID; // 消息的唯一标识id
- private String toOrg; // 目标机构标识
- private String toTopic; // 目标topic
+ private String messageID; // 消息的唯一标识id
+ private String toOrg; // 目标机构标识
+ private String toTopic; // 目标topic
- private Integer timeout = 0; // 超时时间(毫秒)
- private Integer ttl; // TTL 限制重试的次数
+ private Integer timeout = 0; // 超时时间(毫秒)
+ private Integer ttl; // TTL 限制重试的次数
- private String content; // 请求包体
+ private String content; // 请求包体
}
diff --git a/src/main/java/org/fisco/bcos/channel/dto/ChannelResponse.java b/src/main/java/org/fisco/bcos/channel/dto/ChannelResponse.java
index d16b024a7..8af065342 100644
--- a/src/main/java/org/fisco/bcos/channel/dto/ChannelResponse.java
+++ b/src/main/java/org/fisco/bcos/channel/dto/ChannelResponse.java
@@ -1,42 +1,42 @@
package org.fisco.bcos.channel.dto;
public class ChannelResponse {
- public Integer getErrorCode() {
- return errorCode;
- }
+ public Integer getErrorCode() {
+ return errorCode;
+ }
- public void setErrorCode(Integer errorCode) {
- this.errorCode = errorCode;
- }
+ public void setErrorCode(Integer errorCode) {
+ this.errorCode = errorCode;
+ }
- public String getErrorMessage() {
- return errorMessage;
- }
+ public String getErrorMessage() {
+ return errorMessage;
+ }
- public void setErrorMessage(String errorMessage) {
- this.errorMessage = errorMessage;
- }
+ public void setErrorMessage(String errorMessage) {
+ this.errorMessage = errorMessage;
+ }
- public String getMessageID() {
- return messageID;
- }
+ public String getMessageID() {
+ return messageID;
+ }
- public void setMessageID(String messageID) {
- this.messageID = messageID;
- }
+ public void setMessageID(String messageID) {
+ this.messageID = messageID;
+ }
- public String getContent() {
- return content;
- }
+ public String getContent() {
+ return content;
+ }
- public void setContent(String content) {
- this.content = content;
- }
+ public void setContent(String content) {
+ this.content = content;
+ }
- private Integer errorCode; // 错误码
- private String errorMessage; // 错误信息
+ private Integer errorCode; // 错误码
+ private String errorMessage; // 错误信息
- private String messageID; // 消息唯一ID
+ private String messageID; // 消息唯一ID
- private String content; // 响应包体
+ private String content; // 响应包体
}
diff --git a/src/main/java/org/fisco/bcos/channel/dto/FiscoMessage.java b/src/main/java/org/fisco/bcos/channel/dto/FiscoMessage.java
deleted file mode 100644
index 9c6ee0dbb..000000000
--- a/src/main/java/org/fisco/bcos/channel/dto/FiscoMessage.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package org.fisco.bcos.channel.dto;
-
-import io.netty.buffer.ByteBuf;
-import org.fisco.bcos.channel.handler.Message;
-
-public class FiscoMessage extends Message {
- private static final long serialVersionUID = 3763237749437810546L;
-
- public FiscoMessage() {}
-
- public FiscoMessage(Message msg) {
- length = msg.getLength();
- type = msg.getType();
- seq = msg.getSeq();
- result = msg.getResult();
- }
-
- @Override
- public void readExtra(ByteBuf in) {
- data = new byte[length - Message.HEADER_LENGTH];
- in.readBytes(data, 0, length - Message.HEADER_LENGTH);
- }
-
- @Override
- public void writeExtra(ByteBuf out) {
- out.writeBytes(data);
- }
-}
diff --git a/src/main/java/org/fisco/bcos/channel/dto/FiscoRequest.java b/src/main/java/org/fisco/bcos/channel/dto/FiscoRequest.java
deleted file mode 100644
index 93c38ddea..000000000
--- a/src/main/java/org/fisco/bcos/channel/dto/FiscoRequest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package org.fisco.bcos.channel.dto;
-
-public class FiscoRequest {
- private String keyID; // chain ID
- private String orgApp; // org identification
- private String version;
- private String bankNO; // institution identification
- private String appName; // application kinds
-
- private String messageID;
- private Integer timeout = 0; // ms
-
- private String content;
-
- public String getKeyID() {
- return keyID;
- }
-
- public void setKeyID(String keyID) {
- this.keyID = keyID;
- }
-
- public String getOrgApp() {
- return orgApp;
- }
-
- public void setOrgApp(String orgApp) {
- this.orgApp = orgApp;
- }
-
- public String getVersion() {
- return version;
- }
-
- public void setVersion(String version) {
- this.version = version;
- }
-
- public String getBankNO() {
- return bankNO;
- }
-
- public void setBankNO(String bankNO) {
- this.bankNO = bankNO;
- }
-
- public String getAppName() {
- return appName;
- }
-
- public void setAppName(String appName) {
- this.appName = appName;
- }
-
- public String getMessageID() {
- return messageID;
- }
-
- public void setMessageID(String messageID) {
- this.messageID = messageID;
- }
-
- public Integer getTimeout() {
- return timeout;
- }
-
- public void setTimeout(Integer timeout) {
- this.timeout = timeout;
- }
-
- public String getContent() {
- return content;
- }
-
- public void setContent(String content) {
- this.content = content;
- }
-
-
-}
diff --git a/src/main/java/org/fisco/bcos/channel/handler/ChannelConnections.java b/src/main/java/org/fisco/bcos/channel/handler/ChannelConnections.java
index 32aad6898..bcc204ef9 100644
--- a/src/main/java/org/fisco/bcos/channel/handler/ChannelConnections.java
+++ b/src/main/java/org/fisco/bcos/channel/handler/ChannelConnections.java
@@ -3,7 +3,11 @@
import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
-import io.netty.channel.*;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
@@ -17,11 +21,18 @@
import io.netty.handler.timeout.IdleStateHandler;
import java.io.InputStream;
import java.security.SecureRandom;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import java.util.Map.Entry;
+import java.util.Optional;
+import java.util.Random;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLException;
-import org.fisco.bcos.channel.dto.FiscoMessage;
+import org.fisco.bcos.channel.dto.BcosMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
@@ -30,380 +41,435 @@
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
public class ChannelConnections {
- private static Logger logger = LoggerFactory.getLogger(ChannelConnections.class);
-
- private Callback callback;
- private List connectionsStr;
- private String caCertPath = "classpath:ca.crt";
- private String nodeCaPath = "classpath:node.crt";
- private String nodeKeyPath = "classpath:node.key";
- private List connections = new ArrayList();
- private Boolean running = false;
- private ThreadPoolTaskExecutor threadPool;
- private long idleTimeout = (long) 10000;
- private long heartBeatDelay = (long) 2000;
- public Map networkConnections = new HashMap();
- private int groupId;
- private Bootstrap bootstrap = new Bootstrap();
- ServerBootstrap serverBootstrap = new ServerBootstrap();
-
- public int getGroupId() {
- return groupId;
- }
-
- public void setGroupId(int groupId) {
- this.groupId = groupId;
- }
-
- public String getNodeCaPath() {
- return nodeCaPath;
- }
-
- public void setNodeCaPath(String nodeCaPath) {
- this.nodeCaPath = nodeCaPath;
- }
-
- public String getNodeKeyPath() {
- return nodeKeyPath;
- }
-
- public void setNodeKeyPath(String nodeKeyPath) {
- this.nodeKeyPath = nodeKeyPath;
- }
-
- public interface Callback {
- void onConnect(ChannelHandlerContext ctx);
-
- void onDisconnect(ChannelHandlerContext ctx);
-
- void onMessage(ChannelHandlerContext ctx, ByteBuf message);
- }
-
- public Callback getCallback() {
- return callback;
- }
+ private static Logger logger = LoggerFactory.getLogger(ChannelConnections.class);
+
+ private Callback callback;
+ private List connectionsStr;
+ private String caCertPath = "classpath:ca.crt";
+ private String nodeCaPath = "classpath:node.crt";
+ private String nodeKeyPath = "classpath:node.key";
+ private List connections = new ArrayList();
+ private Boolean running = false;
+ private ThreadPoolTaskExecutor threadPool;
+ private long idleTimeout = (long) 10000;
+ private long heartBeatDelay = (long) 2000;
+ public Map networkConnections =
+ new HashMap();
+ private int groupId;
+ private Bootstrap bootstrap = new Bootstrap();
+ ServerBootstrap serverBootstrap = new ServerBootstrap();
+
+ public int getGroupId() {
+ return groupId;
+ }
- public void setCallback(Callback callback) {
- this.callback = callback;
- }
+ public void setGroupId(int groupId) {
+ this.groupId = groupId;
+ }
- public List getConnectionsStr() {
- return connectionsStr;
- }
+ public String getNodeCaPath() {
+ return nodeCaPath;
+ }
- public void setConnectionsStr(List connectionsStr) {
- this.connectionsStr = connectionsStr;
- }
+ public void setNodeCaPath(String nodeCaPath) {
+ this.nodeCaPath = nodeCaPath;
+ }
- public List getConnections() {
- return connections;
- }
+ public String getNodeKeyPath() {
+ return nodeKeyPath;
+ }
- public void setConnections(List connections) {
- this.connections = connections;
- }
+ public void setNodeKeyPath(String nodeKeyPath) {
+ this.nodeKeyPath = nodeKeyPath;
+ }
- public ThreadPoolTaskExecutor getThreadPool() {
- return threadPool;
- }
+ public interface Callback {
+ void onConnect(ChannelHandlerContext ctx);
- public void setThreadPool(ThreadPoolTaskExecutor threadPool) {
- this.threadPool = threadPool;
- }
+ void onDisconnect(ChannelHandlerContext ctx);
- public long getIdleTimeout() {
- return idleTimeout;
- }
+ void onMessage(ChannelHandlerContext ctx, ByteBuf message);
+ }
- public void setIdleTimeout(long idleTimeout) {
- this.idleTimeout = idleTimeout;
- }
+ public Callback getCallback() {
+ return callback;
+ }
- public long getHeartBeatDelay() {
- return heartBeatDelay;
- }
+ public void setCallback(Callback callback) {
+ this.callback = callback;
+ }
- public void setHeartBeatDelay(long heartBeatDelay) {
- this.heartBeatDelay = heartBeatDelay;
- }
+ public List getConnectionsStr() {
+ return connectionsStr;
+ }
- public String getCaCertPath() {
- return caCertPath;
- }
-
- public void setCaCertPath(String caCertPath) {
- this.caCertPath = caCertPath;
- }
-
- public ChannelHandlerContext randomNetworkConnection() throws Exception {
- List activeConnections = new ArrayList();
+ public void setConnectionsStr(List connectionsStr) {
+ this.connectionsStr = connectionsStr;
+ }
- for (String key : networkConnections.keySet()) {
- if (networkConnections.get(key) != null && networkConnections.get(key).channel().isActive()) {
- activeConnections.add(networkConnections.get(key));
- }
+ public List getConnections() {
+ return connections;
}
- if (activeConnections.isEmpty()) {
- logger.error("activeConnections isEmpty");
- throw new Exception("activeConnections isEmpty");
+ public void setConnections(List connections) {
+ this.connections = connections;
}
- Random random = new SecureRandom();
- Integer index = random.nextInt(activeConnections.size());
+ public ThreadPoolTaskExecutor getThreadPool() {
+ return threadPool;
+ }
- logger.debug("selected:{}", index);
+ public void setThreadPool(ThreadPoolTaskExecutor threadPool) {
+ this.threadPool = threadPool;
+ }
- return activeConnections.get(index);
- }
+ public long getIdleTimeout() {
+ return idleTimeout;
+ }
- public ConnectionInfo getConnectionInfo(String host, Integer port) {
- for (ConnectionInfo info : connections) {
- if (info.getHost().equals(host) && info.getPort().equals(port)) {
- return info;
- }
+ public void setIdleTimeout(long idleTimeout) {
+ this.idleTimeout = idleTimeout;
}
- return null;
- }
+ public long getHeartBeatDelay() {
+ return heartBeatDelay;
+ }
- public Map getNetworkConnections() {
- return networkConnections;
- }
+ public void setHeartBeatDelay(long heartBeatDelay) {
+ this.heartBeatDelay = heartBeatDelay;
+ }
- public ChannelHandlerContext getNetworkConnectionByHost(String host, Integer port) {
- String endpoint = host + ":" + port;
+ public String getCaCertPath() {
+ return caCertPath;
+ }
- return networkConnections.get(endpoint);
- }
+ public void setCaCertPath(String caCertPath) {
+ this.caCertPath = caCertPath;
+ }
- public void setNetworkConnectionByHost(String host, Integer port, ChannelHandlerContext ctx) {
- String endpoint = host + ":" + port;
+ public ChannelHandlerContext randomNetworkConnection(
+ ConcurrentHashMap nodeToBlockNumberMap) throws Exception {
+ List activeConnections = new ArrayList();
- networkConnections.put(endpoint, ctx);
- }
+ for (String key : networkConnections.keySet()) {
+ if (networkConnections.get(key) != null
+ && networkConnections.get(key).channel().isActive()) {
+ activeConnections.add(networkConnections.get(key));
+ }
+ }
+
+ if (activeConnections.isEmpty()) {
+ logger.error("activeConnections isEmpty");
+ throw new Exception("activeConnections isEmpty");
+ }
+ // select maxBlockNumber node
+ List maxBlockNumberConnections =
+ new ArrayList();
+ long maxBlockNumber = 0;
+ if (nodeToBlockNumberMap != null) {
+ for (String key : nodeToBlockNumberMap.keySet()) {
+ int blockNumber = nodeToBlockNumberMap.get(key);
+ if (blockNumber >= maxBlockNumber) {
+ if (blockNumber > maxBlockNumber) {
+ maxBlockNumberConnections.clear();
+ }
+
+ Optional optionalCtx =
+ activeConnections
+ .stream()
+ .filter(
+ x ->
+ key.equals(
+ ((SocketChannel) x.channel())
+ .remoteAddress()
+ .getAddress()
+ .getHostAddress()
+ + ((SocketChannel) x.channel())
+ .remoteAddress()
+ .getPort()))
+ .findFirst();
+ if (optionalCtx.isPresent()) {
+ ChannelHandlerContext channelHandlerContext = optionalCtx.get();
+ maxBlockNumberConnections.add(channelHandlerContext);
+ maxBlockNumber = blockNumber;
+ }
+ }
+ }
+ }
+ Random random = new SecureRandom();
+ int selectNodeIndex = 0;
+ ChannelHandlerContext selectedNodeChannelHandlerContext = null;
+ if (!maxBlockNumberConnections.isEmpty()) {
+ selectNodeIndex = random.nextInt(maxBlockNumberConnections.size());
+ selectedNodeChannelHandlerContext = maxBlockNumberConnections.get(selectNodeIndex);
+ } else {
+ selectNodeIndex = random.nextInt(activeConnections.size());
+ selectedNodeChannelHandlerContext = activeConnections.get(selectNodeIndex);
+ }
+ return selectedNodeChannelHandlerContext;
+ }
- public void removeNetworkConnectionByHost(String host, Integer port) {
- String endpoint = host + ":" + port;
+ public ConnectionInfo getConnectionInfo(String host, Integer port) {
+ for (ConnectionInfo info : connections) {
+ if (info.getHost().equals(host) && info.getPort().equals(port)) {
+ return info;
+ }
+ }
- networkConnections.remove(endpoint);
- }
+ return null;
+ }
- public void startListen(Integer port) throws SSLException {
- if (running) {
- logger.debug("running");
- return;
+ public Map getNetworkConnections() {
+ return networkConnections;
}
- logger.debug("init connections listen");
+ public ChannelHandlerContext getNetworkConnectionByHost(String host, Integer port) {
+ String endpoint = host + ":" + port;
- EventLoopGroup bossGroup = new NioEventLoopGroup();
- EventLoopGroup workerGroup = new NioEventLoopGroup();
+ return networkConnections.get(endpoint);
+ }
- final ChannelConnections selfService = this;
- final ThreadPoolTaskExecutor selfThreadPool = threadPool;
+ public void setNetworkConnectionByHost(String host, Integer port, ChannelHandlerContext ctx) {
+ String endpoint = host + ":" + port;
- SslContext sslCtx = initSslContextForListening();
- logger.debug("listening sslcontext init success");
- try {
- serverBootstrap
- .group(bossGroup, workerGroup)
- .channel(NioServerSocketChannel.class)
- .option(ChannelOption.SO_BACKLOG, 100)
- .handler(new LoggingHandler(LogLevel.INFO))
- .childHandler(
- new ChannelInitializer() {
- @Override
- public void initChannel(SocketChannel ch) throws Exception {
- /*
- * 每次连接使用新的handler
- * 连接信息从socketChannel中获取
- */
- ChannelHandler handler = new ChannelHandler();
- handler.setConnections(selfService);
- handler.setIsServer(true);
- handler.setThreadPool(selfThreadPool);
+ networkConnections.put(endpoint, ctx);
+ }
- ch.pipeline()
- .addLast(
- sslCtx.newHandler(ch.alloc()),
- new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, -4, 0),
- new IdleStateHandler(
- idleTimeout, idleTimeout, idleTimeout, TimeUnit.MILLISECONDS),
- handler);
- }
- });
+ public void removeNetworkConnectionByHost(String host, Integer port) {
+ String endpoint = host + ":" + port;
- ChannelFuture future = serverBootstrap.bind(port);
- future.get();
+ networkConnections.remove(endpoint);
+ }
- running = true;
- } catch (Exception e) {
- logger.error("error ", e);
+ public void startListen(Integer port) throws SSLException {
+ if (running) {
+ logger.debug("running");
+ return;
+ }
+
+ logger.debug("init connections listen");
+
+ EventLoopGroup bossGroup = new NioEventLoopGroup();
+ EventLoopGroup workerGroup = new NioEventLoopGroup();
+
+ final ChannelConnections selfService = this;
+ final ThreadPoolTaskExecutor selfThreadPool = threadPool;
+
+ SslContext sslCtx = initSslContextForListening();
+ logger.debug("listening sslcontext init success");
+ try {
+ serverBootstrap
+ .group(bossGroup, workerGroup)
+ .channel(NioServerSocketChannel.class)
+ .option(ChannelOption.SO_BACKLOG, 100)
+ .handler(new LoggingHandler(LogLevel.INFO))
+ .childHandler(
+ new ChannelInitializer() {
+ @Override
+ public void initChannel(SocketChannel ch) throws Exception {
+ /*
+ * 每次连接使用新的handler
+ * 连接信息从socketChannel中获取
+ */
+ ChannelHandler handler = new ChannelHandler();
+ handler.setConnections(selfService);
+ handler.setIsServer(true);
+ handler.setThreadPool(selfThreadPool);
+
+ ch.pipeline()
+ .addLast(
+ sslCtx.newHandler(ch.alloc()),
+ new LengthFieldBasedFrameDecoder(
+ Integer.MAX_VALUE, 0, 4, -4, 0),
+ new IdleStateHandler(
+ idleTimeout,
+ idleTimeout,
+ idleTimeout,
+ TimeUnit.MILLISECONDS),
+ handler);
+ }
+ });
+
+ ChannelFuture future = serverBootstrap.bind(port);
+ future.get();
+
+ running = true;
+ } catch (Exception e) {
+ logger.error("error ", e);
+ }
}
- }
- public void init() {
- logger.debug("init connections");
- // 初始化connections
- for (String conn : connectionsStr) {
- ConnectionInfo connection = new ConnectionInfo();
+ public void init() {
+ logger.debug("init connections");
+ // 初始化connections
+ for (String conn : connectionsStr) {
+ ConnectionInfo connection = new ConnectionInfo();
- String[] split2 = conn.split(":");
+ String[] split2 = conn.split(":");
- connection.setHost(split2[0]);
- connection.setPort(Integer.parseInt(split2[1]));
+ connection.setHost(split2[0]);
+ connection.setPort(Integer.parseInt(split2[1]));
- networkConnections.put(conn, null);
+ networkConnections.put(conn, null);
- logger.debug("add direct node :[" + "]:[" + split2[1] + "]");
+ logger.debug("add direct node :[" + "]:[" + split2[1] + "]");
- connection.setConfig(true);
- connections.add(connection);
+ connection.setConfig(true);
+ connections.add(connection);
+ }
}
- }
- public void startConnect() throws SSLException {
- if (running) {
- logger.debug("running");
- return;
+ public void startConnect() throws SSLException {
+ if (running) {
+ logger.debug("running");
+ return;
+ }
+
+ logger.debug("init connections connect");
+ // 初始化netty
+ EventLoopGroup workerGroup = new NioEventLoopGroup();
+
+ bootstrap.group(workerGroup);
+ bootstrap.channel(NioSocketChannel.class);
+ bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
+
+ final ChannelConnections selfService = this;
+ final ThreadPoolTaskExecutor selfThreadPool = threadPool;
+
+ SslContext sslCtx = initSslContextForConnect();
+ logger.debug(" connect sslcontext init success");
+
+ bootstrap.handler(
+ new ChannelInitializer() {
+ @Override
+ public void initChannel(SocketChannel ch) throws Exception {
+ /*
+ * 每次连接使用新的handler 连接信息从socketChannel中获取
+ */
+ ChannelHandler handler = new ChannelHandler();
+ handler.setConnections(selfService);
+ handler.setIsServer(false);
+ handler.setThreadPool(selfThreadPool);
+
+ ch.pipeline()
+ .addLast(
+ sslCtx.newHandler(ch.alloc()),
+ new LengthFieldBasedFrameDecoder(
+ Integer.MAX_VALUE, 0, 4, -4, 0),
+ new IdleStateHandler(
+ idleTimeout,
+ idleTimeout,
+ idleTimeout,
+ TimeUnit.MILLISECONDS),
+ handler);
+ }
+ });
+
+ running = true;
+
+ Thread loop =
+ new Thread() {
+ public void run() {
+ try {
+ while (true) {
+ if (!running) {
+ return;
+ }
+
+ // 尝试重连
+
+ reconnect();
+ Thread.sleep(heartBeatDelay);
+ }
+ } catch (InterruptedException e) {
+ logger.error("error", e);
+ Thread.currentThread().interrupt();
+ }
+ }
+ };
+
+ loop.start();
}
- logger.debug("init connections connect");
- // 初始化netty
- EventLoopGroup workerGroup = new NioEventLoopGroup();
-
- bootstrap.group(workerGroup);
- bootstrap.channel(NioSocketChannel.class);
- bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
-
- final ChannelConnections selfService = this;
- final ThreadPoolTaskExecutor selfThreadPool = threadPool;
+ private SslContext initSslContextForConnect() throws SSLException {
+ SslContext sslCtx;
+ try {
+ ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
+ Resource caResource = resolver.getResource(getCaCertPath());
+ InputStream caInputStream = caResource.getInputStream();
+ Resource keystorecaResource = resolver.getResource(getNodeCaPath());
+ Resource keystorekeyResource = resolver.getResource(getNodeKeyPath());
+ sslCtx =
+ SslContextBuilder.forClient()
+ .trustManager(caInputStream)
+ .keyManager(
+ keystorecaResource.getInputStream(),
+ keystorekeyResource.getInputStream())
+ .sslProvider(SslProvider.JDK)
+ .build();
+ } catch (Exception e) {
+ logger.debug("SSLCONTEXT ***********" + e.getMessage());
+ throw new SSLException(
+ "Failed to initialize the client-side SSLContext: " + e.getMessage());
+ }
+ return sslCtx;
+ }
- SslContext sslCtx = initSslContextForConnect();
- logger.debug(" connect sslcontext init success");
+ private SslContext initSslContextForListening() throws SSLException {
+ SslContext sslCtx;
+ try {
+ ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
+ Resource caResource = resolver.getResource(getCaCertPath());
+ InputStream caInputStream = caResource.getInputStream();
+ Resource keystorecaResource = resolver.getResource(getNodeCaPath());
+ Resource keystorekeyResource = resolver.getResource(getNodeKeyPath());
+ sslCtx =
+ SslContextBuilder.forServer(
+ keystorecaResource.getInputStream(),
+ keystorekeyResource.getInputStream())
+ .trustManager(caInputStream)
+ .sslProvider(SslProvider.JDK)
+ .build();
+ } catch (Exception e) {
+ logger.debug("SSLCONTEXT ***********" + e.getMessage());
+ throw new SSLException(
+ "Failed to initialize the client-side SSLContext, please checkout ca.crt File!",
+ e);
+ }
+ return sslCtx;
+ }
- bootstrap.handler(
- new ChannelInitializer() {
- @Override
- public void initChannel(SocketChannel ch) throws Exception {
- /*
- * 每次连接使用新的handler 连接信息从socketChannel中获取
- */
- ChannelHandler handler = new ChannelHandler();
- handler.setConnections(selfService);
- handler.setIsServer(false);
- handler.setThreadPool(selfThreadPool);
+ public void reconnect() {
+ for (Entry ctx : networkConnections.entrySet()) {
+ if (ctx.getValue() == null || !ctx.getValue().channel().isActive()) {
+ String[] split = ctx.getKey().split(":");
- ch.pipeline()
- .addLast(
- sslCtx.newHandler(ch.alloc()),
- new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, -4, 0),
- new IdleStateHandler(
- idleTimeout, idleTimeout, idleTimeout, TimeUnit.MILLISECONDS),
- handler);
- }
- });
+ String host = split[0];
+ Integer port = Integer.parseInt(split[1]);
+ logger.debug("try connect to: {}:{}", host, port);
- running = true;
+ bootstrap.connect(host, port);
+ logger.debug("connect to: {}:{} success", host, port);
+ } else {
+ logger.trace("send heart beat to {}", ctx.getKey());
+ // 连接还在,发送心跳
+ BcosMessage fiscoMessage = new BcosMessage();
- Thread loop =
- new Thread() {
- public void run() {
- try {
- while (true) {
- if (!running) {
- return;
- }
+ fiscoMessage.setSeq(UUID.randomUUID().toString().replaceAll("-", ""));
+ fiscoMessage.setResult(0);
+ fiscoMessage.setType((short) 0x13);
+ fiscoMessage.setData("0".getBytes());
- // 尝试重连
+ ByteBuf out = ctx.getValue().alloc().buffer();
+ fiscoMessage.writeHeader(out);
+ fiscoMessage.writeExtra(out);
- reconnect();
- Thread.sleep(heartBeatDelay);
- }
- } catch (InterruptedException e) {
- logger.error("error", e);
- Thread.currentThread().interrupt();
+ ctx.getValue().writeAndFlush(out);
}
- }
- };
-
- loop.start();
- }
-
- private SslContext initSslContextForConnect() throws SSLException {
- SslContext sslCtx;
- try {
- ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
- Resource caResource = resolver.getResource(getCaCertPath());
- InputStream caInputStream = caResource.getInputStream();
- Resource keystorecaResource = resolver.getResource(getNodeCaPath());
- Resource keystorekeyResource = resolver.getResource(getNodeKeyPath());
- sslCtx =
- SslContextBuilder.forClient()
- .trustManager(caInputStream)
- .keyManager(keystorecaResource.getInputStream(), keystorekeyResource.getInputStream())
- .sslProvider(SslProvider.JDK)
- .build();
- } catch (Exception e) {
- logger.debug("SSLCONTEXT ***********" + e.getMessage());
- throw new SSLException("Failed to initialize the client-side SSLContext: " + e.getMessage());
- }
- return sslCtx;
- }
-
- private SslContext initSslContextForListening() throws SSLException {
- SslContext sslCtx;
- try {
- ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
- Resource caResource = resolver.getResource(getCaCertPath());
- InputStream caInputStream = caResource.getInputStream();
- Resource keystorecaResource = resolver.getResource(getNodeCaPath());
- Resource keystorekeyResource = resolver.getResource(getNodeKeyPath());
- sslCtx =
- SslContextBuilder.forServer(
- keystorecaResource.getInputStream(), keystorekeyResource.getInputStream())
- .trustManager(caInputStream)
- .build();
- } catch (Exception e) {
- logger.debug("SSLCONTEXT ***********" + e.getMessage());
- throw new SSLException(
- "Failed to initialize the client-side SSLContext, please checkout ca.crt File!", e);
- }
- return sslCtx;
- }
-
- public void reconnect() {
- for (Entry ctx : networkConnections.entrySet()) {
- if (ctx.getValue() == null || !ctx.getValue().channel().isActive()) {
- String[] split = ctx.getKey().split(":");
-
- String host = split[0];
- Integer port = Integer.parseInt(split[1]);
- logger.debug("try connect to: {}:{}", host, port);
-
- bootstrap.connect(host, port);
- logger.debug("connect to: {}:{} success", host, port);
- } else {
- logger.trace("send heart beat to {}", ctx.getKey());
- // 连接还在,发送心跳
- FiscoMessage fiscoMessage = new FiscoMessage();
-
- fiscoMessage.setSeq(UUID.randomUUID().toString().replaceAll("-", ""));
- fiscoMessage.setResult(0);
- fiscoMessage.setType((short) 0x13);
- fiscoMessage.setData("0".getBytes());
-
- ByteBuf out = ctx.getValue().alloc().buffer();
- fiscoMessage.writeHeader(out);
- fiscoMessage.writeExtra(out);
-
- ctx.getValue().writeAndFlush(out);
- }
- }
- }
-
- public void onReceiveMessage(ChannelHandlerContext ctx, ByteBuf message) {
- callback.onMessage(ctx, message);
- }
+ }
+ }
+
+ public void onReceiveMessage(ChannelHandlerContext ctx, ByteBuf message) {
+ callback.onMessage(ctx, message);
+ }
}
diff --git a/src/main/java/org/fisco/bcos/channel/handler/ChannelHandler.java b/src/main/java/org/fisco/bcos/channel/handler/ChannelHandler.java
index 39ab4bb01..290ac3a71 100644
--- a/src/main/java/org/fisco/bcos/channel/handler/ChannelHandler.java
+++ b/src/main/java/org/fisco/bcos/channel/handler/ChannelHandler.java
@@ -11,203 +11,206 @@
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
public class ChannelHandler extends SimpleChannelInboundHandler {
- private static Logger logger = LoggerFactory.getLogger(ChannelHandler.class);
-
- @Override
- public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
- String host = ((SocketChannel) ctx.channel()).remoteAddress().getAddress().getHostAddress();
- Integer port = ((SocketChannel) ctx.channel()).remoteAddress().getPort();
-
- if (evt instanceof IdleStateEvent) {
- IdleStateEvent e = (IdleStateEvent) evt;
- switch (e.state()) {
- case READER_IDLE:
- case WRITER_IDLE:
- case ALL_IDLE:
- logger.error(
- "event:{} connect{}:{} long time Inactive,disconnect", e.state(), host, port);
- channelInactive(ctx);
- ctx.disconnect();
- ctx.close();
- break;
- default:
- break;
- }
- }
- }
-
- @Override
- public void channelActive(ChannelHandlerContext ctx) throws Exception {
- try {
- // 已连上,获取ip信息
- String host = ((SocketChannel) ctx.channel()).remoteAddress().getAddress().getHostAddress();
- Integer port = ((SocketChannel) ctx.channel()).remoteAddress().getPort();
-
- logger.debug(
- "success,connected["
- + host
- + "]:["
- + String.valueOf(port)
- + "],"
- + String.valueOf(ctx.channel().isActive()));
-
- if (isServer) {
- logger.debug("server accept new connect: {}:{}", host, port);
- // 将此新连接增加到connections
- ConnectionInfo info = new ConnectionInfo();
- info.setHost(host);
- info.setPort(port);
-
- connections.getConnections().add(info);
- connections.setNetworkConnectionByHost(info.getHost(), info.getPort(), ctx);
- connections.getCallback().onConnect(ctx);
- } else {
- // 更新ctx信息
- ChannelHandlerContext connection = connections.getNetworkConnectionByHost(host, port);
- if (connection != null && connection.channel().isActive()) {
- logger.debug("connect available, close reconnect: {}:{}", host, port);
-
- ctx.channel().disconnect();
- ctx.channel().close();
- } else {
- logger.debug("client connect success {}:{}", host, port);
- connections.setNetworkConnectionByHost(host, port, ctx);
- connections.getCallback().onConnect(ctx);
+ private static Logger logger = LoggerFactory.getLogger(ChannelHandler.class);
+
+ @Override
+ public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
+ String host = ((SocketChannel) ctx.channel()).remoteAddress().getAddress().getHostAddress();
+ Integer port = ((SocketChannel) ctx.channel()).remoteAddress().getPort();
+
+ if (evt instanceof IdleStateEvent) {
+ IdleStateEvent e = (IdleStateEvent) evt;
+ switch (e.state()) {
+ case READER_IDLE:
+ case WRITER_IDLE:
+ case ALL_IDLE:
+ logger.error(
+ "event:{} connect{}:{} long time Inactive,disconnect",
+ e.state(),
+ host,
+ port);
+ channelInactive(ctx);
+ ctx.disconnect();
+ ctx.close();
+ break;
+ default:
+ break;
+ }
}
- }
- } catch (Exception e) {
- logger.error("error", e);
}
- }
-
- @Override
- public void channelInactive(ChannelHandlerContext ctx) throws Exception {
- try {
- logger.debug("disconnect");
- // 已断连,获取ip信息
- String host = ((SocketChannel) ctx.channel()).remoteAddress().getAddress().getHostAddress();
- Integer port = ((SocketChannel) ctx.channel()).remoteAddress().getPort();
-
- logger.debug(
- "disconnect "
- + host
- + ":"
- + String.valueOf(port)
- + " ,"
- + String.valueOf(ctx.channel().isActive()));
-
- if (isServer) {
- // server模式下,移除该connectionInfo
- for (Integer i = 0; i < connections.getConnections().size(); ++i) {
- ConnectionInfo info = connections.getConnections().get(i);
-
- if (info.getHost().equals(host) && info.getPort().equals(port)) {
- connections.getConnections().remove(i);
- }
- }
- // 移除该networkConnection
- connections.removeNetworkConnectionByHost(host, port);
- } else {
- // 无需将连接置为null
- // connections.setNetworkConnection(host, port, null);
- }
-
- connections.getCallback().onDisconnect(ctx);
- } catch (Exception e) {
- logger.error("error ", e);
+ @Override
+ public void channelActive(ChannelHandlerContext ctx) throws Exception {
+ try {
+ // connected,get ip info
+ String host =
+ ((SocketChannel) ctx.channel()).remoteAddress().getAddress().getHostAddress();
+ Integer port = ((SocketChannel) ctx.channel()).remoteAddress().getPort();
+
+ logger.debug(
+ "success,connected["
+ + host
+ + "]:["
+ + String.valueOf(port)
+ + "],"
+ + String.valueOf(ctx.channel().isActive()));
+
+ if (isServer) {
+ logger.debug("server accept new connect: {}:{}", host, port);
+ // add the connection to the connections
+ ConnectionInfo info = new ConnectionInfo();
+ info.setHost(host);
+ info.setPort(port);
+
+ connections.getConnections().add(info);
+ connections.setNetworkConnectionByHost(info.getHost(), info.getPort(), ctx);
+ connections.getCallback().onConnect(ctx);
+ } else {
+ // 更新ctx信息
+ ChannelHandlerContext connection =
+ connections.getNetworkConnectionByHost(host, port);
+ if (connection != null && connection.channel().isActive()) {
+ logger.debug("connect available, close reconnect: {}:{}", host, port);
+
+ ctx.channel().disconnect();
+ ctx.channel().close();
+ } else {
+ logger.debug("client connect success {}:{}", host, port);
+ connections.setNetworkConnectionByHost(host, port, ctx);
+ connections.getCallback().onConnect(ctx);
+ }
+ }
+ } catch (Exception e) {
+ logger.error("error", e);
+ }
}
- }
-
- @Override
- public void channelRead(ChannelHandlerContext ctx, Object msg) {
- String host = ((SocketChannel) ctx.channel()).remoteAddress().getAddress().getHostAddress();
- Integer port = ((SocketChannel) ctx.channel()).remoteAddress().getPort();
-
- final ChannelHandlerContext ctxF = ctx;
- final ByteBuf in = (ByteBuf) msg;
-
- logger.trace("receive,from" + host + ":" + port + " in:" + in.readableBytes());
- logger.trace("threadPool:{}", threadPool == null);
-
- try {
- if (threadPool == null) {
- connections.onReceiveMessage(ctx, in);
- } else {
- threadPool.execute(
- new Runnable() {
- @Override
- public void run() {
- connections.onReceiveMessage(ctxF, in);
- }
- });
- }
- } catch (RejectedExecutionException e) {
- logger.error("threadPool is full,reject to request", e);
+
+ @Override
+ public void channelInactive(ChannelHandlerContext ctx) throws Exception {
+ try {
+ logger.debug("disconnect");
+ // lost the connection, get ip info
+ String host =
+ ((SocketChannel) ctx.channel()).remoteAddress().getAddress().getHostAddress();
+ Integer port = ((SocketChannel) ctx.channel()).remoteAddress().getPort();
+
+ logger.debug(
+ "disconnect "
+ + host
+ + ":"
+ + String.valueOf(port)
+ + " ,"
+ + String.valueOf(ctx.channel().isActive()));
+
+ if (isServer) {
+ // server mode,remove the connection
+ for (Integer i = 0; i < connections.getConnections().size(); ++i) {
+ ConnectionInfo info = connections.getConnections().get(i);
+
+ if (info.getHost().equals(host) && info.getPort().equals(port)) {
+ connections.getConnections().remove(i);
+ }
+ }
+
+ // remove the networkConnection
+ connections.removeNetworkConnectionByHost(host, port);
+ } else {
+ // set the connection disabled
+ // connections.setNetworkConnection(host, port, null);
+ }
+
+ connections.getCallback().onDisconnect(ctx);
+ } catch (Exception e) {
+ logger.error("error ", e);
+ }
}
- }
-
- @Override
- public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
- logger.error("network error ", cause);
- // 已断连,获取ip信息
- String host = ((SocketChannel) ctx.channel()).remoteAddress().getAddress().getHostAddress();
- Integer port = ((SocketChannel) ctx.channel()).remoteAddress().getPort();
-
- logger.debug(
- "disconnect "
- + host
- + ":"
- + String.valueOf(port)
- + " ,"
- + String.valueOf(ctx.channel().isActive()));
-
- if (isServer) {
- // server模式下,移除该connection
- connections.removeNetworkConnectionByHost(host, port);
- } else {
- // 将该连接置为不可用
- // connections.setNetworkConnection(host, port, null);
+
+ @Override
+ public void channelRead(ChannelHandlerContext ctx, Object msg) {
+ String host = ((SocketChannel) ctx.channel()).remoteAddress().getAddress().getHostAddress();
+ Integer port = ((SocketChannel) ctx.channel()).remoteAddress().getPort();
+
+ final ChannelHandlerContext ctxF = ctx;
+ final ByteBuf in = (ByteBuf) msg;
+ try {
+ if (threadPool == null) {
+ connections.onReceiveMessage(ctx, in);
+ } else {
+ threadPool.execute(
+ new Runnable() {
+ @Override
+ public void run() {
+ connections.onReceiveMessage(ctxF, in);
+ }
+ });
+ }
+
+ } catch (RejectedExecutionException e) {
+ logger.error("threadPool is full, reject to request", e);
+ }
}
- ctx.disconnect();
- ctx.close();
- }
+ @Override
+ public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
+ logger.error("network error ", cause);
+ // lost the connection,get ip info
+ String host = ((SocketChannel) ctx.channel()).remoteAddress().getAddress().getHostAddress();
+ Integer port = ((SocketChannel) ctx.channel()).remoteAddress().getPort();
+
+ logger.debug(
+ "disconnect "
+ + host
+ + ":"
+ + String.valueOf(port)
+ + " ,"
+ + String.valueOf(ctx.channel().isActive()));
+
+ if (isServer) {
+ // server mode,remove the connection
+ connections.removeNetworkConnectionByHost(host, port);
+ } else {
+ // set the connection disabled
+ // connections.setNetworkConnection(host, port, null);
+ }
+
+ ctx.disconnect();
+ ctx.close();
+ }
- @Override
- protected void channelRead0(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
- channelRead(ctx, in);
- }
+ @Override
+ protected void channelRead0(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
+ channelRead(ctx, in);
+ }
- public void checkAvailable(ChannelHandlerContext ctx) {}
+ public void checkAvailable(ChannelHandlerContext ctx) {}
- public ChannelConnections getConnections() {
- return connections;
- }
+ public ChannelConnections getConnections() {
+ return connections;
+ }
- public void setConnections(ChannelConnections connections) {
- this.connections = connections;
- }
+ public void setConnections(ChannelConnections connections) {
+ this.connections = connections;
+ }
- public Boolean getIsServer() {
- return isServer;
- }
+ public Boolean getIsServer() {
+ return isServer;
+ }
- public void setIsServer(Boolean isServer) {
- this.isServer = isServer;
- }
+ public void setIsServer(Boolean isServer) {
+ this.isServer = isServer;
+ }
- public ThreadPoolTaskExecutor getThreadPool() {
- return threadPool;
- }
+ public ThreadPoolTaskExecutor getThreadPool() {
+ return threadPool;
+ }
- public void setThreadPool(ThreadPoolTaskExecutor threadPool) {
- this.threadPool = threadPool;
+ public void setThreadPool(ThreadPoolTaskExecutor threadPool) {
+ this.threadPool = threadPool;
- logger.debug("set threadPool:{}", threadPool == null);
- }
+ logger.debug("set threadPool:{}", threadPool == null);
+ }
- private ChannelConnections connections;
- private Boolean isServer = false;
- private ThreadPoolTaskExecutor threadPool;
+ private ChannelConnections connections;
+ private Boolean isServer = false;
+ private ThreadPoolTaskExecutor threadPool;
}
diff --git a/src/main/java/org/fisco/bcos/channel/handler/ConnectionCallback.java b/src/main/java/org/fisco/bcos/channel/handler/ConnectionCallback.java
index f2e71cfb0..3edcd4dd6 100644
--- a/src/main/java/org/fisco/bcos/channel/handler/ConnectionCallback.java
+++ b/src/main/java/org/fisco/bcos/channel/handler/ConnectionCallback.java
@@ -1,152 +1,203 @@
package org.fisco.bcos.channel.handler;
+import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.socket.SocketChannel;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
+import java.net.InetSocketAddress;
+import java.util.Arrays;
import java.util.Set;
import java.util.UUID;
+import org.fisco.bcos.channel.client.BcosResponseCallback;
import org.fisco.bcos.channel.client.Service;
+import org.fisco.bcos.channel.dto.BcosMessage;
+import org.fisco.bcos.channel.dto.BcosResponse;
import org.fisco.bcos.channel.dto.ChannelMessage;
import org.fisco.bcos.channel.dto.ChannelMessage2;
-import org.fisco.bcos.channel.dto.FiscoMessage;
+import org.fisco.bcos.web3j.protocol.channel.ChannelEthereumService;
+import org.fisco.bcos.web3j.protocol.core.Request;
+import org.fisco.bcos.web3j.protocol.core.methods.response.BlockNumber;
+import org.fisco.bcos.web3j.protocol.exceptions.MessageDecodingException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ConnectionCallback implements ChannelConnections.Callback {
- private static Logger logger = LoggerFactory.getLogger(ConnectionCallback.class);
+ private static Logger logger = LoggerFactory.getLogger(ConnectionCallback.class);
- private ObjectMapper objectMapper = new ObjectMapper();
- private Service channelService;
- private Set topics;
+ private ObjectMapper objectMapper = new ObjectMapper();
+ private Service channelService;
+ private Set topics;
- public Service getChannelService() {
- return channelService;
- }
-
- public void setChannelService(Service channelService) {
- this.channelService = channelService;
- }
-
- public ConnectionCallback(Set topics) {
- this.topics = topics;
- }
-
- public void setTopics(Set topics) {
- try {
- this.topics = topics;
- } catch (Exception e) {
- logger.error("system error", e);
+ public Service getChannelService() {
+ return channelService;
}
- }
-
- @Override
- public void onConnect(ChannelHandlerContext ctx) {
- try {
- channelService.setNumber(BigInteger.ONE);
-
- Message message = new Message();
- message.setResult(0);
- message.setType((short) 0x32);
- message.setSeq(UUID.randomUUID().toString().replaceAll("-", ""));
-
- logger.debug("connection established,send topic to the connection:{}", message.getSeq());
- topics.add("_block_notify_" + String.valueOf(channelService.getGroupId()));
- message.setData(objectMapper.writeValueAsBytes(topics.toArray()));
-
- logger.debug("topics: {}", new String(message.getData()));
-
- ByteBuf out = ctx.alloc().buffer();
- message.writeHeader(out);
- message.writeExtra(out);
-
- ctx.writeAndFlush(out);
- } catch (Exception e) {
- logger.error("error:", e);
+ public void setChannelService(Service channelService) {
+ this.channelService = channelService;
}
- }
- @Override
- public void onDisconnect(ChannelHandlerContext ctx) {}
-
- @Override
- public void onMessage(ChannelHandlerContext ctx, ByteBuf message) {
- try {
- Message msg = new Message();
- msg.readHeader(message);
+ public ConnectionCallback(Set topics) {
+ this.topics = topics;
+ }
- logger.trace("receive Message type: {}", msg.getType());
+ public void setTopics(Set topics) {
+ try {
+ this.topics = topics;
+ } catch (Exception e) {
+ logger.error("system error", e);
+ }
+ }
- if (msg.getType() == 0x20 || msg.getType() == 0x21) {
- logger.debug("channel message");
+ @Override
+ public void onConnect(ChannelHandlerContext ctx) {
+ try {
+ channelService.setNumber(BigInteger.ONE);
- ChannelMessage channelMessage = new ChannelMessage(msg);
- channelMessage.readExtra(message);
+ Message message = new Message();
+ message.setResult(0);
+ message.setType((short) 0x32);
+ message.setSeq(UUID.randomUUID().toString().replaceAll("-", ""));
- channelService.onReceiveChannelMessage(ctx, channelMessage);
- } else if (msg.getType() == 0x30 || msg.getType() == 0x31) {
- logger.debug("channel2 message");
+ logger.debug(
+ "connection established,send topic to the connection:{}", message.getSeq());
- ChannelMessage2 channelMessage = new ChannelMessage2(msg);
- channelMessage.readExtra(message);
+ topics.add("_block_notify_" + String.valueOf(channelService.getGroupId()));
+ message.setData(objectMapper.writeValueAsBytes(topics.toArray()));
- channelService.onReceiveChannelMessage2(ctx, channelMessage);
- } else if (msg.getType() == 0x12) {
- logger.debug("fisco message");
+ logger.debug("topics: {}", new String(message.getData()));
- FiscoMessage fiscoMessage = new FiscoMessage(msg);
- fiscoMessage.readExtra(message);
+ ByteBuf out = ctx.alloc().buffer();
+ message.writeHeader(out);
+ message.writeExtra(out);
- channelService.onReceiveEthereumMessage(ctx, fiscoMessage);
- } else if (msg.getType() == 0x13) {
- msg.readExtra(message);
+ ctx.writeAndFlush(out);
- String content = "1";
- try {
- content = new String(msg.getData(), "utf-8");
- } catch (UnsupportedEncodingException e) {
- logger.error("heartbeat packet cannot be parsed");
+ queryBlockNumberForSelectNodes(ctx);
} catch (Exception e) {
- logger.error("heartbeat packet Exception");
+ logger.error("error:", e);
}
+ }
- if (content.equals("0")) {
- logger.trace("heartbeat packet,send heartbeat packet back");
- Message response = new Message();
-
- response.setSeq(msg.getSeq());
- response.setResult(0);
- response.setType((short) 0x13);
- response.setData("1".getBytes());
+ private void queryBlockNumberForSelectNodes(ChannelHandlerContext ctx)
+ throws JsonProcessingException {
+ BcosMessage bcosMessage = new BcosMessage();
+ bcosMessage.setType((short) 0x12);
+ String seq = UUID.randomUUID().toString().replaceAll("-", "");
+ bcosMessage.setSeq(seq);
+ ChannelEthereumService channelEthereumService = new ChannelEthereumService();
+ channelEthereumService.setChannelService(channelService);
+ Request request =
+ new Request<>(
+ "getBlockNumber",
+ Arrays.asList(channelService.getGroupId()),
+ channelEthereumService,
+ BlockNumber.class);
+ ObjectMapper objectMapper = new ObjectMapper();
+ bcosMessage.setData(objectMapper.writeValueAsBytes(request));
+ ByteBuf byteBuf = ctx.alloc().buffer();
+ bcosMessage.writeHeader(byteBuf);
+ bcosMessage.writeExtra(byteBuf);
+ ctx.writeAndFlush(byteBuf);
+
+ channelService
+ .getSeq2Callback()
+ .put(
+ seq,
+ new BcosResponseCallback() {
+
+ @Override
+ public void onResponse(BcosResponse response) {
+ try {
+ ObjectMapper objectMapper = new ObjectMapper();
+ BlockNumber blockNumber =
+ objectMapper.readValue(
+ response.getContent(), BlockNumber.class);
+ SocketChannel socketChannel = (SocketChannel) ctx.channel();
+ InetSocketAddress socketAddress = socketChannel.remoteAddress();
+ channelService
+ .getNodeToBlockNumberMap()
+ .put(
+ socketAddress.getAddress().getHostAddress()
+ + socketAddress.getPort(),
+ blockNumber.getBlockNumber().intValue());
+ } catch (Exception e) {
+ throw new MessageDecodingException(response.getContent());
+ }
+ }
+ });
+ }
- ByteBuf out = ctx.alloc().buffer();
- response.writeHeader(out);
- response.writeExtra(out);
+ @Override
+ public void onDisconnect(ChannelHandlerContext ctx) {}
- ctx.writeAndFlush(out);
- } else if (content.equals("1")) {
- logger.trace("heartbeat response");
+ @Override
+ public void onMessage(ChannelHandlerContext ctx, ByteBuf message) {
+ try {
+ Message msg = new Message();
+ msg.readHeader(message);
+
+ if (msg.getType() == 0x20 || msg.getType() == 0x21) {
+ ChannelMessage channelMessage = new ChannelMessage(msg);
+ channelMessage.readExtra(message);
+
+ channelService.onReceiveChannelMessage(ctx, channelMessage);
+ } else if (msg.getType() == 0x30 || msg.getType() == 0x31) {
+ ChannelMessage2 channelMessage = new ChannelMessage2(msg);
+ channelMessage.readExtra(message);
+
+ channelService.onReceiveChannelMessage2(ctx, channelMessage);
+ } else if (msg.getType() == 0x12) {
+ BcosMessage fiscoMessage = new BcosMessage(msg);
+ fiscoMessage.readExtra(message);
+
+ channelService.onReceiveEthereumMessage(ctx, fiscoMessage);
+ } else if (msg.getType() == 0x13) {
+ msg.readExtra(message);
+
+ String content = "1";
+ try {
+ content = new String(msg.getData(), "utf-8");
+ } catch (UnsupportedEncodingException e) {
+ logger.error("heartbeat packet cannot be parsed");
+ } catch (Exception e) {
+ logger.error("heartbeat packet Exception");
+ }
+
+ if ("0".equals(content)) {
+ logger.trace("heartbeat packet,send heartbeat packet back");
+ Message response = new Message();
+
+ response.setSeq(msg.getSeq());
+ response.setResult(0);
+ response.setType((short) 0x13);
+ response.setData("1".getBytes());
+
+ ByteBuf out = ctx.alloc().buffer();
+ response.writeHeader(out);
+ response.writeExtra(out);
+
+ ctx.writeAndFlush(out);
+ } else if ("1".equals(content)) {
+ logger.trace("heartbeat response");
+ }
+ } else if (msg.getType() == 0x1000) {
+ BcosMessage fiscoMessage = new BcosMessage(msg);
+ fiscoMessage.readExtra(message);
+ channelService.onReceiveTransactionMessage(ctx, fiscoMessage);
+ } else if (msg.getType() == 0x1001) {
+ // new block notify
+ ChannelMessage2 channelMessage = new ChannelMessage2(msg);
+ channelMessage.readExtra(message);
+
+ channelService.onReceiveBlockNotify(ctx, channelMessage);
+ } else {
+ logger.error("unknown message type:{}", msg.getType());
+ }
+ } finally {
+ message.release();
}
- } else if (msg.getType() == 0x1000) {
- FiscoMessage fiscoMessage = new FiscoMessage(msg);
- logger.trace("TransactionReceipt notify: {}", fiscoMessage.getSeq());
-
- fiscoMessage.readExtra(message);
- channelService.onReceiveTransactionMessage(ctx, fiscoMessage);
- } else if (msg.getType() == 0x1001) {
- // new block notify
- ChannelMessage2 channelMessage = new ChannelMessage2(msg);
- channelMessage.readExtra(message);
-
- logger.trace("New block notify");
- channelService.onReceiveBlockNotify(ctx, channelMessage);
- } else {
- logger.error("unknown message type:{}", msg.getType());
- }
- } finally {
- message.release();
}
- }
}
diff --git a/src/main/java/org/fisco/bcos/channel/handler/ConnectionInfo.java b/src/main/java/org/fisco/bcos/channel/handler/ConnectionInfo.java
index dd4f61803..9e3ed7536 100644
--- a/src/main/java/org/fisco/bcos/channel/handler/ConnectionInfo.java
+++ b/src/main/java/org/fisco/bcos/channel/handler/ConnectionInfo.java
@@ -4,50 +4,50 @@
import java.util.List;
public class ConnectionInfo {
- public String getNodeID() {
- return nodeID;
- }
+ public String getNodeID() {
+ return nodeID;
+ }
- public void setNodeID(String nodeID) {
- this.nodeID = nodeID;
- }
+ public void setNodeID(String nodeID) {
+ this.nodeID = nodeID;
+ }
- public String getHost() {
- return host;
- }
+ public String getHost() {
+ return host;
+ }
- public void setHost(String host) {
- this.host = host;
- }
+ public void setHost(String host) {
+ this.host = host;
+ }
- public Integer getPort() {
- return port;
- }
+ public Integer getPort() {
+ return port;
+ }
- public void setPort(Integer port) {
- this.port = port;
- }
+ public void setPort(Integer port) {
+ this.port = port;
+ }
- public Boolean getConfig() {
- return config;
- }
+ public Boolean getConfig() {
+ return config;
+ }
- public void setConfig(Boolean config) {
- this.config = config;
- }
+ public void setConfig(Boolean config) {
+ this.config = config;
+ }
- public List getTopics() {
- return topics;
- }
+ public List getTopics() {
+ return topics;
+ }
- public void setTopics(List topics) {
- this.topics = topics;
- }
+ public void setTopics(List topics) {
+ this.topics = topics;
+ }
- private String nodeID = "";
- private String host = "";
- private Integer port = 0;
- private Boolean config = false;
+ private String nodeID = "";
+ private String host = "";
+ private Integer port = 0;
+ private Boolean config = false;
- private List topics = new ArrayList();
+ private List topics = new ArrayList();
}
diff --git a/src/main/java/org/fisco/bcos/channel/handler/Decoder.java b/src/main/java/org/fisco/bcos/channel/handler/Decoder.java
index 1bae71686..1d2bf85e6 100644
--- a/src/main/java/org/fisco/bcos/channel/handler/Decoder.java
+++ b/src/main/java/org/fisco/bcos/channel/handler/Decoder.java
@@ -8,43 +8,44 @@
import org.slf4j.LoggerFactory;
public class Decoder extends ByteToMessageDecoder {
- private static Logger logger = LoggerFactory.getLogger(Decoder.class);
-
- private Integer dataLength = 0;
-
- @Override
- protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception {
- logger.debug("decode:" + in.readableBytes());
-
- while (true) {
- if (dataLength > 0) {
- if (in.readableBytes() < dataLength - 4) {
- return;
+ private static Logger logger = LoggerFactory.getLogger(Decoder.class);
+
+ private Integer dataLength = 0;
+
+ @Override
+ protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out)
+ throws Exception {
+ logger.debug("decode:" + in.readableBytes());
+
+ while (true) {
+ if (dataLength > 0) {
+ if (in.readableBytes() < dataLength - 4) {
+ return;
+ }
+
+ Short type = in.readShort();
+ ByteBuf data = in.readBytes(dataLength - 6);
+
+ Message message = new Message();
+ message.setLength(dataLength);
+ message.setType(type);
+ message.setData(data.array());
+
+ logger.debug(
+ "new message: "
+ + String.valueOf(message.getLength())
+ + ","
+ + String.valueOf(message.getType()));
+ out.add(message);
+ dataLength = 0;
+ } else {
+ if (in.readableBytes() < 4) {
+ return;
+ }
+
+ dataLength = in.readInt();
+ logger.debug("dataLength " + String.valueOf(dataLength));
+ }
}
-
- Short type = in.readShort();
- ByteBuf data = in.readBytes(dataLength - 6);
-
- Message message = new Message();
- message.setLength(dataLength);
- message.setType(type);
- message.setData(data.array());
-
- logger.debug(
- "new message: "
- + String.valueOf(message.getLength())
- + ","
- + String.valueOf(message.getType()));
- out.add(message);
- dataLength = 0;
- } else {
- if (in.readableBytes() < 4) {
- return;
- }
-
- dataLength = in.readInt();
- logger.debug("dataLength " + String.valueOf(dataLength));
- }
}
- }
}
diff --git a/src/main/java/org/fisco/bcos/channel/handler/Encoder.java b/src/main/java/org/fisco/bcos/channel/handler/Encoder.java
index f4335a285..cf1d2e6ec 100644
--- a/src/main/java/org/fisco/bcos/channel/handler/Encoder.java
+++ b/src/main/java/org/fisco/bcos/channel/handler/Encoder.java
@@ -7,14 +7,14 @@
import org.slf4j.LoggerFactory;
public class Encoder extends MessageToByteEncoder {
- private static Logger logger = LoggerFactory.getLogger(Encoder.class);
+ private static Logger logger = LoggerFactory.getLogger(Encoder.class);
- @Override
- protected void encode(ChannelHandlerContext ctx, Message msg, ByteBuf out) throws Exception {
- logger.debug("encode:" + msg.getLength() + "," + msg.getData());
+ @Override
+ protected void encode(ChannelHandlerContext ctx, Message msg, ByteBuf out) throws Exception {
+ logger.debug("encode:" + msg.getLength() + "," + msg.getData());
- out.writeIntLE(msg.getLength());
- out.writeShortLE(msg.getType());
- out.writeBytes(msg.getData());
- }
+ out.writeIntLE(msg.getLength());
+ out.writeShortLE(msg.getType());
+ out.writeBytes(msg.getData());
+ }
}
diff --git a/src/main/java/org/fisco/bcos/channel/handler/GroupChannelConnectionsConfig.java b/src/main/java/org/fisco/bcos/channel/handler/GroupChannelConnectionsConfig.java
index 94b96562b..306f7c9d1 100644
--- a/src/main/java/org/fisco/bcos/channel/handler/GroupChannelConnectionsConfig.java
+++ b/src/main/java/org/fisco/bcos/channel/handler/GroupChannelConnectionsConfig.java
@@ -3,13 +3,13 @@
import java.util.List;
public class GroupChannelConnectionsConfig {
- private List allChannelConnections;
+ private List allChannelConnections;
- public List getAllChannelConnections() {
- return allChannelConnections;
- }
+ public List getAllChannelConnections() {
+ return allChannelConnections;
+ }
- public void setAllChannelConnections(List allChannelConnections) {
- this.allChannelConnections = allChannelConnections;
- }
+ public void setAllChannelConnections(List allChannelConnections) {
+ this.allChannelConnections = allChannelConnections;
+ }
}
diff --git a/src/main/java/org/fisco/bcos/channel/handler/Message.java b/src/main/java/org/fisco/bcos/channel/handler/Message.java
index f6f0e1b95..18dc5bb9b 100644
--- a/src/main/java/org/fisco/bcos/channel/handler/Message.java
+++ b/src/main/java/org/fisco/bcos/channel/handler/Message.java
@@ -7,90 +7,90 @@
import org.slf4j.LoggerFactory;
public class Message implements Serializable {
- private static Logger logger = LoggerFactory.getLogger(Message.class);
+ private static Logger logger = LoggerFactory.getLogger(Message.class);
- private static final long serialVersionUID = -7276897518418560354L;
+ private static final long serialVersionUID = -7276897518418560354L;
- public static final int HEADER_LENGTH = 4 + 2 + 32 + 4;
+ public static final int HEADER_LENGTH = 4 + 2 + 32 + 4;
- public void readHeader(ByteBuf in) {
+ public void readHeader(ByteBuf in) {
- length = in.readInt();
- type = in.readShort();
- byte[] dst = new byte[32];
- in.readBytes(dst);
- try {
- seq = new String(dst, "utf-8");
- } catch (UnsupportedEncodingException e) {
+ length = in.readInt();
+ type = in.readShort();
+ byte[] dst = new byte[32];
+ in.readBytes(dst);
+ try {
+ seq = new String(dst, "utf-8");
+ } catch (UnsupportedEncodingException e) {
+ }
+ result = in.readInt();
}
- result = in.readInt();
- }
-
- public void readExtra(ByteBuf in) {
- data = new byte[length - HEADER_LENGTH];
- in.readBytes(data, 0, length - HEADER_LENGTH);
- }
-
- public void writeHeader(ByteBuf out) {
- // 先计算总长度
- if (length.equals(0)) {
- length = HEADER_LENGTH + data.length;
+
+ public void readExtra(ByteBuf in) {
+ data = new byte[length - HEADER_LENGTH];
+ in.readBytes(data, 0, length - HEADER_LENGTH);
+ }
+
+ public void writeHeader(ByteBuf out) {
+ // 先计算总长度
+ if (length.equals(0)) {
+ length = HEADER_LENGTH + data.length;
+ }
+
+ out.writeInt(length);
+ out.writeShort(type);
+ out.writeBytes(seq.getBytes(), 0, 32);
+ out.writeInt(result);
+ }
+
+ public void writeExtra(ByteBuf out) {
+ out.writeBytes(data);
+ }
+
+ public Integer getLength() {
+ return length;
+ }
+
+ public void setLength(Integer length) {
+ this.length = length;
+ }
+
+ public Short getType() {
+ return type;
+ }
+
+ public void setType(Short type) {
+ this.type = type;
+ }
+
+ public String getSeq() {
+ return seq;
+ }
+
+ public void setSeq(String seq) {
+ this.seq = seq;
+ }
+
+ public Integer getResult() {
+ return result;
+ }
+
+ public void setResult(Integer result) {
+ this.result = result;
+ }
+
+ public byte[] getData() {
+ return data;
+ }
+
+ public void setData(byte[] data) {
+ this.data = data;
+ this.length = data.length + HEADER_LENGTH;
}
- out.writeInt(length);
- out.writeShort(type);
- out.writeBytes(seq.getBytes(), 0, 32);
- out.writeInt(result);
- }
-
- public void writeExtra(ByteBuf out) {
- out.writeBytes(data);
- }
-
- public Integer getLength() {
- return length;
- }
-
- public void setLength(Integer length) {
- this.length = length;
- }
-
- public Short getType() {
- return type;
- }
-
- public void setType(Short type) {
- this.type = type;
- }
-
- public String getSeq() {
- return seq;
- }
-
- public void setSeq(String seq) {
- this.seq = seq;
- }
-
- public Integer getResult() {
- return result;
- }
-
- public void setResult(Integer result) {
- this.result = result;
- }
-
- public byte[] getData() {
- return data;
- }
-
- public void setData(byte[] data) {
- this.data = data;
- this.length = data.length + HEADER_LENGTH;
- }
-
- protected Integer length = 0;
- protected Short type = 0;
- protected String seq = "";
- protected Integer result = 0;
- protected byte[] data;
+ protected Integer length = 0;
+ protected Short type = 0;
+ protected String seq = "";
+ protected Integer result = 0;
+ protected byte[] data;
}
diff --git a/src/main/java/org/fisco/bcos/channel/proxy/ConnectionPair.java b/src/main/java/org/fisco/bcos/channel/proxy/ConnectionPair.java
index bc31a033b..2f56e1e71 100644
--- a/src/main/java/org/fisco/bcos/channel/proxy/ConnectionPair.java
+++ b/src/main/java/org/fisco/bcos/channel/proxy/ConnectionPair.java
@@ -16,166 +16,165 @@
import org.slf4j.LoggerFactory;
class ConnectionPair {
- private static Logger logger = LoggerFactory.getLogger(ConnectionPair.class);
-
- public ChannelHandlerContext localConnection; // SDK connect
- public ChannelHandlerContext remoteConnection; // node connect
- public Timeout timeout;
-
- private Message message;
- private ConnectionInfo remoteConnectionInfo;
- private List remoteConnectionInfos;
- private ChannelConnections remoteChannelConnections;
- private Server server;
-
- public Message getMessage() {
- return message;
- }
-
- public void setMessage(Message message) {
- this.message = message;
- }
-
- public ConnectionInfo getRemoteConnectionInfo() {
- return remoteConnectionInfo;
- }
-
- public void setRemoteConnectionInfo(ConnectionInfo remoteConnectionInfo) {
- this.remoteConnectionInfo = remoteConnectionInfo;
- }
-
- public List getRemoteConnectionInfos() {
- return remoteConnectionInfos;
- }
-
- public void setRemoteConnectionInfos(List remoteConnectionInfos) {
- this.remoteConnectionInfos = remoteConnectionInfos;
- }
-
- public ChannelConnections getRemoteChannelConnections() {
- return remoteChannelConnections;
- }
-
- public void setRemoteChannelConnections(ChannelConnections remoteChannelConnections) {
- this.remoteChannelConnections = remoteChannelConnections;
- }
-
- public Server getServer() {
- return server;
- }
-
- public void setServer(Server server) {
- this.server = server;
- }
-
- public void init() {
- final ConnectionPair self = this;
- final String seq = message.getSeq();
-
- timeout =
- server
- .getTimeoutHandler()
- .newTimeout(
- new TimerTask() {
- private ConnectionPair selfServer = self;
- private String selfSeq = seq;
-
- @Override
- public void run(Timeout timeout) throws Exception {
- // 处理超时逻辑
- logger.trace("clean timeout session:{}", selfSeq);
-
- selfServer.server.getSeq2Connections().remove(selfSeq);
- }
- },
- 30000,
- TimeUnit.MILLISECONDS);
- }
-
- public void retrySendRemoteMessage() {
- Integer errorCode = 0;
- try {
- // 选取客户端节点
- logger.debug("remoteConnection size :{}", remoteConnectionInfos.size());
-
- remoteConnectionInfo = null;
- if (remoteConnectionInfos.size() > 0) {
- Random random = new SecureRandom();
- Integer index = random.nextInt(remoteConnectionInfos.size());
-
- logger.debug("selected:{}", index);
-
- remoteConnectionInfo = remoteConnectionInfos.get(index);
-
- remoteConnectionInfos.remove(remoteConnectionInfos.get(index));
- }
-
- if (remoteConnectionInfo == null) {
- // 所有节点已尝试,无法再重试了
- logger.error("remoteConnectionInfo null");
-
- errorCode = 99;
- throw new Exception("remoteConnectionInfo null");
- }
-
- ChannelHandlerContext ctx =
- remoteChannelConnections.getNetworkConnectionByHost(
- remoteConnectionInfo.getHost(), remoteConnectionInfo.getPort());
- remoteConnection = ctx;
-
- if (ctx != null && ctx.channel().isActive()) {
- ByteBuf out = ctx.alloc().buffer();
- message.writeHeader(out);
- message.writeExtra(out);
-
- ctx.writeAndFlush(out);
-
- logger.debug(
- "send message to "
- + remoteConnectionInfo.getHost()
- + ":"
- + String.valueOf(remoteConnectionInfo.getPort())
- + " success");
- } else {
- logger.error("local node inactive");
- retrySendRemoteMessage();
- }
- } catch (Exception e) {
- logger.error("send message error", e);
-
- ChannelResponse response = new ChannelResponse();
- response.setErrorCode(errorCode);
- response.setErrorMessage(e.getMessage());
-
- // 找不到连接,错误
- logger.error("connection error 99");
-
- if (message.getType() == 0x20 || message.getType() == 0x21) {
- message.setType((short) 0x21);
- } else if (message.getType() == 0x30 || message.getType() == 0x31) {
- message.setType((short) 0x31);
- } else {
- // ethereum消息,不用改类型
- }
-
- message.setResult(99);
-
- ByteBuf out = localConnection.alloc().buffer();
- message.writeHeader(out);
- message.writeExtra(out);
-
- localConnection.writeAndFlush(out);
-
- // 彻底失败后,删掉这个seq
- if (message.getSeq() != null) {
- server.getSeq2Connections().remove(message.getSeq());
- }
-
- if (timeout != null) {
- timeout.cancel();
- }
-
- return;
+ private static Logger logger = LoggerFactory.getLogger(ConnectionPair.class);
+
+ public ChannelHandlerContext localConnection; // SDK connect
+ public ChannelHandlerContext remoteConnection; // node connect
+ public Timeout timeout;
+
+ private Message message;
+ private ConnectionInfo remoteConnectionInfo;
+ private List remoteConnectionInfos;
+ private ChannelConnections remoteChannelConnections;
+ private Server server;
+
+ public Message getMessage() {
+ return message;
+ }
+
+ public void setMessage(Message message) {
+ this.message = message;
+ }
+
+ public ConnectionInfo getRemoteConnectionInfo() {
+ return remoteConnectionInfo;
+ }
+
+ public void setRemoteConnectionInfo(ConnectionInfo remoteConnectionInfo) {
+ this.remoteConnectionInfo = remoteConnectionInfo;
+ }
+
+ public List getRemoteConnectionInfos() {
+ return remoteConnectionInfos;
+ }
+
+ public void setRemoteConnectionInfos(List remoteConnectionInfos) {
+ this.remoteConnectionInfos = remoteConnectionInfos;
+ }
+
+ public ChannelConnections getRemoteChannelConnections() {
+ return remoteChannelConnections;
+ }
+
+ public void setRemoteChannelConnections(ChannelConnections remoteChannelConnections) {
+ this.remoteChannelConnections = remoteChannelConnections;
+ }
+
+ public Server getServer() {
+ return server;
+ }
+
+ public void setServer(Server server) {
+ this.server = server;
+ }
+
+ public void init() {
+ final ConnectionPair self = this;
+ final String seq = message.getSeq();
+
+ timeout =
+ server.getTimeoutHandler()
+ .newTimeout(
+ new TimerTask() {
+ private ConnectionPair selfServer = self;
+ private String selfSeq = seq;
+
+ @Override
+ public void run(Timeout timeout) throws Exception {
+ // 处理超时逻辑
+ logger.trace("clean timeout session:{}", selfSeq);
+
+ selfServer.server.getSeq2Connections().remove(selfSeq);
+ }
+ },
+ 30000,
+ TimeUnit.MILLISECONDS);
+ }
+
+ public void retrySendRemoteMessage() {
+ Integer errorCode = 0;
+ try {
+ // 选取客户端节点
+ logger.debug("remoteConnection size :{}", remoteConnectionInfos.size());
+
+ remoteConnectionInfo = null;
+ if (remoteConnectionInfos.size() > 0) {
+ Random random = new SecureRandom();
+ Integer index = random.nextInt(remoteConnectionInfos.size());
+
+ logger.debug("selected:{}", index);
+
+ remoteConnectionInfo = remoteConnectionInfos.get(index);
+
+ remoteConnectionInfos.remove(remoteConnectionInfos.get(index));
+ }
+
+ if (remoteConnectionInfo == null) {
+ // 所有节点已尝试,无法再重试了
+ logger.error("remoteConnectionInfo null");
+
+ errorCode = 99;
+ throw new Exception("remoteConnectionInfo null");
+ }
+
+ ChannelHandlerContext ctx =
+ remoteChannelConnections.getNetworkConnectionByHost(
+ remoteConnectionInfo.getHost(), remoteConnectionInfo.getPort());
+ remoteConnection = ctx;
+
+ if (ctx != null && ctx.channel().isActive()) {
+ ByteBuf out = ctx.alloc().buffer();
+ message.writeHeader(out);
+ message.writeExtra(out);
+
+ ctx.writeAndFlush(out);
+
+ logger.debug(
+ "send message to "
+ + remoteConnectionInfo.getHost()
+ + ":"
+ + String.valueOf(remoteConnectionInfo.getPort())
+ + " success");
+ } else {
+ logger.error("local node inactive");
+ retrySendRemoteMessage();
+ }
+ } catch (Exception e) {
+ logger.error("send message error", e);
+
+ ChannelResponse response = new ChannelResponse();
+ response.setErrorCode(errorCode);
+ response.setErrorMessage(e.getMessage());
+
+ // 找不到连接,错误
+ logger.error("connection error 99");
+
+ if (message.getType() == 0x20 || message.getType() == 0x21) {
+ message.setType((short) 0x21);
+ } else if (message.getType() == 0x30 || message.getType() == 0x31) {
+ message.setType((short) 0x31);
+ } else {
+ // ethereum消息,不用改类型
+ }
+
+ message.setResult(99);
+
+ ByteBuf out = localConnection.alloc().buffer();
+ message.writeHeader(out);
+ message.writeExtra(out);
+
+ localConnection.writeAndFlush(out);
+
+ // 彻底失败后,删掉这个seq
+ if (message.getSeq() != null) {
+ server.getSeq2Connections().remove(message.getSeq());
+ }
+
+ if (timeout != null) {
+ timeout.cancel();
+ }
+
+ return;
+ }
}
- }
}
diff --git a/src/main/java/org/fisco/bcos/channel/proxy/ResponseCallback.java b/src/main/java/org/fisco/bcos/channel/proxy/ResponseCallback.java
index 0220fe7e2..8fd4e774f 100644
--- a/src/main/java/org/fisco/bcos/channel/proxy/ResponseCallback.java
+++ b/src/main/java/org/fisco/bcos/channel/proxy/ResponseCallback.java
@@ -3,5 +3,5 @@
import org.fisco.bcos.channel.handler.Message;
public interface ResponseCallback {
- public void onResponse(Message response);
+ public void onResponse(Message response);
}
diff --git a/src/main/java/org/fisco/bcos/channel/proxy/Server.java b/src/main/java/org/fisco/bcos/channel/proxy/Server.java
index 2d3f5407a..517cc60d3 100644
--- a/src/main/java/org/fisco/bcos/channel/proxy/Server.java
+++ b/src/main/java/org/fisco/bcos/channel/proxy/Server.java
@@ -8,7 +8,13 @@
import io.netty.util.Timer;
import java.io.UnsupportedEncodingException;
import java.security.SecureRandom;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import javax.net.ssl.SSLException;
import org.fisco.bcos.channel.handler.ChannelConnections;
@@ -19,533 +25,553 @@
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
public class Server {
- private static Logger logger = LoggerFactory.getLogger(Server.class);
+ private static Logger logger = LoggerFactory.getLogger(Server.class);
- class ConnectionCallback implements ChannelConnections.Callback {
- public Server getServer() {
- return server;
- }
-
- public void setServer(Server server) {
- this.server = server;
- }
-
- public Boolean getFromRemote() {
- return fromRemote;
- }
-
- public void setFromRemote(Boolean fromRemote) {
- this.fromRemote = fromRemote;
- }
-
- @Override
- public void onMessage(ChannelHandlerContext ctx, ByteBuf message) {
- try {
- Message msg = new Message();
- msg.readHeader(message);
- msg.readExtra(message);
-
- logger.debug("receive Message type: {}", msg.getType());
-
- if (msg.getType() == 0x20 || msg.getType() == 0x21) {
- logger.debug("channel ");
- } else if (msg.getType() == 0x30 || msg.getType() == 0x31) {
- logger.debug("channel2");
- } else if (msg.getType() == 0x32) {
- logger.debug("topic");
-
- onTopic(ctx, msg);
- return;
- } else if (msg.getType() == 0x12) {
- logger.debug("ethereum");
- } else if (msg.getType() == 0x13) {
- onHeartBeat(ctx, msg);
- return;
- } else if (msg.getType() == 0x1000) {
- logger.debug("transaction message call back.");
- } else {
- logger.error("unknown message:{}", msg.getType());
+ class ConnectionCallback implements ChannelConnections.Callback {
+ public Server getServer() {
+ return server;
}
- if (fromRemote) {
- logger.debug("remote message");
- server.onRemoteMessage(ctx, msg);
- } else {
- logger.debug("local message");
- server.onLocalMessage(ctx, msg);
+ public void setServer(Server server) {
+ this.server = server;
}
- } finally {
- message.release();
- }
- }
- @Override
- public void onConnect(ChannelHandlerContext ctx) {
- // 成功连接到新节点,发送topic
- if (fromRemote) {
- try {
- logger.debug("endpoint connection established,send topic");
- broadcastTopic(ctx);
- } catch (Exception e) {
- logger.error("error ", e);
+ public Boolean getFromRemote() {
+ return fromRemote;
}
- }
- }
- @Override
- public void onDisconnect(ChannelHandlerContext ctx) {
- // 有sdk断开,需更新topic
- if (!fromRemote) {
- // 需要清除该连接的信息
- logger.debug("SDK disconnect,update and broadcast topic");
-
- broadcastTopic();
- }
- }
-
- private Server server;
- private Boolean fromRemote = false;
- }
-
- public ChannelConnections getLocalConnections() {
- return localConnections;
- }
+ public void setFromRemote(Boolean fromRemote) {
+ this.fromRemote = fromRemote;
+ }
- public void setLocalConnections(ChannelConnections localConnections) {
- this.localConnections = localConnections;
- }
+ @Override
+ public void onMessage(ChannelHandlerContext ctx, ByteBuf message) {
+ try {
+ Message msg = new Message();
+ msg.readHeader(message);
+ msg.readExtra(message);
+
+ logger.debug("receive Message type: {}", msg.getType());
+
+ if (msg.getType() == 0x20 || msg.getType() == 0x21) {
+ logger.debug("channel ");
+ } else if (msg.getType() == 0x30 || msg.getType() == 0x31) {
+ logger.debug("channel2");
+ } else if (msg.getType() == 0x32) {
+ logger.debug("topic");
+
+ onTopic(ctx, msg);
+ return;
+ } else if (msg.getType() == 0x12) {
+ logger.debug("ethereum");
+ } else if (msg.getType() == 0x13) {
+ onHeartBeat(ctx, msg);
+ return;
+ } else if (msg.getType() == 0x1000) {
+ logger.debug("transaction message call back.");
+ } else {
+ logger.error("unknown message:{}", msg.getType());
+ }
+
+ if (fromRemote) {
+ logger.debug("remote message");
+ server.onRemoteMessage(ctx, msg);
+ } else {
+ logger.debug("local message");
+ server.onLocalMessage(ctx, msg);
+ }
+ } finally {
+ message.release();
+ }
+ }
- public ChannelConnections getRemoteConnections() {
- return remoteConnections;
- }
+ @Override
+ public void onConnect(ChannelHandlerContext ctx) {
+ // 成功连接到新节点,发送topic
+ if (fromRemote) {
+ try {
+ logger.debug("endpoint connection established,send topic");
+ broadcastTopic(ctx);
+ } catch (Exception e) {
+ logger.error("error ", e);
+ }
+ }
+ }
- public void setRemoteConnections(ChannelConnections connections) {
- this.remoteConnections = connections;
- }
+ @Override
+ public void onDisconnect(ChannelHandlerContext ctx) {
+ // 有sdk断开,需更新topic
+ if (!fromRemote) {
+ // 需要清除该连接的信息
+ logger.debug("SDK disconnect,update and broadcast topic");
- public Map getSeq2Connections() {
- return seq2Connections;
- }
+ broadcastTopic();
+ }
+ }
- public void setSeq2Connections(Map seq2Connections) {
- this.seq2Connections = seq2Connections;
- }
+ private Server server;
+ private Boolean fromRemote = false;
+ }
- public Integer getBindPort() {
- return bindPort;
- }
+ public ChannelConnections getLocalConnections() {
+ return localConnections;
+ }
- public void setBindPort(Integer bindPort) {
- this.bindPort = bindPort;
- }
+ public void setLocalConnections(ChannelConnections localConnections) {
+ this.localConnections = localConnections;
+ }
- public Timer getTimeoutHandler() {
- return timeoutHandler;
- }
+ public ChannelConnections getRemoteConnections() {
+ return remoteConnections;
+ }
- public void setTimeoutHandler(Timer timeoutHandler) {
- this.timeoutHandler = timeoutHandler;
- }
+ public void setRemoteConnections(ChannelConnections connections) {
+ this.remoteConnections = connections;
+ }
- public void run() throws SSLException {
- logger.debug("init ProxyServer");
+ public Map getSeq2Connections() {
+ return seq2Connections;
+ }
- try {
- ConnectionCallback localConnectionCallback = new ConnectionCallback();
- localConnectionCallback.setServer(this);
- localConnectionCallback.setFromRemote(false);
+ public void setSeq2Connections(Map seq2Connections) {
+ this.seq2Connections = seq2Connections;
+ }
- ConnectionCallback remoteConnectionCallback = new ConnectionCallback();
- remoteConnectionCallback.setServer(this);
- remoteConnectionCallback.setFromRemote(true);
+ public Integer getBindPort() {
+ return bindPort;
+ }
- localConnections.setCallback(localConnectionCallback);
- localConnections.startListen(bindPort);
+ public void setBindPort(Integer bindPort) {
+ this.bindPort = bindPort;
+ }
- remoteConnections.setCallback(remoteConnectionCallback);
- remoteConnections.init();
- remoteConnections.setThreadPool(threadPool);
- remoteConnections.startConnect();
- } catch (Exception e) {
- logger.error("error ", e);
+ public Timer getTimeoutHandler() {
+ return timeoutHandler;
+ }
- throw e;
+ public void setTimeoutHandler(Timer timeoutHandler) {
+ this.timeoutHandler = timeoutHandler;
}
- }
-
- public void broadcastTopic() {
- broadcastTopic(null);
- }
-
- public void broadcastTopic(ChannelHandlerContext ctx) {
- try {
- Message message = new Message();
- message.setResult(0);
- message.setType((short) 0x32); // topic设置topic消息0x32
- message.setSeq(UUID.randomUUID().toString().replaceAll("-", ""));
-
- // 综合所有的topics
- Set allTopics = new HashSet();
- for (ConnectionInfo connectionInfo : localConnections.getConnections()) {
- // 有效的连接,才增加到全局topic
- ChannelHandlerContext localCtx =
- localConnections.getNetworkConnectionByHost(
- connectionInfo.getHost(), connectionInfo.getPort());
-
- if (localCtx != null && localCtx.channel().isActive()) {
- logger.debug(
- "node:{}:{} follow topics: {}",
- connectionInfo.getHost(),
- connectionInfo.getPort(),
- connectionInfo.getTopics());
- allTopics.addAll(connectionInfo.getTopics());
- }
- }
- message.setData(objectMapper.writeValueAsBytes(allTopics.toArray()));
+ public void run() throws SSLException {
+ logger.debug("init ProxyServer");
- logger.debug("all topics: {}", new String(message.getData()));
+ try {
+ ConnectionCallback localConnectionCallback = new ConnectionCallback();
+ localConnectionCallback.setServer(this);
+ localConnectionCallback.setFromRemote(false);
- if (ctx == null) {
- // 广播到所有远端节点
- for (String key : remoteConnections.getNetworkConnections().keySet()) {
- ChannelHandlerContext remoteCtx = remoteConnections.getNetworkConnections().get(key);
+ ConnectionCallback remoteConnectionCallback = new ConnectionCallback();
+ remoteConnectionCallback.setServer(this);
+ remoteConnectionCallback.setFromRemote(true);
- if (remoteCtx != null && remoteCtx.channel().isActive()) {
- ByteBuf out = remoteCtx.alloc().buffer();
- message.writeHeader(out);
- message.writeExtra(out);
+ localConnections.setCallback(localConnectionCallback);
+ localConnections.startListen(bindPort);
- if (remoteCtx != null && remoteCtx.channel().isActive()) {
- logger.debug(
- "send topic {}:{}",
- ((SocketChannel) remoteCtx.channel())
- .remoteAddress()
- .getAddress()
- .getHostAddress(),
- ((SocketChannel) remoteCtx.channel()).remoteAddress().getPort());
+ remoteConnections.setCallback(remoteConnectionCallback);
+ remoteConnections.init();
+ remoteConnections.setThreadPool(threadPool);
+ remoteConnections.startConnect();
+ } catch (Exception e) {
+ logger.error("error ", e);
- remoteCtx.writeAndFlush(out);
- }
- }
+ throw e;
}
- } else {
- // 发送到指定远端节点
- logger.debug(
- "topic send to {}:{}",
- ((SocketChannel) ctx.channel()).remoteAddress().getAddress().getHostAddress(),
- ((SocketChannel) ctx.channel()).remoteAddress().getPort());
-
- ByteBuf out = ctx.alloc().buffer();
- message.writeHeader(out);
- message.writeExtra(out);
-
- ctx.writeAndFlush(out);
- }
- } catch (Exception e) {
- logger.error("error ", e);
}
- }
-
- public void onLocalMessage(ChannelHandlerContext ctx, Message message) {
- try {
- logger.debug("sdk request: " + message.getSeq());
- ChannelHandlerContext remoteCtx = null;
-
- ConnectionPair pair = seq2Connections.get(message.getSeq());
-
- if (pair != null) {
- // 已有这个seq,发往远端的响应
- logger.debug("seq existed");
-
- // 发送到远端的响应
- remoteCtx = pair.remoteConnection;
-
- if (message.getType() != 0x31) {
- pair.localConnection = ctx;
- }
+ public void broadcastTopic() {
+ broadcastTopic(null);
+ }
- ByteBuf out = remoteCtx.alloc().buffer();
- message.writeHeader(out);
- message.writeExtra(out);
-
- logger.debug(
- "msg send to:{}:{}",
- ((SocketChannel) remoteCtx.channel()).remoteAddress().getAddress().getHostAddress(),
- ((SocketChannel) remoteCtx.channel()).remoteAddress().getPort());
- remoteCtx.writeAndFlush(out);
- } else {
- pair = new ConnectionPair();
- pair.localConnection = ctx;
- pair.setServer(this);
- pair.setMessage(message);
-
- // 没有这个seq,可能是新发请求或者新收到的push
- // 本地发往远程的消息,如果是链上链下,需要按给定的nodeID发
- if (message.getType() == 0x20 || message.getType() == 0x21) {
- // 获取nodeID
- logger.debug("channel message v1");
- if (message.getData().length < 256) {
- logger.error(
- "wrong channel message, length less than 256:{}", message.getData().length);
- }
-
- // 获取nodeID对应的连接,检查可用性
- String nodeID = new String(message.getData(), 128, 128);
-
- logger.debug("forward:{}", nodeID, message.getData());
- for (ConnectionInfo conn : remoteConnections.getConnections()) {
- if (conn.getNodeID().equals(nodeID)) {
- remoteCtx =
- remoteConnections.getNetworkConnectionByHost(conn.getHost(), conn.getPort());
- pair.remoteConnection = remoteCtx;
-
- break;
+ public void broadcastTopic(ChannelHandlerContext ctx) {
+ try {
+ Message message = new Message();
+ message.setResult(0);
+ message.setType((short) 0x32); // topic设置topic消息0x32
+ message.setSeq(UUID.randomUUID().toString().replaceAll("-", ""));
+
+ // 综合所有的topics
+ Set allTopics = new HashSet();
+ for (ConnectionInfo connectionInfo : localConnections.getConnections()) {
+ // 有效的连接,才增加到全局topic
+ ChannelHandlerContext localCtx =
+ localConnections.getNetworkConnectionByHost(
+ connectionInfo.getHost(), connectionInfo.getPort());
+
+ if (localCtx != null && localCtx.channel().isActive()) {
+ logger.debug(
+ "node:{}:{} follow topics: {}",
+ connectionInfo.getHost(),
+ connectionInfo.getPort(),
+ connectionInfo.getTopics());
+ allTopics.addAll(connectionInfo.getTopics());
+ }
}
- }
-
- if (remoteCtx == null || !remoteCtx.channel().isActive()) {
- // 找不到连接,错误
- logger.error("connect exception,error 99");
- if (message.getType() == 0x20 || message.getType() == 0x21) {
- message.setType((short) 0x21);
+ message.setData(objectMapper.writeValueAsBytes(allTopics.toArray()));
+
+ logger.debug("all topics: {}", new String(message.getData()));
+
+ if (ctx == null) {
+ // 广播到所有远端节点
+ for (String key : remoteConnections.getNetworkConnections().keySet()) {
+ ChannelHandlerContext remoteCtx =
+ remoteConnections.getNetworkConnections().get(key);
+
+ if (remoteCtx != null && remoteCtx.channel().isActive()) {
+ ByteBuf out = remoteCtx.alloc().buffer();
+ message.writeHeader(out);
+ message.writeExtra(out);
+
+ if (remoteCtx != null && remoteCtx.channel().isActive()) {
+ logger.debug(
+ "send topic {}:{}",
+ ((SocketChannel) remoteCtx.channel())
+ .remoteAddress()
+ .getAddress()
+ .getHostAddress(),
+ ((SocketChannel) remoteCtx.channel())
+ .remoteAddress()
+ .getPort());
+
+ remoteCtx.writeAndFlush(out);
+ }
+ }
+ }
} else {
- message.setType((short) 0x31);
+ // 发送到指定远端节点
+ logger.debug(
+ "topic send to {}:{}",
+ ((SocketChannel) ctx.channel())
+ .remoteAddress()
+ .getAddress()
+ .getHostAddress(),
+ ((SocketChannel) ctx.channel()).remoteAddress().getPort());
+
+ ByteBuf out = ctx.alloc().buffer();
+ message.writeHeader(out);
+ message.writeExtra(out);
+
+ ctx.writeAndFlush(out);
}
+ } catch (Exception e) {
+ logger.error("error ", e);
+ }
+ }
- message.setResult(99);
-
- ByteBuf out = ctx.alloc().buffer();
- message.writeHeader(out);
- message.writeExtra(out);
-
- ctx.writeAndFlush(out);
+ public void onLocalMessage(ChannelHandlerContext ctx, Message message) {
+ try {
+ logger.debug("sdk request: " + message.getSeq());
- return;
- }
+ ChannelHandlerContext remoteCtx = null;
- ByteBuf out = remoteCtx.alloc().buffer();
- message.writeHeader(out);
- message.writeExtra(out);
+ ConnectionPair pair = seq2Connections.get(message.getSeq());
- logger.debug(
- "send to:{}:{}",
- ((SocketChannel) remoteCtx.channel()).remoteAddress().getAddress().getHostAddress(),
- ((SocketChannel) remoteCtx.channel()).remoteAddress().getPort());
- remoteCtx.writeAndFlush(out);
- pair.init();
- } else {
- logger.debug("other type message,ConnectionPair");
+ if (pair != null) {
+ // 已有这个seq,发往远端的响应
+ logger.debug("seq existed");
- pair.setRemoteChannelConnections(remoteConnections);
+ // 发送到远端的响应
+ remoteCtx = pair.remoteConnection;
- List remoteConnectionInfos = new ArrayList();
- remoteConnectionInfos.addAll(remoteConnections.getConnections());
- pair.setRemoteConnectionInfos(remoteConnectionInfos);
+ if (message.getType() != 0x31) {
+ pair.localConnection = ctx;
+ }
- seq2Connections.put(message.getSeq(), pair);
+ ByteBuf out = remoteCtx.alloc().buffer();
+ message.writeHeader(out);
+ message.writeExtra(out);
- pair.init();
- pair.retrySendRemoteMessage();
+ logger.debug(
+ "msg send to:{}:{}",
+ ((SocketChannel) remoteCtx.channel())
+ .remoteAddress()
+ .getAddress()
+ .getHostAddress(),
+ ((SocketChannel) remoteCtx.channel()).remoteAddress().getPort());
+ remoteCtx.writeAndFlush(out);
+ } else {
+ pair = new ConnectionPair();
+ pair.localConnection = ctx;
+ pair.setServer(this);
+ pair.setMessage(message);
+
+ // 没有这个seq,可能是新发请求或者新收到的push
+ // 本地发往远程的消息,如果是链上链下,需要按给定的nodeID发
+ if (message.getType() == 0x20 || message.getType() == 0x21) {
+ // 获取nodeID
+ logger.debug("channel message v1");
+ if (message.getData().length < 256) {
+ logger.error(
+ "wrong channel message, length less than 256:{}",
+ message.getData().length);
+ }
+
+ // 获取nodeID对应的连接,检查可用性
+ String nodeID = new String(message.getData(), 128, 128);
+
+ logger.debug("forward:{}", nodeID, message.getData());
+ for (ConnectionInfo conn : remoteConnections.getConnections()) {
+ if (conn.getNodeID().equals(nodeID)) {
+ remoteCtx =
+ remoteConnections.getNetworkConnectionByHost(
+ conn.getHost(), conn.getPort());
+ pair.remoteConnection = remoteCtx;
+
+ break;
+ }
+ }
+
+ if (remoteCtx == null || !remoteCtx.channel().isActive()) {
+ // 找不到连接,错误
+ logger.error("connect exception,error 99");
+
+ if (message.getType() == 0x20 || message.getType() == 0x21) {
+ message.setType((short) 0x21);
+ } else {
+ message.setType((short) 0x31);
+ }
+
+ message.setResult(99);
+
+ ByteBuf out = ctx.alloc().buffer();
+ message.writeHeader(out);
+ message.writeExtra(out);
+
+ ctx.writeAndFlush(out);
+
+ return;
+ }
+
+ ByteBuf out = remoteCtx.alloc().buffer();
+ message.writeHeader(out);
+ message.writeExtra(out);
+
+ logger.debug(
+ "send to:{}:{}",
+ ((SocketChannel) remoteCtx.channel())
+ .remoteAddress()
+ .getAddress()
+ .getHostAddress(),
+ ((SocketChannel) remoteCtx.channel()).remoteAddress().getPort());
+ remoteCtx.writeAndFlush(out);
+ pair.init();
+ } else {
+ logger.debug("other type message,ConnectionPair");
+
+ pair.setRemoteChannelConnections(remoteConnections);
+
+ List remoteConnectionInfos = new ArrayList();
+ remoteConnectionInfos.addAll(remoteConnections.getConnections());
+ pair.setRemoteConnectionInfos(remoteConnectionInfos);
+
+ seq2Connections.put(message.getSeq(), pair);
+
+ pair.init();
+ pair.retrySendRemoteMessage();
+ }
+ }
+ } catch (Exception e) {
+ logger.error("error ", e);
}
- }
- } catch (Exception e) {
- logger.error("error ", e);
}
- }
- public void onRemoteMessage(ChannelHandlerContext ctx, Message message) {
- try {
- logger.debug("processing : " + message.getSeq());
+ public void onRemoteMessage(ChannelHandlerContext ctx, Message message) {
+ try {
+ logger.debug("processing : " + message.getSeq());
+
+ ChannelHandlerContext localCtx = null;
+
+ ConnectionPair pair = seq2Connections.get(message.getSeq());
+
+ if (message.getType() == 0x30) {
+ // 链上链下二期,需要找到关注该topic的连接
+ Short length = (short) message.getData()[0];
+ String topic = new String(message.getData(), 1, length - 1);
+
+ Set topicCtxs = new HashSet();
+ for (ConnectionInfo connectionInfo : localConnections.getConnections()) {
+ if (connectionInfo.getTopics().contains(topic)) {
+ ChannelHandlerContext topicCtx =
+ localConnections.getNetworkConnectionByHost(
+ connectionInfo.getHost(), connectionInfo.getPort());
+
+ if (topicCtx != null && topicCtx.channel().isActive()) {
+ topicCtxs.add(topicCtx);
+ }
+ }
+ }
+
+ logger.debug("send topic:{} sum{} follow topic", topic, topicCtxs.size());
+
+ if (topicCtxs.isEmpty()) {
+ // 找不到连接,错误
+ logger.error("connection not found,error 99");
+
+ message.setType((short) 0x31);
+ message.setResult(99);
+
+ ByteBuf out = ctx.alloc().buffer();
+ message.writeHeader(out);
+ message.writeExtra(out);
+
+ ctx.writeAndFlush(out);
+
+ return;
+ }
+
+ // 随机下发
+ Random random = new SecureRandom();
+ Integer index = random.nextInt(topicCtxs.size());
+ ChannelHandlerContext target = (ChannelHandlerContext) topicCtxs.toArray()[index];
+
+ logger.debug(
+ "send to {}:{}",
+ ((SocketChannel) target.channel())
+ .remoteAddress()
+ .getAddress()
+ .getHostAddress(),
+ ((SocketChannel) target.channel()).remoteAddress().getPort());
+
+ localCtx = target;
+
+ if (pair == null) {
+ pair = new ConnectionPair();
+ pair.localConnection = localCtx;
+ pair.remoteConnection = ctx;
+ pair.setServer(this);
+ pair.setMessage(message);
+
+ seq2Connections.put(message.getSeq(), pair);
+ pair.init();
+ } else {
+ pair.remoteConnection = ctx;
+ }
+ } else {
+ if (pair != null) {
+ // 已有这个seq,可能是发送响应或者收到回包消息
+ logger.debug("seq existed");
- ChannelHandlerContext localCtx = null;
+ // 收到来自远端的回包
+ localCtx = pair.localConnection;
- ConnectionPair pair = seq2Connections.get(message.getSeq());
+ if (message.getResult() != 0 && message.getType() == 0x31) {
+ // 链上链下二期错误时,执行retry
+ logger.error("endpoint error:{},retry", message.getResult());
- if (message.getType() == 0x30) {
- // 链上链下二期,需要找到关注该topic的连接
- Short length = (short) message.getData()[0];
- String topic = new String(message.getData(), 1, length - 1);
+ pair.retrySendRemoteMessage();
+ return;
+ }
- Set topicCtxs = new HashSet();
- for (ConnectionInfo connectionInfo : localConnections.getConnections()) {
- if (connectionInfo.getTopics().contains(topic)) {
- ChannelHandlerContext topicCtx =
- localConnections.getNetworkConnectionByHost(
- connectionInfo.getHost(), connectionInfo.getPort());
+ pair.remoteConnection = ctx;
+ } else {
+ // 没有这个seq,可能是新发请求或者新收到的push
- if (topicCtx != null && topicCtx.channel().isActive()) {
- topicCtxs.add(topicCtx);
+ // 其他消息(链上链下一期),随机发
+ localCtx = localConnections.randomNetworkConnection(null);
+ }
}
- }
- }
-
- logger.debug("send topic:{} sum{} follow topic", topic, topicCtxs.size());
-
- if (topicCtxs.isEmpty()) {
- // 找不到连接,错误
- logger.error("connection not found,error 99");
-
- message.setType((short) 0x31);
- message.setResult(99);
- ByteBuf out = ctx.alloc().buffer();
- message.writeHeader(out);
- message.writeExtra(out);
+ if (localCtx == null || !localCtx.channel().isActive()) {
+ // 找不到连接,错误
+ logger.error("connect unavailable,error 99");
- ctx.writeAndFlush(out);
+ if (message.getType() == 0x20 || message.getType() == 0x21) {
+ message.setType((short) 0x21);
+ } else {
+ message.setType((short) 0x31);
+ }
- return;
- }
-
- // 随机下发
- Random random = new SecureRandom();
- Integer index = random.nextInt(topicCtxs.size());
- ChannelHandlerContext target = (ChannelHandlerContext) topicCtxs.toArray()[index];
-
- logger.debug(
- "send to {}:{}",
- ((SocketChannel) target.channel()).remoteAddress().getAddress().getHostAddress(),
- ((SocketChannel) target.channel()).remoteAddress().getPort());
-
- localCtx = target;
-
- if (pair == null) {
- pair = new ConnectionPair();
- pair.localConnection = localCtx;
- pair.remoteConnection = ctx;
- pair.setServer(this);
- pair.setMessage(message);
-
- seq2Connections.put(message.getSeq(), pair);
- pair.init();
- } else {
- pair.remoteConnection = ctx;
- }
- } else {
- if (pair != null) {
- // 已有这个seq,可能是发送响应或者收到回包消息
- logger.debug("seq existed");
+ message.setResult(99);
- // 收到来自远端的回包
- localCtx = pair.localConnection;
+ ByteBuf out = ctx.alloc().buffer();
+ message.writeHeader(out);
+ message.writeExtra(out);
- if (message.getResult() != 0 && message.getType() == 0x31) {
- // 链上链下二期错误时,执行retry
- logger.error("endpoint error:{},retry", message.getResult());
+ ctx.writeAndFlush(out);
- pair.retrySendRemoteMessage();
- return;
- }
+ return;
+ }
- pair.remoteConnection = ctx;
- } else {
- // 没有这个seq,可能是新发请求或者新收到的push
+ ByteBuf out = localCtx.alloc().buffer();
+ message.writeHeader(out);
+ message.writeExtra(out);
- // 其他消息(链上链下一期),随机发
- localCtx = localConnections.randomNetworkConnection();
+ logger.debug(
+ "send to:{}:{}",
+ ((SocketChannel) localCtx.channel())
+ .remoteAddress()
+ .getAddress()
+ .getHostAddress(),
+ ((SocketChannel) localCtx.channel()).remoteAddress().getPort());
+ localCtx.writeAndFlush(out);
+ } catch (Exception e) {
+ logger.error("error ", e);
}
- }
-
- if (localCtx == null || !localCtx.channel().isActive()) {
- // 找不到连接,错误
- logger.error("connect unavailable,error 99");
+ }
- if (message.getType() == 0x20 || message.getType() == 0x21) {
- message.setType((short) 0x21);
- } else {
- message.setType((short) 0x31);
+ public void onHeartBeat(ChannelHandlerContext ctx, Message message) {
+ String content = "1";
+ try {
+ content = new String(message.getData(), "utf-8");
+ } catch (UnsupportedEncodingException e) {
+ logger.error("unexpected heartbeat ");
+ } catch (Exception e) {
+ logger.error("heartbeat error");
}
- message.setResult(99);
+ if (content.equals("0")) {
+ Message response = new Message();
- ByteBuf out = ctx.alloc().buffer();
- message.writeHeader(out);
- message.writeExtra(out);
+ response.setSeq(message.getSeq());
+ response.setResult(0);
+ response.setType((short) 0x13);
+ response.setData("1".getBytes());
- ctx.writeAndFlush(out);
-
- return;
- }
-
- ByteBuf out = localCtx.alloc().buffer();
- message.writeHeader(out);
- message.writeExtra(out);
+ ByteBuf out = ctx.alloc().buffer();
+ response.writeHeader(out);
+ response.writeExtra(out);
- logger.debug(
- "send to:{}:{}",
- ((SocketChannel) localCtx.channel()).remoteAddress().getAddress().getHostAddress(),
- ((SocketChannel) localCtx.channel()).remoteAddress().getPort());
- localCtx.writeAndFlush(out);
- } catch (Exception e) {
- logger.error("error ", e);
- }
- }
-
- public void onHeartBeat(ChannelHandlerContext ctx, Message message) {
- String content = "1";
- try {
- content = new String(message.getData(), "utf-8");
- } catch (UnsupportedEncodingException e) {
- logger.error("unexpected heartbeat ");
- } catch (Exception e) {
- logger.error("heartbeat error");
+ ctx.writeAndFlush(out);
+ } else if (content.equals("1")) {
+ }
}
- if (content.equals("0")) {
- Message response = new Message();
+ public void onTopic(ChannelHandlerContext ctx, Message message) {
+ logger.debug("SDK topics message: {} {}", message.getSeq(), new String(message.getData()));
+ String host = ((SocketChannel) ctx.channel()).remoteAddress().getAddress().getHostAddress();
+ Integer port = ((SocketChannel) ctx.channel()).remoteAddress().getPort(); //
+ ConnectionInfo info = localConnections.getConnectionInfo(host, port);
- response.setSeq(message.getSeq());
- response.setResult(0);
- response.setType((short) 0x13);
- response.setData("1".getBytes());
+ if (info != null) {
+ try {
+ List topics = objectMapper.readValue(message.getData(), List.class);
- ByteBuf out = ctx.alloc().buffer();
- response.writeHeader(out);
- response.writeExtra(out);
+ info.setTopics(topics);
- ctx.writeAndFlush(out);
- } else if (content.equals("1")) {
+ broadcastTopic();
+ } catch (Exception e) {
+ logger.error("parse topic error", e);
+ }
+ }
}
- }
- public void onTopic(ChannelHandlerContext ctx, Message message) {
- logger.debug("SDK topics message: {} {}", message.getSeq(), new String(message.getData()));
- String host = ((SocketChannel) ctx.channel()).remoteAddress().getAddress().getHostAddress();
- Integer port = ((SocketChannel) ctx.channel()).remoteAddress().getPort(); //
- ConnectionInfo info = localConnections.getConnectionInfo(host, port);
+ public ThreadPoolTaskExecutor getThreadPool() {
+ return threadPool;
+ }
- if (info != null) {
- try {
- List topics = objectMapper.readValue(message.getData(), List.class);
+ public void setThreadPool(ThreadPoolTaskExecutor threadPool) {
+ this.threadPool = threadPool;
+ }
- info.setTopics(topics);
+ // private String orgID;
+ private ChannelConnections localConnections = new ChannelConnections();
+ private ChannelConnections remoteConnections;
+ private Map seq2Connections =
+ new ConcurrentHashMap();
+ private Integer bindPort = 8830;
+ private ObjectMapper objectMapper = new ObjectMapper();
+ private Timer timeoutHandler = new HashedWheelTimer();
- broadcastTopic();
- } catch (Exception e) {
- logger.error("parse topic error", e);
- }
- }
- }
-
- public ThreadPoolTaskExecutor getThreadPool() {
- return threadPool;
- }
-
- public void setThreadPool(ThreadPoolTaskExecutor threadPool) {
- this.threadPool = threadPool;
- }
-
- // private String orgID;
- private ChannelConnections localConnections = new ChannelConnections();
- private ChannelConnections remoteConnections;
- private Map seq2Connections =
- new ConcurrentHashMap();
- private Integer bindPort = 8830;
- private ObjectMapper objectMapper = new ObjectMapper();
- private Timer timeoutHandler = new HashedWheelTimer();
-
- private ThreadPoolTaskExecutor threadPool;
+ private ThreadPoolTaskExecutor threadPool;
}
diff --git a/src/main/java/org/fisco/bcos/web3j/abi/EventEncoder.java b/src/main/java/org/fisco/bcos/web3j/abi/EventEncoder.java
index 4280c0b20..d0d18206d 100644
--- a/src/main/java/org/fisco/bcos/web3j/abi/EventEncoder.java
+++ b/src/main/java/org/fisco/bcos/web3j/abi/EventEncoder.java
@@ -13,31 +13,31 @@
*/
public class EventEncoder {
- private EventEncoder() {}
+ private EventEncoder() {}
- public static String encode(Event event) {
+ public static String encode(Event event) {
- String methodSignature = buildMethodSignature(event.getName(), event.getParameters());
+ String methodSignature = buildMethodSignature(event.getName(), event.getParameters());
- return buildEventSignature(methodSignature);
- }
+ return buildEventSignature(methodSignature);
+ }
- static String buildMethodSignature(
- String methodName, List> parameters) {
+ static String buildMethodSignature(
+ String methodName, List> parameters) {
- StringBuilder result = new StringBuilder();
- result.append(methodName);
- result.append("(");
- String params =
- parameters.stream().map(p -> Utils.getTypeName(p)).collect(Collectors.joining(","));
- result.append(params);
- result.append(")");
- return result.toString();
- }
+ StringBuilder result = new StringBuilder();
+ result.append(methodName);
+ result.append("(");
+ String params =
+ parameters.stream().map(p -> Utils.getTypeName(p)).collect(Collectors.joining(","));
+ result.append(params);
+ result.append(")");
+ return result.toString();
+ }
- public static String buildEventSignature(String methodSignature) {
- byte[] input = methodSignature.getBytes();
- byte[] hash = Hash.sha3(input);
- return Numeric.toHexString(hash);
- }
+ public static String buildEventSignature(String methodSignature) {
+ byte[] input = methodSignature.getBytes();
+ byte[] hash = Hash.sha3(input);
+ return Numeric.toHexString(hash);
+ }
}
diff --git a/src/main/java/org/fisco/bcos/web3j/abi/EventValues.java b/src/main/java/org/fisco/bcos/web3j/abi/EventValues.java
index bb1b46476..8c40bca85 100644
--- a/src/main/java/org/fisco/bcos/web3j/abi/EventValues.java
+++ b/src/main/java/org/fisco/bcos/web3j/abi/EventValues.java
@@ -5,19 +5,19 @@
/** Persisted solidity event parameters. */
public class EventValues {
- private final List indexedValues;
- private final List nonIndexedValues;
+ private final List indexedValues;
+ private final List nonIndexedValues;
- public EventValues(List indexedValues, List nonIndexedValues) {
- this.indexedValues = indexedValues;
- this.nonIndexedValues = nonIndexedValues;
- }
+ public EventValues(List indexedValues, List nonIndexedValues) {
+ this.indexedValues = indexedValues;
+ this.nonIndexedValues = nonIndexedValues;
+ }
- public List getIndexedValues() {
- return indexedValues;
- }
+ public List getIndexedValues() {
+ return indexedValues;
+ }
- public List getNonIndexedValues() {
- return nonIndexedValues;
- }
+ public List getNonIndexedValues() {
+ return nonIndexedValues;
+ }
}
diff --git a/src/main/java/org/fisco/bcos/web3j/abi/FunctionEncoder.java b/src/main/java/org/fisco/bcos/web3j/abi/FunctionEncoder.java
index 359f53cf5..6399ca8cc 100644
--- a/src/main/java/org/fisco/bcos/web3j/abi/FunctionEncoder.java
+++ b/src/main/java/org/fisco/bcos/web3j/abi/FunctionEncoder.java
@@ -16,71 +16,72 @@
*/
public class FunctionEncoder {
- private FunctionEncoder() {}
+ private FunctionEncoder() {}
- public static String encode(Function function) {
- List parameters = function.getInputParameters();
+ public static String encode(Function function) {
+ List parameters = function.getInputParameters();
- String methodSignature = buildMethodSignature(function.getName(), parameters);
- String methodId = buildMethodId(methodSignature);
+ String methodSignature = buildMethodSignature(function.getName(), parameters);
+ String methodId = buildMethodId(methodSignature);
- StringBuilder result = new StringBuilder();
- result.append(methodId);
+ StringBuilder result = new StringBuilder();
+ result.append(methodId);
- return encodeParameters(parameters, result);
- }
+ return encodeParameters(parameters, result);
+ }
- public static String encodeConstructor(List parameters) {
- return encodeParameters(parameters, new StringBuilder());
- }
+ public static String encodeConstructor(List parameters) {
+ return encodeParameters(parameters, new StringBuilder());
+ }
- private static String encodeParameters(List parameters, StringBuilder result) {
- int dynamicDataOffset = getLength(parameters) * Type.MAX_BYTE_LENGTH;
- StringBuilder dynamicData = new StringBuilder();
+ private static String encodeParameters(List parameters, StringBuilder result) {
+ int dynamicDataOffset = getLength(parameters) * Type.MAX_BYTE_LENGTH;
+ StringBuilder dynamicData = new StringBuilder();
- for (Type parameter : parameters) {
- String encodedValue = TypeEncoder.encode(parameter);
+ for (Type parameter : parameters) {
+ String encodedValue = TypeEncoder.encode(parameter);
- if (TypeEncoder.isDynamic(parameter)) {
- String encodedDataOffset =
- TypeEncoder.encodeNumeric(new Uint(BigInteger.valueOf(dynamicDataOffset)));
- result.append(encodedDataOffset);
- dynamicData.append(encodedValue);
- dynamicDataOffset += encodedValue.length() >> 1;
- } else {
- result.append(encodedValue);
- }
- }
- result.append(dynamicData);
+ if (TypeEncoder.isDynamic(parameter)) {
+ String encodedDataOffset =
+ TypeEncoder.encodeNumeric(new Uint(BigInteger.valueOf(dynamicDataOffset)));
+ result.append(encodedDataOffset);
+ dynamicData.append(encodedValue);
+ dynamicDataOffset += encodedValue.length() >> 1;
+ } else {
+ result.append(encodedValue);
+ }
+ }
+ result.append(dynamicData);
- return result.toString();
- }
+ return result.toString();
+ }
- private static int getLength(List parameters) {
- int count = 0;
- for (Type type : parameters) {
- if (type instanceof StaticArray) {
- count += ((StaticArray) type).getValue().size();
- } else {
- count++;
- }
+ private static int getLength(List parameters) {
+ int count = 0;
+ for (Type type : parameters) {
+ if (type instanceof StaticArray) {
+ count += ((StaticArray) type).getValue().size();
+ } else {
+ count++;
+ }
+ }
+ return count;
}
- return count;
- }
- static String buildMethodSignature(String methodName, List parameters) {
- StringBuilder result = new StringBuilder();
- result.append(methodName);
- result.append("(");
- String params = parameters.stream().map(Type::getTypeAsString).collect(Collectors.joining(","));
- result.append(params);
- result.append(")");
- return result.toString();
- }
+ static String buildMethodSignature(String methodName, List parameters) {
+ StringBuilder result = new StringBuilder();
+ result.append(methodName);
+ result.append("(");
+ String params =
+ parameters.stream().map(Type::getTypeAsString).collect(Collectors.joining(","));
+ result.append(params);
+ result.append(")");
+ return result.toString();
+ }
- static String buildMethodId(String methodSignature) {
- byte[] input = methodSignature.getBytes();
- byte[] hash = Hash.sha3(input);
- return Numeric.toHexString(hash).substring(0, 10);
- }
+ static String buildMethodId(String methodSignature) {
+ byte[] input = methodSignature.getBytes();
+ byte[] hash = Hash.sha3(input);
+ return Numeric.toHexString(hash).substring(0, 10);
+ }
}
diff --git a/src/main/java/org/fisco/bcos/web3j/abi/FunctionReturnDecoder.java b/src/main/java/org/fisco/bcos/web3j/abi/FunctionReturnDecoder.java
index 332e5cfa8..492fe301e 100644
--- a/src/main/java/org/fisco/bcos/web3j/abi/FunctionReturnDecoder.java
+++ b/src/main/java/org/fisco/bcos/web3j/abi/FunctionReturnDecoder.java
@@ -18,115 +18,122 @@
/** Decodes values returned by function or event calls. */
public class FunctionReturnDecoder {
- private FunctionReturnDecoder() {}
+ private FunctionReturnDecoder() {}
- /**
- * Decode ABI encoded return values from smart contract function call.
- *
- * @param rawInput ABI encoded input
- * @param outputParameters list of return types as {@link TypeReference}
- * @return {@link List} of values returned by function, {@link Collections#emptyList()} if invalid
- * response
- */
- public static List decode(String rawInput, List> outputParameters) {
- String input = Numeric.cleanHexPrefix(rawInput);
+ /**
+ * Decode ABI encoded return values from smart contract function call.
+ *
+ * @param rawInput ABI encoded input
+ * @param outputParameters list of return types as {@link TypeReference}
+ * @return {@link List} of values returned by function, {@link Collections#emptyList()} if
+ * invalid response
+ */
+ public static List decode(String rawInput, List> outputParameters) {
+ String input = Numeric.cleanHexPrefix(rawInput);
- if (Strings.isEmpty(input)) {
- return Collections.emptyList();
- } else {
- return build(input, outputParameters);
+ if (Strings.isEmpty(input)) {
+ return Collections.emptyList();
+ } else {
+ return build(input, outputParameters);
+ }
}
- }
- /**
- * Decodes an indexed parameter associated with an event. Indexed parameters are individually
- * encoded, unlike non-indexed parameters which are encoded as per ABI-encoded function parameters
- * and return values.
- *
- * If any of the following types are indexed, the Keccak-256 hashes of the values are returned
- * instead. These are returned as a bytes32 value.
- *
- *
- * Arrays
- * Strings
- * Bytes
- *
- *
- * See the Solidity
- * documentation for further information.
- *
- * @param rawInput ABI encoded input
- * @param typeReference of expected result type
- * @param type of TypeReference
- * @return the decode value
- */
- @SuppressWarnings("unchecked")
- public static Type decodeIndexedValue(
- String rawInput, TypeReference typeReference) {
- String input = Numeric.cleanHexPrefix(rawInput);
+ /**
+ * Decodes an indexed parameter associated with an event. Indexed parameters are individually
+ * encoded, unlike non-indexed parameters which are encoded as per ABI-encoded function
+ * parameters and return values.
+ *
+ * If any of the following types are indexed, the Keccak-256 hashes of the values are
+ * returned instead. These are returned as a bytes32 value.
+ *
+ *
+ * Arrays
+ * Strings
+ * Bytes
+ *
+ *
+ * See the Solidity
+ * documentation for further information.
+ *
+ * @param rawInput ABI encoded input
+ * @param typeReference of expected result type
+ * @param type of TypeReference
+ * @return the decode value
+ */
+ @SuppressWarnings("unchecked")
+ public static Type decodeIndexedValue(
+ String rawInput, TypeReference typeReference) {
+ String input = Numeric.cleanHexPrefix(rawInput);
- try {
- Class type = typeReference.getClassType();
+ try {
+ Class type = typeReference.getClassType();
- if (Bytes.class.isAssignableFrom(type)) {
- return TypeDecoder.decodeBytes(input, (Class) Class.forName(type.getName()));
- } else if (Array.class.isAssignableFrom(type)
- || BytesType.class.isAssignableFrom(type)
- || Utf8String.class.isAssignableFrom(type)) {
- return TypeDecoder.decodeBytes(input, Bytes32.class);
- } else {
- return TypeDecoder.decode(input, type);
- }
- } catch (ClassNotFoundException e) {
- throw new UnsupportedOperationException("Invalid class reference provided", e);
+ if (Bytes.class.isAssignableFrom(type)) {
+ return TypeDecoder.decodeBytes(input, (Class) Class.forName(type.getName()));
+ } else if (Array.class.isAssignableFrom(type)
+ || BytesType.class.isAssignableFrom(type)
+ || Utf8String.class.isAssignableFrom(type)) {
+ return TypeDecoder.decodeBytes(input, Bytes32.class);
+ } else {
+ return TypeDecoder.decode(input, type);
+ }
+ } catch (ClassNotFoundException e) {
+ throw new UnsupportedOperationException("Invalid class reference provided", e);
+ }
}
- }
- private static List build(String input, List> outputParameters) {
- List results = new ArrayList<>(outputParameters.size());
+ private static List build(String input, List> outputParameters) {
+ List results = new ArrayList<>(outputParameters.size());
- int offset = 0;
- for (TypeReference> typeReference : outputParameters) {
- try {
- @SuppressWarnings("unchecked")
- Class type = (Class) typeReference.getClassType();
+ int offset = 0;
+ for (TypeReference> typeReference : outputParameters) {
+ try {
+ @SuppressWarnings("unchecked")
+ Class type = (Class) typeReference.getClassType();
- int hexStringDataOffset = getDataOffset(input, offset, type);
+ int hexStringDataOffset = getDataOffset(input, offset, type);
- Type result;
- if (DynamicArray.class.isAssignableFrom(type)) {
- result = TypeDecoder.decodeDynamicArray(input, hexStringDataOffset, typeReference);
- offset += TypeDecoder.MAX_BYTE_LENGTH_FOR_HEX_STRING;
- } else if (typeReference instanceof TypeReference.StaticArrayTypeReference) {
- int length = ((TypeReference.StaticArrayTypeReference) typeReference).getSize();
- result = TypeDecoder.decodeStaticArray(input, hexStringDataOffset, typeReference, length);
- offset += length * TypeDecoder.MAX_BYTE_LENGTH_FOR_HEX_STRING;
- } else if (StaticArray.class.isAssignableFrom(type)) {
- int length =
- Integer.parseInt(
- type.getSimpleName().substring(StaticArray.class.getSimpleName().length()));
- result = TypeDecoder.decodeStaticArray(input, hexStringDataOffset, typeReference, length);
- offset += length * TypeDecoder.MAX_BYTE_LENGTH_FOR_HEX_STRING;
- } else {
- result = TypeDecoder.decode(input, hexStringDataOffset, type);
- offset += TypeDecoder.MAX_BYTE_LENGTH_FOR_HEX_STRING;
- }
- results.add(result);
+ Type result;
+ if (DynamicArray.class.isAssignableFrom(type)) {
+ result =
+ TypeDecoder.decodeDynamicArray(
+ input, hexStringDataOffset, typeReference);
+ offset += TypeDecoder.MAX_BYTE_LENGTH_FOR_HEX_STRING;
+ } else if (typeReference instanceof TypeReference.StaticArrayTypeReference) {
+ int length = ((TypeReference.StaticArrayTypeReference) typeReference).getSize();
+ result =
+ TypeDecoder.decodeStaticArray(
+ input, hexStringDataOffset, typeReference, length);
+ offset += length * TypeDecoder.MAX_BYTE_LENGTH_FOR_HEX_STRING;
+ } else if (StaticArray.class.isAssignableFrom(type)) {
+ int length =
+ Integer.parseInt(
+ type.getSimpleName()
+ .substring(StaticArray.class.getSimpleName().length()));
+ result =
+ TypeDecoder.decodeStaticArray(
+ input, hexStringDataOffset, typeReference, length);
+ offset += length * TypeDecoder.MAX_BYTE_LENGTH_FOR_HEX_STRING;
+ } else {
+ result = TypeDecoder.decode(input, hexStringDataOffset, type);
+ offset += TypeDecoder.MAX_BYTE_LENGTH_FOR_HEX_STRING;
+ }
+ results.add(result);
- } catch (ClassNotFoundException e) {
- throw new UnsupportedOperationException("Invalid class reference provided", e);
- }
+ } catch (ClassNotFoundException e) {
+ throw new UnsupportedOperationException("Invalid class reference provided", e);
+ }
+ }
+ return results;
}
- return results;
- }
- private static int getDataOffset(String input, int offset, Class type) {
- if (DynamicBytes.class.isAssignableFrom(type)
- || Utf8String.class.isAssignableFrom(type)
- || DynamicArray.class.isAssignableFrom(type)) {
- return TypeDecoder.decodeUintAsInt(input, offset) << 1;
- } else {
- return offset;
+ private static int getDataOffset(String input, int offset, Class type) {
+ if (DynamicBytes.class.isAssignableFrom(type)
+ || Utf8String.class.isAssignableFrom(type)
+ || DynamicArray.class.isAssignableFrom(type)) {
+ return TypeDecoder.decodeUintAsInt(input, offset) << 1;
+ } else {
+ return offset;
+ }
}
- }
}
diff --git a/src/main/java/org/fisco/bcos/web3j/abi/TypeDecoder.java b/src/main/java/org/fisco/bcos/web3j/abi/TypeDecoder.java
index 7520121e7..f98f24d20 100644
--- a/src/main/java/org/fisco/bcos/web3j/abi/TypeDecoder.java
+++ b/src/main/java/org/fisco/bcos/web3j/abi/TypeDecoder.java
@@ -33,250 +33,256 @@
*/
public class TypeDecoder {
- static final int MAX_BYTE_LENGTH_FOR_HEX_STRING = Type.MAX_BYTE_LENGTH << 1;
-
- static int getSingleElementLength(String input, int offset, Class type) {
- if (input.length() == offset) {
- return 0;
- } else if (DynamicBytes.class.isAssignableFrom(type)
- || Utf8String.class.isAssignableFrom(type)) {
- // length field + data value
- return (decodeUintAsInt(input, offset) / Type.MAX_BYTE_LENGTH) + 2;
- } else {
- return 1;
+ static final int MAX_BYTE_LENGTH_FOR_HEX_STRING = Type.MAX_BYTE_LENGTH << 1;
+
+ static int getSingleElementLength(String input, int offset, Class type) {
+ if (input.length() == offset) {
+ return 0;
+ } else if (DynamicBytes.class.isAssignableFrom(type)
+ || Utf8String.class.isAssignableFrom(type)) {
+ // length field + data value
+ return (decodeUintAsInt(input, offset) / Type.MAX_BYTE_LENGTH) + 2;
+ } else {
+ return 1;
+ }
}
- }
-
- @SuppressWarnings("unchecked")
- static T decode(String input, int offset, Class type) {
- if (NumericType.class.isAssignableFrom(type)) {
- return (T) decodeNumeric(input.substring(offset), (Class) type);
- } else if (Address.class.isAssignableFrom(type)) {
- return (T) decodeAddress(input.substring(offset));
- } else if (Bool.class.isAssignableFrom(type)) {
- return (T) decodeBool(input, offset);
- } else if (Bytes.class.isAssignableFrom(type)) {
- return (T) decodeBytes(input, offset, (Class) type);
- } else if (DynamicBytes.class.isAssignableFrom(type)) {
- return (T) decodeDynamicBytes(input, offset);
- } else if (Utf8String.class.isAssignableFrom(type)) {
- return (T) decodeUtf8String(input, offset);
- } else if (Array.class.isAssignableFrom(type)) {
- throw new UnsupportedOperationException("Array types must be wrapped in a TypeReference");
- } else {
- throw new UnsupportedOperationException("Type cannot be encoded: " + type.getClass());
+
+ @SuppressWarnings("unchecked")
+ static T decode(String input, int offset, Class type) {
+ if (NumericType.class.isAssignableFrom(type)) {
+ return (T) decodeNumeric(input.substring(offset), (Class) type);
+ } else if (Address.class.isAssignableFrom(type)) {
+ return (T) decodeAddress(input.substring(offset));
+ } else if (Bool.class.isAssignableFrom(type)) {
+ return (T) decodeBool(input, offset);
+ } else if (Bytes.class.isAssignableFrom(type)) {
+ return (T) decodeBytes(input, offset, (Class) type);
+ } else if (DynamicBytes.class.isAssignableFrom(type)) {
+ return (T) decodeDynamicBytes(input, offset);
+ } else if (Utf8String.class.isAssignableFrom(type)) {
+ return (T) decodeUtf8String(input, offset);
+ } else if (Array.class.isAssignableFrom(type)) {
+ throw new UnsupportedOperationException(
+ "Array types must be wrapped in a TypeReference");
+ } else {
+ throw new UnsupportedOperationException("Type cannot be encoded: " + type.getClass());
+ }
}
- }
-
- public static T decode(
- String input, int offset, TypeReference typeReference) {
- Class cls = ((ParameterizedType) typeReference.getType()).getRawType().getClass();
- if (StaticArray.class.isAssignableFrom(cls)) {
- return decodeStaticArray(input, offset, typeReference, 1);
- } else if (DynamicArray.class.isAssignableFrom(cls)) {
- return decodeDynamicArray(input, offset, typeReference);
- } else {
- throw new UnsupportedOperationException(
- "Unsupported TypeReference: "
- + cls.getName()
- + ", only Array types can be passed as TypeReferences");
+
+ public static T decode(
+ String input, int offset, TypeReference typeReference) {
+ Class cls = ((ParameterizedType) typeReference.getType()).getRawType().getClass();
+ if (StaticArray.class.isAssignableFrom(cls)) {
+ return decodeStaticArray(input, offset, typeReference, 1);
+ } else if (DynamicArray.class.isAssignableFrom(cls)) {
+ return decodeDynamicArray(input, offset, typeReference);
+ } else {
+ throw new UnsupportedOperationException(
+ "Unsupported TypeReference: "
+ + cls.getName()
+ + ", only Array types can be passed as TypeReferences");
+ }
}
- }
- static T decode(String input, Class type) {
- return decode(input, 0, type);
- }
+ static T decode(String input, Class type) {
+ return decode(input, 0, type);
+ }
- static Address decodeAddress(String input) {
- return new Address(decodeNumeric(input, Uint160.class));
- }
+ static Address decodeAddress(String input) {
+ return new Address(decodeNumeric(input, Uint160.class));
+ }
- static T decodeNumeric(String input, Class type) {
- try {
- byte[] inputByteArray = Numeric.hexStringToByteArray(input);
- int typeLengthAsBytes = getTypeLengthInBytes(type);
+ static T decodeNumeric(String input, Class type) {
+ try {
+ byte[] inputByteArray = Numeric.hexStringToByteArray(input);
+ int typeLengthAsBytes = getTypeLengthInBytes(type);
- byte[] resultByteArray = new byte[typeLengthAsBytes + 1];
+ byte[] resultByteArray = new byte[typeLengthAsBytes + 1];
- if (Int.class.isAssignableFrom(type) || Fixed.class.isAssignableFrom(type)) {
- resultByteArray[0] = inputByteArray[0]; // take MSB as sign bit
- }
+ if (Int.class.isAssignableFrom(type) || Fixed.class.isAssignableFrom(type)) {
+ resultByteArray[0] = inputByteArray[0]; // take MSB as sign bit
+ }
- int valueOffset = Type.MAX_BYTE_LENGTH - typeLengthAsBytes;
- System.arraycopy(inputByteArray, valueOffset, resultByteArray, 1, typeLengthAsBytes);
+ int valueOffset = Type.MAX_BYTE_LENGTH - typeLengthAsBytes;
+ System.arraycopy(inputByteArray, valueOffset, resultByteArray, 1, typeLengthAsBytes);
- BigInteger numericValue = new BigInteger(resultByteArray);
- return type.getConstructor(BigInteger.class).newInstance(numericValue);
+ BigInteger numericValue = new BigInteger(resultByteArray);
+ return type.getConstructor(BigInteger.class).newInstance(numericValue);
- } catch (NoSuchMethodException
- | SecurityException
- | InstantiationException
- | IllegalAccessException
- | IllegalArgumentException
- | InvocationTargetException e) {
- throw new UnsupportedOperationException("Unable to create instance of " + type.getName(), e);
+ } catch (NoSuchMethodException
+ | SecurityException
+ | InstantiationException
+ | IllegalAccessException
+ | IllegalArgumentException
+ | InvocationTargetException e) {
+ throw new UnsupportedOperationException(
+ "Unable to create instance of " + type.getName(), e);
+ }
}
- }
-
- static int getTypeLengthInBytes(Class type) {
- return getTypeLength(type) >> 3; // divide by 8
- }
-
- static int getTypeLength(Class type) {
- if (IntType.class.isAssignableFrom(type)) {
- String regex = "(" + Uint.class.getSimpleName() + "|" + Int.class.getSimpleName() + ")";
- String[] splitName = type.getSimpleName().split(regex);
- if (splitName.length == 2) {
- return Integer.parseInt(splitName[1]);
- }
- } else if (FixedPointType.class.isAssignableFrom(type)) {
- String regex = "(" + Ufixed.class.getSimpleName() + "|" + Fixed.class.getSimpleName() + ")";
- String[] splitName = type.getSimpleName().split(regex);
- if (splitName.length == 2) {
- String[] bitsCounts = splitName[1].split("x");
- return Integer.parseInt(bitsCounts[0]) + Integer.parseInt(bitsCounts[1]);
- }
+
+ static int getTypeLengthInBytes(Class type) {
+ return getTypeLength(type) >> 3; // divide by 8
}
- return Type.MAX_BIT_LENGTH;
- }
-
- static int decodeUintAsInt(String rawInput, int offset) {
- String input = rawInput.substring(offset, offset + MAX_BYTE_LENGTH_FOR_HEX_STRING);
- return decode(input, 0, Uint.class).getValue().intValue();
- }
-
- static Bool decodeBool(String rawInput, int offset) {
- String input = rawInput.substring(offset, offset + MAX_BYTE_LENGTH_FOR_HEX_STRING);
- BigInteger numericValue = Numeric.toBigInt(input);
- boolean value = numericValue.equals(BigInteger.ONE);
- return new Bool(value);
- }
-
- static T decodeBytes(String input, Class type) {
- return decodeBytes(input, 0, type);
- }
-
- static T decodeBytes(String input, int offset, Class type) {
- try {
- String simpleName = type.getSimpleName();
- String[] splitName = simpleName.split(Bytes.class.getSimpleName());
- int length = Integer.parseInt(splitName[1]);
- int hexStringLength = length << 1;
-
- byte[] bytes =
- Numeric.hexStringToByteArray(input.substring(offset, offset + hexStringLength));
- return type.getConstructor(byte[].class).newInstance(bytes);
- } catch (NoSuchMethodException
- | SecurityException
- | InstantiationException
- | IllegalAccessException
- | IllegalArgumentException
- | InvocationTargetException e) {
- throw new UnsupportedOperationException("Unable to create instance of " + type.getName(), e);
+
+ static int getTypeLength(Class type) {
+ if (IntType.class.isAssignableFrom(type)) {
+ String regex = "(" + Uint.class.getSimpleName() + "|" + Int.class.getSimpleName() + ")";
+ String[] splitName = type.getSimpleName().split(regex);
+ if (splitName.length == 2) {
+ return Integer.parseInt(splitName[1]);
+ }
+ } else if (FixedPointType.class.isAssignableFrom(type)) {
+ String regex =
+ "(" + Ufixed.class.getSimpleName() + "|" + Fixed.class.getSimpleName() + ")";
+ String[] splitName = type.getSimpleName().split(regex);
+ if (splitName.length == 2) {
+ String[] bitsCounts = splitName[1].split("x");
+ return Integer.parseInt(bitsCounts[0]) + Integer.parseInt(bitsCounts[1]);
+ }
+ }
+ return Type.MAX_BIT_LENGTH;
}
- }
-
- static DynamicBytes decodeDynamicBytes(String input, int offset) {
- int encodedLength = decodeUintAsInt(input, offset);
- int hexStringEncodedLength = encodedLength << 1;
-
- int valueOffset = offset + MAX_BYTE_LENGTH_FOR_HEX_STRING;
-
- String data = input.substring(valueOffset, valueOffset + hexStringEncodedLength);
- byte[] bytes = Numeric.hexStringToByteArray(data);
-
- return new DynamicBytes(bytes);
- }
-
- static Utf8String decodeUtf8String(String input, int offset) {
- DynamicBytes dynamicBytesResult = decodeDynamicBytes(input, offset);
- byte[] bytes = dynamicBytesResult.getValue();
-
- return new Utf8String(new String(bytes, StandardCharsets.UTF_8));
- }
-
- /** Static array length cannot be passed as a type. */
- @SuppressWarnings("unchecked")
- static T decodeStaticArray(
- String input, int offset, TypeReference