Added jsonrpc server.

This commit is contained in:
Adrian Tiberius 2015-06-08 14:51:03 +02:00
parent 48df2ae587
commit b3afe42f38
5 changed files with 469 additions and 228 deletions

View File

@ -1,118 +1,159 @@
package org.ethereum.android_app; package org.ethereum.android_app;
import android.content.Context; import android.content.Context;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.app.ActionBarActivity; import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
import android.util.Log; import android.util.Log;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.os.Build;
import org.ethereum.android.EthereumManager;
import org.ethereum.android.EthereumManager;
public class MainActivity extends ActionBarActivity {
public class MainActivity extends ActionBarActivity {
private static final String TAG = "MyActivity";
private static Integer quit = 0; private static final String TAG = "MyActivity";
private static Integer quit = 0;
private Toolbar toolbar;
private ViewPager viewPager; private Toolbar toolbar;
private SlidingTabLayout tabs; private ViewPager viewPager;
private TabsPagerAdapter adapter; private SlidingTabLayout tabs;
private TabsPagerAdapter adapter;
public EthereumManager ethereumManager = null;
public EthereumManager ethereumManager = null;
@Override
protected void onCreate(Bundle savedInstanceState) { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.tool_bar);
setSupportActionBar(toolbar); toolbar = (Toolbar) findViewById(R.id.tool_bar);
setSupportActionBar(toolbar);
ethereumManager = new EthereumManager(this);
ethereumManager = new EthereumManager(this);
adapter = new TabsPagerAdapter(getSupportFragmentManager(), ethereumManager);
viewPager = (ViewPager) findViewById(R.id.pager); adapter = new TabsPagerAdapter(getSupportFragmentManager(), ethereumManager);
viewPager.setAdapter(adapter);; viewPager = (ViewPager) findViewById(R.id.pager);
viewPager.setAdapter(adapter);;
tabs = (SlidingTabLayout) findViewById(R.id.tabs);
tabs.setDistributeEvenly(true); tabs = (SlidingTabLayout) findViewById(R.id.tabs);
tabs.setViewPager(viewPager); tabs.setDistributeEvenly(true);
tabs.setViewPager(viewPager);
//StrictMode.enableDefaults();
//StrictMode.enableDefaults();
new PostTask().execute();
} if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
new PostTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
@Override else
public boolean onCreateOptionsMenu(Menu menu) { new PostTask().execute();
//return super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.menu_main, menu); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
return true; new JsonRpcTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else
new JsonRpcTask().execute();
@Override }
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will @Override
// automatically handle clicks on the Home/Up button, so long public boolean onCreateOptionsMenu(Menu menu) {
// as you specify a parent activity in AndroidManifest.xml. //return super.onCreateOptionsMenu(menu);
int id = item.getItemId(); getMenuInflater().inflate(R.menu.menu_main, menu);
Log.v(TAG, Integer.valueOf(id).toString()); return true;
//noinspection SimplifiableIfStatement }
if (id == R.id.action_settings) {
return true; @Override
} public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
return super.onOptionsItemSelected(item); // automatically handle clicks on the Home/Up button, so long
} // as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
// The definition of our task class Log.v(TAG, Integer.valueOf(id).toString());
private class PostTask extends AsyncTask<Context, Integer, String> { //noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
@Override }
protected void onPreExecute() {
super.onPreExecute(); return super.onOptionsItemSelected(item);
} }
@Override // The definition of our task class
protected String doInBackground(Context... params) { private class PostTask extends AsyncTask<Context, Integer, String> {
Log.v(TAG, "111");
Log.v(TAG, "222"); @Override
ethereumManager.connect(); protected void onPreExecute() {
Log.v(TAG, "333"); super.onPreExecute();
while(true) { }
try { @Override
Thread.sleep(50); protected String doInBackground(Context... params) {
} catch (InterruptedException e) { Log.v(TAG, "111");
e.printStackTrace();
} Log.v(TAG, "222");
ethereumManager.connect();
if (quit == 1) { Log.v(TAG, "333");
Log.v(TAG, "Ending background process."); while(true) {
return "All Done!";
} try {
Thread.sleep(50);
//publishProgress(1111); } catch (InterruptedException e) {
} e.printStackTrace();
} }
@Override if (quit == 1) {
protected void onProgressUpdate(Integer... values) { Log.v(TAG, "Ending background process.");
super.onProgressUpdate(values); return "All Done!";
Log.v(TAG, values[0].toString()); }
}
//publishProgress(1111);
@Override }
protected void onPostExecute(String result) { }
super.onPostExecute(result);
} @Override
} protected void onProgressUpdate(Integer... values) {
} super.onProgressUpdate(values);
Log.v(TAG, values[0].toString());
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
}
}
// The definition of our task class
private class JsonRpcTask extends AsyncTask<Context, Integer, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected String doInBackground(Context... params) {
Log.v(TAG, "444");
try {
ethereumManager.startJsonRpc();
} catch (Exception e) {
}
Log.v(TAG, "555");
return "done";
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
Log.v(TAG, values[0].toString());
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
}
}
}

