diff --git a/voter-registry/src/main/java/meerkat/SimpleRegistry.java b/voter-registry/src/main/java/meerkat/SimpleRegistry.java index 89dd39a..4422fac 100644 --- a/voter-registry/src/main/java/meerkat/SimpleRegistry.java +++ b/voter-registry/src/main/java/meerkat/SimpleRegistry.java @@ -10,9 +10,11 @@ import meerkat.crypto.Encryption; import meerkat.protobuf.BulletinBoardAPI; import meerkat.protobuf.Crypto; import util.AccurateTimestamp; -import util.RegistryTagTypes; +import util.CollectionMessagesUtils; +import util.Tags; import java.io.IOException; +import java.text.ParseException; import java.util.*; /** @@ -44,13 +46,13 @@ public class SimpleRegistry { */ public void AddVoter(String voterID, String personalData) throws CommunicationException, IOException { Tag.Builder idTag = Tag.newBuilder(); - idTag.setContent(RegistryTagTypes.ID_TAG + " " + voterID); + idTag.setContent(Tags.ID_TAG + " " + voterID); Tag.Builder voterEntryTag = Tag.newBuilder(); - voterEntryTag.setContent(RegistryTagTypes.VOTER_ENTRY_TAG); + voterEntryTag.setContent(Tags.VOTER_ENTRY_TAG.toString()); Tag.Builder timestampTag = Tag.newBuilder(); - timestampTag.setContent(RegistryTagTypes.ACTION_TIMESTAMP_TAG + " " + timestampTag.setContent(Tags.ACTION_TIMESTAMP_TAG + " " + AccurateTimestamp.GetCurrentTimestampString()); BasicMessage.Builder basicMessage = @@ -69,16 +71,16 @@ public class SimpleRegistry { */ public void AddToGroup(String voterID, String groupID) throws CommunicationException, IOException { Tag.Builder idTag = Tag.newBuilder(); - idTag.setContent(RegistryTagTypes.ID_TAG + " " + voterID); + idTag.setContent(Tags.ID_TAG + " " + voterID); Tag.Builder groupIDTag = Tag.newBuilder(); - groupIDTag.setContent(RegistryTagTypes.GROUP_ID_TAG + " " + groupID); + groupIDTag.setContent(Tags.GROUP_ID_TAG + " " + groupID); Tag.Builder actionTag = Tag.newBuilder(); - actionTag.setContent(RegistryTagTypes.GROUP_ACTION_TAG + " " + RegistryTagTypes.ADD_TO_GROUP_TAG); + actionTag.setContent(Tags.GROUP_ACTION_TAG + " " + Tags.ADD_TO_GROUP_TAG); Tag.Builder timestampTag = Tag.newBuilder(); - timestampTag.setContent(RegistryTagTypes.ACTION_TIMESTAMP_TAG + " " + timestampTag.setContent(Tags.ACTION_TIMESTAMP_TAG + " " +AccurateTimestamp.GetCurrentTimestampString()); BasicMessage.Builder basicMessage = @@ -96,16 +98,16 @@ public class SimpleRegistry { */ public void RemoveFromGroup(String voterID, String groupID) throws CommunicationException, IOException { Tag.Builder idTag = Tag.newBuilder(); - idTag.setContent(RegistryTagTypes.ID_TAG + " " + voterID); + idTag.setContent(Tags.ID_TAG + " " + voterID); Tag.Builder groupIDTag = Tag.newBuilder(); - groupIDTag.setContent(RegistryTagTypes.GROUP_ID_TAG + " " + groupID); + groupIDTag.setContent(Tags.GROUP_ID_TAG + " " + groupID); Tag.Builder actionTag = Tag.newBuilder(); - actionTag.setContent(RegistryTagTypes.GROUP_ACTION_TAG + " " + RegistryTagTypes.REMOVE_FROM_GROUP_TAG); + actionTag.setContent(Tags.GROUP_ACTION_TAG + " " + Tags.REMOVE_FROM_GROUP_TAG); Tag.Builder timestampTag = Tag.newBuilder(); - timestampTag.setContent(RegistryTagTypes.ACTION_TIMESTAMP_TAG + " " + timestampTag.setContent(Tags.ACTION_TIMESTAMP_TAG + " " +AccurateTimestamp.GetCurrentTimestampString()); BasicMessage.Builder basicMessage = @@ -122,13 +124,13 @@ public class SimpleRegistry { */ public void SetVoted(String id) throws CommunicationException, IOException { Tag.Builder idTag = Tag.newBuilder(); - idTag.setContent(RegistryTagTypes.ID_TAG + " " + id); + idTag.setContent(Tags.ID_TAG + " " + id); Tag.Builder voteAction = Tag.newBuilder(); - voteAction.setContent(RegistryTagTypes.VOTE_ACTION_TAG); + voteAction.setContent(Tags.VOTE_ACTION_TAG.toString()); Tag.Builder timestampTag = Tag.newBuilder(); - timestampTag.setContent(RegistryTagTypes.ACTION_TIMESTAMP_TAG + " " + timestampTag.setContent(Tags.ACTION_TIMESTAMP_TAG + " " +AccurateTimestamp.GetCurrentTimestampString()); BasicMessage.Builder basicMessage = BasicMessage.newBuilder().addTag(idTag).addTag(voteAction).addTag(timestampTag); @@ -146,20 +148,16 @@ public class SimpleRegistry { BulletinBoardAPI.BulletinBoardMessage.Builder bulletinBoardMessage = BulletinBoardAPI.BulletinBoardMessage.newBuilder(); - // signs the basic message Crypto.RerandomizableEncryptedMessage encryptedMessage = signatory.encrypt(basicMessage, signatory.generateRandomness(new Random())); - // creates the signature of signed basic message Crypto.Signature.Builder messageSignature = Crypto.Signature.newBuilder(); messageSignature.mergeFrom(encryptedMessage); - // creates the unsigned basic message BulletinBoardAPI.UnsignedBulletinBoardMessage.Builder unsignedBulletinBoardMessage = BulletinBoardAPI.UnsignedBulletinBoardMessage.newBuilder(); unsignedBulletinBoardMessage.setData(basicMessage.toByteString()); - // sets the signature and the byte array bulletinBoardMessage.addSig(messageSignature); bulletinBoardMessage.setMsg(unsignedBulletinBoardMessage); @@ -177,45 +175,15 @@ public class SimpleRegistry { BulletinBoardAPI.MessageFilterList.newBuilder(); BulletinBoardAPI.MessageFilter.Builder idFilter = - BulletinBoardAPI.MessageFilter.newBuilder().setTag(RegistryTagTypes.ID_TAG + " " + id) - .setTag(RegistryTagTypes.GROUP_ACTION_TAG + " " + RegistryTagTypes.ADD_TO_GROUP_TAG) - .setTag(RegistryTagTypes.GROUP_ACTION_TAG + " " + RegistryTagTypes.REMOVE_FROM_GROUP_TAG); + BulletinBoardAPI.MessageFilter.newBuilder().setTag(Tags.ID_TAG + " " + id) + .setTag(Tags.GROUP_ACTION_TAG + " " + Tags.ADD_TO_GROUP_TAG) + .setTag(Tags.GROUP_ACTION_TAG + " " + Tags.REMOVE_FROM_GROUP_TAG); filters.addFilter(idFilter); return communicator.readMessages(filters.build()); } - /** - * Gets all the basic messages from bulletin board messages - * @param listOfMessages - * @return List G - * @throws InvalidProtocolBufferException - */ - private List GetBasicMessagesFromBulletinBoardMessages( - List listOfMessages) throws InvalidProtocolBufferException { - - List basicMessages = new ArrayList(); - - for (BulletinBoardAPI.BulletinBoardMessage bulletinBoardMessage : listOfMessages){ - BasicMessage.Builder basicMessage = - BasicMessage.newBuilder().mergeFrom(bulletinBoardMessage.getMsg().getData()); - basicMessages.add(basicMessage.build()); - } - - return basicMessages; - } - - - private List GetAllGroupsIdsUserIn(List messages){ - Map groupIdToMessage = new HashMap(); - List latestStateOfGroup = new ArrayList(); - - for (BasicMessage message : messages) { - BasicMessage temporary = groupIdToMessage.get(message.get) - } - } - /** * Requests all the groups that the given id voter is in @@ -223,28 +191,35 @@ public class SimpleRegistry { * @return list of groups ids (or names), if the method fails its empty * @throws CommunicationException */ - public List GetGroups(String id) throws CommunicationException { + public List GetGroups(String id) throws CommunicationException, InvalidProtocolBufferException { List relevantMessages = GetRelevantMessages(id); - List groups = new ArrayList(); + List messages = + CollectionMessagesUtils.GetBasicMessagesFromBulletinBoardMessages(relevantMessages); - - /** - * Retrieve all List that contains this id - * creates new list of strings with the names of the group - * Returns the created list - */ + List voterRegistryMessages = + CollectionMessagesUtils.ConvertToVoterRegistryMessages(messages); + try{ + Map groupIdToMessage = + CollectionMessagesUtils.GetLatestGroupsActions(voterRegistryMessages); + return CollectionMessagesUtils.GetListOfGroupIds(groupIdToMessage); + } + catch (ParseException e) + { + // write log + return null; + } } /** - * Retreives list of strings that represents voter + * Retrieves list of strings that represents voter * @param id * @return list of strings (empty list if the lookup failed) * @throws CommunicationException */ public List GetPersonIDDetails(String id) throws CommunicationException { /** - * Retreive all List that contains this id + * Retrieve all List that contains this id * search for message with the wanted personal data * Create list with personal data * return the list diff --git a/voter-registry/src/main/java/meerkat/VoterRegistryMessage.java b/voter-registry/src/main/java/meerkat/VoterRegistryMessage.java new file mode 100644 index 0000000..6426b9c --- /dev/null +++ b/voter-registry/src/main/java/meerkat/VoterRegistryMessage.java @@ -0,0 +1,64 @@ +package meerkat; + +import util.AccurateTimestamp; +import util.Tags; + +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(Tags 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(Tags.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(Tags.ADD_TO_GROUP_TAG.toString())) { + return true; + } + } + return false; + } +} diff --git a/voter-registry/src/main/java/util/AccurateTimestamp.java b/voter-registry/src/main/java/util/AccurateTimestamp.java index 680bf18..e4cbd98 100644 --- a/voter-registry/src/main/java/util/AccurateTimestamp.java +++ b/voter-registry/src/main/java/util/AccurateTimestamp.java @@ -27,7 +27,7 @@ public abstract class AccurateTimestamp { * @return * @throws ParseException */ - public static java.sql.Timestamp GetCurrentTimestampFromString(String timestamp) 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()); } diff --git a/voter-registry/src/main/java/util/CollectionMessagesUtils.java b/voter-registry/src/main/java/util/CollectionMessagesUtils.java new file mode 100644 index 0000000..9b809a5 --- /dev/null +++ b/voter-registry/src/main/java/util/CollectionMessagesUtils.java @@ -0,0 +1,96 @@ +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 Dasha on 1/15/2016. + */ +public abstract class CollectionMessagesUtils { + + /** + * Converts lost of BasicMessages to VoterRegistryMessags + * @param messages list + * @return List + */ + public static List ConvertToVoterRegistryMessages(List messages){ + List voterRegistryMessages = new ArrayList(); + 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 + * @return Map + * @throws ParseException + */ + public static Map GetLatestGroupsActions(List messages) throws ParseException { + + Map groupIdToMessage = new HashMap(); + + // 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(Tags.GROUP_ID_TAG); + VoterRegistryMessage temp = groupIdToMessage.get(groupId); + + if (temp != null) { + if (temp != messages.get(i)) { + if (temp.GetBasicMessageActionTimestamp().compareTo(messages.get(i).GetBasicMessageActionTimestamp()) < 0) { + 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 + * @return List + */ + public static List GetListOfGroupIds(Map groupIdToMessage) { + List groupsIds = new ArrayList(); + + for (VoterRegistryMessage message : groupIdToMessage.values()) { + if (message.IsGroupAdding()) { + String groupId = message.GetWantedTagFromBasicMessage(Tags.GROUP_ID_TAG); + groupsIds.add(groupId); + } + } + return groupsIds; + } + + /** + * Gets all the basic messages from bulletin board messages + * @param listOfMessages + * @return List G + * @throws InvalidProtocolBufferException + */ + public static final List GetBasicMessagesFromBulletinBoardMessages( + List listOfMessages) throws InvalidProtocolBufferException { + + List basicMessages = new ArrayList(); + + for (BulletinBoardAPI.BulletinBoardMessage bulletinBoardMessage : listOfMessages){ + ProtobufsMessages.BasicMessage.Builder basicMessage = + ProtobufsMessages.BasicMessage.newBuilder().mergeFrom(bulletinBoardMessage.getMsg().getData()); + basicMessages.add(basicMessage.build()); + } + + return basicMessages; + } +} diff --git a/voter-registry/src/main/java/util/MessagesUtils.java b/voter-registry/src/main/java/util/MessagesUtils.java deleted file mode 100644 index d98c0d4..0000000 --- a/voter-registry/src/main/java/util/MessagesUtils.java +++ /dev/null @@ -1,51 +0,0 @@ -package util; - -import com.google.protobuf.InvalidProtocolBufferException; -import meerkat.ProtobufsMessages; -import meerkat.protobuf.BulletinBoardAPI; - -import java.util.ArrayList; -import java.util.List; - -/** - * Created by Dasha on 1/15/2016. - */ -public abstract class MessagesUtils { - - /** - * Gets all the basic messages from bulletin board messages - * @param listOfMessages - * @return List G - * @throws InvalidProtocolBufferException - */ - public static final List GetBasicMessagesFromBulletinBoardMessages( - List listOfMessages) throws InvalidProtocolBufferException { - - List basicMessages = new ArrayList(); - - for (BulletinBoardAPI.BulletinBoardMessage bulletinBoardMessage : listOfMessages){ - ProtobufsMessages.BasicMessage.Builder basicMessage = - ProtobufsMessages.BasicMessage.newBuilder().mergeFrom(bulletinBoardMessage.getMsg().getData()); - basicMessages.add(basicMessage.build()); - } - - return basicMessages; - } - - /** - * Gets the wanted tag from given basic message - * @param message - * @param tagName - * @return string - */ - public static final String GetWantedTagFromBasicMessage(ProtobufsMessages.BasicMessage message, Tags tagName){ - List tags = message.getTagList(); - - for (ProtobufsMessages.Tag tag : tags) { - if ( tag.getContent().contains(tagName.toString())) { - return tag.getContent(); - } - } - return null; - } -} diff --git a/voter-registry/src/main/java/util/RegistryTagTypes.java b/voter-registry/src/main/java/util/RegistryTagTypes.java index f3eae81..2d1b10b 100644 --- a/voter-registry/src/main/java/util/RegistryTagTypes.java +++ b/voter-registry/src/main/java/util/RegistryTagTypes.java @@ -4,26 +4,26 @@ package util; * Created by Vladimir Eliezer Tokarev on 1/9/2016. * Have the tags for the registry messages */ -public abstract class RegistryTagTypes { +public enum Tags { - private RegistryTagTypes(){} + 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"); - public static final String ID_TAG = "ID:"; + private final String text; - public static final String VOTER_ENTRY_TAG = "Voter Entry"; - - public static final String GROUP_ID_TAG = "Group ID:"; - - public static final String GROUP_ACTION_TAG = "Group Action:"; - - public static final String REMOVE_FROM_GROUP_TAG = "Remove From Group"; - - public static final String ADD_TO_GROUP_TAG = "Add To Group"; - - public static final String ACTION_TIMESTAMP_TAG = "Action timestamp: "; - - public static final String VOTE_ACTION_TAG = "Vote Action"; + Tags(final String text){ + this.text = text + } + public String toString(){ + return text; + } }