This is an automated email from the ASF dual-hosted git repository. bibryam pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/master by this push: new cfa2bfe Added jpmorganchase/quorum cfa2bfe is described below commit cfa2bfe7f11864260f4dd7ed8935b3f4dd850e46 Author: Bilgin Ibryam <bibr...@gmail.com> AuthorDate: Tue Aug 14 21:02:33 2018 +0100 Added jpmorganchase/quorum --- components/camel-web3j/pom.xml | 6 +- .../camel-web3j/src/main/docs/web3j-component.adoc | 4 +- .../camel/component/web3j/Web3jConfiguration.java | 28 +++ .../camel/component/web3j/Web3jConstants.java | 12 ++ .../camel/component/web3j/Web3jEndpoint.java | 5 + .../camel/component/web3j/Web3jProducer.java | 195 ++++++++++++++++++- .../camel/component/web3j/Web3jProducerTest.java | 2 +- .../component/web3j/Web3jQuorumProducerTest.java | 211 +++++++++++++++++++++ .../integration/Web3jProducerGanacheTest.java | 4 + parent/pom.xml | 1 + .../springboot/Web3jComponentConfiguration.java | 24 +++ 11 files changed, 486 insertions(+), 6 deletions(-) diff --git a/components/camel-web3j/pom.xml b/components/camel-web3j/pom.xml index babfede..2f5439e 100644 --- a/components/camel-web3j/pom.xml +++ b/components/camel-web3j/pom.xml @@ -56,7 +56,11 @@ <artifactId>parity</artifactId> <version>${web3j-version}</version> </dependency> - + <dependency> + <groupId>org.web3j</groupId> + <artifactId>quorum</artifactId> + <version>${web3j-quorum-version}</version> + </dependency> <!-- for testing --> <dependency> <groupId>org.apache.camel</groupId> diff --git a/components/camel-web3j/src/main/docs/web3j-component.adoc b/components/camel-web3j/src/main/docs/web3j-component.adoc index 0e3dc09..9be54ac 100644 --- a/components/camel-web3j/src/main/docs/web3j-component.adoc +++ b/components/camel-web3j/src/main/docs/web3j-component.adoc @@ -63,7 +63,7 @@ with the following path and query parameters: |=== -==== Query Parameters (36 parameters): +==== Query Parameters (38 parameters): [width="100%",cols="2,5,^1,2",options="header"] @@ -74,6 +74,8 @@ with the following path and query parameters: | *fromBlock* (common) | The block number, or the string latest for the last mined block or pending, earliest for not yet mined transactions. | latest | DefaultBlockParameter | *fullTransactionObjects* (common) | If true it returns the full transaction objects, if false only the hashes of the transactions. | false | boolean | *gasLimit* (common) | The maximum gas allowed in this block. | | BigInteger +| *privateFor* (common) | A transaction privateFor nodes with public keys in a Quorum network | | List +| *quorumAPI* (common) | If true, this will support Quorum API. | false | boolean | *toAddress* (common) | The address the transaction is directed to. | | String | *toBlock* (common) | The block number, or the string latest for the last mined block or pending, earliest for not yet mined transactions. | latest | DefaultBlockParameter | *topics* (common) | Topics are order-dependent. Each topic can also be a list of topics. Specify multiple topics separated by comma. | | String diff --git a/components/camel-web3j/src/main/java/org/apache/camel/component/web3j/Web3jConfiguration.java b/components/camel-web3j/src/main/java/org/apache/camel/component/web3j/Web3jConfiguration.java index d06929f..f65fc7c 100644 --- a/components/camel-web3j/src/main/java/org/apache/camel/component/web3j/Web3jConfiguration.java +++ b/components/camel-web3j/src/main/java/org/apache/camel/component/web3j/Web3jConfiguration.java @@ -126,6 +126,34 @@ public class Web3jConfiguration implements Cloneable { @UriParam(label = "common") private boolean fullTransactionObjects; + @UriParam(label = "common", defaultValue = "false") + private boolean quorumAPI; + + @UriParam(label = "common") + private List<String> privateFor; + + + public List<String> getPrivateFor() { + return privateFor; + } + /** + * A transaction privateFor nodes with public keys in a Quorum network + */ + public void setPrivateFor(List<String> privateFor) { + this.privateFor = privateFor; + } + + + public boolean isQuorumAPI() { + return quorumAPI; + } + /** + * If true, this will support Quorum API. + */ + public void setQuorumAPI(boolean quorumAPI) { + this.quorumAPI = quorumAPI; + } + public Web3j getWeb3j() { return web3j; } diff --git a/components/camel-web3j/src/main/java/org/apache/camel/component/web3j/Web3jConstants.java b/components/camel-web3j/src/main/java/org/apache/camel/component/web3j/Web3jConstants.java index 1830372..409afd7 100644 --- a/components/camel-web3j/src/main/java/org/apache/camel/component/web3j/Web3jConstants.java +++ b/components/camel-web3j/src/main/java/org/apache/camel/component/web3j/Web3jConstants.java @@ -80,6 +80,17 @@ public interface Web3jConstants { String SHH_GET_FILTER_CHANGES = "SHH_GET_FILTER_CHANGES"; String SHH_GET_MESSAGES = "SHH_GET_MESSAGES"; + String QUORUM_ETH_SEND_TRANSACTION = "QUORUM_ETH_SEND_TRANSACTION"; + String QUORUM_NODE_INFO = "QUORUM_NODE_INFO"; + String QUORUM_CANONICAL_HASH = "QUORUM_CANONICAL_HASH"; + String QUORUM_VOTE = "QUORUM_VOTE"; + String QUORUM_MAKE_BLOCK = "QUORUM_MAKE_BLOCK"; + String QUORUM_PAUSE_BLOCK_MAKER= "QUORUM_PAUSE_BLOCK_MAKER"; + String QUORUM_RESUME_BLOCK_MAKER= "QUORUM_RESUME_BLOCK_MAKER"; + String QUORUM_IS_BLOCK_MAKER = "QUORUM_IS_BLOCK_MAKER"; + String QUORUM_IS_VOTER = "QUORUM_IS_VOTER"; + String QUORUM_GET_PRIVATE_PAYLOAD = "QUORUM_GET_PRIVATE_PAYLOAD"; + String ETH_LOG_OBSERVABLE = "ETH_LOG_OBSERVABLE"; String ETH_BLOCK_HASH_OBSERVABLE = "ETH_BLOCK_HASH_OBSERVABLE"; String ETH_PENDING_TRANSACTION_HASH_OBSERVABLE = "ETH_PENDING_TRANSACTION_HASH_OBSERVABLE"; @@ -125,6 +136,7 @@ public interface Web3jConstants { String TOPICS = "TOPICS"; String PRIORITY = "PRIORITY"; String TTL = "TTL"; + String PRIVATE_FOR = "PRIVATE_FOR"; String ERROR_CODE = "ERROR_CODE"; String ERROR_DATA = "ERROR_DATA"; diff --git a/components/camel-web3j/src/main/java/org/apache/camel/component/web3j/Web3jEndpoint.java b/components/camel-web3j/src/main/java/org/apache/camel/component/web3j/Web3jEndpoint.java index cf69f64..d533a8f 100644 --- a/components/camel-web3j/src/main/java/org/apache/camel/component/web3j/Web3jEndpoint.java +++ b/components/camel-web3j/src/main/java/org/apache/camel/component/web3j/Web3jEndpoint.java @@ -37,6 +37,7 @@ import org.web3j.protocol.core.methods.request.ShhFilter; import org.web3j.protocol.http.HttpService; import org.web3j.protocol.ipc.UnixIpcService; import org.web3j.protocol.ipc.WindowsIpcService; +import org.web3j.quorum.Quorum; /** * The web3j component uses the Web3j client API and allows you to add/read nodes to/from a web3j compliant content repositories. @@ -99,6 +100,10 @@ public class Web3jEndpoint extends DefaultEndpoint { web3jService = new UnixIpcService(clientAddress); } + if (configuration.isQuorumAPI()) { + return Quorum.build(web3jService); + } + return Web3j.build(web3jService); } diff --git a/components/camel-web3j/src/main/java/org/apache/camel/component/web3j/Web3jProducer.java b/components/camel-web3j/src/main/java/org/apache/camel/component/web3j/Web3jProducer.java index b784eed..4c52e57 100644 --- a/components/camel-web3j/src/main/java/org/apache/camel/component/web3j/Web3jProducer.java +++ b/components/camel-web3j/src/main/java/org/apache/camel/component/web3j/Web3jProducer.java @@ -80,8 +80,18 @@ import org.web3j.protocol.core.methods.response.ShhNewIdentity; import org.web3j.protocol.core.methods.response.ShhPost; import org.web3j.protocol.core.methods.response.ShhUninstallFilter; import org.web3j.protocol.core.methods.response.ShhVersion; +import org.web3j.protocol.core.methods.response.VoidResponse; import org.web3j.protocol.core.methods.response.Web3ClientVersion; import org.web3j.protocol.core.methods.response.Web3Sha3; +import org.web3j.quorum.Quorum; +import org.web3j.quorum.methods.request.PrivateTransaction; +import org.web3j.quorum.methods.response.BlockMaker; +import org.web3j.quorum.methods.response.CanonicalHash; +import org.web3j.quorum.methods.response.MakeBlock; +import org.web3j.quorum.methods.response.PrivatePayload; +import org.web3j.quorum.methods.response.QuorumNodeInfo; +import org.web3j.quorum.methods.response.Vote; +import org.web3j.quorum.methods.response.Voter; /** * The web3j producer. @@ -90,14 +100,16 @@ import org.web3j.protocol.core.methods.response.Web3Sha3; public class Web3jProducer extends HeaderSelectorProducer { private static final Logger LOG = LoggerFactory.getLogger(Web3jProducer.class); private Web3j web3j; + private Quorum quorum; private Web3jConfiguration configuration; - private Web3jEndpoint endpoint; public Web3jProducer(Web3jEndpoint endpoint, final Web3jConfiguration configuration) { super(endpoint, Web3jConstants.OPERATION, () -> configuration.getOperationOrDefault(), false); web3j = endpoint.getWeb3j(); - this.endpoint = endpoint; this.configuration = configuration; + if (web3j instanceof Quorum) { + quorum = (Quorum) web3j; + } } @Override @@ -909,6 +921,180 @@ public class Web3jProducer extends HeaderSelectorProducer { } } + // Quorum API Operations + @InvokeOnHeader(Web3jConstants.QUORUM_NODE_INFO) + void quorumNodeInfo(Message message) throws IOException { + if (quorum == null) { + setQuorumEndpointError(message); + return; + } + + Request<?, QuorumNodeInfo> request = quorum.quorumNodeInfo(); + setRequestId(message, request); + QuorumNodeInfo response = request.send(); + boolean hasError = checkForError(message, response); + if (!hasError) { + message.setBody(response.getNodeInfo()); + } + } + + @InvokeOnHeader(Web3jConstants.QUORUM_CANONICAL_HASH) + void quorumCanonicalHash(Message message) throws IOException { + if (quorum == null) { + setQuorumEndpointError(message); + return; + } + + Request<?, CanonicalHash> request = quorum.quorumCanonicalHash(message.getBody(BigInteger.class)); + setRequestId(message, request); + CanonicalHash response = request.send(); + boolean hasError = checkForError(message, response); + if (!hasError) { + message.setBody(response.getCanonicalHash()); + } + } + + @InvokeOnHeader(Web3jConstants.QUORUM_VOTE) + void quorumVote(Message message) throws IOException { + if (quorum == null) { + setQuorumEndpointError(message); + return; + } + + String blockHash = message.getHeader(Web3jConstants.BLOCK_HASH, configuration::getBlockHash, String.class); + Request<?, Vote> request = quorum.quorumVote(blockHash); + setRequestId(message, request); + Vote response = request.send(); + boolean hasError = checkForError(message, response); + if (!hasError) { + message.setBody(response.getTransactionHash()); + } + } + + @InvokeOnHeader(Web3jConstants.QUORUM_MAKE_BLOCK) + void quorumMakeBlock(Message message) throws IOException { + if (quorum == null) { + setQuorumEndpointError(message); + return; + } + + Request<?, MakeBlock> request = quorum.quorumMakeBlock(); + setRequestId(message, request); + MakeBlock response = request.send(); + boolean hasError = checkForError(message, response); + if (!hasError) { + message.setBody(response.getBlockHash()); + } + } + + @InvokeOnHeader(Web3jConstants.QUORUM_PAUSE_BLOCK_MAKER) + void quorumPauseBlockMaker(Message message) throws IOException { + if (quorum == null) { + setQuorumEndpointError(message); + return; + } + + Request<?, VoidResponse> request = quorum.quorumPauseBlockMaker(); + setRequestId(message, request); + VoidResponse response = request.send(); + boolean hasError = checkForError(message, response); + if (!hasError) { + message.setBody(response.isValid()); + } + } + + @InvokeOnHeader(Web3jConstants.QUORUM_RESUME_BLOCK_MAKER) + void quorumResumeBlockMaker(Message message) throws IOException { + if (quorum == null) { + setQuorumEndpointError(message); + return; + } + + Request<?, VoidResponse> request = quorum.quorumResumeBlockMaker(); + setRequestId(message, request); + VoidResponse response = request.send(); + boolean hasError = checkForError(message, response); + if (!hasError) { + message.setBody(response.isValid()); + } + } + + @InvokeOnHeader(Web3jConstants.QUORUM_IS_BLOCK_MAKER) + void quorumIsBlockMaker(Message message) throws IOException { + if (quorum == null) { + setQuorumEndpointError(message); + return; + } + + String address = message.getHeader(Web3jConstants.ADDRESS, configuration::getAddress, String.class); + Request<?, BlockMaker> request = quorum.quorumIsBlockMaker(address); + setRequestId(message, request); + BlockMaker response = request.send(); + boolean hasError = checkForError(message, response); + if (!hasError) { + message.setBody(response.isBlockMaker()); + } + } + + @InvokeOnHeader(Web3jConstants.QUORUM_IS_VOTER) + void quorumIsVoter(Message message) throws IOException { + if (quorum == null) { + setQuorumEndpointError(message); + return; + } + + String address = message.getHeader(Web3jConstants.ADDRESS, configuration::getAddress, String.class); + Request<?, Voter> request = quorum.quorumIsVoter(address); + setRequestId(message, request); + Voter response = request.send(); + boolean hasError = checkForError(message, response); + if (!hasError) { + message.setBody(response.isVoter()); + } + } + + @InvokeOnHeader(Web3jConstants.QUORUM_GET_PRIVATE_PAYLOAD) + void quorumGetPrivatePayload(Message message) throws IOException { + if (quorum == null) { + setQuorumEndpointError(message); + return; + } + + Request<?, PrivatePayload> request = quorum.quorumGetPrivatePayload(message.getBody(String.class)); + setRequestId(message, request); + PrivatePayload response = request.send(); + boolean hasError = checkForError(message, response); + if (!hasError) { + message.setBody(response.getPrivatePayload()); + } + } + + @InvokeOnHeader(Web3jConstants.QUORUM_ETH_SEND_TRANSACTION) + void quorumEthSendTransaction(Message message) throws IOException { + if (quorum == null) { + setQuorumEndpointError(message); + return; + } + + //the same as a regular transaction, but there is no gasPrice, instead there is optional privateFor + String fromAddress = message.getHeader(Web3jConstants.FROM_ADDRESS, configuration::getFromAddress, String.class); + String toAddress = message.getHeader(Web3jConstants.TO_ADDRESS, configuration::getToAddress, String.class); + BigInteger nonce = message.getHeader(Web3jConstants.NONCE, configuration::getNonce, BigInteger.class); + BigInteger gasLimit = message.getHeader(Web3jConstants.GAS_LIMIT, configuration::getGasLimit, BigInteger.class); + BigInteger value = message.getHeader(Web3jConstants.VALUE, configuration::getValue, BigInteger.class); + String data = message.getHeader(Web3jConstants.DATA, configuration::getData, String.class); + List<String> privateFor = message.getHeader(Web3jConstants.PRIVATE_FOR, configuration::getPrivateFor, List.class); + PrivateTransaction transaction = new PrivateTransaction(fromAddress, nonce, gasLimit, toAddress, value, data, privateFor); + + Request<?, EthSendTransaction> request = quorum.ethSendTransaction(transaction); + setRequestId(message, request); + EthSendTransaction response = request.send(); + boolean hasError = checkForError(message, response); + if (!hasError) { + message.setBody(response.getTransactionHash()); + } + } + private void setRequestId(Message message, Request request) { final Long id = message.getHeader(Web3jConstants.ID, Long.class); LOG.debug("setRequestId " + id); @@ -934,7 +1120,6 @@ public class Web3jProducer extends HeaderSelectorProducer { return defaultBlockParameter; } - private boolean checkForError(Message message, Response response) { if (response.hasError()) { int code = response.getError().getCode(); @@ -949,4 +1134,8 @@ public class Web3jProducer extends HeaderSelectorProducer { return false; } } + + private void setQuorumEndpointError(Message message) { + message.getExchange().setException(new CamelExchangeException("This is not a Quorum endpoint. Create one by specifying quorumAPI=true", message.getExchange())); + } } diff --git a/components/camel-web3j/src/test/java/org/apache/camel/component/web3j/Web3jProducerTest.java b/components/camel-web3j/src/test/java/org/apache/camel/component/web3j/Web3jProducerTest.java index e86fe66..72ed9dd 100644 --- a/components/camel-web3j/src/test/java/org/apache/camel/component/web3j/Web3jProducerTest.java +++ b/components/camel-web3j/src/test/java/org/apache/camel/component/web3j/Web3jProducerTest.java @@ -158,7 +158,7 @@ public class Web3jProducerTest extends Web3jMockTestSupport { @Test public void netPeerCountTest() throws Exception { - BigInteger peerCount = BigInteger.valueOf(1L); + BigInteger peerCount = BigInteger.ONE; NetPeerCount response = Mockito.mock(NetPeerCount.class); Mockito.when(mockWeb3j.netPeerCount()).thenReturn(request); Mockito.when(request.send()).thenReturn(response); diff --git a/components/camel-web3j/src/test/java/org/apache/camel/component/web3j/Web3jQuorumProducerTest.java b/components/camel-web3j/src/test/java/org/apache/camel/component/web3j/Web3jQuorumProducerTest.java new file mode 100644 index 0000000..ad0cde2 --- /dev/null +++ b/components/camel-web3j/src/test/java/org/apache/camel/component/web3j/Web3jQuorumProducerTest.java @@ -0,0 +1,211 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.web3j; + +import org.apache.camel.Exchange; +import org.apache.camel.Produce; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.impl.JndiRegistry; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.web3j.protocol.core.Request; +import org.web3j.protocol.core.methods.response.EthSendTransaction; +import org.web3j.protocol.core.methods.response.VoidResponse; +import org.web3j.quorum.Quorum; +import org.web3j.quorum.methods.response.BlockMaker; +import org.web3j.quorum.methods.response.CanonicalHash; +import org.web3j.quorum.methods.response.MakeBlock; +import org.web3j.quorum.methods.response.PrivatePayload; +import org.web3j.quorum.methods.response.QuorumNodeInfo; +import org.web3j.quorum.methods.response.Vote; +import org.web3j.quorum.methods.response.Voter; + +import static org.apache.camel.component.web3j.Web3jConstants.OPERATION; +import static org.mockito.ArgumentMatchers.any; + +public class Web3jQuorumProducerTest extends Web3jMockTestSupport { + + @Mock + protected Quorum mockQuorum; + + @Override + protected JndiRegistry createRegistry() throws Exception { + JndiRegistry registry = super.createRegistry(); + registry.bind("mockQuorum", mockQuorum); + return registry; + } + + protected String getUrl() { + return "web3j://http://127.0.0.1:8545?web3j=#mockQuorum&quorumAPI=true&"; + } + + @Produce(uri = "direct:start") + protected ProducerTemplate template; + + @Mock + private Request request; + + @Override + public boolean isUseAdviceWith() { + return false; + } + + //Quorum API tests + @Test + public void quorumNodeInfoTest() throws Exception { + QuorumNodeInfo.NodeInfo nodeInfo = new QuorumNodeInfo.NodeInfo(); + QuorumNodeInfo response = Mockito.mock(QuorumNodeInfo.class); + + Mockito.when(mockQuorum.quorumNodeInfo()).thenReturn(request); + Mockito.when(request.send()).thenReturn(response); + Mockito.when(response.getNodeInfo()).thenReturn(nodeInfo); + + Exchange exchange = createExchangeWithBodyAndHeader(null, OPERATION, Web3jConstants.QUORUM_NODE_INFO); + template.send(exchange); + QuorumNodeInfo.NodeInfo body = exchange.getIn().getBody(QuorumNodeInfo.NodeInfo.class); + assertTrue(body != null); + } + + @Test + public void quorumCanonicalHashTest() throws Exception { + CanonicalHash response = Mockito.mock(CanonicalHash.class); + Mockito.when(mockQuorum.quorumCanonicalHash(any())).thenReturn(request); + Mockito.when(request.send()).thenReturn(response); + Mockito.when(response.getCanonicalHash()).thenReturn("test"); + + Exchange exchange = createExchangeWithBodyAndHeader("test-hash", OPERATION, Web3jConstants.QUORUM_CANONICAL_HASH); + template.send(exchange); + String body = exchange.getIn().getBody(String.class); + assertTrue(body.equals("test")); + } + + @Test + public void quorumVoteTest() throws Exception { + Vote response = Mockito.mock(Vote.class); + Mockito.when(mockQuorum.quorumVote(any())).thenReturn(request); + Mockito.when(request.send()).thenReturn(response); + Mockito.when(response.getTransactionHash()).thenReturn("test"); + + Exchange exchange = createExchangeWithBodyAndHeader(null, OPERATION, Web3jConstants.QUORUM_VOTE); + template.send(exchange); + String body = exchange.getIn().getBody(String.class); + assertTrue(body.equals("test")); + } + + @Test + public void quorumMakeBlockTest() throws Exception { + MakeBlock response = Mockito.mock(MakeBlock.class); + Mockito.when(mockQuorum.quorumMakeBlock()).thenReturn(request); + Mockito.when(request.send()).thenReturn(response); + Mockito.when(response.getBlockHash()).thenReturn("test"); + + Exchange exchange = createExchangeWithBodyAndHeader(null, OPERATION, Web3jConstants.QUORUM_MAKE_BLOCK); + template.send(exchange); + String body = exchange.getIn().getBody(String.class); + assertTrue(body.equals("test")); + } + + @Test + public void quorumPauseBlockMakerTest() throws Exception { + VoidResponse response = Mockito.mock(VoidResponse.class); + Mockito.when(mockQuorum.quorumPauseBlockMaker()).thenReturn(request); + Mockito.when(request.send()).thenReturn(response); + Mockito.when(response.isValid()).thenReturn(Boolean.TRUE); + + Exchange exchange = createExchangeWithBodyAndHeader(null, OPERATION, Web3jConstants.QUORUM_PAUSE_BLOCK_MAKER); + template.send(exchange); + Boolean body = exchange.getIn().getBody(Boolean.class); + assertTrue(body); + } + + @Test + public void quorumResumeBlockMakerTest() throws Exception { + VoidResponse response = Mockito.mock(VoidResponse.class); + Mockito.when(mockQuorum.quorumResumeBlockMaker()).thenReturn(request); + Mockito.when(request.send()).thenReturn(response); + Mockito.when(response.isValid()).thenReturn(Boolean.TRUE); + + Exchange exchange = createExchangeWithBodyAndHeader(null, OPERATION, Web3jConstants.QUORUM_RESUME_BLOCK_MAKER); + template.send(exchange); + Boolean body = exchange.getIn().getBody(Boolean.class); + assertTrue(body); + } + + @Test + public void quorumIsBlockMakerTest() throws Exception { + BlockMaker response = Mockito.mock(BlockMaker.class); + Mockito.when(mockQuorum.quorumIsBlockMaker(any())).thenReturn(request); + Mockito.when(request.send()).thenReturn(response); + Mockito.when(response.isBlockMaker()).thenReturn(Boolean.TRUE); + + Exchange exchange = createExchangeWithBodyAndHeader(null, OPERATION, Web3jConstants.QUORUM_IS_BLOCK_MAKER); + template.send(exchange); + Boolean body = exchange.getIn().getBody(Boolean.class); + assertTrue(body); + } + + @Test + public void quorumIsVoterTest() throws Exception { + Voter response = Mockito.mock(Voter.class); + Mockito.when(mockQuorum.quorumIsVoter(any())).thenReturn(request); + Mockito.when(request.send()).thenReturn(response); + Mockito.when(response.isVoter()).thenReturn(Boolean.TRUE); + + Exchange exchange = createExchangeWithBodyAndHeader(null, OPERATION, Web3jConstants.QUORUM_IS_VOTER); + template.send(exchange); + Boolean body = exchange.getIn().getBody(Boolean.class); + assertTrue(body); + } + + @Test + public void quorumGetPrivatePayloadTest() throws Exception { + PrivatePayload response = Mockito.mock(PrivatePayload.class); + Mockito.when(mockQuorum.quorumGetPrivatePayload(any())).thenReturn(request); + Mockito.when(request.send()).thenReturn(response); + Mockito.when(response.getPrivatePayload()).thenReturn("secret"); + + Exchange exchange = createExchangeWithBodyAndHeader("foo", OPERATION, Web3jConstants.QUORUM_GET_PRIVATE_PAYLOAD); + template.send(exchange); + String body = exchange.getIn().getBody(String.class); + assertTrue(body.equals("secret")); + } + + @Test + public void quorumEthSendTransactionTest() throws Exception { + EthSendTransaction response = Mockito.mock(EthSendTransaction.class); + Mockito.when(mockQuorum.ethSendTransaction(any())).thenReturn(request); + Mockito.when(request.send()).thenReturn(response); + Mockito.when(response.getTransactionHash()).thenReturn("test"); + + Exchange exchange = createExchangeWithBodyAndHeader(null, OPERATION, Web3jConstants.QUORUM_ETH_SEND_TRANSACTION); + template.send(exchange); + String body = exchange.getIn().getBody(String.class); + assertTrue(body.equals("test")); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + public void configure() { + from("direct:start") + .to(getUrl() + OPERATION.toLowerCase() + "=" + Web3jConstants.WEB3_CLIENT_VERSION); + } + }; + } +} diff --git a/components/camel-web3j/src/test/java/org/apache/camel/component/web3j/integration/Web3jProducerGanacheTest.java b/components/camel-web3j/src/test/java/org/apache/camel/component/web3j/integration/Web3jProducerGanacheTest.java index ee8146a..1a5e7fa 100644 --- a/components/camel-web3j/src/test/java/org/apache/camel/component/web3j/integration/Web3jProducerGanacheTest.java +++ b/components/camel-web3j/src/test/java/org/apache/camel/component/web3j/integration/Web3jProducerGanacheTest.java @@ -24,6 +24,7 @@ import org.apache.camel.Exchange; import org.apache.camel.Produce; import org.apache.camel.ProducerTemplate; import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.web3j.Web3jConstants; import org.junit.Ignore; import org.junit.Test; import org.web3j.protocol.core.methods.response.EthBlock; @@ -343,6 +344,9 @@ public class Web3jProducerGanacheTest extends Web3jIntegrationTestSupport { exchange.getIn().setHeader(GAS_PRICE, BigInteger.valueOf(10000000000000L)); exchange.getIn().setHeader(GAS_LIMIT, BigInteger.valueOf(30400L)); exchange.getIn().setHeader(VALUE, BigInteger.valueOf(50000000000000L)); + +// String data = message.getHeader(Web3jConstants.DATA, configuration::getData, String.class); +// template.send(exchange); String body = exchange.getIn().getBody(String.class); assertTrue(body != null); diff --git a/parent/pom.xml b/parent/pom.xml index 9297407..23bb7ab 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -703,6 +703,7 @@ <vertx-version>3.5.3</vertx-version> <vysper-version>0.7</vysper-version> <web3j-version>3.5.0</web3j-version> + <web3j-quorum-version>0.8.0</web3j-quorum-version> <weld1-version>1.1.28.Final</weld1-version> <weld2-version>2.4.7.Final</weld2-version> <weld3-version>3.0.5.Final</weld3-version> diff --git a/platforms/spring-boot/components-starter/camel-web3j-starter/src/main/java/org/apache/camel/component/web3j/springboot/Web3jComponentConfiguration.java b/platforms/spring-boot/components-starter/camel-web3j-starter/src/main/java/org/apache/camel/component/web3j/springboot/Web3jComponentConfiguration.java index fc125ad..41d16e4 100644 --- a/platforms/spring-boot/components-starter/camel-web3j-starter/src/main/java/org/apache/camel/component/web3j/springboot/Web3jComponentConfiguration.java +++ b/platforms/spring-boot/components-starter/camel-web3j-starter/src/main/java/org/apache/camel/component/web3j/springboot/Web3jComponentConfiguration.java @@ -72,6 +72,14 @@ public class Web3jComponentConfiguration public static class Web3jConfigurationNestedConfiguration { public static final Class CAMEL_NESTED_CLASS = org.apache.camel.component.web3j.Web3jConfiguration.class; /** + * A transaction privateFor nodes with public keys in a Quorum network + */ + private List privateFor; + /** + * If true, this will support Quorum API. + */ + private Boolean quorumAPI = false; + /** * The preconfigured Web3j object. */ private Web3j web3j; @@ -195,6 +203,22 @@ public class Web3jComponentConfiguration */ private String operation = "transaction"; + public List getPrivateFor() { + return privateFor; + } + + public void setPrivateFor(List privateFor) { + this.privateFor = privateFor; + } + + public Boolean getQuorumAPI() { + return quorumAPI; + } + + public void setQuorumAPI(Boolean quorumAPI) { + this.quorumAPI = quorumAPI; + } + public Web3j getWeb3j() { return web3j; }