View File

@ -1,60 +1,62 @@
apply plugin: 'com.android.library' apply plugin: 'com.android.library'
apply plugin: 'com.neenbedankt.android-apt' apply plugin: 'com.neenbedankt.android-apt'
buildscript { buildscript {
repositories { repositories {
jcenter() jcenter()
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:1.2.3' classpath 'com.android.tools.build:gradle:1.2.3'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4' classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
} }
} }
repositories { repositories {
jcenter() jcenter()
mavenCentral() mavenCentral()
} }
android { android {
compileSdkVersion 22 compileSdkVersion 22
buildToolsVersion "22.0.1" buildToolsVersion "22.0.1"
defaultConfig { defaultConfig {
minSdkVersion 14 minSdkVersion 14
targetSdkVersion 22 targetSdkVersion 22
versionCode 1 versionCode 1
versionName "1.0" versionName "1.0"
} }
buildTypes { buildTypes {
release { release {
minifyEnabled false minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
} }
} }
} }
tasks.withType(JavaCompile){ tasks.withType(JavaCompile){
options.warnings = false options.warnings = false
} }
dependencies { dependencies {
apt 'com.google.dagger:dagger-compiler:2.0' apt 'com.google.dagger:dagger-compiler:2.0'
compile fileTree(dir: 'libs', include: ['*.jar']) compile fileTree(dir: 'libs', include: ['*.jar'])
compile (project(':ethereumj-core')) { compile (project(':ethereumj-core')) {
exclude group: "org.apache.commons", module: "commons-pool2" exclude group: "org.apache.commons", module: "commons-pool2"
exclude group: "org.slf4j", module: "slf4j-log4j12" exclude group: "org.slf4j", module: "slf4j-log4j12"
exclude group: "org.hibernate", module: "hibernate-core" exclude group: "org.hibernate", module: "hibernate-core"
exclude group: "org.hibernate", module: "hibernate-entitymanager" exclude group: "org.hibernate", module: "hibernate-entitymanager"
exclude group: "redis.clients", module: "jedis" exclude group: "redis.clients", module: "jedis"
exclude group: "org.antlr", module: "antlr4-runtime" exclude group: "org.antlr", module: "antlr4-runtime"
} }
//compile "com.google.dagger:dagger:2.1-SNAPSHOT" //compile "com.google.dagger:dagger:2.1-SNAPSHOT"
compile "com.j256.ormlite:ormlite-android:4.48" compile "com.j256.ormlite:ormlite-android:4.48"
compile "org.glassfish:javax.annotation:10.0-b28" compile "org.glassfish:javax.annotation:10.0-b28"
compile "org.iq80.leveldb:leveldb:0.7" compile "org.iq80.leveldb:leveldb:0.7"
compile 'org.slf4j:slf4j-android:1.7.12' compile 'org.slf4j:slf4j-android:1.7.12'
compile 'javax.persistence:persistence-api:1.0.2' compile 'javax.persistence:persistence-api:1.0.2'
}
compile group: 'com.thetransactioncompany', name: 'jsonrpc2-server', version: '1.11'
}

