diff --git a/.gitignore b/.gitignore index 094313f..0790958 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ # Gradle # ------ .gradle +gradlew.bat gradle graphenej/build /build diff --git a/gradlew.bat b/gradlew.bat deleted file mode 100644 index 8a0b282..0000000 --- a/gradlew.bat +++ /dev/null @@ -1,90 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windowz variants - -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/graphenej/build.gradle b/graphenej/build.gradle index 5a93a00..db2e11c 100644 --- a/graphenej/build.gradle +++ b/graphenej/build.gradle @@ -19,7 +19,7 @@ android { buildToolsVersion "25.0.0" defaultConfig { - minSdkVersion 3 + minSdkVersion 9 targetSdkVersion 24 versionCode 5 versionName "0.4.3" diff --git a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/BaseGrapheneHandler.java b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/BaseGrapheneHandler.java index e6dbab2..80d7e2b 100644 --- a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/BaseGrapheneHandler.java +++ b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/BaseGrapheneHandler.java @@ -3,17 +3,20 @@ package de.bitsharesmunich.graphenej.api; import com.neovisionaries.ws.client.WebSocket; import com.neovisionaries.ws.client.WebSocketAdapter; import com.neovisionaries.ws.client.WebSocketException; + +import org.w3c.dom.Node; + +import de.bitsharesmunich.graphenej.interfaces.NodeErrorListener; import de.bitsharesmunich.graphenej.interfaces.WitnessResponseListener; import de.bitsharesmunich.graphenej.models.BaseResponse; /** * Base class that should be extended by any implementation of a specific request to the full node. - * - * Created by nelson on 1/5/17. */ public abstract class BaseGrapheneHandler extends WebSocketAdapter { protected WitnessResponseListener mListener; + protected NodeErrorListener mErrorListener; /** * The 'id' field of a message to the node. This is used in order to multiplex different messages @@ -27,14 +30,30 @@ public abstract class BaseGrapheneHandler extends WebSocketAdapter { */ protected long requestId; + /** + * Constructor (The original constructor, should be replaced with the one that receives + * NodeErrorListener instead of WitnessResponseListener) + * + * @param listener listener to be notified in if an error occurs + */ + @Deprecated public BaseGrapheneHandler(WitnessResponseListener listener){ this.mListener = listener; } + /** + * Constructor + * + * @param listener listener to be notified if an error occurs + */ + public BaseGrapheneHandler(NodeErrorListener listener){ + this.mErrorListener = listener; + } + @Override public void onError(WebSocket websocket, WebSocketException cause) throws Exception { System.out.println("onError. cause: "+cause.getMessage()); - mListener.onError(new BaseResponse.Error(cause.getMessage())); + mErrorListener.onError(new BaseResponse.Error(cause.getMessage())); websocket.disconnect(); } @@ -44,7 +63,14 @@ public abstract class BaseGrapheneHandler extends WebSocketAdapter { for (StackTraceElement element : cause.getStackTrace()){ System.out.println(element.getFileName()+"#"+element.getClassName()+":"+element.getLineNumber()); } - mListener.onError(new BaseResponse.Error(cause.getMessage())); + // Should be replaced for mErrorListener (NodeErrorListener type) only in the future + if(mErrorListener != null){ + mErrorListener.onError(new BaseResponse.Error(cause.getMessage())); + } + else{ + mListener.onError(new BaseResponse.Error(cause.getMessage())); + } + websocket.disconnect(); } diff --git a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetAccountBalances.java b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetAccountBalances.java index d7aeda4..41f6287 100644 --- a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetAccountBalances.java +++ b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetAccountBalances.java @@ -19,17 +19,52 @@ import java.util.List; import java.util.Map; /** - * Created by nelson on 1/13/17. + * Class that implements get_account_balances request handler. + * + * Get an account’s balances in various assets. + * + * The response returns the balances of the account + * + * @see get_account_balances API doc + * */ public class GetAccountBalances extends BaseGrapheneHandler { private UserAccount mUserAccount; private List mAssetList; + private boolean mOneTime; - public GetAccountBalances(UserAccount userAccount, List assets, WitnessResponseListener listener) { + /** + * Default Constructor + * + * @param userAccount account to get balances for + * @param assets list of the assets to get balances of; if empty, get all assets account + * has a balance in + * @param oneTime boolean value indicating if WebSocket must be closed (true) or not + * (false) after the response + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the + * success/failure of the operation. + */ + public GetAccountBalances(UserAccount userAccount, List assets, boolean oneTime, WitnessResponseListener listener) { super(listener); this.mUserAccount = userAccount; this.mAssetList = assets; + this.mOneTime = oneTime; + } + + /** + * Using this constructor the WebSocket connection closes after the response. + * + * @param userAccount account to get balances for + * @param assets list of the assets to get balances of; if empty, get all assets account + * has a balance in + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the + * success/failure of the operation. + */ + public GetAccountBalances(UserAccount userAccount, List assets, WitnessResponseListener listener) { + this(userAccount, assets, true, listener); } @Override @@ -57,7 +92,9 @@ public class GetAccountBalances extends BaseGrapheneHandler { Type WitnessResponseType = new TypeToken>>(){}.getType(); WitnessResponse> witnessResponse = gsonBuilder.create().fromJson(response, WitnessResponseType); mListener.onSuccess(witnessResponse); - websocket.disconnect(); + if(mOneTime){ + websocket.disconnect(); + } } @Override diff --git a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetAccountByName.java b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetAccountByName.java index f4f17f8..d11634f 100644 --- a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetAccountByName.java +++ b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetAccountByName.java @@ -20,19 +20,49 @@ import de.bitsharesmunich.graphenej.models.ApiCall; import de.bitsharesmunich.graphenej.models.WitnessResponse; /** - * Created by nelson on 11/15/16. + * Class that implements get_account_by_name request handler. + * + * Get an account’s info by name. + * + * The response returns account data that refer to the name. + * + * @see get_account_by_name API doc */ public class GetAccountByName extends BaseGrapheneHandler { private String accountName; private WitnessResponseListener mListener; + private boolean mOneTime; - public GetAccountByName(String accountName, WitnessResponseListener listener){ + /** + * Default Constructor + * + * @param accountName name of the account to get info + * @param oneTime boolean value indicating if WebSocket must be closed (true) or not + * (false) after the response + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the + * success/failure of the operation. + */ + public GetAccountByName(String accountName, boolean oneTime, WitnessResponseListener listener){ super(listener); this.accountName = accountName; + this.mOneTime = oneTime; this.mListener = listener; } + /** + * Using this constructor the WebSocket connection closes after the response. + * + * @param accountName name of the account to get info + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the + * success/failure of the operation. + */ + public GetAccountByName(String accountName, WitnessResponseListener listener){ + this(accountName, true, listener); + } + @Override public void onConnected(WebSocket websocket, Map> headers) throws Exception { ArrayList accountParams = new ArrayList<>(); @@ -58,8 +88,9 @@ public class GetAccountByName extends BaseGrapheneHandler { }else{ this.mListener.onSuccess(witnessResponse); } - - websocket.disconnect(); + if(mOneTime){ + websocket.disconnect(); + } } @Override diff --git a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetAccountHistory.java b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetAccountHistory.java index 1c1db62..061cedc 100644 --- a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetAccountHistory.java +++ b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetAccountHistory.java @@ -3,5 +3,6 @@ package de.bitsharesmunich.graphenej.api; /** * Created by nelson on 12/26/16. */ +//TODO: Implement if needed: http://docs.bitshares.eu/api/history.html?highlight=get_market_history#account-history-api public class GetAccountHistory { } diff --git a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetAccounts.java b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetAccounts.java index e3d4a46..9350ee5 100644 --- a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetAccounts.java +++ b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetAccounts.java @@ -21,29 +21,79 @@ import de.bitsharesmunich.graphenej.models.ApiCall; import de.bitsharesmunich.graphenej.models.WitnessResponse; /** + * Class that implements get_accounts request handler. * - * @author henry + * Get a list of accounts by ID. + * + * The response returns the accounts corresponding to the provided IDs. + * + * @see get_accounts API doc */ public class GetAccounts extends BaseGrapheneHandler { private String accountId; private List userAccounts; private WitnessResponseListener mListener; - private boolean oneTime; + private boolean mOneTime; + /** + * Constructor for one account only. + * + * @param accountId ID of the account to retrieve + * @param oneTime boolean value indicating if WebSocket must be closed (true) or not + * (false) after the response + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the + * success/failure of the operation. + */ public GetAccounts(String accountId, boolean oneTime, WitnessResponseListener listener){ super(listener); this.accountId = accountId; - this.oneTime = oneTime; + this.mOneTime = oneTime; this.mListener = listener; } + /** + * Constructor for account list. + * + * @param accounts list with the accounts to retrieve + * @param oneTime boolean value indicating if WebSocket must be closed (true) or not + * (false) after the response + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the + * success/failure of the operation. + */ public GetAccounts(List accounts, boolean oneTime, WitnessResponseListener listener){ super(listener); this.userAccounts = accounts; - this.oneTime = oneTime; + this.mOneTime = oneTime; this.mListener = listener; } + /** + * Using this constructor the WebSocket connection closes after the response. (Account based) + * + * @param accountId ID of the account to retrieve + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the + * success/failure of the operation. + */ + public GetAccounts(String accountId, WitnessResponseListener listener){ + this(accountId, true, listener); + } + + /** + * Using this constructor the WebSocket connection closes after the response. (Account List + * based) + * + * @param accounts list with the accounts to retrieve + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the + * success/failure of the operation. + */ + public GetAccounts(List accounts, WitnessResponseListener listener){ + this(accounts, true, listener); + } + @Override public void onConnected(WebSocket websocket, Map> headers) throws Exception { ArrayList params = new ArrayList(); @@ -76,7 +126,7 @@ public class GetAccounts extends BaseGrapheneHandler { } else { this.mListener.onSuccess(witnessResponse); } - if(oneTime){ + if(mOneTime){ websocket.disconnect(); } } diff --git a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetAllAssetHolders.java b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetAllAssetHolders.java index 9d92f8b..4147bc5 100644 --- a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetAllAssetHolders.java +++ b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetAllAssetHolders.java @@ -16,7 +16,13 @@ import java.util.List; import java.util.Map; /** - * Created by nelson on 1/25/17. + * Class that implements get_all_asset_holders request handler. + * + * Get a list of all system assets with holders count. + * + * The response returns the list of all assets with holders count. + * + * @see get_all_asset_holders API doc (source code ref.) */ public class GetAllAssetHolders extends BaseGrapheneHandler { private final static int LOGIN_ID = 1; @@ -26,10 +32,31 @@ public class GetAllAssetHolders extends BaseGrapheneHandler { private int currentId = 1; private int assetApiId = -1; - public GetAllAssetHolders(WitnessResponseListener listener) { + private boolean mOneTime; + + /** + * Default Constructor + * + * @param oneTime boolean value indicating if WebSocket must be closed (true) or not + * (false) after the response + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the + * success/failure of the operation. + */ + public GetAllAssetHolders(boolean oneTime, WitnessResponseListener listener) { super(listener); + this.mOneTime = oneTime; } + /** + * Using this constructor the WebSocket connection closes after the response. + * + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the success/failure + * of the transaction broadcast operation. + */ + public GetAllAssetHolders(WitnessResponseListener listener) { this(true, listener);} + @Override public void onConnected(WebSocket websocket, Map> headers) throws Exception { ArrayList loginParams = new ArrayList<>(); @@ -48,7 +75,9 @@ public class GetAllAssetHolders extends BaseGrapheneHandler { BaseResponse baseResponse = gson.fromJson(response, BaseResponse.class); if(baseResponse.error != null){ mListener.onError(baseResponse.error); - websocket.disconnect(); + if(mOneTime){ + websocket.disconnect(); + } }else { currentId++; ArrayList emptyParams = new ArrayList<>(); @@ -68,7 +97,9 @@ public class GetAllAssetHolders extends BaseGrapheneHandler { builder.registerTypeAdapter(AssetHolderCount.class, new AssetHolderCount.HoldersCountDeserializer()); WitnessResponse> witnessResponse = builder.create().fromJson(response, AssetTokenHolders); mListener.onSuccess(witnessResponse); - websocket.disconnect(); + if(mOneTime){ + websocket.disconnect(); + } }else{ System.out.println("current id: "+currentId); } diff --git a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetBlockHeader.java b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetBlockHeader.java index 4cab506..cb59103 100644 --- a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetBlockHeader.java +++ b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetBlockHeader.java @@ -19,7 +19,13 @@ import de.bitsharesmunich.graphenej.models.BlockHeader; import de.bitsharesmunich.graphenej.models.WitnessResponse; /** - * Created by nelson on 12/13/16. + * Class that implements get_block_header request handler. + * + * Retrieve a block header. + * + * The request returns the header of the referenced block, or null if no matching block was found + * + * @see get_block_header API doc */ public class GetBlockHeader extends BaseGrapheneHandler { @@ -34,12 +40,37 @@ public class GetBlockHeader extends BaseGrapheneHandler { private int currentId = LOGIN_ID; private int apiId = -1; - public GetBlockHeader(long blockNumber, WitnessResponseListener listener){ + private boolean mOneTime; + + /** + * Default Constructor + * + * @param blockNumber height of the block whose header should be returned + * @param oneTime boolean value indicating if WebSocket must be closed (true) or not + * (false) after the response + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the + * success/failure of the operation. + */ + public GetBlockHeader(long blockNumber, boolean oneTime, WitnessResponseListener listener){ super(listener); this.blockNumber = blockNumber; + this.mOneTime = oneTime; this.mListener = listener; } + /** + * Using this constructor the WebSocket connection closes after the response. + * + * @param blockNumber height of the block whose header should be returned + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the + * success/failure of the operation. + */ + public GetBlockHeader(long blockNumber, WitnessResponseListener listener){ + this(blockNumber, true, listener); + } + @Override public void onConnected(WebSocket websocket, Map> headers) throws Exception { ArrayList loginParams = new ArrayList<>(); @@ -58,7 +89,9 @@ public class GetBlockHeader extends BaseGrapheneHandler { BaseResponse baseResponse = gson.fromJson(response, BaseResponse.class); if(baseResponse.error != null){ mListener.onError(baseResponse.error); - websocket.disconnect(); + if(mOneTime){ + websocket.disconnect(); + } }else { currentId++; ArrayList emptyParams = new ArrayList<>(); @@ -80,7 +113,9 @@ public class GetBlockHeader extends BaseGrapheneHandler { Type RelativeAccountHistoryResponse = new TypeToken>(){}.getType(); WitnessResponse transfersResponse = gson.fromJson(response, RelativeAccountHistoryResponse); mListener.onSuccess(transfersResponse); - websocket.disconnect(); + if(mOneTime){ + websocket.disconnect(); + } } } diff --git a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetKeyReferences.java b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetKeyReferences.java index 5eb4243..576d6a6 100644 --- a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetKeyReferences.java +++ b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetKeyReferences.java @@ -19,23 +19,75 @@ import de.bitsharesmunich.graphenej.models.ApiCall; import de.bitsharesmunich.graphenej.models.WitnessResponse; /** - * Created by nelson on 11/15/16. + * Class that implements get_key_references request handler. + * + * Retrieve the keys that refer to the address/list of addresses. + * + * The request returns all accounts that refer to the key or account id in their owner or active authorities. + * + * @see get_key_references API doc */ public class GetKeyReferences extends BaseGrapheneHandler { private List
addresses; - public GetKeyReferences(Address address, WitnessResponseListener listener){ + private boolean mOneTime; + + /** + * Constructor + * + * @param address address to be query + * @param oneTime boolean value indicating if WebSocket must be closed (true) or not (false) + * after the response + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the success/failure + * of the transaction broadcast operation. + */ + public GetKeyReferences(Address address, boolean oneTime, WitnessResponseListener listener){ super(listener); addresses = new ArrayList<>(); addresses.add(address); - + this.mOneTime = oneTime; } - public GetKeyReferences(List
addresses, WitnessResponseListener listener) { + /** + * + * @param addresses list of addresses to be query + * @param oneTime boolean value indicating if WebSocket must be closed (true) or not (false) + * after the response + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the success/failure + * of the transaction broadcast operation. + */ + public GetKeyReferences(List
addresses, boolean oneTime, WitnessResponseListener listener) { super(listener); this.addresses = addresses; this.mListener = listener; + this.mOneTime = oneTime; + } + + /** + * Using this constructor the websocket connection closes after the response. + * + * @param address + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the success/failure + * of the transaction broadcast operation. + */ + public GetKeyReferences(Address address, WitnessResponseListener listener){ + this(address, true, listener); + } + + /** + * Using this constructor the websocket connection closes after the response. + * + * @param addresses + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the success/failure + * of the transaction broadcast operation. + */ + public GetKeyReferences(List
addresses, WitnessResponseListener listener) { + this(addresses, true, listener); } @Override @@ -64,7 +116,9 @@ public class GetKeyReferences extends BaseGrapheneHandler { } else { this.mListener.onSuccess(witnessResponse); } - websocket.disconnect(); + if(mOneTime){ + websocket.disconnect(); + } } @Override diff --git a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetLimitOrders.java b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetLimitOrders.java index eacdda9..3327ff7 100644 --- a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetLimitOrders.java +++ b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetLimitOrders.java @@ -22,7 +22,14 @@ import de.bitsharesmunich.graphenej.models.BaseResponse; import de.bitsharesmunich.graphenej.models.WitnessResponse; /** - * Created by nelson on 11/15/16. + * Class that implements get_limit_orders request handler. + * + * Get limit orders in a given market. + * + * The request returns the limit orders, ordered from least price to greatest + * + * @see get_limit_orders API doc + * */ public class GetLimitOrders extends BaseGrapheneHandler { @@ -31,12 +38,42 @@ public class GetLimitOrders extends BaseGrapheneHandler { private int limit; private WitnessResponseListener mListener; - public GetLimitOrders(String a, String b, int limit, WitnessResponseListener mListener) { - super(mListener); + private boolean mOneTime; + + + /** + * Default Constructor + * + * @param a id of asset being sold + * @param b id of asset being purchased + * @param limit maximum number of orders to retrieve + * @param oneTime boolean value indicating if WebSocket must be closed (true) or not + * (false) after the response + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the + * success/failure of the operation. + */ + public GetLimitOrders(String a, String b, int limit, boolean oneTime, WitnessResponseListener listener) { + super(listener); this.a = a; this.b = b; this.limit = limit; - this.mListener = mListener; + this.mOneTime = oneTime; + this.mListener = listener; + } + + /** + * Using this constructor the WebSocket connection closes after the response. + * + * @param a id of asset being sold + * @param b id of asset being purchased + * @param limit maximum number of orders to retrieve + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the + * success/failure of the operation. + */ + public GetLimitOrders(String a, String b, int limit, WitnessResponseListener listener) { + this(a, b, limit, true, listener); } @Override @@ -70,7 +107,9 @@ public class GetLimitOrders extends BaseGrapheneHandler { } catch (Exception e) { e.printStackTrace(); } - websocket.disconnect(); + if(mOneTime){ + websocket.disconnect(); + } } @Override @@ -83,12 +122,16 @@ public class GetLimitOrders extends BaseGrapheneHandler { @Override public void onError(WebSocket websocket, WebSocketException cause) throws Exception { mListener.onError(new BaseResponse.Error(cause.getMessage())); - websocket.disconnect(); + if(mOneTime){ + websocket.disconnect(); + } } @Override public void handleCallbackError(WebSocket websocket, Throwable cause) throws Exception { mListener.onError(new BaseResponse.Error(cause.getMessage())); - websocket.disconnect(); + if(mOneTime){ + websocket.disconnect(); + } } } diff --git a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetMarketHistory.java b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetMarketHistory.java index b570839..06e2a7f 100644 --- a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetMarketHistory.java +++ b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetMarketHistory.java @@ -23,7 +23,12 @@ import de.bitsharesmunich.graphenej.models.BucketObject; import de.bitsharesmunich.graphenej.models.WitnessResponse; /** - * Created by nelson on 12/22/16. + * Class that implements get_market_history request handler. + * + * Get mar + * + * @see get_market_history API doc + * */ public class GetMarketHistory extends BaseGrapheneHandler { @@ -44,16 +49,59 @@ public class GetMarketHistory extends BaseGrapheneHandler { private int apiId = -1; private int counter = 0; - public GetMarketHistory(Asset base, Asset quote, long bucket, Date start, Date end, WitnessResponseListener listener){ + private boolean mOneTime; + + /** + * Default Constructor + * + * @param base asset which history is desired + * @param quote asset which the base price asset will be compared to + * @param bucket the time interval (in seconds) for each point should be (analog to + * candles on a candle stick graph). + * Note: The bucket value is discrete and node dependent. The default value + * is 3600s. To get the available buckets of a node use + * get_all_asset_holders API call. + * @param start datetime of of the most recent operation to retrieve (Note: The name is + * counter intuitive, but it follow the original API parameter name) + * @param end datetime of the the earliest operation to retrieve + * @param oneTime boolean value indicating if WebSocket must be closed (true) or not + * (false) after the response + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the + * success/failure of the operation. + */ + public GetMarketHistory(Asset base, Asset quote, long bucket, Date start, Date end, boolean oneTime, WitnessResponseListener listener){ super(listener); this.base = base; this.quote = quote; this.bucket = bucket; this.start = start; this.end = end; + this.mOneTime = oneTime; this.mListener = listener; } + /** + * Using this constructor the WebSocket connection closes after the response. + * + * @param base asset which history is desired + * @param quote asset which the base price asset will be compared to + * @param bucket the time interval (in seconds) for each point should be (analog to + * candles on a candle stick graph). + * Note: The bucket value is discrete and node dependent. The default value + * is 3600s. To get the available buckets of a node use + * get_all_asset_holders API call. + * @param start datetime of of the most recent operation to retrieve (Note: The name is + * counter intuitive, but it follow the original API parameter name) + * @param end datetime of the the earliest operation to retrieve + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the + * success/failure of the operation. + */ + public GetMarketHistory(Asset base, Asset quote, long bucket, Date start, Date end, WitnessResponseListener listener){ + this(base, quote, bucket, start, end, true, listener); + } + public Asset getBase() { return base; } @@ -131,7 +179,9 @@ public class GetMarketHistory extends BaseGrapheneHandler { BaseResponse baseResponse = gson.fromJson(response, BaseResponse.class); if(baseResponse.error != null){ mListener.onError(baseResponse.error); - websocket.disconnect(); + if(mOneTime){ + websocket.disconnect(); + } }else{ currentId++; ArrayList emptyParams = new ArrayList<>(); diff --git a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetObjects.java b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetObjects.java index 548dfcd..9c34966 100644 --- a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetObjects.java +++ b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetObjects.java @@ -28,14 +28,47 @@ import de.bitsharesmunich.graphenej.models.BitAssetData; import de.bitsharesmunich.graphenej.models.WitnessResponse; /** - * Created by nelson on 1/8/17. + * + * Class that implements get_objects request handler. + * + * Get the objects corresponding to the provided IDs. + * + * The response returns a list of objects retrieved, in the order they are mentioned in ids + * + * @see get_objects API doc + * */ public class GetObjects extends BaseGrapheneHandler { private List ids; - public GetObjects(List ids, WitnessResponseListener listener){ + private boolean mOneTime; + + /** + * Default Constructor + * + * @param ids list of IDs of the objects to retrieve + * @param oneTime boolean value indicating if WebSocket must be closed (true) or not + * (false) after the response + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the + * success/failure of the operation. + */ + public GetObjects(List ids, boolean oneTime, WitnessResponseListener listener){ super(listener); this.ids = ids; + this.mOneTime = oneTime; + } + + /** + * Using this constructor the WebSocket connection closes after the response. + * + * @param ids list of IDs of the objects to retrieve + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the + * success/failure of the operation. + */ + public GetObjects(List ids, WitnessResponseListener listener){ + this(ids, true, listener); } @Override @@ -92,7 +125,9 @@ public class GetObjects extends BaseGrapheneHandler { WitnessResponse> output = new WitnessResponse<>(); output.result = parsedResult; mListener.onSuccess(output); - websocket.disconnect(); + if(mOneTime){ + websocket.disconnect(); + } } @Override diff --git a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetRelativeAccountHistory.java b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetRelativeAccountHistory.java index dd023a4..32da128 100644 --- a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetRelativeAccountHistory.java +++ b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetRelativeAccountHistory.java @@ -49,38 +49,81 @@ public class GetRelativeAccountHistory extends BaseGrapheneHandler { private int currentId = 1; private int apiId = -1; + private boolean mOneTime; + /** * Constructor that takes all possible parameters. - * @param userAccount The user account to be queried - * @param stop Sequence number of earliest operation - * @param limit Maximum number of operations to retrieve (must not exceed 100) - * @param start Sequence number of the most recent operation to retrieve - * @param listener Listener to be notified with the result of this query + * + * @param userAccount The user account to be queried + * @param stop Sequence number of earliest operation + * @param limit Maximum number of operations to retrieve (must not exceed 100) + * @param start Sequence number of the most recent operation to retrieve + * @param oneTime boolean value indicating if WebSocket must be closed (true) or not + * (false) after the response + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the + * success/failure of the operation. */ - public GetRelativeAccountHistory(UserAccount userAccount, int stop, int limit, int start, WitnessResponseListener listener){ + public GetRelativeAccountHistory(UserAccount userAccount, int stop, int limit, int start, boolean oneTime, WitnessResponseListener listener){ super(listener); if(limit > MAX_LIMIT) limit = MAX_LIMIT; this.mUserAccount = userAccount; this.stop = stop; this.limit = limit; this.start = start; + this.mOneTime = oneTime; this.mListener = listener; } /** * Constructor that uses the default values, and sets the limit to its maximum possible value. - * @param userAccount The user account to be queried - * @param listener Listener to be notified with the result of this query + * + * @param userAccount The user account to be queried + * @param oneTime boolean value indicating if WebSocket must be closed (true) or not + * (false) after the response + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the + * success/failure of the operation. */ - public GetRelativeAccountHistory(UserAccount userAccount, WitnessResponseListener listener){ + public GetRelativeAccountHistory(UserAccount userAccount, boolean oneTime, WitnessResponseListener listener){ super(listener); this.mUserAccount = userAccount; this.stop = DEFAULT_STOP; this.limit = MAX_LIMIT; this.start = DEFAULT_START; + this.mOneTime = oneTime; this.mListener = listener; } + /** + * Constructor that takes all possible parameters for the query. + * Using this constructor the WebSocket connection closes after the response. + * + * @param userAccount The user account to be queried + * @param stop Sequence number of earliest operation + * @param limit Maximum number of operations to retrieve (must not exceed 100) + * @param start Sequence number of the most recent operation to retrieve + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the + * success/failure of the operation. + */ + public GetRelativeAccountHistory(UserAccount userAccount, int stop, int limit, int start, WitnessResponseListener listener){ + this(userAccount, stop, limit, start, true, listener); + } + + /** + * Constructor that uses the default values, and sets the limit to its maximum possible value. + * Using this constructor the WebSocket connection closes after the response. + * + * @param userAccount The user account to be queried + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the + * success/failure of the operation. + */ + public GetRelativeAccountHistory(UserAccount userAccount, WitnessResponseListener listener){ + this(userAccount, true, listener); + } + @Override public void onConnected(WebSocket websocket, Map> headers) throws Exception { mWebsocket = websocket; @@ -99,7 +142,9 @@ public class GetRelativeAccountHistory extends BaseGrapheneHandler { BaseResponse baseResponse = gson.fromJson(response, BaseResponse.class); if(baseResponse.error != null){ mListener.onError(baseResponse.error); - websocket.disconnect(); + if(mOneTime){ + websocket.disconnect(); + } }else{ currentId++; ArrayList emptyParams = new ArrayList<>(); @@ -139,7 +184,8 @@ public class GetRelativeAccountHistory extends BaseGrapheneHandler { } /** - * Updates the arguments and makes a new call to the get_relative_account_history API + * Updates the arguments and makes a new call to the get_relative_account_history API. + * * @param stop Sequence number of earliest operation * @param limit Maximum number of operations to retrieve (must not exceed 100) * @param start Sequence number of the most recent operation to retrieve @@ -152,10 +198,10 @@ public class GetRelativeAccountHistory extends BaseGrapheneHandler { } /** - * Disconnects the websocket + * Disconnects the WebSocket. */ public void disconnect(){ - if(mWebsocket != null && mWebsocket.isOpen()){ + if(mWebsocket != null && mWebsocket.isOpen() && mOneTime){ mWebsocket.disconnect(); } } diff --git a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetRequiredFees.java b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetRequiredFees.java index f82b950..553c95d 100644 --- a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetRequiredFees.java +++ b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetRequiredFees.java @@ -23,20 +23,52 @@ import java.util.List; import java.util.Map; /** - * Created by nelson on 11/15/16. + * Class that implements get_required_fees request handler. + * + * For each operation calculate the required fee in the specified asset type. + * + * @see get_required_fees API doc */ -public class GetRequiredFees extends WebSocketAdapter { +public class GetRequiredFees extends BaseGrapheneHandler { private WitnessResponseListener mListener; private List operations; private Asset asset; - public GetRequiredFees(List operations, Asset asset, WitnessResponseListener listener){ + private boolean mOneTime; + + /** + * Default Constructor + * + * @param operations list of operations that fee should be calculated + * @param asset specify the asset of the operations + * @param oneTime boolean value indicating if WebSocket must be closed (true) or not + * (false) after the response + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the + * success/failure of the operation. + */ + public GetRequiredFees(List operations, Asset asset, boolean oneTime, WitnessResponseListener listener){ + super(listener); this.operations = operations; this.asset = asset; + this.mOneTime = oneTime; this.mListener = listener; } + /** + * Using this constructor the WebSocket connection closes after the response. + * + * @param operations list of operations that fee should be calculated + * @param asset specify the asset of the operations + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the + * success/failure of the operation. + */ + public GetRequiredFees(List operations, Asset asset, WitnessResponseListener listener){ + this(operations, asset, true, listener); + } + @Override public void onConnected(WebSocket websocket, Map> headers) throws Exception { ArrayList accountParams = new ArrayList<>(); @@ -66,12 +98,16 @@ public class GetRequiredFees extends WebSocketAdapter { @Override public void onError(WebSocket websocket, WebSocketException cause) throws Exception { mListener.onError(new BaseResponse.Error(cause.getMessage())); - websocket.disconnect(); + if(mOneTime){ + websocket.disconnect(); + } } @Override public void handleCallbackError(WebSocket websocket, Throwable cause) throws Exception { mListener.onError(new BaseResponse.Error(cause.getMessage())); - websocket.disconnect(); + if(mOneTime){ + websocket.disconnect(); + } } } diff --git a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetTradeHistory.java b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetTradeHistory.java index 46dd72d..dde5665 100644 --- a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetTradeHistory.java +++ b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/GetTradeHistory.java @@ -18,7 +18,15 @@ import de.bitsharesmunich.graphenej.models.ApiCall; import de.bitsharesmunich.graphenej.models.WitnessResponse; /** - * @author henry + * Class that implements get_trade_history request handler. + * + * Get recent trades for the market assetA:assetB for a time interval + * Note: Currently, timezone offsets are not supported. The time must be UTC. + * + * The request returns the all trades of the passed pair of asset at a specific time interval. + * + * @see get_trade_history API doc + * */ public class GetTradeHistory extends BaseGrapheneHandler { @@ -29,14 +37,47 @@ public class GetTradeHistory extends BaseGrapheneHandler { private int limit; private WitnessResponseListener mListener; - public GetTradeHistory(String a, String b, String toTime, String fromTime,int limit, WitnessResponseListener mListener) { - super(mListener); + private boolean mOneTime; + + /** + * Constructor + * + * @param a name of the first asset + * @param b name of the second asset + * @param toTime stop time as a UNIX timestamp + * @param fromTime start time as a UNIX timestamp + * @param limit number of transactions to retrieve, capped at 100 + * @param oneTime boolean value indicating if WebSocket must be closed (true) or not + * (false) after the response + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the + * success/failure of the operation. + */ + public GetTradeHistory(String a, String b, String toTime, String fromTime,int limit, boolean oneTime, WitnessResponseListener listener) { + super(listener); this.a = a; this.b = b; this.toTime = toTime; this.fromTime = fromTime; this.limit = limit; - this.mListener = mListener; + this.mOneTime = oneTime; + this.mListener = listener; + } + + /** + * Using this constructor the WebSocket connection closes after the response. + * + * @param a name of the first asset + * @param b name of the second asset + * @param toTime stop time as a UNIX timestamp + * @param fromTime start time as a UNIX timestamp + * @param limit number of transactions to retrieve, capped at 100 + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the + * success/failure of the operation. + */ + public GetTradeHistory(String a, String b, String toTime, String fromTime,int limit, WitnessResponseListener listener) { + this(a, b, toTime, fromTime, limit, true, listener); } @Override @@ -72,7 +113,9 @@ public class GetTradeHistory extends BaseGrapheneHandler { } catch (Exception e) { e.printStackTrace(); } - websocket.disconnect(); + if(mOneTime){ + websocket.disconnect(); + } } @Override diff --git a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/ListAssets.java b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/ListAssets.java index 5a674cc..28fb6bb 100644 --- a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/ListAssets.java +++ b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/ListAssets.java @@ -19,14 +19,12 @@ import java.util.Map; /** * WebSocketAdapter class used to send a request a 'list_assets' API call to the witness node. * - * @see: - * * The API imposes a limit of of 100 assets per request, but if the user of this class wants * to get a list of all assets, the LIST_ALL constant must be used as second argument in the * constructor. Internally we are going to perform multiple calls in order to satisfy the user's * request. * - * Created by nelson on 1/5/17. + * @see: */ public class ListAssets extends BaseGrapheneHandler { /** @@ -45,16 +43,41 @@ public class ListAssets extends BaseGrapheneHandler { private int limit; private int requestCounter = 0; + private boolean mOneTime; + /** * Constructor - * @param lowerBoundSymbol: Lower bound of symbol names to retrieve - * @param limit: Maximum number of assets to fetch, if the constant LIST_ALL - * is passed, all existing assets will be retrieved. + * + * @param lowerBoundSymbol Lower bound of symbol names to retrieve + * @param limit Maximum number of assets to fetch, if the constant LIST_ALL + * is passed, all existing assets will be retrieved. + * @param oneTime boolean value indicating if WebSocket must be closed (true) or not + * (false) after the response + * @param listener A class implementing the WitnessResponseListener interface. This + * should be implemented by the party interested in being notified + * about the success/failure of the operation. */ - public ListAssets(String lowerBoundSymbol, int limit, WitnessResponseListener listener){ + public ListAssets(String lowerBoundSymbol, int limit, boolean oneTime, WitnessResponseListener listener){ super(listener); this.lowerBound = lowerBoundSymbol; this.limit = limit; + this.mOneTime = oneTime; + } + + /** + * Using this constructor the WebSocket connection closes after the response. + * + * @param lowerBoundSymbol Lower bound of symbol names to retrieve + * @param limit Maximum number of assets to fetch, if the constant LIST_ALL + * is passed, all existing assets will be retrieved. + * @param oneTime boolean value indicating if WebSocket must be closed (true) or not + * (false) after the response + * @param listener A class implementing the WitnessResponseListener interface. This + * should be implemented by the party interested in being notified + * about the success/failure of the operation. + */ + public ListAssets(String lowerBoundSymbol, int limit, WitnessResponseListener listener){ + this(lowerBoundSymbol, limit, true, listener); } @Override @@ -81,7 +104,9 @@ public class ListAssets extends BaseGrapheneHandler { // If the requested number of assets was below // the limit, we just call the listener. mListener.onSuccess(witnessResponse); - websocket.disconnect(); + if(mOneTime){ + websocket.disconnect(); + } }else{ // Updating counter to keep track of how many batches we already retrieved. requestCounter++; @@ -96,12 +121,16 @@ public class ListAssets extends BaseGrapheneHandler { // we got less than the requested amount. witnessResponse.result = this.assets; mListener.onSuccess(witnessResponse); - websocket.disconnect(); + if(mOneTime){ + websocket.disconnect(); + } }else if(this.assets.size() == this.limit){ // We already have the required amount of assets witnessResponse.result = this.assets; mListener.onSuccess(witnessResponse); - websocket.disconnect(); + if(mOneTime){ + websocket.disconnect(); + } }else{ // We still need to fetch some more assets this.lowerBound = this.assets.get(this.assets.size() - 1).getSymbol(); diff --git a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/LookupAccounts.java b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/LookupAccounts.java index 6b424b9..97ab2bf 100644 --- a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/LookupAccounts.java +++ b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/LookupAccounts.java @@ -18,7 +18,13 @@ import de.bitsharesmunich.graphenej.models.ApiCall; import de.bitsharesmunich.graphenej.models.WitnessResponse; /** - * Created by henry on 07/12/16. + * Class that implements lookup_accounts request handler. + * + * Get names and IDs for registered accounts. + * + * The request returns a map of account names to corresponding IDs. + * + * @see lookup_accounts API doc */ public class LookupAccounts extends BaseGrapheneHandler { @@ -27,20 +33,70 @@ public class LookupAccounts extends BaseGrapheneHandler { private int maxAccounts = DEFAULT_MAX; private final WitnessResponseListener mListener; - public LookupAccounts(String accountName, WitnessResponseListener listener){ + private boolean mOneTime; + + /** + * Constructor + * + * @param accountName account name used at the query + * @param oneTime boolean value indicating if WebSocket must be closed (true) or not + * (false) after the response + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the + * success/failure of the operation. + */ + public LookupAccounts(String accountName, boolean oneTime, WitnessResponseListener listener){ super(listener); this.accountName = accountName; this.maxAccounts = DEFAULT_MAX; + this.mOneTime = oneTime; this.mListener = listener; } - public LookupAccounts(String accountName, int maxAccounts, WitnessResponseListener listener){ + /** + * Constructor with maxAccounts + * + * @param accountName account name used at the query + * @param maxAccounts maximum number of results to return (must not exceed 1000) + * @param oneTime boolean value indicating if WebSocket must be closed (true) or not + * (false) after the response + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the + * success/failure of the operation. + */ + public LookupAccounts(String accountName, int maxAccounts, boolean oneTime, WitnessResponseListener listener){ super(listener); this.accountName = accountName; this.maxAccounts = maxAccounts; + this.mOneTime = oneTime; this.mListener = listener; } + /** + * Using this constructor the WebSocket connection closes after the response. + * + * @param accountName account name used at the query + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the + * success/failure of the operation. + */ + public LookupAccounts(String accountName, WitnessResponseListener listener){ + this(accountName, true, listener); + } + + /** + * Using this constructor the WebSocket connection closes after the response. + * + * @param accountName account name used at the query + * @param maxAccounts maximum number of results to return (must not exceed 1000) + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the + * success/failure of the operation. + */ + public LookupAccounts(String accountName, int maxAccounts, WitnessResponseListener listener){ + this(accountName, maxAccounts, true, listener); + } + @Override public void onConnected(WebSocket websocket, Map> headers) throws Exception { ArrayList accountParams = new ArrayList<>(); @@ -65,7 +121,9 @@ public class LookupAccounts extends BaseGrapheneHandler { this.mListener.onSuccess(witnessResponse); } - websocket.disconnect(); + if(mOneTime){ + websocket.disconnect(); + } } @Override diff --git a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/LookupAssetSymbols.java b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/LookupAssetSymbols.java index 3c24247..2a649d0 100644 --- a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/LookupAssetSymbols.java +++ b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/LookupAssetSymbols.java @@ -18,18 +18,49 @@ import de.bitsharesmunich.graphenej.models.ApiCall; import de.bitsharesmunich.graphenej.models.WitnessResponse; /** - * Created by nelson on 12/12/16. + * Class that implements lookup_asset_symbols request handler. + * + * Get the assets corresponding to the provided IDs. + * + * The response returns the assets corresponding to the provided symbols or IDs. + * + * @see lookup_asset_symbols API doc */ public class LookupAssetSymbols extends BaseGrapheneHandler { private WitnessResponseListener mListener; private List assets; - public LookupAssetSymbols(List assets, WitnessResponseListener listener){ + private boolean mOneTime; + + /** + * Default Constructor + * + * @param assets list of the assets to retrieve + * @param oneTime boolean value indicating if WebSocket must be closed (true) or not + * (false) after the response + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the + * success/failure of the operation. + */ + public LookupAssetSymbols(List assets, boolean oneTime, WitnessResponseListener listener){ super(listener); this.assets = assets; + this.mOneTime = oneTime; this.mListener = listener; } + /** + * Using this constructor the WebSocket connection closes after the response. + * + * @param assets list of the assets to retrieve + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the + * success/failure of the operation. + */ + public LookupAssetSymbols(List assets, WitnessResponseListener listener){ + this(assets, true, listener); + } + @Override public void onConnected(WebSocket websocket, Map> headers) throws Exception { ArrayList params = new ArrayList<>(); @@ -51,6 +82,9 @@ public class LookupAssetSymbols extends BaseGrapheneHandler { gsonBuilder.registerTypeAdapter(Asset.class, new Asset.AssetDeserializer()); WitnessResponse> witnessResponse = gsonBuilder.create().fromJson(response, LookupAssetSymbolsResponse); mListener.onSuccess(witnessResponse); + if(mOneTime){ + websocket.disconnect(); + } } @Override diff --git a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/SubscriptionMessagesHub.java b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/SubscriptionMessagesHub.java index 95c39f4..2be0780 100644 --- a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/SubscriptionMessagesHub.java +++ b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/SubscriptionMessagesHub.java @@ -18,6 +18,7 @@ import de.bitsharesmunich.graphenej.RPC; import de.bitsharesmunich.graphenej.Transaction; import de.bitsharesmunich.graphenej.UserAccount; import de.bitsharesmunich.graphenej.errors.RepeatedRequestIdException; +import de.bitsharesmunich.graphenej.interfaces.NodeErrorListener; import de.bitsharesmunich.graphenej.interfaces.SubscriptionHub; import de.bitsharesmunich.graphenej.interfaces.SubscriptionListener; import de.bitsharesmunich.graphenej.interfaces.WitnessResponseListener; @@ -30,9 +31,7 @@ import de.bitsharesmunich.graphenej.operations.LimitOrderCreateOperation; import de.bitsharesmunich.graphenej.operations.TransferOperation; /** - * A websocket adapter prepared to be used as a basic dispatch hub for subscription messages. - * - * Created by nelson on 1/26/17. + * A WebSocket adapter prepared to be used as a basic dispatch hub for subscription messages. */ public class SubscriptionMessagesHub extends BaseGrapheneHandler implements SubscriptionHub { @@ -73,12 +72,13 @@ public class SubscriptionMessagesHub extends BaseGrapheneHandler implements Subs * * A list of ObjectTypes must be provided, otherwise we won't get any update. * - * @param user: User name, in case the node to which we're going to connect to requires authentication - * @param password: Password, same as above - * @param clearFilter: Whether to automatically subscribe of not to the notification feed. - * @param errorListener: Callback that will be fired in case there is an error. + * @param user User name, in case the node to which we're going to connect to requires + * authentication + * @param password Password, same as above + * @param clearFilter Whether to automatically subscribe of not to the notification feed. + * @param errorListener Callback that will be fired in case there is an error. */ - public SubscriptionMessagesHub(String user, String password, boolean clearFilter, WitnessResponseListener errorListener){ + public SubscriptionMessagesHub(String user, String password, boolean clearFilter, NodeErrorListener errorListener){ super(errorListener); this.user = user; this.password = password; @@ -97,15 +97,16 @@ public class SubscriptionMessagesHub extends BaseGrapheneHandler implements Subs } /** - * Constructor used to create a subscription message hub that will call the set_subscribe_callback - * API with the clear_filter parameter set to false, meaning that it will only receive updates - * from objects we register. + * Constructor used to create a subscription message hub that will call the + * set_subscribe_callback API with the clear_filter parameter set to false, meaning that it will + * only receive updates from objects we register. * - * @param user: User name, in case the node to which we're going to connect to requires authentication - * @param password: Password, same as above - * @param errorListener: Callback that will be fired in case there is an error. + * @param user User name, in case the node to which we're going to connect to requires + * authentication + * @param password Password, same as above + * @param errorListener Callback that will be fired in case there is an error. */ - public SubscriptionMessagesHub(String user, String password, WitnessResponseListener errorListener){ + public SubscriptionMessagesHub(String user, String password, NodeErrorListener errorListener){ this(user, password, false, errorListener); } @@ -247,7 +248,8 @@ public class SubscriptionMessagesHub extends BaseGrapheneHandler implements Subs /** * Method used to check the current state of the connection. - * @return: True if the websocket is open and there is an active subscription, false otherwise. + * + * @return True if the websocket is open and there is an active subscription, false otherwise. */ public boolean isSubscribed(){ return this.mWebsocket.isOpen() && isSubscribed; diff --git a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/TransactionBroadcastSequence.java b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/TransactionBroadcastSequence.java index 30549d9..6064df5 100644 --- a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/TransactionBroadcastSequence.java +++ b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/TransactionBroadcastSequence.java @@ -43,20 +43,38 @@ public class TransactionBroadcastSequence extends BaseGrapheneHandler { private int currentId = 1; private int broadcastApiId = -1; + private boolean mOneTime; + /** - * Constructor of this class. The ids required - * @param transaction: The transaction to be broadcasted. - * @param listener: A class implementing the WitnessResponseListener interface. This should - * be implemented by the party interested in being notified about the success/failure - * of the transaction broadcast operation. + * Default Constructor + * + * @param transaction transaction to be broadcasted. + * @param oneTime boolean value indicating if WebSocket must be closed (true) or not + * (false) after the response + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the + * success/failure of the operation. */ - public TransactionBroadcastSequence(Transaction transaction, Asset feeAsset, WitnessResponseListener listener){ + public TransactionBroadcastSequence(Transaction transaction, Asset feeAsset, boolean oneTime, WitnessResponseListener listener){ super(listener); this.transaction = transaction; this.feeAsset = feeAsset; + this.mOneTime = oneTime; this.mListener = listener; } + /** + * Using this constructor the WebSocket connection closes after the response. + * + * @param transaction: transaction to be broadcasted. + * @param listener A class implementing the WitnessResponseListener interface. This should + * be implemented by the party interested in being notified about the + * success/failure of the operation. + */ + public TransactionBroadcastSequence(Transaction transaction, Asset feeAsset, WitnessResponseListener listener){ + this(transaction, feeAsset, true, listener); + } + @Override public void onConnected(WebSocket websocket, Map> headers) throws Exception { ArrayList loginParams = new ArrayList<>(); @@ -77,7 +95,9 @@ public class TransactionBroadcastSequence extends BaseGrapheneHandler { BaseResponse baseResponse = gson.fromJson(response, BaseResponse.class); if(baseResponse.error != null){ mListener.onError(baseResponse.error); - websocket.disconnect(); + if(mOneTime){ + websocket.disconnect(); + } }else{ currentId++; ArrayList emptyParams = new ArrayList<>(); @@ -140,7 +160,9 @@ public class TransactionBroadcastSequence extends BaseGrapheneHandler { Type WitnessResponseType = new TypeToken>(){}.getType(); WitnessResponse witnessResponse = gson.fromJson(response, WitnessResponseType); mListener.onSuccess(witnessResponse); - websocket.disconnect(); + if(mOneTime){ + websocket.disconnect(); + } } } } @@ -156,7 +178,9 @@ public class TransactionBroadcastSequence extends BaseGrapheneHandler { public void onError(WebSocket websocket, WebSocketException cause) throws Exception { System.out.println("onError. cause: "+cause.getMessage()); mListener.onError(new BaseResponse.Error(cause.getMessage())); - websocket.disconnect(); + if(mOneTime){ + websocket.disconnect(); + } } @Override @@ -166,6 +190,8 @@ public class TransactionBroadcastSequence extends BaseGrapheneHandler { System.out.println(element.getFileName()+"#"+element.getClassName()+":"+element.getLineNumber()); } mListener.onError(new BaseResponse.Error(cause.getMessage())); - websocket.disconnect(); + if(mOneTime){ + websocket.disconnect(); + } } } \ No newline at end of file diff --git a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/android/NodeConnection.java b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/android/NodeConnection.java index a8a76f4..3bd90e8 100644 --- a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/android/NodeConnection.java +++ b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/android/NodeConnection.java @@ -6,21 +6,39 @@ import java.util.List; import de.bitsharesmunich.graphenej.api.BaseGrapheneHandler; import de.bitsharesmunich.graphenej.api.SubscriptionMessagesHub; import de.bitsharesmunich.graphenej.errors.RepeatedRequestIdException; +import de.bitsharesmunich.graphenej.interfaces.NodeErrorListener; import de.bitsharesmunich.graphenej.interfaces.WitnessResponseListener; +import de.bitsharesmunich.graphenej.models.BaseResponse; /** - * Created by nelson on 6/26/17. + * Class used to encapsulate all connections that should be done to a node (with node hop support). + * + * This class is intended to be used as a central broker for all full node API requests. It should + * be used as a singleton under an application. */ - public class NodeConnection { + /** + * List of URLs of the nodes + */ private List mUrlList; + /** + * Index of the current node from the list + */ private int mUrlIndex; private WebsocketWorkerThread mThread; private SubscriptionMessagesHub mMessagesHub; private long requestCounter = SubscriptionMessagesHub.MANUAL_SUBSCRIPTION_ID + 1; + private WitnessResponseListener mErrorListener; private static NodeConnection instance; + private String mUser; + private String mPassword; + private boolean mSubscribe; + + /* + * Get the instance of the NodeConnection which is intended to be used as a Singleton. + */ public static NodeConnection getInstance(){ if(instance == null){ instance = new NodeConnection(); @@ -32,34 +50,91 @@ public class NodeConnection { this.mUrlList = new ArrayList<>(); } + /** + * Add a WebSocket URL node that will be added to the list used at node hop scheme. + * + * @param url: URL of the node + */ public void addNodeUrl(String url){ + System.out.println("addNodeUrl: "+url); this.mUrlList.add(url); } + /** + * Add a list of WebSocket URL nodes that will be added to the current list and + * be used at node hop scheme. + * + * @param urlList: List of URLs of the nodes + */ + public void addNodeUrls(List urlList){ + List newList = new ArrayList(mUrlList); + newList.addAll(urlList); + } + + /** + * Get the list of WebSocket URL nodes. + * + * @return List of URLs of the nodes + */ public List getNodeUrls(){ return this.mUrlList; } + /** + * Clear list of WebSocket URL nodes. + */ public void clearNodeList(){ this.mUrlList.clear(); } + private NodeErrorListener mInternalErrorListener = new NodeErrorListener() { + @Override + public void onError(BaseResponse.Error error) { + System.out.println("NodeConnect Error. Msg: "+error); + + connect(mUser, mPassword, mSubscribe, mErrorListener); + } + }; + + /** + + */ /** * Method that will try to connect to one of the nodes. If the connection fails * a subsequent call to this method will try to connect with the next node in the * list if there is one. + * + * @param user user credential used for restricted requested that needed to be + * logged + * @param password password credential used for restricted requested that needed to be + * logged + * @param subscribe if the node should be subscribed to the node + * @param errorListener a class implementing the WitnessResponseListener interface. This + * should be implemented by the party interested in being notified + * about the failure of the desired broadcast operation. */ public void connect(String user, String password, boolean subscribe, WitnessResponseListener errorListener) { if(this.mUrlList.size() > 0){ - mThread = new WebsocketWorkerThread(this.mUrlList.get(mUrlIndex)); + mUser = user; + mPassword = password; + mSubscribe = subscribe; + System.out.println("Connecting to: "+ this.mUrlList.get(mUrlIndex)); + mErrorListener = errorListener; + mThread = new WebsocketWorkerThread(this.mUrlList.get(mUrlIndex), mInternalErrorListener); mUrlIndex = mUrlIndex + 1 % this.mUrlList.size(); - mMessagesHub = new SubscriptionMessagesHub(user, password, subscribe, errorListener); + mMessagesHub = new SubscriptionMessagesHub(user, password, subscribe, mInternalErrorListener); mThread.addListener(mMessagesHub); mThread.start(); } } + /** + * Add the API Handler to the node. + * + * @param handler request handler to be added to the connection + * @throws RepeatedRequestIdException + */ public void addRequestHandler(BaseGrapheneHandler handler) throws RepeatedRequestIdException { handler.setRequestId(requestCounter); requestCounter++; diff --git a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/android/WebsocketWorkerThread.java b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/android/WebsocketWorkerThread.java index 91aeba8..76db5e0 100644 --- a/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/android/WebsocketWorkerThread.java +++ b/graphenej/src/main/java/de/bitsharesmunich/graphenej/api/android/WebsocketWorkerThread.java @@ -10,10 +10,13 @@ import java.security.NoSuchAlgorithmException; import javax.net.ssl.SSLContext; +import de.bitsharesmunich.graphenej.interfaces.NodeErrorListener; +import de.bitsharesmunich.graphenej.models.BaseResponse; import de.bitsharesmunich.graphenej.test.NaiveSSLContext; /** - * Created by nelson on 11/17/16. + * Class used to encapsulate the thread where the WebSocket does the requests. + * */ public class WebsocketWorkerThread extends Thread { private final String TAG = this.getClass().getName(); @@ -23,7 +26,13 @@ public class WebsocketWorkerThread extends Thread { private final int TIMEOUT = 5000; private WebSocket mWebSocket; + private NodeErrorListener mErrorListener; + /** + * Constructor + * + * @param url URL of the WebSocket + */ public WebsocketWorkerThread(String url){ try { WebSocketFactory factory = new WebSocketFactory().setConnectionTimeout(TIMEOUT); @@ -45,15 +54,56 @@ public class WebsocketWorkerThread extends Thread { } } + /** + * Constructor with connection error listener. + * + * @param url URL of the WebSocket + * @param errorListener a class implementing the NodeErrorListener interface. This + * should be implemented by the party interested in being notified + * about the failure of the connection. + */ + public WebsocketWorkerThread(String url, NodeErrorListener errorListener){ + try { + WebSocketFactory factory = new WebSocketFactory().setConnectionTimeout(TIMEOUT); + + if(DEBUG){ + SSLContext context = NaiveSSLContext.getInstance("TLS"); + + // Set the custom SSL context. + factory.setSSLContext(context); + } + + mWebSocket = factory.createSocket(url); + mErrorListener = errorListener; + } catch (IOException e) { + System.out.println("IOException. Msg: "+e.getMessage()); + } catch(NullPointerException e){ + System.out.println("NullPointerException at WebsocketWorkerThreas. Msg: "+e.getMessage()); + } catch (NoSuchAlgorithmException e) { + System.out.println("NoSuchAlgorithmException. Msg: "+e.getMessage()); + } + } + + /** + * Method call when the thread is started. + */ @Override public void run() { try { mWebSocket.connect(); } catch (WebSocketException e) { System.out.println("WebSocketException. Msg: "+e.getMessage()); + mErrorListener.onError(new BaseResponse.Error(e.getMessage())); } } + /** + * Add a WebSocketListener to the thread that will run. This should be implemented by the party + * interested in being notified about the response value of a request. + * + * @param listener listener implemented to be notified when the socket get a response from the + * node + */ public void addListener(WebSocketListener listener){ mWebSocket.addListener(listener); } diff --git a/graphenej/src/main/java/de/bitsharesmunich/graphenej/interfaces/NodeErrorListener.java b/graphenej/src/main/java/de/bitsharesmunich/graphenej/interfaces/NodeErrorListener.java new file mode 100644 index 0000000..f0386b7 --- /dev/null +++ b/graphenej/src/main/java/de/bitsharesmunich/graphenej/interfaces/NodeErrorListener.java @@ -0,0 +1,10 @@ +package de.bitsharesmunich.graphenej.interfaces; + +import de.bitsharesmunich.graphenej.models.BaseResponse; + +/** + * Interface to be implemented by any listener to network errors. + */ +public interface NodeErrorListener { + void onError(BaseResponse.Error error); +} diff --git a/graphenej/src/test/java/de/bitsharesmunich/graphenej/api/SubscriptionMessagesHubTest.java b/graphenej/src/test/java/de/bitsharesmunich/graphenej/api/SubscriptionMessagesHubTest.java index a0828d3..9d4e4b5 100644 --- a/graphenej/src/test/java/de/bitsharesmunich/graphenej/api/SubscriptionMessagesHubTest.java +++ b/graphenej/src/test/java/de/bitsharesmunich/graphenej/api/SubscriptionMessagesHubTest.java @@ -11,6 +11,7 @@ import java.util.TimerTask; import de.bitsharesmunich.graphenej.ObjectType; import de.bitsharesmunich.graphenej.Transaction; +import de.bitsharesmunich.graphenej.interfaces.NodeErrorListener; import de.bitsharesmunich.graphenej.interfaces.SubscriptionListener; import de.bitsharesmunich.graphenej.interfaces.WitnessResponseListener; import de.bitsharesmunich.graphenej.models.BaseResponse; @@ -29,12 +30,7 @@ public class SubscriptionMessagesHubTest extends BaseApiTest { /** * Error listener */ - private WitnessResponseListener mErrorListener = new WitnessResponseListener() { - @Override - public void onSuccess(WitnessResponse response) { - System.out.println("onSuccess"); - } - + private NodeErrorListener mErrorListener = new NodeErrorListener() { @Override public void onError(BaseResponse.Error error) { System.out.println("onError"); diff --git a/graphenej/src/test/java/de/bitsharesmunich/graphenej/api/android/NodeConnectionTest.java b/graphenej/src/test/java/de/bitsharesmunich/graphenej/api/android/NodeConnectionTest.java index c682528..226c92d 100644 --- a/graphenej/src/test/java/de/bitsharesmunich/graphenej/api/android/NodeConnectionTest.java +++ b/graphenej/src/test/java/de/bitsharesmunich/graphenej/api/android/NodeConnectionTest.java @@ -1,21 +1,71 @@ package de.bitsharesmunich.graphenej.api.android; +import com.google.common.primitives.UnsignedLong; +import com.neovisionaries.ws.client.WebSocket; +import com.neovisionaries.ws.client.WebSocketException; +import com.neovisionaries.ws.client.WebSocketFactory; + +import org.bitcoinj.core.ECKey; import org.junit.Test; +import java.io.IOException; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.Date; import java.util.Timer; import java.util.TimerTask; +import javax.net.ssl.SSLContext; + +import de.bitsharesmunich.graphenej.Address; +import de.bitsharesmunich.graphenej.Asset; +import de.bitsharesmunich.graphenej.AssetAmount; +import de.bitsharesmunich.graphenej.BaseOperation; +import de.bitsharesmunich.graphenej.BrainKey; +import de.bitsharesmunich.graphenej.Transaction; +import de.bitsharesmunich.graphenej.UserAccount; +import de.bitsharesmunich.graphenej.api.GetAccountBalances; +import de.bitsharesmunich.graphenej.api.GetAccountByName; import de.bitsharesmunich.graphenej.api.GetAccounts; +import de.bitsharesmunich.graphenej.api.GetAllAssetHolders; +import de.bitsharesmunich.graphenej.api.GetBlockHeader; +import de.bitsharesmunich.graphenej.api.GetKeyReferences; +import de.bitsharesmunich.graphenej.api.GetLimitOrders; +import de.bitsharesmunich.graphenej.api.GetMarketHistory; +import de.bitsharesmunich.graphenej.api.GetObjects; +import de.bitsharesmunich.graphenej.api.GetRelativeAccountHistory; +import de.bitsharesmunich.graphenej.api.GetRequiredFees; +import de.bitsharesmunich.graphenej.api.GetTradeHistory; +import de.bitsharesmunich.graphenej.api.ListAssets; +import de.bitsharesmunich.graphenej.api.LookupAccounts; +import de.bitsharesmunich.graphenej.api.LookupAssetSymbols; +import de.bitsharesmunich.graphenej.api.TransactionBroadcastSequence; +import de.bitsharesmunich.graphenej.errors.MalformedAddressException; import de.bitsharesmunich.graphenej.errors.RepeatedRequestIdException; import de.bitsharesmunich.graphenej.interfaces.WitnessResponseListener; import de.bitsharesmunich.graphenej.models.BaseResponse; import de.bitsharesmunich.graphenej.models.WitnessResponse; +import de.bitsharesmunich.graphenej.operations.TransferOperation; +import de.bitsharesmunich.graphenej.operations.TransferOperationBuilder; +import de.bitsharesmunich.graphenej.test.NaiveSSLContext; /** * Created by nelson on 6/26/17. */ public class NodeConnectionTest { - private String BLOCK_PAY_DE = System.getenv("OPENLEDGER_EU"); + private String NODE_URL_1 = System.getenv("NODE_URL_1"); + private String NODE_URL_2 = System.getenv("NODE_URL_2"); + private String NODE_URL_3 = System.getenv("NODE_URL_3"); + private String NODE_URL_4 = System.getenv("NODE_URL_4"); + private String TEST_ACCOUNT_BRAIN_KEY = System.getenv("TEST_ACCOUNT_BRAIN_KEY"); + private String ACCOUNT_ID_1 = System.getenv("ACCOUNT_ID_1"); + private String ACCOUNT_ID_2 = System.getenv("ACCOUNT_ID_2"); + private String ACCOUNT_NAME = System.getenv("ACCOUNT_NAME"); + private long BlOCK_TEST_NUMBER = Long.parseLong(System.getenv("BlOCK_TEST_NUMBER")); + private Asset BTS = new Asset("1.3.0"); + private Asset BLOCKPAY = new Asset("1.3.1072"); + private Asset BITDOLAR = new Asset("1.3.121"); //USD Smartcoin + private Asset BITEURO = new Asset("1.3.120"); //EUR Smartcoin private NodeConnection nodeConnection; private TimerTask scheduleTask = new TimerTask() { @@ -54,7 +104,7 @@ public class NodeConnectionTest { @Test public void testNodeConnection(){ nodeConnection = NodeConnection.getInstance(); - nodeConnection.addNodeUrl(BLOCK_PAY_DE); + nodeConnection.addNodeUrl(NODE_URL_1); nodeConnection.connect("", "", true, mErrorListener); Timer timer = new Timer(); @@ -71,6 +121,874 @@ public class NodeConnectionTest { } } + @Test + /** + * Test for NodeConnection's addNodeUrl and addNodeUrls working together. + * + * Need to setup the NODE_URL_(1 to 4) env to work. Some of the nodes may have invalid nodes + * websockets URL just to test the hop. + * + */ + public void testNodeHopFeature(){ + nodeConnection = NodeConnection.getInstance(); + //nodeConnection.addNodeUrl(NODE_URL_4); + //Test adding a "sublist" + ArrayList urlList = new ArrayList(){{ + add(NODE_URL_3); + add(NODE_URL_3); + }}; + //nodeConnection.addNodeUrls(urlList); + nodeConnection.addNodeUrl(NODE_URL_1); + + nodeConnection.connect("", "", true, mErrorListener); + + Timer timer = new Timer(); + timer.schedule(scheduleTask, 5000); + timer.schedule(releaseTask, 30000); + + try{ + // Holding this thread while we get update notifications + synchronized (this){ + wait(); + } + }catch(InterruptedException e){ + System.out.println("InterruptedException. Msg: "+e.getMessage()); + } + } + + /** + * Test for GetAccountBalances Handler. + * + * Request balances for a valid account (Need to setup the ACCOUNT_ID_1 env with desired account id) + * + */ + @Test + public void testGetAccountBalancesRequest(){ + nodeConnection = NodeConnection.getInstance(); + nodeConnection.addNodeUrl(NODE_URL_1); + nodeConnection.connect("", "", false, mErrorListener); + + System.out.println("Adding GetAccountBalances here"); + try{ + UserAccount userAccount = new UserAccount(ACCOUNT_ID_1); + ArrayList assetList = new ArrayList<>(); + assetList.add(BTS); + assetList.add(BITDOLAR); + assetList.add(BITEURO); + System.out.println("Test: Request to discrete asset list"); + nodeConnection.addRequestHandler(new GetAccountBalances(userAccount, assetList, false, new WitnessResponseListener(){ + @Override + public void onSuccess(WitnessResponse response) { + System.out.println("getAccountBalances.onSuccess"); + } + + @Override + public void onError(BaseResponse.Error error) { + System.out.println("getAccountBalances.onError. Msg: "+ error.message); + } + })); + }catch(RepeatedRequestIdException e){ + System.out.println("RepeatedRequestIdException. Msg: "+e.getMessage()); + } + + try{ + UserAccount userAccount = new UserAccount(ACCOUNT_ID_1); + System.out.println("Test: Request to all account' assets balance"); + nodeConnection.addRequestHandler(new GetAccountBalances(userAccount, null, false, new WitnessResponseListener(){ + @Override + public void onSuccess(WitnessResponse response) { + System.out.println("getAccountBalances.onSuccess"); + } + + @Override + public void onError(BaseResponse.Error error) { + System.out.println("getAccountBalances.onError. Msg: "+ error.message); + } + })); + }catch(RepeatedRequestIdException e){ + System.out.println("RepeatedRequestIdException. Msg: "+e.getMessage()); + } + + try{ + // Holding this thread while we get update notifications + synchronized (this){ + wait(); + } + }catch(InterruptedException e){ + System.out.println("InterruptedException. Msg: "+e.getMessage()); + } + } + + @Test + /** + * Test for GetAccountByName Handler. + * + * Request for a valid account name by name (Need to setup the ACCOUNT_NAME env with desired + * account name) + * + */ + public void testGetAccountByNameRequest(){ + nodeConnection = NodeConnection.getInstance(); + nodeConnection.addNodeUrl(NODE_URL_1); + nodeConnection.connect("", "", false, mErrorListener); + + System.out.println("Adding GetAccountByName here"); + try{ + nodeConnection.addRequestHandler(new GetAccountByName(ACCOUNT_NAME, false, new WitnessResponseListener(){ + @Override + public void onSuccess(WitnessResponse response) { + System.out.println("GetAccountByName.onSuccess"); + } + + @Override + public void onError(BaseResponse.Error error) { + System.out.println("GetAccountByName.onError. Msg: "+ error.message); + } + })); + }catch(RepeatedRequestIdException e){ + System.out.println("RepeatedRequestIdException. Msg: "+e.getMessage()); + } + + try{ + // Holding this thread while we get update notifications + synchronized (this){ + wait(); + } + }catch(InterruptedException e){ + System.out.println("InterruptedException. Msg: "+e.getMessage()); + } + } + + /** + * Test for GetAccounts Handler. + * + * Request for a valid account name by name (Need to setup the ACCOUNT_NAME env with desired + * account name) + * + */ + public void testGetAccountsRequest(){ + nodeConnection = NodeConnection.getInstance(); + nodeConnection.addNodeUrl(NODE_URL_1); + + ArrayList accountList = new ArrayList(){{ + add(new UserAccount(ACCOUNT_ID_1)); + add(new UserAccount(ACCOUNT_ID_2)); + }}; + + nodeConnection.connect("", "", false, mErrorListener); + + System.out.println("Adding GetAccounts for one Account ID."); + try{ + nodeConnection.addRequestHandler(new GetAccounts(ACCOUNT_ID_1, false, new WitnessResponseListener(){ + @Override + public void onSuccess(WitnessResponse response) { + System.out.println("GetAccounts.onSuccess"); + } + + @Override + public void onError(BaseResponse.Error error) { + System.out.println("GetAccounts.onError. Msg: "+ error.message); + } + })); + }catch(RepeatedRequestIdException e){ + System.out.println("RepeatedRequestIdException. Msg: "+e.getMessage()); + } + + System.out.println("Adding GetAccounts for a list of Account IDs."); + try{ + nodeConnection.addRequestHandler(new GetAccounts(accountList, false, new WitnessResponseListener(){ + @Override + public void onSuccess(WitnessResponse response) { + System.out.println("GetAccounts.onSuccess"); + } + + @Override + public void onError(BaseResponse.Error error) { + System.out.println("GetAccounts.onError. Msg: "+ error.message); + } + })); + }catch(RepeatedRequestIdException e){ + System.out.println("RepeatedRequestIdException. Msg: "+e.getMessage()); + } + + + try{ + // Holding this thread while we get update notifications + synchronized (this){ + wait(); + } + }catch(InterruptedException e){ + System.out.println("InterruptedException. Msg: "+e.getMessage()); + } + } + + /** + * Test for GetAllAssetHolders Handler. + * + */ + @Test + public void testGetAllAssetHoldersRequest(){ + nodeConnection = NodeConnection.getInstance(); + nodeConnection.addNodeUrl(NODE_URL_1); + nodeConnection.connect("", "", false, mErrorListener); + + System.out.println("Adding GetAllAssetHolders request"); + try{ + nodeConnection.addRequestHandler(new GetAllAssetHolders(false, new WitnessResponseListener(){ + @Override + public void onSuccess(WitnessResponse response) { + System.out.println("GetAllAssetHolders.onSuccess"); + } + + @Override + public void onError(BaseResponse.Error error) { + System.out.println("GetAllAssetHolders.onError. Msg: "+ error.message); + } + })); + }catch(RepeatedRequestIdException e){ + System.out.println("RepeatedRequestIdException. Msg: "+e.getMessage()); + } + + try{ + // Holding this thread while we get update notifications + synchronized (this){ + wait(); + } + }catch(InterruptedException e){ + System.out.println("InterruptedException. Msg: "+e.getMessage()); + } + } + + /** + * Test for GetBlockHeader Handler. + * + * Request for a valid account block header (Need to setup the BlOCK_TEST_NUMBER env with desired + * block height) + */ + @Test + public void testGetBlockHeaderRequest(){ + nodeConnection = NodeConnection.getInstance(); + nodeConnection.addNodeUrl(NODE_URL_1); + nodeConnection.connect("", "", false, mErrorListener); + + + System.out.println("Adding GetBlockHeader request"); + try{ + nodeConnection.addRequestHandler(new GetBlockHeader(BlOCK_TEST_NUMBER,false, new WitnessResponseListener(){ + @Override + public void onSuccess(WitnessResponse response) { + System.out.println("GetBlockHeader.onSuccess"); + } + + @Override + public void onError(BaseResponse.Error error) { + System.out.println("GetBlockHeader.onError. Msg: "+ error.message); + } + })); + }catch(RepeatedRequestIdException e){ + System.out.println("RepeatedRequestIdException. Msg: "+e.getMessage()); + } + + + try{ + // Holding this thread while we get update notifications + synchronized (this){ + wait(); + } + }catch(InterruptedException e){ + System.out.println("InterruptedException. Msg: "+e.getMessage()); + } + } + + /** + * Test for GetKeyReferences Handler. + * + */ + @Test + public void testGetKeyReferencesRequest(){ + nodeConnection = NodeConnection.getInstance(); + nodeConnection.addNodeUrl(NODE_URL_1); + nodeConnection.connect("", "", false, mErrorListener); + + Address address1 = null; + Address address2 = null; + Address address3 = null; + try { + address1 = new Address("BTS8RiFgs8HkcVPVobHLKEv6yL3iXcC9SWjbPVS15dDAXLG9GYhnY"); + address2 = new Address("BTS8RiFgs8HkcVPVobHLKEv6yL3iXcC9SWjbPVS15dDAXLG9GYhnY"); + address3 = new Address("BTS8RiFgs8HkcVPVobHLKEv6yL3iXcC9SWjbPVS15dDAXLG9GYp00"); + } catch (MalformedAddressException e) { + System.out.println("MalformedAddressException. Msg: " + e.getMessage()); + } + + ArrayList
addresses = new ArrayList<>(); + addresses.add(address1); + addresses.add(address2); + addresses.add(address3); + + // Test with the one address constructor + System.out.println("Adding GetKeyReferences one address request (One address)"); + try{ + nodeConnection.addRequestHandler(new GetKeyReferences(address1, false, new WitnessResponseListener(){ + @Override + public void onSuccess(WitnessResponse response) { + System.out.println("GetKeyReferences.onSuccess"); + } + + @Override + public void onError(BaseResponse.Error error) { + System.out.println("GetKeyReferences.onError. Msg: "+ error.message); + } + })); + }catch(RepeatedRequestIdException e){ + System.out.println("RepeatedRequestIdException. Msg: "+e.getMessage()); + } + + // Test with the list of addresses constructor + System.out.println("Adding GetKeyReferences address request (List of Addresses)"); + try{ + nodeConnection.addRequestHandler(new GetKeyReferences(addresses, false, new WitnessResponseListener(){ + @Override + public void onSuccess(WitnessResponse response) { + System.out.println("GetKeyReferences.onSuccess"); + } + + @Override + public void onError(BaseResponse.Error error) { + System.out.println("GetKeyReferences.onError. Msg: "+ error.message); + } + })); + }catch(RepeatedRequestIdException e){ + System.out.println("RepeatedRequestIdException. Msg: "+e.getMessage()); + } + + try{ + // Holding this thread while we get update notifications + synchronized (this){ + wait(); + } + }catch(InterruptedException e){ + System.out.println("InterruptedException. Msg: "+e.getMessage()); + } + } + + /** + * Test for GetLimitOrders Handler. + * + * Request for a limit orders between two assets + */ + @Test + public void testGetLimitOrdersRequest(){ + nodeConnection = NodeConnection.getInstance(); + nodeConnection.addNodeUrl(NODE_URL_1); + nodeConnection.connect("", "", false, mErrorListener); + + String asset_sold_id = BLOCKPAY.getBitassetId(); + String asset_purchased_id = BTS.getBitassetId(); + int limit = 10; + + System.out.println("Adding GetLimitOrders request"); + try{ + nodeConnection.addRequestHandler(new GetLimitOrders(asset_sold_id, asset_purchased_id, limit, true, new WitnessResponseListener(){ + @Override + public void onSuccess(WitnessResponse response) { + System.out.println("GetLimitOrders.onSuccess"); + } + + @Override + public void onError(BaseResponse.Error error) { + System.out.println("GetLimitOrders.onError. Msg: "+ error.message); + } + })); + }catch(RepeatedRequestIdException e){ + System.out.println("RepeatedRequestIdException. Msg: "+e.getMessage()); + } + + + try{ + // Holding this thread while we get update notifications + synchronized (this){ + wait(); + } + }catch(InterruptedException e){ + System.out.println("InterruptedException. Msg: "+e.getMessage()); + } + } + + + /** + * Test for GetMarketHistory Handler. + * + * Request for market history of a base asset compared to a quote asset. + */ + @Test + public void testGetMarketHistoryRequest(){ + nodeConnection = NodeConnection.getInstance(); + nodeConnection.addNodeUrl(NODE_URL_1); + nodeConnection.connect("", "", false, mErrorListener); + + Asset asset_base = BLOCKPAY; + Asset asset_quote = BTS; + //the time interval of the bucket in seconds + long bucket = 3600; + + //datetime of of the most recent operation to retrieve + Date start = new Date(); + //datetime of the the earliest operation to retrieve + //07/16/2017 1:33pm + Date end = new Date(1500211991); + + System.out.println("Adding GetMarketHistory request"); + try{ + nodeConnection.addRequestHandler(new GetMarketHistory(asset_base, asset_quote, bucket, start, end, true, new WitnessResponseListener(){ + @Override + public void onSuccess(WitnessResponse response) { + System.out.println("GetMarketHistory.onSuccess"); + } + + @Override + public void onError(BaseResponse.Error error) { + System.out.println("GetMarketHistory.onError. Msg: "+ error.message); + } + })); + }catch(RepeatedRequestIdException e){ + System.out.println("RepeatedRequestIdException. Msg: "+e.getMessage()); + } + + + try{ + // Holding this thread while we get update notifications + synchronized (this){ + wait(); + } + }catch(InterruptedException e){ + System.out.println("InterruptedException. Msg: "+e.getMessage()); + } + } + + /** + * Test for GetObjects Handler. + * + * Request for a limit orders between two assets + */ + @Test + public void testGetObjectsRequest(){ + nodeConnection = NodeConnection.getInstance(); + nodeConnection.addNodeUrl(NODE_URL_1); + nodeConnection.connect("", "", false, mErrorListener); + + String asset_sold_id = BLOCKPAY.getBitassetId(); + String asset_purchased_id = BTS.getBitassetId(); + int limit = 10; + + ArrayList objectList = new ArrayList(){{ + add(BLOCKPAY.getBitassetId()); + add(BTS.getBitassetId()); + add(BITEURO.getBitassetId()); + }}; + + System.out.println("Adding GetObjects request"); + try{ + nodeConnection.addRequestHandler(new GetObjects(objectList, true, new WitnessResponseListener(){ + @Override + public void onSuccess(WitnessResponse response) { + System.out.println("GetObjects.onSuccess"); + } + + @Override + public void onError(BaseResponse.Error error) { + System.out.println("GetObjects.onError. Msg: "+ error.message); + } + })); + }catch(RepeatedRequestIdException e){ + System.out.println("RepeatedRequestIdException. Msg: "+e.getMessage()); + } + + Timer timer = new Timer(); + timer.schedule(releaseTask, 30000); + + try{ + // Holding this thread while we get update notifications + synchronized (this){ + wait(); + } + }catch(InterruptedException e){ + System.out.println("InterruptedException. Msg: "+e.getMessage()); + } + } + + /** + * Test for GetRelativeAccount Handler. + * + * Request for the transaction history of a user account. + */ + @Test + public void testGetRelativeAccountHistoryRequest(){ + nodeConnection = NodeConnection.getInstance(); + nodeConnection.addNodeUrl(NODE_URL_1); + nodeConnection.connect("", "", false, mErrorListener); + + UserAccount userAccount = new UserAccount(ACCOUNT_ID_1); + + //Sequence number of earliest operation + int stop = 10; + int limit = 50; + //Sequence number of the most recent operation to retrieve + int start = 50; + + System.out.println("Adding GetRelativeAccountHistory request"); + try{ + nodeConnection.addRequestHandler(new GetRelativeAccountHistory(userAccount, stop, limit, start, true, new WitnessResponseListener(){ + @Override + public void onSuccess(WitnessResponse response) { + System.out.println("GetRelativeAccountHistory.onSuccess"); + } + + @Override + public void onError(BaseResponse.Error error) { + System.out.println("GetRelativeAccountHistory.onError. Msg: "+ error.message); + } + })); + }catch(RepeatedRequestIdException e){ + System.out.println("RepeatedRequestIdException. Msg: "+e.getMessage()); + } + + + try{ + // Holding this thread while we get update notifications + synchronized (this){ + wait(); + } + }catch(InterruptedException e){ + System.out.println("InterruptedException. Msg: "+e.getMessage()); + } + } + + /** + * Test for GetRequiredFees Handler. + * + */ + @Test + public void testGetRequiredFeesRequest(){ + nodeConnection = NodeConnection.getInstance(); + nodeConnection.addNodeUrl(NODE_URL_1); + nodeConnection.connect("", "", false, mErrorListener); + + UserAccount userAccount_from = new UserAccount(ACCOUNT_ID_1); + UserAccount userAccount_to = new UserAccount(ACCOUNT_ID_2); + + //Test with 2 BTS + Asset testAsset = new Asset("1.3.0"); + AssetAmount assetAmountTest = new AssetAmount(UnsignedLong.valueOf(200000), testAsset); + AssetAmount feeAmountTest = new AssetAmount(UnsignedLong.valueOf(100000), testAsset); + + TransferOperation transferOperation = new TransferOperation(userAccount_from, userAccount_to, assetAmountTest, feeAmountTest); + + ArrayList operations = new ArrayList<>(); + operations.add(transferOperation); + + System.out.println("Adding GetBlockHeader request"); + try{ + nodeConnection.addRequestHandler(new GetRequiredFees(operations, testAsset, true, new WitnessResponseListener(){ + @Override + public void onSuccess(WitnessResponse response) { + System.out.println("GetRequiredFees.onSuccess"); + } + + @Override + public void onError(BaseResponse.Error error) { + System.out.println("GetRequiredFees.onError. Msg: "+ error.message); + } + })); + }catch(RepeatedRequestIdException e){ + System.out.println("RepeatedRequestIdException. Msg: "+e.getMessage()); + } + + + try{ + // Holding this thread while we get update notifications + synchronized (this){ + wait(); + } + }catch(InterruptedException e){ + System.out.println("InterruptedException. Msg: "+e.getMessage()); + } + } + + /** + * Test for GetTradeHistory Handler. + * + */ + @Test + public void testGetTradeHistoryRequest(){ + nodeConnection = NodeConnection.getInstance(); + nodeConnection.addNodeUrl(NODE_URL_1); + nodeConnection.connect("", "", false, mErrorListener); + + UserAccount userAccount_from = new UserAccount(ACCOUNT_ID_1); + UserAccount userAccount_to = new UserAccount(ACCOUNT_ID_2); + + + String asset_sold_id = BLOCKPAY.getBitassetId(); + String asset_purchased_id = BTS.getBitassetId(); + int limit = 10; + + System.out.println("Adding GetTradeHistory request"); + try{ + nodeConnection.addRequestHandler(new GetTradeHistory(asset_sold_id, asset_purchased_id, "", "", limit, true, new WitnessResponseListener(){ + @Override + public void onSuccess(WitnessResponse response) { + System.out.println("GetTradeHistory.onSuccess"); + } + + @Override + public void onError(BaseResponse.Error error) { + System.out.println("GetTradeHistory.onError. Msg: "+ error.message); + } + })); + }catch(RepeatedRequestIdException e){ + System.out.println("RepeatedRequestIdException. Msg: "+e.getMessage()); + } + + + try{ + // Holding this thread while we get update notifications + synchronized (this){ + wait(); + } + }catch(InterruptedException e){ + System.out.println("InterruptedException. Msg: "+e.getMessage()); + } + } + + /** + * Test for ListAsset Handler. + *' + * Request the 'list_assets' API call to the witness node + */ + @Test + public void testListAssetRequest(){ + nodeConnection = NodeConnection.getInstance(); + nodeConnection.addNodeUrl(NODE_URL_1); + nodeConnection.connect("", "", false, mErrorListener); + + UserAccount userAccount_from = new UserAccount(ACCOUNT_ID_1); + UserAccount userAccount_to = new UserAccount(ACCOUNT_ID_2); + + + String asset_symbol = BLOCKPAY.getSymbol(); + int limit = 10; + + System.out.println("Adding ListAssets request"); + try{ + nodeConnection.addRequestHandler(new ListAssets(asset_symbol, limit, true, new WitnessResponseListener(){ + @Override + public void onSuccess(WitnessResponse response) { + System.out.println("ListAssets.onSuccess"); + } + + @Override + public void onError(BaseResponse.Error error) { + System.out.println("ListAssets.onError. Msg: "+ error.message); + } + })); + }catch(RepeatedRequestIdException e){ + System.out.println("RepeatedRequestIdException. Msg: "+e.getMessage()); + } + + + try{ + // Holding this thread while we get update notifications + synchronized (this){ + wait(); + } + }catch(InterruptedException e){ + System.out.println("InterruptedException. Msg: "+e.getMessage()); + } + } + + /** + * Test for GetRelativeAccount Handler. + * + * Request for the transaction history of a user account. + */ + @Test + public void testGetLookupAccountsRequest(){ + nodeConnection = NodeConnection.getInstance(); + nodeConnection.addNodeUrl(NODE_URL_1); + nodeConnection.connect("", "", false, mErrorListener); + + UserAccount userAccount = new UserAccount(ACCOUNT_ID_1); + UserAccount userAccount_2 = new UserAccount(ACCOUNT_ID_2); + + int maxAccounts = 10; + + System.out.println("Adding LookupAccounts request"); + try{ + nodeConnection.addRequestHandler(new LookupAccounts(userAccount.getName(), true, new WitnessResponseListener(){ + @Override + public void onSuccess(WitnessResponse response) { + System.out.println("LookupAccounts.onSuccess"); + } + + @Override + public void onError(BaseResponse.Error error) { + System.out.println("LookupAccounts.onError. Msg: "+ error.message); + } + })); + }catch(RepeatedRequestIdException e){ + System.out.println("RepeatedRequestIdException. Msg: "+e.getMessage()); + } + + System.out.println("Adding LookupAccounts request . maxAccounts = "+maxAccounts); + try{ + nodeConnection.addRequestHandler(new LookupAccounts(userAccount_2.getName(), maxAccounts, true, new WitnessResponseListener(){ + @Override + public void onSuccess(WitnessResponse response) { + System.out.println("LookupAccounts.onSuccess"); + } + + @Override + public void onError(BaseResponse.Error error) { + System.out.println("LookupAccounts.onError. Msg: "+ error.message); + } + })); + }catch(RepeatedRequestIdException e){ + System.out.println("RepeatedRequestIdException. Msg: "+e.getMessage()); + } + + try{ + // Holding this thread while we get update notifications + synchronized (this){ + wait(); + } + }catch(InterruptedException e){ + System.out.println("InterruptedException. Msg: "+e.getMessage()); + } + } + + /** + * Test for LookupAssetSymbols Handler. + * + * Request for the assets corresponding to the provided symbols or IDs. + */ + @Test + public void testLookupAssetSymbolsRequest(){ + nodeConnection = NodeConnection.getInstance(); + nodeConnection.addNodeUrl(NODE_URL_1); + nodeConnection.connect("", "", false, mErrorListener); + + + ArrayList assetList = new ArrayList(){{ + add(BLOCKPAY); + add(BTS); + add(BITEURO); + }}; + + System.out.println("Adding LookupAssetSymbols request"); + try{ + nodeConnection.addRequestHandler(new LookupAssetSymbols(assetList, true, new WitnessResponseListener(){ + @Override + public void onSuccess(WitnessResponse response) { + System.out.println("LookupAssetSymbols.onSuccess"); + } + + @Override + public void onError(BaseResponse.Error error) { + System.out.println("LookupAssetSymbols.onError. Msg: "+ error.message); + } + })); + }catch(RepeatedRequestIdException e){ + System.out.println("RepeatedRequestIdException. Msg: "+e.getMessage()); + } + + try{ + // Holding this thread while we get update notifications + synchronized (this){ + wait(); + } + }catch(InterruptedException e){ + System.out.println("InterruptedException. Msg: "+e.getMessage()); + } + } + + /** + * Test for TransactionBroadcastSequence Handler. + * + */ + @Test + public void testTransactionBroadcastSequenceRequest(){ + nodeConnection = NodeConnection.getInstance(); + nodeConnection.addNodeUrl(NODE_URL_1); + nodeConnection.connect("", "", false, mErrorListener); + + + ArrayList assetList = new ArrayList(){{ + add(BLOCKPAY); + add(BTS); + add(BITEURO); + }}; + + ECKey privateKey = new BrainKey(TEST_ACCOUNT_BRAIN_KEY, 0).getPrivateKey(); + + UserAccount userAccount = new UserAccount(ACCOUNT_ID_1); + UserAccount userAccount_2 = new UserAccount(ACCOUNT_ID_2); + + TransferOperation transferOperation1 = new TransferOperationBuilder() + .setTransferAmount(new AssetAmount(UnsignedLong.valueOf(1), BTS)) + .setSource(userAccount) + .setDestination(userAccount_2) + .setFee(new AssetAmount(UnsignedLong.valueOf(264174), BTS)) + .build(); + + + ArrayList operationList = new ArrayList<>(); + operationList.add(transferOperation1); + + try{ + Transaction transaction = new Transaction(privateKey, null, operationList); + + SSLContext context = null; + context = NaiveSSLContext.getInstance("TLS"); + WebSocketFactory factory = new WebSocketFactory(); + + // Set the custom SSL context. + factory.setSSLContext(context); + + WebSocket mWebSocket = factory.createSocket(NODE_URL_1); + + mWebSocket.addListener(new TransactionBroadcastSequence(transaction, BTS, new WitnessResponseListener(){ + @Override + public void onSuccess(WitnessResponse response) { + System.out.println("TransactionBroadcastSequence.onSuccess"); + } + + @Override + public void onError(BaseResponse.Error error) { + System.out.println("TransactionBroadcastSequence.onError. Msg: "+ error.message); + } + })); + mWebSocket.connect(); + + try{ + // Holding this thread while we get update notifications + synchronized (this){ + wait(); + } + }catch(InterruptedException e){ + System.out.println("InterruptedException. Msg: "+e.getMessage()); + } + + }catch(NoSuchAlgorithmException e){ + System.out.println("NoSuchAlgoritmException. Msg: " + e.getMessage()); + } catch (IOException e) { + System.out.println("IOException. Msg: " + e.getMessage()); + } catch (WebSocketException e) { + System.out.println("WebSocketException. Msg: " + e.getMessage()); + } + } + + private WitnessResponseListener mErrorListener = new WitnessResponseListener() { @Override diff --git a/graphenej/src/test/java/de/bitsharesmunich/graphenej/objects/MemoTest.java b/graphenej/src/test/java/de/bitsharesmunich/graphenej/objects/MemoTest.java index 33cd015..cdc7101 100644 --- a/graphenej/src/test/java/de/bitsharesmunich/graphenej/objects/MemoTest.java +++ b/graphenej/src/test/java/de/bitsharesmunich/graphenej/objects/MemoTest.java @@ -3,6 +3,7 @@ package de.bitsharesmunich.graphenej.objects; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import de.bitsharesmunich.graphenej.Address; +import de.bitsharesmunich.graphenej.PublicKey; import de.bitsharesmunich.graphenej.Util; import de.bitsharesmunich.graphenej.errors.ChecksumException; import org.bitcoinj.core.DumpedPrivateKey; @@ -13,7 +14,7 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; /** - * Created by nelson on 12/19/16. + * Unit Tests for Memo Related Classes. */ public class MemoTest { @@ -24,8 +25,13 @@ public class MemoTest { private Address destinationAddress; private long nonce; + private String sourceWIF = System.getenv("SOURCE_WIF"); + private String destinationWIF = System.getenv("DESTINATION_WIF"); + private byte[] memoEncryptedEnvMessage = Util.hexToBytes(System.getenv("MEMO_MESSAGE")); + //private String sourceWIF = "5J96pne45qWM1WpektoeazN6k9Mt93jQ7LyueRxFfEMTiy6yxjM"; + //private String destinationWIF = "5HuGQT8qwHScBgD4XsGbQUmXQF18MrbzxaQDiGGXFNRrCtqgT5Q"; private String shortMessage = "test"; - private String longerMessage = "testing now longer string!!"; + private String longerMessage = "testing now longer string with some special charaters é ç o ú á í Í mMno!!"; private byte[] shortEncryptedMessage = Util.hexToBytes("4c81c2db6ebc61e3f9e0ead65c0559dd"); private byte[] longerEncryptedMessage = Util.hexToBytes("1f8a08f1ff53dcefd48eeb052d26fba425f2a917f508ce61fc3d5696b10efa17"); @@ -34,12 +40,17 @@ public class MemoTest { @Before public void setUp() throws Exception { - sourcePrivate = DumpedPrivateKey.fromBase58(null, "5J96pne45qWM1WpektoeazN6k9Mt93jQ7LyueRxFfEMTiy6yxjM").getKey(); - destinationPrivate = DumpedPrivateKey.fromBase58(null, "5HuGQT8qwHScBgD4XsGbQUmXQF18MrbzxaQDiGGXFNRrCtqgT5Q").getKey(); + //Source + sourcePrivate = DumpedPrivateKey.fromBase58(null, sourceWIF).getKey(); + PublicKey publicKey = new PublicKey(ECKey.fromPublicOnly(sourcePrivate.getPubKey())); + sourceAddress = new Address(publicKey.getKey()); - sourceAddress = new Address("BTS8RiFgs8HkcVPVobHLKEv6yL3iXcC9SWjbPVS15dDAXLG9GYhnY"); - destinationAddress = new Address("BTS8ADjGaswhfFoxMGxqCdBtzhTBJsrGadCLoc9Ey5AGc8eoVZ5bV"); + //Destination + destinationPrivate = DumpedPrivateKey.fromBase58(null, destinationWIF).getKey(); + publicKey = new PublicKey(ECKey.fromPublicOnly(destinationPrivate.getPubKey())); + destinationAddress = new Address(publicKey.getKey()); + //memo.getNonce() nonce = 5; } @@ -52,11 +63,45 @@ public class MemoTest { assertArrayEquals("Testing with longer message and nonce 1", encryptedLong, longerEncryptedMessage); } + @Test + public void shouldDecryptEnvMessage(){ + try { + String decrypted = Memo.decryptMessage(destinationPrivate, sourceAddress, nonce, memoEncryptedEnvMessage); + System.out.println("Short Decrypted Message: " + decrypted); + assertEquals("Decrypted message must be equal to original", decrypted, shortMessage); + } catch (ChecksumException e) { + e.printStackTrace(); + } + } + + @Test + public void shouldDecryptShortMessage(){ + try { + String decrypted = Memo.decryptMessage(destinationPrivate, sourceAddress, nonce, shortEncryptedMessage); + System.out.println("Short Decrypted Message: " + decrypted); + assertEquals("Decrypted message must be equal to original", decrypted, shortMessage); + } catch (ChecksumException e) { + e.printStackTrace(); + } + } + + @Test + public void shouldDecryptLongerMessage(){ + try{ + String longDecrypted = Memo.decryptMessage(destinationPrivate, sourceAddress, nonce, longerEncryptedMessage); + System.out.println("Long Decrypted Message: " + longDecrypted); + assertEquals("The longer message must be equal to the original", longerMessage, longDecrypted); + } catch (ChecksumException e) { + e.printStackTrace(); + } + } + @Test public void shouldEncryptAndDecryptShortMessage(){ try { byte[] encrypted = Memo.encryptMessage(sourcePrivate, destinationAddress, nonce, shortMessage); - String decrypted = decrypted = Memo.decryptMessage(destinationPrivate, sourceAddress, nonce, encrypted); + String decrypted = Memo.decryptMessage(destinationPrivate, sourceAddress, nonce, encrypted); + System.out.println("Short Decrypted Message: " + decrypted); assertEquals("Decrypted message must be equal to original", decrypted, shortMessage); } catch (ChecksumException e) { e.printStackTrace(); @@ -68,6 +113,7 @@ public class MemoTest { try{ byte[] longEncrypted = Memo.encryptMessage(sourcePrivate, destinationAddress, nonce, longerMessage); String longDecrypted = Memo.decryptMessage(destinationPrivate, sourceAddress, nonce, longEncrypted); + System.out.println("Long Decrypted Message: " + longDecrypted); assertEquals("The longer message must be equal to the original", longerMessage, longDecrypted); } catch (ChecksumException e) { e.printStackTrace();