Compare commits

...

19 Commits

Author SHA1 Message Date
Vladimir Eliezer Tokarev e75317efa9 Changed the RegistryTagsType to RegistryTags
The Name RegistryTags more indicative
2016-01-22 05:13:32 -08:00
Vladimir Eliezer Tokarev 5971e8c16e Added the SimpleRegistryTest
This object tests the simple registry functionality
2016-01-16 06:58:09 -08:00
Vladimir Eliezer Tokarev de835a8c13 Added the SimpleRegistryTest
This object tests the simple registry functionality
2016-01-16 06:57:12 -08:00
Vladimir Eliezer Tokarev 109135ae1b Changed the simpleRegistry file
Edited the GetPersonIDDetails method , and refactored the basic methods of upload data to BulletinBoardServer
2016-01-16 06:00:07 -08:00
Vladimir Eliezer Tokarev 7734ba8c91 Created VoterRegistryMessage
VoterRegistryMessage extending the abilities of the basic message also changed the
name of  MessagesUtils  to CollectionMessagesUtils because its suits more this class destination
2016-01-15 08:41:20 -08:00
Vladimir Eliezer Tokarev 8546a347ca Add the MessagesUtil file
This file contain helpfull methods for working with messages (such as basicMessage and BulletinBoardMessage)
2016-01-15 06:52:05 -08:00
Vladimir Eliezer Tokarev 65bc8bc160 Moved the AccurateTimeStamp and the RegistryTagTypes to package called util
This way the project files are more organized
2016-01-15 06:27:15 -08:00
Vladimir Eliezer Tokarev 36d94b41ab Added the AccurateTimestamp file
This file converts string timestamp to timestamp and the other way , its used for the SimpleRegistry tags
2016-01-15 05:04:43 -08:00
Vladimir Eliezer Tokarev 87e8ad9470 Changed the SimpleRegistry file
Managed to create the signatory and add empty builder
2016-01-15 02:28:02 -08:00
Vladimir Eliezer Tokarev 717c2e6e65 Changed the ProtobufMessages file
now using only the basic registry messages
2016-01-15 01:32:12 -08:00
Vladimir Eliezer Tokarev 51b9f9decd Changed the SimpleRegistry file
started to implement the different methods of this class (such as created basic messages)
2016-01-09 03:52:42 -08:00
Vladimir Eliezer Tokarev 05871a2ea7 Created RegistryTagTypes file
this file have the different tags for registry messages
2016-01-09 02:29:15 -08:00
Vladimir Eliezer Tokarev 070b851203 Created the SimpleRegistry file
SimpleRegistry expose the ability of manging voters information (their groups, and personal data)
2016-01-08 10:09:19 -08:00
Vladimir Eliezer Tokarev 4aa6c25c0f Changed the location of the ProtobufsMessages file
for creating more organized project
2016-01-08 08:40:04 -08:00
Vladimir Eliezer Tokarev 84555f0639 Changed the location of the Protobufs file and added the Registry class
The protobufs files location was changed for the right location of the packages for Registry
class be able to use the protobufs files
2016-01-08 08:07:15 -08:00
Vladimir Eliezer Tokarev 42bc35cbe8 Changed the location of the ProtobufsMessages file
so that the Registry file could use it freely
2016-01-08 07:55:59 -08:00
Vladimir Eliezer Tokarev f9d7b4b1ce Changed the location of the protobufs file
The location have been changed to create order in the packages
2016-01-08 07:41:26 -08:00
Vladimir Eliezer Tokarev 25eefc4b16 Added The protobufs file and its java representation
Those protobufs are representing the messages that the registry will use when communicating with the bulletin-board

D:/Work/Wombat Working/voter-registry/comment-info.txt
2016-01-08 06:00:40 -08:00
Arbel Deutsch Peled a12685d757 Stub Voter Registry project 2016-01-02 13:23:39 +02:00
13 changed files with 2282 additions and 1 deletions

View File

