first commit

This commit is contained in:
davassi 2016-10-06 17:37:28 +02:00
commit baa9f32e9b
23 changed files with 1162 additions and 0 deletions

12
.gitignore vendored Normal file
View File

@ -0,0 +1,12 @@
/target*
/.classpath
/.project
/.settings
/tomcat.*
/.idea
/*.iml
.classpath
.project
*.class
target/*

81
README.md Normal file
View File

@ -0,0 +1,81 @@
##Introduction
The JOTA library is a simple Java8 wrapper around IOTA Node's JSON-REST HTTP interface.
It allows to connect easily using java directly to a local or a remote [[IOTA]](https://iota.readme.io/docs/syncing-to-the-network) node.
* **Latest release:** 0.0.1 Snapshot
* **Compatibility:** IOTA IRI v1.0.6
* **API coverage:** 20 of 20 commands fully implemented
* **License:** Apache License 2.0
* **Readme updated:** 2016-02-17 10:16:43 (UTC)
A list of all *IOTA* JSON-REST API commands currently supported by jota wrapper can be found in the `Commands` enum (see [here](IotaAPICommands.java) for more details).
JOTA java wrapper is being designed to be thread-safe and simplest as possible in order to be easily mantainable, accordingly with the ongoing natural evolution of IOTA'api.
All the boilerplate code for connecting to the node rest interface has been gotten rid off by using Retrofit.
##Technologies & dependencies
The JOTA library has been designed to be used exclusively with Java 8+.
Core dependencies:
* Retrofit Client 2.1.0 [[link]](https://square.github.io/retrofit/)
* Gson JSON Processor :
* Annotations 2.5.0 (`jackson-annotations`) [[link]](https://github.com/FasterXML/jackson-annotations)
* Databind 2.5.0 (`jackson-databind`) [[link]](https://github.com/FasterXML/jackson-databind)
* Lombok 1.16.2 [[link]](https://github.com/rzwitserloot/lombok)
Other dependencies:
* Simple Logging Facade for Java 1.7.21 [[link]](http://www.slf4j.org/)
* Apache Commons Lang 3.3.2 [[link]](http://commons.apache.org/proper/commons-lang/)
##Getting started <a name="getting-started"></a>
Connect to your local node with the default settings is quite straitforward: it requires only 2 lines of code. For example, in order to fetch the Node Info:
IotaApiProxy api = new IotaApiProxy.Builder.build();
GetNodeInfoResponse response = api.getNodeInfo();
of if you need to connect to a remote node on https:
IotaApiProxy api = new IotaApiProxy.Builder
.protocol("https")
.nodeAddress("somewhere_remotely")
.port(54321)
.build();
GetNodeInfoResponse response = api.getNodeInfo();
Next, modify your `pom.xml` to include `btcd-cli4j-core` as a dependency:
<dependency>
<groupId>com.neemre.btcd-cli4j</groupId>
<artifactId>btcd-cli4j-core</artifactId>
<version>0.5.1</version>
</dependency>
In order to communicate with *IOTA node*, JOTA needs to be aware of your node's exact configuration. The easiest way of providing this information is via a `node_config.properties` file, for example:
node.bitcoind.rpc.protocol = http
node.bitcoind.rpc.host = 127.0.0.1
node.bitcoind.rpc.port = 8332
node.bitcoind.rpc.user = falcon-pc
node.bitcoind.rpc.password = 3F4DN9QGqWrB4DCdfYMXp8xdDYL4HDFzpaS9r76DbNhw
node.bitcoind.http.auth_scheme = Basic
That's it!
##Examples
There's an extensive list of test coverages on the src/test/java package of the project that can be used as reference.
##Supporting the project
If JOTA has been useful to you and you feel like contributing, consider posting a [bug report](https://github.com/priiduneemre/btcd-cli4j/issues) or a [pull request](https://github.com/priiduneemre/btcd-cli4j/pulls). Alternatively, donations are very welcome too!
* Bitcoin: `12CfEQ7RAEwpS82jFZg1HgjeH8obbpMeL5`
* IOTA: ``
* Ethereum: ``

5
node_config.properties Normal file
View File

@ -0,0 +1,5 @@
iota.node.protocol=http
iota.node.host=127.0.0.1
iota.node.port=14265

86
pom.xml Normal file
View File

@ -0,0 +1,86 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.iota</groupId>
<artifactId>jota</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>JOTA</name>
<description>JOTA library is a simple Java8 wrapper around IOTA Node's JSON-REST HTTP interface.</description>
<properties>
<java-version>1.8</java-version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/com.squareup.retrofit2/retrofit -->
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>retrofit</artifactId>
<version>2.1.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.squareup.retrofit2/converter-gson -->
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>converter-gson</artifactId>
<version>2.1.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.3.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
<!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.7</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>${java-version}</source>
<target>${java-version}</target>
<testSource>${java-version}</testSource>
<testTarget>${java-version}</testTarget>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

View File

@ -0,0 +1,45 @@
package jota;
/**
* IOTA's node command list
*/
public enum IotaAPICommands {
GET_NODE_INFO("getNodeInfo", 0),
GET_MILESTONE("getMilestone", 0),
GET_NEIGHBORS("getNeighbors", 0),
GET_TIPS("getTips",0),
GET_TRANSFER("getTransfers", 0), //
FIND_TRANSACTIONS("findTransactions", 0),
GET_INCLUSIONS_STATES("getInclusionStates", 0),
GET_BUNDLE("getBundle", 0),
GET_TRYTES("getTrytes", 0),
ANALYZE_TRANSACTIONS("analyzeTransactions", 0),
GET_NEW_ADDRESS("getNewAddress", 0),
PREPARE_TRANSFERS("prepareTransfers", 0),
GET_TRANSACTIONS_TO_APPROVE("getTransactionsToApprove", 0),
ATTACH_TO_TANGLE("attachToTangle", 0),
INTERRUPT_ATTACHING_TO_TANGLE("interruptAttachingToTangle", 0),
PUSH_TRANSACTIONS("pushTransactions", 0),
STORE_TRANSACTIONS("storeTransactions", 0),
TRANSFER("transfer", 0),
REPLAY_TRANSFER("replayTransfer",0),
PULL_TRANSACTIONS("pullTransactions", 0);
private IotaAPICommands(String command, int params) {
this.command = command;
this.params = params;
}
private String command;
private int params;
public String command() {
return command;
}
public int params() {
return params;
}
}

