Commit bc0de048 authored by Piotr Gawron's avatar Piotr Gawron
Browse files

upload of project with invalid data overlay should fail

parent c00fe9ef
Pipeline #24151 canceled with stage
in 5 minutes and 5 seconds
...@@ -2,6 +2,8 @@ minerva (15.0.0~beta.3) unstable; urgency=medium ...@@ -2,6 +2,8 @@ minerva (15.0.0~beta.3) unstable; urgency=medium
* Improvement: API allows to merge files (#1208) * Improvement: API allows to merge files (#1208)
* Bug fix: exported SBML was not compliant with the standard when element * Bug fix: exported SBML was not compliant with the standard when element
name was empty (#1147) name was empty (#1147)
* Bug fix: invalid data overlays in uploaded zip file created "valid" project
that could not be opened (#1086)
-- Piotr Gawron <piotr.gawron@uni.lu> Wed, 1 Apr 2020 14:00:00 +0200 -- Piotr Gawron <piotr.gawron@uni.lu> Wed, 1 Apr 2020 14:00:00 +0200
......
...@@ -2,6 +2,7 @@ package lcsb.mapviewer.services.impl; ...@@ -2,6 +2,7 @@ package lcsb.mapviewer.services.impl;
import java.awt.Color; import java.awt.Color;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.util.*; import java.util.*;
import java.util.Comparator; import java.util.Comparator;
...@@ -151,21 +152,8 @@ public class LayoutService implements ILayoutService { ...@@ -151,21 +152,8 @@ public class LayoutService implements ILayoutService {
@Override @Override
public Layout createLayout(final CreateLayoutParams params) throws IOException, InvalidColorSchemaException { public Layout createLayout(final CreateLayoutParams params) throws IOException, InvalidColorSchemaException {
ColorSchemaReader reader = new ColorSchemaReader(); ColorSchemaReader reader = new ColorSchemaReader();
Map<String, String> parameters = TextFileUtils.getHeaderParametersFromFile(params.getColorInputStream());
ColorSchemaType colorSchemaType = params.getColorSchemaType(); ColorSchemaType colorSchemaType = params.getColorSchemaType();
if (colorSchemaType == null) { Map<String, String> parameters = extractHeaderParameters(params.getColorInputStream(), colorSchemaType);
String type = parameters.get(ZipEntryFileFactory.LAYOUT_HEADER_PARAM_TYPE);
if (type != null) {
colorSchemaType = ColorSchemaType.valueOf(type);
}
}
if (colorSchemaType == null) {
colorSchemaType = ColorSchemaType.GENERIC;
}
if (parameters.get(ZipEntryFileFactory.LAYOUT_HEADER_PARAM_TYPE) == null && params.getColorSchemaType() != null) {
parameters.put(ZipEntryFileFactory.LAYOUT_HEADER_PARAM_TYPE, params.getColorSchemaType().name());
}
final Collection<ColorSchema> schemas = reader.readColorSchema(params.getColorInputStream(), parameters); final Collection<ColorSchema> schemas = reader.readColorSchema(params.getColorInputStream(), parameters);
// check if we can color our model using this schema, // check if we can color our model using this schema,
...@@ -218,6 +206,24 @@ public class LayoutService implements ILayoutService { ...@@ -218,6 +206,24 @@ public class LayoutService implements ILayoutService {
return topLayout; return topLayout;
} }
protected Map<String, String> extractHeaderParameters(InputStream colorInputStream, ColorSchemaType colorSchemaType) throws IOException {
Map<String, String> parameters = TextFileUtils.getHeaderParametersFromFile(colorInputStream);
if (colorSchemaType == null) {
String type = parameters.get(ZipEntryFileFactory.LAYOUT_HEADER_PARAM_TYPE);
if (type != null) {
colorSchemaType = ColorSchemaType.valueOf(type);
}
}
if (colorSchemaType == null) {
colorSchemaType = ColorSchemaType.GENERIC;
}
if (parameters.get(ZipEntryFileFactory.LAYOUT_HEADER_PARAM_TYPE) == null && colorSchemaType != null) {
parameters.put(ZipEntryFileFactory.LAYOUT_HEADER_PARAM_TYPE, colorSchemaType.name());
}
return parameters;
}
@Override @Override
public Layout createLayoutWithImages(final CreateLayoutParams params) public Layout createLayoutWithImages(final CreateLayoutParams params)
throws IOException, InvalidColorSchemaException, CommandExecutionException { throws IOException, InvalidColorSchemaException, CommandExecutionException {
......
...@@ -50,8 +50,7 @@ import lcsb.mapviewer.services.overlay.AnnotatedObjectTreeRow; ...@@ -50,8 +50,7 @@ import lcsb.mapviewer.services.overlay.AnnotatedObjectTreeRow;
import lcsb.mapviewer.services.search.chemical.IChemicalService; import lcsb.mapviewer.services.search.chemical.IChemicalService;
import lcsb.mapviewer.services.search.drug.IDrugService; import lcsb.mapviewer.services.search.drug.IDrugService;
import lcsb.mapviewer.services.search.mirna.IMiRNAService; import lcsb.mapviewer.services.search.mirna.IMiRNAService;
import lcsb.mapviewer.services.utils.CreateProjectParams; import lcsb.mapviewer.services.utils.*;
import lcsb.mapviewer.services.utils.EmailSender;
import lcsb.mapviewer.services.utils.data.BuildInLayout; import lcsb.mapviewer.services.utils.data.BuildInLayout;
/** /**
...@@ -694,9 +693,11 @@ public class ProjectService implements IProjectService { ...@@ -694,9 +693,11 @@ public class ProjectService implements IProjectService {
* project where the model should be placed * project where the model should be placed
* @throws InvalidInputDataExecption * @throws InvalidInputDataExecption
* thrown when there is a problem with input file * thrown when there is a problem with input file
* @throws InvalidColorSchemaException
* @throws IOException
*/ */
protected void createModel(final CreateProjectParams params, Project dbProject) protected void createModel(final CreateProjectParams params, Project dbProject)
throws InvalidInputDataExecption, ConverterException { throws InvalidInputDataExecption, ConverterException, IOException, InvalidColorSchemaException {
User dbUser = userDao.getById(params.getUser().getId()); User dbUser = userDao.getById(params.getUser().getId());
UserAnnotationSchema userAnnotationSchema = dbUser.getAnnotationSchema(); UserAnnotationSchema userAnnotationSchema = dbUser.getAnnotationSchema();
if (userAnnotationSchema == null) { if (userAnnotationSchema == null) {
...@@ -830,7 +831,7 @@ public class ProjectService implements IProjectService { ...@@ -830,7 +831,7 @@ public class ProjectService implements IProjectService {
l.setOrderIndex(order++); l.setOrderIndex(order++);
} }
projectDao.update(project); projectDao.update(project);
validateDataOverlays(project);
if (params.isUpdateAnnotations()) { if (params.isUpdateAnnotations()) {
Map<Class<?>, List<ElementAnnotator>> annotators = null; Map<Class<?>, List<ElementAnnotator>> annotators = null;
if (params.getAnnotatorsMap() != null) { if (params.getAnnotatorsMap() != null) {
...@@ -853,6 +854,21 @@ public class ProjectService implements IProjectService { ...@@ -853,6 +854,21 @@ public class ProjectService implements IProjectService {
} }
private void validateDataOverlays(final Project project) throws IOException, InvalidColorSchemaException {
for (Layout l : project.getLayouts()) {
if (l.getInputData() != null) {
ColorSchemaReader reader = new ColorSchemaReader();
Map<String, String> parameters = new LayoutService(null, null, null, null)
.extractHeaderParameters(new ByteArrayInputStream(l.getInputData().getFileContent()), null);
try {
reader.readColorSchema(new ByteArrayInputStream(l.getInputData().getFileContent()), parameters);
} catch (InvalidColorSchemaException e) {
throw new InvalidColorSchemaException("Problematic data overlay: " + l.getTitle() + ". " + e.getMessage(), e);
}
}
}
}
private void assignZoomLevelDataToModel(Model topModel) throws InvalidInputDataExecption { private void assignZoomLevelDataToModel(Model topModel) throws InvalidInputDataExecption {
Integer maxZoomLevels = Integer Integer maxZoomLevels = Integer
.parseInt(configurationService.getValue(ConfigurationElementType.MAX_NUMBER_OF_MAP_LEVELS).getValue()); .parseInt(configurationService.getValue(ConfigurationElementType.MAX_NUMBER_OF_MAP_LEVELS).getValue());
......
package lcsb.mapviewer.web; package lcsb.mapviewer.web;
import static org.junit.Assert.assertEquals;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
...@@ -20,8 +21,11 @@ import org.springframework.http.MediaType; ...@@ -20,8 +21,11 @@ import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.RequestBuilder; import org.springframework.test.web.servlet.RequestBuilder;
import lcsb.mapviewer.model.Project;
import lcsb.mapviewer.model.ProjectStatus;
import lcsb.mapviewer.model.cache.UploadedFileEntry; import lcsb.mapviewer.model.cache.UploadedFileEntry;
import lcsb.mapviewer.model.user.User; import lcsb.mapviewer.model.user.User;
import lcsb.mapviewer.services.interfaces.IProjectService;
import lcsb.mapviewer.services.interfaces.IUserService; import lcsb.mapviewer.services.interfaces.IUserService;
@RunWith(SpringJUnit4ClassRunner.class) @RunWith(SpringJUnit4ClassRunner.class)
...@@ -36,6 +40,9 @@ public class ProjectControllerIntegrationTestWithoutTransaction extends Controll ...@@ -36,6 +40,9 @@ public class ProjectControllerIntegrationTestWithoutTransaction extends Controll
@Autowired @Autowired
private IUserService userService; private IUserService userService;
@Autowired
private IProjectService projectService;
@Before @Before
public void setup() { public void setup() {
} }
...@@ -327,4 +334,60 @@ public class ProjectControllerIntegrationTestWithoutTransaction extends Controll ...@@ -327,4 +334,60 @@ public class ProjectControllerIntegrationTestWithoutTransaction extends Controll
} }
} }
@Test
public void addComplexProjectWithInvalidOverlay() throws Exception {
User admin = userService.getUserByLogin(BUILT_IN_ADMIN_LOGIN);
UploadedFileEntry fileEntry = createFileInSeparateThread(
Files.readAllBytes(Paths.get("./src/test/resources/complex_model_with_invalid_layouts.zip")), admin);
try {
String body = EntityUtils.toString(new UrlEncodedFormEntity(Arrays.asList(
new BasicNameValuePair("file-id", String.valueOf(fileEntry.getId())),
new BasicNameValuePair("mapCanvasType", "OPEN_LAYERS"),
new BasicNameValuePair("parser", "lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser"),
new BasicNameValuePair("zip-entries[0][_type]", "MAP"),
new BasicNameValuePair("zip-entries[0][_filename]", "main.xml"),
new BasicNameValuePair("zip-entries[0][_data][root]", "true"),
new BasicNameValuePair("zip-entries[0][_data][name]", "s1"),
new BasicNameValuePair("zip-entries[0][_data][type][id]", "UNKNOWN"),
new BasicNameValuePair("zip-entries[0][_data][type][name]", "Unknown"),
new BasicNameValuePair("zip-entries[1][_type]", "OVERLAY"),
new BasicNameValuePair("zip-entries[1][_filename]", "layouts/badSchema.txt"),
new BasicNameValuePair("zip-entries[1][_data][name]", "test-o")
)));
RequestBuilder request = post("/projects/" + TEST_PROJECT)
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.content(body)
.session(createSession(BUILT_IN_ADMIN_LOGIN, BUILT_IN_ADMIN_PASSWORD));
mockMvc.perform(request).andExpect(status().is2xxSuccessful());
callInSeparateThread(() -> {
try {
waitForProjectToFinishLoading(TEST_PROJECT);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
});
Project project = projectService.getProjectByProjectId(TEST_PROJECT);
assertEquals(ProjectStatus.FAIL, project.getStatus());
} finally {
callInSeparateThread(() -> {
try {
waitForProjectToFinishLoading(TEST_PROJECT);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
});
removeProjectInSeparateThread(TEST_PROJECT);
}
}
} }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment