diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/checks/SparqlSelectQueryResultsChecker.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/checks/SparqlSelectQueryResultsChecker.java index b40044d152..72087f89fb 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/checks/SparqlSelectQueryResultsChecker.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/checks/SparqlSelectQueryResultsChecker.java @@ -46,7 +46,7 @@ public static boolean sparqlSelectQueryResultsContain(Check check, Authorization AccessObject ao = ar.getAccessObject(); Model m = ao.getModel(); if (m == null) { - log.debug("SparqlQueryContains model is not provided"); + log.error("Model not provided"); return false; } @@ -116,10 +116,11 @@ private static Set getSparqlSelectResults(Model model, String profileUri AuthorizationRequest ar) { HashMap> queryMap = QueryResultsMapCache.get(); String queryMapKey = createQueryMapKey(profileUri, queryTemplate, ar); + HashSet results = new HashSet<>(); if (queryMap.containsKey(queryMapKey)) { - return queryMap.get(queryMapKey); + results.addAll(queryMap.get(queryMapKey)); + return results; } - Set results = new HashSet<>(); ParameterizedSparqlString pss = new ParameterizedSparqlString(); pss.setCommandText(queryTemplate); setVariables(profileUri, ar, pss); @@ -140,7 +141,9 @@ private static Set getSparqlSelectResults(Model model, String profileUri queryExecution.close(); } debug("query results: " + results); - queryMap.put(queryMapKey, results); + Set queryMapValue = new HashSet<>(); + queryMapValue.addAll(results); + queryMap.put(queryMapKey, queryMapValue); QueryResultsMapCache.update(queryMap); return results; } diff --git a/api/src/test/java/edu/cornell/mannlib/vitro/webapp/auth/checks/SparqlSelectQueryResultsCheckerTest.java b/api/src/test/java/edu/cornell/mannlib/vitro/webapp/auth/checks/SparqlSelectQueryResultsCheckerTest.java new file mode 100644 index 0000000000..cfd0dd611c --- /dev/null +++ b/api/src/test/java/edu/cornell/mannlib/vitro/webapp/auth/checks/SparqlSelectQueryResultsCheckerTest.java @@ -0,0 +1,98 @@ +package edu.cornell.mannlib.vitro.webapp.auth.checks; + +import static edu.cornell.mannlib.vitro.testing.ModelUtilitiesTestHelper.dataProperty; +import static edu.cornell.mannlib.vitro.webapp.auth.checks.SparqlSelectQueryResultsChecker.sparqlSelectQueryResultsContain; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; + +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessOperation; +import edu.cornell.mannlib.vitro.webapp.auth.attributes.MutableAttributeValueSet; +import edu.cornell.mannlib.vitro.webapp.auth.objects.NamedAccessObject; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.TestAuthorizationRequest; +import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; +import org.apache.jena.ontology.OntModel; +import org.apache.jena.ontology.OntModelSpec; +import org.apache.jena.ontology.impl.OntModelImpl; +import org.junit.Before; +import org.junit.Test; +import stubs.edu.cornell.mannlib.vitro.webapp.config.ConfigurationPropertiesStub; + +public class SparqlSelectQueryResultsCheckerTest { + + private static final String SIMPLE_QUERY = "SELECT ?value WHERE {?subject ?property ?value .}"; + private static final String NOT_PRESENT_VALUE = "not present value"; + private static final String TEST_URI = "test:uri"; + private static final String TEST_PROPERTY = "test:property"; + private static final String PRESENT_VALUE = "present value"; + + @Before + public void init() { + ConfigurationProperties configuration = new ConfigurationPropertiesStub(); + ConfigurationProperties.setInstance(configuration); + } + + @Test + public void testSimpleQuery() { + assertTrue(QueryResultsMapCache.get().isEmpty()); + MutableAttributeValueSet values = new MutableAttributeValueSet(PRESENT_VALUE); + Check check = new StatementObjectUriCheck(TEST_URI, values); + check.setConfiguration(SIMPLE_QUERY); + NamedAccessObject ao = new NamedAccessObject(TEST_URI); + OntModel model = new OntModelImpl(OntModelSpec.OWL_MEM); + model.add(dataProperty(TEST_URI, TEST_PROPERTY, PRESENT_VALUE)); + ao.setModel(model); + AuthorizationRequest ar = new TestAuthorizationRequest(ao, AccessOperation.DISPLAY); + boolean result = SparqlSelectQueryResultsChecker.sparqlSelectQueryResultsContain(check, ar, null); + assertTrue(result); + } + + @Test + public void testCacheNotCorruptedAfterCaching() throws IOException { + try (QueryResultsMapCache cache = new QueryResultsMapCache();) { + assertTrue(QueryResultsMapCache.get().isEmpty()); + MutableAttributeValueSet values = new MutableAttributeValueSet(NOT_PRESENT_VALUE); + Check check = new StatementObjectUriCheck(TEST_URI, values); + check.setConfiguration(SIMPLE_QUERY); + NamedAccessObject ao = new NamedAccessObject(TEST_URI); + OntModel model = new OntModelImpl(OntModelSpec.OWL_MEM); + model.add(dataProperty(TEST_URI, TEST_PROPERTY, PRESENT_VALUE)); + ao.setModel(model); + AuthorizationRequest ar = new TestAuthorizationRequest(ao, AccessOperation.DISPLAY); + assertFalse(sparqlSelectQueryResultsContain(check, ar, null)); + assertEquals(1, QueryResultsMapCache.get().size()); + values.remove(NOT_PRESENT_VALUE); + values.add(PRESENT_VALUE); + // Test that SPARQL results weren't modified after being cached + assertTrue(sparqlSelectQueryResultsContain(check, ar, null)); + } + } + + @Test + public void testCacheResultsNotCorruptedOnReuse() throws IOException { + try (QueryResultsMapCache cache = new QueryResultsMapCache();) { + assertTrue(QueryResultsMapCache.get().isEmpty()); + MutableAttributeValueSet values = new MutableAttributeValueSet(PRESENT_VALUE); + Check check = new StatementObjectUriCheck(TEST_URI, values); + check.setConfiguration(SIMPLE_QUERY); + NamedAccessObject ao = new NamedAccessObject(TEST_URI); + OntModel model = new OntModelImpl(OntModelSpec.OWL_MEM); + model.add(dataProperty(TEST_URI, TEST_PROPERTY, PRESENT_VALUE)); + ao.setModel(model); + AuthorizationRequest ar = new TestAuthorizationRequest(ao, AccessOperation.DISPLAY); + assertTrue(sparqlSelectQueryResultsContain(check, ar, null)); + assertEquals(1, QueryResultsMapCache.get().size()); + values.remove(PRESENT_VALUE); + values.add(NOT_PRESENT_VALUE); + assertFalse(sparqlSelectQueryResultsContain(check, ar, null)); + values.remove(NOT_PRESENT_VALUE); + values.add(PRESENT_VALUE); + // Test that SPARQL results weren't modified by previous cache client + assertTrue(sparqlSelectQueryResultsContain(check, ar, null)); + } + } + +}