View File

@ -0,0 +1,226 @@
package jota;
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Collection;
import java.util.Optional;
import java.util.Properties;
import jota.dto.request.*;
import jota.dto.response.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import retrofit2.Call;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
/**
* IotaAPIProxy Builder. Usage:
*
* IotaApiProxy api = IotaApiProxy.Builder
* .protocol("http")
* .nodeAddress("localhost")
* .port(12345)
* .build();
*
* GetNodeInfoResponse response = api.getNodeInfo();
*
* @author davassi
*/
public class IotaAPIProxy {
private static final Logger log = LoggerFactory.getLogger(IotaAPIProxy.class);
private IotaAPIService service;
private IotaAPIProxy(final Builder builder) {
protocol = builder.protocol;
host = builder.host;
port = builder.port;
postConstruct();
}
private String protocol, host, port;
private void postConstruct() {
final String nodeUrl = protocol + "://" + host + ":" + port;
final Retrofit retrofit = new Retrofit.Builder()
.baseUrl(nodeUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
service = retrofit.create(IotaAPIService.class);
log.debug("Jota-API Java proxy pointing to node url: '{}'", nodeUrl);
}
public GetNodeInfoResponse getNodeInfo() {
final Call<GetNodeInfoResponse> res = service.getNodeInfo(IotaCommandRequest.createNodeInfoRequest());
return wrapCheckedException(res).body();
}
public GetMilestoneResponse getMilestone(Integer index) {
final Call<GetMilestoneResponse> res = service.getMilestone(IotaGetMilestoneRequest.createMilestoneRequest(index));
return wrapCheckedException(res).body();
}
public GetNeighborsResponse getNeighbors() {
final Call<GetNeighborsResponse> res = service.getNeighbors(IotaCommandRequest.createGetNeighborsRequest());
return wrapCheckedException(res).body();
}
public GetTipsResponse getTips() {
final Call<GetTipsResponse> res = service.getTips(IotaCommandRequest.createGetTipsRequest());
return wrapCheckedException(res).body();
}
public GetTransfersResponse getTransfers(String seed, Integer securityLevel) {
final Call<GetTransfersResponse> res = service.getTransfers(IotaGetTransferRequest.createGetTransferRequest(seed, securityLevel));
return wrapCheckedException(res).body();
}
public FindTransactionResponse findTransactions(String [] addresses, String [] digests, String [] approvees, String [] bundles ) {
final IotaFindTransactionsRequest findTransRequest = IotaFindTransactionsRequest
.createFindTransactionRequest()
.byAddresses(addresses)
.byDigests(digests)
.byApprovees(approvees)
.byBundles(bundles);
final Call<FindTransactionResponse> res = service.findTransactions(findTransRequest);
return wrapCheckedException(res).body();
}
public FindTransactionResponse findTransactionsByAddresses(String [] addresses) {
return findTransactions(addresses, null, null, null);
}
public FindTransactionResponse findTransactionsByBundles(String [] bundles) {
return findTransactions(null, null, null, bundles);
}
public FindTransactionResponse findTransactionsByApprovees(String [] approvees) {
return findTransactions(null, null, approvees, null);
}
public FindTransactionResponse findTransactionsByDigests(String [] digests) {
return findTransactions(null, digests, null, null);
}
public GetInclusionStateResponse getInclusionStates(String[] transactions, String[] tips) {
final Call<GetInclusionStateResponse> res = service.getInclusionStates(IotaGetInclusionStateRequest
.createGetInclusionStateRequest(transactions, tips));
return wrapCheckedException(res).body();
}
public GetInclusionStateResponse getInclusionStates(Collection<String> transactions, Collection<String> tips) {
final Call<GetInclusionStateResponse> res = service.getInclusionStates(IotaGetInclusionStateRequest
.createGetInclusionStateRequest(transactions, tips));
return wrapCheckedException(res).body();
}
protected static <T> Response<T> wrapCheckedException(final Call<T> call) {
try {
final Response<T> res = call.execute();
if (res.code() == 400) {
throw new IllegalAccessError(res.errorBody().toString());
}
return res;
} catch (IOException e) {
log.error("Execution of the API call raised exception. IOTA Node not reachable?", e);
throw new IllegalStateException(e.getMessage());
}
}
private static final String env(String env, String def) {
return Optional.ofNullable(System.getenv(env)).orElseGet(() -> {
log.warn("Enviroment variable '{}' is not defined, and actual value has not been specified. "
+ "Rolling back to default value: '{}'", env, def);
return def;
});
}
public static class Builder {
String protocol, host, port;
public IotaAPIProxy build() {
if (protocol == null || host == null || port == null) {
// check properties files.
if (!checkPropertiesFiles()) {
// last resort: best effort on enviroment variable,
// before assigning default values.
checkEnviromentVariables();
}
}
return new IotaAPIProxy(this);
}
private boolean checkPropertiesFiles() {
try (BufferedReader reader = Files.newBufferedReader(Paths.get("node_config.properties"))) {
final Properties nodeConfig = new Properties();
nodeConfig.load(reader);
Optional.ofNullable(nodeConfig.getProperty("iota.node.protocol"))
.filter(v -> protocol == null)
.ifPresent(v -> protocol = v);
Optional.ofNullable(nodeConfig.getProperty("iota.node.host"))
.filter(v -> host == null)
.ifPresent(v -> host = v);
Optional.ofNullable(nodeConfig.getProperty("iota.node.port"))
.filter(v -> port == null)
.ifPresent(v -> port = v);
} catch (IOException e1) {
log.debug("node_config.properties not found. Rolling back for another solution...");
}
return (port != null && protocol != null && host != null);
}
private void checkEnviromentVariables() {
Optional.of(env("IOTA_NODE_PROTOCOL", "http"))
.filter(v -> protocol == null)
.ifPresent(v -> protocol = v);
Optional.ofNullable(env("IOTA_NODE_HOST", "localhost"))
.filter(v -> host == null)
.ifPresent(v -> host = v);
Optional.ofNullable(env("IOTA_NODE_PORT", "14265"))
.filter(v -> port == null)
.ifPresent(v -> port = v);
}
public Builder host(String host) {
this.host = host;
return this;
}
public Builder port(String port) {
this.port = port;
return this;
}
public Builder protocol(String protocol) {
this.protocol = protocol;
return this;
}
}
}

View File

@ -0,0 +1,180 @@
package jota;
import jota.dto.request.*;
import jota.dto.response.*;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.Headers;
import retrofit2.http.POST;
/**
* IOTA API Proxy Service definition using Retrofit2
*
* @author davassi
*/
public interface IotaAPIService {
public static final String CONTENT_TYPE_HEADER = "Content-Type: application/json";
public static final String USER_AGENT_HEADER = "User-Agent: JOTA-API wrapper";
/**
* Returns information about your node.
*
* curl http://localhost:14265 \ -X POST \ -H 'Content-Type:
* application/json' \ -d '{"command": "getNodeInfo"}'
*
* @return a {@code NodeInfoResponse} object, if succesfull.
*/
@Headers({ CONTENT_TYPE_HEADER, USER_AGENT_HEADER })
@POST("./")
Call<GetNodeInfoResponse> getNodeInfo(@Body IotaCommandRequest request);
/**
* Returns a milestone from a given index.
*
* curl http://localhost:14265 \ -X POST \ -H 'Content-Type:
* application/json' \ -d '{"command": "getMilestone", "index": 8059}'
*
* @return
*/
@Headers({ CONTENT_TYPE_HEADER, USER_AGENT_HEADER })
@POST("./")
Call<GetMilestoneResponse> getMilestone(@Body IotaGetMilestoneRequest request);
/**
* Get the list of latest tips (unconfirmed transactions).
*
* curl http://localhost:14265 -X POST -H 'Content-Type: application/json'
* -d '{"command": "getNeighbors"}'
*/
@Headers({ CONTENT_TYPE_HEADER, USER_AGENT_HEADER })
@POST("./")
Call<GetNeighborsResponse> getNeighbors(@Body IotaCommandRequest request);
/**
* Get the list of latest tips (unconfirmed transactions).
*
* curl http://localhost:14265 \ -X POST \ -H 'Content-Type:
* application/json' \ -d '{"command": "getTips"}'
*/
@Headers({ CONTENT_TYPE_HEADER, USER_AGENT_HEADER })
@POST("./")
Call<GetTipsResponse> getTips(@Body IotaCommandRequest request);
/**
* Get the list of latest tips (unconfirmed transactions).
*
* curl http://localhost:14265 \ -X POST \ -H 'Content-Type:
* application/json' \ -d '{"command": "getTips"}'
*/
@Headers({ CONTENT_TYPE_HEADER, USER_AGENT_HEADER })
@POST("./")
Call<GetTransfersResponse> getTransfers(@Body IotaGetTransferRequest request);
/**
* Find the transactions which match the specified input and return
*
* curl http://localhost:14265 \ -X POST \ -H 'Content-Type: application/json' \
* -d '{"command": "findTransactions", "addresses": ["RVORZ9SIIP9RCYMREUIXXVPQIPHVCNPQ9HZWYKFWYWZRE9JQKG9REPKIASHUUECPSQO9JT9XNMVKWYGVAZETAIRPTM"]}'
*/
@Headers({ CONTENT_TYPE_HEADER, USER_AGENT_HEADER })
@POST("./")
Call<FindTransactionResponse> findTransactions(@Body IotaFindTransactionsRequest request);
/**
* Get the inclusion states of a set of transactions. This is for determining if a transaction was accepted and confirmed by the network or not. You can search for multiple tips (and thus, milestones) to get past inclusion states of transactions.
*
* curl http://localhost:14265 -X POST -H 'Content-Type: application/json'
* -d '{"command": "getInclusionStates", "transactions"Q9HZWYKFWYWZRE9JQKG9REPKIASHUUECPSQO9JT9XNMVKWYGVAZETAIRPTM"], "tips" : []}'
*
*
*/
@Headers({ CONTENT_TYPE_HEADER, USER_AGENT_HEADER })
@POST("./")
Call<GetInclusionStateResponse> getInclusionStates(@Body IotaGetInclusionStateRequest request);
@Headers({ CONTENT_TYPE_HEADER, USER_AGENT_HEADER })
@POST("./")
Call<GetBundleResponse> getBundle(@Body IotaGetBundleRequest request);
/*
@Headers({ CONTENT_TYPE_HEADER, USER_AGENT_HEADER })
@POST("./")
Call<GetTrytesResponse> getTrytes(@Body IotaGetTrytesRequest request);
@Headers({ CONTENT_TYPE_HEADER, USER_AGENT_HEADER })
@POST("./")
Call<AnalyzeTransactionResponse> analyzeTransactions(@Body IotaAnalyzeTransactionRequest request);
@Headers({ CONTENT_TYPE_HEADER, USER_AGENT_HEADER })
@POST("./")
Call<GetNewAddressResponse> getNewAddress(@Body IotaGetNewAddressRequest request);
@Headers({ CONTENT_TYPE_HEADER, USER_AGENT_HEADER })
@POST("./")
Call<PrepareTransfersResponse> prepareTransfers(@Body IotaPrepareTransfersRequest request);
@Headers({ CONTENT_TYPE_HEADER, USER_AGENT_HEADER })
@POST("./")
Call<GetTransactionsToApproveResponse> getTransactionsToApprove(@Body IotaGetTransactionsToApproveRequest request);
@Headers({ CONTENT_TYPE_HEADER, USER_AGENT_HEADER })
@POST("./")
Call<GetAttachToTangleResponse> attachToTangle(@Body IotaAttachToTangleRequest request);
@Headers({ CONTENT_TYPE_HEADER, USER_AGENT_HEADER })
@POST("./")
Call<InterruptAttachingToTangleResponse> interruptAttachingToTangle(@Body IotaInterruptAttachingToTangleRequest request);
@Headers({ CONTENT_TYPE_HEADER, USER_AGENT_HEADER })
@POST("./")
Call<PushTransactionsResponse> pushTransactions(@Body IotaPushTransactionsRequest request);
@Headers({ CONTENT_TYPE_HEADER, USER_AGENT_HEADER })
@POST("./")
Call<StoreTransactionsResponse> storeTransactions(@Body IotaStoreTransactionsRequest request);
@Headers({ CONTENT_TYPE_HEADER, USER_AGENT_HEADER })
@POST("./")
Call<TransferResponse> transfer(@Body IotaTransferRequest request);
@Headers({ CONTENT_TYPE_HEADER, USER_AGENT_HEADER })
@POST("./")
Call<ReplayTransferResponse> replayTransfer(@Body IotaReplayTransferRequest request);
@Headers({ CONTENT_TYPE_HEADER, USER_AGENT_HEADER })
@POST("./")
Call<PullTransactionsResponse> pullTransactions(@Body IotaPullTransactionsRequest request);
* Get the list of transactions which were bundled with the specified tail transaction.
* This call returns the full value of all individual transactions, not just the hashes.
*/
}

View File

@ -0,0 +1,24 @@
package jota.dto.request;
import jota.IotaAPICommands;
public class IotaCommandRequest {
final String command;
protected IotaCommandRequest(IotaAPICommands command) {
this.command = command.command();
}
public static IotaCommandRequest createNodeInfoRequest() {
return new IotaCommandRequest(IotaAPICommands.GET_NODE_INFO);
}
public static IotaCommandRequest createGetTipsRequest() {
return new IotaCommandRequest(IotaAPICommands.GET_TIPS);
}
public static IotaCommandRequest createGetNeighborsRequest() {
return new IotaCommandRequest(IotaAPICommands.GET_NEIGHBORS);
}
}

View File

@ -0,0 +1,42 @@
package jota.dto.request;
import jota.IotaAPICommands;
public class IotaFindTransactionsRequest extends IotaCommandRequest {
private IotaFindTransactionsRequest() {
super(IotaAPICommands.FIND_TRANSACTIONS);
}
private String[] bundles; // List of bundle hashes. The hashes need to be extended to 81chars by padding the hash with 9's.
private String[] addresses;
private String[] digests;
private String[] approvees;
public static IotaFindTransactionsRequest createFindTransactionRequest() {
return new IotaFindTransactionsRequest();
}
public IotaFindTransactionsRequest byBundles(String [] bundles) {
this.bundles = bundles;
return this;
}
public IotaFindTransactionsRequest byAddresses(String [] addresses) {
this.addresses = addresses;
return this;
}
public IotaFindTransactionsRequest byDigests(String [] digests) {
this.digests = digests;
return this;
}
public IotaFindTransactionsRequest byApprovees(String [] approvees) {
this.approvees = approvees;
return this;
}
}

View File

@ -0,0 +1,18 @@
package jota.dto.request;
import jota.IotaAPICommands;
public class IotaGetBundleRequest extends IotaCommandRequest {
private String transaction;
private IotaGetInclusionStateRequest(final String transaction) {
super(IotaAPICommands.GET_BUNDLE);
this.transaction = transaction;
}
public static IotaGetBundleRequest createIotaGetBundleRequest(String transaction) {
return new IotaGetBundleRequest(transaction);
}
}

View File

@ -0,0 +1,29 @@
package jota.dto.request;
import jota.IotaAPICommands;
import java.util.Collection;
import java.util.stream.Collectors;
public class IotaGetInclusionStateRequest extends IotaCommandRequest {
private IotaGetInclusionStateRequest(final String[] transactions, final String[] tips) {
super(IotaAPICommands.GET_INCLUSIONS_STATES);
this.transactions = transactions;
this.tips = tips;
}
private String[] transactions;
private String[] tips;
public static IotaGetInclusionStateRequest createGetInclusionStateRequest(String[] transactions, String[] tips) {
return new IotaGetInclusionStateRequest(transactions, tips);
}
public static IotaGetInclusionStateRequest createGetInclusionStateRequest(Collection<String> transactions, Collection<String> tips) {
return createGetInclusionStateRequest(
transactions.toArray(new String[] {}),
tips.toArray(new String[] {}));
}
}

View File

@ -0,0 +1,17 @@
package jota.dto.request;
import jota.IotaAPICommands;
public class IotaGetMilestoneRequest extends IotaCommandRequest {
private String index;
private IotaGetMilestoneRequest(final String index) {
super(IotaAPICommands.GET_MILESTONE);
this.index = index;
}
public static IotaGetMilestoneRequest createMilestoneRequest(Integer index) {
return new IotaGetMilestoneRequest(String.valueOf(index));
}
}

View File

@ -0,0 +1,19 @@
package jota.dto.request;
import jota.IotaAPICommands;
public class IotaGetTransferRequest extends IotaCommandRequest {
private String seed;
private String securityLevel;
private IotaGetTransferRequest(final String seed, final String securityLevel) {
super(IotaAPICommands.GET_TRANSFER);
this.seed = seed;
this.securityLevel = securityLevel;
}
public static IotaGetTransferRequest createGetTransferRequest(String seed, Integer securityLevel) {
return new IotaGetTransferRequest(seed, String.valueOf(securityLevel));
}
}

View File

@ -0,0 +1,30 @@
package jota.dto.response;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
public abstract class AbstractResponse {
private Integer duration;
public Integer getDuration() {
return duration;
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
}
@Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this, false);
}
@Override
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(this, obj, false);
}
}