View File

@ -1,50 +1,60 @@
package org.ethereum.android; package org.ethereum.android;
import android.content.Context; import android.content.Context;
import org.ethereum.android.di.modules.EthereumModule; import org.ethereum.android.di.modules.EthereumModule;
import org.ethereum.android.di.components.DaggerEthereumComponent; import org.ethereum.android.di.components.DaggerEthereumComponent;
import org.ethereum.config.SystemProperties; import org.ethereum.config.SystemProperties;
import org.ethereum.facade.Ethereum; import org.ethereum.facade.Ethereum;
import org.ethereum.listener.EthereumListenerAdapter; import org.ethereum.listener.EthereumListenerAdapter;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.ethereum.android.jsonrpc.JsonRpcServer;
public class EthereumManager {
public class EthereumManager {
private static final Logger logger = LoggerFactory.getLogger("manager");
private static final Logger logger = LoggerFactory.getLogger("manager");
public static Ethereum ethereum = null;
public static Ethereum ethereum = null;
public EthereumManager(Context context) { private JsonRpcServer jsonRpcServer;
System.setProperty("sun.arch.data.model", "32");
System.setProperty("leveldb.mmap", "false");
ethereum = DaggerEthereumComponent.builder() public EthereumManager(Context context) {
.ethereumModule(new EthereumModule(context)) System.setProperty("sun.arch.data.model", "32");
.build().ethereum(); System.setProperty("leveldb.mmap", "false");
} ethereum = DaggerEthereumComponent.builder()
.ethereumModule(new EthereumModule(context))
public void start() { .build().ethereum();
} jsonRpcServer = new JsonRpcServer(ethereum);
}
public void connect() {
public void start() {
ethereum.connect(SystemProperties.CONFIG.activePeerIP(),
SystemProperties.CONFIG.activePeerPort(), }
SystemProperties.CONFIG.activePeerNodeid());
//ethereum.getBlockchain(); public void connect() {
}
ethereum.connect(SystemProperties.CONFIG.activePeerIP(),
public void startPeerDiscovery() { SystemProperties.CONFIG.activePeerPort(),
SystemProperties.CONFIG.activePeerNodeid());
ethereum.startPeerDiscovery(); //ethereum.getBlockchain();
} }
public void addListener(EthereumListenerAdapter listener) { public void startPeerDiscovery() {
ethereum.addListener(listener); ethereum.startPeerDiscovery();
} }
} public void addListener(EthereumListenerAdapter listener) {
ethereum.addListener(listener);
}
public void startJsonRpc() throws Exception {
jsonRpcServer.start();
}
}

View File

