SQLite post working.

Bulletin_Board_Server_phase_1
Arbel Deutsch Peled 2015-11-12 21:30:53 +02:00
parent 58c1816324
commit d3af34d046
11 changed files with 180 additions and 97 deletions

1
.gitignore vendored
View File

@ -9,3 +9,4 @@ out
*.prefs *.prefs
*.project *.project
*.classpath *.classpath
bulletin-board-server/local-instances/meerkat.db

View File

@ -9,8 +9,10 @@ apply plugin: 'java'
apply plugin: 'eclipse' apply plugin: 'eclipse'
apply plugin: 'idea' apply plugin: 'idea'
//apply plugin: 'application'
//apply plugin: 'jetty' //apply plugin: 'jetty'
//mainClassName = 'Demo' //mainClassName = 'SQLiteIntegrationTest'
apply plugin: 'maven-publish' apply plugin: 'maven-publish'
@ -42,6 +44,8 @@ dependencies {
// Jersey for RESTful API // Jersey for RESTful API
compile 'org.glassfish.jersey.containers:jersey-container-servlet:2.22.+' compile 'org.glassfish.jersey.containers:jersey-container-servlet:2.22.+'
compile 'org.xerial:sqlite-jdbc:3.7.+'
// Logging // Logging
compile 'org.slf4j:slf4j-api:1.7.7' compile 'org.slf4j:slf4j-api:1.7.7'
@ -68,6 +72,8 @@ task integrationTest(type: Test) {
gretty { gretty {
httpPort = 8081 httpPort = 8081
contextPath = '/'
servletContainer = 'jetty9'
integrationTestTask = 'integrationTest' integrationTestTask = 'integrationTest'
} }

View File

@ -2,6 +2,9 @@ package meerkat.bulletinboard.sqlserver;
import java.util.List; import java.util.List;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import com.google.protobuf.ProtocolStringList; import com.google.protobuf.ProtocolStringList;
import java.sql.Connection; import java.sql.Connection;
@ -11,7 +14,7 @@ import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import meerkat.bulletinboard.BulletinBoardServer; import meerkat.bulletinboard.BulletinBoardServer;
import meerkat.bulletinboard.MessageFilter; import meerkat.protobuf.Voting.MessageFilterList;
import meerkat.comm.CommunicationException; import meerkat.comm.CommunicationException;
import meerkat.protobuf.Crypto.SignatureVerificationKey; import meerkat.protobuf.Crypto.SignatureVerificationKey;
import meerkat.protobuf.Voting.BulletinBoardMessage; import meerkat.protobuf.Voting.BulletinBoardMessage;
@ -19,6 +22,7 @@ import meerkat.crypto.Digest;
import meerkat.crypto.concrete.SHA256Digest; import meerkat.crypto.concrete.SHA256Digest;
import meerkat.protobuf.Voting.MessageID; import meerkat.protobuf.Voting.MessageID;
@Path("/SQLServer")
public abstract class BulletinBoardSQLServer implements BulletinBoardServer{ public abstract class BulletinBoardSQLServer implements BulletinBoardServer{
protected Connection connection; protected Connection connection;
@ -53,6 +57,7 @@ public abstract class BulletinBoardSQLServer implements BulletinBoardServer{
* @return TRUE if the message is authenticated and FALSE otherwise. * @return TRUE if the message is authenticated and FALSE otherwise.
*/ */
private boolean verifyMessage(BulletinBoardMessage msg) { private boolean verifyMessage(BulletinBoardMessage msg) {
//TODO: Replace with actual verification.
return true; return true;
} }
@ -60,8 +65,9 @@ public abstract class BulletinBoardSQLServer implements BulletinBoardServer{
* This procedure makes sure that all tags in the given list have an entry in the tags list. * This procedure makes sure that all tags in the given list have an entry in the tags list.
* @param tagIterator * @param tagIterator
*/ */
protected abstract void insertNewTags(String[] tags) throws CommunicationException; protected abstract void insertNewTags(String[] tags) throws SQLException;
@POST
@Override @Override
public boolean postMessage(BulletinBoardMessage msg) throws CommunicationException { public boolean postMessage(BulletinBoardMessage msg) throws CommunicationException {
if (!verifyMessage(msg)) { if (!verifyMessage(msg)) {
@ -85,17 +91,29 @@ public abstract class BulletinBoardSQLServer implements BulletinBoardServer{
sql = "INSERT INTO MsgTable (Id, Data, Signature) VALUES(?,?,?)"; sql = "INSERT INTO MsgTable (Id, Data, Signature) VALUES(?,?,?)";
pstmt = connection.prepareStatement(sql); pstmt = connection.prepareStatement(sql);
pstmt.setBytes(1, msgID); pstmt.setBytes(1, msgID);
pstmt.setBytes(2,msg.getMsg().getData().toByteArray()); pstmt.setBytes(2, msg.getMsg().getData().toByteArray());
pstmt.setBytes(3,msg.getSig().toByteArray()); pstmt.setBytes(3, msg.getSig().toByteArray());
pstmt.executeUpdate(); pstmt.executeUpdate();
pstmt.close(); pstmt.close();
} catch (SQLException e) {
throw new CommunicationException("Error inserting into MsgTable: " + e.getMessage());
}
try {
tagList = msg.getMsg().getTagsList(); tagList = msg.getMsg().getTagsList();
tags = new String[tagList.size()]; tags = new String[tagList.size()];
tags = tagList.toArray(tags);
insertNewTags(tags); insertNewTags(tags);
sql = "INSERT INTO MsgTagTable (MsgId, TagId) SELECT (?, TagId) FROM TagTable WHERE tag=?"; } catch (SQLException e) {
throw new CommunicationException(e.getMessage());
}
try{
sql = "INSERT INTO MsgTagTable (TagId, MsgId) SELECT TagTable.Id, ? AS MsgId FROM TagTable WHERE tag = ?";
pstmt = connection.prepareStatement(sql); pstmt = connection.prepareStatement(sql);
for (String tag : tags){ for (String tag : tags){
@ -108,19 +126,21 @@ public abstract class BulletinBoardSQLServer implements BulletinBoardServer{
pstmt.close(); pstmt.close();
} catch (SQLException e) { } catch (SQLException e) {
throw new CommunicationException("Error accessing DB: " + e.getMessage()); throw new CommunicationException("Error Linking tags: " + e.getMessage());
} }
return true; return true;
} }
@Override @Override
public List<BulletinBoardMessage> readMessages(MessageFilter filter, int max) { public List<BulletinBoardMessage> readMessages(MessageFilterList filterList, int max) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
return null; return null;
} }
public void testPrint(){ public String testPrint(){
String s = "";
try { try {
@ -128,20 +148,30 @@ public abstract class BulletinBoardSQLServer implements BulletinBoardServer{
ResultSet rs = statement.executeQuery("select * from MsgTable"); ResultSet rs = statement.executeQuery("select * from MsgTable");
while (rs.next()) { while (rs.next()) {
// read the result set // read the result set
System.out.println("data = " + rs.getString("Data")); s += "entry = " + rs.getInt("EntryNum") + " \n";
System.out.println("id = " + rs.getInt("Id")); s += "id = " + new String(rs.getBytes("Id")) + " \n";
s += "data = " + new String(rs.getBytes("Data")) + " \n";
s += "signature = " + new String(rs.getBytes("Signature")) + "\t\n<BR>";
}
rs = statement.executeQuery("select * from TagTable");
while (rs.next()) {
// read the result set
s += "Tag = " + rs.getString("Tag") + " \n";
s += "TagId = " + rs.getInt("Id") + "\t\n<BR>";
} }
rs = statement.executeQuery("select * from MsgTagTable"); rs = statement.executeQuery("select * from MsgTagTable");
while (rs.next()) { while (rs.next()) {
// read the result set // read the result set
System.out.println("MsgId = " + rs.getInt("MsgId")); s += "MsgId = " + new String(rs.getBytes("MsgId")) + " \n";
System.out.println("TagId = " + rs.getString("TagId")); s += "TagId = " + rs.getInt("TagId") + "\t\n<BR>";
} }
} catch(SQLException e){ } catch(SQLException e){
System.out.println("Error reading from DB"); s += "Error reading from DB";
} }
return s;
} }
} }

View File

@ -6,7 +6,7 @@ import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.List; import java.util.List;
import meerkat.bulletinboard.MessageFilter; import meerkat.protobuf.Voting.MessageFilterList;
import meerkat.bulletinboard.sqlserver.BulletinBoardSQLServer; import meerkat.bulletinboard.sqlserver.BulletinBoardSQLServer;
import meerkat.comm.CommunicationException; import meerkat.comm.CommunicationException;
import meerkat.protobuf.Voting.BulletinBoardMessage; import meerkat.protobuf.Voting.BulletinBoardMessage;
@ -27,13 +27,13 @@ public class SQLiteBulletinBoardServer extends BulletinBoardSQLServer {
try{ try{
connection = DriverManager.getConnection("jdbc:sqlite:./local-instances/meerkat.db"); connection = DriverManager.getConnection("jdbc:sqlite:local-instances/meerkat.db");
Statement statement = connection.createStatement(); Statement statement = connection.createStatement();
statement.setQueryTimeout(TIMEOUT); statement.setQueryTimeout(TIMEOUT);
statement.executeUpdate("CREATE TABLE IF NOT EXISTS MsgTable (EntryNum INTEGER, Id varbinary(1000) UNIQUE, Data varbinary(1000), Signature varbinary(1000), PRIMARY KEY (EntryNum ASC))"); statement.executeUpdate("CREATE TABLE IF NOT EXISTS MsgTable (EntryNum INTEGER PRIMARY KEY, Id BLOB UNIQUE, Data BLOB, Signature BLOB)");
statement.executeUpdate("CREATE TABLE IF NOT EXISTS TagTable (Id int, Tag v archar(50) UNIQUE, PRIMARY KEY (Id ASC))"); statement.executeUpdate("CREATE TABLE IF NOT EXISTS TagTable (Id INTEGER PRIMARY KEY, Tag varchar(50) UNIQUE)");
statement.executeUpdate("CREATE TABLE IF NOT EXISTS MsgTagTable (MsgId varbinary(1000), TagId int, FOREIGN KEY (MsgId) REFERENCES MsgTable(Id), FOREIGN KEY (TagId) REFERENCES TagTable(Id))"); statement.executeUpdate("CREATE TABLE IF NOT EXISTS MsgTagTable (MsgId BLOB, TagId INTEGER, FOREIGN KEY (MsgId) REFERENCES MsgTable(Id), FOREIGN KEY (TagId) REFERENCES TagTable(Id))");
statement.close(); statement.close();
@ -41,7 +41,7 @@ public class SQLiteBulletinBoardServer extends BulletinBoardSQLServer {
} catch (SQLException e) { } catch (SQLException e) {
throw new CommunicationException("Couldn't form a connection with the database"); throw new CommunicationException("Couldn't form a connection with the database" + e.getMessage());
} }
@ -49,7 +49,7 @@ public class SQLiteBulletinBoardServer extends BulletinBoardSQLServer {
@Override @Override
public List<BulletinBoardMessage> readMessages(MessageFilter filter, int max) { public List<BulletinBoardMessage> readMessages(MessageFilterList filterList, int max) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
return null; return null;
} }
@ -68,7 +68,7 @@ public class SQLiteBulletinBoardServer extends BulletinBoardSQLServer {
@Override @Override
protected void insertNewTags(String[] tags) throws CommunicationException { protected void insertNewTags(String[] tags) throws SQLException {
PreparedStatement pstmt; PreparedStatement pstmt;
String sql; String sql;
@ -87,7 +87,7 @@ public class SQLiteBulletinBoardServer extends BulletinBoardSQLServer {
pstmt.close(); pstmt.close();
} catch (SQLException e){ } catch (SQLException e){
throw new CommunicationException("Error adding new tags to table"); throw new SQLException("Error adding new tags to table: " + e.getMessage());
} }
} }

View File

@ -1,22 +1,54 @@
package meerkat.bulletinboard.webapp; package meerkat.bulletinboard.webapp;
import com.google.protobuf.ByteString;
import com.google.protobuf.Message; import com.google.protobuf.Message;
import meerkat.bulletinboard.service.HelloProtoBuf; import meerkat.bulletinboard.service.HelloProtoBuf;
import meerkat.protobuf.Crypto.Signature;
import meerkat.protobuf.Crypto.SignatureType;
import meerkat.protobuf.Voting.BulletinBoardMessage;
import meerkat.protobuf.Voting.UnsignedBulletinBoardMessage;
import meerkat.rest.Constants; import meerkat.rest.Constants;
import service.HelloWorldService;
import javax.annotation.PostConstruct;
import javax.ws.rs.GET; import javax.ws.rs.GET;
import javax.ws.rs.Path; import javax.ws.rs.Path;
import javax.ws.rs.Produces; import javax.ws.rs.Produces;
@Path("/proto") @Path("/proto")
public class HelloProtoWebApp { public class HelloProtoWebApp {
private static HelloProtoBuf helloProtoBuf = new HelloProtoBuf(); private HelloProtoBuf helloProtoBuf;
@PostConstruct
public void init(){
//helloProtoBuf = new HelloProtoBuf();
}
@GET @GET
@Produces(Constants.MEDIATYPE_PROTOBUF) @Produces(Constants.MEDIATYPE_PROTOBUF)
public Message hello() { public Message hello() {
return helloProtoBuf.sayHello(); byte[] b1 = {(byte) 1, (byte)2, (byte) 3, (byte) 4};
byte[] b2 = {(byte) 11, (byte)12, (byte) 13, (byte) 14};
Message msg;
if (helloProtoBuf != null){
msg = helloProtoBuf.sayHello();
}
else{
msg = BulletinBoardMessage.newBuilder()
.setMsg(UnsignedBulletinBoardMessage.newBuilder()
.addTags("signature")
.addTags("Trustee")
.setData(ByteString.copyFrom(b1))
.build())
.setSig(Signature.newBuilder()
.setType(SignatureType.DSA)
.setData(ByteString.copyFrom(b2))
.build())
.build();
}
return msg;
} }
} }

View File

@ -0,0 +1,57 @@
package meerkat.bulletinboard.webapp;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import com.google.protobuf.ByteString;
import meerkat.bulletinboard.sqlserver.SQLiteBulletinBoardServer;
import meerkat.comm.CommunicationException;
import meerkat.protobuf.Crypto.*;
import meerkat.protobuf.Voting.*;
@Path("/test")
public class SQLiteServerTest {
@GET
public Response main(){
byte[] b1 = {(byte) 1, (byte)2, (byte) 3, (byte) 4};
byte[] b2 = {(byte) 11, (byte)12, (byte) 13, (byte) 14};
Response response;
BulletinBoardMessage msg;
try{
msg = BulletinBoardMessage.newBuilder()
.setMsg(UnsignedBulletinBoardMessage.newBuilder()
.addTags("Signature")
.addTags("Trustee")
.setData(ByteString.copyFrom(b1))
.build())
.setSig(Signature.newBuilder()
.setType(SignatureType.DSA)
.setData(ByteString.copyFrom(b2))
.build())
.build();
SQLiteBulletinBoardServer bbs = new SQLiteBulletinBoardServer();
bbs.init();
bbs.postMessage(msg);
response = Response.status(Status.OK).entity(bbs.testPrint()).build();
bbs.close();
} catch(CommunicationException e){
response = Response.status(Status.OK).entity(e.getMessage()).build();;
}
return response;
}
}

View File

@ -8,7 +8,7 @@ import org.junit.Test;
public class HelloIntegrationTest { public class HelloIntegrationTest {
private static String PROP_GETTY_URL = "gretty.httpBaseURI"; private static String PROP_GETTY_URL = "gretty.httpBaseURI";
private static String BASE_URL = System.getProperty(PROP_GETTY_URL); private static String BASE_URL = System.getProperty(PROP_GETTY_URL);
private static String HELLO_URL = BASE_URL + "/hello"; private static String HELLO_URL = BASE_URL + "/hello";
@Test @Test

View File

@ -1,41 +0,0 @@
package meerkat.bulletinboard;
import com.google.protobuf.ByteString;
import meerkat.bulletinboard.sqlserver.SQLiteBulletinBoardServer;
import meerkat.comm.CommunicationException;
import meerkat.protobuf.Crypto.*;
import meerkat.protobuf.Voting.*;
public class SQLiteIntegrationTest {
public static void main(){
byte[] b1 = {(byte) 1, (byte)2, (byte) 3, (byte) 4};
byte[] b2 = {(byte) 11, (byte)12, (byte) 13, (byte) 14};
BulletinBoardMessage msg = BulletinBoardMessage.newBuilder()
.setMsg(UnsignedBulletinBoardMessage.newBuilder()
.setTags(0, "signature")
.setTags(1, "Trustee")
.setData(ByteString.copyFrom(b1))
.build())
.setSig(Signature.newBuilder()
.setType(SignatureType.DSA)
.setData(ByteString.copyFrom(b2))
.build())
.build();
SQLiteBulletinBoardServer bbs = new SQLiteBulletinBoardServer();
try{
bbs.init();
bbs.postMessage(msg);
bbs.testPrint();
bbs.close();
} catch(CommunicationException e){
System.out.println(e.getMessage());
}
}
}

View File

@ -4,6 +4,7 @@ import java.util.List;
import meerkat.comm.CommunicationException; import meerkat.comm.CommunicationException;
import meerkat.protobuf.Voting.BulletinBoardMessage; import meerkat.protobuf.Voting.BulletinBoardMessage;
import meerkat.protobuf.Voting.MessageFilterList;
/** /**
* Created by Arbel on 07/11/15. * Created by Arbel on 07/11/15.
@ -35,7 +36,7 @@ public interface BulletinBoardServer{
* @param max maximum number of messages to return (0=no limit) * @param max maximum number of messages to return (0=no limit)
* @return * @return
*/ */
List<BulletinBoardMessage> readMessages(MessageFilter filter, int max); List<BulletinBoardMessage> readMessages(MessageFilterList filterList, int max);
/** /**
* This method closes the connection to the DB. * This method closes the connection to the DB.

View File

@ -1,27 +0,0 @@
package meerkat.bulletinboard;
/**
* Created by talm on 25/10/15.
*
* A filter for messages (run on the BB server side).
*
* TODO: define a limited filter language (e.g., by tag, by signer, by time, etc.) that can
* be efficiently run on the BB database.
*
*/
public abstract class MessageFilter {
public enum FilterType{
ENTRY_NUM,
ID,
TAG,
SIGNER,
TIME
}
FilterType filterType;
public MessageFilter(FilterType filterType){
}
}

View File

@ -28,6 +28,30 @@ message BulletinBoardMessage {
meerkat.Signature sig = 2; meerkat.Signature sig = 2;
} }
enum FilterType {
ID = 0; // Match exact message ID
EXACT_ENTRY = 1; // Match exact entry number in database (chronological)
MAX_ENTRY = 2; // Find all entries in database up to specified entry number (chronological)
SIGNATURE = 3; // Find all entries in database that correspond to specific signature (signer)
TAG = 4; // Find all entries in database that have a specific tag
}
message MessageFilter {
FilterType type = 1;
// Concrete data input to filter
bytes filter = 2;
}
message MessageFilterList {
// Combination of filters.
// To be implemented using intersection ("AND") operations.
repeated MessageFilter filters = 1;
}
// A ballot question. This is an opaque // A ballot question. This is an opaque
// data type that is parsed by the UI to display // data type that is parsed by the UI to display
// the question. // the question.