diff --git a/search-services/alfresco-search/pom.xml b/search-services/alfresco-search/pom.xml index 8a1abc182..67e513dff 100644 --- a/search-services/alfresco-search/pom.xml +++ b/search-services/alfresco-search/pom.xml @@ -18,7 +18,7 @@ org.alfresco alfresco-solrclient - ${alfresco-solr.version} + ${alfresco-solrclient.version} servlet-api @@ -60,6 +60,12 @@ solr-langid ${solr.version} provided + + + xercesImpl + xerces + + diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/AlfrescoSolrDataModel.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/AlfrescoSolrDataModel.java index dc782e79a..8d777c5a3 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/AlfrescoSolrDataModel.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/AlfrescoSolrDataModel.java @@ -1386,7 +1386,7 @@ public class AlfrescoSolrDataModel implements QueryConstants } // parse cmis syntax - CapabilityJoin joinSupport = (mode == CMISQueryMode.CMS_STRICT) ? CapabilityJoin.NONE : CapabilityJoin.INNERONLY; + CapabilityJoin joinSupport = (mode == CMISQueryMode.CMS_STRICT) ? CapabilityJoin.NONE : CapabilityJoin.INNERANDOUTER; CmisFunctionEvaluationContext functionContext = getCMISFunctionEvaluationContext(mode, cmisVersion, alternativeDictionary); CMISDictionaryService cmisDictionary = getCMISDictionary(alternativeDictionary, cmisVersion); @@ -1401,10 +1401,6 @@ public class AlfrescoSolrDataModel implements QueryConstants { throw new UnsupportedOperationException("No selectors"); } - if (selectorGroups.size() > 1) - { - throw new UnsupportedOperationException("Advanced join is not supported"); - } } return queryModelQuery; } diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/component/AsyncBuildSuggestComponent.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/component/AsyncBuildSuggestComponent.java index bd3ccf308..efcb7d38d 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/component/AsyncBuildSuggestComponent.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/component/AsyncBuildSuggestComponent.java @@ -748,7 +748,10 @@ public class AsyncBuildSuggestComponent extends SearchComponent implements SolrC return initialSuggester; } - tempFileWarningLogger.checkFiles(); + if(tempFileWarningLogger.checkFiles()) + { + tempFileWarningLogger.removeFiles(); + } RefCounted refCountedSearcher = core.getSearcher(); try diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/component/TempFileWarningLogger.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/component/TempFileWarningLogger.java index 8d4cb0bbe..b2b8d07f3 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/component/TempFileWarningLogger.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/component/TempFileWarningLogger.java @@ -57,12 +57,12 @@ public class TempFileWarningLogger { for (Path file : stream) { - if (log.isWarnEnabled()) + if (log.isDebugEnabled()) { - log.warn("Solr suggester temp file found matching file pattern: " + glob + ", path: " + file); - log.warn("Reported first suggester temp file found, others may exist."); - return true; + log.debug("Solr suggester temp file found matching file pattern: " + glob + ", path: " + file); + log.debug("Removing suggester temp files."); } + return true; } return false; } @@ -71,6 +71,21 @@ public class TempFileWarningLogger throw new RuntimeException("Unable to create directory stream", e); } } + + public void removeFiles() + { + try(DirectoryStream stream = Files.newDirectoryStream(dir, glob)) + { + for (Path file : stream) + { + file.toFile().delete(); + } + } + catch (IOException e) + { + log.debug("Unable to delete temp file", e); + } + } protected String getGlob() { diff --git a/search-services/alfresco-search/src/main/resources/solr/instance/conf/shared.properties b/search-services/alfresco-search/src/main/resources/solr/instance/conf/shared.properties index dd0b2f7fb..e78b8ee32 100644 --- a/search-services/alfresco-search/src/main/resources/solr/instance/conf/shared.properties +++ b/search-services/alfresco-search/src/main/resources/solr/instance/conf/shared.properties @@ -1,3 +1,4 @@ + # Shared Properties file #Host details an external client would use to connect to Solr @@ -12,6 +13,7 @@ alfresco.identifier.property.0={http://www.alfresco.org/model/content/1.0}creato alfresco.identifier.property.1={http://www.alfresco.org/model/content/1.0}modifier alfresco.identifier.property.2={http://www.alfresco.org/model/content/1.0}userName alfresco.identifier.property.3={http://www.alfresco.org/model/content/1.0}authorityName +alfresco.identifier.property.4={http://www.alfresco.org/model/content/1.0}lockOwner # Suggestable Propeties #alfresco.suggestable.property.0={http://www.alfresco.org/model/content/1.0}name @@ -21,6 +23,7 @@ alfresco.identifier.property.3={http://www.alfresco.org/model/content/1.0}author # Data types that support cross locale/word splitting/token patterns if tokenised alfresco.cross.locale.property.0={http://www.alfresco.org/model/content/1.0}name +alfresco.cross.locale.property.1={http://www.alfresco.org/model/content/1.0}lockOwner # Data types that support cross locale/word splitting/token patterns if tokenised # alfresco.cross.locale.datatype.0={http://www.alfresco.org/model/dictionary/1.0}text diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/CMISDataCreatorTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/CMISDataCreatorTest.java index 97af9c241..edd3e709e 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/CMISDataCreatorTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/CMISDataCreatorTest.java @@ -414,6 +414,12 @@ public class CMISDataCreatorTest extends TestCase result = session.query("select * from cmis:document where cmis:name = '"+document1.getName()+"' AND cmis:contentStreamLength = 5 AND cmis:contentStreamMimeType = 'text/plain'", false); assertEquals(1, result.getTotalNumItems()); + + result = session.query("SELECT * FROM cmis:document", false); + long docCount = result.getTotalNumItems(); + + result = session.query("SELECT * FROM cmis:document d left outer join exif:exif t on d.cmis:objectId = t.cmis:objectId", false); + assertEquals(docCount, result.getTotalNumItems()); } private Document createUniqueDocument(Folder newFolder) diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/component/TempFileWarningLoggerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/component/TempFileWarningLoggerTest.java index a97a468bd..c15f848f9 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/component/TempFileWarningLoggerTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/component/TempFileWarningLoggerTest.java @@ -21,7 +21,7 @@ package org.alfresco.solr.component; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.never; import java.io.File; import java.io.IOException; @@ -84,7 +84,7 @@ public class TempFileWarningLoggerTest assertTrue("Should have found matching files", found); // Should be a warn-level log message. - Mockito.verify(log, atLeastOnce()).warn(Mockito.anyString()); + Mockito.verify(log, never()).warn(Mockito.anyString()); } finally { @@ -114,4 +114,57 @@ public class TempFileWarningLoggerTest // Should be no warn-level log message. Mockito.verify(log, Mockito.never()).warn(Mockito.anyString()); } + + @Test + public void removeManyFiles() throws IOException + { + File f = File.createTempFile("WFSTInputIterator", ".input", path.toFile()); + File f2 = File.createTempFile("WFSTInputIterator", ".sorted", path.toFile()); + f.deleteOnExit(); + f2.deleteOnExit(); + + TempFileWarningLogger warner = new TempFileWarningLogger(log, + "WFSTInputIterator*", + new String[] { "input", "sorted" }, + path); + boolean found = warner.checkFiles(); + assertTrue("Should have found matching file", found); + assertTrue(f.exists()); + assertTrue(f2.exists()); + if(found) + { + warner.removeFiles(); + } + assertFalse(f.exists()); + assertFalse(f2.exists()); + + boolean found2 = warner.checkFiles(); + assertFalse("Should NOT have found a matching file", found2); + + } + @Test + public void notToRemoveFilesThatDontMatch() throws IOException + { + File f = File.createTempFile("someotherfile", ".input", path.toFile()); + File f2 = File.createTempFile("someotherfile", ".sorted", path.toFile()); + f.deleteOnExit(); + f2.deleteOnExit(); + + TempFileWarningLogger warner = new TempFileWarningLogger(log, + "WFSTInputIterator*", + new String[] { "input", "sorted" }, + path); + + + assertTrue(f.exists()); + assertTrue(f2.exists()); + warner.removeFiles(); + assertTrue(f.exists()); + assertTrue(f2.exists()); + + boolean found2 = warner.checkFiles(); + assertFalse("Should NOT have found a matching file", found2); + + } + } diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/cmis/AlfrescoCMISQParserPluginTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/cmis/AlfrescoCMISQParserPluginTest.java index 81981807c..b98fe72b0 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/cmis/AlfrescoCMISQParserPluginTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/cmis/AlfrescoCMISQParserPluginTest.java @@ -690,19 +690,37 @@ public class AlfrescoCMISQParserPluginTest extends LoadCMISData implements Query assertQ(qurySolr("SELECT D.*, O.* FROM cmis:document AS D JOIN cm:ownable AS O ON D.cmis:objectId = O.cmis:objectId"), expectedDocCount(1)); + + assertQ(qurySolr("SELECT D.*, O.* FROM cmis:document AS D LEFT OUTER JOIN cm:ownable AS O ON D.cmis:objectId = O.cmis:objectId"), + expectedDocCount(11)); + + assertQ(qurySolr("SELECT D.*, O.* FROM cmis:folder AS D LEFT OUTER JOIN cm:ownable AS O ON D.cmis:objectId = O.cmis:objectId"), + expectedDocCount(11)); + + assertQ(qurySolr("SELECT D.*, O.* FROM cmis:folder AS D JOIN cm:ownable AS O ON D.cmis:objectId = O.cmis:objectId"), + expectedDocCount(0)); assertQ(qurySolr("SELECT D.*, O.*, T.* FROM cmis:document AS D JOIN cm:ownable AS O ON D.cmis:objectId = O.cmis:objectId JOIN cm:titled AS T ON T.cmis:objectId = D.cmis:objectId"), expectedDocCount(1)); assertQ(qurySolr("SELECT D.*, O.* FROM cm:ownable O JOIN cmis:document D ON D.cmis:objectId = O.cmis:objectId"), expectedDocCount(1)); + + assertQ(qurySolr("SELECT D.*, O.* FROM cm:ownable O LEFT JOIN cmis:document D ON D.cmis:objectId = O.cmis:objectId"), + expectedDocCount(1)); assertQ(qurySolr("SELECT D.*, F.* FROM cmis:folder F JOIN cmis:document D ON D.cmis:objectId = F.cmis:objectId"), expectedDocCount(0)); + + assertQ(qurySolr("SELECT D.*, F.* FROM cmis:folder F LEFT JOIN cmis:document D ON D.cmis:objectId = F.cmis:objectId"), + expectedDocCount(11)); assertQ(qurySolr("SELECT O.*, T.* FROM cm:ownable O JOIN cm:titled T ON O.cmis:objectId = T.cmis:objectId"), expectedDocCount(1)); + assertQ(qurySolr("SELECT O.*, T.* FROM cm:ownable O LEFT JOIN cm:titled T ON O.cmis:objectId = T.cmis:objectId"), + expectedDocCount(1)); + assertQ(qurySolr("select o.*, t.* from cm:ownable o join cm:titled t on o.cmis:objectId = t.cmis:objectId"), expectedDocCount(1)); diff --git a/search-services/packaging/config.properties b/search-services/packaging/config.properties index d9e023d1f..73bd605de 100644 --- a/search-services/packaging/config.properties +++ b/search-services/packaging/config.properties @@ -7,6 +7,6 @@ alfresco.gc.logs.win=set "GC_LOG_OPTS= " alfresco.search.logs.win=set SOLR_LOGS_DIR=..\\..\\logs\ ${line.separator}set LOG4J_CONFIG=!SOLR_LOGS_DIR!\\log4j.properties alfresco.search.config=# Alfresco configuration. This file is automatically included by solr. You can define your custom settings here\ -${line.separator}SOLR_OPTS="$SOLR_OPTS -Dsolr.jetty.request.header.size=1000000 -Dsolr.jetty.threads.stop.timeout=300000" +${line.separator}SOLR_OPTS="$SOLR_OPTS -Dsolr.jetty.request.header.size=1000000 -Dsolr.jetty.threads.stop.timeout=300000 -Ddisable.configEdit=true" alfresco.search.config.win=REM Alfresco configuration. This file is automatically included by solr. You can define your custom settings here\ -${line.separator}set SOLR_OPTS=%SOLR_OPTS% -Dsolr.jetty.request.header.size=1000000 -Dsolr.jetty.threads.stop.timeout=300000 \ No newline at end of file +${line.separator}set SOLR_OPTS=%SOLR_OPTS% -Dsolr.jetty.request.header.size=1000000 -Dsolr.jetty.threads.stop.timeout=300000 -Ddisable.configEdit=true \ No newline at end of file diff --git a/search-services/packaging/pom.xml b/search-services/packaging/pom.xml index 46caad408..ea24e181f 100644 --- a/search-services/packaging/pom.xml +++ b/search-services/packaging/pom.xml @@ -37,7 +37,6 @@ org.codehaus.mojo properties-maven-plugin - 1.0.0 initialize @@ -55,7 +54,6 @@ org.apache.maven.plugins maven-dependency-plugin - 2.10 unpack-solr-war diff --git a/search-services/pom.xml b/search-services/pom.xml index e6fb6c176..3646f381f 100644 --- a/search-services/pom.xml +++ b/search-services/pom.xml @@ -13,6 +13,7 @@ 6.6.0 5.3-SNAPSHOT + 6.4