View File

@ -0,0 +1,10 @@
package jota.dto.response;
public class FindTransactionResponse extends AbstractResponse {
String [] addresses;
public String[] getAddresses() {
return addresses;
}
}

View File

@ -0,0 +1,93 @@
package jota.dto.response;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
public class GetBundleResponse extends AbstractResponse {
private Transactions[] transactions;
private String warning;
public String getWarning() {
return warning;
}
public Transactions[] getTransactions() {
return transactions;
}
static class Transactions {
private String signatureMessageChunk;
private String index;
private String approvalNonce;
private String hash;
private String digest;
private String type;
private String timestamp;
private String trunkTransaction;
private String branchTransaction;
private String signatureNonce;
private String address;
private String value;
private String bundle;
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
}
public String getAddress() {
return address;
}
public String getApprovalNonce() {
return approvalNonce;
}
public String getBranchTransaction() {
return branchTransaction;
}
public String getBundle() {
return bundle;
}
public String getDigest() {
return digest;
}
public String getHash() {
return hash;
}
public String getIndex() {
return index;
}
public String getSignatureMessageChunk() {
return signatureMessageChunk;
}
public String getSignatureNonce() {
return signatureNonce;
}
public String getTimestamp() {
return timestamp;
}
public String getType() {
return type;
}
public String getTrunkTransaction() {
return trunkTransaction;
}
public String getValue() {
return value;
}
}
}

