Detecting and deserializing operation history objects

This commit is contained in:
Nelson R. Perez 2018-04-27 00:09:37 -05:00
parent 5dea8a6eb4
commit 0b79231a3a
4 changed files with 112 additions and 10 deletions

View file

@ -23,6 +23,7 @@ import cy.agorise.graphenej.interfaces.SubscriptionHub;
import cy.agorise.graphenej.interfaces.SubscriptionListener; import cy.agorise.graphenej.interfaces.SubscriptionListener;
import cy.agorise.graphenej.models.ApiCall; import cy.agorise.graphenej.models.ApiCall;
import cy.agorise.graphenej.models.DynamicGlobalProperties; import cy.agorise.graphenej.models.DynamicGlobalProperties;
import cy.agorise.graphenej.models.OperationHistory;
import cy.agorise.graphenej.models.SubscriptionResponse; import cy.agorise.graphenej.models.SubscriptionResponse;
import cy.agorise.graphenej.models.WitnessResponse; import cy.agorise.graphenej.models.WitnessResponse;
import cy.agorise.graphenej.objects.Memo; import cy.agorise.graphenej.objects.Memo;
@ -96,6 +97,7 @@ public class SubscriptionMessagesHub extends BaseGrapheneHandler implements Subs
builder.registerTypeAdapter(UserAccount.class, new UserAccount.UserAccountSimpleDeserializer()); builder.registerTypeAdapter(UserAccount.class, new UserAccount.UserAccountSimpleDeserializer());
builder.registerTypeAdapter(DynamicGlobalProperties.class, new DynamicGlobalProperties.DynamicGlobalPropertiesDeserializer()); builder.registerTypeAdapter(DynamicGlobalProperties.class, new DynamicGlobalProperties.DynamicGlobalPropertiesDeserializer());
builder.registerTypeAdapter(Memo.class, new Memo.MemoDeserializer()); builder.registerTypeAdapter(Memo.class, new Memo.MemoDeserializer());
builder.registerTypeAdapter(OperationHistory.class, new OperationHistory.OperationHistoryDeserializer());
this.gson = builder.create(); this.gson = builder.create();
} }

View file

