new files with new names (old test passed)
parent
db4cf6a734
commit
11b86dd2aa
|
@ -0,0 +1,59 @@
|
|||
package meerkat.pollingstation;
|
||||
|
||||
import com.google.common.util.concurrent.FutureCallback;
|
||||
import meerkat.protobuf.PollingStation;
|
||||
import meerkat.rest.ProtobufMessageBodyReader;
|
||||
import meerkat.rest.ProtobufMessageBodyWriter;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.glassfish.jersey.servlet.ServletContainer;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Laura on 3/20/2017.
|
||||
*/
|
||||
public class ReceiverScanHandler implements PollingStationScanner.Consumer{
|
||||
|
||||
public final static String CALLBACKS_ATTRIBUTE_NAME = "callbacks";
|
||||
|
||||
private final Server server;
|
||||
private final List<FutureCallback<PollingStation.ScannedData>> callbacks;
|
||||
|
||||
public ReceiverScanHandler(int port, String subAddress) {
|
||||
|
||||
callbacks = new LinkedList<>();
|
||||
|
||||
server = new Server(port);
|
||||
|
||||
ServletContextHandler servletContextHandler = new ServletContextHandler(server, subAddress);
|
||||
servletContextHandler.setAttribute(CALLBACKS_ATTRIBUTE_NAME, (Iterable<FutureCallback<PollingStation.ScannedData>>) callbacks);
|
||||
|
||||
ResourceConfig resourceConfig = new ResourceConfig(ReceiverWebAPI.class);
|
||||
resourceConfig.register(ProtobufMessageBodyReader.class);
|
||||
resourceConfig.register(ProtobufMessageBodyWriter.class);
|
||||
|
||||
ServletHolder servletHolder = new ServletHolder(new ServletContainer(resourceConfig));
|
||||
|
||||
servletContextHandler.addServlet(servletHolder, "/*");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() throws Exception {
|
||||
server.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() throws Exception {
|
||||
server.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subscribe(FutureCallback<PollingStation.ScannedData> scanCallback) {
|
||||
callbacks.add(scanCallback);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
package meerkat.pollingstation;
|
||||
|
||||
import com.google.common.util.concurrent.FutureCallback;
|
||||
import com.google.protobuf.BoolValue;
|
||||
import meerkat.protobuf.PollingStation;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.Context;
|
||||
import java.io.IOException;
|
||||
|
||||
import static meerkat.pollingstation.PollingStationConstants.POLLING_STATION_WEB_SCANNER_ERROR_PATH;
|
||||
import static meerkat.pollingstation.PollingStationConstants.POLLING_STATION_WEB_SCANNER_SCAN_PATH;
|
||||
import static meerkat.rest.Constants.MEDIATYPE_PROTOBUF;
|
||||
|
||||
/**
|
||||
* Implements a Web-App interface for {@link meerkat.pollingstation.PollingStationScanner.Producer}
|
||||
* This class depends on {@link meerkat.pollingstation.PollingStationWebScanner} and works in conjunction with it
|
||||
*/
|
||||
@Path("/")
|
||||
public class ReceiverWebAPI implements PollingStationScanner.Producer {
|
||||
|
||||
@Context
|
||||
ServletContext servletContext;
|
||||
|
||||
Iterable<FutureCallback<PollingStation.ScannedData>> callbacks;
|
||||
|
||||
/**
|
||||
* This method is called by the Jetty engine when instantiating the servlet
|
||||
*/
|
||||
@PostConstruct
|
||||
@SuppressWarnings("unchecked")
|
||||
public void init() throws Exception {
|
||||
Object context = servletContext.getAttribute(PollingStationWebScanner.CALLBACKS_ATTRIBUTE_NAME);
|
||||
|
||||
try {
|
||||
callbacks = (Iterable<FutureCallback<PollingStation.ScannedData>>) context;
|
||||
} catch (ClassCastException e) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path(POLLING_STATION_WEB_SCANNER_SCAN_PATH)
|
||||
@Consumes(MEDIATYPE_PROTOBUF)
|
||||
@Produces(MEDIATYPE_PROTOBUF)
|
||||
@Override
|
||||
public BoolValue newScan(PollingStation.ScannedData scannedData) {
|
||||
|
||||
boolean handled = false;
|
||||
|
||||
for (FutureCallback<PollingStation.ScannedData> callback : callbacks){
|
||||
|
||||
callback.onSuccess(scannedData);
|
||||
handled = true;
|
||||
|
||||
}
|
||||
|
||||
return BoolValue.newBuilder()
|
||||
.setValue(handled)
|
||||
.build();
|
||||
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path(POLLING_STATION_WEB_SCANNER_ERROR_PATH)
|
||||
@Consumes(MEDIATYPE_PROTOBUF)
|
||||
@Produces(MEDIATYPE_PROTOBUF)
|
||||
@Override
|
||||
public BoolValue reportScanError(PollingStation.ErrorMsg errorMsg) {
|
||||
|
||||
boolean handled = false;
|
||||
|
||||
for (FutureCallback<PollingStation.ScannedData> callback : callbacks){
|
||||
|
||||
callback.onFailure(new IOException(errorMsg.getMsg()));
|
||||
handled = true;
|
||||
|
||||
}
|
||||
|
||||
return BoolValue.newBuilder()
|
||||
.setValue(handled)
|
||||
.build();
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package meerkat.pollingstation;
|
||||
|
||||
/**
|
||||
* Created by Laura on 3/20/2017.
|
||||
*/
|
||||
public class ScannerClientAPI {
|
||||
}
|
|
@ -0,0 +1,162 @@
|
|||
package meerkat.pollingstation;
|
||||
|
||||
import com.google.common.util.concurrent.FutureCallback;
|
||||
import com.google.protobuf.ByteString;
|
||||
import meerkat.protobuf.PollingStation.ErrorMsg;
|
||||
import meerkat.protobuf.PollingStation.ScannedData;
|
||||
import meerkat.rest.Constants;
|
||||
import meerkat.rest.ProtobufMessageBodyReader;
|
||||
import meerkat.rest.ProtobufMessageBodyWriter;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
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.util.concurrent.Semaphore;
|
||||
|
||||
import static meerkat.pollingstation.PollingStationConstants.POLLING_STATION_WEB_SCANNER_ERROR_PATH;
|
||||
import static meerkat.pollingstation.PollingStationConstants.POLLING_STATION_WEB_SCANNER_SCAN_PATH;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
/**
|
||||
* Created by Arbel on 25/05/2016.
|
||||
*/
|
||||
public class ReceiverTest {
|
||||
|
||||
private PollingStationScanner.Consumer scanner;
|
||||
private static final String ADDRESS = "http://localhost";
|
||||
private static final String SUB_ADDRESS = "";
|
||||
private static final int PORT = 8080;
|
||||
|
||||
private Semaphore semaphore;
|
||||
private Throwable thrown;
|
||||
private boolean dataIsAsExpected;
|
||||
|
||||
private class ScanHandler implements FutureCallback<ScannedData> {
|
||||
|
||||
private final ScannedData expectedData;
|
||||
|
||||
public ScanHandler(ScannedData expectedData) {
|
||||
this.expectedData = expectedData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(ScannedData result) {
|
||||
dataIsAsExpected = result.getChannel().equals(expectedData.getChannel());
|
||||
semaphore.release();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
dataIsAsExpected = false;
|
||||
thrown = t;
|
||||
semaphore.release();
|
||||
}
|
||||
}
|
||||
|
||||
private class ErrorHandler implements FutureCallback<ScannedData> {
|
||||
|
||||
private final String expectedErrorMessage;
|
||||
|
||||
public ErrorHandler(String expectedErrorMessage) {
|
||||
this.expectedErrorMessage = expectedErrorMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(ScannedData result) {
|
||||
dataIsAsExpected = false;
|
||||
semaphore.release();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
dataIsAsExpected = t.getMessage().equals(expectedErrorMessage);
|
||||
semaphore.release();
|
||||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
|
||||
System.err.println("Setting up Scanner WebApp!");
|
||||
|
||||
scanner = new ReceiverScanHandler(PORT, SUB_ADDRESS);
|
||||
|
||||
semaphore = new Semaphore(0);
|
||||
thrown = null;
|
||||
|
||||
try {
|
||||
scanner.start();
|
||||
} catch (Exception e) {
|
||||
assertThat("Could not start server: " + e.getMessage(), false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccessfulScan() throws InterruptedException {
|
||||
|
||||
Client client = ClientBuilder.newClient();
|
||||
client.register(ProtobufMessageBodyReader.class);
|
||||
client.register(ProtobufMessageBodyWriter.class);
|
||||
WebTarget webTarget = client.target(ADDRESS + ":" + PORT)
|
||||
.path(SUB_ADDRESS).path(POLLING_STATION_WEB_SCANNER_SCAN_PATH);
|
||||
|
||||
byte[] data = {(byte) 1, (byte) 2};
|
||||
|
||||
ScannedData scannedData = ScannedData.newBuilder()
|
||||
.setChannel(ByteString.copyFrom(data))
|
||||
.build();
|
||||
|
||||
scanner.subscribe(new ScanHandler(scannedData));
|
||||
|
||||
Response response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(scannedData, Constants.MEDIATYPE_PROTOBUF));
|
||||
response.close();
|
||||
|
||||
semaphore.acquire();
|
||||
assertThat("Scanner has thrown an error", thrown == null);
|
||||
assertThat("Scanned data received was incorrect", dataIsAsExpected);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testErroneousScan() throws InterruptedException {
|
||||
|
||||
Client client = ClientBuilder.newClient();
|
||||
client.register(ProtobufMessageBodyReader.class);
|
||||
client.register(ProtobufMessageBodyWriter.class);
|
||||
WebTarget webTarget = client.target(ADDRESS + ":" + PORT)
|
||||
.path(SUB_ADDRESS).path(POLLING_STATION_WEB_SCANNER_ERROR_PATH);
|
||||
|
||||
ErrorMsg errorMsg = ErrorMsg.newBuilder()
|
||||
.setMsg("!Error Message!")
|
||||
.build();
|
||||
|
||||
scanner.subscribe(new ErrorHandler(errorMsg.getMsg()));
|
||||
|
||||
Response response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(errorMsg, Constants.MEDIATYPE_PROTOBUF));
|
||||
response.close();
|
||||
|
||||
semaphore.acquire();
|
||||
assertThat("Scanner error received was incorrect", dataIsAsExpected);
|
||||
|
||||
}
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
|
||||
System.err.println("ReceiverScanHandler shutting down...");
|
||||
|
||||
try {
|
||||
scanner.stop();
|
||||
} catch (Exception e) {
|
||||
assertThat("Could not stop server: " + e.getMessage(), false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue