Rewrote JSONInterface to reflect new features provided by the I2PControl API.
Added new API test to Main, maybe time to extract them to testclass. Refactored JSONInterface to (more) gracefully handle connection issues.
This commit is contained in:
@ -4,6 +4,12 @@ package net.i2p.itoopie;
|
||||
* Main.java
|
||||
*/
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
@ -13,10 +19,13 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.JSONRPC2Error;
|
||||
import com.thetransactioncompany.jsonrpc2.client.JSONRPC2SessionException;
|
||||
|
||||
import net.i2p.itoopie.configuration.ConfigurationManager;
|
||||
import net.i2p.itoopie.i2pcontrol.InvalidParametersException;
|
||||
import net.i2p.itoopie.i2pcontrol.InvalidPasswordException;
|
||||
import net.i2p.itoopie.i2pcontrol.JSONInterface;
|
||||
import net.i2p.itoopie.i2pcontrol.JSONInterface.NETWORK_INFO;
|
||||
import net.i2p.itoopie.security.CertificateHelper;
|
||||
|
||||
/**
|
||||
@ -83,24 +92,97 @@ public class Main {
|
||||
_conf.parseConfigStr("server.target=jsonrpc");
|
||||
|
||||
|
||||
|
||||
String str = null;
|
||||
// Test basic echo method
|
||||
try {
|
||||
str = JSONInterface.getEcho("Echo this mofo!");
|
||||
String str = JSONInterface.getEcho("Echo this mofo!");
|
||||
System.out.println("Echo response: " + str);
|
||||
}catch (InvalidPasswordException e) {
|
||||
e.printStackTrace();
|
||||
} catch (JSONRPC2SessionException e) {
|
||||
System.out.println("Connection failed..");
|
||||
}
|
||||
System.out.println("Echo response: " + str);
|
||||
|
||||
|
||||
Double dbl = null;
|
||||
// Test reading a rateStat
|
||||
try {
|
||||
dbl = JSONInterface.getRateStat("bw.sendRate", 3600000L);
|
||||
Double dbl = JSONInterface.getRateStat("bw.sendRate", 3600000L);
|
||||
System.out.println("rateStat: " + dbl);
|
||||
} catch (InvalidPasswordException e) {
|
||||
e.printStackTrace();
|
||||
} catch (JSONRPC2SessionException e) {
|
||||
System.out.println("Connection failed..");
|
||||
} catch (InvalidParametersException e) {
|
||||
System.out.println("Bad parameters sent..");
|
||||
}
|
||||
System.out.println("rateStat: " + dbl);
|
||||
|
||||
// Test reading all settings
|
||||
try {
|
||||
HashMap hm = JSONInterface.getNetworkInfo(JSONInterface.NETWORK_INFO.values());
|
||||
System.out.println("getNetworkInfo: All: ");
|
||||
Set<Entry> set = hm.entrySet();
|
||||
for (Entry e : set){
|
||||
System.out.println(e.getKey() +":"+ e.getValue());
|
||||
}
|
||||
} catch (InvalidPasswordException e1) {
|
||||
//e1.printStackTrace();
|
||||
} catch (JSONRPC2SessionException e) {
|
||||
System.out.println("Connection failed..");
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Test saving all settings
|
||||
try {
|
||||
HashMap<NETWORK_INFO, String> hm = new HashMap<NETWORK_INFO,String>();
|
||||
|
||||
List<NETWORK_INFO> list = Arrays.asList(NETWORK_INFO.values());
|
||||
for (NETWORK_INFO i : list){
|
||||
hm.put(i, "66"); // 66 is an arbitrary number that should work for most fields.
|
||||
}
|
||||
HashMap nextHM= JSONInterface.setNetworkSetting(hm);
|
||||
System.out.println("setNetworkInfo: All: ");
|
||||
Set<Entry> set = nextHM.entrySet();
|
||||
for (Entry e : set){
|
||||
System.out.println(e.getKey() +":"+ e.getValue());
|
||||
}
|
||||
} catch (InvalidPasswordException e){
|
||||
//e.printStackTrace();
|
||||
} catch (JSONRPC2SessionException e){
|
||||
//e.printStackTrace();
|
||||
System.out.println("Connection failed..");
|
||||
} catch (InvalidParametersException e) {
|
||||
System.out.println("Bad parameters sent..");
|
||||
}
|
||||
|
||||
// Manually test saving all(?) settings
|
||||
try {
|
||||
HashMap<NETWORK_INFO, String> hm = new HashMap<NETWORK_INFO,String>();
|
||||
hm.put(NETWORK_INFO.BW_IN, "666");
|
||||
hm.put(NETWORK_INFO.BW_OUT, "666");
|
||||
hm.put(NETWORK_INFO.BW_SHARE, "66");
|
||||
hm.put(NETWORK_INFO.DETECTED_IP, "66.66.66.66");
|
||||
hm.put(NETWORK_INFO.LAPTOP_MODE, "true");
|
||||
hm.put(NETWORK_INFO.TCP_AUTOIP, "always");
|
||||
hm.put(NETWORK_INFO.TCP_HOSTNAME, "66.66.66.66");
|
||||
hm.put(NETWORK_INFO.TCP_PORT, "66");
|
||||
hm.put(NETWORK_INFO.UDP_AUTO_IP, "local,upnp,ssu");
|
||||
hm.put(NETWORK_INFO.UDP_HOSTNAME, "66.66.66.66");
|
||||
hm.put(NETWORK_INFO.UDP_PORT, "66");
|
||||
hm.put(NETWORK_INFO.UPNP, "true");
|
||||
|
||||
HashMap nextHM= JSONInterface.setNetworkSetting(hm);
|
||||
System.out.println("setNetworkInfo: Manual: ");
|
||||
Set<Entry> set = nextHM.entrySet();
|
||||
for (Entry e : set){
|
||||
System.out.println(e.getKey() +":"+ e.getValue());
|
||||
}
|
||||
} catch (InvalidPasswordException e){
|
||||
//e.printStackTrace();
|
||||
} catch (JSONRPC2SessionException e){
|
||||
//e.printStackTrace();
|
||||
System.out.println("Connection failed..");
|
||||
} catch (InvalidParametersException e) {
|
||||
System.out.println("Bad parameters sent..");
|
||||
}
|
||||
final Main main = new Main();
|
||||
main.launchForeverLoop();
|
||||
//We'll be doing GUI work, so let's stay in the event dispatcher thread.
|
||||
|
@ -15,7 +15,6 @@ import javax.swing.JOptionPane;
|
||||
import javax.swing.SwingWorker;
|
||||
|
||||
import net.i2p.itoopie.i18n.Transl;
|
||||
import net.i2p.itoopie.util.BrowseException;
|
||||
import net.i2p.itoopie.util.IsJar;
|
||||
|
||||
/**
|
||||
|
@ -12,7 +12,6 @@ import javax.swing.SwingWorker;
|
||||
|
||||
import net.i2p.itoopie.i18n.Transl;
|
||||
import net.i2p.itoopie.i2pcontrol.JSONInterface;
|
||||
import net.i2p.itoopie.util.BrowseException;
|
||||
|
||||
public class Main {
|
||||
|
||||
|
@ -2,12 +2,19 @@ package net.i2p.itoopie.i2pcontrol;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
import net.i2p.itoopie.configuration.ConfigurationManager;
|
||||
|
||||
import org.GNOME.Accessibility.CollectionHelper;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
@ -25,13 +32,47 @@ public class JSONInterface {
|
||||
private static final int MAX_NBR_RETRIES = 2;
|
||||
private static JSONRPC2Session session;
|
||||
private static String token;
|
||||
|
||||
/*
|
||||
* i2p.router.net.ntcp.port
|
||||
* i2p.router.net.ntcp.hostname
|
||||
* i2p.router.net.ntcp.autoip // true|always|false //disables autodetect|disabled //disables ntcp
|
||||
* i2p.router.net.ssu.port
|
||||
* i2p.router.net.ssu.hostname
|
||||
* i2p.router.net.ssu.detectedip
|
||||
* i2p.router.net.ssu.autoip //[local,upnp,ssu] any of prev., in order |fixed // fixed = no detection
|
||||
* i2p.router.net.upnp //
|
||||
* i2p.router.net.bw.share
|
||||
* i2p.router.net.bw.in
|
||||
* i2p.router.net.bw.out
|
||||
* i2p.router.net.laptopmode
|
||||
*/
|
||||
public interface RemoteSetable{ public boolean isSetable(); }
|
||||
public static enum NETWORK_INFO implements RemoteSetable{
|
||||
DETECTED_IP { public boolean isSetable(){ return false;} public String toString() { return "i2p.router.net.ssu.detectedip"; }},
|
||||
TCP_PORT { public boolean isSetable(){ return true;} public String toString() { return "i2p.router.net.ntcp.port"; }},
|
||||
TCP_HOSTNAME { public boolean isSetable(){ return true;} public String toString() { return "i2p.router.net.ntcp.hostname"; }},
|
||||
TCP_AUTOIP { public boolean isSetable(){ return true;} public String toString() { return "i2p.router.net.ntcp.autoip"; }},
|
||||
UDP_PORT { public boolean isSetable(){ return true;} public String toString() { return "i2p.router.net.ssu.port"; }},
|
||||
UDP_HOSTNAME { public boolean isSetable(){ return true;} public String toString() { return "i2p.router.net.ssu.hostname"; }},
|
||||
UDP_AUTO_IP { public boolean isSetable(){ return true;} public String toString() { return "i2p.router.net.ssu.autoip"; }},
|
||||
UPNP { public boolean isSetable(){ return true;} public String toString() { return "i2p.router.net.upnp"; }},
|
||||
BW_SHARE { public boolean isSetable(){ return true;} public String toString() { return "i2p.router.net.bw.share"; }},
|
||||
BW_IN { public boolean isSetable(){ return true;} public String toString() { return "i2p.router.net.bw.in"; }},
|
||||
BW_OUT { public boolean isSetable(){ return true;} public String toString() { return "i2p.router.net.bw.out"; }},
|
||||
LAPTOP_MODE { public boolean isSetable(){ return true;} public String toString() { return "i2p.router.net.laptopmode"; }}
|
||||
};
|
||||
private final static HashMap<String,NETWORK_INFO> enumMap;
|
||||
|
||||
static {
|
||||
_log = LogFactory.getLog(JSONInterface.class);
|
||||
_conf = ConfigurationManager.getInstance();
|
||||
Random rnd = new Random();
|
||||
nonce = rnd.nextInt();
|
||||
setupSession();
|
||||
enumMap = new HashMap<String,NETWORK_INFO>();
|
||||
for (NETWORK_INFO n : NETWORK_INFO.values()){
|
||||
enumMap.put(n.toString(), n);
|
||||
}
|
||||
}
|
||||
|
||||
private static synchronized int incrNonce() {
|
||||
@ -55,131 +96,204 @@ public class JSONInterface {
|
||||
}
|
||||
|
||||
private static JSONRPC2Response sendReq(JSONRPC2Request req)
|
||||
throws InvalidPasswordException, UnrecoverableFailedRequestException{
|
||||
throws InvalidPasswordException, UnrecoverableFailedRequestException,
|
||||
InvalidParametersException, JSONRPC2SessionException{
|
||||
return sendReq(req, 1);
|
||||
}
|
||||
|
||||
private static JSONRPC2Response sendReq(JSONRPC2Request req, int tryNbr)
|
||||
throws InvalidPasswordException, UnrecoverableFailedRequestException{
|
||||
if (tryNbr <= MAX_NBR_RETRIES){
|
||||
HashMap outParams = (HashMap) req.getParams();
|
||||
outParams.put("token", token); // Add authentication token
|
||||
req.setParams(outParams);
|
||||
|
||||
JSONRPC2Response resp = null;
|
||||
try {
|
||||
resp = session.send(req);
|
||||
JSONRPC2Error err = resp.getError();
|
||||
if (err != null) {
|
||||
switch (err.getCode()) {
|
||||
case -32700:
|
||||
// Parse error
|
||||
break;
|
||||
case -32600:
|
||||
// Invalid request
|
||||
break;
|
||||
case -32601:
|
||||
// Method not found
|
||||
break;
|
||||
case -32602:
|
||||
// Invalid params
|
||||
break;
|
||||
case -32603:
|
||||
// Internal error
|
||||
break;
|
||||
|
||||
// Custom errors (as defined by the I2PControl API)
|
||||
case -32001:
|
||||
// Invalid password
|
||||
throw new InvalidPasswordException();
|
||||
// break;
|
||||
case -32002:
|
||||
// No token
|
||||
token = getNewToken();
|
||||
throw new FailedRequestException();
|
||||
// break;
|
||||
case -32003:
|
||||
// Invalid token
|
||||
token = getNewToken();
|
||||
throw new FailedRequestException();
|
||||
//break;
|
||||
case -32004:
|
||||
// Token expired
|
||||
token = getNewToken();
|
||||
throw new FailedRequestException();
|
||||
// break;
|
||||
}
|
||||
throws InvalidPasswordException, UnrecoverableFailedRequestException,
|
||||
InvalidParametersException, JSONRPC2SessionException {
|
||||
if (tryNbr > MAX_NBR_RETRIES){
|
||||
throw new UnrecoverableFailedRequestException(); // Max retries reached. Throw exception.
|
||||
}
|
||||
HashMap outParams = (HashMap) req.getParams();
|
||||
outParams.put("Token", token); // Add authentication token
|
||||
req.setParams(outParams);
|
||||
|
||||
JSONRPC2Response resp = null;
|
||||
try {
|
||||
resp = session.send(req);
|
||||
JSONRPC2Error err = resp.getError();
|
||||
if (err != null) {
|
||||
switch (err.getCode()) {
|
||||
case -32700:
|
||||
// Parse error
|
||||
_log.error(err.getMessage());
|
||||
break;
|
||||
case -32600:
|
||||
// Invalid request
|
||||
_log.error(err.getMessage());
|
||||
break;
|
||||
case -32601:
|
||||
// Method not found
|
||||
_log.error(err.getMessage());
|
||||
break;
|
||||
case -32602:
|
||||
// Invalid params
|
||||
_log.error(err.getMessage());
|
||||
throw new InvalidParametersException();
|
||||
//break;
|
||||
case -32603:
|
||||
// Internal error
|
||||
_log.error("Remote host: " + err.getMessage());
|
||||
break;
|
||||
|
||||
// Custom errors (as defined by the I2PControl API)
|
||||
case -32001:
|
||||
// Invalid password
|
||||
_log.info("Provided password was rejected by the remote host");
|
||||
throw new InvalidPasswordException();
|
||||
// break;
|
||||
case -32002:
|
||||
// No token
|
||||
token = getNewToken();
|
||||
throw new FailedRequestException();
|
||||
// break;
|
||||
case -32003:
|
||||
// Invalid token
|
||||
token = getNewToken();
|
||||
throw new FailedRequestException();
|
||||
//break;
|
||||
case -32004:
|
||||
// Token expired
|
||||
token = getNewToken();
|
||||
throw new FailedRequestException();
|
||||
// break;
|
||||
}
|
||||
} catch (JSONRPC2SessionException e) {
|
||||
_log.error(req.toString(), e);
|
||||
} catch (FailedRequestException e) {
|
||||
// Try sending the same request again with a current authentication token.
|
||||
return sendReq(req, ++tryNbr);
|
||||
}
|
||||
return resp;
|
||||
} else {
|
||||
throw new UnrecoverableFailedRequestException(); // Max retries reached. Throw exception.
|
||||
}catch (FailedRequestException e) {
|
||||
return sendReq(req, ++tryNbr);
|
||||
}
|
||||
}
|
||||
|
||||
private static synchronized String getNewToken()
|
||||
throws InvalidPasswordException {
|
||||
JSONRPC2Request req = new JSONRPC2Request("authenticate", incrNonce());
|
||||
throws InvalidPasswordException, JSONRPC2SessionException {
|
||||
JSONRPC2Request req = new JSONRPC2Request("Authenticate", incrNonce());
|
||||
|
||||
Map outParams = new HashMap();
|
||||
outParams.put("password",
|
||||
outParams.put("Password",
|
||||
_conf.getConf("server.password", DEFAULT_PASSWORD));
|
||||
req.setParams(outParams);
|
||||
|
||||
JSONRPC2Response resp = null;
|
||||
try {
|
||||
resp = sendReq(req);
|
||||
Map inParams = (HashMap) resp.getResult();
|
||||
return (String) inParams.get("Token");
|
||||
}catch (UnrecoverableFailedRequestException e) {
|
||||
return null; // Shouldn't normaly happen.
|
||||
return null; // Shouldn't normally happen.
|
||||
} catch (InvalidParametersException e) {
|
||||
_log.error("getNewToken() invalid parameters used");
|
||||
}
|
||||
Map inParams = (HashMap) resp.getResult();
|
||||
return (String) inParams.get("token");
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Double getRateStat(String stat, long period)
|
||||
throws InvalidPasswordException {
|
||||
throws InvalidPasswordException, JSONRPC2SessionException, InvalidParametersException {
|
||||
|
||||
JSONRPC2Request req = new JSONRPC2Request("getRate", incrNonce());
|
||||
JSONRPC2Request req = new JSONRPC2Request("GetRate", incrNonce());
|
||||
@SuppressWarnings("rawtypes")
|
||||
Map params = new HashMap();
|
||||
params.put("stat", stat);
|
||||
params.put("period", period);
|
||||
params.put("Stat", stat);
|
||||
params.put("Period", period);
|
||||
req.setParams(params);
|
||||
|
||||
JSONRPC2Response resp = null;
|
||||
try {
|
||||
resp = sendReq(req);
|
||||
Map inParams = (HashMap) resp.getResult();
|
||||
return (Double) inParams.get("Result");
|
||||
}catch (UnrecoverableFailedRequestException e) {
|
||||
_log.error("getRateStat failed.", e);
|
||||
}
|
||||
|
||||
Map inParams = (HashMap) resp.getResult();
|
||||
return (Double) inParams.get("result");
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static String getEcho(String str) throws InvalidPasswordException {
|
||||
public static String getEcho(String str)
|
||||
throws InvalidPasswordException, JSONRPC2SessionException {
|
||||
|
||||
JSONRPC2Request req = new JSONRPC2Request("echo", incrNonce());
|
||||
JSONRPC2Request req = new JSONRPC2Request("Echo", incrNonce());
|
||||
@SuppressWarnings("rawtypes")
|
||||
Map params = new HashMap();
|
||||
params.put("echo", str);
|
||||
params.put("Echo", str);
|
||||
req.setParams(params);
|
||||
|
||||
JSONRPC2Response resp = null;
|
||||
try {
|
||||
resp = sendReq(req);
|
||||
Map inParams = (HashMap) resp.getResult();
|
||||
return (String) inParams.get("Result");
|
||||
} catch (UnrecoverableFailedRequestException e) {
|
||||
_log.error("getEcho failed.", e);
|
||||
_log.error("GetEcho failed.", e);
|
||||
} catch (InvalidParametersException e) {
|
||||
_log.error("Remote host rejected provided parameters: " + req.toJSON().toJSONString());
|
||||
}
|
||||
System.out.println("Response: " + resp.toJSON().toJSONString());
|
||||
Map inParams = (HashMap) resp.getResult();
|
||||
return (String) inParams.get("result");
|
||||
return null;
|
||||
}
|
||||
|
||||
public static HashMap getNetworkInfo(NETWORK_INFO ... options)
|
||||
throws InvalidPasswordException, JSONRPC2SessionException{
|
||||
|
||||
JSONRPC2Request req = new JSONRPC2Request("NetworkSetting", incrNonce());
|
||||
@SuppressWarnings("rawtypes")
|
||||
Map outParams = new HashMap();
|
||||
List<NETWORK_INFO> list = Arrays.asList(options);
|
||||
|
||||
for (NETWORK_INFO i : list){
|
||||
outParams.put(i.toString(), null);
|
||||
}
|
||||
|
||||
req.setParams(outParams);
|
||||
|
||||
JSONRPC2Response resp = null;
|
||||
try {
|
||||
resp = sendReq(req);
|
||||
HashMap map = (HashMap) resp.getResult();
|
||||
if (map != null){
|
||||
Set<Entry> set = map.entrySet();
|
||||
HashMap output = new HashMap();
|
||||
for (Entry e: set){
|
||||
output.put(enumMap.get(e.getKey()), e.getValue());
|
||||
}
|
||||
return map;
|
||||
} else {
|
||||
return new HashMap();
|
||||
}
|
||||
} catch (UnrecoverableFailedRequestException e) {
|
||||
_log.error("getNetworkInfo failed.", e);
|
||||
} catch (InvalidParametersException e) {
|
||||
_log.error("Remote host rejected provided parameters: " + req.toJSON().toJSONString());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static HashMap<NETWORK_INFO, Boolean> setNetworkSetting(Map<NETWORK_INFO,String> settings)
|
||||
throws InvalidPasswordException, JSONRPC2SessionException, InvalidParametersException{
|
||||
|
||||
JSONRPC2Request req = new JSONRPC2Request("NetworkSetting", incrNonce());
|
||||
|
||||
Map outParams = new HashMap();
|
||||
|
||||
Set<Entry<NETWORK_INFO,String>> set = settings.entrySet();
|
||||
for (Entry<NETWORK_INFO,String> e : set){
|
||||
if(e.getKey().isSetable()){
|
||||
outParams.put(e.getKey().toString(), e.getValue());
|
||||
}
|
||||
}
|
||||
req.setParams(outParams);
|
||||
|
||||
JSONRPC2Response resp = null;
|
||||
try {
|
||||
resp = sendReq(req);
|
||||
HashMap map = (HashMap) resp.getResult();
|
||||
return map;
|
||||
} catch (UnrecoverableFailedRequestException e) {
|
||||
_log.error("setNetworkInfo failed.", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,9 @@
|
||||
package net.i2p.itoopie.i2pcontrol;
|
||||
|
||||
public class UnrecoverableFailedRequestException extends Exception {
|
||||
|
||||
/**
|
||||
* Signifies that a request has been tried thoroughly anda few times and has
|
||||
* not worked or returned errors.
|
||||
*/
|
||||
private static final long serialVersionUID = 4133380969869898255L;
|
||||
|
||||
}
|
||||
|
@ -1,23 +0,0 @@
|
||||
package net.i2p.itoopie.util;
|
||||
|
||||
public class BrowseException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public BrowseException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public BrowseException(String s) {
|
||||
super(s);
|
||||
}
|
||||
|
||||
public BrowseException(String s, Throwable t) {
|
||||
super(s, t);
|
||||
}
|
||||
|
||||
public BrowseException(Throwable t) {
|
||||
super(t);
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user