@ -1,5 +1,15 @@
package cy.agorise.graphenej.models; package cy.agorise.graphenej.models;
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.io.Serializable;
import java.lang.reflect.Type;
import cy.agorise.graphenej.GrapheneObject;
import cy.agorise.graphenej.operations.TransferOperation; import cy.agorise.graphenej.operations.TransferOperation;
@ -10,8 +20,13 @@ import cy.agorise.graphenej.operations.TransferOperation;
* More operations types might be listed in the response of that method, but by using this class * More operations types might be listed in the response of that method, but by using this class
* those will be filtered out of the parsed result. * those will be filtered out of the parsed result.
*/ */
public class OperationHistory { public class OperationHistory extends GrapheneObject implements Serializable {
private String id; public static final String KEY_OP = "op";
public static final String KEY_BLOCK_NUM = "block_num";
public static final String KEY_TRX_IN_BLOCK = "trx_in_block";
public static final String KEY_OP_IN_TRX = "op_in_trx";
public static final String KEY_VIRTUAL_OP = "virtual_op";
private TransferOperation op; private TransferOperation op;
public Object[] result; public Object[] result;
private long block_num; private long block_num;
@ -19,12 +34,8 @@ public class OperationHistory {
private long op_in_trx; private long op_in_trx;
private long virtual_op; private long virtual_op;
public String getId() { public OperationHistory(String id) {
return id; super(id);
}
public void setId(String id) {
this.id = id;
} }
public TransferOperation getOperation() { public TransferOperation getOperation() {
@ -66,4 +77,61 @@ public class OperationHistory {
public void setVirtualOp(long virtual_op) { public void setVirtualOp(long virtual_op) {
this.virtual_op = virtual_op; this.virtual_op = virtual_op;
} }
/**
* Deserializer used to transform a an operation history object from its serialized form to an
* OperationHistory instance.
*
* The serialized form of this object is the following:
*
* {
"id": "1.11.178205535",
"op": [
14,
{
"fee": {
"amount": 10425,
"asset_id": "1.3.0"
},
"issuer": "1.2.374566",
"asset_to_issue": {
"amount": 8387660,
"asset_id": "1.3.3271"
},
"issue_to_account": "1.2.797835",
"extensions": []
}
],
"result": [
0,
{}
],
"block_num": 26473240,
"trx_in_block": 11,
"op_in_trx": 0,
"virtual_op": 660
}
* //TODO: Expand this deserializer for operation history objects that have an operation other than the transfer operation
*/
public static class OperationHistoryDeserializer implements JsonDeserializer<OperationHistory> {
@Override
public OperationHistory deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
JsonObject jsonObject = json.getAsJsonObject();
String id = jsonObject.get(KEY_ID).getAsString();
long blockNum = jsonObject.get(KEY_BLOCK_NUM).getAsLong();
long trxInBlock = jsonObject.get(KEY_TRX_IN_BLOCK).getAsLong();
long opInTrx = jsonObject.get(KEY_OP_IN_TRX).getAsLong();
TransferOperation transferOperation = context.deserialize(jsonObject.get(KEY_OP), TransferOperation.class);
long virtualOp = jsonObject.get(KEY_VIRTUAL_OP).getAsLong();
OperationHistory operationHistory = new OperationHistory(id);
operationHistory.setBlockNum(blockNum);
operationHistory.setTransactionsInBlock(trxInBlock);
operationHistory.setOperationsInTrx(opInTrx);
operationHistory.setOperation(transferOperation);
operationHistory.setVirtualOp(virtualOp);
return operationHistory;
}
}
} }

View file

@ -16,6 +16,7 @@ import java.util.List;
import cy.agorise.graphenej.GrapheneObject; import cy.agorise.graphenej.GrapheneObject;
import cy.agorise.graphenej.ObjectType; import cy.agorise.graphenej.ObjectType;
import cy.agorise.graphenej.OperationType;
import cy.agorise.graphenej.Transaction; import cy.agorise.graphenej.Transaction;
import cy.agorise.graphenej.interfaces.SubscriptionListener; import cy.agorise.graphenej.interfaces.SubscriptionListener;
@ -183,7 +184,13 @@ public class SubscriptionResponse {
objectMap.put(ObjectType.TRANSACTION_OBJECT, true); objectMap.put(ObjectType.TRANSACTION_OBJECT, true);
secondArgument.add(broadcastedTransaction); secondArgument.add(broadcastedTransaction);
}else if(grapheneObject.getObjectType() == ObjectType.OPERATION_HISTORY_OBJECT){ }else if(grapheneObject.getObjectType() == ObjectType.OPERATION_HISTORY_OBJECT){
//TODO: Add support for other types of objects if(jsonObject.get(OperationHistory.KEY_OP).getAsJsonArray().get(0).getAsLong() == OperationType.TRANSFER_OPERATION.ordinal()){
OperationHistory operationHistory = context.deserialize(jsonObject, OperationHistory.class);
objectMap.put(ObjectType.OPERATION_HISTORY_OBJECT, true);
secondArgument.add(operationHistory);
}else{
//TODO: Add support for other operations
}
}else{ }else{
//TODO: Add support for other types of objects //TODO: Add support for other types of objects
} }

View file

@ -15,6 +15,7 @@ import cy.agorise.graphenej.interfaces.SubscriptionListener;
import cy.agorise.graphenej.models.BaseResponse; import cy.agorise.graphenej.models.BaseResponse;
import cy.agorise.graphenej.models.BroadcastedTransaction; import cy.agorise.graphenej.models.BroadcastedTransaction;
import cy.agorise.graphenej.models.DynamicGlobalProperties; import cy.agorise.graphenej.models.DynamicGlobalProperties;
import cy.agorise.graphenej.models.OperationHistory;
import cy.agorise.graphenej.models.SubscriptionResponse; import cy.agorise.graphenej.models.SubscriptionResponse;
import cy.agorise.graphenej.Transaction; import cy.agorise.graphenej.Transaction;
@ -197,7 +198,7 @@ public class SubscriptionMessagesHubTest extends BaseApiTest {
if(item instanceof BroadcastedTransaction){ if(item instanceof BroadcastedTransaction){
BroadcastedTransaction broadcastedTransaction = (BroadcastedTransaction) item; BroadcastedTransaction broadcastedTransaction = (BroadcastedTransaction) item;
Transaction tx = broadcastedTransaction.getTransaction(); Transaction tx = broadcastedTransaction.getTransaction();
System.out.println(String.format("Got %d operations", tx.getOperations().size())); // System.out.println(String.format("Got %d operations", tx.getOperations().size()));
} }
} }
} }
@ -213,6 +214,30 @@ public class SubscriptionMessagesHubTest extends BaseApiTest {
} }
}); });
mMessagesHub.addSubscriptionListener(new SubscriptionListener() {
@Override
public ObjectType getInterestObjectType() {
return ObjectType.OPERATION_HISTORY_OBJECT;
}
@Override
public void onSubscriptionUpdate(SubscriptionResponse response) {
System.out.println("onSubscriptionUpdate. response.params.size: "+response.params.size());
if(response.params.size() == 2){
List<Serializable> payload = (List) response.params.get(1);
if(payload.size() > 0){
for(Serializable item : payload){
if(item instanceof OperationHistory){
OperationHistory operationHistory = (OperationHistory) item;
System.out.println("Operation history: <id:"+operationHistory.getObjectId()+", op: "+operationHistory.getOperation().toJsonString()+">");
}
}
}
}
}
});
mWebSocket.addListener(mMessagesHub); mWebSocket.addListener(mMessagesHub);
mWebSocket.connect(); mWebSocket.connect();