Introduced the DynamicGlobalPropertiesDeserializer
This commit is contained in:
parent
1c5d382891
commit
37f52283a9
5 changed files with 165 additions and 32 deletions
|
@ -4,7 +4,6 @@ import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
import com.neovisionaries.ws.client.WebSocket;
|
import com.neovisionaries.ws.client.WebSocket;
|
||||||
import com.neovisionaries.ws.client.WebSocketException;
|
|
||||||
import com.neovisionaries.ws.client.WebSocketFrame;
|
import com.neovisionaries.ws.client.WebSocketFrame;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
@ -20,6 +19,7 @@ import de.bitsharesmunich.graphenej.interfaces.SubscriptionHub;
|
||||||
import de.bitsharesmunich.graphenej.interfaces.SubscriptionListener;
|
import de.bitsharesmunich.graphenej.interfaces.SubscriptionListener;
|
||||||
import de.bitsharesmunich.graphenej.interfaces.WitnessResponseListener;
|
import de.bitsharesmunich.graphenej.interfaces.WitnessResponseListener;
|
||||||
import de.bitsharesmunich.graphenej.models.ApiCall;
|
import de.bitsharesmunich.graphenej.models.ApiCall;
|
||||||
|
import de.bitsharesmunich.graphenej.models.DynamicGlobalProperties;
|
||||||
import de.bitsharesmunich.graphenej.models.SubscriptionResponse;
|
import de.bitsharesmunich.graphenej.models.SubscriptionResponse;
|
||||||
import de.bitsharesmunich.graphenej.models.WitnessResponse;
|
import de.bitsharesmunich.graphenej.models.WitnessResponse;
|
||||||
import de.bitsharesmunich.graphenej.operations.TransferOperation;
|
import de.bitsharesmunich.graphenej.operations.TransferOperation;
|
||||||
|
@ -55,6 +55,7 @@ public class SubscriptionMessagesHub extends BaseGrapheneHandler implements Subs
|
||||||
builder.registerTypeAdapter(Transaction.class, new Transaction.TransactionDeserializer());
|
builder.registerTypeAdapter(Transaction.class, new Transaction.TransactionDeserializer());
|
||||||
builder.registerTypeAdapter(TransferOperation.class, new TransferOperation.TransferDeserializer());
|
builder.registerTypeAdapter(TransferOperation.class, new TransferOperation.TransferDeserializer());
|
||||||
builder.registerTypeAdapter(AssetAmount.class, new AssetAmount.AssetAmountDeserializer());
|
builder.registerTypeAdapter(AssetAmount.class, new AssetAmount.AssetAmountDeserializer());
|
||||||
|
builder.registerTypeAdapter(DynamicGlobalProperties.class, new DynamicGlobalProperties.DynamicGlobalPropertiesDeserializer());
|
||||||
this.gson = builder.create();
|
this.gson = builder.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +102,7 @@ public class SubscriptionMessagesHub extends BaseGrapheneHandler implements Subs
|
||||||
ApiCall getDatabaseId = new ApiCall(databaseApiId, RPC.CALL_SET_SUBSCRIBE_CALLBACK, subscriptionParams, RPC.VERSION, currentId);
|
ApiCall getDatabaseId = new ApiCall(databaseApiId, RPC.CALL_SET_SUBSCRIBE_CALLBACK, subscriptionParams, RPC.VERSION, currentId);
|
||||||
websocket.sendText(getDatabaseId.toJsonString());
|
websocket.sendText(getDatabaseId.toJsonString());
|
||||||
}else if(currentId == SUBCRIPTION_REQUEST){
|
}else if(currentId == SUBCRIPTION_REQUEST){
|
||||||
// Listeners are called from within the SubscriptionResponseDeserializer, so there's nothing to handle here.
|
// There's nothing to handle here.
|
||||||
}else{
|
}else{
|
||||||
SubscriptionResponse subscriptionResponse = gson.fromJson(message, SubscriptionResponse.class);
|
SubscriptionResponse subscriptionResponse = gson.fromJson(message, SubscriptionResponse.class);
|
||||||
}
|
}
|
||||||
|
@ -112,14 +113,4 @@ public class SubscriptionMessagesHub extends BaseGrapheneHandler implements Subs
|
||||||
public void onFrameSent(WebSocket websocket, WebSocketFrame frame) throws Exception {
|
public void onFrameSent(WebSocket websocket, WebSocketFrame frame) throws Exception {
|
||||||
System.out.println(">> "+frame.getPayloadText());
|
System.out.println(">> "+frame.getPayloadText());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onError(WebSocket websocket, WebSocketException cause) throws Exception {
|
|
||||||
super.onError(websocket, cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleCallbackError(WebSocket websocket, Throwable cause) throws Exception {
|
|
||||||
super.handleCallbackError(websocket, cause);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,12 +9,9 @@ import com.neovisionaries.ws.client.WebSocketFrame;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TimeZone;
|
|
||||||
|
|
||||||
import de.bitsharesmunich.graphenej.Asset;
|
import de.bitsharesmunich.graphenej.Asset;
|
||||||
import de.bitsharesmunich.graphenej.AssetAmount;
|
import de.bitsharesmunich.graphenej.AssetAmount;
|
||||||
|
@ -74,7 +71,9 @@ public class TransactionBroadcastSequence extends BaseGrapheneHandler {
|
||||||
if(frame.isTextFrame())
|
if(frame.isTextFrame())
|
||||||
System.out.println("<<< "+frame.getPayloadText());
|
System.out.println("<<< "+frame.getPayloadText());
|
||||||
String response = frame.getPayloadText();
|
String response = frame.getPayloadText();
|
||||||
Gson gson = new Gson();
|
GsonBuilder builder = new GsonBuilder();
|
||||||
|
builder.registerTypeAdapter(DynamicGlobalProperties.class, new DynamicGlobalProperties.DynamicGlobalPropertiesDeserializer());
|
||||||
|
Gson gson = builder.create();
|
||||||
BaseResponse baseResponse = gson.fromJson(response, BaseResponse.class);
|
BaseResponse baseResponse = gson.fromJson(response, BaseResponse.class);
|
||||||
if(baseResponse.error != null){
|
if(baseResponse.error != null){
|
||||||
mListener.onError(baseResponse.error);
|
mListener.onError(baseResponse.error);
|
||||||
|
@ -104,12 +103,8 @@ public class TransactionBroadcastSequence extends BaseGrapheneHandler {
|
||||||
WitnessResponse<DynamicGlobalProperties> witnessResponse = gson.fromJson(response, DynamicGlobalPropertiesResponse);
|
WitnessResponse<DynamicGlobalProperties> witnessResponse = gson.fromJson(response, DynamicGlobalPropertiesResponse);
|
||||||
DynamicGlobalProperties dynamicProperties = witnessResponse.result;
|
DynamicGlobalProperties dynamicProperties = witnessResponse.result;
|
||||||
|
|
||||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
|
|
||||||
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
|
|
||||||
Date date = dateFormat.parse(dynamicProperties.time);
|
|
||||||
|
|
||||||
// Adjusting dynamic block data to every transaction
|
// Adjusting dynamic block data to every transaction
|
||||||
long expirationTime = (date.getTime() / 1000) + Transaction.DEFAULT_EXPIRATION_TIME;
|
long expirationTime = (dynamicProperties.time.getTime() / 1000) + Transaction.DEFAULT_EXPIRATION_TIME;
|
||||||
String headBlockId = dynamicProperties.head_block_id;
|
String headBlockId = dynamicProperties.head_block_id;
|
||||||
long headBlockNumber = dynamicProperties.head_block_number;
|
long headBlockNumber = dynamicProperties.head_block_number;
|
||||||
transaction.setBlockData(new BlockData(headBlockNumber, headBlockId, expirationTime));
|
transaction.setBlockData(new BlockData(headBlockNumber, headBlockId, expirationTime));
|
||||||
|
|
|
@ -1,8 +1,19 @@
|
||||||
package de.bitsharesmunich.graphenej.models;
|
package de.bitsharesmunich.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.io.Serializable;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
import de.bitsharesmunich.graphenej.GrapheneObject;
|
import de.bitsharesmunich.graphenej.GrapheneObject;
|
||||||
|
import de.bitsharesmunich.graphenej.Util;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class used to deserialize the 'result' field returned by the full node after making a call
|
* Class used to deserialize the 'result' field returned by the full node after making a call
|
||||||
|
@ -25,19 +36,62 @@ public class DynamicGlobalProperties extends GrapheneObject implements Serializa
|
||||||
|
|
||||||
public long head_block_number;
|
public long head_block_number;
|
||||||
public String head_block_id;
|
public String head_block_id;
|
||||||
public String time;
|
public Date time;
|
||||||
public String current_witness;
|
public String current_witness;
|
||||||
public String next_maintenance_time;
|
public Date next_maintenance_time;
|
||||||
public String last_budget_time;
|
public String last_budget_time;
|
||||||
public long witness_budget;
|
public long witness_budget;
|
||||||
public long accounts_registered_this_interval;
|
public long accounts_registered_this_interval;
|
||||||
public long recently_missed_count;
|
public long recently_missed_count;
|
||||||
public long current_aslot;
|
public long current_aslot;
|
||||||
public String recent_slots_filled;
|
public String recent_slots_filled;
|
||||||
public long dynamic_flags;
|
public int dynamic_flags;
|
||||||
public long last_irreversible_block_num;
|
public long last_irreversible_block_num;
|
||||||
|
|
||||||
public DynamicGlobalProperties(String id) {
|
public DynamicGlobalProperties(String id) {
|
||||||
super(id);
|
super(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class that will parse the JSON element containing the dynamic global properties object and
|
||||||
|
* return an instance of the {@link DynamicGlobalProperties} class.
|
||||||
|
*/
|
||||||
|
public static class DynamicGlobalPropertiesDeserializer implements JsonDeserializer<DynamicGlobalProperties> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DynamicGlobalProperties deserialize(JsonElement jsonElement, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||||
|
JsonObject jsonObject = jsonElement.getAsJsonObject();
|
||||||
|
|
||||||
|
// Creating an instance of the DynamicGlobalProperties
|
||||||
|
DynamicGlobalProperties dynamicGlobal = new DynamicGlobalProperties(jsonElement.getAsJsonObject().get(KEY_ID).getAsString());
|
||||||
|
|
||||||
|
// Start to fill in the parsed details
|
||||||
|
dynamicGlobal.head_block_number = jsonObject.get(DynamicGlobalProperties.KEY_HEAD_BLOCK_NUMBER).getAsLong();
|
||||||
|
dynamicGlobal.head_block_id = jsonObject.get(DynamicGlobalProperties.KEY_HEAD_BLOCK_ID).getAsString();
|
||||||
|
|
||||||
|
SimpleDateFormat dateFormat = new SimpleDateFormat(Util.TIME_DATE_FORMAT);
|
||||||
|
try {
|
||||||
|
dynamicGlobal.time = dateFormat.parse(jsonObject.get(DynamicGlobalProperties.KEY_TIME).getAsString());
|
||||||
|
} catch (ParseException e) {
|
||||||
|
System.out.println("ParseException. Msg: "+e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
dynamicGlobal.next_maintenance_time = dateFormat.parse(jsonObject.get(DynamicGlobalProperties.KEY_NEXT_MAINTENANCE_TIME).getAsString());
|
||||||
|
} catch (ParseException e) {
|
||||||
|
System.out.println("ParseException. Msg: "+e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamicGlobal.current_witness = jsonObject.get(DynamicGlobalProperties.KEY_CURRENT_WITNESS).getAsString();
|
||||||
|
dynamicGlobal.last_budget_time = jsonObject.get(DynamicGlobalProperties.KEY_LAST_BUDGET_TIME).getAsString();
|
||||||
|
dynamicGlobal.witness_budget = jsonObject.get(DynamicGlobalProperties.KEY_WITNESS_BUDGET).getAsLong();
|
||||||
|
dynamicGlobal.accounts_registered_this_interval = jsonObject.get(DynamicGlobalProperties.KEY_ACCOUNTS_REGISTERED_THIS_INTERVAL).getAsLong();
|
||||||
|
dynamicGlobal.recently_missed_count = jsonObject.get(DynamicGlobalProperties.KEY_RECENTLY_MISSED_COUNT).getAsLong();
|
||||||
|
dynamicGlobal.current_aslot = jsonObject.get(DynamicGlobalProperties.KEY_CURRENT_ASLOT).getAsLong();
|
||||||
|
dynamicGlobal.recent_slots_filled = jsonObject.get(DynamicGlobalProperties.KEY_RECENT_SLOTS_FILLED).getAsString();
|
||||||
|
dynamicGlobal.dynamic_flags = jsonObject.get(DynamicGlobalProperties.KEY_DYNAMIC_FLAGS).getAsInt();
|
||||||
|
dynamicGlobal.last_irreversible_block_num = jsonObject.get(DynamicGlobalProperties.KEY_LAST_IRREVERSIBLE_BLOCK_NUM).getAsLong();
|
||||||
|
return dynamicGlobal;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -9,9 +9,14 @@ import com.google.gson.JsonParseException;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import de.bitsharesmunich.graphenej.*;
|
import de.bitsharesmunich.graphenej.GrapheneObject;
|
||||||
|
import de.bitsharesmunich.graphenej.ObjectType;
|
||||||
|
import de.bitsharesmunich.graphenej.Transaction;
|
||||||
import de.bitsharesmunich.graphenej.interfaces.SubscriptionListener;
|
import de.bitsharesmunich.graphenej.interfaces.SubscriptionListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -57,7 +62,14 @@ public class SubscriptionResponse {
|
||||||
* objects that might come once the are subscribed to the witness notifications.
|
* objects that might come once the are subscribed to the witness notifications.
|
||||||
*/
|
*/
|
||||||
public static class SubscriptionResponseDeserializer implements JsonDeserializer<SubscriptionResponse> {
|
public static class SubscriptionResponseDeserializer implements JsonDeserializer<SubscriptionResponse> {
|
||||||
|
/**
|
||||||
|
* Map of ObjectType to Integer used to keep track of the current amount of listener per type
|
||||||
|
*/
|
||||||
private HashMap<ObjectType, Integer> listenerTypeCount;
|
private HashMap<ObjectType, Integer> listenerTypeCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of listeners
|
||||||
|
*/
|
||||||
private LinkedList<SubscriptionListener> mListeners;
|
private LinkedList<SubscriptionListener> mListeners;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -128,12 +140,8 @@ public class SubscriptionResponse {
|
||||||
balanceObject.balance = jsonObject.get(AccountBalanceUpdate.KEY_BALANCE).getAsLong();
|
balanceObject.balance = jsonObject.get(AccountBalanceUpdate.KEY_BALANCE).getAsLong();
|
||||||
secondArgument.add(balanceObject);
|
secondArgument.add(balanceObject);
|
||||||
}else if(grapheneObject.getObjectType() == ObjectType.DYNAMIC_GLOBAL_PROPERTY_OBJECT){
|
}else if(grapheneObject.getObjectType() == ObjectType.DYNAMIC_GLOBAL_PROPERTY_OBJECT){
|
||||||
DynamicGlobalProperties dynamicGlobal = new DynamicGlobalProperties(grapheneObject.getObjectId());
|
DynamicGlobalProperties dynamicGlobalProperties = context.deserialize(object, DynamicGlobalProperties.class);
|
||||||
dynamicGlobal.head_block_number = jsonObject.get(DynamicGlobalProperties.KEY_HEAD_BLOCK_NUMBER).getAsLong();
|
secondArgument.add(dynamicGlobalProperties);
|
||||||
dynamicGlobal.head_block_id = jsonObject.get(DynamicGlobalProperties.KEY_HEAD_BLOCK_ID).getAsString();
|
|
||||||
dynamicGlobal.time = jsonObject.get(DynamicGlobalProperties.KEY_TIME).getAsString();
|
|
||||||
//TODO: Deserialize all other attributes
|
|
||||||
secondArgument.add(dynamicGlobal);
|
|
||||||
}else if(grapheneObject.getObjectType() == ObjectType.TRANSACTION_OBJECT){
|
}else if(grapheneObject.getObjectType() == ObjectType.TRANSACTION_OBJECT){
|
||||||
BroadcastedTransaction broadcastedTransaction = new BroadcastedTransaction(grapheneObject.getObjectId());
|
BroadcastedTransaction broadcastedTransaction = new BroadcastedTransaction(grapheneObject.getObjectId());
|
||||||
broadcastedTransaction.setTransaction((Transaction) context.deserialize(jsonObject.get(BroadcastedTransaction.KEY_TRX), Transaction.class));
|
broadcastedTransaction.setTransaction((Transaction) context.deserialize(jsonObject.get(BroadcastedTransaction.KEY_TRX), Transaction.class));
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
package de.bitsharesmunich.graphenej.api;
|
||||||
|
|
||||||
|
import com.neovisionaries.ws.client.WebSocketException;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import java.util.List;
|
||||||
|
import de.bitsharesmunich.graphenej.ObjectType;
|
||||||
|
import de.bitsharesmunich.graphenej.interfaces.SubscriptionListener;
|
||||||
|
import de.bitsharesmunich.graphenej.interfaces.WitnessResponseListener;
|
||||||
|
import de.bitsharesmunich.graphenej.models.BaseResponse;
|
||||||
|
import de.bitsharesmunich.graphenej.models.DynamicGlobalProperties;
|
||||||
|
import de.bitsharesmunich.graphenej.models.SubscriptionResponse;
|
||||||
|
import de.bitsharesmunich.graphenej.models.WitnessResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by nelson on 4/25/17.
|
||||||
|
*/
|
||||||
|
public class SubscriptionMessagesHubTest extends BaseApiTest {
|
||||||
|
|
||||||
|
private SubscriptionMessagesHub mMessagesHub;
|
||||||
|
private WitnessResponseListener mErrorListener = new WitnessResponseListener() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(WitnessResponse response) {
|
||||||
|
System.out.println("onSuccess");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(BaseResponse.Error error) {
|
||||||
|
System.out.println("onError");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGlobalPropertiesDeserializer(){
|
||||||
|
try{
|
||||||
|
mMessagesHub = new SubscriptionMessagesHub("", "", mErrorListener);
|
||||||
|
mMessagesHub.addSubscriptionListener(new SubscriptionListener() {
|
||||||
|
private int MAX_MESSAGES = 5;
|
||||||
|
private int messageCounter = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObjectType getInterestObjectType() {
|
||||||
|
return ObjectType.DYNAMIC_GLOBAL_PROPERTY_OBJECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSubscriptionUpdate(SubscriptionResponse response) {
|
||||||
|
if(response.params.size() == 2){
|
||||||
|
try{
|
||||||
|
List<Object> payload = (List) response.params.get(1);
|
||||||
|
if(payload.size() > 0 && payload.get(0) instanceof DynamicGlobalProperties){
|
||||||
|
DynamicGlobalProperties globalProperties = (DynamicGlobalProperties) payload.get(0);
|
||||||
|
System.out.println("time.....................: "+globalProperties.time);
|
||||||
|
System.out.println("next_maintenance_time....: "+globalProperties.next_maintenance_time);
|
||||||
|
System.out.println("recent_slots_filled......: "+globalProperties.recent_slots_filled);
|
||||||
|
}
|
||||||
|
}catch(Exception e){
|
||||||
|
System.out.println("Exception");
|
||||||
|
System.out.println("Type: "+e.getClass());
|
||||||
|
System.out.println("Msg: "+e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 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