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

filter by includedCompartmentIds did not work

parent 6c89a8f1
Pipeline #50762 failed with stage
in 63 minutes and 18 seconds
......@@ -8,9 +8,10 @@ minerva (16.0.5) stable; urgency=medium
* Bug fix: some old maps could not be removed (#1607)
* Bug fix: concurency issue when exporting to CellDesigner - minerva could
crash when there were two exports running in parallel (#1598)
* Bug fix: fetching elements filtered by includedCompartmentIds using REST
API did not work (#1614)
-- Piotr Gawron <piotr.gawron@uni.lu> Mon, 13 Dec 2021 15:00:00 +0200
-- Piotr Gawron <piotr.gawron@uni.lu> Thu, 16 Dec 2021 11:00:00 +0200
minerva (16.0.4) stable; urgency=high
* Bug fix: security fix in log4j2 zero day exploit
......
package lcsb.mapviewer.api.projects.models.bioEntities.elements;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
......@@ -15,8 +23,24 @@ import lcsb.mapviewer.model.map.BioEntity;
import lcsb.mapviewer.model.map.compartment.Compartment;
import lcsb.mapviewer.model.map.layout.graphics.Glyph;
import lcsb.mapviewer.model.map.model.ModelData;
import lcsb.mapviewer.model.map.species.*;
import lcsb.mapviewer.model.map.species.field.*;
import lcsb.mapviewer.model.map.species.AntisenseRna;
import lcsb.mapviewer.model.map.species.Element;
import lcsb.mapviewer.model.map.species.Gene;
import lcsb.mapviewer.model.map.species.Protein;
import lcsb.mapviewer.model.map.species.Rna;
import lcsb.mapviewer.model.map.species.Species;
import lcsb.mapviewer.model.map.species.field.AbstractSiteModification;
import lcsb.mapviewer.model.map.species.field.BindingRegion;
import lcsb.mapviewer.model.map.species.field.CodingRegion;
import lcsb.mapviewer.model.map.species.field.ModificationResidue;
import lcsb.mapviewer.model.map.species.field.ModificationSite;
import lcsb.mapviewer.model.map.species.field.ProteinBindingDomain;
import lcsb.mapviewer.model.map.species.field.RegulatoryRegion;
import lcsb.mapviewer.model.map.species.field.Residue;
import lcsb.mapviewer.model.map.species.field.StructuralState;
import lcsb.mapviewer.model.map.species.field.Structure;
import lcsb.mapviewer.model.map.species.field.TranscriptionSite;
import lcsb.mapviewer.model.map.species.field.UniprotRecord;
import lcsb.mapviewer.persist.dao.map.species.ElementProperty;
import lcsb.mapviewer.services.QueryException;
import lcsb.mapviewer.services.interfaces.IElementService;
......@@ -33,13 +57,13 @@ public class ElementsRestImpl extends BaseRestImpl {
private Logger logger = LogManager.getLogger();
@Autowired
public ElementsRestImpl(IElementService elementService, IModelService modelService) {
public ElementsRestImpl(final IElementService elementService, final IModelService modelService) {
this.elementService = elementService;
this.modelService = modelService;
}
public List<Map<String, Object>> getElements(String projectId, String id, String columns, String mapId,
String type, String includedCompartmentIds, String excludedCompartmentIds)
public List<Map<String, Object>> getElements(final String projectId, final String id, final String columns, final String mapId,
final String type, final String includedCompartmentIds, final String excludedCompartmentIds)
throws QueryException {
Set<Integer> ids = new LinkedHashSet<>();
if (!id.equals("")) {
......@@ -87,8 +111,8 @@ public class ElementsRestImpl extends BaseRestImpl {
return result;
}
private boolean matchIncludedExcludedCompartments(Element element, Set<Compartment> includedCompartments,
Set<Compartment> excludedCompartments) {
private boolean matchIncludedExcludedCompartments(final Element element, final Set<Compartment> includedCompartments,
final Set<Compartment> excludedCompartments) {
boolean matchIncluded = true;
boolean matchExcluded = false;
......@@ -102,11 +126,11 @@ public class ElementsRestImpl extends BaseRestImpl {
return matchIncluded && !matchExcluded;
}
private boolean matchCompartments(Element element, Set<Compartment> compartmentList) {
private boolean matchCompartments(final Element element, final Set<Compartment> compartmentList) {
boolean isInside = false;
if (element != null) {
for (Compartment compartment : compartmentList) {
if (compartment.contains(element) && element.getModel().getId().equals(compartment.getModel().getId())) {
if (compartment.contains(element) && Objects.equals(element.getModelData().getId(), compartment.getModelData().getId())) {
isInside = true;
}
}
......@@ -114,7 +138,7 @@ public class ElementsRestImpl extends BaseRestImpl {
return isInside;
}
private Set<Compartment> getCompartments(String includedCompartmentIds, List<Element> elements) {
private Set<Compartment> getCompartments(final String includedCompartmentIds, final List<Element> elements) {
Set<Compartment> includedCompartments = new LinkedHashSet<>();
int count = 0;
if (!includedCompartmentIds.isEmpty()) {
......@@ -134,131 +158,131 @@ public class ElementsRestImpl extends BaseRestImpl {
return includedCompartments;
}
private Map<String, Object> preparedElement(Element element, Set<String> columnsSet) {
private Map<String, Object> preparedElement(final Element element, final Set<String> columnsSet) {
Map<String, Object> result = new TreeMap<>();
for (String string : columnsSet) {
String column = string.toLowerCase();
Object value = null;
switch (column) {
case "id":
case "idobject":
value = element.getId();
break;
case "modelid":
value = element.getModelData().getId();
break;
case "elementid":
value = element.getElementId();
break;
case "name":
value = element.getName();
break;
case "type":
value = element.getStringType();
break;
case "symbol":
value = element.getSymbol();
break;
case "fullname":
value = element.getFullName();
break;
case "abbreviation":
value = element.getAbbreviation();
break;
case "compartmentid":
if (element.getCompartment() != null) {
value = element.getCompartment().getId();
}
break;
case "complexid":
if (element instanceof Species) {
if (((Species) element).getComplex() != null) {
value = ((Species) element).getComplex().getId();
case "id":
case "idobject":
value = element.getId();
break;
case "modelid":
value = element.getModelData().getId();
break;
case "elementid":
value = element.getElementId();
break;
case "name":
value = element.getName();
break;
case "type":
value = element.getStringType();
break;
case "symbol":
value = element.getSymbol();
break;
case "fullname":
value = element.getFullName();
break;
case "abbreviation":
value = element.getAbbreviation();
break;
case "compartmentid":
if (element.getCompartment() != null) {
value = element.getCompartment().getId();
}
}
break;
case "initialconcentration":
if (element instanceof Species) {
value = ((Species) element).getInitialConcentration();
}
break;
case "initialamount":
if (element instanceof Species) {
value = ((Species) element).getInitialAmount();
}
break;
case "boundarycondition":
if (element instanceof Species) {
value = ((Species) element).isBoundaryCondition();
}
break;
case "constant":
if (element instanceof Species) {
value = ((Species) element).isConstant();
}
break;
case "hypothetical":
if (element instanceof Species) {
value = ((Species) element).isHypothetical();
}
break;
case "activity":
if (element instanceof Species) {
value = ((Species) element).getActivity();
}
break;
case "references":
value = createAnnotations(element.getMiriamData());
break;
case "synonyms":
value = element.getSynonyms();
break;
case "homomultimer":
if (element instanceof Species) {
value = ((Species) element).getHomodimer();
} else {
value = null;
}
break;
case "formula":
value = element.getFormula();
break;
case "notes":
value = element.getNotes();
break;
case "other":
value = getOthersForElement(element);
break;
case "formersymbols":
value = element.getFormerSymbols();
break;
case "hierarchyvisibilitylevel":
value = element.getVisibilityLevel();
break;
case "transparencylevel":
value = element.getTransparencyLevel();
break;
case "linkedsubmodel":
if (element.getSubmodel() != null) {
value = element.getSubmodel().getSubmodel().getId();
}
break;
case "bounds":
value = createBounds(element.getX(), element.getY(), element.getZ(), element.getWidth(), element.getHeight());
break;
case "glyph":
value = createGlyph(element.getGlyph());
break;
default:
value = "Unknown column";
break;
break;
case "complexid":
if (element instanceof Species) {
if (((Species) element).getComplex() != null) {
value = ((Species) element).getComplex().getId();
}
}
break;
case "initialconcentration":
if (element instanceof Species) {
value = ((Species) element).getInitialConcentration();
}
break;
case "initialamount":
if (element instanceof Species) {
value = ((Species) element).getInitialAmount();
}
break;
case "boundarycondition":
if (element instanceof Species) {
value = ((Species) element).isBoundaryCondition();
}
break;
case "constant":
if (element instanceof Species) {
value = ((Species) element).isConstant();
}
break;
case "hypothetical":
if (element instanceof Species) {
value = ((Species) element).isHypothetical();
}
break;
case "activity":
if (element instanceof Species) {
value = ((Species) element).getActivity();
}
break;
case "references":
value = createAnnotations(element.getMiriamData());
break;
case "synonyms":
value = element.getSynonyms();
break;
case "homomultimer":
if (element instanceof Species) {
value = ((Species) element).getHomodimer();
} else {
value = null;
}
break;
case "formula":
value = element.getFormula();
break;
case "notes":
value = element.getNotes();
break;
case "other":
value = getOthersForElement(element);
break;
case "formersymbols":
value = element.getFormerSymbols();
break;
case "hierarchyvisibilitylevel":
value = element.getVisibilityLevel();
break;
case "transparencylevel":
value = element.getTransparencyLevel();
break;
case "linkedsubmodel":
if (element.getSubmodel() != null) {
value = element.getSubmodel().getSubmodel().getId();
}
break;
case "bounds":
value = createBounds(element.getX(), element.getY(), element.getZ(), element.getWidth(), element.getHeight());
break;
case "glyph":
value = createGlyph(element.getGlyph());
break;
default:
value = "Unknown column";
break;
}
result.put(string, value);
}
return result;
}
private Map<String, Object> createGlyph(Glyph glyph) {
private Map<String, Object> createGlyph(final Glyph glyph) {
if (glyph == null) {
return null;
} else {
......@@ -268,7 +292,7 @@ public class ElementsRestImpl extends BaseRestImpl {
}
}
protected Map<String, Object> getOthersForElement(Element element) {
protected Map<String, Object> getOthersForElement(final Element element) {
Map<String, Object> result = new TreeMap<>();
List<Map<String, Object>> modifications = new ArrayList<>();
StructuralState structuralState = null;
......@@ -287,7 +311,7 @@ public class ElementsRestImpl extends BaseRestImpl {
modifications = getModifications(gene.getModificationResidues());
}
if (element instanceof Species) {
Species species= (Species) element;
Species species = (Species) element;
structures = getStructures(species.getUniprots());
structuralState = species.getStructuralState();
}
......@@ -302,7 +326,7 @@ public class ElementsRestImpl extends BaseRestImpl {
return result;
}
private List<Map<String, Object>> getModifications(List<? extends ModificationResidue> elements) {
private List<Map<String, Object>> getModifications(final List<? extends ModificationResidue> elements) {
List<Map<String, Object>> result = new ArrayList<>();
for (ModificationResidue region : elements) {
Map<String, Object> row = new TreeMap<>();
......@@ -342,7 +366,7 @@ public class ElementsRestImpl extends BaseRestImpl {
return result;
}
private Map<String, Object> getStructures(Set<UniprotRecord> uniprots) {
private Map<String, Object> getStructures(final Set<UniprotRecord> uniprots) {
Map<String, Object> result = new TreeMap<>();
for (UniprotRecord uniprotRec : uniprots) {
Set<Object> structs = new LinkedHashSet<>();
......@@ -354,7 +378,7 @@ public class ElementsRestImpl extends BaseRestImpl {
return result;
}
private Map<String, Object> createBounds(Double x, Double y, Integer z, Double width, Double height) {
private Map<String, Object> createBounds(final Double x, final Double y, final Integer z, final Double width, final Double height) {
Map<String, Object> result = new TreeMap<>();
result.put("x", x);
result.put("y", y);
......@@ -397,7 +421,7 @@ public class ElementsRestImpl extends BaseRestImpl {
return result;
}
private Set<String> createElementColumnSet(String columns) {
private Set<String> createElementColumnSet(final String columns) {
Set<String> columnsSet = new LinkedHashSet<>();
if (columns.equals("")) {
columnsSet.addAll(getAvailableElementColumns());
......
package lcsb.mapviewer.web;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
import static org.springframework.restdocs.request.RequestDocumentation.*;
import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName;
import static org.springframework.restdocs.request.RequestDocumentation.pathParameters;
import static org.springframework.restdocs.request.RequestDocumentation.requestParameters;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
......@@ -10,8 +12,14 @@ import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.*;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.function.Supplier;
import javax.annotation.PostConstruct;
......@@ -22,7 +30,9 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.LogEvent;
import org.junit.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.restdocs.JUnitRestDocumentation;
......@@ -41,20 +51,44 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import lcsb.mapviewer.api.projects.chemicals.ChemicalRestImpl;
import lcsb.mapviewer.common.*;
import lcsb.mapviewer.common.MinervaLoggerAppender;
import lcsb.mapviewer.common.TextFileUtils;
import lcsb.mapviewer.common.UnitTestFailedWatcher;
import lcsb.mapviewer.converter.ColorSchemaReader;
import lcsb.mapviewer.converter.zip.ZipEntryFileFactory;
import lcsb.mapviewer.model.*;
import lcsb.mapviewer.model.Project;
import lcsb.mapviewer.model.ProjectLogEntry;
import lcsb.mapviewer.model.ProjectLogEntryType;
import lcsb.mapviewer.model.ProjectStatus;
import lcsb.mapviewer.model.cache.UploadedFileEntry;
import lcsb.mapviewer.model.graphics.*;
import lcsb.mapviewer.model.map.*;
import lcsb.mapviewer.model.map.kinetics.*;
import lcsb.mapviewer.model.map.layout.*;
import lcsb.mapviewer.model.graphics.HorizontalAlign;
import lcsb.mapviewer.model.graphics.PolylineData;
import lcsb.mapviewer.model.graphics.VerticalAlign;
import lcsb.mapviewer.model.map.Comment;
import lcsb.mapviewer.model.map.MiriamData;
import lcsb.mapviewer.model.map.MiriamType;
import lcsb.mapviewer.model.map.OverviewImage;
import lcsb.mapviewer.model.map.compartment.Compartment;
import lcsb.mapviewer.model.map.compartment.SquareCompartment;
import lcsb.mapviewer.model.map.kinetics.SbmlFunction;
import lcsb.mapviewer.model.map.kinetics.SbmlParameter;
import lcsb.mapviewer.model.map.kinetics.SbmlUnit;
import lcsb.mapviewer.model.map.layout.ProjectBackground;
import lcsb.mapviewer.model.map.layout.ProjectBackgroundImageLayer;
import lcsb.mapviewer.model.map.layout.ProjectBackgroundStatus;
import lcsb.mapviewer.model.map.layout.graphics.Glyph;
import lcsb.mapviewer.model.map.model.*;
import lcsb.mapviewer.model.map.reaction.*;
import lcsb.mapviewer.model.map.model.ModelData;
import lcsb.mapviewer.model.map.model.ModelSubmodelConnection;
import lcsb.mapviewer.model.map.model.SubmodelType;
import lcsb.mapviewer.model.map.reaction.NodeOperator;
import lcsb.mapviewer.model.map.reaction.Product;
import lcsb.mapviewer.model.map.reaction.Reactant;
import lcsb.mapviewer.model.map.reaction.Reaction;
import lcsb.mapviewer.model.map.reaction.SplitOperator;
import lcsb.mapviewer.model.map.reaction.type.TransportReaction;
import lcsb.mapviewer.model.map.species.*;
import lcsb.mapviewer.model.map.species.Element;
import lcsb.mapviewer.model.map.species.GenericProtein;
import lcsb.mapviewer.model.map.species.SimpleMolecule;
import lcsb.mapviewer.model.overlay.DataOverlay;
import lcsb.mapviewer.model.overlay.DataOverlayType;
import lcsb.mapviewer.model.security.PrivilegeType;
......@@ -63,7 +97,9 @@ import lcsb.mapviewer.model.user.User;
import lcsb.mapviewer.persist.DbUtils;
import lcsb.mapviewer.persist.dao.ProjectDao;
import lcsb.mapviewer.persist.dao.cache.UploadedFileEntryDao;
import lcsb.mapviewer.persist.dao.map.*;
import lcsb.mapviewer.persist.dao.map.CommentDao;
import lcsb.mapviewer.persist.dao.map.DataOverlayDao;
import lcsb.mapviewer.persist.dao.map.ModelDao;
import lcsb.mapviewer.persist.dao.user.ResetPasswordTokenDao;
import lcsb.mapviewer.persist.dao.user.UserDao;
import lcsb.mapviewer.services.interfaces.IProjectService;
......@@ -169,17 +205,17 @@ abstract public class ControllerIntegrationTest {
}
/**
* This method can be used to work around the fact that MockMvc cannot retrieve
* cookies from Spring Security. The Reason for that is that MockMvc calls the
* controller directly and (partially?) bypasses Spring.
* This method can be used to work around the fact that MockMvc cannot
* retrieve cookies from Spring Security. The Reason for that is that MockMvc
* calls the controller directly and (partially?) bypasses Spring.
*
* This method creates a mocked session that can be used in a request as opposed
* to the token.
* This method creates a mocked session that can be used in a request as
* opposed to the token.
*
* FIXME: Find a better solution, that does not violate the spirit of
* integration tests.
*/
protected MockHttpSession createSession(String login, String password) throws Exception {
protected MockHttpSession createSession(final String login, final String password) throws Exception {
RequestBuilder request = post("/api/doLogin")
.param("login", login)
.param("password", password);
......@@ -224,7 +260,7 @@ abstract public class ControllerIntegrationTest {
return appender.getDebugs();
}
protected User createUser(String login, String password) {
protected User createUser(final String login, final String password) {
User user = new User();
user.setLogin(login);
user.setCryptedPassword(passwordEncoder.encode(password));
......@@ -232,32 +268,32 @@ abstract public class ControllerIntegrationTest {
return user;
}
protected User createUser(String login, String password, Project project) {
protected User createUser(final String login, final String password, final Project project) {
User user = createUser(login, password);
userService.grantUserPrivilege(user, PrivilegeType.READ_PROJECT, project.getProjectId());
return user;
}
protected User createAdmin(String login, String password) {
protected User createAdmin(final String login, final String password) {
User user = createUser(login, password);
userService.grantUserPrivilege(user, PrivilegeType.IS_ADMIN);
return user;
}
protected User createCurator(String login, String password) {
protected User createCurator(final String login, final String password) {
User user = createUser(login, password);
userService.grantUserPrivilege(user, PrivilegeType.IS_CURATOR);
return user;
}
protected User createCurator(String login, String password, Project project) {
protected User createCurator(final String login, final String password, final Project project) {
User user = createCurator(login, password);
userService.grantUserPrivilege(user, PrivilegeType.READ_PROJECT, project.getProjectId());
userService.grantUserPrivilege(user, PrivilegeType.WRITE_PROJECT, project.getProjectId());