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;
import android.content.Context;
import android.os.AsyncTask;
import android.support.v4.view.ViewPager;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import org.ethereum.android.EthereumManager;
public class MainActivity extends ActionBarActivity {
private static final String TAG = "MyActivity";
private static Integer quit = 0;
private Toolbar toolbar;
private ViewPager viewPager;
private SlidingTabLayout tabs;
private TabsPagerAdapter adapter;
public EthereumManager ethereumManager = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.tool_bar);
setSupportActionBar(toolbar);
ethereumManager = new EthereumManager(this);
adapter = new TabsPagerAdapter(getSupportFragmentManager(), ethereumManager);
viewPager = (ViewPager) findViewById(R.id.pager);
viewPager.setAdapter(adapter);;
tabs = (SlidingTabLayout) findViewById(R.id.tabs);
tabs.setDistributeEvenly(true);
tabs.setViewPager(viewPager);
//StrictMode.enableDefaults();
new PostTask().execute();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
//return super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
Log.v(TAG, Integer.valueOf(id).toString());
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
// The definition of our task class
private class PostTask extends AsyncTask<Context, Integer, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected String doInBackground(Context... params) {
Log.v(TAG, "111");
Log.v(TAG, "222");
ethereumManager.connect();
Log.v(TAG, "333");
while(true) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (quit == 1) {
Log.v(TAG, "Ending background process.");
return "All Done!";
}
//publishProgress(1111);
}
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
Log.v(TAG, values[0].toString());
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
}
}
}
package org.ethereum.android_app;
import android.content.Context;
import android.os.AsyncTask;
import android.support.v4.view.ViewPager;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.os.Build;
import org.ethereum.android.EthereumManager;
public class MainActivity extends ActionBarActivity {
private static final String TAG = "MyActivity";
private static Integer quit = 0;
private Toolbar toolbar;
private ViewPager viewPager;
private SlidingTabLayout tabs;
private TabsPagerAdapter adapter;
public EthereumManager ethereumManager = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.tool_bar);
setSupportActionBar(toolbar);
ethereumManager = new EthereumManager(this);
adapter = new TabsPagerAdapter(getSupportFragmentManager(), ethereumManager);
viewPager = (ViewPager) findViewById(R.id.pager);
viewPager.setAdapter(adapter);;
tabs = (SlidingTabLayout) findViewById(R.id.tabs);
tabs.setDistributeEvenly(true);
tabs.setViewPager(viewPager);
//StrictMode.enableDefaults();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
new PostTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else
new PostTask().execute();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
new JsonRpcTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else
new JsonRpcTask().execute();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
//return super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
Log.v(TAG, Integer.valueOf(id).toString());
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
// The definition of our task class
private class PostTask extends AsyncTask<Context, Integer, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected String doInBackground(Context... params) {
Log.v(TAG, "111");
Log.v(TAG, "222");
ethereumManager.connect();
Log.v(TAG, "333");
while(true) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (quit == 1) {
Log.v(TAG, "Ending background process.");
return "All Done!";
}
//publishProgress(1111);
}
}
@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.neenbedankt.android-apt'
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.2.3'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
}
}
repositories {
jcenter()
mavenCentral()
}
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
minSdkVersion 14
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
tasks.withType(JavaCompile){
options.warnings = false
}
dependencies {
apt 'com.google.dagger:dagger-compiler:2.0'
compile fileTree(dir: 'libs', include: ['*.jar'])
compile (project(':ethereumj-core')) {
exclude group: "org.apache.commons", module: "commons-pool2"
exclude group: "org.slf4j", module: "slf4j-log4j12"
exclude group: "org.hibernate", module: "hibernate-core"
exclude group: "org.hibernate", module: "hibernate-entitymanager"
exclude group: "redis.clients", module: "jedis"
exclude group: "org.antlr", module: "antlr4-runtime"
}
//compile "com.google.dagger:dagger:2.1-SNAPSHOT"
compile "com.j256.ormlite:ormlite-android:4.48"
compile "org.glassfish:javax.annotation:10.0-b28"
compile "org.iq80.leveldb:leveldb:0.7"
compile 'org.slf4j:slf4j-android:1.7.12'
compile 'javax.persistence:persistence-api:1.0.2'
}
apply plugin: 'com.android.library'
apply plugin: 'com.neenbedankt.android-apt'
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.2.3'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
}
}
repositories {
jcenter()
mavenCentral()
}
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
minSdkVersion 14
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
tasks.withType(JavaCompile){
options.warnings = false
}
dependencies {
apt 'com.google.dagger:dagger-compiler:2.0'
compile fileTree(dir: 'libs', include: ['*.jar'])
compile (project(':ethereumj-core')) {
exclude group: "org.apache.commons", module: "commons-pool2"
exclude group: "org.slf4j", module: "slf4j-log4j12"
exclude group: "org.hibernate", module: "hibernate-core"
exclude group: "org.hibernate", module: "hibernate-entitymanager"
exclude group: "redis.clients", module: "jedis"
exclude group: "org.antlr", module: "antlr4-runtime"
}
//compile "com.google.dagger:dagger:2.1-SNAPSHOT"
compile "com.j256.ormlite:ormlite-android:4.48"
compile "org.glassfish:javax.annotation:10.0-b28"
compile "org.iq80.leveldb:leveldb:0.7"
compile 'org.slf4j:slf4j-android:1.7.12'
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;
import android.content.Context;
import org.ethereum.android.di.modules.EthereumModule;
import org.ethereum.android.di.components.DaggerEthereumComponent;
import org.ethereum.config.SystemProperties;
import org.ethereum.facade.Ethereum;
import org.ethereum.listener.EthereumListenerAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class EthereumManager {
private static final Logger logger = LoggerFactory.getLogger("manager");
public static Ethereum ethereum = null;
public EthereumManager(Context context) {
System.setProperty("sun.arch.data.model", "32");
System.setProperty("leveldb.mmap", "false");
ethereum = DaggerEthereumComponent.builder()
.ethereumModule(new EthereumModule(context))
.build().ethereum();
}
public void start() {
}
public void connect() {
ethereum.connect(SystemProperties.CONFIG.activePeerIP(),
SystemProperties.CONFIG.activePeerPort(),
SystemProperties.CONFIG.activePeerNodeid());
//ethereum.getBlockchain();
}
public void startPeerDiscovery() {
ethereum.startPeerDiscovery();
}
public void addListener(EthereumListenerAdapter listener) {
ethereum.addListener(listener);
}
}
package org.ethereum.android;
import android.content.Context;
import org.ethereum.android.di.modules.EthereumModule;
import org.ethereum.android.di.components.DaggerEthereumComponent;
import org.ethereum.config.SystemProperties;
import org.ethereum.facade.Ethereum;
import org.ethereum.listener.EthereumListenerAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.ethereum.android.jsonrpc.JsonRpcServer;
public class EthereumManager {
private static final Logger logger = LoggerFactory.getLogger("manager");
public static Ethereum ethereum = null;
private JsonRpcServer jsonRpcServer;
public EthereumManager(Context context) {
System.setProperty("sun.arch.data.model", "32");
System.setProperty("leveldb.mmap", "false");
ethereum = DaggerEthereumComponent.builder()
.ethereumModule(new EthereumModule(context))
.build().ethereum();
jsonRpcServer = new JsonRpcServer(ethereum);
}
public void start() {
}
public void connect() {
ethereum.connect(SystemProperties.CONFIG.activePeerIP(),
SystemProperties.CONFIG.activePeerPort(),
SystemProperties.CONFIG.activePeerNodeid());
//ethereum.getBlockchain();
}
public void startPeerDiscovery() {
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());
}
}
}