diff --git a/dspace-api/src/main/java/org/dspace/statistics/SolrLoggerServiceImpl.java b/dspace-api/src/main/java/org/dspace/statistics/SolrLoggerServiceImpl.java index 7cb88c43d8..e92d448caf 100644 --- a/dspace-api/src/main/java/org/dspace/statistics/SolrLoggerServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/statistics/SolrLoggerServiceImpl.java @@ -34,6 +34,7 @@ import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.time.temporal.ChronoUnit; import java.util.ArrayList; +import java.util.Arrays; import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; @@ -231,6 +232,10 @@ public class SolrLoggerServiceImpl implements SolrLoggerService, InitializingBea throw new RuntimeException(e); } + if (dspaceObject instanceof Bitstream && !isBitstreamLoggable((Bitstream) dspaceObject)) { + return; + } + if (solr == null) { return; } @@ -278,6 +283,10 @@ public class SolrLoggerServiceImpl implements SolrLoggerService, InitializingBea @Override public void postView(DSpaceObject dspaceObject, String ip, String userAgent, String xforwardedfor, EPerson currentUser, String referrer) { + if (dspaceObject instanceof Bitstream && !isBitstreamLoggable((Bitstream) dspaceObject)) { + return; + } + if (solr == null) { return; } @@ -1617,4 +1626,35 @@ public class SolrLoggerServiceImpl implements SolrLoggerService, InitializingBea throw new UnknownHostException("unknown ip format"); } + + /** + * Checks if a given Bitstream's bundles are configured to be logged in Solr statistics. + * + * @param bitstream The bitstream to check. + * @return {@code true} if the bitstream event should be logged, {@code false} otherwise. + */ + private boolean isBitstreamLoggable(Bitstream bitstream) { + String[] allowedBundles = configurationService + .getArrayProperty("solr-statistics.query.filter.bundles"); + if (allowedBundles == null || allowedBundles.length == 0) { + return true; + } + List allowedBundlesList = Arrays.asList(allowedBundles); + try { + List actualBundles = bitstream.getBundles(); + if (actualBundles.isEmpty()) { + return true; + } + for (Bundle bundle : actualBundles) { + if (allowedBundlesList.contains(bundle.getName())) { + return true; + } + } + } catch (SQLException e) { + log.error("Error checking bitstream bundles for logging statistics for bitstream {}", + bitstream.getID(), e); + return true; + } + return false; + } } diff --git a/dspace-api/src/test/java/org/dspace/statistics/SolrLoggerServiceImplIT.java b/dspace-api/src/test/java/org/dspace/statistics/SolrLoggerServiceImplIT.java index 2765719477..e5a4471ea6 100644 --- a/dspace-api/src/test/java/org/dspace/statistics/SolrLoggerServiceImplIT.java +++ b/dspace-api/src/test/java/org/dspace/statistics/SolrLoggerServiceImplIT.java @@ -11,6 +11,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.Writer; import java.nio.charset.StandardCharsets; @@ -27,8 +28,14 @@ import org.apache.solr.client.solrj.response.QueryResponse; import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrInputDocument; import org.dspace.AbstractIntegrationTestWithDatabase; +import org.dspace.builder.BitstreamBuilder; +import org.dspace.builder.CollectionBuilder; import org.dspace.builder.CommunityBuilder; +import org.dspace.builder.ItemBuilder; +import org.dspace.content.Bitstream; +import org.dspace.content.Collection; import org.dspace.content.Community; +import org.dspace.content.Item; import org.dspace.content.factory.ContentServiceFactory; import org.dspace.core.Constants; import org.dspace.core.factory.CoreServiceFactory; @@ -303,4 +310,56 @@ public class SolrLoggerServiceImplIT } assertEquals("Wrong number of documents remaining --", 1, nDocs); } + + @Test + public void testPostViewShouldNotLogIgnoredBundles() throws Exception { + ContentServiceFactory csf = ContentServiceFactory.getInstance(); + MockSolrLoggerServiceImpl solrLoggerService = DSpaceServicesFactory.getInstance() + .getServiceManager() + .getServiceByName("solrLoggerService", MockSolrLoggerServiceImpl.class); + solrLoggerService.bitstreamService = csf.getBitstreamService(); + solrLoggerService.contentServiceFactory = csf; + solrLoggerService.configurationService = DSpaceServicesFactory.getInstance().getConfigurationService(); + solrLoggerService.clientInfoService = CoreServiceFactory.getInstance().getClientInfoService(); + solrLoggerService.afterPropertiesSet(); + SolrStatisticsCore solrStatisticsCore = DSpaceServicesFactory.getInstance() + .getServiceManager() + .getServiceByName(SolrStatisticsCore.class.getName(), MockSolrStatisticsCore.class); + + solrStatisticsCore.getSolr().deleteByQuery("*:*"); + solrStatisticsCore.getSolr().commit(); + + context.turnOffAuthorisationSystem(); + Community community = CommunityBuilder + .createCommunity(context) + .withName("Test Community").build(); + Collection collection = CollectionBuilder + .createCollection(context, community) + .withName("Test Collection").build(); + Item item = ItemBuilder + .createItem(context, collection) + .withTitle("Test Item for Logging").build(); + Bitstream originalBitstream = BitstreamBuilder + .createBitstream(context, item, new ByteArrayInputStream("original content".getBytes()), "ORIGINAL") + .withName("original.txt") + .build(); + Bitstream thumbnailBitstream = BitstreamBuilder + .createBitstream(context, item, new ByteArrayInputStream("thumbnail content".getBytes()), "THUMBNAIL") + .withName("thumbnail.jpg") + .build(); + + context.restoreAuthSystemState(); + solrLoggerService.postView(originalBitstream, null, eperson); + solrLoggerService.postView(thumbnailBitstream, null, eperson); + + solrStatisticsCore.getSolr().commit(); + + SolrQuery thumbnailQuery = new SolrQuery("id:" + thumbnailBitstream.getID().toString()); + QueryResponse thumbnailResponse = solrStatisticsCore.getSolr().query(thumbnailQuery); + assertEquals("Thumbnail bundle should NOT be logged", 0, thumbnailResponse.getResults().getNumFound()); + + SolrQuery originalQuery = new SolrQuery("id:" + originalBitstream.getID().toString()); + QueryResponse originalResponse = solrStatisticsCore.getSolr().query(originalQuery); + assertEquals("ORIGINAL bundle SHOULD be logged", 1, originalResponse.getResults().getNumFound()); + } }