package eu.europeana.cloud.service.dps.rest;
import eu.europeana.cloud.mcs.driver.DataSetServiceClient;
import eu.europeana.cloud.mcs.driver.FileServiceClient;
import eu.europeana.cloud.mcs.driver.RecordServiceClient;
import eu.europeana.cloud.service.dps.DpsTask;
import eu.europeana.cloud.service.dps.PluginParameterKeys;
import eu.europeana.cloud.service.dps.TaskExecutionReportService;
import eu.europeana.cloud.service.dps.exception.AccessDeniedOrObjectDoesNotExistException;
import eu.europeana.cloud.service.dps.exception.AccessDeniedOrTopologyDoesNotExistException;
import eu.europeana.cloud.service.dps.rest.exceptions.TaskSubmissionException;
import eu.europeana.cloud.service.dps.service.utils.TopologyManager;
import eu.europeana.cloud.service.dps.service.utils.validation.DpsTaskValidationException;
import eu.europeana.cloud.service.dps.storm.utils.CassandraTaskInfoDAO;
import eu.europeana.cloud.service.dps.utils.files.counter.FilesCounter;
import eu.europeana.cloud.service.dps.utils.files.counter.FilesCounterFactory;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.validation.constraints.NotNull;
import javax.ws.rs.container.AsyncResponse;
import javax.ws.rs.core.UriInfo;
import java.net.URI;
import java.util.Arrays;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doNothing;
@RunWith(SpringJUnit4ClassRunner.class)
public class DpsResourceAATest extends AbstractSecurityTest {
@Autowired
@NotNull
private TopologyTasksResource topologyTasksResource;
@Autowired
@NotNull
private TopologiesResource topologiesResource;
@Autowired
@NotNull
private TaskExecutionReportService reportService;
@Autowired
@NotNull
private TopologyManager topologyManager;
@Autowired
private RecordServiceClient recordServiceClient;
@Autowired
private DataSetServiceClient dataSetServiceClient;
@Autowired
private FileServiceClient fileServiceClient;
@Autowired
private CassandraTaskInfoDAO taskDAO;
@Autowired
private FilesCounterFactory filesCounterFactory;
@Autowired
private FilesCounter filesCounter;
/**
* Pre-defined users
*/
private final static String VAN_PERSIE = "Robin_Van_Persie";
private final static String VAN_PERSIE_PASSWORD = "Feyenoord";
private final static String RONALDO = "Cristiano";
private final static String RONALD_PASSWORD = "Ronaldo";
private final static String ADMIN = "admin";
private final static String ADMIN_PASSWORD = "admin";
private final static String SAMPLE_TOPOLOGY_NAME = "sampleTopology";
private final static String PROGRESS = "100%";
private DpsTask XSLT_TASK;
private DpsTask XSLT_TASK2;
private DpsTask XSLT_TASK_WITH_MALFORMED_URL;
private DpsTask IC_TASK;
private UriInfo URI_INFO;
private AsyncResponse asyncResponse;
private static final String AUTH_HEADER_VALUE = "header_value";
@Before
public void mockUp() throws Exception {
XSLT_TASK = new DpsTask("xsltTask");
XSLT_TASK.addDataEntry(DpsTask.FILE_URLS, Arrays.asList("http://127.0.0.1:8080/mcs/records/FUWQ4WMUGIGEHVA3X7FY5PA3DR5Q4B2C4TWKNILLS6EM4SJNTVEQ/representations/TIFF/versions/86318b00-6377-11e5-a1c6-90e6ba2d09ef/files/sampleFileName.txt"));
XSLT_TASK2 = new DpsTask("xsltTask");
XSLT_TASK2.addDataEntry(DpsTask.FILE_URLS, Arrays.asList("http://127.0.0.1:8080/mcs/records/sampleId/representations/TIFF/versions/86318b00-6377-11e5-a1c6-90e6ba2d09ef/files/sampleFileName.txt"));
XSLT_TASK_WITH_MALFORMED_URL = new DpsTask("taskWithMalformedUrl");
XSLT_TASK_WITH_MALFORMED_URL.addDataEntry("FILE_URLS", Arrays.asList("httpz://127.0.0.1:8080/mcs/records/FUWQ4WMUGIGEHVA3X7FY5PA3DR5Q4B2C4TWKNILLS6EM4SJNTVEQ/representations/TIFF/versions/86318b00-6377-11e5-a1c6-90e6ba2d09ef/files/sampleFileName.txt"));
URI_INFO = Mockito.mock(UriInfo.class);
asyncResponse = Mockito.mock(AsyncResponse.class);
Mockito.doReturn(PROGRESS).when(reportService).getTaskProgress(Mockito.anyString());
Mockito.when(URI_INFO.getBaseUri()).thenReturn(new URI("http:127.0.0.1:8080/sampleuri/"));
Mockito.when(topologyManager.containsTopology(SAMPLE_TOPOLOGY_NAME)).thenReturn(true);
doNothing().when(recordServiceClient).useAuthorizationHeader(anyString());
Mockito.when(filesCounterFactory.createFilesCounter(anyString())).thenReturn(filesCounter);
}
/*
Task Submission tests
*/
@Test(expected = AuthenticationCredentialsNotFoundException.class)
public void shouldThrowExceptionWhenNonAuthenticatedUserTriesToSubmitTask() throws AccessDeniedOrTopologyDoesNotExistException, DpsTaskValidationException, TaskSubmissionException {
DpsTask t = new DpsTask("xsltTask");
String topology = "xsltTopology";
topologyTasksResource.submitTask(asyncResponse, t, topology, URI_INFO, AUTH_HEADER_VALUE);
}
@Test
public void shouldBeAbleToSubmitTaskToTopologyThatHasPermissionsTo() throws AccessDeniedOrTopologyDoesNotExistException, DpsTaskValidationException, TaskSubmissionException {
login(ADMIN, ADMIN_PASSWORD);
topologiesResource.grantPermissionsToTopology(VAN_PERSIE, SAMPLE_TOPOLOGY_NAME);
logoutEveryone();
login(VAN_PERSIE, VAN_PERSIE_PASSWORD);
DpsTask task = new DpsTask();
task.addDataEntry(DpsTask.FILE_URLS, Arrays.asList("http://127.0.0.1:8080/mcs/records/FUWQ4WMUGIGEHVA3X7FY5PA3DR5Q4B2C4TWKNILLS6EM4SJNTVEQ/representations/TIFF/versions/86318b00-6377-11e5-a1c6-90e6ba2d09ef/files/sampleFileName.txt"));
task.addParameter(PluginParameterKeys.MIME_TYPE, "image/tiff");
task.addParameter(PluginParameterKeys.OUTPUT_MIME_TYPE, "image/jp2");
topologyTasksResource.submitTask(asyncResponse, task, SAMPLE_TOPOLOGY_NAME, URI_INFO, AUTH_HEADER_VALUE);
}
@Test
public void shouldBeAbleToSubmitTaskToXsltTopology() throws AccessDeniedOrTopologyDoesNotExistException, DpsTaskValidationException, TaskSubmissionException {
//when
DpsTask task = new DpsTask("xsltTask");
task.addDataEntry(DpsTask.FILE_URLS, Arrays.asList("http://127.0.0.1:8080/mcs/records/FUWQ4WMUGIGEHVA3X7FY5PA3DR5Q4B2C4TWKNILLS6EM4SJNTVEQ/representations/TIFF/versions/86318b00-6377-11e5-a1c6-90e6ba2d09ef/files/sampleFileName.txt"));
task.addParameter(PluginParameterKeys.XSLT_URL, "http://test.xslt");
String topologyName = "xslt_topology";
String user = VAN_PERSIE;
grantUserToTopology(topologyName, user);
login(user, VAN_PERSIE_PASSWORD);
//then
topologyTasksResource.submitTask(asyncResponse, task, topologyName, URI_INFO, AUTH_HEADER_VALUE);
}
@Test
public void shouldThrowDpsTaskValidationExceptionOnSubmitTaskToXsltTopologyWithMissingFileUrls() throws AccessDeniedOrTopologyDoesNotExistException, DpsTaskValidationException, TaskSubmissionException {
//when
DpsTask task = new DpsTask("xsltTask");
task.addParameter(PluginParameterKeys.XSLT_URL, "http://test.xslt");
String topologyName = "xslt_topology";
String user = VAN_PERSIE;
grantUserToTopology(topologyName, user);
login(user, VAN_PERSIE_PASSWORD);
try {
//when
topologyTasksResource.submitTask(asyncResponse, task, topologyName, URI_INFO, AUTH_HEADER_VALUE);
fail();
} catch (DpsTaskValidationException e) {
//then
assertThat(e.getMessage(), startsWith("Validation failed"));
}
}
@Test
public void shouldThrowDpsTaskValidationExceptionOnSubmitTaskToXsltTopologyWithMissingXsltUrl() throws AccessDeniedOrTopologyDoesNotExistException, DpsTaskValidationException, TaskSubmissionException {
//when
DpsTask task = new DpsTask("xsltTask");
task.addDataEntry(DpsTask.FILE_URLS, Arrays.asList("http://127.0.0.1:8080/mcs/records/FUWQ4WMUGIGEHVA3X7FY5PA3DR5Q4B2C4TWKNILLS6EM4SJNTVEQ/representations/TIFF/versions/86318b00-6377-11e5-a1c6-90e6ba2d09ef/files/sampleFileName.txt"));
String topologyName = "xslt_topology";
String user = VAN_PERSIE;
grantUserToTopology(topologyName, user);
login(user, VAN_PERSIE_PASSWORD);
try {
//when
topologyTasksResource.submitTask(asyncResponse, task, topologyName, URI_INFO, AUTH_HEADER_VALUE);
fail();
} catch (DpsTaskValidationException e) {
//then
assertThat(e.getMessage(), is("Expected parameter does not exist in dpsTask. Parameter name: XSLT_URL"));
}
}
@Test
public void shouldBeAbleToSubmitTaskToIcTopology() throws AccessDeniedOrTopologyDoesNotExistException, DpsTaskValidationException, TaskSubmissionException {
//when
DpsTask task = new DpsTask("icTask");
task.addDataEntry(DpsTask.FILE_URLS, Arrays.asList("http://127.0.0.1:8080/mcs/records/FUWQ4WMUGIGEHVA3X7FY5PA3DR5Q4B2C4TWKNILLS6EM4SJNTVEQ/representations/TIFF/versions/86318b00-6377-11e5-a1c6-90e6ba2d09ef/files/sampleFileName.txt"));
task.addParameter(PluginParameterKeys.MIME_TYPE, "image/tiff");
task.addParameter(PluginParameterKeys.OUTPUT_MIME_TYPE, "image/jp2");
String topologyName = "ic_topology";
String user = VAN_PERSIE;
grantUserToTopology(topologyName, user);
login(user, VAN_PERSIE_PASSWORD);
//then
topologyTasksResource.submitTask(asyncResponse, task, topologyName, URI_INFO, AUTH_HEADER_VALUE);
}
@Test
public void shouldNotBeAbleToSubmitTaskToIcTopologyWithUnacceptedOutputMimeType() throws AccessDeniedOrTopologyDoesNotExistException, DpsTaskValidationException, TaskSubmissionException {
//when
DpsTask task = new DpsTask("icTask");
task.addDataEntry(DpsTask.FILE_URLS, Arrays.asList("http://127.0.0.1:8080/mcs/records/FUWQ4WMUGIGEHVA3X7FY5PA3DR5Q4B2C4TWKNILLS6EM4SJNTVEQ/representations/TIFF/versions/86318b00-6377-11e5-a1c6-90e6ba2d09ef/files/sampleFileName.txt"));
task.addParameter(PluginParameterKeys.MIME_TYPE, "image/tiff");
task.addParameter(PluginParameterKeys.OUTPUT_MIME_TYPE, "undefined");
String topologyName = "ic_topology";
String user = VAN_PERSIE;
grantUserToTopology(topologyName, user);
login(user, VAN_PERSIE_PASSWORD);
//then
try {
topologyTasksResource.submitTask(asyncResponse, task, topologyName, URI_INFO, AUTH_HEADER_VALUE);
fail();
} catch (DpsTaskValidationException e) {
assertThat(e.getMessage(), is("Parameter does not meet constraints. Parameter name: OUTPUT_MIME_TYPE"));
}
}
@Test
public void shouldThrowDpsTaskValidationExceptionOnSubmitTaskToIcTopologyWithMissingFileUrls() throws AccessDeniedOrTopologyDoesNotExistException, DpsTaskValidationException, TaskSubmissionException {
//when
DpsTask task = new DpsTask("icTask");
String topologyName = "ic_topology";
String user = VAN_PERSIE;
grantUserToTopology(topologyName, user);
login(user, VAN_PERSIE_PASSWORD);
try {
//when
topologyTasksResource.submitTask(asyncResponse, task, topologyName, URI_INFO, AUTH_HEADER_VALUE);
fail();
} catch (DpsTaskValidationException e) {
//then
assertThat(e.getMessage(), startsWith("Validation failed"));
}
}
private void grantUserToTopology(String topologyName, String user) throws AccessDeniedOrTopologyDoesNotExistException {
login(ADMIN, ADMIN_PASSWORD);
Mockito.when(topologyManager.containsTopology(topologyName)).thenReturn(true);
topologiesResource.grantPermissionsToTopology(user, topologyName);
logoutEveryone();
}
@Test(expected = AccessDeniedException.class)
public void shouldNotBeAbleToSubmitTaskToTopologyThatHasNotPermissionsTo() throws AccessDeniedOrTopologyDoesNotExistException, DpsTaskValidationException, TaskSubmissionException {
login(ADMIN, ADMIN_PASSWORD);
topologiesResource.grantPermissionsToTopology(VAN_PERSIE, SAMPLE_TOPOLOGY_NAME);
logoutEveryone();
login(RONALDO, RONALD_PASSWORD);
DpsTask sampleTask = new DpsTask();
topologyTasksResource.submitTask(asyncResponse, sampleTask, SAMPLE_TOPOLOGY_NAME, URI_INFO, AUTH_HEADER_VALUE);
}
// -- progress report tests --
@Test
public void shouldBeAbleToCheckProgressIfHeIsTheTaskOwner() throws AccessDeniedOrObjectDoesNotExistException, AccessDeniedOrTopologyDoesNotExistException, DpsTaskValidationException, TaskSubmissionException {
login(ADMIN, ADMIN_PASSWORD);
topologiesResource.grantPermissionsToTopology(VAN_PERSIE, SAMPLE_TOPOLOGY_NAME);
login(VAN_PERSIE, VAN_PERSIE_PASSWORD);
submitTaskAndWait(asyncResponse, XSLT_TASK, SAMPLE_TOPOLOGY_NAME, URI_INFO, AUTH_HEADER_VALUE);
topologyTasksResource.getTaskProgress(SAMPLE_TOPOLOGY_NAME, "" + XSLT_TASK.getTaskId());
}
@Test(expected = AuthenticationCredentialsNotFoundException.class)
public void shouldThrowExceptionWhenNonAuthenticatedUserTriesToCheckProgress() throws AccessDeniedOrObjectDoesNotExistException, AccessDeniedOrTopologyDoesNotExistException {
topologyTasksResource.getTaskProgress(SAMPLE_TOPOLOGY_NAME, "" + XSLT_TASK.getTaskId());
}
@Test(expected = AccessDeniedException.class)
public void vanPersieShouldNotBeAbleCheckProgressOfRonaldosTask() throws AccessDeniedOrObjectDoesNotExistException, AccessDeniedOrTopologyDoesNotExistException, DpsTaskValidationException, TaskSubmissionException {
login(ADMIN, ADMIN_PASSWORD);
topologiesResource.grantPermissionsToTopology(RONALDO, SAMPLE_TOPOLOGY_NAME);
login(RONALDO, RONALD_PASSWORD);
submitTaskAndWait(asyncResponse, XSLT_TASK, SAMPLE_TOPOLOGY_NAME, URI_INFO, AUTH_HEADER_VALUE);
login(VAN_PERSIE, VAN_PERSIE_PASSWORD);
topologyTasksResource.getTaskProgress(SAMPLE_TOPOLOGY_NAME, "" + XSLT_TASK.getTaskId());
}
@Test(expected = AccessDeniedOrTopologyDoesNotExistException.class)
public void vanPersieShouldNotBeAbleGrantPermissionsToNotDefinedTopology() throws AccessDeniedOrObjectDoesNotExistException, AccessDeniedOrTopologyDoesNotExistException {
final String FAIL_TOPOLOGY_NAME = "failTopology";
//given
login(ADMIN, ADMIN_PASSWORD);
//when
topologiesResource.grantPermissionsToTopology(RONALDO, FAIL_TOPOLOGY_NAME);
//then - intentionally empty
}
@Test
public void vanPersieShouldNotBeAbleSubmitTaskToNotDefinedTopology() throws AccessDeniedOrTopologyDoesNotExistException, DpsTaskValidationException, TaskSubmissionException {
//given
Mockito.reset(topologyManager);
Mockito.when(topologyManager.containsTopology(SAMPLE_TOPOLOGY_NAME)).thenReturn(true, false);
login(ADMIN, ADMIN_PASSWORD);
topologiesResource.grantPermissionsToTopology(RONALDO, SAMPLE_TOPOLOGY_NAME);
login(RONALDO, RONALD_PASSWORD);
//when
try {
topologyTasksResource.submitTask(asyncResponse, XSLT_TASK, SAMPLE_TOPOLOGY_NAME, URI_INFO, AUTH_HEADER_VALUE);
fail();
//then
} catch (AccessDeniedOrTopologyDoesNotExistException e) {
}
}
@Test
public void vanPersieShouldNotBeAbleGetTaskProgressToNotDefinedTopology() throws AccessDeniedOrTopologyDoesNotExistException, AccessDeniedOrObjectDoesNotExistException, DpsTaskValidationException, TaskSubmissionException {
//given
Mockito.reset(topologyManager);
Mockito.when(topologyManager.containsTopology(SAMPLE_TOPOLOGY_NAME)).thenReturn(true, true, false);
login(ADMIN, ADMIN_PASSWORD);
topologiesResource.grantPermissionsToTopology(RONALDO, SAMPLE_TOPOLOGY_NAME);
login(RONALDO, RONALD_PASSWORD);
submitTaskAndWait(asyncResponse, XSLT_TASK, SAMPLE_TOPOLOGY_NAME, URI_INFO, AUTH_HEADER_VALUE);
//when
try {
topologyTasksResource.getTaskProgress(SAMPLE_TOPOLOGY_NAME, "" + XSLT_TASK.getTaskId());
fail();
//then
} catch (AccessDeniedOrTopologyDoesNotExistException e) {
}
}
@Test
public void vanPersieShouldNotBeAbleKillTaskoNotDefinedTopology() throws AccessDeniedOrTopologyDoesNotExistException, AccessDeniedOrObjectDoesNotExistException, DpsTaskValidationException, TaskSubmissionException {
//given
Mockito.reset(topologyManager);
Mockito.when(topologyManager.containsTopology(SAMPLE_TOPOLOGY_NAME)).thenReturn(true, true, false);
login(ADMIN, ADMIN_PASSWORD);
topologiesResource.grantPermissionsToTopology(RONALDO, SAMPLE_TOPOLOGY_NAME);
login(RONALDO, RONALD_PASSWORD);
submitTaskAndWait(asyncResponse, XSLT_TASK, SAMPLE_TOPOLOGY_NAME, URI_INFO, AUTH_HEADER_VALUE);
//when
try {
topologyTasksResource.killTask(SAMPLE_TOPOLOGY_NAME, "" + XSLT_TASK.getTaskId());
fail();
//then
} catch (AccessDeniedOrTopologyDoesNotExistException e) {
}
}
@Test
public void vanPersieShouldNotBeAbleCheckKillFlagNotDefinedTopology() throws AccessDeniedOrTopologyDoesNotExistException, AccessDeniedOrObjectDoesNotExistException, DpsTaskValidationException, TaskSubmissionException {
//given
Mockito.reset(topologyManager);
Mockito.when(topologyManager.containsTopology(SAMPLE_TOPOLOGY_NAME)).thenReturn(true, true, false);
login(ADMIN, ADMIN_PASSWORD);
topologiesResource.grantPermissionsToTopology(RONALDO, SAMPLE_TOPOLOGY_NAME);
login(RONALDO, RONALD_PASSWORD);
submitTaskAndWait(asyncResponse, XSLT_TASK, SAMPLE_TOPOLOGY_NAME, URI_INFO, AUTH_HEADER_VALUE);
//when
try {
topologyTasksResource.checkKillFlag(SAMPLE_TOPOLOGY_NAME, "" + XSLT_TASK.getTaskId());
fail();
//then
} catch (AccessDeniedOrTopologyDoesNotExistException e) {
}
}
@Test
public void vanPersieShouldNotBeRemoveKillFlagNotDefinedTopology() throws AccessDeniedOrTopologyDoesNotExistException, AccessDeniedOrObjectDoesNotExistException, DpsTaskValidationException, TaskSubmissionException {
//given
Mockito.reset(topologyManager);
Mockito.when(topologyManager.containsTopology(SAMPLE_TOPOLOGY_NAME)).thenReturn(true, true, false);
login(ADMIN, ADMIN_PASSWORD);
topologiesResource.grantPermissionsToTopology(RONALDO, SAMPLE_TOPOLOGY_NAME);
login(RONALDO, RONALD_PASSWORD);
submitTaskAndWait(asyncResponse, XSLT_TASK, SAMPLE_TOPOLOGY_NAME, URI_INFO, AUTH_HEADER_VALUE);
//when
try {
topologyTasksResource.removeKillFlag(SAMPLE_TOPOLOGY_NAME, "" + XSLT_TASK.getTaskId());
fail();
//then
} catch (AccessDeniedOrTopologyDoesNotExistException e) {
}
}
void submitTaskAndWait(AsyncResponse asyncResponse, DpsTask dpsTask, String topologyName, UriInfo uriInfo, String authHeader) throws DpsTaskValidationException, AccessDeniedOrTopologyDoesNotExistException {
topologyTasksResource.submitTask(asyncResponse, dpsTask, topologyName, uriInfo, authHeader);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}