Introduced the DynamicGlobalPropertiesDeserializer

develop
Nelson R. Perez 2017-04-27 15:16:33 -05:00
parent 1c5d382891
commit 37f52283a9
5 changed files with 165 additions and 32 deletions

View File

@ -4,7 +4,6 @@ import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.neovisionaries.ws.client.WebSocket;
import com.neovisionaries.ws.client.WebSocketException;
import com.neovisionaries.ws.client.WebSocketFrame;
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.WitnessResponseListener;
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.TransferOperation;
@ -55,6 +55,7 @@ public class SubscriptionMessagesHub extends BaseGrapheneHandler implements Subs
builder.registerTypeAdapter(Transaction.class, new Transaction.TransactionDeserializer());
builder.registerTypeAdapter(TransferOperation.class, new TransferOperation.TransferDeserializer());
builder.registerTypeAdapter(AssetAmount.class, new AssetAmount.AssetAmountDeserializer());
builder.registerTypeAdapter(DynamicGlobalProperties.class, new DynamicGlobalProperties.DynamicGlobalPropertiesDeserializer());
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);
websocket.sendText(getDatabaseId.toJsonString());
}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{
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 {
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);
}
}

View File

@ -9,12 +9,9 @@ import com.neovisionaries.ws.client.WebSocketFrame;
import java.io.Serializable;
import java.lang.reflect.Type;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import de.bitsharesmunich.graphenej.Asset;
import de.bitsharesmunich.graphenej.AssetAmount;
@ -74,7 +71,9 @@ public class TransactionBroadcastSequence extends BaseGrapheneHandler {
if(frame.isTextFrame())
System.out.println("<<< "+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);
if(baseResponse.error != null){
mListener.onError(baseResponse.error);
@ -104,12 +103,8 @@ public class TransactionBroadcastSequence extends BaseGrapheneHandler {
WitnessResponse<DynamicGlobalProperties> witnessResponse = gson.fromJson(response, DynamicGlobalPropertiesResponse);
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
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;
long headBlockNumber = dynamicProperties.head_block_number;
transaction.setBlockData(new BlockData(headBlockNumber, headBlockId, expirationTime));

View File

@ -1,8 +1,19 @@
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.lang.reflect.Type;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
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
@ -25,19 +36,62 @@ public class DynamicGlobalProperties extends GrapheneObject implements Serializa
public long head_block_number;
public String head_block_id;
public String time;
public Date time;
public String current_witness;
public String next_maintenance_time;
public Date next_maintenance_time;
public String last_budget_time;
public long witness_budget;
public long accounts_registered_this_interval;
public long recently_missed_count;
public long current_aslot;
public String recent_slots_filled;
public long dynamic_flags;
public int dynamic_flags;
public long last_irreversible_block_num;
public DynamicGlobalProperties(String 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;
}
}
}

View File

@ -9,9 +9,14 @@ import com.google.gson.JsonParseException;
import java.io.Serializable;
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;
/**
@ -57,7 +62,14 @@ public class SubscriptionResponse {
* objects that might come once the are subscribed to the witness notifications.
*/
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;
/**
* List of listeners
*/
private LinkedList<SubscriptionListener> mListeners;
/**
@ -128,12 +140,8 @@ public class SubscriptionResponse {
balanceObject.balance = jsonObject.get(AccountBalanceUpdate.KEY_BALANCE).getAsLong();
secondArgument.add(balanceObject);
}else if(grapheneObject.getObjectType() == ObjectType.DYNAMIC_GLOBAL_PROPERTY_OBJECT){
DynamicGlobalProperties dynamicGlobal = new DynamicGlobalProperties(grapheneObject.getObjectId());
dynamicGlobal.head_block_number = jsonObject.get(DynamicGlobalProperties.KEY_HEAD_BLOCK_NUMBER).getAsLong();
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);
DynamicGlobalProperties dynamicGlobalProperties = context.deserialize(object, DynamicGlobalProperties.class);
secondArgument.add(dynamicGlobalProperties);
}else if(grapheneObject.getObjectType() == ObjectType.TRANSACTION_OBJECT){
BroadcastedTransaction broadcastedTransaction = new BroadcastedTransaction(grapheneObject.getObjectId());
broadcastedTransaction.setTransaction((Transaction) context.deserialize(jsonObject.get(BroadcastedTransaction.KEY_TRX), Transaction.class));

View File

@ -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());
}
}
}