Skip to content

Commit 1aeb08a

Browse files
authored
Merge pull request #43 from proximax-storage/issue/41-listener_refactoring
Issue #41 listener refactoring
2 parents 975c0c3 + cec08ed commit 1aeb08a

26 files changed

+11790
-589
lines changed

src/e2e/java/io/proximax/sdk/E2EBaseTest.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
import org.slf4j.Logger;
3636
import org.slf4j.LoggerFactory;
3737

38-
import io.proximax.sdk.infrastructure.Listener;
3938
import io.proximax.sdk.model.account.Account;
4039
import io.proximax.sdk.model.account.Address;
4140
import io.proximax.sdk.model.mosaic.Mosaic;
@@ -66,7 +65,7 @@ public class E2EBaseTest extends BaseTest {
6665
protected NamespaceRepository namespaceHttp;
6766
protected MetadataRepository metadataHttp;
6867

69-
protected Listener listener;
68+
protected ListenerRepository listener;
7069

7170
protected Account seedAccount;
7271

src/e2e/java/io/proximax/sdk/E2ETransferTest.java

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,8 @@ void addListener() {
6363

6464
@AfterAll
6565
void closeDown() {
66-
// return the XPX
67-
SignedTransaction signedTransaction = signTransfer(simpleAccount,
68-
seedAccount.getAddress(),
69-
NetworkCurrencyMosaic.createAbsolute(BigInteger.valueOf(4)),
70-
new PlainMessage("money back guarantee"));
71-
logger.info("Returning funds. {}", transactionHttp.announce(signedTransaction).blockingFirst());
72-
logger.info("Returned funds. {}",
73-
listener.confirmed(simpleAccount.getAddress()).timeout(getTimeoutSeconds(), TimeUnit.SECONDS).blockingFirst());
66+
// return the funds
67+
returnAllToSeed(simpleAccount);
7468
// check that target account has expected number of incoming transactions
7569
int transactions = accountHttp.incomingTransactions(simpleAccount.getPublicAccount()).blockingFirst().size();
7670
// TODO why 2? we did 4 transfers but 2 were aggregate?
@@ -95,6 +89,16 @@ void sendSecureMessage() {
9589
transfer(seedAccount, simpleAccount.getAddress(), NetworkCurrencyMosaic.createAbsolute(BigInteger.valueOf(1)), secureMessage);
9690
}
9791

92+
@Test
93+
void insufficientFunds() {
94+
transactionHttp.announce(simpleAccount.sign(TransferTransaction.create(getDeadline(),
95+
seedAccount.getAddress(),
96+
Arrays.asList(NetworkCurrencyMosaic.createRelative(BigInteger.TEN)),
97+
PlainMessage.Empty,
98+
getNetworkType()))).blockingFirst();
99+
listener.status(simpleAccount.getAddress()).timeout(getTimeoutSeconds(), TimeUnit.SECONDS).blockingFirst();
100+
}
101+
98102
/**
99103
* return transactions as specified by arguments signed by the signer account
100104
*

src/e2e/java/io/proximax/sdk/infrastructure/E2ETest.java

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import io.proximax.core.crypto.Hashes;
3636
import io.proximax.sdk.BaseTest;
3737
import io.proximax.sdk.BlockchainApi;
38+
import io.proximax.sdk.ListenerRepository;
3839
import io.proximax.sdk.TransactionRepository;
3940
import io.proximax.sdk.model.account.Account;
4041
import io.proximax.sdk.model.account.Address;
@@ -55,20 +56,23 @@ class E2ETest extends BaseTest {
5556
private Account cosignatoryAccount;
5657
private Account cosignatoryAccount2;
5758
private NamespaceId namespaceId = new NamespaceId(new BigInteger("-1999805136990834023")); // This namespace is created in functional testing
58-
private String namespaceName = "nem2-tests";
5959
private MosaicId mosaicId = new MosaicId(new BigInteger("4532189107927582222")); // This mosaic is created in functional testing
60-
private Listener listener;
60+
private ListenerRepository listener;
6161

6262
@BeforeAll
63-
void setup() throws ExecutionException, InterruptedException, IOException {
64-
transactionHttp = new BlockchainApi(new URL(this.getNodeUrl()), getNetworkType()).createTransactionRepository();
65-
account = new Account("787225aaff3d2c71f4ffa32d4f19ec4922f3cd869747f267378f81f8e3fcb12d", NetworkType.MIJIN_TEST);
66-
multisigAccount = new Account("5edebfdbeb32e9146d05ffd232c8af2cf9f396caf9954289daa0362d097fff3b", NetworkType.MIJIN_TEST);
67-
cosignatoryAccount = new Account("2a2b1f5d366a5dd5dc56c3c757cf4fe6c66e2787087692cf329d7a49a594658b", NetworkType.MIJIN_TEST);
68-
cosignatoryAccount2 = new Account("b8afae6f4ad13a1b8aad047b488e0738a437c7389d4ff30c359ac068910c1d59", NetworkType.MIJIN_TEST);
69-
listener = new Listener(new URL(getNodeUrl()));
70-
listener.open().get();
71-
}
63+
void setup() throws ExecutionException, InterruptedException, IOException {
64+
BlockchainApi api = new BlockchainApi(new URL(this.getNodeUrl()), getNetworkType());
65+
transactionHttp = api.createTransactionRepository();
66+
account = new Account("787225aaff3d2c71f4ffa32d4f19ec4922f3cd869747f267378f81f8e3fcb12d", NetworkType.MIJIN_TEST);
67+
multisigAccount = new Account("5edebfdbeb32e9146d05ffd232c8af2cf9f396caf9954289daa0362d097fff3b",
68+
NetworkType.MIJIN_TEST);
69+
cosignatoryAccount = new Account("2a2b1f5d366a5dd5dc56c3c757cf4fe6c66e2787087692cf329d7a49a594658b",
70+
NetworkType.MIJIN_TEST);
71+
cosignatoryAccount2 = new Account("b8afae6f4ad13a1b8aad047b488e0738a437c7389d4ff30c359ac068910c1d59",
72+
NetworkType.MIJIN_TEST);
73+
listener = api.createListener();
74+
listener.open().get();
75+
}
7276

7377
@Test
7478
void standaloneTransferTransaction() throws ExecutionException, InterruptedException {

src/e2e/java/io/proximax/sdk/infrastructure/ListenerTest.java

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import io.proximax.sdk.AccountRepository;
3939
import io.proximax.sdk.BaseTest;
4040
import io.proximax.sdk.BlockchainApi;
41+
import io.proximax.sdk.ListenerRepository;
4142
import io.proximax.sdk.TransactionRepository;
4243
import io.proximax.sdk.model.account.Account;
4344
import io.proximax.sdk.model.account.Address;
@@ -78,7 +79,8 @@ void setup() throws IOException {
7879

7980
@Test
8081
void shouldConnectToWebSocket() throws ExecutionException, InterruptedException, IOException {
81-
Listener listener = new Listener(new URL(getNodeUrl()));
82+
BlockchainApi api = new BlockchainApi(new URL(this.getNodeUrl()), getNetworkType());
83+
ListenerRepository listener = api.createListener();
8284
CompletableFuture<Void> connected = listener.open();
8385
connected.get();
8486
assertTrue(connected.isDone());
@@ -87,7 +89,8 @@ void shouldConnectToWebSocket() throws ExecutionException, InterruptedException,
8789

8890
@Test
8991
void shouldReturnNewBlockViaListener() throws ExecutionException, InterruptedException, IOException {
90-
Listener listener = new Listener(new URL(getNodeUrl()));
92+
BlockchainApi api = new BlockchainApi(new URL(this.getNodeUrl()), getNetworkType());
93+
ListenerRepository listener = api.createListener();
9194
listener.open().get();
9295

9396
this.announceStandaloneTransferTransaction();
@@ -99,7 +102,8 @@ void shouldReturnNewBlockViaListener() throws ExecutionException, InterruptedExc
99102

100103
@Test
101104
void shouldReturnConfirmedTransactionAddressSignerViaListener() throws ExecutionException, InterruptedException, IOException {
102-
Listener listener = new Listener(new URL(getNodeUrl()));
105+
BlockchainApi api = new BlockchainApi(new URL(this.getNodeUrl()), getNetworkType());
106+
ListenerRepository listener = api.createListener();
103107
listener.open().get();
104108

105109
SignedTransaction signedTransaction = this.announceStandaloneTransferTransaction();
@@ -110,7 +114,8 @@ void shouldReturnConfirmedTransactionAddressSignerViaListener() throws Execution
110114

111115
@Test
112116
void shouldReturnConfirmedTransactionAddressRecipientViaListener() throws ExecutionException, InterruptedException, IOException {
113-
Listener listener = new Listener(new URL(getNodeUrl()));
117+
BlockchainApi api = new BlockchainApi(new URL(this.getNodeUrl()), getNetworkType());
118+
ListenerRepository listener = api.createListener();
114119
listener.open().get();
115120

116121
SignedTransaction signedTransaction = this.announceStandaloneTransferTransaction();
@@ -122,7 +127,8 @@ void shouldReturnConfirmedTransactionAddressRecipientViaListener() throws Execut
122127

123128
@Test
124129
void shouldReturnUnconfirmedAddedTransactionViaListener() throws ExecutionException, InterruptedException, IOException {
125-
Listener listener = new Listener(new URL(getNodeUrl()));
130+
BlockchainApi api = new BlockchainApi(new URL(this.getNodeUrl()), getNetworkType());
131+
ListenerRepository listener = api.createListener();
126132
listener.open().get();
127133

128134
SignedTransaction signedTransaction = this.announceStandaloneTransferTransaction();
@@ -133,7 +139,8 @@ void shouldReturnUnconfirmedAddedTransactionViaListener() throws ExecutionExcept
133139

134140
@Test
135141
void shouldReturnUnconfirmedRemovedTransactionViaListener() throws ExecutionException, InterruptedException, IOException {
136-
Listener listener = new Listener(new URL(getNodeUrl()));
142+
BlockchainApi api = new BlockchainApi(new URL(this.getNodeUrl()), getNetworkType());
143+
ListenerRepository listener = api.createListener();
137144
listener.open().get();
138145

139146
SignedTransaction signedTransaction = this.announceStandaloneTransferTransaction();
@@ -145,7 +152,8 @@ void shouldReturnUnconfirmedRemovedTransactionViaListener() throws ExecutionExce
145152
@Disabled
146153
@Test
147154
void shouldReturnAggregateBondedAddedTransactionViaListener() throws ExecutionException, InterruptedException, IOException {
148-
Listener listener = new Listener(new URL(getNodeUrl()));
155+
BlockchainApi api = new BlockchainApi(new URL(this.getNodeUrl()), getNetworkType());
156+
ListenerRepository listener = api.createListener();
149157
listener.open().get();
150158

151159
SignedTransaction signedTransaction = this.announceAggregateBondedTransaction();
@@ -157,7 +165,8 @@ void shouldReturnAggregateBondedAddedTransactionViaListener() throws ExecutionEx
157165
@Disabled
158166
@Test
159167
void shouldReturnAggregateBondedRemovedTransactionViaListener() throws ExecutionException, InterruptedException, IOException {
160-
Listener listener = new Listener(new URL(getNodeUrl()));
168+
BlockchainApi api = new BlockchainApi(new URL(this.getNodeUrl()), getNetworkType());
169+
ListenerRepository listener = api.createListener();
161170
listener.open().get();
162171

163172
SignedTransaction signedTransaction = this.announceAggregateBondedTransaction();
@@ -169,7 +178,8 @@ void shouldReturnAggregateBondedRemovedTransactionViaListener() throws Execution
169178
@Disabled
170179
@Test
171180
void shouldReturnCosignatureAddedViaListener() throws ExecutionException, InterruptedException, IOException {
172-
Listener listener = new Listener(new URL(getNodeUrl()));
181+
BlockchainApi api = new BlockchainApi(new URL(this.getNodeUrl()), getNetworkType());
182+
ListenerRepository listener = api.createListener();
173183
listener.open().get();
174184

175185
SignedTransaction signedTransaction = this.announceAggregateBondedTransaction();
@@ -192,7 +202,8 @@ void shouldReturnCosignatureAddedViaListener() throws ExecutionException, Interr
192202

193203
@Test
194204
void shouldReturnTransactionStatusGivenAddedViaListener() throws ExecutionException, InterruptedException, IOException {
195-
Listener listener = new Listener(new URL(getNodeUrl()));
205+
BlockchainApi api = new BlockchainApi(new URL(this.getNodeUrl()), getNetworkType());
206+
ListenerRepository listener = api.createListener();
196207
listener.open().get();
197208

198209
SignedTransaction signedTransaction = this.announceStandaloneTransferTransactionWithInsufficientBalance();

src/main/java/io/proximax/sdk/BlockchainApi.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,8 @@ public TransactionRepository createTransactionRepository() {
137137
*
138138
* @return the network listener
139139
*/
140-
public Listener createListener() {
141-
return new Listener(url);
140+
public ListenerRepository createListener() {
141+
return new Listener(this);
142142
}
143143

144144
/**
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
/*
2+
* Copyright 2018 NEM
3+
* Copyright 2019 ProximaX
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package io.proximax.sdk;
19+
20+
import java.util.concurrent.CompletableFuture;
21+
22+
import io.proximax.sdk.model.account.Address;
23+
import io.proximax.sdk.model.blockchain.BlockInfo;
24+
import io.proximax.sdk.model.transaction.AggregateTransaction;
25+
import io.proximax.sdk.model.transaction.CosignatureSignedTransaction;
26+
import io.proximax.sdk.model.transaction.Transaction;
27+
import io.proximax.sdk.model.transaction.TransactionStatusError;
28+
import io.reactivex.Observable;
29+
30+
/**
31+
* Listener
32+
*
33+
* @since 1.0
34+
*/
35+
public interface ListenerRepository {
36+
37+
/**
38+
* UID of the listener as registered on server
39+
*
40+
* @return the UID connected to
41+
*/
42+
public String getUID();
43+
44+
/**
45+
* @return a {@link CompletableFuture} that resolves when the web-socket connection is opened
46+
*/
47+
public CompletableFuture<Void> open();
48+
49+
/**
50+
* Close webSocket connection
51+
*/
52+
public void close();
53+
54+
/**
55+
* Returns an observable stream of BlockInfo.
56+
* Each time a new Block is added into the blockchain,
57+
* it emits a new BlockInfo in the event stream.
58+
*
59+
* @return an observable stream of BlockInfo
60+
*/
61+
public Observable<BlockInfo> newBlock();
62+
63+
/**
64+
* Returns an observable stream of Transaction for a specific address.
65+
* Each time a transaction is in confirmed state an it involves the address,
66+
* it emits a new Transaction in the event stream.
67+
*
68+
* @param address address we listen when a transaction is in confirmed state
69+
* @return an observable stream of Transaction with state confirmed
70+
*/
71+
public Observable<Transaction> confirmed(Address address);
72+
73+
/**
74+
* Returns an observable stream of Transaction for a specific address.
75+
* Each time a transaction is in unconfirmed state an it involves the address,
76+
* it emits a new Transaction in the event stream.
77+
*
78+
* @param address address we listen when a transaction is in unconfirmed state
79+
* @return an observable stream of Transaction with state unconfirmed
80+
*/
81+
public Observable<Transaction> unconfirmedAdded(Address address);
82+
83+
/**
84+
* Returns an observable stream of Transaction Hashes for specific address.
85+
* Each time a transaction with state unconfirmed changes its state,
86+
* it emits a new message with the transaction hash in the event stream.
87+
*
88+
* @param address address we listen when a transaction is removed from unconfirmed state
89+
* @return an observable stream of Strings with the transaction hash
90+
*/
91+
public Observable<String> unconfirmedRemoved(Address address);
92+
93+
/**
94+
* Return an observable of {@link AggregateTransaction} for specific address.
95+
* Each time an aggregate bonded transaction is announced,
96+
* it emits a new {@link AggregateTransaction} in the event stream.
97+
*
98+
* @param address address we listen when a transaction with missing signatures state
99+
* @return an observable stream of AggregateTransaction with missing signatures state
100+
*/
101+
public Observable<AggregateTransaction> aggregateBondedAdded(Address address);
102+
103+
/**
104+
* Returns an observable stream of Transaction Hashes for specific address.
105+
* Each time an aggregate bonded transaction is announced,
106+
* it emits a new message with the transaction hash in the event stream.
107+
*
108+
* @param address address we listen when a transaction is confirmed or rejected
109+
* @return an observable stream of Strings with the transaction hash
110+
*/
111+
public Observable<String> aggregateBondedRemoved(Address address);
112+
113+
/**
114+
* Returns an observable stream of {@link TransactionStatusError} for specific address.
115+
* Each time a transaction contains an error,
116+
* it emits a new message with the transaction status error in the event stream.
117+
*
118+
* @param address address we listen to be notified when some error happened
119+
* @return an observable stream of {@link TransactionStatusError}
120+
*/
121+
public Observable<TransactionStatusError> status(Address address);
122+
123+
/**
124+
* Returns an observable stream of {@link CosignatureSignedTransaction} for specific address.
125+
* Each time a cosigner signs a transaction the address initialized,
126+
* it emits a new message with the cosignatory signed transaction in the even stream.
127+
*
128+
* @param address address we listen when a cosignatory is added to some transaction address sent
129+
* @return an observable stream of {@link CosignatureSignedTransaction}
130+
*/
131+
public Observable<CosignatureSignedTransaction> cosignatureAdded(Address address);
132+
}

src/main/java/io/proximax/sdk/infrastructure/HttpClient.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
import com.google.gson.JsonObject;
1919

2020
import io.reactivex.Observable;
21+
import okhttp3.Request;
22+
import okhttp3.WebSocket;
23+
import okhttp3.WebSocketListener;
2124

2225
/**
2326
* generic HTTP client API
@@ -83,4 +86,11 @@ public interface HttpClient {
8386
* @return observable response
8487
*/
8588
Observable<HttpResponse> putAbs(String absoluteUrl, JsonObject body);
89+
90+
/**
91+
* @param request
92+
* @param webSocketListener
93+
* @return
94+
*/
95+
WebSocket newWebSocket(Request request, WebSocketListener webSocketListener);
8696
}

0 commit comments

Comments
 (0)