View File

@ -0,0 +1,9 @@
package jota.dto.response;
public class GetInclusionStateResponse extends AbstractResponse {
boolean [] states;
public boolean[] getStates() {
return states;
}
}

View File

@ -0,0 +1,10 @@
package jota.dto.response;
public class GetMilestoneResponse extends AbstractResponse {
private String milestone;
public String getMilestone() {
return milestone;
}
}

View File

@ -0,0 +1,27 @@
package jota.dto.response;
public class GetNeighborsResponse extends AbstractResponse {
private Neighbors[] neighbors;
public Neighbors[] getNeighbors() {
return neighbors;
}
static class Neighbors {
private String numberOfAllTransactions;
private String address;
private String numberOfNewTransactions;
public String getAddress() {
return address;
}
public String getNumberOfAllTransactions() {
return numberOfAllTransactions;
}
public String getNumberOfNewTransactions() {
return numberOfNewTransactions;
}
}
}

View File

@ -0,0 +1,66 @@
package jota.dto.response;
public class GetNodeInfoResponse extends AbstractResponse {
private String incomingPacketsBacklog;
private String appName;
private String transactionsToRequest;
private String jreTotalMemory;
private String time;
private String neighbors;
private String milestoneIndex;
private String appVersion;
private String jreAvailableProcessors;
private String jreMaxMemory;
private String tips;
private String jreFreeMemory;
public String getIncomingPacketsBacklog() {
return incomingPacketsBacklog;
}
public String getAppName() {
return appName;
}
public String getTransactionsToRequest() {
return transactionsToRequest;
}
public String getJreTotalMemory() {
return jreTotalMemory;
}
public String getTime() {
return time;
}
public String getNeighbors() {
return neighbors;
}
public String getMilestoneIndex() {
return milestoneIndex;
}
public String getAppVersion() {
return appVersion;
}
public String getJreAvailableProcessors() {
return jreAvailableProcessors;
}
public String getJreMaxMemory() {
return jreMaxMemory;
}
public String getTips() {
return tips;
}
public String getJreFreeMemory() {
return jreFreeMemory;
}
}

