Telling the Deserializing LimitOrderCreateOperation objects in the stream coming in the SubscriptionMessagesHub
This commit is contained in:
parent
37f52283a9
commit
457164b002
6 changed files with 162 additions and 13 deletions
|
@ -1,11 +1,16 @@
|
|||
package de.bitsharesmunich.graphenej;
|
||||
|
||||
import com.google.common.primitives.Bytes;
|
||||
import com.google.gson.*;
|
||||
import de.bitsharesmunich.graphenej.interfaces.ByteSerializable;
|
||||
import de.bitsharesmunich.graphenej.interfaces.JsonSerializable;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
|
||||
import de.bitsharesmunich.graphenej.operations.TransferOperation;
|
||||
import org.bitcoinj.core.DumpedPrivateKey;
|
||||
import org.bitcoinj.core.ECKey;
|
||||
import org.bitcoinj.core.Sha256Hash;
|
||||
|
@ -19,6 +24,11 @@ import java.util.Date;
|
|||
import java.util.List;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import de.bitsharesmunich.graphenej.interfaces.ByteSerializable;
|
||||
import de.bitsharesmunich.graphenej.interfaces.JsonSerializable;
|
||||
import de.bitsharesmunich.graphenej.operations.LimitOrderCreateOperation;
|
||||
import de.bitsharesmunich.graphenej.operations.TransferOperation;
|
||||
|
||||
/**
|
||||
* Class used to represent a generic Graphene transaction.
|
||||
*/
|
||||
|
@ -263,10 +273,9 @@ public class Transaction implements ByteSerializable, JsonSerializable {
|
|||
for (JsonElement jsonOperation : jsonObject.get(KEY_OPERATIONS).getAsJsonArray()) {
|
||||
int operationId = jsonOperation.getAsJsonArray().get(0).getAsInt();
|
||||
if (operationId == OperationType.TRANSFER_OPERATION.ordinal()) {
|
||||
System.out.println("Transfer operation detected!");
|
||||
operation = context.deserialize(jsonOperation, TransferOperation.class);
|
||||
} else if (operationId == OperationType.LIMIT_ORDER_CREATE_OPERATION.ordinal()) {
|
||||
//TODO: Add operation deserialization support
|
||||
operation = context.deserialize(jsonOperation, LimitOrderCreateOperation.class);
|
||||
} else if (operationId == OperationType.LIMIT_ORDER_CANCEL_OPERATION.ordinal()) {
|
||||
//TODO: Add operation deserialization support
|
||||
} else if (operationId == OperationType.CALL_ORDER_UPDATE_OPERATION.ordinal()) {
|
||||
|
|
|
@ -15,6 +15,7 @@ import java.util.Map;
|
|||
import de.bitsharesmunich.graphenej.AssetAmount;
|
||||
import de.bitsharesmunich.graphenej.RPC;
|
||||
import de.bitsharesmunich.graphenej.Transaction;
|
||||
import de.bitsharesmunich.graphenej.UserAccount;
|
||||
import de.bitsharesmunich.graphenej.interfaces.SubscriptionHub;
|
||||
import de.bitsharesmunich.graphenej.interfaces.SubscriptionListener;
|
||||
import de.bitsharesmunich.graphenej.interfaces.WitnessResponseListener;
|
||||
|
@ -22,6 +23,7 @@ import de.bitsharesmunich.graphenej.models.ApiCall;
|
|||
import de.bitsharesmunich.graphenej.models.DynamicGlobalProperties;
|
||||
import de.bitsharesmunich.graphenej.models.SubscriptionResponse;
|
||||
import de.bitsharesmunich.graphenej.models.WitnessResponse;
|
||||
import de.bitsharesmunich.graphenej.operations.LimitOrderCreateOperation;
|
||||
import de.bitsharesmunich.graphenej.operations.TransferOperation;
|
||||
|
||||
/**
|
||||
|
@ -54,7 +56,9 @@ public class SubscriptionMessagesHub extends BaseGrapheneHandler implements Subs
|
|||
builder.registerTypeAdapter(SubscriptionResponse.class, mSubscriptionDeserializer);
|
||||
builder.registerTypeAdapter(Transaction.class, new Transaction.TransactionDeserializer());
|
||||
builder.registerTypeAdapter(TransferOperation.class, new TransferOperation.TransferDeserializer());
|
||||
builder.registerTypeAdapter(LimitOrderCreateOperation.class, new LimitOrderCreateOperation.LimitOrderCreateDeserializer());
|
||||
builder.registerTypeAdapter(AssetAmount.class, new AssetAmount.AssetAmountDeserializer());
|
||||
builder.registerTypeAdapter(UserAccount.class, new UserAccount.UserAccountSimpleDeserializer());
|
||||
builder.registerTypeAdapter(DynamicGlobalProperties.class, new DynamicGlobalProperties.DynamicGlobalPropertiesDeserializer());
|
||||
this.gson = builder.create();
|
||||
}
|
||||
|
@ -104,7 +108,7 @@ public class SubscriptionMessagesHub extends BaseGrapheneHandler implements Subs
|
|||
}else if(currentId == SUBCRIPTION_REQUEST){
|
||||
// There's nothing to handle here.
|
||||
}else{
|
||||
SubscriptionResponse subscriptionResponse = gson.fromJson(message, SubscriptionResponse.class);
|
||||
gson.fromJson(message, SubscriptionResponse.class);
|
||||
}
|
||||
currentId++;
|
||||
}
|
||||
|
|
|
@ -120,8 +120,8 @@ public class SubscriptionResponse {
|
|||
JsonArray subArray = paramsArray.get(1).getAsJsonArray().get(0).getAsJsonArray();
|
||||
for(JsonElement object : subArray){
|
||||
if(object.isJsonObject()){
|
||||
|
||||
GrapheneObject grapheneObject = new GrapheneObject(object.getAsJsonObject().get(KEY_ID).getAsString());
|
||||
|
||||
int listenerTypeCount = 0;
|
||||
if(this.listenerTypeCount.containsKey(grapheneObject.getObjectType())){
|
||||
listenerTypeCount = this.listenerTypeCount.get(grapheneObject.getObjectType());
|
||||
|
|
|
@ -2,10 +2,15 @@ package de.bitsharesmunich.graphenej.operations;
|
|||
|
||||
import com.google.common.primitives.Bytes;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
@ -151,4 +156,78 @@ public class LimitOrderCreateOperation extends BaseOperation {
|
|||
|
||||
return Bytes.concat(feeBytes, sellerBytes, amountBytes, minAmountBytes, expirationBytes, fillOrKill, extensions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializer used to convert the JSON-formatted representation of a limit_order_create_operation
|
||||
* into its java object version.
|
||||
*
|
||||
* The following is an example of the serialized form of this operation:
|
||||
*
|
||||
* [
|
||||
* 1,
|
||||
* {
|
||||
* "fee": {
|
||||
* "amount": 14676,
|
||||
* "asset_id": "1.3.0"
|
||||
* },
|
||||
* "seller": "1.2.36449",
|
||||
* "amount_to_sell": {
|
||||
* "amount": 945472,
|
||||
* "asset_id": "1.3.850"
|
||||
* },
|
||||
* "min_to_receive": {
|
||||
* "amount": 4354658,
|
||||
* "asset_id": "1.3.861"
|
||||
* },
|
||||
* "expiration": "1963-11-25T06:31:44",
|
||||
* "fill_or_kill": false,
|
||||
* "extensions": []
|
||||
* }
|
||||
* ]
|
||||
*
|
||||
*
|
||||
*/
|
||||
public static class LimitOrderCreateDeserializer implements JsonDeserializer<LimitOrderCreateOperation> {
|
||||
|
||||
@Override
|
||||
public LimitOrderCreateOperation deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
if(json.isJsonArray()){
|
||||
// This block is used just to check if we are in the first step of the deserialization
|
||||
// when we are dealing with an array.
|
||||
JsonArray serializedTransfer = json.getAsJsonArray();
|
||||
if(serializedTransfer.get(0).getAsInt() != OperationType.LIMIT_ORDER_CREATE_OPERATION.ordinal()){
|
||||
// If the operation type does not correspond to a transfer operation, we return null
|
||||
return null;
|
||||
}else{
|
||||
// Calling itself recursively, this is only done once, so there will be no problems.
|
||||
return context.deserialize(serializedTransfer.get(1), LimitOrderCreateOperation.class);
|
||||
}
|
||||
}else{
|
||||
// This block is called in the second recursion and takes care of deserializing the
|
||||
// limit order data itself.
|
||||
JsonObject jsonObject = json.getAsJsonObject();
|
||||
|
||||
AssetAmount fee = context.deserialize(jsonObject.get(KEY_FEE), AssetAmount.class);
|
||||
UserAccount seller = context.deserialize(jsonObject.get(KEY_SELLER), UserAccount.class);
|
||||
AssetAmount amountToSell = context.deserialize(jsonObject.get(KEY_AMOUNT_TO_SELL), AssetAmount.class);
|
||||
AssetAmount minToReceive = context.deserialize(jsonObject.get(KEY_MIN_TO_RECEIVE), AssetAmount.class);
|
||||
String expiration = jsonObject.get(KEY_EXPIRATION).getAsString();
|
||||
boolean fillOrKill = jsonObject.get(KEY_FILL_OR_KILL).getAsBoolean();
|
||||
|
||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(Util.TIME_DATE_FORMAT);
|
||||
int expirationPosix = 0;
|
||||
try {
|
||||
Date expirationDate = simpleDateFormat.parse(expiration);
|
||||
expirationPosix = (int) (expirationDate.getTime() / 1000);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// Creating an instance of the LimitOrderCreateOperation and setting the fee
|
||||
LimitOrderCreateOperation operation = new LimitOrderCreateOperation(seller, amountToSell, minToReceive, expirationPosix, fillOrKill);
|
||||
operation.setFee(fee);
|
||||
return operation;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package de.bitsharesmunich.graphenej;
|
||||
|
||||
import org.junit.Assert;
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -8,7 +9,6 @@ import org.junit.Test;
|
|||
* Created by nelson on 4/18/17.
|
||||
*/
|
||||
public class BrainKeyTest {
|
||||
// public final String TEST_BRAINKEY = "SOAPILY GASSING FIFIE OZONATE WHYO TOPLINE PRISMY ZEUGMA GLOTTIC DAVEN CORODY PFUI";
|
||||
public final String TEST_BRAINKEY = "BARIC BICKERN LITZ TIPFUL JINGLED POOL TUMBAK PURIST APOPYLE DURAIN SATLIJK FAUCAL";
|
||||
private BrainKey mBrainKey;
|
||||
|
||||
|
@ -20,9 +20,6 @@ public class BrainKeyTest {
|
|||
@Test
|
||||
public void testAddress(){
|
||||
Address address = mBrainKey.getPublicAddress(Address.BITSHARES_PREFIX);
|
||||
// Assert.assertEquals("Assert that the address created is the expected one",
|
||||
// "BTS7yT2vnjGAxPocqsnDfoJv3DHUtCNGWwqvc7mWRikkqwuhKtT5s",
|
||||
// address.toString());
|
||||
Assert.assertEquals("Assert that the address created is the expected one",
|
||||
"BTS61UqqgE3ARuTGcckzARsdQm4EMFdBEwYyi1pbwyHrZZWrCDhT2",
|
||||
address.toString());
|
||||
|
|
|
@ -3,11 +3,16 @@ package de.bitsharesmunich.graphenej.api;
|
|||
import com.neovisionaries.ws.client.WebSocketException;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
import de.bitsharesmunich.graphenej.ObjectType;
|
||||
import de.bitsharesmunich.graphenej.Transaction;
|
||||
import de.bitsharesmunich.graphenej.interfaces.SubscriptionListener;
|
||||
import de.bitsharesmunich.graphenej.interfaces.WitnessResponseListener;
|
||||
import de.bitsharesmunich.graphenej.models.BaseResponse;
|
||||
import de.bitsharesmunich.graphenej.models.BroadcastedTransaction;
|
||||
import de.bitsharesmunich.graphenej.models.DynamicGlobalProperties;
|
||||
import de.bitsharesmunich.graphenej.models.SubscriptionResponse;
|
||||
import de.bitsharesmunich.graphenej.models.WitnessResponse;
|
||||
|
@ -82,4 +87,59 @@ public class SubscriptionMessagesHubTest extends BaseApiTest {
|
|||
System.out.println("InterruptedException. Msg: "+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a basic test that will only display a count of operations per received broadcasted transactions.
|
||||
*/
|
||||
@Test
|
||||
public void testBroadcastedTransactionDeserializer(){
|
||||
try{
|
||||
mMessagesHub = new SubscriptionMessagesHub("", "", mErrorListener);
|
||||
mMessagesHub.addSubscriptionListener(new SubscriptionListener() {
|
||||
private int MAX_MESSAGES = 15;
|
||||
private int messageCounter = 0;
|
||||
|
||||
@Override
|
||||
public ObjectType getInterestObjectType() {
|
||||
return ObjectType.TRANSACTION_OBJECT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSubscriptionUpdate(SubscriptionResponse response) {
|
||||
if(response.params.size() == 2){
|
||||
List<Serializable> payload = (List) response.params.get(1);
|
||||
if(payload.size() > 0){
|
||||
for(Serializable item : payload){
|
||||
if(item instanceof BroadcastedTransaction){
|
||||
BroadcastedTransaction broadcastedTransaction = (BroadcastedTransaction) item;
|
||||
Transaction tx = broadcastedTransaction.getTransaction();
|
||||
System.out.println(String.format("Got %d operations", tx.getOperations().size()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Waiting for MAX_MESSAGES messages before releasing the wait lock
|
||||
messageCounter++;
|
||||
if(messageCounter > MAX_MESSAGES){
|
||||
synchronized (SubscriptionMessagesHubTest.this){
|
||||
SubscriptionMessagesHubTest.this.notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
mWebSocket.addListener(mMessagesHub);
|
||||
mWebSocket.connect();
|
||||
|
||||
// Holding this thread while we get update notifications
|
||||
synchronized (this){
|
||||
wait();
|
||||
}
|
||||
} catch (WebSocketException e) {
|
||||
System.out.println("WebSocketException. Msg: " + e.getMessage());
|
||||
} catch (InterruptedException e) {
|
||||
System.out.println("InterruptedException. Msg: "+e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue