Changed the writing of all the groups ids of one simple voter.

Voter-Registry
Vladimir Eliezer Tokarev 2016-03-18 10:42:07 -07:00
parent 37002a7f1e
commit c767d8af58
6 changed files with 107 additions and 60 deletions

View File

@ -1,10 +1,10 @@
package meerkat; package meerkat;
import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.FutureCallback;
import com.google.protobuf.ByteString;
import meerkat.bulletinboard.AsyncBulletinBoardClient; import meerkat.bulletinboard.AsyncBulletinBoardClient;
import meerkat.crypto.DigitalSignature; import meerkat.crypto.DigitalSignature;
import meerkat.protobuf.BulletinBoardAPI.UnsignedBulletinBoardMessage; import meerkat.protobuf.BulletinBoardAPI.UnsignedBulletinBoardMessage;
import meerkat.protobuf.VoterRegistry.GroupID;
import meerkat.protobuf.VoterRegistry.VoterID; import meerkat.protobuf.VoterRegistry.VoterID;
import meerkat.protobuf.VoterRegistry.VoterInfo; import meerkat.protobuf.VoterRegistry.VoterInfo;
import meerkat.protobuf.VoterRegistry.VoterRegistryMessage; import meerkat.protobuf.VoterRegistry.VoterRegistryMessage;
@ -15,6 +15,9 @@ import meerkat.registry.MessageCollectionUtils;
import meerkat.registry.RegistryTags; import meerkat.registry.RegistryTags;
import meerkat.util.BulletinBoardUtils; import meerkat.util.BulletinBoardUtils;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.security.SignatureException; import java.security.SignatureException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@ -42,12 +45,12 @@ public class AsyncRegistry implements VoterRegistry{
@Override @Override
public void addVoter(VoterInfo voterInfo, FutureCallback<Boolean> callback) throws SignatureException { public void addVoter(VoterInfo voterInfo, FutureCallback<Boolean> callback) throws SignatureException {
UnsignedBulletinBoardMessage basicMessage = UnsignedBulletinBoardMessage basicMessage =
UnsignedBulletinBoardMessage.newBuilder() UnsignedBulletinBoardMessage.newBuilder()
.addTag(RegistryTags.ID_TAG + voterInfo.getId().getId()) .addTag(RegistryTags.ID_TAG + voterInfo.getId().getId())
.addTag(RegistryTags.VOTER_ENTRY_TAG) .addTag(RegistryTags.VOTER_ENTRY_TAG)
.setData(voterInfo.getInfoBytes()) .setData(voterInfo.toByteString())
.setTimestamp(BulletinBoardUtils.getCurrentTimestampProto()) .setTimestamp(BulletinBoardUtils.getCurrentTimestampProto())
.build(); .build();
@ -55,24 +58,23 @@ public class AsyncRegistry implements VoterRegistry{
} }
@Override @Override
public void setVoterGroups(VoterRegistryMessage voterGroup, FutureCallback<Boolean> callback) throws SignatureException { public void setVoterGroups(VoterRegistryMessage voterRegistryMessage, FutureCallback<Boolean> callback) throws SignatureException, IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(voterRegistryMessage.getGroupIDList());
UnsignedBulletinBoardMessage.Builder basicMessage = UnsignedBulletinBoardMessage.Builder basicMessage =
UnsignedBulletinBoardMessage.newBuilder() UnsignedBulletinBoardMessage.newBuilder()
.addTag(RegistryTags.ID_TAG + voterGroup.getVoterID().getId()) .addTag(RegistryTags.ID_TAG + voterRegistryMessage.getVoterID().getId())
.addTag(RegistryTags.ADD_TO_GROUP_TAG) .addTag(RegistryTags.ADD_TO_GROUP_TAG)
.setData(ByteString.copyFrom(bos.toByteArray()))
.setTimestamp(BulletinBoardUtils.getCurrentTimestampProto()); .setTimestamp(BulletinBoardUtils.getCurrentTimestampProto());
for (GroupID groupId : voterGroup.getGroupIDList())
{
basicMessage.addTag(RegistryTags.GROUP_ID_TAG + groupId.getId());
}
bulletinBoardClient.postMessage(signBulletinBoardMessage(basicMessage.build(), signers), callback); bulletinBoardClient.postMessage(signBulletinBoardMessage(basicMessage.build(), signers), callback);
} }
@Override @Override
public void setVoted(VoterID voterId, FutureCallback<Boolean> callback) throws SignatureException { public void setVoted(VoterID voterId, FutureCallback<Boolean> callback) throws SignatureException {
UnsignedBulletinBoardMessage basicMessage = UnsignedBulletinBoardMessage basicMessage =
UnsignedBulletinBoardMessage.newBuilder() UnsignedBulletinBoardMessage.newBuilder()
.addTag(RegistryTags.ID_TAG + voterId.getId()) .addTag(RegistryTags.ID_TAG + voterId.getId())
@ -84,9 +86,10 @@ public class AsyncRegistry implements VoterRegistry{
} }
@Override @Override
public void getGroups(VoterID voterID, FutureCallback<List<String>> callback) { public void getGroups(VoterID voterID, FutureCallback<List<meerkat.protobuf.VoterRegistry.GroupID>> callback) {
List<String> GroupsActionsTags = new ArrayList<String>(2) {{ List<String> GroupsActionsTags = new ArrayList<String>(2) {{
add(RegistryTags.ADD_TO_GROUP_TAG); add(RegistryTags.ADD_TO_GROUP_TAG);
add(RegistryTags.ID_TAG + voterID.getId());
}}; }};
bulletinBoardClient.readMessages(MessageCollectionUtils.generateFiltersFromTags(GroupsActionsTags), bulletinBoardClient.readMessages(MessageCollectionUtils.generateFiltersFromTags(GroupsActionsTags),
@ -94,8 +97,8 @@ public class AsyncRegistry implements VoterRegistry{
} }
@Override @Override
public void getVoter(VoterID voterID, FutureCallback<VoterInfo> callback) { public void getVoter(VoterID voterID, FutureCallback<VoterInfo> callback) {
List<String> addVoterTags = new ArrayList<String>() {{ List<String> addVoterTags = new ArrayList<String>(2) {{
add(RegistryTags.ID_TAG + voterID.getId()); add(RegistryTags.ID_TAG + voterID.getId());
add(RegistryTags.VOTER_ENTRY_TAG); add(RegistryTags.VOTER_ENTRY_TAG);
}}; }};
@ -105,8 +108,8 @@ public class AsyncRegistry implements VoterRegistry{
} }
@Override @Override
public void hasVoted(VoterID voterId, FutureCallback<Boolean> callBack) { public void hasVoted(VoterID voterId, FutureCallback<Boolean> callBack) {
List<String> setVotedTags = new ArrayList<String>() {{ List<String> setVotedTags = new ArrayList<String>(2) {{
add(RegistryTags.ID_TAG + voterId.getId()); add(RegistryTags.ID_TAG + voterId.getId());
add(RegistryTags.VOTE_ACTION_TAG); add(RegistryTags.VOTE_ACTION_TAG);
}}; }};

View File

@ -7,6 +7,7 @@ import meerkat.protobuf.VoterRegistry.VoterID;
import meerkat.protobuf.VoterRegistry.VoterInfo; import meerkat.protobuf.VoterRegistry.VoterInfo;
import meerkat.protobuf.VoterRegistry.VoterRegistryMessage; import meerkat.protobuf.VoterRegistry.VoterRegistryMessage;
import java.io.IOException;
import java.security.SignatureException; import java.security.SignatureException;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
@ -40,11 +41,12 @@ public interface VoterRegistry {
* Passes the group to callBack.handleResult if the actions succeeded else * Passes the group to callBack.handleResult if the actions succeeded else
* call the onFailure method of the callback with the arisen error * call the onFailure method of the callback with the arisen error
* *
* @param voterGroup protobuff object that is coupling of voterId to groupId * @param voterRegistryMessage protobuff object that is coupling of voterId to groupId
* @param callBack when the adding voter done callBack.handleResult will be called * @param callBack when the adding voter done callBack.handleResult will be called
* @throws SignatureException * @throws SignatureException
* @throws IOException
*/ */
void setVoterGroups(VoterRegistryMessage voterGroup, FutureCallback<Boolean> callBack) throws SignatureException; void setVoterGroups(VoterRegistryMessage voterRegistryMessage, FutureCallback<Boolean> callBack) throws SignatureException, IOException;
/** /**
* Sets that the voter have voted * Sets that the voter have voted
@ -64,9 +66,8 @@ public interface VoterRegistry {
* *
* @param voterID protobuff object that represent the voter * @param voterID protobuff object that represent the voter
* @param callBack when the adding voter done callBack.handleResult will be called * @param callBack when the adding voter done callBack.handleResult will be called
* @throws SignatureException
*/ */
void getGroups(VoterID voterID, FutureCallback<List<String>> callBack) throws SignatureException; void getGroups(VoterID voterID, FutureCallback<List<meerkat.protobuf.VoterRegistry.GroupID>> callBack);
/** /**
* Retrieves VoterInfo protobuff that represents voter * Retrieves VoterInfo protobuff that represents voter
@ -75,9 +76,8 @@ public interface VoterRegistry {
* *
* @param voterID protobuff object that represent the voter * @param voterID protobuff object that represent the voter
* @param callBack when the adding voter done callBack.handleResult will be called * @param callBack when the adding voter done callBack.handleResult will be called
* @throws SignatureException
*/ */
void getVoter(VoterID voterID, FutureCallback<VoterInfo> callBack) throws SignatureException; void getVoter(VoterID voterID, FutureCallback<VoterInfo> callBack);
/** /**
* Checks if the given voter (by his id) have already voted * Checks if the given voter (by his id) have already voted
@ -86,8 +86,7 @@ public interface VoterRegistry {
* *
* @param voterID protobuff object that represent the voter * @param voterID protobuff object that represent the voter
* @param callBack method that will be called with the when the result will be found * @param callBack method that will be called with the when the result will be found
* @throws SignatureException
*/ */
void hasVoted(VoterID voterID, FutureCallback<Boolean> callBack) throws SignatureException; void hasVoted(VoterID voterID, FutureCallback<Boolean> callBack);
} }

View File

@ -1,12 +1,16 @@
package meerkat.registry.AsyncRegistryCallbacks; package meerkat.registry.AsyncRegistryCallbacks;
import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.FutureCallback;
import javassist.NotFoundException;
import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage; import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage;
import meerkat.registry.RegistryTags; import meerkat.protobuf.VoterRegistry;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.List; import java.util.List;
import static meerkat.util.BulletinBoardUtils.GetListOfTags; import static meerkat.util.BulletinBoardUtils.getLatestMessage;
// TODO : add logging // TODO : add logging
@ -15,19 +19,42 @@ import static meerkat.util.BulletinBoardUtils.GetListOfTags;
* AsyncRegistry getGroups creates this callback to list of groups the voter in * AsyncRegistry getGroups creates this callback to list of groups the voter in
*/ */
public class GetGroupsCallback implements FutureCallback<List<BulletinBoardMessage>> { public class GetGroupsCallback implements FutureCallback<List<BulletinBoardMessage>> {
protected FutureCallback<List<String>> callback; protected FutureCallback<List<VoterRegistry.GroupID>> callback;
public GetGroupsCallback(FutureCallback<List<String>> callback){ public GetGroupsCallback(FutureCallback<List<VoterRegistry.GroupID>> callback){
this.callback = callback; this.callback = callback;
} }
/**
* Gets List of GroupId objects from given message
* @param message BulletinBoardMessage which contains all groups ids of voter
* @return list of GroupId
* @throws IOException
* @throws ClassNotFoundException
*/
private List<VoterRegistry.GroupID> getVoterGroups(BulletinBoardMessage message) throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(message.getMsg().getData().toByteArray()));
return (List<VoterRegistry.GroupID>)ois.readObject();
}
@Override @Override
public void onSuccess(List<BulletinBoardMessage> messages) { public void onSuccess(List<BulletinBoardMessage> messages) {
callback.onSuccess(GetListOfTags(messages, RegistryTags.GROUP_ID_TAG)); if (messages.isEmpty()){
callback.onFailure(new NotFoundException("Voter permissions not found in database"));
}
BulletinBoardMessage message = getLatestMessage(messages);
try {
callback.onSuccess(getVoterGroups(message));
} catch (IOException | ClassNotFoundException e) {
callback.onFailure(e);
}
} }
@Override @Override
public void onFailure(Throwable t) { public void onFailure(Throwable t) {
System.out.println(t);
this.callback.onFailure(t); this.callback.onFailure(t);
} }
} }

View File

@ -2,13 +2,9 @@ package meerkat.registry.AsyncRegistryCallbacks;
import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.FutureCallback;
import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage; import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage;
import meerkat.registry.RegistryTags;
import java.util.List; import java.util.List;
import static meerkat.util.BulletinBoardUtils.findTagWithPrefix;
import static meerkat.util.BulletinBoardUtils.getLatestMessage;
// TODO : add logging // TODO : add logging
/** /**
@ -24,8 +20,10 @@ public class HasVotedCallback implements FutureCallback<List<BulletinBoardMessag
@Override @Override
public void onSuccess(List<BulletinBoardMessage> messages) { public void onSuccess(List<BulletinBoardMessage> messages) {
BulletinBoardMessage message = getLatestMessage(messages); if (messages.isEmpty()){
this.callback.onSuccess(findTagWithPrefix(message, RegistryTags.VOTE_ACTION_TAG) != null); callback.onSuccess(false);
}
callback.onSuccess(true);
} }
@Override @Override

View File

@ -1,13 +1,13 @@
package meerkat.registry.AsyncRegistryCallbacks; package meerkat.registry.AsyncRegistryCallbacks;
import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.FutureCallback;
import com.google.protobuf.InvalidProtocolBufferException;
import javassist.NotFoundException;
import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage; import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage;
import meerkat.protobuf.VoterRegistry; import meerkat.protobuf.VoterRegistry;
import meerkat.registry.RegistryTags;
import java.util.List; import java.util.List;
import static meerkat.util.BulletinBoardUtils.findTagWithPrefix;
import static meerkat.util.BulletinBoardUtils.getLatestMessage; import static meerkat.util.BulletinBoardUtils.getLatestMessage;
// TODO : add logging // TODO : add logging
@ -25,14 +25,19 @@ public class GetVoterCallback implements FutureCallback<List<BulletinBoardMessag
@Override @Override
public void onSuccess(List<BulletinBoardMessage> messages) { public void onSuccess(List<BulletinBoardMessage> messages) {
if(messages.isEmpty()){
callback.onFailure(new NotFoundException("Voter info not found in database."));
}
BulletinBoardMessage latestMessage = getLatestMessage(messages); BulletinBoardMessage latestMessage = getLatestMessage(messages);
VoterRegistry.VoterInfo info = VoterRegistry.VoterInfo.newBuilder() try {
.setId(VoterRegistry.VoterID.newBuilder() VoterRegistry.VoterInfo info = VoterRegistry.VoterInfo.newBuilder()
.setId(findTagWithPrefix(latestMessage, RegistryTags.ID_TAG))) .mergeFrom(latestMessage.getMsg().getData()).build();
.setInfo(latestMessage.getMsg().getData().toStringUtf8()).build(); callback.onSuccess(info);
} catch (InvalidProtocolBufferException e) {
callback.onSuccess(info); e.printStackTrace();
callback.onFailure(e);
}
} }
@Override @Override

View File

@ -16,7 +16,10 @@ import meerkat.registry.RegistryTags;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.ObjectInputStream;
import java.math.BigInteger; import java.math.BigInteger;
import java.security.KeyStore; import java.security.KeyStore;
import java.security.SecureRandom; import java.security.SecureRandom;
@ -29,6 +32,7 @@ import java.util.concurrent.Semaphore;
import static junit.framework.TestCase.assertEquals; import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertTrue; import static junit.framework.TestCase.assertTrue;
import static meerkat.util.BulletinBoardUtils.findTagWithPrefix; import static meerkat.util.BulletinBoardUtils.findTagWithPrefix;
import static meerkat.util.BulletinBoardUtils.getLatestMessage;
/** /**
* TODO: add logs prints for the tests to be clear what they are * TODO: add logs prints for the tests to be clear what they are
@ -258,14 +262,14 @@ public class SimpleRegistryTest /**extends TestCase**/ {
* Test that get groups retrieves the right groups the user are in * Test that get groups retrieves the right groups the user are in
*/ */
@Test @Test
public void testAddToGroup() throws InterruptedException, SignatureException { public void testSetVoterGroups() throws InterruptedException, SignatureException, IOException, ClassNotFoundException {
DummyRegistryCallBackHandler<Boolean> handler = new DummyRegistryCallBackHandler<>(); DummyRegistryCallBackHandler<Boolean> handler = new DummyRegistryCallBackHandler<>();
String voterId = generateString(); String voterId = generateString();
String groupId = generateString(); String groupId1 = generateString();
VoterRegistry.VoterRegistryMessage voterInfo = VoterRegistry.VoterRegistryMessage.newBuilder() VoterRegistry.VoterRegistryMessage voterInfo = VoterRegistry.VoterRegistryMessage.newBuilder()
.setVoterID(VoterID.newBuilder().setId(voterId)) .setVoterID(VoterID.newBuilder().setId(voterId))
.addGroupID(GroupID.newBuilder().setId(groupId)).build(); .addGroupID(GroupID.newBuilder().setId(groupId1)).build();
AsyncRegistry registry = GetRegistry(); AsyncRegistry registry = GetRegistry();
registry.setVoterGroups(voterInfo, handler); registry.setVoterGroups(voterInfo, handler);
@ -273,32 +277,38 @@ public class SimpleRegistryTest /**extends TestCase**/ {
jobSemaphore.acquire(); jobSemaphore.acquire();
assertEquals("The callback handler hasn't been called yet", 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);}}; List<String> tags = new ArrayList<String>(){{add(RegistryTags.ADD_TO_GROUP_TAG);
add(RegistryTags.ID_TAG + voterId);}};
DummyBulletinBoardCallBackHandler bulletinHandler = readMessagesByTags(tags); DummyBulletinBoardCallBackHandler bulletinHandler = readMessagesByTags(tags);
jobSemaphore.acquire(); jobSemaphore.acquire();
tags.clear(); BulletinBoardMessage latestMessage = getLatestMessage(bulletinHandler.messages);
tags.add(RegistryTags.ID_TAG + voterId);
tags.add(RegistryTags.GROUP_ID_TAG + groupId);
int counter = countMessagesWithTags(bulletinHandler.messages, tags); assert findTagWithPrefix(latestMessage, RegistryTags.ID_TAG).equals(voterId) :
assert counter == 1 : "The server don't have the new user added to group."; "The latest message recieved is not of our voter";
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(latestMessage.getMsg().getData().toByteArray()));
List<GroupID> groupsIds = (List<GroupID>)ois.readObject();
assert groupsIds.get(0).getId().equals(groupId1) : "The latest message doesn't have the voter group";
} }
/** /**
* Test that remove from group creates correct bulletin board message and removes the user from a group * Test that remove from group creates correct bulletin board message and removes the user from a group
*/ */
@Test @Test
public void testGetGroups() throws InterruptedException, SignatureException { public void testGetGroups() throws InterruptedException, SignatureException, IOException {
DummyRegistryCallBackHandler<Boolean> handler = DummyRegistryCallBackHandler<Boolean> handler =
new DummyRegistryCallBackHandler<>(); new DummyRegistryCallBackHandler<>();
String voterId = generateString(); String voterId = generateString();
String groupId = generateString(); String groupId1 = generateString();
String groupId2 = generateString();
VoterRegistry.VoterRegistryMessage voterInfo = VoterRegistry.VoterRegistryMessage.newBuilder() VoterRegistry.VoterRegistryMessage voterInfo = VoterRegistry.VoterRegistryMessage.newBuilder()
.setVoterID(VoterID.newBuilder().setId(voterId)) .setVoterID(VoterID.newBuilder().setId(voterId))
.addGroupID(GroupID.newBuilder().setId(groupId)).build(); .addGroupID(GroupID.newBuilder().setId(groupId1))
.addGroupID(GroupID.newBuilder().setId(groupId2)).build();
this.certStream = getClass().getResourceAsStream(CERT1_PEM_EXAMPLE); this.certStream = getClass().getResourceAsStream(CERT1_PEM_EXAMPLE);
@ -308,12 +318,17 @@ public class SimpleRegistryTest /**extends TestCase**/ {
jobSemaphore.acquire(); jobSemaphore.acquire();
assertEquals("The callback handler hasn't been called yet", 1, handler.counter ); assertEquals("The callback handler hasn't been called yet", 1, handler.counter );
DummyRegistryCallBackHandler<List<String>> groupsHandler = new DummyRegistryCallBackHandler<>(); DummyRegistryCallBackHandler<List<GroupID>> groupsHandler = new DummyRegistryCallBackHandler<>();
registry.getGroups(VoterID.newBuilder().setId(groupId).build(), groupsHandler); registry.getGroups(VoterID.newBuilder().setId(voterId).build(), groupsHandler);
jobSemaphore.acquire(1); jobSemaphore.acquire(1);
List<String> userGroups = groupsHandler.data; List<GroupID> userGroups = groupsHandler.data;
assert userGroups.contains(groupId) : "The simple voter registry object does not retrieved right user groups";
assert userGroups.contains(GroupID.newBuilder().setId(groupId1).build()) :
"The simple voter registry object does not retrieved the first user groups";
assert userGroups.contains(GroupID.newBuilder().setId(groupId2).build()) :
"The simple voter registry object does not retrieved the second user groups";
} }
/** /**