@ -0,0 +1,235 @@
plugins {
id "us.kirchmeier.capsule" version "1.0.1"
id 'com.google.protobuf' version '0.7.0'
}
apply plugin: 'java'
apply plugin: 'com.google.protobuf'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'maven-publish'
// Is this a snapshot version?
ext { isSnapshot = false }
ext {
groupId = 'org.factcenter.meerkat'
nexusRepository = "https://cs.idc.ac.il/nexus/content/groups/${isSnapshot ? 'unstable' : 'public'}/"
// Credentials for IDC nexus repositories (needed only for using unstable repositories and publishing)
// Should be set in ${HOME}/.gradle/gradle.properties
nexusUser = project.hasProperty('nexusUser') ? project.property('nexusUser') : ""
nexusPassword = project.hasProperty('nexusPassword') ? project.property('nexusPassword') : ""
}
description = "Meerkat Bulletin Board Client implementation"
// Your project version
version = "0.0"
version += "${isSnapshot ? '-SNAPSHOT' : ''}"
dependencies {
// Meerkat common
compile project(':meerkat-common')
compile project(':restful-api-common')
// 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'
runtime 'ch.qos.logback:logback-classic:1.1.2'
runtime 'ch.qos.logback:logback-core:1.1.2'
// Google protobufs
compile 'com.google.protobuf:protobuf-java:3.+'
// Crypto
compile 'org.factcenter.qilin:qilin:1.1+'
compile 'org.bouncycastle:bcprov-jdk15on:1.53'
compile 'org.bouncycastle:bcpkix-jdk15on:1.53'
testCompile 'junit:junit:4.+'
testCompile 'org.hamcrest:hamcrest-all:1.3'
runtime 'org.codehaus.groovy:groovy:2.4.+'
}
test {
exclude '**/*IntegrationTest*'
}
task integrationTest(type: Test) {
include '**/*IntegrationTest*'
// debug = true
outputs.upToDateWhen { false }
}
/*==== You probably don't have to edit below this line =======*/
// Setup test configuration that can appear as a dependency in
// other subprojects
configurations {
testOutput.extendsFrom (testCompile)
}
task testJar(type: Jar, dependsOn: testClasses) {
classifier = 'tests'
from sourceSets.test.output
}
artifacts {
testOutput testJar
}
// The run task added by the application plugin
// is also of type JavaExec.
tasks.withType(JavaExec) {
// Assign all Java system properties from
// the command line to the JavaExec task.
systemProperties System.properties
}
protobuf {
// Configure the protoc executable
protoc {
// Download from repositories
artifact = 'com.google.protobuf:protoc:3.+'
}
}
idea {
module {
project.sourceSets.each { sourceSet ->
def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java"
// add protobuf generated sources to generated source dir.
if ("test".equals(sourceSet.name)) {
testSourceDirs += file(srcDir)
} else {
sourceDirs += file(srcDir)
}
generatedSourceDirs += file(srcDir)
}
// Don't exclude build directory
excludeDirs -= file(buildDir)
}
}
/*===================================
* "Fat" Build targets
*===================================*/
if (project.hasProperty('mainClassName') && (mainClassName != null)) {
task mavenCapsule(type: MavenCapsule) {
description = "Generate a capsule jar that automatically downloads and caches dependencies when run."
applicationClass mainClassName
destinationDir = buildDir
}
task fatCapsule(type: FatCapsule) {
description = "Generate a single capsule jar containing everything. Use -Pfatmain=... to override main class"
destinationDir = buildDir
def fatMain = hasProperty('fatmain') ? fatmain : mainClassName
applicationClass fatMain
def testJar = hasProperty('test')
if (hasProperty('fatmain')) {
appendix = "fat-${fatMain}"
} else {
appendix = "fat"
}
if (testJar) {
from sourceSets.test.output
}
}
}
/*===================================
* Repositories
*===================================*/
repositories {
mavenLocal();
// Prefer the local nexus repository (it may have 3rd party artifacts not found in mavenCentral)
maven {
url nexusRepository
if (isSnapshot) {
credentials { username
password
username nexusUser
password nexusPassword
}
}
}
// Use 'maven central' for other dependencies.
mavenCentral()
}
task "info" << {
println "Project: ${project.name}"
println "Description: ${project.description}"
println "--------------------------"
println "GroupId: $groupId"
println "Version: $version (${isSnapshot ? 'snapshot' : 'release'})"
println ""
}
info.description 'Print some information about project parameters'
/*===================================
* Publishing
*===================================*/
publishing {
publications {
mavenJava(MavenPublication) {
groupId project.groupId
pom.withXml {
asNode().appendNode('description', project.description)
}
from project.components.java
}
}
repositories {
maven {
url "https://cs.idc.ac.il/nexus/content/repositories/${project.isSnapshot ? 'snapshots' : 'releases'}"
credentials { username
password
username nexusUser
password nexusPassword
}
}
}
}

View File

@ -4,4 +4,4 @@ include 'bulletin-board-server'
include 'polling-station'
include 'restful-api-common'
include 'bulletin-board-client'
include 'voter-registry'

3
voter-registry/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
/protoc.exe
/bin/
/comment-info.txt

195
voter-registry/build.gradle Normal file
View File

@ -0,0 +1,195 @@
plugins {
id "us.kirchmeier.capsule" version "1.0.1"
id 'com.google.protobuf' version '0.7.0'
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'maven-publish'
// Uncomment the lines below to define an application
// (this will also allow you to build a "fatCapsule" which includes
// the entire application, including all dependencies in a single jar)
//apply plugin: 'application'
//mainClassName='your.main.ApplicationClass'
// Is this a snapshot version?
ext { isSnapshot = false }
ext {
groupId = 'org.factcenter.meerkat'
nexusRepository = "https://cs.idc.ac.il/nexus/content/groups/${isSnapshot ? 'unstable' : 'public'}/"
// Credentials for IDC nexus repositories (needed only for using unstable repositories and publishing)
// Should be set in ${HOME}/.gradle/gradle.properties
nexusUser = project.hasProperty('nexusUser') ? project.property('nexusUser') : ""
nexusPassword = project.hasProperty('nexusPassword') ? project.property('nexusPassword') : ""
}
description = "Meerkat Voter SimpleRegistry application"
// Your project version
version = "0.0"
version += "${isSnapshot ? '-SNAPSHOT' : ''}"
dependencies {
// Meerkat common
compile project(':meerkat-common')
compile project(':bulletin-board-client')
// Logging
compile 'org.slf4j:slf4j-api:1.7.7'
runtime 'ch.qos.logback:logback-classic:1.1.2'
runtime 'ch.qos.logback:logback-core:1.1.2'
// Google protobufs
compile 'com.google.protobuf:protobuf-java:3.+'
testCompile 'junit:junit:4.+'
runtime 'org.codehaus.groovy:groovy:2.4.+'
}
/*==== You probably don't have to edit below this line =======*/
protobuf {
// Configure the protoc executable
protoc {
// Download from repositories
artifact = 'com.google.protobuf:protoc:3.+'
}
}
idea {
module {
project.sourceSets.each { sourceSet ->
def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java"
// add protobuf generated sources to generated source dir.
if ("test".equals(sourceSet.name)) {
testSourceDirs += file(srcDir)
} else {
sourceDirs += file(srcDir)
}
generatedSourceDirs += file(srcDir)
}
// Don't exclude build directory
excludeDirs -= file(buildDir)
}
}
/*===================================
* "Fat" Build targets
*===================================*/
if (project.hasProperty('mainClassName') && (mainClassName != null)) {
task mavenCapsule(type: MavenCapsule) {
description = "Generate a capsule jar that automatically downloads and caches dependencies when run."
applicationClass mainClassName
destinationDir = buildDir
}
task fatCapsule(type: FatCapsule) {
description = "Generate a single capsule jar containing everything. Use -Pfatmain=... to override main class"
destinationDir = buildDir
def fatMain = hasProperty('fatmain') ? fatmain : mainClassName
applicationClass fatMain
def testJar = hasProperty('test')
if (hasProperty('fatmain')) {
appendix = "fat-${fatMain}"
} else {
appendix = "fat"
}
if (testJar) {
from sourceSets.test.output
}
}
}
/*===================================
* Repositories
*===================================*/
repositories {
// Prefer the local nexus repository (it may have 3rd party artifacts not found in mavenCentral)
maven {
url nexusRepository
if (isSnapshot) {
credentials { username
password
username nexusUser
password nexusPassword
}
}
}
// Use local maven repository
mavenLocal()
// Use 'maven central' for other dependencies.
mavenCentral()
}
task "info" << {
println "Project: ${project.name}"
println "Description: ${project.description}"
println "--------------------------"
println "GroupId: $groupId"
println "Version: $version (${isSnapshot ? 'snapshot' : 'release'})"
println ""
}
info.description 'Print some information about project parameters'
/*===================================
* Publishing
*===================================*/
publishing {
publications {
mavenJava(MavenPublication) {
groupId project.groupId
pom.withXml {
asNode().appendNode('description', project.description)
}
from project.components.java
}
}
repositories {
maven {
url "https://cs.idc.ac.il/nexus/content/repositories/${project.isSnapshot ? 'snapshots' : 'releases'}"
credentials { username
password
username nexusUser
password nexusPassword
}
}
}
}

1
voter-registry/gradlew vendored Normal file
View File

@ -0,0 +1 @@
../gradlew

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,231 @@
package meerkat;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import meerkat.ProtobufsMessages.BasicMessage;
import meerkat.ProtobufsMessages.Tag;
import meerkat.bulletinboard.SimpleBulletinBoardClient;
import meerkat.comm.CommunicationException;
import meerkat.crypto.Encryption;
import meerkat.protobuf.BulletinBoardAPI;
import meerkat.protobuf.Crypto;
import util.AccurateTimestamp;
import util.CollectionMessagesUtils;
import util.RegistryTags;
import java.io.IOException;
import java.text.ParseException;
import java.util.*;
/**
* Created by Vladimir Eliezer Tokarev on 1/8/2016.
* Gives the ability to manage voters information
*/
public class SimpleRegistry {
protected Encryption signatory;
protected SimpleBulletinBoardClient communicator;
public SimpleRegistry(Encryption signatory, SimpleBulletinBoardClient communicator) {
this.signatory = signatory;
this.communicator = communicator;
}
private Tag.Builder[] GetTagsArrayInLength(int length) {
Tag.Builder[] tags = new Tag.Builder[length];
for (int i = 0; i < length; i++) {
tags[i] = Tag.newBuilder();
}
return tags;
}
/**
* Creates BulletinBoardMessage with signed basicMessage and UnsignedBulletinBoardMessage that contains the basic message
*
* @param basicMessage BasicMessage
* @return BulletinBoardAPI.BulletinBoardMessage
*/
private BulletinBoardAPI.BulletinBoardMessage CreateBulletinBoardMessage(BasicMessage basicMessage) throws IOException {
BulletinBoardAPI.BulletinBoardMessage.Builder bulletinBoardMessage =
BulletinBoardAPI.BulletinBoardMessage.newBuilder();
Crypto.RerandomizableEncryptedMessage encryptedMessage =
signatory.encrypt(basicMessage, signatory.generateRandomness(new Random()));
Crypto.Signature.Builder messageSignature = Crypto.Signature.newBuilder();
messageSignature.mergeFrom(encryptedMessage);
BulletinBoardAPI.UnsignedBulletinBoardMessage.Builder unsignedBulletinBoardMessage =
BulletinBoardAPI.UnsignedBulletinBoardMessage.newBuilder();
unsignedBulletinBoardMessage.setData(basicMessage.toByteString());
bulletinBoardMessage.addSig(messageSignature);
bulletinBoardMessage.setMsg(unsignedBulletinBoardMessage);
return bulletinBoardMessage.build();
}
/**
* Gets messages that have the wanted id tag and have or the ADD_TO_GROUP_TAG or REMOVE_FROM_GROUP_TAG
*
* @param tags the tags based on which the messages will be filtered
* @return List<BulletinBoardAPI.BulletinBoardMessage>
*/
private List<BulletinBoardAPI.BulletinBoardMessage> GetRelevantMessages(List<Tag> tags) {
BulletinBoardAPI.MessageFilterList.Builder filters =
BulletinBoardAPI.MessageFilterList.newBuilder();
for (Tag tag : tags) {
BulletinBoardAPI.MessageFilter.Builder idFilter =
BulletinBoardAPI.MessageFilter.newBuilder().setTag(tag.getContent());
filters.addFilter(idFilter);
}
return communicator.readMessages(filters.build());
}
/**
* Gets Relevant bulletinBoard messages from communicator than converts them to VoterRegistryMessages
*
* @param tags list of tags that will be used as filters
* @return List<VoterRegistryMessage>
*/
private List<VoterRegistryMessage> GetRelevantVoterRegistryMessages(List<Tag> tags) throws InvalidProtocolBufferException {
List<BulletinBoardAPI.BulletinBoardMessage> relevantMessages = GetRelevantMessages(tags);
List<BasicMessage> messages = CollectionMessagesUtils.GetBasicMessagesFromBulletinBoardMessages(relevantMessages);
List<VoterRegistryMessage> voterRegistryMessages = CollectionMessagesUtils.ConvertToVoterRegistryMessages(messages);
return voterRegistryMessages;
}
/**
* Adds new voter to the bulletin-board
*
* @param voterID
* @param personalData for example residence location
* @return void
* @throws throws CommunicationException
*/
public void AddVoter(String voterID, String personalData) throws CommunicationException, IOException {
Tag.Builder[] tags = GetTagsArrayInLength(3);
tags[0].setContent(RegistryTags.ID_TAG + " " + voterID);
tags[1].setContent(RegistryTags.VOTER_ENTRY_TAG.toString());
tags[2].setContent(RegistryTags.ACTION_TIMESTAMP_TAG + " " + AccurateTimestamp.GetCurrentTimestampString());
BasicMessage.Builder basicMessage = BasicMessage.newBuilder().addTag(tags[0]).addTag(tags[1]).addTag(tags[1]);
basicMessage.setData(ByteString.copyFrom(personalData.getBytes()));
communicator.postMessage(CreateBulletinBoardMessage(basicMessage.build()));
}
/**
* Adding given voter to given group
*
* @param voterID
* @param groupID
* @return true if the adding action succeeded else return false
* @throws CommunicationException
*/
public void AddToGroup(String voterID, String groupID) throws CommunicationException, IOException {
Tag.Builder[] tags = GetTagsArrayInLength(4);
tags[0].setContent(RegistryTags.ID_TAG + " " + voterID);
tags[1].setContent(RegistryTags.GROUP_ID_TAG + " " + groupID);
tags[2].setContent(RegistryTags.GROUP_ACTION_TAG + " " + RegistryTags.ADD_TO_GROUP_TAG);
tags[3].setContent(RegistryTags.ACTION_TIMESTAMP_TAG + " " + AccurateTimestamp.GetCurrentTimestampString());
BasicMessage.Builder basicMessage =
BasicMessage.newBuilder().addTag(tags[0]).addTag(tags[1]).addTag(tags[2]).addTag(tags[3]);
communicator.postMessage(CreateBulletinBoardMessage(basicMessage.build()));
}
/**
* Removes given voter from given group
*
* @param voterID
* @param groupID
* @return true if the removing action succeeded else return false
* @throws CommunicationException
*/
public void RemoveFromGroup(String voterID, String groupID) throws CommunicationException, IOException {
Tag.Builder[] tags = GetTagsArrayInLength(4);
tags[0].setContent(RegistryTags.ID_TAG + " " + voterID);
tags[1].setContent(RegistryTags.GROUP_ID_TAG + " " + groupID);
tags[2].setContent(RegistryTags.GROUP_ACTION_TAG + " " + RegistryTags.REMOVE_FROM_GROUP_TAG);
tags[3].setContent(RegistryTags.ACTION_TIMESTAMP_TAG + " " + AccurateTimestamp.GetCurrentTimestampString());
BasicMessage.Builder basicMessage =
BasicMessage.newBuilder().addTag(tags[0]).addTag(tags[1]).addTag(tags[2]).addTag(tags[3]);
communicator.postMessage(CreateBulletinBoardMessage(basicMessage.build()));
}
/**
* Sets that the voter have voted
*
* @param id id tag string
* @return true if the set voted succeded else false
* @throws CommunicationException
*/
public void AddVoter(String id) throws CommunicationException, IOException {
Tag.Builder[] tags = GetTagsArrayInLength(3);
tags[0].setContent(RegistryTags.ID_TAG + " " + id);
tags[1].setContent(RegistryTags.VOTE_ACTION_TAG.toString());
tags[2].setContent(RegistryTags.ACTION_TIMESTAMP_TAG + " " + AccurateTimestamp.GetCurrentTimestampString());
BasicMessage.Builder basicMessage = BasicMessage.newBuilder().addTag(tags[0]).addTag(tags[1]).addTag(tags[2]);
communicator.postMessage(CreateBulletinBoardMessage(basicMessage.build()));
}
/**
* Requests all the groups that the given id voter is in
*
* @param id id tag string
* @return list of groups ids (or names), if the method fails its empty
* @throws CommunicationException, InvalidProtocolBufferException
*/
public List<String> GetGroups(String id) throws CommunicationException, InvalidProtocolBufferException {
List<Tag> GroupsActionsTags = new ArrayList<Tag>();
GroupsActionsTags.add(Tag.newBuilder().setContent(RegistryTags.ID_TAG + " " + id).build());
GroupsActionsTags.add(Tag.newBuilder().setContent(RegistryTags.GROUP_ACTION_TAG + " " + RegistryTags.REMOVE_FROM_GROUP_TAG).build());
GroupsActionsTags.add(Tag.newBuilder().setContent(RegistryTags.GROUP_ACTION_TAG + " " + RegistryTags.ADD_TO_GROUP_TAG).build());
List<VoterRegistryMessage> voterRegistryMessages = GetRelevantVoterRegistryMessages(GroupsActionsTags);
try {
Map<String, VoterRegistryMessage> groupIdToMessage = CollectionMessagesUtils.GetLatestGroupsActions(voterRegistryMessages);
return CollectionMessagesUtils.GetListOfGroupIds(groupIdToMessage);
} catch (ParseException e) {
return null;
}
}
/**
* Retrieves list of strings that represents voter
*
* @param id id tag string
* @return list of strings (empty list if the lookup failed)
* @throws CommunicationException
*/
public List<String> GetPersonIDDetails(String id) throws CommunicationException, InvalidProtocolBufferException, ParseException {
List<Tag> GroupsActionsTags = new ArrayList<Tag>();
GroupsActionsTags.add(Tag.newBuilder().setContent(RegistryTags.ID_TAG + " " + id).build());
GroupsActionsTags.add(Tag.newBuilder().setContent(RegistryTags.VOTER_ENTRY_TAG.toString()).build());
List<VoterRegistryMessage> voterRegistryMessages = GetRelevantVoterRegistryMessages(GroupsActionsTags);
VoterRegistryMessage LatestMessage = voterRegistryMessages.get(0);
for (VoterRegistryMessage message : voterRegistryMessages) {
if (message.GetBasicMessageActionTimestamp().before(LatestMessage.GetBasicMessageActionTimestamp())) {
LatestMessage = message;
}
}
return Arrays.asList(LatestMessage.GetWantedTagFromBasicMessage(RegistryTags.ID_TAG), LatestMessage.base.getData().toString());
}
}

View File

@ -0,0 +1,64 @@
package meerkat;
import util.AccurateTimestamp;
import util.RegistryTags;
import java.sql.Timestamp;
import java.text.ParseException;
/**
* Created by Vladimir Eliezer Tokarev on 1/15.2016
* this class wraps BasicMessage and gives the ability to find wanted tags
*/
public class VoterRegistryMessage {
public ProtobufsMessages.BasicMessage base;
public VoterRegistryMessage(ProtobufsMessages.BasicMessage message){
base = ProtobufsMessages.BasicMessage.newBuilder().addAllTag(message.getTagList()).build();
}
/**
* Gets the wanted tag from given basic message
* @param tagName
* @return string
*/
public String GetWantedTagFromBasicMessage(RegistryTags tagName){
for (ProtobufsMessages.Tag tag : base.getTagList()) {
if ( tag.getContent().contains(tagName.toString())) {
return tag.getContent();
}
}
return null;
}
/**
* Gets the timestamp of the tag adding
* @return Timestamp
* @throws ParseException
*/
public Timestamp GetBasicMessageActionTimestamp() throws ParseException {
for (ProtobufsMessages.Tag tag : base.getTagList()) {
if ( tag.getContent().contains(RegistryTags.ACTION_TIMESTAMP_TAG.toString())) {
String[] tagParts = tag.getContent().split(" ");
String timestamp = tagParts[tagParts.length - 1];
return AccurateTimestamp.GetTimestampFromString(timestamp);
}
}
return null;
}
/**
* Checks if the given message have the ADD_TO_GROUP_TAG
* @return
*/
public boolean IsGroupAdding() {
for (ProtobufsMessages.Tag tag : base.getTagList()) {
if ( tag.getContent().contains(RegistryTags.ADD_TO_GROUP_TAG.toString())) {
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,35 @@
package util;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Created by Vladimir Eliezer Tokarev on 1/15/2016.
* converts time stamps to strings and the other way
*/
public abstract class AccurateTimestamp {
private static final String DATE_FORMAT = "yyyy-MM-dd hh:mm:ss.SSS";
/**
* Converts current timestamp to string
* @return
*/
public static String GetCurrentTimestampString(){
return new SimpleDateFormat(DATE_FORMAT).format(new java.util.Date());
}
/**
* Convets string timesta,p tp java.sql.timestamp
* @param timestamp string
* @return
* @throws ParseException
*/
public static java.sql.Timestamp GetTimestampFromString(String timestamp) throws ParseException {
Date date = new SimpleDateFormat(DATE_FORMAT).parse(timestamp);
return new Timestamp(date.getTime());
}
}

View File

@ -0,0 +1,97 @@
package util;
import com.google.protobuf.InvalidProtocolBufferException;
import meerkat.ProtobufsMessages;
import meerkat.VoterRegistryMessage;
import meerkat.protobuf.BulletinBoardAPI;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by Vladimir Eliezer Tokarev on 1/15/2016.
* adds extra functionality to Messages collections
*/
public abstract class CollectionMessagesUtils {
/**
* Converts lost of BasicMessages to VoterRegistryMessags
* @param messages list<BasicMessages>
* @return List<VoterRegistryMessage>
*/
public static List<VoterRegistryMessage> ConvertToVoterRegistryMessages(List<ProtobufsMessages.BasicMessage> messages){
List<VoterRegistryMessage> voterRegistryMessages = new ArrayList<VoterRegistryMessage>();
for (ProtobufsMessages.BasicMessage message : messages){
voterRegistryMessages.add(new VoterRegistryMessage(message));
}
return voterRegistryMessages;
}
/**
* Gets map of GroupId to basicMessage, where the basicMessages are the last actions for those groups
* @param messages List<BasicMessages>
* @return Map<String, VoterRegistryMessage>
* @throws ParseException
*/
public static Map<String, VoterRegistryMessage> GetLatestGroupsActions(List<VoterRegistryMessage> messages) throws ParseException {
Map<String, VoterRegistryMessage> groupIdToMessage = new HashMap<String, VoterRegistryMessage>();
// iterate trough all the messages and put into the map the last updated groups actions
for (int i = 0; i < messages.size(); i++) {
String groupId = messages.get(i).GetWantedTagFromBasicMessage(RegistryTags.GROUP_ID_TAG);
VoterRegistryMessage temp = groupIdToMessage.get(groupId);
if (temp != null) {
if (temp != messages.get(i)) {
if (temp.GetBasicMessageActionTimestamp().before(messages.get(i).GetBasicMessageActionTimestamp())) {
groupIdToMessage.put(groupId, messages.get(i));
}
}
}
}
return groupIdToMessage;
}
/**
* Gets list of groups ids of the basicMessages that carried the adding to group tag
* @param groupIdToMessage Map<String, BasicMessage>
* @return List<String>
*/
public static List<String> GetListOfGroupIds(Map<String, VoterRegistryMessage> groupIdToMessage) {
List<String> groupsIds = new ArrayList<String>();
for (VoterRegistryMessage message : groupIdToMessage.values()) {
if (message.IsGroupAdding()) {
String groupId = message.GetWantedTagFromBasicMessage(RegistryTags.GROUP_ID_TAG);
groupsIds.add(groupId);
}
}
return groupsIds;
}
/**
* Gets all the basic messages from bulletin board messages
* @param listOfMessages
* @return List<BasicMessage> G
* @throws InvalidProtocolBufferException
*/
public static final List<ProtobufsMessages.BasicMessage> GetBasicMessagesFromBulletinBoardMessages(
List<BulletinBoardAPI.BulletinBoardMessage> listOfMessages) throws InvalidProtocolBufferException {
List<ProtobufsMessages.BasicMessage> basicMessages = new ArrayList<ProtobufsMessages.BasicMessage>();
for (BulletinBoardAPI.BulletinBoardMessage bulletinBoardMessage : listOfMessages){
ProtobufsMessages.BasicMessage.Builder basicMessage =
ProtobufsMessages.BasicMessage.newBuilder().mergeFrom(bulletinBoardMessage.getMsg().getData());
basicMessages.add(basicMessage.build());
}
return basicMessages;
}
}

View File

@ -0,0 +1,31 @@
package util;
/**
* Created by Vladimir Eliezer Tokarev on 1/9/2016.
* Have the tags for the registry messages
*/
public enum RegistryTags {
ID_TAG("ID:"),
VOTER_ENTRY_TAG("Voter Entry"),
GROUP_ID_TAG("Group ID:"),
GROUP_ACTION_TAG("Group Action:"),
REMOVE_FROM_GROUP_TAG("Remove From Group"),
ADD_TO_GROUP_TAG("Add To Group"),
ACTION_TIMESTAMP_TAG("Action timestamp: "),
VOTE_ACTION_TAG("Vote Action");
private final String text;
RegistryTags(final String text){
this.text = text;
}
public String toString(){
return text;
}
}

View File

@ -0,0 +1,12 @@
package meerkat;
option java_outer_classname = "ProtobufsMessages";
message Tag {
required string content = 1;
}
message BasicMessage {
repeated Tag tag = 1;
optional bytes data = 2;
}

View File

@ -0,0 +1,59 @@
import junit.framework.TestCase;
/**
* Created by Vladimir Eliezer Tokarev on 1/16/2016.
* Tests the Simple Registry contents
*
*/
public class SimpleRegistryTest extends TestCase{
/**
* Initialize SimpleRegistry object
*/
public void setUp(){
}
/**
* Test that add voter creates new correct bulletin board message and add the voter
*/
public void testAddVoter(){
}
/**
* Test that set voted posts creates correct bulletin board message and sets that the user have been voted
*/
public void testSetVoted(){
}
/**
* Test that add to group creates correct bulletin board message and adds a user to a group
*/
public void testAddToGroup(){
}
/**
* Test that remove from group creates correct bulletin board message and removes the user from a group
*/
public void testRemoveFromGroup(){
}
/**
* Test that get groups retrieves the right groups the user are in
*/
public void testGetGroups(){
}
/**
* Test that the personal data outputted about the user is right
*/
public void testGetPersonalIDDetails(){
}
}