diff --git a/.gitignore b/.gitignore index 429a385..9793e15 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ out *.prefs *.project *.classpath +bulletin-board-server/local-instances/meerkat.db diff --git a/bulletin-board-server/build.gradle b/bulletin-board-server/build.gradle index ae8e028..e9f3a90 100644 --- a/bulletin-board-server/build.gradle +++ b/bulletin-board-server/build.gradle @@ -9,8 +9,10 @@ apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'idea' +//apply plugin: 'application' + //apply plugin: 'jetty' -//mainClassName = 'Demo' +//mainClassName = 'SQLiteIntegrationTest' apply plugin: 'maven-publish' @@ -42,6 +44,8 @@ dependencies { // Jersey for RESTful API compile 'org.glassfish.jersey.containers:jersey-container-servlet:2.22.+' + compile 'org.xerial:sqlite-jdbc:3.7.+' + // Logging compile 'org.slf4j:slf4j-api:1.7.7' @@ -68,6 +72,8 @@ task integrationTest(type: Test) { gretty { httpPort = 8081 + contextPath = '/' + servletContainer = 'jetty9' integrationTestTask = 'integrationTest' } diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java index 0ed06c9..de4e52e 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java @@ -2,6 +2,9 @@ package meerkat.bulletinboard.sqlserver; import java.util.List; +import javax.ws.rs.POST; +import javax.ws.rs.Path; + import com.google.protobuf.ProtocolStringList; import java.sql.Connection; @@ -11,7 +14,7 @@ import java.sql.SQLException; import java.sql.Statement; import meerkat.bulletinboard.BulletinBoardServer; -import meerkat.bulletinboard.MessageFilter; +import meerkat.protobuf.Voting.MessageFilterList; import meerkat.comm.CommunicationException; import meerkat.protobuf.Crypto.SignatureVerificationKey; import meerkat.protobuf.Voting.BulletinBoardMessage; @@ -19,6 +22,7 @@ import meerkat.crypto.Digest; import meerkat.crypto.concrete.SHA256Digest; import meerkat.protobuf.Voting.MessageID; +@Path("/SQLServer") public abstract class BulletinBoardSQLServer implements BulletinBoardServer{ protected Connection connection; @@ -53,6 +57,7 @@ public abstract class BulletinBoardSQLServer implements BulletinBoardServer{ * @return TRUE if the message is authenticated and FALSE otherwise. */ private boolean verifyMessage(BulletinBoardMessage msg) { + //TODO: Replace with actual verification. 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. * @param tagIterator */ - protected abstract void insertNewTags(String[] tags) throws CommunicationException; + protected abstract void insertNewTags(String[] tags) throws SQLException; + @POST @Override public boolean postMessage(BulletinBoardMessage msg) throws CommunicationException { if (!verifyMessage(msg)) { @@ -85,17 +91,29 @@ public abstract class BulletinBoardSQLServer implements BulletinBoardServer{ sql = "INSERT INTO MsgTable (Id, Data, Signature) VALUES(?,?,?)"; pstmt = connection.prepareStatement(sql); pstmt.setBytes(1, msgID); - pstmt.setBytes(2,msg.getMsg().getData().toByteArray()); - pstmt.setBytes(3,msg.getSig().toByteArray()); + pstmt.setBytes(2, msg.getMsg().getData().toByteArray()); + pstmt.setBytes(3, msg.getSig().toByteArray()); pstmt.executeUpdate(); pstmt.close(); + } catch (SQLException e) { + throw new CommunicationException("Error inserting into MsgTable: " + e.getMessage()); + } + + try { + tagList = msg.getMsg().getTagsList(); tags = new String[tagList.size()]; + tags = tagList.toArray(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); for (String tag : tags){ @@ -108,19 +126,21 @@ public abstract class BulletinBoardSQLServer implements BulletinBoardServer{ pstmt.close(); } catch (SQLException e) { - throw new CommunicationException("Error accessing DB: " + e.getMessage()); + throw new CommunicationException("Error Linking tags: " + e.getMessage()); } return true; } @Override - public List readMessages(MessageFilter filter, int max) { + public List readMessages(MessageFilterList filterList, int max) { // TODO Auto-generated method stub return null; } - public void testPrint(){ + public String testPrint(){ + + String s = ""; try { @@ -128,20 +148,30 @@ public abstract class BulletinBoardSQLServer implements BulletinBoardServer{ ResultSet rs = statement.executeQuery("select * from MsgTable"); while (rs.next()) { // read the result set - System.out.println("data = " + rs.getString("Data")); - System.out.println("id = " + rs.getInt("Id")); + s += "entry = " + rs.getInt("EntryNum") + " \n"; + 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
"; + } + + 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
"; } rs = statement.executeQuery("select * from MsgTagTable"); while (rs.next()) { // read the result set - System.out.println("MsgId = " + rs.getInt("MsgId")); - System.out.println("TagId = " + rs.getString("TagId")); + s += "MsgId = " + new String(rs.getBytes("MsgId")) + " \n"; + s += "TagId = " + rs.getInt("TagId") + "\t\n
"; } } catch(SQLException e){ - System.out.println("Error reading from DB"); + s += "Error reading from DB"; } + return s; } } diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/SQLiteBulletinBoardServer.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/SQLiteBulletinBoardServer.java index 6c9cf40..104ea57 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/SQLiteBulletinBoardServer.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/SQLiteBulletinBoardServer.java @@ -6,7 +6,7 @@ import java.sql.SQLException; import java.sql.Statement; import java.util.List; -import meerkat.bulletinboard.MessageFilter; +import meerkat.protobuf.Voting.MessageFilterList; import meerkat.bulletinboard.sqlserver.BulletinBoardSQLServer; import meerkat.comm.CommunicationException; import meerkat.protobuf.Voting.BulletinBoardMessage; @@ -27,13 +27,13 @@ public class SQLiteBulletinBoardServer extends BulletinBoardSQLServer { try{ - connection = DriverManager.getConnection("jdbc:sqlite:./local-instances/meerkat.db"); + connection = DriverManager.getConnection("jdbc:sqlite:local-instances/meerkat.db"); Statement statement = connection.createStatement(); 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 TagTable (Id int, Tag v archar(50) UNIQUE, PRIMARY KEY (Id ASC))"); - 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 MsgTable (EntryNum INTEGER PRIMARY KEY, Id BLOB UNIQUE, Data BLOB, Signature BLOB)"); + 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 BLOB, TagId INTEGER, FOREIGN KEY (MsgId) REFERENCES MsgTable(Id), FOREIGN KEY (TagId) REFERENCES TagTable(Id))"); statement.close(); @@ -41,7 +41,7 @@ public class SQLiteBulletinBoardServer extends BulletinBoardSQLServer { } 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 - public List readMessages(MessageFilter filter, int max) { + public List readMessages(MessageFilterList filterList, int max) { // TODO Auto-generated method stub return null; } @@ -68,7 +68,7 @@ public class SQLiteBulletinBoardServer extends BulletinBoardSQLServer { @Override - protected void insertNewTags(String[] tags) throws CommunicationException { + protected void insertNewTags(String[] tags) throws SQLException { PreparedStatement pstmt; String sql; @@ -87,7 +87,7 @@ public class SQLiteBulletinBoardServer extends BulletinBoardSQLServer { pstmt.close(); } catch (SQLException e){ - throw new CommunicationException("Error adding new tags to table"); + throw new SQLException("Error adding new tags to table: " + e.getMessage()); } } diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/HelloProtoWebApp.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/HelloProtoWebApp.java index cbe2ae5..ab2d952 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/HelloProtoWebApp.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/HelloProtoWebApp.java @@ -1,22 +1,54 @@ package meerkat.bulletinboard.webapp; +import com.google.protobuf.ByteString; import com.google.protobuf.Message; 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 service.HelloWorldService; +import javax.annotation.PostConstruct; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; @Path("/proto") public class HelloProtoWebApp { - private static HelloProtoBuf helloProtoBuf = new HelloProtoBuf(); - + private HelloProtoBuf helloProtoBuf; + + @PostConstruct + public void init(){ + //helloProtoBuf = new HelloProtoBuf(); + } + @GET @Produces(Constants.MEDIATYPE_PROTOBUF) 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; } } diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/SQLiteServerTest.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/SQLiteServerTest.java new file mode 100644 index 0000000..7206ad0 --- /dev/null +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/SQLiteServerTest.java @@ -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; + } + +} diff --git a/bulletin-board-server/src/test/java/HelloIntegrationTest.java b/bulletin-board-server/src/test/java/HelloIntegrationTest.java index 9de027e..3a01d5e 100644 --- a/bulletin-board-server/src/test/java/HelloIntegrationTest.java +++ b/bulletin-board-server/src/test/java/HelloIntegrationTest.java @@ -8,7 +8,7 @@ import org.junit.Test; public class HelloIntegrationTest { 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"; @Test diff --git a/bulletin-board-server/src/test/java/meerkat/bulletinboard/SQLiteIntegrationTest.java b/bulletin-board-server/src/test/java/meerkat/bulletinboard/SQLiteIntegrationTest.java deleted file mode 100644 index 0ebb8e0..0000000 --- a/bulletin-board-server/src/test/java/meerkat/bulletinboard/SQLiteIntegrationTest.java +++ /dev/null @@ -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()); - } - } -} diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java index fdd0b3c..05bdf47 100644 --- a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java @@ -4,6 +4,7 @@ import java.util.List; import meerkat.comm.CommunicationException; import meerkat.protobuf.Voting.BulletinBoardMessage; +import meerkat.protobuf.Voting.MessageFilterList; /** * 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) * @return */ - List readMessages(MessageFilter filter, int max); + List readMessages(MessageFilterList filterList, int max); /** * This method closes the connection to the DB. diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/MessageFilter.java b/meerkat-common/src/main/java/meerkat/bulletinboard/MessageFilter.java deleted file mode 100644 index 08dcb52..0000000 --- a/meerkat-common/src/main/java/meerkat/bulletinboard/MessageFilter.java +++ /dev/null @@ -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){ - - } - -} diff --git a/meerkat-common/src/main/proto/meerkat/voting.proto b/meerkat-common/src/main/proto/meerkat/voting.proto index 5d2586a..c7dcad3 100644 --- a/meerkat-common/src/main/proto/meerkat/voting.proto +++ b/meerkat-common/src/main/proto/meerkat/voting.proto @@ -28,6 +28,30 @@ message BulletinBoardMessage { 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 // data type that is parsed by the UI to display // the question.