@ -0,0 +1,159 @@
package org.ethereum.android.jsonrpc;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.multipart.HttpPostStandardRequestDecoder;
import io.netty.handler.codec.http.multipart.DefaultHttpDataFactory;
import io.netty.handler.codec.http.HttpObject;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpContent;
import io.netty.handler.codec.http.LastHttpContent;
import io.netty.buffer.ByteBuf;
import io.netty.util.CharsetUtil;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.channel.ChannelFuture;
import org.ethereum.facade.Ethereum;
import com.thetransactioncompany.jsonrpc2.*;
import com.thetransactioncompany.jsonrpc2.server.*;
import io.netty.handler.codec.http.HttpHeaders;
import static io.netty.handler.codec.http.HttpHeaders.Names.*;
import org.ethereum.android.jsonrpc.method.*;
public final class JsonRpcServer {
static final int PORT = 8545;
private Ethereum ethereum;
private Dispatcher dispatcher;
public JsonRpcServer(Ethereum ethereum) {
this.ethereum = ethereum;
this.dispatcher = new Dispatcher();
this.dispatcher.register(new eth_coinbase(this.ethereum));
}
public void start() throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.option(ChannelOption.SO_BACKLOG, 1024);
// b.localAddress(InetAddress.getLocalHost(), PORT);
b.localAddress(PORT);
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new JsonRpcServerInitializer());
Channel ch = b.bind().sync().channel();
ch.closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
class JsonRpcServerInitializer extends ChannelInitializer<SocketChannel> {
@Override
public void initChannel(SocketChannel ch) {
ChannelPipeline p = ch.pipeline();
p.addLast(new HttpServerCodec());
p.addLast(new JsonRpcServerHandler());
}
}
class JsonRpcServerHandler extends SimpleChannelInboundHandler<HttpObject> {
private HttpRequest request;
private final StringBuilder responseContent = new StringBuilder();
private HttpPostStandardRequestDecoder decoder;
private String postData;
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
if (decoder != null) {
decoder.destroy();
}
}
@Override
public void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
if (msg instanceof HttpRequest) {
HttpRequest req = this.request = (HttpRequest) msg;
if (!req.getUri().equals("/") || !request.getMethod().equals(HttpMethod.POST)) {
responseContent.append("Hi, how are you?!!");
return;
} else {
decoder = new HttpPostStandardRequestDecoder(new DefaultHttpDataFactory(false), req);
postData = "";
}
}
if (decoder != null) {
if (msg instanceof HttpContent) {
HttpContent chunk = (HttpContent) msg;
decoder.offer(chunk);
postData += chunk.content().toString(0, chunk.content().capacity(), CharsetUtil.UTF_8);
if (chunk instanceof LastHttpContent) {
JSONRPC2Request req = JSONRPC2Request.parse(postData);
JSONRPC2Response resp = dispatcher.process(req, null);
responseContent.append(resp);
writeResponse(ctx);
request = null;
decoder.destroy();
decoder = null;
}
}
} else {
writeResponse(ctx);
}
}
private void writeResponse(ChannelHandlerContext ctx) {
ByteBuf buf = Unpooled.copiedBuffer(responseContent.toString(), CharsetUtil.UTF_8);
responseContent.setLength(0);
boolean close = HttpHeaders.Values.CLOSE.equalsIgnoreCase(request.headers().get(CONNECTION))
|| request.getProtocolVersion().equals(HttpVersion.HTTP_1_0)
&& !HttpHeaders.Values.KEEP_ALIVE.equalsIgnoreCase(request.headers().get(CONNECTION));
FullHttpResponse response = new DefaultFullHttpResponse(
HttpVersion.HTTP_1_1, HttpResponseStatus.OK, buf);
response.headers().set(CONTENT_TYPE, "text/plain; charset=UTF-8");
if (!close) {
response.headers().set(CONTENT_LENGTH, buf.readableBytes());
}
ChannelFuture future = ctx.writeAndFlush(response);
if (close) {
future.addListener(ChannelFutureListener.CLOSE);
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}
}

View File

@ -0,0 +1,29 @@
package org.ethereum.android.jsonrpc.method;
import com.thetransactioncompany.jsonrpc2.*;
import com.thetransactioncompany.jsonrpc2.server.*;
import org.ethereum.facade.Ethereum;
public class eth_coinbase implements RequestHandler {
private String name = "";
private Ethereum ethereum;
public eth_coinbase(Ethereum ethereum) {
this.ethereum = ethereum;
name = this.getClass().getSimpleName();
}
public String[] handledRequests() {
return new String[]{name};
}
public JSONRPC2Response process(JSONRPC2Request req, MessageContext ctx) {
if (req.getMethod().equals(name)) {
//TODO: place business logic here
return null;
} else {
return new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, req.getID());
}
}
}