Added the option to check if some voter have voted already.
parent
4d72d6083e
commit
6d807cdd4d
|
@ -1,23 +0,0 @@
|
|||
package meerkat;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Provides the validation option for objects
|
||||
* @param <T>
|
||||
*/
|
||||
public interface MessageValidator <T extends List<?>>
|
||||
{
|
||||
/**
|
||||
* Throws ValidationError when no part of the object is valid else return the valid part
|
||||
* @param object object which will be checked
|
||||
* @return T object
|
||||
*/
|
||||
T validate(T object) throws ValidationError;
|
||||
|
||||
class ValidationError extends Exception {
|
||||
public ValidationError(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -121,22 +121,28 @@ public class Registry implements VoterRegistry{
|
|||
}};
|
||||
|
||||
bulletinBoardClient.readMessages(MessageCollectionUtils.generateFiltersFromTags(GroupsActionsTags),
|
||||
new LatestMessagesCallBack(callback, signers));
|
||||
new LatestMessagesCallBack(callback, signers, "getGroups"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getPersonIDDetails(VoterID voterID, RegistryCallBack callback) {
|
||||
List<String> GroupsActionsTags = new ArrayList<String>() {{
|
||||
List<String> addVoterTags = new ArrayList<String>() {{
|
||||
add(RegistryTags.ID_TAG + voterID.getId());
|
||||
add(RegistryTags.VOTER_ENTRY_TAG);
|
||||
}};
|
||||
|
||||
bulletinBoardClient.readMessages(MessageCollectionUtils.generateFiltersFromTags(GroupsActionsTags),
|
||||
new LatestMessagesCallBack(callback, signers));
|
||||
bulletinBoardClient.readMessages(MessageCollectionUtils.generateFiltersFromTags(addVoterTags),
|
||||
new LatestMessagesCallBack(callback, signers, "getPersonIDDetails"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasVoted(VoterID voterId, RegistryCallBack callBack) {
|
||||
return false;
|
||||
public void hasVoted(VoterID voterId, RegistryCallBack callBack) {
|
||||
List<String> setVotedTags = new ArrayList<String>() {{
|
||||
add(RegistryTags.ID_TAG + voterId.getId());
|
||||
add(RegistryTags.VOTE_ACTION_TAG);
|
||||
}};
|
||||
|
||||
bulletinBoardClient.readMessages(MessageCollectionUtils.generateFiltersFromTags(setVotedTags),
|
||||
new LatestMessagesCallBack(callBack, signers, "hasVoted"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,6 +84,6 @@ public interface VoterRegistry {
|
|||
* @param callBack method that will be called with the when the result will be found
|
||||
* @return true if voter had voted
|
||||
*/
|
||||
boolean hasVoted(VoterID voterId, RegistryCallBack callBack);
|
||||
void hasVoted(VoterID voterId, RegistryCallBack callBack);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,58 +1,42 @@
|
|||
package meerkat.registry;
|
||||
|
||||
import com.google.common.util.concurrent.FutureCallback;
|
||||
import meerkat.MessageValidator;
|
||||
import meerkat.VoterRegistry.RegistryCallBack;
|
||||
import meerkat.crypto.DigitalSignature;
|
||||
import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage;
|
||||
import meerkat.protobuf.Crypto;
|
||||
import meerkat.util.TimestampComparator;
|
||||
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static meerkat.util.BulletinBoardUtils.GetListOfTags;
|
||||
import static meerkat.util.BulletinBoardUtils.findTagWithPrefix;
|
||||
|
||||
/**
|
||||
* TODO : add logging and verification of the messages
|
||||
* TODO : add logging and verification of the messages by Arbel Peled
|
||||
*/
|
||||
|
||||
/**
|
||||
* Created by Vladimir Eliezer Tokarev on 2/19/2016.
|
||||
* Gets latest data from given List<BulletinBoardMessage>
|
||||
*/
|
||||
public class LatestMessagesCallBack implements FutureCallback<List<BulletinBoardMessage>>, MessageValidator<List<BulletinBoardMessage>> {
|
||||
public class LatestMessagesCallBack implements FutureCallback<List<BulletinBoardMessage>> {
|
||||
public RegistryCallBack callback;
|
||||
protected Collection<DigitalSignature> validators;
|
||||
protected String type;
|
||||
|
||||
/**
|
||||
* init MessagesCallBack
|
||||
* @param callback voter registry callback object
|
||||
* @param validators DigitalSignature object
|
||||
*/
|
||||
public LatestMessagesCallBack(RegistryCallBack callback, Collection<DigitalSignature> validators) {
|
||||
public LatestMessagesCallBack(RegistryCallBack callback,
|
||||
Collection<DigitalSignature> validators, String type) {
|
||||
this.callback = callback;
|
||||
this.validators = validators;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given list have tags of type GROUP_ID_TAG or else
|
||||
* @param msg List<BulletinBoardAPI.BulletinBoardMessage>
|
||||
* @return true if the messages are with GROUP_ID_TAG tags
|
||||
*/
|
||||
private boolean isAddToGroupsList(List<BulletinBoardMessage> msg) {
|
||||
List<String> tags = msg.get(0).getMsg().getTagList();
|
||||
for (String tag : tags) {
|
||||
if(tag.contains(RegistryTags.GROUP_ID_TAG))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -70,12 +54,16 @@ public class LatestMessagesCallBack implements FutureCallback<List<BulletinBoard
|
|||
});
|
||||
|
||||
List<BulletinBoardMessage> messages = new ArrayList<BulletinBoardMessage>(){{add(lastAddedMessage);}};
|
||||
|
||||
if (isAddToGroupsList(msg)) {
|
||||
callback.handleResult(GetListOfTags(messages, RegistryTags.GROUP_ID_TAG));
|
||||
}
|
||||
else {
|
||||
callback.handleResult(lastAddedMessage);
|
||||
switch (type){
|
||||
case "getGroups" :
|
||||
callback.handleResult(GetListOfTags(messages, RegistryTags.GROUP_ID_TAG));
|
||||
break;
|
||||
case "getPersonIDDetails" : callback.handleResult(lastAddedMessage);
|
||||
break;
|
||||
case "hasVoted" :
|
||||
callback.handleResult(findTagWithPrefix(lastAddedMessage,
|
||||
RegistryTags.VOTE_ACTION_TAG) != null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,51 +75,4 @@ public class LatestMessagesCallBack implements FutureCallback<List<BulletinBoard
|
|||
public void onFailure(Throwable t) {
|
||||
callback.handleFailure(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* verify that the message is valid
|
||||
* @param message BulletinBoardMessage instance
|
||||
* @return true if the message is valid else false
|
||||
*/
|
||||
private boolean verifyMessage(BulletinBoardMessage message)
|
||||
{
|
||||
try {
|
||||
int counter = 0;
|
||||
for (Crypto.Signature signature : message.getSigList()) {
|
||||
for (DigitalSignature digitalSignature : validators) {
|
||||
if (signature.getSignerId().equals(digitalSignature.getSignerID()))
|
||||
{
|
||||
digitalSignature.initVerify(signature);
|
||||
if(digitalSignature.verify())
|
||||
{
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return counter == validators.size();
|
||||
} catch (CertificateException | InvalidKeyException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the valid messages from the list of bulletin board messages
|
||||
* @param object object which will be checked
|
||||
* @return List<BulletinBoardMessage>
|
||||
* @throws ValidationError
|
||||
*/
|
||||
@Override
|
||||
public List<BulletinBoardMessage> validate(List<BulletinBoardMessage> object) throws ValidationError {
|
||||
List<BulletinBoardMessage> verifiedMessages = new ArrayList<>(object.size());
|
||||
for (BulletinBoardMessage message : object)
|
||||
{
|
||||
if(verifyMessage(message))
|
||||
{
|
||||
verifiedMessages.add(message);
|
||||
}
|
||||
}
|
||||
return verifiedMessages;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import com.google.common.util.concurrent.FutureCallback;
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import junit.framework.TestCase;
|
||||
import meerkat.Registry;
|
||||
import meerkat.bulletinboard.AsyncBulletinBoardClient;
|
||||
|
@ -15,6 +14,7 @@ import meerkat.protobuf.VoterRegistry.VoterInfo;
|
|||
import meerkat.protobuf.Voting;
|
||||
import meerkat.registry.MessageCollectionUtils;
|
||||
import meerkat.registry.RegistryTags;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.math.BigInteger;
|
||||
|
@ -67,6 +67,7 @@ public class SimpleRegistryTest extends TestCase {
|
|||
|
||||
@Override
|
||||
public void handleFailure(Throwable throwable) {
|
||||
System.out.print(throwable);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -137,10 +138,16 @@ public class SimpleRegistryTest extends TestCase {
|
|||
return registry;
|
||||
}
|
||||
|
||||
private String generateString()
|
||||
{
|
||||
return new BigInteger(130, random).toString(32);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the creation of the registry have been successful
|
||||
*/
|
||||
public void testSimpleRegistryCreation() {
|
||||
@Test
|
||||
public void simpleRegistryCreation() {
|
||||
try {
|
||||
Registry registry = GetRegistry();
|
||||
} catch (Exception e) {
|
||||
|
@ -175,14 +182,30 @@ public class SimpleRegistryTest extends TestCase {
|
|||
return counter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads messages from bulletinBoardClient by given tags and return the callback handler
|
||||
* object
|
||||
*
|
||||
* @param tags list of strings that represents tags
|
||||
* @return DummyBulletinBoardCallBackHandler which method will be called
|
||||
*/
|
||||
private DummyBulletinBoardCallBackHandler readMessagesByTags(List<String> tags)
|
||||
{
|
||||
MessageFilterList filters = MessageCollectionUtils.generateFiltersFromTags(tags);
|
||||
DummyBulletinBoardCallBackHandler bulletinHandler = new DummyBulletinBoardCallBackHandler();
|
||||
bulletinBoardClient.readMessages(filters, bulletinHandler);
|
||||
return bulletinHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that add voter creates new correct bulletin board message and adds the voter
|
||||
*/
|
||||
public void testAddVoter() throws InvalidProtocolBufferException, InterruptedException {
|
||||
@Test
|
||||
public void testAddVoter() throws InterruptedException {
|
||||
DummyRegistryCallBackHandler<Boolean> handler = new DummyRegistryCallBackHandler<>();
|
||||
|
||||
String id = new BigInteger(130, random).toString(32);
|
||||
String data = new BigInteger(130, random).toString(32);
|
||||
String id = generateString();
|
||||
String data = generateString();
|
||||
VoterInfo voterInfo = VoterInfo.newBuilder().setId(VoterID.newBuilder().setId(id)).setInfo(data).build();
|
||||
|
||||
Registry registry = GetRegistry();
|
||||
|
@ -192,9 +215,7 @@ public class SimpleRegistryTest extends TestCase {
|
|||
assertEquals(1, handler.counter );
|
||||
|
||||
List<String> tags = new ArrayList<String>(){{ add(RegistryTags.VOTER_ENTRY_TAG);}};
|
||||
MessageFilterList filters = MessageCollectionUtils.generateFiltersFromTags(tags);
|
||||
DummyBulletinBoardCallBackHandler bulletinHandler = new DummyBulletinBoardCallBackHandler();
|
||||
bulletinBoardClient.readMessages(filters, bulletinHandler);
|
||||
DummyBulletinBoardCallBackHandler bulletinHandler = readMessagesByTags(tags);
|
||||
|
||||
jobSemaphore.acquire();
|
||||
|
||||
|
@ -208,10 +229,11 @@ public class SimpleRegistryTest extends TestCase {
|
|||
/**
|
||||
* Test that set voted posts creates correct bulletin board message and sets that the user have been voted
|
||||
*/
|
||||
public void testSetVoted() throws InvalidProtocolBufferException, InterruptedException {
|
||||
@Test
|
||||
public void testSetVoted() throws InterruptedException {
|
||||
DummyRegistryCallBackHandler<Boolean> handler = new DummyRegistryCallBackHandler<>();
|
||||
|
||||
String id = new BigInteger(130, random).toString(32);
|
||||
String id = generateString();
|
||||
VoterID voterInfo = VoterID.newBuilder().setId(id).build();
|
||||
|
||||
Registry registry = GetRegistry();
|
||||
|
@ -221,9 +243,7 @@ public class SimpleRegistryTest extends TestCase {
|
|||
assertEquals(1, handler.counter );
|
||||
|
||||
List<String> tags = new ArrayList<String>(){{ add(RegistryTags.VOTE_ACTION_TAG);}};
|
||||
MessageFilterList filters = MessageCollectionUtils.generateFiltersFromTags(tags);
|
||||
DummyBulletinBoardCallBackHandler bulletinHandler = new DummyBulletinBoardCallBackHandler();
|
||||
bulletinBoardClient.readMessages(filters, bulletinHandler);
|
||||
DummyBulletinBoardCallBackHandler bulletinHandler = readMessagesByTags(tags);
|
||||
|
||||
jobSemaphore.acquire();
|
||||
|
||||
|
@ -237,11 +257,12 @@ public class SimpleRegistryTest extends TestCase {
|
|||
/**
|
||||
* Test that get groups retrieves the right groups the user are in
|
||||
*/
|
||||
public void testAddToGroup() throws InvalidProtocolBufferException, InterruptedException {
|
||||
@Test
|
||||
public void testAddToGroup() throws InterruptedException {
|
||||
DummyRegistryCallBackHandler<Boolean> handler = new DummyRegistryCallBackHandler<>();
|
||||
|
||||
String voterId = new BigInteger(130, random).toString(32);
|
||||
String groupId = new BigInteger(130, random).toString(32);
|
||||
String voterId = generateString();
|
||||
String groupId = generateString();
|
||||
VoterRegistry.VoterRegistryMessage voterInfo = VoterRegistry.VoterRegistryMessage.newBuilder()
|
||||
.setVoterID(VoterID.newBuilder().setId(voterId))
|
||||
.addGroupID(GroupID.newBuilder().setId(groupId)).build();
|
||||
|
@ -250,12 +271,10 @@ public class SimpleRegistryTest extends TestCase {
|
|||
registry.setVoterGroups(voterInfo, handler);
|
||||
|
||||
jobSemaphore.acquire();
|
||||
assertEquals(1, handler.counter);
|
||||
assertEquals("The callback handler hasn't been called yet", 1, handler.counter);
|
||||
|
||||
List<String> tags = new ArrayList<String>(){{add(RegistryTags.ADD_TO_GROUP_TAG);}};
|
||||
MessageFilterList filters = MessageCollectionUtils.generateFiltersFromTags(tags);
|
||||
DummyBulletinBoardCallBackHandler bulletinHandler = new DummyBulletinBoardCallBackHandler();
|
||||
bulletinBoardClient.readMessages(filters, bulletinHandler);
|
||||
DummyBulletinBoardCallBackHandler bulletinHandler = readMessagesByTags(tags);
|
||||
|
||||
jobSemaphore.acquire();
|
||||
|
||||
|
@ -270,12 +289,13 @@ public class SimpleRegistryTest extends TestCase {
|
|||
/**
|
||||
* Test that remove from group creates correct bulletin board message and removes the user from a group
|
||||
*/
|
||||
public void testGetGroups() throws InvalidProtocolBufferException, InterruptedException {
|
||||
@Test
|
||||
public void testGetGroups() throws InterruptedException {
|
||||
DummyRegistryCallBackHandler<List<BulletinBoardMessage>> handler =
|
||||
new DummyRegistryCallBackHandler<>();
|
||||
|
||||
String voterId = new BigInteger(130, random).toString(32);
|
||||
String groupId = new BigInteger(130, random).toString(32);
|
||||
String voterId = generateString();
|
||||
String groupId = generateString();
|
||||
VoterRegistry.VoterRegistryMessage voterInfo = VoterRegistry.VoterRegistryMessage.newBuilder()
|
||||
.setVoterID(VoterID.newBuilder().setId(voterId))
|
||||
.addGroupID(GroupID.newBuilder().setId(groupId)).build();
|
||||
|
@ -286,7 +306,7 @@ public class SimpleRegistryTest extends TestCase {
|
|||
registry.setVoterGroups(voterInfo, handler);
|
||||
|
||||
jobSemaphore.acquire();
|
||||
assertEquals(1, handler.counter );
|
||||
assertEquals("The callback handler hasn't been called yet", 1, handler.counter );
|
||||
|
||||
DummyRegistryCallBackHandler<List<String>> groupsHandler = new DummyRegistryCallBackHandler<>();
|
||||
registry.getGroups(GroupID.newBuilder().setId(groupId).build(), groupsHandler);
|
||||
|
@ -299,12 +319,13 @@ public class SimpleRegistryTest extends TestCase {
|
|||
/**
|
||||
* Test that the personal data outputted about the user is right
|
||||
*/
|
||||
public void testGetPersonalIDDetails() throws InvalidProtocolBufferException, InterruptedException {
|
||||
@Test
|
||||
public void testGetPersonalIDDetails() throws InterruptedException {
|
||||
DummyRegistryCallBackHandler<List<BulletinBoardMessage>> handler =
|
||||
new DummyRegistryCallBackHandler<>();
|
||||
|
||||
String id = new BigInteger(130, random).toString(32);
|
||||
String data = new BigInteger(130, random).toString(32);
|
||||
String id = generateString();
|
||||
String data = generateString();
|
||||
VoterInfo voterInfo = VoterInfo.newBuilder().
|
||||
setId(VoterID.newBuilder().setId(id)).setInfo(data).build();
|
||||
|
||||
|
@ -312,14 +333,34 @@ public class SimpleRegistryTest extends TestCase {
|
|||
registry.addVoter(voterInfo, handler);
|
||||
|
||||
jobSemaphore.acquire();
|
||||
assertEquals(1, handler.counter );
|
||||
assertEquals("The callback handler hasn't been called yet", 1, handler.counter );
|
||||
|
||||
DummyRegistryCallBackHandler<BulletinBoardMessage> personalHandler = new DummyRegistryCallBackHandler<>();
|
||||
registry.getPersonIDDetails(VoterID.newBuilder().setId(id).build(), personalHandler);
|
||||
|
||||
jobSemaphore.acquire(1);
|
||||
assertEquals(id, findTagWithPrefix(personalHandler.data, RegistryTags.ID_TAG));
|
||||
assertTrue(findTagWithPrefix(personalHandler.data, data) != null);
|
||||
assertEquals("The voter id doesn't match the created on ",
|
||||
id, findTagWithPrefix(personalHandler.data, RegistryTags.ID_TAG));
|
||||
assertTrue("The voter personal data can't be found.",
|
||||
findTagWithPrefix(personalHandler.data, data) != null);
|
||||
}
|
||||
|
||||
|
||||
public void testHasVoted () throws InterruptedException {
|
||||
DummyRegistryCallBackHandler<Boolean> handler = new DummyRegistryCallBackHandler<>();
|
||||
String id = generateString();
|
||||
VoterID voterInfo = VoterID.newBuilder().setId(id).build();
|
||||
|
||||
Registry registry = GetRegistry();
|
||||
registry.setVoted(voterInfo, handler);
|
||||
jobSemaphore.acquire();
|
||||
assertEquals("The callback handler hasn't been called yet", 1, handler.counter);
|
||||
DummyRegistryCallBackHandler<Boolean> personalHandler = new DummyRegistryCallBackHandler<>();
|
||||
registry.hasVoted(VoterID.newBuilder().setId(id).build(), personalHandler);
|
||||
|
||||
jobSemaphore.acquire(1);
|
||||
assertTrue("The voter hasn't voted yet.", personalHandler.data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue