diff --git a/meerkat-common/src/main/proto/meerkat/PollingStation.proto b/meerkat-common/src/main/proto/meerkat/PollingStation.proto index 0cdc658..09596a5 100644 --- a/meerkat-common/src/main/proto/meerkat/PollingStation.proto +++ b/meerkat-common/src/main/proto/meerkat/PollingStation.proto @@ -2,11 +2,16 @@ syntax = "proto3"; package meerkat; +import "meerkat/voting.proto"; + option java_package = "meerkat.protobuf"; // Container for scanned data message ScannedData { - bytes data = 1; + bytes channel = 1; + + SignedEncryptedBallot signed_encrypted_ballot = 2; + } // Container for error messages diff --git a/polling-station/src/test/java/meerkat/pollingstation/PollingStationWebScannerTest.java b/polling-station/src/test/java/meerkat/pollingstation/PollingStationWebScannerTest.java index 7da106c..e94c633 100644 --- a/polling-station/src/test/java/meerkat/pollingstation/PollingStationWebScannerTest.java +++ b/polling-station/src/test/java/meerkat/pollingstation/PollingStationWebScannerTest.java @@ -2,7 +2,9 @@ package meerkat.pollingstation; import com.google.common.util.concurrent.FutureCallback; import com.google.protobuf.ByteString; +import meerkat.protobuf.Crypto.Signature; import meerkat.protobuf.PollingStation.*; +import meerkat.protobuf.Voting.SignedEncryptedBallot; import meerkat.rest.Constants; import meerkat.rest.*; @@ -46,7 +48,7 @@ public class PollingStationWebScannerTest { @Override public void onSuccess(ScannedData result) { - dataIsAsExpected = result.getData().equals(expectedData.getData()); + dataIsAsExpected = result.getChannel().equals(expectedData.getChannel()); semaphore.release(); } @@ -109,7 +111,7 @@ public class PollingStationWebScannerTest { byte[] data = {(byte) 1, (byte) 2}; ScannedData scannedData = ScannedData.newBuilder() - .setData(ByteString.copyFrom(data)) + .setChannel(ByteString.copyFrom(data)) .build(); scanner.subscribe(new ScanHandler(scannedData)); diff --git a/voting-booth/src/main/java/meerkat/voting/output/AsyncRunnableOutputDevice.java b/voting-booth/src/main/java/meerkat/voting/output/AsyncRunnableOutputDevice.java index 50bd6d5..d4620bb 100644 --- a/voting-booth/src/main/java/meerkat/voting/output/AsyncRunnableOutputDevice.java +++ b/voting-booth/src/main/java/meerkat/voting/output/AsyncRunnableOutputDevice.java @@ -1,46 +1,30 @@ package meerkat.voting.output; import com.google.common.util.concurrent.FutureCallback; -import com.google.protobuf.BoolValue; -import meerkat.protobuf.PollingStation.ScannedData; -import meerkat.protobuf.Voting.*; -import meerkat.rest.*; +import meerkat.protobuf.Voting.BallotSecrets; +import meerkat.protobuf.Voting.PlaintextBallot; +import meerkat.protobuf.Voting.SignedEncryptedBallot; import meerkat.voting.controller.callbacks.ControllerCallback; import meerkat.voting.output.outputcommands.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.ws.rs.client.*; -import javax.ws.rs.core.Response; - -import java.io.IOException; import java.util.concurrent.LinkedBlockingQueue; -import static meerkat.pollingstation.PollingStationConstants.*; - /** * Created by hai on 27/06/16. */ -public class AsyncRunnableOutputDevice implements BallotOutputDevice, Runnable { +public abstract class AsyncRunnableOutputDevice implements BallotOutputDevice, Runnable { private Logger logger; private LinkedBlockingQueue queue; private volatile boolean shutDownHasBeenCalled; - private SignedEncryptedBallot signedEncryptedBallot; - - private final WebTarget successfulPrintTarget; - - public AsyncRunnableOutputDevice(String address) { + public AsyncRunnableOutputDevice() { logger = LoggerFactory.getLogger(AsyncRunnableOutputDevice.class); - logger.info("A NetworkVirtualPrinter is constructed"); + logger.info("AsyncRunnableOutputDevice is constructed"); queue = new LinkedBlockingQueue<>(); shutDownHasBeenCalled = false; - - Client client = ClientBuilder.newClient(); - client.register(ProtobufMessageBodyReader.class); - client.register(ProtobufMessageBodyWriter.class); - successfulPrintTarget = client.target(address).path(POLLING_STATION_WEB_SCANNER_SCAN_PATH); } @Override @@ -69,6 +53,15 @@ public class AsyncRunnableOutputDevice implements BallotOutputDevice, Runnable } + abstract void doCommitToBallot(CommitOutputCommand command); + + abstract void doAudit(AuditOutputCommand command); + + abstract void doCastBallot(CastOutputCommand command); + + abstract void doCancel(CancelOutputCommand command); + + private void handleSingleCommand(OutputCommand command) { if (command instanceof CommitOutputCommand) { doCommitToBallot((CommitOutputCommand)command); @@ -118,44 +111,4 @@ public class AsyncRunnableOutputDevice implements BallotOutputDevice, Runnable } - public void doCommitToBallot(CommitOutputCommand command) { - logger.debug("entered method doCommitToBallot"); - signedEncryptedBallot = command.getSignedEncryptedBallot(); - command.getCallback().onSuccess(null); - } - - - public void doAudit(AuditOutputCommand command) { - logger.debug("entered method doAudit"); - signedEncryptedBallot = null; - command.getCallback().onSuccess(null); - } - - - public void doCastBallot(CastOutputCommand command) { - logger.debug("entered method doCastBallot"); - ScannedData scannedData = ScannedData.newBuilder() - .setChannel(null) //TODO: fill the details for the channel to be able to send here - .setSignedEncryptedBallot(this.signedEncryptedBallot) - .build(); - - Response response = successfulPrintTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(scannedData, Constants.MEDIATYPE_PROTOBUF)); - BoolValue b = response.readEntity(BoolValue.class); - response.close(); - - if (b.getValue()) { - command.getCallback().onSuccess(null); - } - else { - command.getCallback().onFailure(new IOException()); - } - } - - - public void doCancel(CancelOutputCommand command) { - logger.debug("entered method doCancel"); - signedEncryptedBallot = null; - command.getCallback().onSuccess(null); - } - } diff --git a/voting-booth/src/main/java/meerkat/voting/output/NetworkVirtualPrinter.java b/voting-booth/src/main/java/meerkat/voting/output/NetworkVirtualPrinter.java index d3e3625..f65959f 100644 --- a/voting-booth/src/main/java/meerkat/voting/output/NetworkVirtualPrinter.java +++ b/voting-booth/src/main/java/meerkat/voting/output/NetworkVirtualPrinter.java @@ -1,37 +1,84 @@ package meerkat.voting.output; import com.google.protobuf.BoolValue; -import meerkat.pollingstation.PollingStationScanner; -import meerkat.protobuf.PollingStation.*; -import meerkat.rest.*; +import meerkat.protobuf.PollingStation.ScannedData; +import meerkat.protobuf.Voting.SignedEncryptedBallot; +import meerkat.rest.Constants; +import meerkat.rest.ProtobufMessageBodyReader; +import meerkat.rest.ProtobufMessageBodyWriter; +import meerkat.voting.output.outputcommands.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -import javax.ws.rs.client.*; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.Response; +import java.io.IOException; -import static meerkat.pollingstation.PollingStationConstants.*; +import static meerkat.pollingstation.PollingStationConstants.POLLING_STATION_WEB_SCANNER_SCAN_PATH; /** * Created by hai on 27/06/16. */ -public class NetworkVirtualPrinter implements PollingStationScanner.Producer { +public class NetworkVirtualPrinter extends AsyncRunnableOutputDevice { - WebTarget successfulScanPath; - WebTarget errorPath; + private Logger logger; + private SignedEncryptedBallot signedEncryptedBallot; + private final WebTarget successfulPrintTarget; public NetworkVirtualPrinter(String address) { + super(); + + logger = LoggerFactory.getLogger(NetworkVirtualPrinter.class); + logger.info("A NetworkVirtualPrinter is constructed"); + Client client = ClientBuilder.newClient(); client.register(ProtobufMessageBodyReader.class); client.register(ProtobufMessageBodyWriter.class); - successfulScanPath = client.target(address).path(POLLING_STATION_WEB_SCANNER_SCAN_PATH); - errorPath = client.target(address).path(POLLING_STATION_WEB_SCANNER_ERROR_PATH); + successfulPrintTarget = client.target(address).path(POLLING_STATION_WEB_SCANNER_SCAN_PATH); } - @Override - public BoolValue newScan(ScannedData scannedData) { - return null; + + public void doCommitToBallot(CommitOutputCommand command) { + logger.debug("entered method doCommitToBallot"); + signedEncryptedBallot = command.getSignedEncryptedBallot(); + command.getCallback().onSuccess(null); } - @Override - public BoolValue reportScanError(ErrorMsg errorMsg) { - return null; + + public void doAudit(AuditOutputCommand command) { + logger.debug("entered method doAudit"); + signedEncryptedBallot = null; + command.getCallback().onSuccess(null); } + + + public void doCastBallot(CastOutputCommand command) { + logger.debug("entered method doCastBallot"); + ScannedData scannedData = ScannedData.newBuilder() + .setChannel(null) //TODO: fill the details for the channel to be able to send here + .setSignedEncryptedBallot(this.signedEncryptedBallot) + .build(); + + Response response = successfulPrintTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(scannedData, Constants.MEDIATYPE_PROTOBUF)); + BoolValue b = response.readEntity(BoolValue.class); + response.close(); + + if (b.getValue()) { + command.getCallback().onSuccess(null); + } + else { + command.getCallback().onFailure(new IOException()); + } + } + + + public void doCancel(CancelOutputCommand command) { + logger.debug("entered method doCancel"); + signedEncryptedBallot = null; + command.getCallback().onSuccess(null); + } + } diff --git a/voting-booth/src/main/java/meerkat/voting/output/SystemConsoleOutputDevice.java b/voting-booth/src/main/java/meerkat/voting/output/SystemConsoleOutputDevice.java index 614dc40..62bebe3 100644 --- a/voting-booth/src/main/java/meerkat/voting/output/SystemConsoleOutputDevice.java +++ b/voting-booth/src/main/java/meerkat/voting/output/SystemConsoleOutputDevice.java @@ -1,96 +1,28 @@ package meerkat.voting.output; -import com.google.common.util.concurrent.FutureCallback; import com.google.protobuf.ByteString; import meerkat.protobuf.Crypto.*; import meerkat.protobuf.Voting.*; -import meerkat.voting.controller.callbacks.ControllerCallback; import meerkat.voting.output.outputcommands.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.concurrent.LinkedBlockingQueue; - /** * A toy OutputDevice class * outputs everything simply to the System console */ -public class SystemConsoleOutputDevice implements BallotOutputDevice, Runnable { +public class SystemConsoleOutputDevice extends AsyncRunnableOutputDevice { private Logger logger; - private LinkedBlockingQueue queue; - private volatile boolean shutDownHasBeenCalled; public SystemConsoleOutputDevice () { + super(); logger = LoggerFactory.getLogger(SystemConsoleOutputDevice.class); logger.info("A SystemConsoleOutputDevice is constructed"); - queue = new LinkedBlockingQueue<>(); - shutDownHasBeenCalled = false; } - /* - * Returns the UTF8 decoding of byte-string data - */ - private static String bytesToString(ByteString data) { - return data.toStringUtf8(); - } - @Override - public void run () { - logger.info("UI starts running"); - while (! wasShutDownCalled()) { - try { - OutputCommand command = queue.take(); - handleSingleCommand(command); - } - catch (InterruptedException e) { - logger.warn ("Interrupted while reading from command queue " + e); - } - } - } - - private boolean wasShutDownCalled () { - return shutDownHasBeenCalled; - } - - @Override - public void callShutDown() { - logger.info("callShutDown command has been called"); - shutDownHasBeenCalled = true; - queue.clear(); - } - - - private void handleSingleCommand(OutputCommand command) { - if (command instanceof CommitOutputCommand) { - doCommitToBallot((CommitOutputCommand)command); - } - else if (command instanceof AuditOutputCommand) { - doAudit((AuditOutputCommand)command); - } - else if (command instanceof CastOutputCommand) { - doCastBallot((CastOutputCommand)command); - } - else if (command instanceof CancelOutputCommand) { - doCancel((CancelOutputCommand)command); - } - else { - String errorMessage = "handleSingleCommand: unknown type of OutputCommand received: " + - command.getClass().getName(); - logger.error(errorMessage); - throw new RuntimeException(errorMessage); - } - } - - - @Override - public void commitToBallot(PlaintextBallot plaintextBallot, - SignedEncryptedBallot signedEncryptedBallot, - FutureCallback callback) { - logger.debug("Output interface call to commit to ballot"); - queue.add(new CommitOutputCommand(plaintextBallot, signedEncryptedBallot, (ControllerCallback)callback)); - } public void doCommitToBallot(CommitOutputCommand command) { logger.debug("entered method doCommitToBallot"); @@ -111,12 +43,6 @@ public class SystemConsoleOutputDevice implements BallotOutputDevice, Runnable { } - @Override - public void audit(BallotSecrets ballotSecrets, FutureCallback callback) { - logger.debug("an interface call to audit"); - queue.add(new AuditOutputCommand(ballotSecrets, (ControllerCallback)callback)); - } - public void doAudit(AuditOutputCommand command) { logger.debug("entered method doAudit"); System.out.println("Auditing"); @@ -127,12 +53,6 @@ public class SystemConsoleOutputDevice implements BallotOutputDevice, Runnable { } - @Override - public void castBallot(FutureCallback callback) { - logger.debug("an interface call to cast ballot"); - queue.add(new CastOutputCommand((ControllerCallback)callback)); - } - public void doCastBallot(CastOutputCommand command) { logger.debug("entered method doCastBallot"); System.out.println("Ballot finalized for casting!"); @@ -140,12 +60,6 @@ public class SystemConsoleOutputDevice implements BallotOutputDevice, Runnable { } - @Override - public void cancelBallot(FutureCallback callback) { - logger.debug("an interface call to cancel the output"); - queue.add(new CancelOutputCommand((ControllerCallback)callback)); - } - public void doCancel(CancelOutputCommand command) { logger.debug("entered method doCancel"); System.out.println("Ballot cancelled!"); @@ -165,4 +79,12 @@ public class SystemConsoleOutputDevice implements BallotOutputDevice, Runnable { System.out.println(bytesToString(data)); } + + /* + * Returns the UTF8 decoding of byte-string data + */ + private static String bytesToString(ByteString data) { + return data.toStringUtf8(); + } + }