View File

@ -0,0 +1,10 @@
package jota.dto.response;
public class GetTipsResponse extends AbstractResponse {
private String[] hashes;
public String[] getHashes() {
return hashes;
}
}

View File

@ -0,0 +1,34 @@
package jota.dto.response;
public class GetTransfersResponse extends AbstractResponse {
private Transfers[] transfers;
public static class Transfers {
private String timestamp;
private String address;
private String hash;
private String persistence;
private String value;
public String getAddress() {
return address;
}
public String getHash() {
return hash;
}
public String getPersistence() {
return persistence;
}
public String getTimestamp() {
return timestamp;
}
public String getValue() {
return value;
}
}
public Transfers[] getTransfers() {
return transfers;
}
}

View File

@ -0,0 +1,89 @@
package jota;
import static org.junit.Assert.assertThat;
import jota.dto.response.*;
import org.hamcrest.core.IsNull;
import org.junit.Before;
import org.junit.Test;
/**
* Let's do some test coverage.
*
* @author davassi
*/
public class IotaAPIProxyTest {
private IotaAPIProxy proxy;
@Before
public void createProxyInstance() {
proxy = new IotaAPIProxy.Builder().build();
}
@Test
public void shouldCreateIotaApiProxyInstanceWithDefaultValues() {
IotaAPIProxy proxy = new IotaAPIProxy.Builder().build();
assertThat(proxy, IsNull.notNullValue());
}
@Test(expected = IllegalStateException.class)
public void shouldNotCreateIotaApiProxyInstanceWithDefaultValues() {
new IotaAPIProxy.Builder().host("a_very_wrong_ip_address").build().getNodeInfo();
}
@Test
public void shouldGetNodeInfo() {
GetNodeInfoResponse nodeInfo = proxy.getNodeInfo();
assertThat(nodeInfo, IsNull.notNullValue());
}
@Test
public void shouldGetMilestone() {
GetMilestoneResponse milestone = proxy.getMilestone(1000);
assertThat(milestone, IsNull.notNullValue());
}
@Test
public void shouldGetNeighbors() {
GetNeighborsResponse neighbors = proxy.getNeighbors();
assertThat(neighbors, IsNull.notNullValue());
}
@Test
public void shouldGetTips() {
GetTipsResponse tips = proxy.getTips();
assertThat(tips, IsNull.notNullValue());
}
@Test
public void shouldFindTransactionsByAddresses() {
FindTransactionResponse trans = proxy.findTransactionsByAddresses(new String[]{"123ABC"});
assertThat(trans, IsNull.notNullValue());
}
@Test
public void shouldFindTransactionsByApprovees() {
FindTransactionResponse trans = proxy.findTransactionsByApprovees(new String[]{"123ABC"});
assertThat(trans, IsNull.notNullValue());
}
@Test
public void shouldFindTransactionsByBundles() {
FindTransactionResponse trans = proxy.findTransactionsByBundles(new String[]{"123ABC"});
assertThat(trans, IsNull.notNullValue());
}
@Test
public void shouldFindTransactionsByDigests() {
FindTransactionResponse trans = proxy.findTransactionsByDigests(new String[]{"123ABC"});
assertThat(trans, IsNull.notNullValue());
}
@Test
public void shouldGetInclusionStates() {
GetInclusionStateResponse res = proxy.getInclusionStates(new String[]{"123ABC"},
new String[]{"123"});
assertThat(res, IsNull.notNullValue());
}
}