Refactor: add comments to VotingBoothImpl.java, and rename tasks to commands (because they were two names of the same thing)
Signed-off-by: Hai Brenner <haibrenner@gmail.com>vbdev2
parent
42d68b7ce8
commit
0956fa98d3
|
@ -24,29 +24,30 @@ import java.util.concurrent.LinkedBlockingQueue;
|
||||||
*/
|
*/
|
||||||
public class VotingBoothImpl implements VotingBoothController {
|
public class VotingBoothImpl implements VotingBoothController {
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(VotingBoothImpl.class);;
|
||||||
|
|
||||||
|
// the component interfaces of the Voting Booth
|
||||||
private BallotOutputDevice outputDevice;
|
private BallotOutputDevice outputDevice;
|
||||||
private VBCryptoManager crypto;
|
private VBCryptoManager crypto;
|
||||||
private VotingBoothUI ui;
|
private VotingBoothUI ui;
|
||||||
private StorageManager storageManager;
|
private StorageManager storageManager;
|
||||||
|
|
||||||
|
// election details and info
|
||||||
private List<BallotQuestion> questionsForChoosingChannel;
|
private List<BallotQuestion> questionsForChoosingChannel;
|
||||||
private List<BallotQuestion> questions;
|
private List<BallotQuestion> questions;
|
||||||
private QuestionSelector questionSelector;
|
private QuestionSelector questionSelector;
|
||||||
private Map<String, UIElement> systemMessages;
|
private Map<String, UIElement> systemMessages;
|
||||||
|
|
||||||
private LinkedBlockingQueue<ControllerCommand> queue;
|
// state
|
||||||
|
|
||||||
private Logger logger;
|
|
||||||
|
|
||||||
private ControllerState state;
|
private ControllerState state;
|
||||||
private volatile boolean shutDownHasBeenCalled;
|
private volatile boolean shutDownHasBeenCalled;
|
||||||
|
private LinkedBlockingQueue<ControllerCommand> queue;
|
||||||
protected final int MAX_REQUEST_IDENTIFIER = 100000;
|
protected final int MAX_REQUEST_IDENTIFIER = 100000;
|
||||||
private static int requestCounter = 0;
|
private static int requestCounter = 0;
|
||||||
|
|
||||||
|
|
||||||
|
// a simple constructor
|
||||||
public VotingBoothImpl () {
|
public VotingBoothImpl () {
|
||||||
logger = LoggerFactory.getLogger(VotingBoothImpl.class);
|
|
||||||
logger.info("A VotingBoothImpl is constructed");
|
logger.info("A VotingBoothImpl is constructed");
|
||||||
shutDownHasBeenCalled = false;
|
shutDownHasBeenCalled = false;
|
||||||
queue = new LinkedBlockingQueue<>();
|
queue = new LinkedBlockingQueue<>();
|
||||||
|
@ -59,11 +60,14 @@ public class VotingBoothImpl implements VotingBoothController {
|
||||||
VotingBoothUI vbUI,
|
VotingBoothUI vbUI,
|
||||||
StorageManager vbStorageManager) throws IOException {
|
StorageManager vbStorageManager) throws IOException {
|
||||||
logger.info("init is called");
|
logger.info("init is called");
|
||||||
|
|
||||||
|
// keep pointers to the VB components
|
||||||
this.outputDevice = outputDevice;
|
this.outputDevice = outputDevice;
|
||||||
this.crypto = vbCrypto;
|
this.crypto = vbCrypto;
|
||||||
this.ui = vbUI;
|
this.ui = vbUI;
|
||||||
this.storageManager = vbStorageManager;
|
this.storageManager = vbStorageManager;
|
||||||
|
|
||||||
|
// store election details and info
|
||||||
ElectionParams electionParams;
|
ElectionParams electionParams;
|
||||||
try {
|
try {
|
||||||
logger.info("init: reading election params");
|
logger.info("init: reading election params");
|
||||||
|
@ -92,6 +96,10 @@ public class VotingBoothImpl implements VotingBoothController {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* a method for running the Voting flow of the VB (in contrast to the admin-setup flow
|
||||||
|
* It simply loops: takes the next command in its inner queue and handles it
|
||||||
|
*/
|
||||||
private void runVotingFlow () {
|
private void runVotingFlow () {
|
||||||
logger.info("entered the voting flow");
|
logger.info("entered the voting flow");
|
||||||
|
|
||||||
|
@ -99,11 +107,11 @@ public class VotingBoothImpl implements VotingBoothController {
|
||||||
|
|
||||||
while (! wasShutDownCalled()) {
|
while (! wasShutDownCalled()) {
|
||||||
try {
|
try {
|
||||||
ControllerCommand task = queue.take();
|
ControllerCommand Command = queue.take();
|
||||||
handleSingleTask (task);
|
handleSingleCommand(Command);
|
||||||
}
|
}
|
||||||
catch (InterruptedException e) {
|
catch (InterruptedException e) {
|
||||||
logger.warn ("Interrupted while reading from task queue " + e);
|
logger.warn ("Interrupted while reading from command queue " + e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,41 +125,48 @@ public class VotingBoothImpl implements VotingBoothController {
|
||||||
outputDevice.callShutDown();
|
outputDevice.callShutDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleSingleTask (ControllerCommand task) {
|
/**
|
||||||
if (task.getBallotSerialNumber() != state.currentBallotSerialNumber && !(task instanceof RestartVotingCommand)) {
|
* this method decides upon a given command if to ignore it (if it has an old serial number) or to handle it
|
||||||
|
* If we choose to handle it, then it simply calls the matching method which handles this type of command
|
||||||
|
* @param command a command to handle next (probably from the inner command queue)
|
||||||
|
*/
|
||||||
|
private void handleSingleCommand(ControllerCommand command) {
|
||||||
|
// check if the command is old and should be ignored
|
||||||
|
if (command.getBallotSerialNumber() != state.currentBallotSerialNumber && !(command instanceof RestartVotingCommand)) {
|
||||||
// probably an old command relating to some old ballot serial number. Simply log it and ignore it.
|
// probably an old command relating to some old ballot serial number. Simply log it and ignore it.
|
||||||
String errorMessage = "handleSingleTask: received a task too old. " +
|
String errorMessage = "handleSingleCommand: received a task too old. " +
|
||||||
task.getBallotSerialNumber() + " " + state.currentBallotSerialNumber;
|
command.getBallotSerialNumber() + " " + state.currentBallotSerialNumber;
|
||||||
logger.debug(errorMessage);
|
logger.debug(errorMessage);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (task instanceof RestartVotingCommand) {
|
// decide which method to run according to the command type
|
||||||
|
if (command instanceof RestartVotingCommand) {
|
||||||
doRestartVoting ();
|
doRestartVoting ();
|
||||||
}
|
}
|
||||||
else if (task instanceof ChannelChoiceCommand) {
|
else if (command instanceof ChannelChoiceCommand) {
|
||||||
doChooseChannel();
|
doChooseChannel();
|
||||||
}
|
}
|
||||||
else if (task instanceof ChannelDeterminedCommand) {
|
else if (command instanceof ChannelDeterminedCommand) {
|
||||||
doSetChannelAndAskQuestions ((ChannelDeterminedCommand)task);
|
doSetChannelAndAskQuestions ((ChannelDeterminedCommand)command);
|
||||||
}
|
}
|
||||||
else if (task instanceof ChooseFinalizeOptionCommand) {
|
else if (command instanceof ChooseFinalizeOptionCommand) {
|
||||||
doChooseFinalizeOption();
|
doChooseFinalizeOption();
|
||||||
}
|
}
|
||||||
else if (task instanceof CastCommand) {
|
else if (command instanceof CastCommand) {
|
||||||
doFinalize(false);
|
doFinalize(false);
|
||||||
}
|
}
|
||||||
else if (task instanceof AuditCommand) {
|
else if (command instanceof AuditCommand) {
|
||||||
doFinalize(true);
|
doFinalize(true);
|
||||||
}
|
}
|
||||||
else if (task instanceof EncryptAndCommitBallotCommand) {
|
else if (command instanceof EncryptAndCommitBallotCommand) {
|
||||||
doCommit ((EncryptAndCommitBallotCommand)task);
|
doCommit ((EncryptAndCommitBallotCommand)command);
|
||||||
}
|
}
|
||||||
else if (task instanceof ReportErrorCommand) {
|
else if (command instanceof ReportErrorCommand) {
|
||||||
doReportErrorAndForceRestart((ReportErrorCommand)task);
|
doReportErrorAndForceRestart((ReportErrorCommand)command);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
logger.error("handleSingleTask: unknown type of ControllerCommand received: " + task.getClass().getName());
|
logger.error("handleSingleCommand: unknown type of ControllerCommand received: " + command.getClass().getName());
|
||||||
doReportErrorAndForceRestart(systemMessages.get(StorageManager.SOMETHING_WRONG_MESSAGE));
|
doReportErrorAndForceRestart(systemMessages.get(StorageManager.SOMETHING_WRONG_MESSAGE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -166,17 +181,28 @@ public class VotingBoothImpl implements VotingBoothController {
|
||||||
//TODO: add commands to actually shut down the machine
|
//TODO: add commands to actually shut down the machine
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* a method to execute a Restart Voting Command
|
||||||
|
*/
|
||||||
private void doRestartVoting () {
|
private void doRestartVoting () {
|
||||||
queue.clear();
|
queue.clear();
|
||||||
state.clearAndResetState(VBState.NEW_VOTER);
|
state.clearAndResetState(VBState.NEW_VOTER);
|
||||||
|
|
||||||
ui.startNewVoterSession(new NewVoterCallback(generateRequestIdentifier(), state.currentBallotSerialNumber, this.queue));
|
ui.startNewVoterSession(new NewVoterCallback(generateRequestIdentifier(), state.currentBallotSerialNumber, this.queue));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doReportErrorAndForceRestart(ReportErrorCommand task) {
|
/**
|
||||||
doReportErrorAndForceRestart(task.getErrorMessage());
|
* a (overloaded) method to execute a Report Error Command.
|
||||||
|
* It actually just runs the overloaded version of this method with the error message inside the command
|
||||||
|
* @param command the command has the info of the error message to report
|
||||||
|
*/
|
||||||
|
private void doReportErrorAndForceRestart(ReportErrorCommand command) {
|
||||||
|
doReportErrorAndForceRestart(command.getErrorMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* a (overloaded) method to report an error message to the voter
|
||||||
|
* @param errorMessage message to show the voter
|
||||||
|
*/
|
||||||
private void doReportErrorAndForceRestart(UIElement errorMessage) {
|
private void doReportErrorAndForceRestart(UIElement errorMessage) {
|
||||||
queue.clear();
|
queue.clear();
|
||||||
state.clearAndResetState(VBState.FATAL_ERROR_FORCE_NEW_VOTER);
|
state.clearAndResetState(VBState.FATAL_ERROR_FORCE_NEW_VOTER);
|
||||||
|
@ -187,6 +213,10 @@ public class VotingBoothImpl implements VotingBoothController {
|
||||||
this.queue));
|
this.queue));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* a method to execute a Channel Choice Command
|
||||||
|
* it notifies the UI to present the channel choice questions to the voter
|
||||||
|
*/
|
||||||
private void doChooseChannel () {
|
private void doChooseChannel () {
|
||||||
if (state.stateIdentifier == VBState.NEW_VOTER) {
|
if (state.stateIdentifier == VBState.NEW_VOTER) {
|
||||||
logger.debug("doing chooseChannel");
|
logger.debug("doing chooseChannel");
|
||||||
|
@ -203,11 +233,17 @@ public class VotingBoothImpl implements VotingBoothController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doSetChannelAndAskQuestions (ChannelDeterminedCommand task) {
|
/**
|
||||||
|
* a method to execute a Channel Determined Command
|
||||||
|
* (this actually sets the channel now after the voter has answered the channel choice questions)
|
||||||
|
* It then determines the race questions for the voter, and notifies the UI to present them to the voter
|
||||||
|
* @param command details of the voter's answers on the channel choice questions
|
||||||
|
*/
|
||||||
|
private void doSetChannelAndAskQuestions (ChannelDeterminedCommand command) {
|
||||||
if (state.stateIdentifier == VBState.CHOOSE_CHANNEL) {
|
if (state.stateIdentifier == VBState.CHOOSE_CHANNEL) {
|
||||||
logger.debug("doing set channel and ask questions");
|
logger.debug("doing set channel and ask questions");
|
||||||
state.stateIdentifier = VBState.ANSWER_QUESTIONS;
|
state.stateIdentifier = VBState.ANSWER_QUESTIONS;
|
||||||
List<BallotAnswer> channelChoiceAnswers = task.channelChoiceAnswers;
|
List<BallotAnswer> channelChoiceAnswers = command.channelChoiceAnswers;
|
||||||
state.channelIdentifier = questionSelector.getChannelIdentifier(channelChoiceAnswers);
|
state.channelIdentifier = questionSelector.getChannelIdentifier(channelChoiceAnswers);
|
||||||
state.channelSpecificQuestions = questionSelector.selectQuestionsForVoter(state.channelIdentifier);
|
state.channelSpecificQuestions = questionSelector.selectQuestionsForVoter(state.channelIdentifier);
|
||||||
ui.askVoterQuestions(state.channelSpecificQuestions,
|
ui.askVoterQuestions(state.channelSpecificQuestions,
|
||||||
|
@ -222,7 +258,10 @@ public class VotingBoothImpl implements VotingBoothController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* a method to execute a Do-Finalzie-Option Command
|
||||||
|
* notifies the UI to present the cast-or-audit question to the voter
|
||||||
|
*/
|
||||||
private void doChooseFinalizeOption() {
|
private void doChooseFinalizeOption() {
|
||||||
if (state.stateIdentifier == VBState.COMMITTING_TO_BALLOT) {
|
if (state.stateIdentifier == VBState.COMMITTING_TO_BALLOT) {
|
||||||
logger.debug("doChooseFinalizeOption");
|
logger.debug("doChooseFinalizeOption");
|
||||||
|
@ -237,11 +276,17 @@ public class VotingBoothImpl implements VotingBoothController {
|
||||||
// ignore this request
|
// ignore this request
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private void doCommit (EncryptAndCommitBallotCommand task) {
|
|
||||||
|
/**
|
||||||
|
* a method to execute a Encrypt-and-Commit Command
|
||||||
|
* It sends a notification to commit to the output device
|
||||||
|
* @param command details of the voter's answers on the ballot questions
|
||||||
|
*/
|
||||||
|
private void doCommit (EncryptAndCommitBallotCommand command) {
|
||||||
if (state.stateIdentifier == VBState.ANSWER_QUESTIONS) {
|
if (state.stateIdentifier == VBState.ANSWER_QUESTIONS) {
|
||||||
logger.debug("doing commit");
|
logger.debug("doing commit");
|
||||||
try {
|
try {
|
||||||
setBallotData(task);
|
setBallotData(command);
|
||||||
ui.notifyVoterToWaitForFinish(systemMessages.get(StorageManager.WAIT_FOR_COMMIT_MESSAGE),
|
ui.notifyVoterToWaitForFinish(systemMessages.get(StorageManager.WAIT_FOR_COMMIT_MESSAGE),
|
||||||
new WaitForFinishCallback(generateRequestIdentifier(),
|
new WaitForFinishCallback(generateRequestIdentifier(),
|
||||||
state.currentBallotSerialNumber,
|
state.currentBallotSerialNumber,
|
||||||
|
@ -257,6 +302,9 @@ public class VotingBoothImpl implements VotingBoothController {
|
||||||
}
|
}
|
||||||
catch (SignatureException | IOException e) {
|
catch (SignatureException | IOException e) {
|
||||||
logger.error("doCommit: encryption failed. exception: " + e);
|
logger.error("doCommit: encryption failed. exception: " + e);
|
||||||
|
|
||||||
|
// in case the encryption failed for some unknown reason, we send the UI a notification
|
||||||
|
// to ask the voter whether he wants to retry or cancel the ballot
|
||||||
UIElement errorMessage = systemMessages.get(StorageManager.ENCRYPTION_FAILED_MESSAGE);
|
UIElement errorMessage = systemMessages.get(StorageManager.ENCRYPTION_FAILED_MESSAGE);
|
||||||
UIElement[] buttons = new UIElement[]{
|
UIElement[] buttons = new UIElement[]{
|
||||||
systemMessages.get(StorageManager.RETRY_BUTTON),
|
systemMessages.get(StorageManager.RETRY_BUTTON),
|
||||||
|
@ -274,25 +322,41 @@ public class VotingBoothImpl implements VotingBoothController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setBallotData (EncryptAndCommitBallotCommand task) throws IOException, SignatureException{
|
/**
|
||||||
if (! (task instanceof RetryEncryptAndCommitBallotCommand)) {
|
* encrypt the ballot, and keep all info (plaintext, encryption and secrets) in the state's attributes
|
||||||
|
* @param command either an EncryptAndCommitBallotCommand if we encrypt the plaintext for the first time, or a RetryEncryptAndCommitBallotCommand if we already got here but encryption failed before
|
||||||
|
* @throws IOException problems in the encryption process
|
||||||
|
* @throws SignatureException problems in the digital signature process
|
||||||
|
*/
|
||||||
|
private void setBallotData (EncryptAndCommitBallotCommand command) throws IOException, SignatureException{
|
||||||
|
// a Retry command is given only if we first got here, and later the encryption failed but the voter chose to retry
|
||||||
|
// in such a case the plaintext is already set from previous attempt
|
||||||
|
if (! (command instanceof RetryEncryptAndCommitBallotCommand)) {
|
||||||
// this is not a retry attempt, so the plaintext is not set yet
|
// this is not a retry attempt, so the plaintext is not set yet
|
||||||
// otherwise, we have the plaintext from the previous encryption attempt
|
// otherwise, we have the plaintext from the previous encryption attempt
|
||||||
state.plaintextBallot = PlaintextBallot.newBuilder()
|
state.plaintextBallot = PlaintextBallot.newBuilder()
|
||||||
.setSerialNumber(task.getBallotSerialNumber())
|
.setSerialNumber(command.getBallotSerialNumber())
|
||||||
.addAllAnswers(task.getVotingAnswers())
|
.addAllAnswers(command.getVotingAnswers())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// keep the encryption and the secrets we used for it
|
||||||
EncryptionAndSecrets encryptionAndSecrets = crypto.encrypt(state.plaintextBallot);
|
EncryptionAndSecrets encryptionAndSecrets = crypto.encrypt(state.plaintextBallot);
|
||||||
state.signedEncryptedBallot = encryptionAndSecrets.getSignedEncryptedBallot();
|
state.signedEncryptedBallot = encryptionAndSecrets.getSignedEncryptedBallot();
|
||||||
state.secrets = encryptionAndSecrets.getSecrets();
|
state.secrets = encryptionAndSecrets.getSecrets();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* a method to execute a Cast Command or an Audit Command
|
||||||
|
* according to the flag, chooses which finalize ballot task to send to the output device
|
||||||
|
* @param auditRequested true if we wish to finalize by auditing. false if we finalize by casting the ballot
|
||||||
|
*/
|
||||||
private void doFinalize (boolean auditRequested) {
|
private void doFinalize (boolean auditRequested) {
|
||||||
if (state.stateIdentifier == VBState.CAST_OR_AUDIT) {
|
if (state.stateIdentifier == VBState.CAST_OR_AUDIT) {
|
||||||
logger.debug("finalizing");
|
logger.debug("finalizing");
|
||||||
state.stateIdentifier = VBState.FINALIZING;
|
state.stateIdentifier = VBState.FINALIZING;
|
||||||
if (auditRequested) {
|
if (auditRequested) {
|
||||||
|
// finalize by auditing
|
||||||
ui.notifyVoterToWaitForFinish(systemMessages.get(StorageManager.WAIT_FOR_AUDIT_MESSAGE),
|
ui.notifyVoterToWaitForFinish(systemMessages.get(StorageManager.WAIT_FOR_AUDIT_MESSAGE),
|
||||||
new WaitForFinishCallback(generateRequestIdentifier(),
|
new WaitForFinishCallback(generateRequestIdentifier(),
|
||||||
state.currentBallotSerialNumber,
|
state.currentBallotSerialNumber,
|
||||||
|
@ -305,6 +369,7 @@ public class VotingBoothImpl implements VotingBoothController {
|
||||||
systemMessages.get(StorageManager.OUTPUT_DEVICE_FAILURE_MESSAGE)));
|
systemMessages.get(StorageManager.OUTPUT_DEVICE_FAILURE_MESSAGE)));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// finalize by casting the ballot
|
||||||
ui.notifyVoterToWaitForFinish(systemMessages.get(StorageManager.WAIT_FOR_CAST_MESSAGE),
|
ui.notifyVoterToWaitForFinish(systemMessages.get(StorageManager.WAIT_FOR_CAST_MESSAGE),
|
||||||
new WaitForFinishCallback(generateRequestIdentifier(),
|
new WaitForFinishCallback(generateRequestIdentifier(),
|
||||||
state.currentBallotSerialNumber,
|
state.currentBallotSerialNumber,
|
||||||
|
@ -325,8 +390,7 @@ public class VotingBoothImpl implements VotingBoothController {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// an enum to keep the step (of the voting process) in which the VB is currently in
|
||||||
|
|
||||||
private enum VBState {
|
private enum VBState {
|
||||||
NEW_VOTER,
|
NEW_VOTER,
|
||||||
CHOOSE_CHANNEL,
|
CHOOSE_CHANNEL,
|
||||||
|
@ -339,6 +403,15 @@ public class VotingBoothImpl implements VotingBoothController {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* a class to keep and directly access all the details of the VB controller state.
|
||||||
|
* naming:
|
||||||
|
* - the (enum) state identifier of the current step
|
||||||
|
* - the chosen channel
|
||||||
|
* - all details of the ballot (both plaintext and encryption)
|
||||||
|
* - last request identifier (to one of the other component interfaces)
|
||||||
|
* - serial number of the current ballot
|
||||||
|
*/
|
||||||
private class ControllerState {
|
private class ControllerState {
|
||||||
public VBState stateIdentifier;
|
public VBState stateIdentifier;
|
||||||
public byte[] channelIdentifier;
|
public byte[] channelIdentifier;
|
||||||
|
@ -359,7 +432,6 @@ public class VotingBoothImpl implements VotingBoothController {
|
||||||
currentBallotSerialNumber = 0;
|
currentBallotSerialNumber = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void clearPlaintext () {
|
private void clearPlaintext () {
|
||||||
plaintextBallot = null;
|
plaintextBallot = null;
|
||||||
}
|
}
|
||||||
|
@ -379,6 +451,11 @@ public class VotingBoothImpl implements VotingBoothController {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new request identifier to identify any call to one of the other component interfaces.
|
||||||
|
* We limit its value to MAX_REQUEST_IDENTIFIER, so the identifier is kept short.
|
||||||
|
* @return a new request identifier
|
||||||
|
*/
|
||||||
private int generateRequestIdentifier() {
|
private int generateRequestIdentifier() {
|
||||||
++requestCounter;
|
++requestCounter;
|
||||||
if (requestCounter >= MAX_REQUEST_IDENTIFIER) {
|
if (requestCounter >= MAX_REQUEST_IDENTIFIER) {
|
||||||
|
|
Loading…
Reference in New Issue