diff --git a/repository/src/main/java/org/alfresco/repo/virtual/ref/NodeIdHasher.java b/repository/src/main/java/org/alfresco/repo/virtual/ref/NodeIdHasher.java new file mode 100644 index 0000000000..1e039aaa10 --- /dev/null +++ b/repository/src/main/java/org/alfresco/repo/virtual/ref/NodeIdHasher.java @@ -0,0 +1,39 @@ +/* + * #%L + * Alfresco Repository + * %% + * Copyright (C) 2025 - 2025 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ + +package org.alfresco.repo.virtual.ref; + +import org.alfresco.service.cmr.repository.NodeRef; + +/** + * Creates and looks up string hash codes of id part of {@link NodeRef}s.
+ */ +interface NodeIdHasher +{ + String lookup(String idHash); + + String hash(String id); +} diff --git a/repository/src/main/java/org/alfresco/repo/virtual/ref/NodeRefHasher.java b/repository/src/main/java/org/alfresco/repo/virtual/ref/NodeRefHasher.java index 1bc5949651..3d58e72e9e 100644 --- a/repository/src/main/java/org/alfresco/repo/virtual/ref/NodeRefHasher.java +++ b/repository/src/main/java/org/alfresco/repo/virtual/ref/NodeRefHasher.java @@ -32,7 +32,7 @@ import org.alfresco.util.Pair; /** * Creates and looks up string-pair hash codes of {@link NodeRef}s.
*/ -public interface NodeRefHasher +interface NodeRefHasher { NodeRef lookup(Pair hash); diff --git a/repository/src/main/java/org/alfresco/repo/virtual/ref/NodeRefRadixHasher.java b/repository/src/main/java/org/alfresco/repo/virtual/ref/NodeRefRadixHasher.java index 3c8324f1ff..929ff5d311 100644 --- a/repository/src/main/java/org/alfresco/repo/virtual/ref/NodeRefRadixHasher.java +++ b/repository/src/main/java/org/alfresco/repo/virtual/ref/NodeRefRadixHasher.java @@ -2,23 +2,23 @@ * #%L * Alfresco Repository * %% - * Copyright (C) 2005 - 2016 Alfresco Software Limited + * Copyright (C) 2005 - 2025 Alfresco Software Limited * %% - * This file is part of the Alfresco software. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is * provided under the following open source license terms: - * + * * Alfresco is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * Alfresco is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see . * #L% @@ -26,27 +26,25 @@ package org.alfresco.repo.virtual.ref; -import java.math.BigInteger; +import java.util.regex.Pattern; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.util.Pair; -import org.apache.commons.lang3.StringUtils; /** - * Creates string-pair hashes of {@link NodeRef}s where the first string is a - * stored hash combination for {@link NodeRef} store elements (protocol and id) - * and the second is a radix 36 encoded {@link NodeRef} id. + * Creates string-pair hashes of {@link NodeRef}s where the first string is a stored hash combination for {@link NodeRef} store elements (protocol and id) and the second is a radix 36 encoded {@link NodeRef} id. */ -public class NodeRefRadixHasher implements NodeRefHasher +class NodeRefRadixHasher implements NodeRefHasher { public static final NodeRefRadixHasher RADIX_36_HASHER = new NodeRefRadixHasher(36); - private HashStore storeProtocolStore; + static final Pattern UUID_PATTERN = Pattern.compile("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"); + static final String NOT_UUID_FORMAT_MARKER = "X"; - private HashStore storeIdStore; - - private int radix; + private final StoreRefHasher storeRefHasher; + private final NodeIdHasher uuidNodeIdHasher; + private final NodeIdHasher notUuidNodeIdHasher; public NodeRefRadixHasher() { @@ -56,87 +54,51 @@ public class NodeRefRadixHasher implements NodeRefHasher public NodeRefRadixHasher(int radix) { super(); - this.radix = radix; - this.storeProtocolStore = HashStoreConfiguration.getInstance().getStoreProtocolStore(); - this.storeIdStore = HashStoreConfiguration.getInstance().getStoreIdStore(); + this.storeRefHasher = new StoredStoreRefHasher(); + this.uuidNodeIdHasher = new UuidNodeIdRadixHasher(radix); + this.notUuidNodeIdHasher = new NotUuidNodeIdRadixHasher(radix); } @Override public Pair hash(NodeRef nodeRef) { - String uuid = nodeRef.getId(); - - if (uuid.length() != 36) - { - throw new RuntimeException("Invalid noderf id length " + uuid); - } - - String bigInt16String = uuid.replaceAll("-", - ""); - if (bigInt16String.length() != 32) - { - throw new RuntimeException("Invalid noderf id format " + uuid); - } - - BigInteger bigIntId = new BigInteger(bigInt16String, - 16); StoreRef storeRef = nodeRef.getStoreRef(); - String storeProtocolHash = storeProtocolStore.hash(storeRef.getProtocol()); - String storeIdHash = storeIdStore.hash(storeRef.getIdentifier()); - if (storeProtocolHash == null || storeIdHash == null) - { - throw new RuntimeException("Missing hash for " + storeRef); - } - String storeHash = storeProtocolHash + storeIdHash; - return new Pair(storeHash, - bigIntId.toString(radix)); + String storeHash = storeRefHasher.hash(storeRef); + String id = nodeRef.getId(); + String idHash = idToIdHash(id); + + return new Pair<>(storeHash, idHash); + } + + private String idToIdHash(String id) + { + if (UUID_PATTERN.matcher(id).matches()) + { + return uuidNodeIdHasher.hash(id); + } + return NOT_UUID_FORMAT_MARKER + notUuidNodeIdHasher.hash(id); } @Override public NodeRef lookup(Pair hash) { String storeHash = hash.getFirst(); - String storeProtocolHash = storeHash.substring(0, - 1); - String storeIdHash = storeHash.substring(1, - 2); + StoreRef storeRef = storeRefHasher.lookup(storeHash); - String storeProtocol = storeProtocolStore.lookup(storeProtocolHash); - String storeId = storeIdStore.lookup(storeIdHash); - if (storeProtocol == null || storeId == null) + String hashId = hash.getSecond(); + String id = hashIdToId(hashId); + + return new NodeRef(storeRef, id); + } + + private String hashIdToId(String hashId) + { + if (hashId.startsWith(NOT_UUID_FORMAT_MARKER)) { - throw new RuntimeException("Lookup found no protocol or id for " + storeHash); + String hashIdWithoutMarker = hashId.substring(NOT_UUID_FORMAT_MARKER.length()); + return notUuidNodeIdHasher.lookup(hashIdWithoutMarker); } - BigInteger nodeId = new BigInteger(hash.getSecond(), - radix); - String nodeIdHexa = nodeId.toString(16); - nodeIdHexa = StringUtils.leftPad(nodeIdHexa, - 32, - "0"); - int leadZeros = 32 - nodeIdHexa.length(); - if (leadZeros > 0) - { - } - String groups[] = new String[5]; - groups[0] = nodeIdHexa.substring(0, - 8); - groups[1] = nodeIdHexa.substring(8, - 12); - groups[2] = nodeIdHexa.substring(12, - 16); - groups[3] = nodeIdHexa.substring(16, - 20); - groups[4] = nodeIdHexa.substring(20, - 32); - StringBuilder idBuilder = new StringBuilder(groups[0]); - for (int i = 1; i < groups.length; i++) - { - idBuilder.append("-"); - idBuilder.append(groups[i]); - } - return new NodeRef(storeProtocol, - storeId, - idBuilder.toString()); + return uuidNodeIdHasher.lookup(hashId); } } diff --git a/repository/src/main/java/org/alfresco/repo/virtual/ref/NotUuidNodeIdRadixHasher.java b/repository/src/main/java/org/alfresco/repo/virtual/ref/NotUuidNodeIdRadixHasher.java new file mode 100644 index 0000000000..d6381ab814 --- /dev/null +++ b/repository/src/main/java/org/alfresco/repo/virtual/ref/NotUuidNodeIdRadixHasher.java @@ -0,0 +1,57 @@ +/* + * #%L + * Alfresco Repository + * %% + * Copyright (C) 2025 - 2025 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ + +package org.alfresco.repo.virtual.ref; + +import static java.nio.charset.StandardCharsets.UTF_8; + +import java.math.BigInteger; + +class NotUuidNodeIdRadixHasher implements NodeIdHasher +{ + private final int radix; + + public NotUuidNodeIdRadixHasher(int radix) + { + this.radix = radix; + } + + @Override + public String lookup(String hashId) + { + BigInteger hashIdBigInt = new BigInteger(hashId, radix); + byte[] hashIdBytes = hashIdBigInt.toByteArray(); + return new String(hashIdBytes); + } + + @Override + public String hash(String id) + { + byte[] bytes = id.getBytes(UTF_8); + BigInteger bigIntegerBytes = new BigInteger(bytes); + return bigIntegerBytes.toString(radix); + } +} diff --git a/repository/src/main/java/org/alfresco/repo/virtual/ref/StoreRefHasher.java b/repository/src/main/java/org/alfresco/repo/virtual/ref/StoreRefHasher.java new file mode 100644 index 0000000000..d670e022ee --- /dev/null +++ b/repository/src/main/java/org/alfresco/repo/virtual/ref/StoreRefHasher.java @@ -0,0 +1,40 @@ +/* + * #%L + * Alfresco Repository + * %% + * Copyright (C) 2025 - 2025 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ + +package org.alfresco.repo.virtual.ref; + +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.StoreRef; + +/** + * Creates and looks up string hash codes of {@link StoreRef} part of {@link NodeRef}s.
+ */ +interface StoreRefHasher +{ + StoreRef lookup(String storeHash); + + String hash(StoreRef storeRef); +} diff --git a/repository/src/main/java/org/alfresco/repo/virtual/ref/StoredStoreRefHasher.java b/repository/src/main/java/org/alfresco/repo/virtual/ref/StoredStoreRefHasher.java new file mode 100644 index 0000000000..7180c874e6 --- /dev/null +++ b/repository/src/main/java/org/alfresco/repo/virtual/ref/StoredStoreRefHasher.java @@ -0,0 +1,68 @@ +/* + * #%L + * Alfresco Repository + * %% + * Copyright (C) 2025 - 2025 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ + +package org.alfresco.repo.virtual.ref; + +import org.alfresco.service.cmr.repository.StoreRef; + +class StoredStoreRefHasher implements StoreRefHasher +{ + private final HashStore storeProtocolStore; + private final HashStore storeIdStore; + + public StoredStoreRefHasher() + { + this.storeProtocolStore = HashStoreConfiguration.getInstance().getStoreProtocolStore(); + this.storeIdStore = HashStoreConfiguration.getInstance().getStoreIdStore(); + } + + @Override + public StoreRef lookup(String storeHash) + { + String storeProtocolHash = storeHash.substring(0, 1); + String storeIdHash = storeHash.substring(1, 2); + + String storeProtocol = storeProtocolStore.lookup(storeProtocolHash); + String storeId = storeIdStore.lookup(storeIdHash); + if (storeProtocol == null || storeId == null) + { + throw new RuntimeException("Lookup found no protocol or id for " + storeHash); + } + return new StoreRef(storeProtocol, storeId); + } + + @Override + public String hash(StoreRef storeRef) + { + String storeProtocolHash = storeProtocolStore.hash(storeRef.getProtocol()); + String storeIdHash = storeIdStore.hash(storeRef.getIdentifier()); + if (storeProtocolHash == null || storeIdHash == null) + { + throw new RuntimeException("Missing hash for " + storeRef); + } + return storeProtocolHash + storeIdHash; + } +} diff --git a/repository/src/main/java/org/alfresco/repo/virtual/ref/UuidNodeIdRadixHasher.java b/repository/src/main/java/org/alfresco/repo/virtual/ref/UuidNodeIdRadixHasher.java new file mode 100644 index 0000000000..1cfc95a773 --- /dev/null +++ b/repository/src/main/java/org/alfresco/repo/virtual/ref/UuidNodeIdRadixHasher.java @@ -0,0 +1,63 @@ +/* + * #%L + * Alfresco Repository + * %% + * Copyright (C) 2025 - 2025 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ + +package org.alfresco.repo.virtual.ref; + +import java.math.BigInteger; + +import org.apache.commons.lang3.StringUtils; + +class UuidNodeIdRadixHasher implements NodeIdHasher +{ + private final int radix; + + public UuidNodeIdRadixHasher(int radix) + { + this.radix = radix; + } + + @Override + public String lookup(String hashUuid) + { + BigInteger nodeId = new BigInteger(hashUuid, radix); + String nodeIdHex = nodeId.toString(16); + String paddedNodeIdHex = StringUtils.leftPad(nodeIdHex, 32, "0"); + return String.join("-", + paddedNodeIdHex.substring(0, 8), + paddedNodeIdHex.substring(8, 12), + paddedNodeIdHex.substring(12, 16), + paddedNodeIdHex.substring(16, 20), + paddedNodeIdHex.substring(20, 32)); + } + + @Override + public String hash(String uuid) + { + String uuidWithoutDashes = uuid.replaceAll("-", ""); + BigInteger bigIntUuidWithoutDashesHex = new BigInteger(uuidWithoutDashes, 16); + return bigIntUuidWithoutDashesHex.toString(radix); + } +} diff --git a/repository/src/test/java/org/alfresco/AllUnitTestsSuite.java b/repository/src/test/java/org/alfresco/AllUnitTestsSuite.java index cd6d76158e..aff459d446 100644 --- a/repository/src/test/java/org/alfresco/AllUnitTestsSuite.java +++ b/repository/src/test/java/org/alfresco/AllUnitTestsSuite.java @@ -4,27 +4,31 @@ * %% * Copyright (C) 2005 - 2025 Alfresco Software Limited * %% - * This file is part of the Alfresco software. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is * provided under the following open source license terms: - * + * * Alfresco is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * Alfresco is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see . * #L% */ package org.alfresco; +import org.junit.experimental.categories.Categories; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + import org.alfresco.repo.security.authentication.identityservice.ClientRegistrationProviderUnitTest; import org.alfresco.repo.security.authentication.identityservice.IdentityServiceFacadeFactoryBeanTest; import org.alfresco.repo.security.authentication.identityservice.IdentityServiceJITProvisioningHandlerUnitTest; @@ -35,235 +39,233 @@ import org.alfresco.repo.security.authentication.identityservice.admin.AdminCons import org.alfresco.repo.security.authentication.identityservice.admin.IdentityServiceAdminConsoleAuthenticatorUnitTest; import org.alfresco.util.testing.category.DBTests; import org.alfresco.util.testing.category.NonBuildTests; -import org.junit.experimental.categories.Categories; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; /** - * All Repository project UNIT test classes (no application context) should be added to this test suite. - * Tests marked as DBTests are automatically excluded and are run as part of {@link AllDBTestsTestSuite}. + * All Repository project UNIT test classes (no application context) should be added to this test suite. Tests marked as DBTests are automatically excluded and are run as part of {@link AllDBTestsTestSuite}. */ @RunWith(Categories.class) @Categories.ExcludeCategory({DBTests.class, NonBuildTests.class}) -@Suite.SuiteClasses({ - org.alfresco.repo.site.SiteMembershipTest.class, - org.alfresco.encryption.EncryptorTest.class, - org.alfresco.encryption.KeyStoreKeyProviderTest.class, - org.alfresco.filesys.config.ServerConfigurationBeanTest.class, - org.alfresco.filesys.repo.rules.ShuffleTest.class, - org.alfresco.opencmis.AlfrescoCmisExceptionInterceptorTest.class, - org.alfresco.repo.admin.Log4JHierarchyInitTest.class, - org.alfresco.repo.attributes.PropTablesCleanupJobTest.class, - org.alfresco.repo.cache.AbstractCacheFactoryTest.class, - org.alfresco.repo.cache.DefaultCacheFactoryTest.class, - org.alfresco.repo.cache.DefaultSimpleCacheTest.class, - org.alfresco.repo.cache.InMemoryCacheStatisticsTest.class, - org.alfresco.repo.cache.TransactionStatsTest.class, - org.alfresco.repo.cache.lookup.EntityLookupCacheTest.class, - org.alfresco.repo.calendar.CalendarHelpersTest.class, - org.alfresco.repo.copy.CopyServiceImplUnitTest.class, - org.alfresco.repo.dictionary.RepoDictionaryDAOTest.class, - org.alfresco.repo.forms.processor.node.FieldProcessorTest.class, - org.alfresco.repo.forms.processor.workflow.TaskFormProcessorTest.class, - org.alfresco.repo.forms.processor.workflow.WorkflowFormProcessorTest.class, - org.alfresco.repo.invitation.site.InviteSenderTest.class, - org.alfresco.repo.invitation.site.InviteModeratedSenderTest.class, - org.alfresco.repo.jscript.ScriptSearchTest.class, - org.alfresco.repo.lock.LockUtilsTest.class, - org.alfresco.repo.lock.mem.LockStoreImplTest.class, - org.alfresco.repo.management.CheckRequiredClassesForLoggingConsoleUnitTest.class, - org.alfresco.repo.management.subsystems.CryptodocSwitchableApplicationContextFactoryTest.class, - org.alfresco.repo.module.ModuleDetailsImplTest.class, - org.alfresco.repo.module.ModuleVersionNumberTest.class, - org.alfresco.repo.module.DeprecatedModulesValidatorTest.class, - org.alfresco.repo.node.integrity.IntegrityEventTest.class, - org.alfresco.repo.policy.MTPolicyComponentTest.class, - org.alfresco.repo.policy.PolicyComponentTest.class, - org.alfresco.repo.rendition.RenditionNodeManagerTest.class, - org.alfresco.repo.rendition.RenditionServiceImplTest.class, - org.alfresco.repo.replication.ReplicationServiceImplTest.class, - org.alfresco.repo.rule.RuleServiceImplUnitTest.class, - org.alfresco.repo.service.StoreRedirectorProxyFactoryTest.class, - org.alfresco.repo.site.RoleComparatorImplTest.class, - org.alfresco.repo.template.UnsafeMethodsTest.class, - org.alfresco.repo.tenant.MultiTAdminServiceImplTest.class, - org.alfresco.repo.thumbnail.ThumbnailServiceImplParameterTest.class, - org.alfresco.repo.transfer.ContentChunkerImplTest.class, - org.alfresco.repo.transfer.HttpClientTransmitterImplTest.class, - org.alfresco.repo.transfer.manifest.TransferManifestTest.class, - org.alfresco.repo.transfer.TransferVersionCheckerImplTest.class, - org.alfresco.service.cmr.calendar.CalendarRecurrenceHelperTest.class, - org.alfresco.service.cmr.calendar.CalendarTimezoneHelperTest.class, - org.alfresco.tools.RenameUserTest.class, - org.alfresco.util.VersionNumberTest.class, - org.alfresco.util.FileNameValidatorTest.class, - org.alfresco.util.HttpClientHelperTest.class, - org.alfresco.util.JSONtoFmModelTest.class, - org.alfresco.util.ModelUtilTest.class, - org.alfresco.util.PropertyMapTest.class, - org.alfresco.util.ValueProtectingMapTest.class, - org.alfresco.util.json.ExceptionJsonSerializerTest.class, - org.alfresco.util.collections.CollectionUtilsTest.class, - org.alfresco.util.schemacomp.DbObjectXMLTransformerTest.class, - org.alfresco.util.schemacomp.DbPropertyTest.class, - org.alfresco.util.schemacomp.DefaultComparisonUtilsTest.class, - org.alfresco.util.schemacomp.DifferenceTest.class, - org.alfresco.util.schemacomp.MultiFileDumperTest.class, - org.alfresco.util.schemacomp.RedundantDbObjectTest.class, - org.alfresco.util.schemacomp.SchemaComparatorTest.class, - org.alfresco.util.schemacomp.SchemaToXMLTest.class, - org.alfresco.util.schemacomp.ValidatingVisitorTest.class, - org.alfresco.util.schemacomp.ValidationResultTest.class, - org.alfresco.util.schemacomp.XMLToSchemaTest.class, - org.alfresco.util.schemacomp.model.ColumnTest.class, - org.alfresco.util.schemacomp.model.ForeignKeyTest.class, - org.alfresco.util.schemacomp.model.IndexTest.class, - org.alfresco.util.schemacomp.model.PrimaryKeyTest.class, - org.alfresco.util.schemacomp.model.SchemaTest.class, - org.alfresco.util.schemacomp.model.SequenceTest.class, - org.alfresco.util.schemacomp.model.TableTest.class, - org.alfresco.util.schemacomp.validator.IndexColumnsValidatorTest.class, - org.alfresco.util.schemacomp.validator.NameValidatorTest.class, - org.alfresco.util.schemacomp.validator.SchemaVersionValidatorTest.class, - org.alfresco.util.schemacomp.validator.TypeNameOnlyValidatorTest.class, - org.alfresco.util.test.OmittedTestClassFinderUnitTest.class, - org.alfresco.util.test.junitrules.RetryAtMostRuleTest.class, - org.alfresco.util.test.junitrules.TemporaryMockOverrideTest.class, - org.alfresco.repo.search.impl.solr.AbstractSolrQueryHTTPClientTest.class, - org.alfresco.repo.search.impl.solr.SpellCheckDecisionManagerTest.class, - org.alfresco.repo.search.impl.solr.SolrStoreMappingWrapperTest.class, - org.alfresco.repo.search.impl.querymodel.impl.db.DBQueryEngineTest.class, - org.alfresco.repo.search.impl.querymodel.impl.db.NodePermissionAssessorLimitsTest.class, - org.alfresco.repo.search.impl.querymodel.impl.db.NodePermissionAssessorPermissionsTest.class, - org.alfresco.repo.search.impl.solr.DbOrIndexSwitchingQueryLanguageTest.class, - org.alfresco.repo.search.impl.solr.SolrQueryHTTPClientTest.class, - org.alfresco.repo.search.impl.solr.SolrSQLHttpClientTest.class, - org.alfresco.repo.search.impl.solr.SolrStatsResultTest.class, - org.alfresco.repo.search.impl.solr.SolrJSONResultTest.class, - org.alfresco.repo.search.impl.solr.SolrSQLJSONResultMetadataSetTest.class, - org.alfresco.repo.search.impl.solr.facet.SolrFacetComparatorTest.class, - org.alfresco.repo.search.impl.solr.facet.FacetQNameUtilsTest.class, - org.alfresco.util.BeanExtenderUnitTest.class, - org.alfresco.repo.solr.SOLRTrackingComponentUnitTest.class, - IdentityServiceFacadeFactoryBeanTest.class, - LazyInstantiatingIdentityServiceFacadeUnitTest.class, - SpringBasedIdentityServiceFacadeUnitTest.class, - IdentityServiceJITProvisioningHandlerUnitTest.class, - AdminConsoleAuthenticationCookiesServiceUnitTest.class, - AdminConsoleHttpServletRequestWrapperUnitTest.class, - IdentityServiceAdminConsoleAuthenticatorUnitTest.class, - ClientRegistrationProviderUnitTest.class, - org.alfresco.repo.security.authentication.CompositePasswordEncoderTest.class, - org.alfresco.repo.security.authentication.PasswordHashingTest.class, - org.alfresco.repo.security.authority.script.ScriptAuthorityService_RegExTest.class, - org.alfresco.repo.security.permissions.PermissionCheckCollectionTest.class, - org.alfresco.repo.security.sync.LDAPUserRegistryTest.class, - org.alfresco.traitextender.TraitExtenderIntegrationTest.class, - org.alfresco.traitextender.AJExtensionsCompileTest.class, +@Suite.SuiteClasses(value = { + org.alfresco.repo.site.SiteMembershipTest.class, + org.alfresco.encryption.EncryptorTest.class, + org.alfresco.encryption.KeyStoreKeyProviderTest.class, + org.alfresco.filesys.config.ServerConfigurationBeanTest.class, + org.alfresco.filesys.repo.rules.ShuffleTest.class, + org.alfresco.opencmis.AlfrescoCmisExceptionInterceptorTest.class, + org.alfresco.repo.admin.Log4JHierarchyInitTest.class, + org.alfresco.repo.attributes.PropTablesCleanupJobTest.class, + org.alfresco.repo.cache.AbstractCacheFactoryTest.class, + org.alfresco.repo.cache.DefaultCacheFactoryTest.class, + org.alfresco.repo.cache.DefaultSimpleCacheTest.class, + org.alfresco.repo.cache.InMemoryCacheStatisticsTest.class, + org.alfresco.repo.cache.TransactionStatsTest.class, + org.alfresco.repo.cache.lookup.EntityLookupCacheTest.class, + org.alfresco.repo.calendar.CalendarHelpersTest.class, + org.alfresco.repo.copy.CopyServiceImplUnitTest.class, + org.alfresco.repo.dictionary.RepoDictionaryDAOTest.class, + org.alfresco.repo.forms.processor.node.FieldProcessorTest.class, + org.alfresco.repo.forms.processor.workflow.TaskFormProcessorTest.class, + org.alfresco.repo.forms.processor.workflow.WorkflowFormProcessorTest.class, + org.alfresco.repo.invitation.site.InviteSenderTest.class, + org.alfresco.repo.invitation.site.InviteModeratedSenderTest.class, + org.alfresco.repo.jscript.ScriptSearchTest.class, + org.alfresco.repo.lock.LockUtilsTest.class, + org.alfresco.repo.lock.mem.LockStoreImplTest.class, + org.alfresco.repo.management.CheckRequiredClassesForLoggingConsoleUnitTest.class, + org.alfresco.repo.management.subsystems.CryptodocSwitchableApplicationContextFactoryTest.class, + org.alfresco.repo.module.ModuleDetailsImplTest.class, + org.alfresco.repo.module.ModuleVersionNumberTest.class, + org.alfresco.repo.module.DeprecatedModulesValidatorTest.class, + org.alfresco.repo.node.integrity.IntegrityEventTest.class, + org.alfresco.repo.policy.MTPolicyComponentTest.class, + org.alfresco.repo.policy.PolicyComponentTest.class, + org.alfresco.repo.rendition.RenditionNodeManagerTest.class, + org.alfresco.repo.rendition.RenditionServiceImplTest.class, + org.alfresco.repo.replication.ReplicationServiceImplTest.class, + org.alfresco.repo.rule.RuleServiceImplUnitTest.class, + org.alfresco.repo.service.StoreRedirectorProxyFactoryTest.class, + org.alfresco.repo.site.RoleComparatorImplTest.class, + org.alfresco.repo.template.UnsafeMethodsTest.class, + org.alfresco.repo.tenant.MultiTAdminServiceImplTest.class, + org.alfresco.repo.thumbnail.ThumbnailServiceImplParameterTest.class, + org.alfresco.repo.transfer.ContentChunkerImplTest.class, + org.alfresco.repo.transfer.HttpClientTransmitterImplTest.class, + org.alfresco.repo.transfer.manifest.TransferManifestTest.class, + org.alfresco.repo.transfer.TransferVersionCheckerImplTest.class, + org.alfresco.service.cmr.calendar.CalendarRecurrenceHelperTest.class, + org.alfresco.service.cmr.calendar.CalendarTimezoneHelperTest.class, + org.alfresco.tools.RenameUserTest.class, + org.alfresco.util.VersionNumberTest.class, + org.alfresco.util.FileNameValidatorTest.class, + org.alfresco.util.HttpClientHelperTest.class, + org.alfresco.util.JSONtoFmModelTest.class, + org.alfresco.util.ModelUtilTest.class, + org.alfresco.util.PropertyMapTest.class, + org.alfresco.util.ValueProtectingMapTest.class, + org.alfresco.util.json.ExceptionJsonSerializerTest.class, + org.alfresco.util.collections.CollectionUtilsTest.class, + org.alfresco.util.schemacomp.DbObjectXMLTransformerTest.class, + org.alfresco.util.schemacomp.DbPropertyTest.class, + org.alfresco.util.schemacomp.DefaultComparisonUtilsTest.class, + org.alfresco.util.schemacomp.DifferenceTest.class, + org.alfresco.util.schemacomp.MultiFileDumperTest.class, + org.alfresco.util.schemacomp.RedundantDbObjectTest.class, + org.alfresco.util.schemacomp.SchemaComparatorTest.class, + org.alfresco.util.schemacomp.SchemaToXMLTest.class, + org.alfresco.util.schemacomp.ValidatingVisitorTest.class, + org.alfresco.util.schemacomp.ValidationResultTest.class, + org.alfresco.util.schemacomp.XMLToSchemaTest.class, + org.alfresco.util.schemacomp.model.ColumnTest.class, + org.alfresco.util.schemacomp.model.ForeignKeyTest.class, + org.alfresco.util.schemacomp.model.IndexTest.class, + org.alfresco.util.schemacomp.model.PrimaryKeyTest.class, + org.alfresco.util.schemacomp.model.SchemaTest.class, + org.alfresco.util.schemacomp.model.SequenceTest.class, + org.alfresco.util.schemacomp.model.TableTest.class, + org.alfresco.util.schemacomp.validator.IndexColumnsValidatorTest.class, + org.alfresco.util.schemacomp.validator.NameValidatorTest.class, + org.alfresco.util.schemacomp.validator.SchemaVersionValidatorTest.class, + org.alfresco.util.schemacomp.validator.TypeNameOnlyValidatorTest.class, + org.alfresco.util.test.OmittedTestClassFinderUnitTest.class, + org.alfresco.util.test.junitrules.RetryAtMostRuleTest.class, + org.alfresco.util.test.junitrules.TemporaryMockOverrideTest.class, + org.alfresco.repo.search.impl.solr.AbstractSolrQueryHTTPClientTest.class, + org.alfresco.repo.search.impl.solr.SpellCheckDecisionManagerTest.class, + org.alfresco.repo.search.impl.solr.SolrStoreMappingWrapperTest.class, + org.alfresco.repo.search.impl.querymodel.impl.db.DBQueryEngineTest.class, + org.alfresco.repo.search.impl.querymodel.impl.db.NodePermissionAssessorLimitsTest.class, + org.alfresco.repo.search.impl.querymodel.impl.db.NodePermissionAssessorPermissionsTest.class, + org.alfresco.repo.search.impl.solr.DbOrIndexSwitchingQueryLanguageTest.class, + org.alfresco.repo.search.impl.solr.SolrQueryHTTPClientTest.class, + org.alfresco.repo.search.impl.solr.SolrSQLHttpClientTest.class, + org.alfresco.repo.search.impl.solr.SolrStatsResultTest.class, + org.alfresco.repo.search.impl.solr.SolrJSONResultTest.class, + org.alfresco.repo.search.impl.solr.SolrSQLJSONResultMetadataSetTest.class, + org.alfresco.repo.search.impl.solr.facet.SolrFacetComparatorTest.class, + org.alfresco.repo.search.impl.solr.facet.FacetQNameUtilsTest.class, + org.alfresco.util.BeanExtenderUnitTest.class, + org.alfresco.repo.solr.SOLRTrackingComponentUnitTest.class, + IdentityServiceFacadeFactoryBeanTest.class, + LazyInstantiatingIdentityServiceFacadeUnitTest.class, + SpringBasedIdentityServiceFacadeUnitTest.class, + IdentityServiceJITProvisioningHandlerUnitTest.class, + AdminConsoleAuthenticationCookiesServiceUnitTest.class, + AdminConsoleHttpServletRequestWrapperUnitTest.class, + IdentityServiceAdminConsoleAuthenticatorUnitTest.class, + ClientRegistrationProviderUnitTest.class, + org.alfresco.repo.security.authentication.CompositePasswordEncoderTest.class, + org.alfresco.repo.security.authentication.PasswordHashingTest.class, + org.alfresco.repo.security.authority.script.ScriptAuthorityService_RegExTest.class, + org.alfresco.repo.security.permissions.PermissionCheckCollectionTest.class, + org.alfresco.repo.security.sync.LDAPUserRegistryTest.class, + org.alfresco.traitextender.TraitExtenderIntegrationTest.class, + org.alfresco.traitextender.AJExtensionsCompileTest.class, - org.alfresco.repo.virtual.page.PageCollatorTest.class, - org.alfresco.repo.virtual.ref.GetChildByIdMethodTest.class, - org.alfresco.repo.virtual.ref.GetParentReferenceMethodTest.class, - org.alfresco.repo.virtual.ref.NewVirtualReferenceMethodTest.class, - org.alfresco.repo.virtual.ref.PlainReferenceParserTest.class, - org.alfresco.repo.virtual.ref.PlainStringifierTest.class, - org.alfresco.repo.virtual.ref.ProtocolTest.class, - org.alfresco.repo.virtual.ref.ReferenceTest.class, - org.alfresco.repo.virtual.ref.ResourceParameterTest.class, - org.alfresco.repo.virtual.ref.StringParameterTest.class, - org.alfresco.repo.virtual.ref.VirtualProtocolTest.class, - org.alfresco.repo.virtual.store.ReferenceComparatorTest.class, + org.alfresco.repo.virtual.page.PageCollatorTest.class, + org.alfresco.repo.virtual.ref.GetChildByIdMethodTest.class, + org.alfresco.repo.virtual.ref.GetParentReferenceMethodTest.class, + org.alfresco.repo.virtual.ref.NewVirtualReferenceMethodTest.class, + org.alfresco.repo.virtual.ref.PlainReferenceParserTest.class, + org.alfresco.repo.virtual.ref.PlainStringifierTest.class, + org.alfresco.repo.virtual.ref.ProtocolTest.class, + org.alfresco.repo.virtual.ref.ReferenceTest.class, + org.alfresco.repo.virtual.ref.ResourceParameterTest.class, + org.alfresco.repo.virtual.ref.StringParameterTest.class, + org.alfresco.repo.virtual.ref.VirtualProtocolTest.class, + org.alfresco.repo.virtual.store.ReferenceComparatorTest.class, - org.alfresco.repo.virtual.ref.ZeroReferenceParserTest.class, - org.alfresco.repo.virtual.ref.ZeroStringifierTest.class, + org.alfresco.repo.virtual.ref.ZeroReferenceParserTest.class, + org.alfresco.repo.virtual.ref.ZeroStringifierTest.class, - org.alfresco.repo.virtual.ref.HashStringifierTest.class, - org.alfresco.repo.virtual.ref.NodeRefRadixHasherTest.class, - org.alfresco.repo.virtual.ref.NumericPathHasherTest.class, - org.alfresco.repo.virtual.ref.StoredPathHasherTest.class, + org.alfresco.repo.virtual.ref.HashStringifierTest.class, + org.alfresco.repo.virtual.ref.NodeRefRadixHasherTest.class, + org.alfresco.repo.virtual.ref.StoredStoreRefHasherTest.class, + org.alfresco.repo.virtual.ref.UuidNodeIdRadixHasherTest.class, + org.alfresco.repo.virtual.ref.NotUuidNodeIdRadixHasherTest.class, + org.alfresco.repo.virtual.ref.NumericPathHasherTest.class, + org.alfresco.repo.virtual.ref.StoredPathHasherTest.class, - org.alfresco.repo.virtual.template.VirtualQueryImplTest.class, - org.alfresco.repo.virtual.store.TypeVirtualizationMethodUnitTest.class, + org.alfresco.repo.virtual.template.VirtualQueryImplTest.class, + org.alfresco.repo.virtual.store.TypeVirtualizationMethodUnitTest.class, - org.alfresco.repo.security.authentication.AuthenticationServiceImplTest.class, - org.alfresco.util.EmailHelperTest.class, - org.alfresco.repo.action.ParameterDefinitionImplTest.class, - org.alfresco.repo.action.ActionDefinitionImplTest.class, - org.alfresco.repo.action.ActionConditionDefinitionImplTest.class, - org.alfresco.repo.action.ActionImplTest.class, - org.alfresco.repo.action.ActionConditionImplTest.class, - org.alfresco.repo.action.CompositeActionImplTest.class, - org.alfresco.repo.action.CompositeActionConditionImplTest.class, - org.alfresco.repo.action.executer.TransformActionExecuterTest.class, - org.alfresco.repo.action.executer.ImporterActionExecutorUnitTest.class, - org.alfresco.repo.audit.AuditableAnnotationTest.class, - org.alfresco.repo.audit.PropertyAuditFilterTest.class, - org.alfresco.repo.audit.access.NodeChangeTest.class, - org.alfresco.repo.content.ContentServiceImplUnitTest.class, - org.alfresco.repo.content.directurl.SystemWideDirectUrlConfigUnitTest.class, - org.alfresco.repo.content.directurl.ContentStoreDirectUrlConfigUnitTest.class, - org.alfresco.repo.content.LimitedStreamCopierTest.class, - org.alfresco.repo.content.filestore.FileIOTest.class, - org.alfresco.repo.content.filestore.SpoofedTextContentReaderTest.class, - org.alfresco.repo.content.ContentDataTest.class, - org.alfresco.repo.content.replication.AggregatingContentStoreUnitTest.class, - org.alfresco.service.cmr.repository.TransformationOptionLimitsTest.class, - org.alfresco.service.cmr.repository.TransformationOptionPairTest.class, - org.alfresco.repo.content.transform.TransformerConfigTestSuite.class, - org.alfresco.repo.content.transform.TransformerDebugTest.class, - org.alfresco.service.cmr.repository.TemporalSourceOptionsTest.class, - org.alfresco.repo.content.metadata.MetadataExtracterLimitsTest.class, - org.alfresco.repo.content.caching.quota.StandardQuotaStrategyMockTest.class, - org.alfresco.repo.content.caching.quota.UnlimitedQuotaStrategyTest.class, - org.alfresco.repo.content.caching.CachingContentStoreTest.class, - org.alfresco.repo.content.caching.ContentCacheImplTest.class, - org.alfresco.repo.domain.permissions.FixedAclUpdaterUnitTest.class, - org.alfresco.repo.domain.propval.PropertyTypeConverterTest.class, - org.alfresco.repo.domain.schema.script.ScriptBundleExecutorImplTest.class, - org.alfresco.repo.search.MLAnaysisModeExpansionTest.class, - org.alfresco.repo.search.DocumentNavigatorTest.class, - org.alfresco.util.NumericEncodingTest.class, - org.alfresco.repo.search.impl.parsers.CMIS_FTSTest.class, - org.alfresco.repo.search.impl.parsers.CMISTest.class, - org.alfresco.repo.search.impl.parsers.FTSTest.class, - org.alfresco.repo.security.authentication.AlfrescoSSLSocketFactoryTest.class, - org.alfresco.repo.security.authentication.AuthorizationTest.class, - org.alfresco.repo.security.permissions.PermissionCheckedCollectionTest.class, - org.alfresco.repo.security.permissions.impl.acegi.FilteringResultSetTest.class, - org.alfresco.repo.security.permissions.impl.acegi.ACLEntryVoterUtilsTest.class, - org.alfresco.repo.security.authentication.ChainingAuthenticationServiceTest.class, - org.alfresco.repo.security.authentication.NameBasedUserNameGeneratorTest.class, - org.alfresco.repo.version.common.VersionImplTest.class, - org.alfresco.repo.version.common.VersionHistoryImplTest.class, - org.alfresco.repo.version.common.versionlabel.SerialVersionLabelPolicyTest.class, - org.alfresco.repo.workflow.activiti.WorklfowObjectFactoryTest.class, - org.alfresco.repo.workflow.activiti.properties.ActivitiPriorityPropertyHandlerTest.class, - org.alfresco.repo.workflow.WorkflowSuiteContextShutdownTest.class, - org.alfresco.repo.search.LuceneUtilsTest.class, + org.alfresco.repo.security.authentication.AuthenticationServiceImplTest.class, + org.alfresco.util.EmailHelperTest.class, + org.alfresco.repo.action.ParameterDefinitionImplTest.class, + org.alfresco.repo.action.ActionDefinitionImplTest.class, + org.alfresco.repo.action.ActionConditionDefinitionImplTest.class, + org.alfresco.repo.action.ActionImplTest.class, + org.alfresco.repo.action.ActionConditionImplTest.class, + org.alfresco.repo.action.CompositeActionImplTest.class, + org.alfresco.repo.action.CompositeActionConditionImplTest.class, + org.alfresco.repo.action.executer.TransformActionExecuterTest.class, + org.alfresco.repo.action.executer.ImporterActionExecutorUnitTest.class, + org.alfresco.repo.audit.AuditableAnnotationTest.class, + org.alfresco.repo.audit.PropertyAuditFilterTest.class, + org.alfresco.repo.audit.access.NodeChangeTest.class, + org.alfresco.repo.content.ContentServiceImplUnitTest.class, + org.alfresco.repo.content.directurl.SystemWideDirectUrlConfigUnitTest.class, + org.alfresco.repo.content.directurl.ContentStoreDirectUrlConfigUnitTest.class, + org.alfresco.repo.content.LimitedStreamCopierTest.class, + org.alfresco.repo.content.filestore.FileIOTest.class, + org.alfresco.repo.content.filestore.SpoofedTextContentReaderTest.class, + org.alfresco.repo.content.ContentDataTest.class, + org.alfresco.repo.content.replication.AggregatingContentStoreUnitTest.class, + org.alfresco.service.cmr.repository.TransformationOptionLimitsTest.class, + org.alfresco.service.cmr.repository.TransformationOptionPairTest.class, + org.alfresco.repo.content.transform.TransformerConfigTestSuite.class, + org.alfresco.repo.content.transform.TransformerDebugTest.class, + org.alfresco.service.cmr.repository.TemporalSourceOptionsTest.class, + org.alfresco.repo.content.metadata.MetadataExtracterLimitsTest.class, + org.alfresco.repo.content.caching.quota.StandardQuotaStrategyMockTest.class, + org.alfresco.repo.content.caching.quota.UnlimitedQuotaStrategyTest.class, + org.alfresco.repo.content.caching.CachingContentStoreTest.class, + org.alfresco.repo.content.caching.ContentCacheImplTest.class, + org.alfresco.repo.domain.permissions.FixedAclUpdaterUnitTest.class, + org.alfresco.repo.domain.propval.PropertyTypeConverterTest.class, + org.alfresco.repo.domain.schema.script.ScriptBundleExecutorImplTest.class, + org.alfresco.repo.search.MLAnaysisModeExpansionTest.class, + org.alfresco.repo.search.DocumentNavigatorTest.class, + org.alfresco.util.NumericEncodingTest.class, + org.alfresco.repo.search.impl.parsers.CMIS_FTSTest.class, + org.alfresco.repo.search.impl.parsers.CMISTest.class, + org.alfresco.repo.search.impl.parsers.FTSTest.class, + org.alfresco.repo.security.authentication.AlfrescoSSLSocketFactoryTest.class, + org.alfresco.repo.security.authentication.AuthorizationTest.class, + org.alfresco.repo.security.permissions.PermissionCheckedCollectionTest.class, + org.alfresco.repo.security.permissions.impl.acegi.FilteringResultSetTest.class, + org.alfresco.repo.security.permissions.impl.acegi.ACLEntryVoterUtilsTest.class, + org.alfresco.repo.security.authentication.ChainingAuthenticationServiceTest.class, + org.alfresco.repo.security.authentication.NameBasedUserNameGeneratorTest.class, + org.alfresco.repo.version.common.VersionImplTest.class, + org.alfresco.repo.version.common.VersionHistoryImplTest.class, + org.alfresco.repo.version.common.versionlabel.SerialVersionLabelPolicyTest.class, + org.alfresco.repo.workflow.activiti.WorklfowObjectFactoryTest.class, + org.alfresco.repo.workflow.activiti.properties.ActivitiPriorityPropertyHandlerTest.class, + org.alfresco.repo.workflow.WorkflowSuiteContextShutdownTest.class, + org.alfresco.repo.search.LuceneUtilsTest.class, - org.alfresco.heartbeat.HBDataCollectorServiceImplTest.class, - org.alfresco.heartbeat.jobs.LockingJobTest.class, - org.alfresco.heartbeat.jobs.QuartzJobSchedulerTest.class, - org.alfresco.heartbeat.AuthoritiesDataCollectorTest.class, - org.alfresco.heartbeat.ConfigurationDataCollectorTest.class, - org.alfresco.heartbeat.InfoDataCollectorTest.class, - org.alfresco.heartbeat.ModelUsageDataCollectorTest.class, - org.alfresco.heartbeat.SessionsUsageDataCollectorTest.class, - org.alfresco.heartbeat.SystemUsageDataCollectorTest.class, + org.alfresco.heartbeat.HBDataCollectorServiceImplTest.class, + org.alfresco.heartbeat.jobs.LockingJobTest.class, + org.alfresco.heartbeat.jobs.QuartzJobSchedulerTest.class, + org.alfresco.heartbeat.AuthoritiesDataCollectorTest.class, + org.alfresco.heartbeat.ConfigurationDataCollectorTest.class, + org.alfresco.heartbeat.InfoDataCollectorTest.class, + org.alfresco.heartbeat.ModelUsageDataCollectorTest.class, + org.alfresco.heartbeat.SessionsUsageDataCollectorTest.class, + org.alfresco.heartbeat.SystemUsageDataCollectorTest.class, - org.alfresco.util.BeanExtenderUnitTest.class, - org.alfresco.util.bean.HierarchicalBeanLoaderTest.class, - org.alfresco.util.resource.HierarchicalResourceLoaderTest.class, - org.alfresco.repo.events.ClientUtilTest.class, - org.alfresco.repo.rendition2.RenditionService2Test.class, - org.alfresco.repo.rendition2.TransformationOptionsConverterTest.class, + org.alfresco.util.BeanExtenderUnitTest.class, + org.alfresco.util.bean.HierarchicalBeanLoaderTest.class, + org.alfresco.util.resource.HierarchicalResourceLoaderTest.class, + org.alfresco.repo.events.ClientUtilTest.class, + org.alfresco.repo.rendition2.RenditionService2Test.class, + org.alfresco.repo.rendition2.TransformationOptionsConverterTest.class, - org.alfresco.repo.event2.RepoEvent2UnitSuite.class, + org.alfresco.repo.event2.RepoEvent2UnitSuite.class, - org.alfresco.util.schemacomp.SchemaDifferenceHelperUnitTest.class, - org.alfresco.repo.tagging.TaggingServiceImplUnitTest.class, - org.alfresco.repo.serviceaccount.ServiceAccountRegistryImplTest.class + org.alfresco.util.schemacomp.SchemaDifferenceHelperUnitTest.class, + org.alfresco.repo.tagging.TaggingServiceImplUnitTest.class, + org.alfresco.repo.serviceaccount.ServiceAccountRegistryImplTest.class }) public class AllUnitTestsSuite -{ -} \ No newline at end of file +{} diff --git a/repository/src/test/java/org/alfresco/repo/virtual/ref/NodeRefRadixHasherTest.java b/repository/src/test/java/org/alfresco/repo/virtual/ref/NodeRefRadixHasherTest.java index c3513b1dbe..4fdb1915b3 100644 --- a/repository/src/test/java/org/alfresco/repo/virtual/ref/NodeRefRadixHasherTest.java +++ b/repository/src/test/java/org/alfresco/repo/virtual/ref/NodeRefRadixHasherTest.java @@ -2,23 +2,23 @@ * #%L * Alfresco Repository * %% - * Copyright (C) 2005 - 2016 Alfresco Software Limited + * Copyright (C) 2005 - 2025 Alfresco Software Limited * %% - * This file is part of the Alfresco software. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is * provided under the following open source license terms: - * + * * Alfresco is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * Alfresco is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see . * #L% @@ -26,119 +26,98 @@ package org.alfresco.repo.virtual.ref; -import junit.framework.TestCase; +import static org.junit.Assert.*; +import static org.junit.runners.Parameterized.*; + +import static org.alfresco.repo.version.VersionModel.STORE_ID; +import static org.alfresco.service.cmr.repository.StoreRef.*; +import static org.alfresco.service.cmr.repository.StoreRef.PROTOCOL_DELETED; +import static org.alfresco.service.cmr.version.VersionService.VERSION_STORE_PROTOCOL; + +import java.util.Collection; +import java.util.List; +import java.util.UUID; +import java.util.stream.Stream; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; import org.alfresco.repo.version.Version2Model; -import org.alfresco.repo.version.VersionModel; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.service.cmr.version.VersionService; import org.alfresco.util.Pair; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.Test; -public class NodeRefRadixHasherTest extends TestCase +@RunWith(Parameterized.class) +public class NodeRefRadixHasherTest { - private static Log logger = LogFactory.getLog(NodeRefRadixHasherTest.class); + private final NodeRefRadixHasher nodeRefRadixHasher; + + @Parameters(name = "radix: {0}") + public static Collection data() + { + return List.of( + new Object[]{NodeRefRadixHasher.RADIX_36_HASHER}, + new Object[]{new NodeRefRadixHasher()}, + new Object[]{new NodeRefRadixHasher(32)}); + } + + public NodeRefRadixHasherTest(NodeRefRadixHasher nodeRefRadixHasher) + { + this.nodeRefRadixHasher = nodeRefRadixHasher; + } @Test - public void testSupportedStores() throws Exception + public void testSupportedStoresWithRandomUuids() { - NodeRefRadixHasher h = NodeRefRadixHasher.RADIX_36_HASHER; - - String[] storeProtocols = new String[] { StoreRef.PROTOCOL_WORKSPACE, StoreRef.PROTOCOL_ARCHIVE, - StoreRef.PROTOCOL_AVM, StoreRef.PROTOCOL_DELETED, VersionService.VERSION_STORE_PROTOCOL }; - String[] storeIds = new String[] { "SpacesStore", VersionModel.STORE_ID, Version2Model.STORE_ID }; + List storeProtocols = List.of(PROTOCOL_WORKSPACE, PROTOCOL_ARCHIVE, PROTOCOL_AVM, PROTOCOL_DELETED, VERSION_STORE_PROTOCOL); + List storeIds = List.of("SpacesStore", STORE_ID, Version2Model.STORE_ID); + List uuidNodeIds = Stream.generate(UUID::randomUUID) + .map(UUID::toString) + .limit(5) + .toList(); - for (int i = 0; i < storeProtocols.length; i++) + for (String storeProtocol : storeProtocols) { - for (int j = 0; j < storeIds.length; j++) + for (String storeId : storeIds) { - NodeRef nr = new NodeRef(storeProtocols[i], - storeIds[j], - "0d3b26ff-c4c1-4680-8622-8608ea7ab4b2"); - Pair nh = h.hash(nr); - NodeRef nr2 = h.lookup(nh); - assertEquals("Could match hash-lookup " + nr, - nr, - nr2); + for (String uuidNodeId : uuidNodeIds) + { + NodeRef nodeRef = new NodeRef(storeProtocol, storeId, uuidNodeId); + Pair hash = nodeRefRadixHasher.hash(nodeRef); + assertFalse(hash.getSecond().startsWith(NodeRefRadixHasher.NOT_UUID_FORMAT_MARKER)); + NodeRef actualNodeRef = nodeRefRadixHasher.lookup(hash); + assertEquals(nodeRef, actualNodeRef); + } } } } @Test - public void testZeroPaddedNodeId() throws Exception + public void testSpecificValidNotUuidNodeIds() { - NodeRefRadixHasher h = NodeRefRadixHasher.RADIX_36_HASHER; - NodeRef nr = new NodeRef("workspace://SpacesStore/0d3b26ff-c4c1-4680-8622-8608ea7ab4b2"); - Pair nh = h.hash(nr); - NodeRef nr2 = h.lookup(nh); - assertEquals(nr, - nr2); - } - - @Test - public void testInvalidStoreId() throws Exception - { - NodeRefRadixHasher h = NodeRefRadixHasher.RADIX_36_HASHER; - NodeRef nr = new NodeRef("workspace://ASpacesStore/0d3b26ff-c4c1-4680-8622-8608ea7ab4b2"); - try + StoreRef storeRef = new StoreRef(PROTOCOL_WORKSPACE, STORE_ID); + List notUuidNodeIds = List.of( + "0d3b26ff-c4c1-4680-8622-8608ea7ab4", + "0d3b26ff-c4c14680-8622-8608ea7ab4b29", + "wf-email-html-ftl", + "a", + NodeRefRadixHasher.NOT_UUID_FORMAT_MARKER, + "defrobldkfoeirjtuy79dfwwqperfiidoelb"); + for (String notUuidNodeId : notUuidNodeIds) { - h.hash(nr); - fail("Should not be able to hash invalid store NodeRef " + nr); - } - catch (RuntimeException e) - { - logger.info("Caught invalid NodeRef " + e.getMessage()); + NodeRef nodeRef = new NodeRef(storeRef, notUuidNodeId); + Pair hash = nodeRefRadixHasher.hash(nodeRef); + assertTrue(hash.getSecond().startsWith(NodeRefRadixHasher.NOT_UUID_FORMAT_MARKER)); + NodeRef actualNodeRef = nodeRefRadixHasher.lookup(hash); + assertEquals(nodeRef, actualNodeRef); } } - @Test - public void testInvalidStoreProtocol() throws Exception + @Test(expected = RuntimeException.class) + public void testEmptyNodeId() { - NodeRefRadixHasher h = NodeRefRadixHasher.RADIX_36_HASHER; - NodeRef nr = new NodeRef("Xworkspace://SpacesStore/0d3b26ff-c4c1-4680-8622-8608ea7ab4b2"); - try - { - h.hash(nr); - fail("Should not be able to hash invalid store NodeRef " + nr); - } - catch (RuntimeException e) - { - logger.info("Caught invalid NodeRef " + e.getMessage()); - } - } - - @Test - public void testInvalidNodeId1() throws Exception - { - NodeRefRadixHasher h = NodeRefRadixHasher.RADIX_36_HASHER; - NodeRef nr = new NodeRef("workspace://SpacesStore/0d3b26ff-c4c1-4680-8622-8608ea7ab4"); - try - { - h.hash(nr); - fail("Should not be able to hash invalid id (length) NodeRef " + nr); - } - catch (RuntimeException e) - { - logger.info("Caught invalid NodeRef " + e.getMessage()); - } - } - - @Test - public void testInvalidNodeId2() throws Exception - { - NodeRefRadixHasher h = NodeRefRadixHasher.RADIX_36_HASHER; - NodeRef nr = new NodeRef("workspace://SpacesStore/0d3b26ff-c4c14680-8622-8608ea7ab4b29"); - try - { - h.hash(nr); - fail("Should not be able to hash invalid id (format) NodeRef " + nr); - } - catch (RuntimeException e) - { - logger.info("Caught invalid NodeRef " + e.getMessage()); - } + NodeRef nodeRef = new NodeRef("workspace://SpacesStore/"); + nodeRefRadixHasher.hash(nodeRef); } } diff --git a/repository/src/test/java/org/alfresco/repo/virtual/ref/NotUuidNodeIdRadixHasherTest.java b/repository/src/test/java/org/alfresco/repo/virtual/ref/NotUuidNodeIdRadixHasherTest.java new file mode 100644 index 0000000000..02ca8e5f56 --- /dev/null +++ b/repository/src/test/java/org/alfresco/repo/virtual/ref/NotUuidNodeIdRadixHasherTest.java @@ -0,0 +1,100 @@ +/* + * #%L + * Alfresco Repository + * %% + * Copyright (C) 2025 - 2025 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ + +package org.alfresco.repo.virtual.ref; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class NotUuidNodeIdRadixHasherTest +{ + @Test + public void testRadix36Hashing() + { + NodeIdHasher nodeIdHasher = new NotUuidNodeIdRadixHasher(36); + String id = "wf-email-html-ftl"; + + String hashedId = nodeIdHasher.hash(id); + + String expected = "1e9lat6m0tvszgcle5scyylab8s"; + assertEquals(expected, hashedId); + } + + @Test + public void testRadix36Lookup() + { + NodeIdHasher nodeIdHasher = new NotUuidNodeIdRadixHasher(36); + String hashedUuid = "1e9lat6m0tvszgcle5scyylab8s"; + + String id = nodeIdHasher.lookup(hashedUuid); + + String expected = "wf-email-html-ftl"; + assertEquals(expected, id); + } + + @Test + public void testRadix16Hashing() + { + NodeIdHasher nodeIdHasher = new NotUuidNodeIdRadixHasher(16); + String id = "wf-email-html-ftl"; + + String hashedId = nodeIdHasher.hash(id); + + String expected = "77662d656d61696c2d68746d6c2d66746c"; + assertEquals(expected, hashedId); + } + + @Test + public void testRadix16Lookup() + { + NodeIdHasher nodeIdHasher = new NotUuidNodeIdRadixHasher(16); + String hashedUuid = "77662d656d61696c2d68746d6c2d66746c"; + + String id = nodeIdHasher.lookup(hashedUuid); + + String expected = "wf-email-html-ftl"; + assertEquals(expected, id); + } + + @Test(expected = RuntimeException.class) + public void testHashForEmptyUuid() + { + NodeIdHasher nodeIdHasher = new NotUuidNodeIdRadixHasher(36); + String uuid = ""; + + nodeIdHasher.hash(uuid); + } + + @Test(expected = RuntimeException.class) + public void testLookupForEmptyUuid() + { + NodeIdHasher nodeIdHasher = new NotUuidNodeIdRadixHasher(36); + String hashedUuid = ""; + + nodeIdHasher.lookup(hashedUuid); + } +} diff --git a/repository/src/test/java/org/alfresco/repo/virtual/ref/StoredStoreRefHasherTest.java b/repository/src/test/java/org/alfresco/repo/virtual/ref/StoredStoreRefHasherTest.java new file mode 100644 index 0000000000..4c95ba1a79 --- /dev/null +++ b/repository/src/test/java/org/alfresco/repo/virtual/ref/StoredStoreRefHasherTest.java @@ -0,0 +1,91 @@ +/* + * #%L + * Alfresco Repository + * %% + * Copyright (C) 2025 - 2025 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ + +package org.alfresco.repo.virtual.ref; + +import static org.junit.Assert.assertEquals; + +import static org.alfresco.repo.version.VersionModel.STORE_ID; +import static org.alfresco.service.cmr.repository.StoreRef.*; +import static org.alfresco.service.cmr.version.VersionService.VERSION_STORE_PROTOCOL; + +import java.util.List; + +import org.junit.Test; + +import org.alfresco.repo.version.Version2Model; +import org.alfresco.service.cmr.repository.StoreRef; + +public class StoredStoreRefHasherTest +{ + private final StoreRefHasher storeRefHasher = new StoredStoreRefHasher(); + + @Test + public void testSupportedStores() + { + List storeProtocols = List.of(PROTOCOL_WORKSPACE, PROTOCOL_ARCHIVE, PROTOCOL_AVM, PROTOCOL_DELETED, VERSION_STORE_PROTOCOL); + List storeIds = List.of("SpacesStore", STORE_ID, Version2Model.STORE_ID); + + for (String storeProtocol : storeProtocols) + { + for (String storeId : storeIds) + { + StoreRef storeRef = new StoreRef(storeProtocol, storeId); + String hash = storeRefHasher.hash(storeRef); + StoreRef actualStoreRef = storeRefHasher.lookup(hash); + assertEquals(storeRef, actualStoreRef); + } + } + } + + @Test(expected = RuntimeException.class) + public void testHashInvalidStoreId() + { + StoreRef storeRef = new StoreRef(PROTOCOL_WORKSPACE, "ASpacesStore"); + + storeRefHasher.hash(storeRef); + } + + @Test(expected = RuntimeException.class) + public void testHashInvalidStoreProtocol() + { + StoreRef storeRef = new StoreRef("Xworkspace", STORE_ID); + + storeRefHasher.hash(storeRef); + } + + @Test(expected = RuntimeException.class) + public void testLookupInvalidStoreId() + { + storeRefHasher.lookup("91"); + } + + @Test(expected = RuntimeException.class) + public void testLookupInvalidStoreProtocol() + { + storeRefHasher.lookup("19"); + } +} diff --git a/repository/src/test/java/org/alfresco/repo/virtual/ref/UuidNodeIdRadixHasherTest.java b/repository/src/test/java/org/alfresco/repo/virtual/ref/UuidNodeIdRadixHasherTest.java new file mode 100644 index 0000000000..e6697380c6 --- /dev/null +++ b/repository/src/test/java/org/alfresco/repo/virtual/ref/UuidNodeIdRadixHasherTest.java @@ -0,0 +1,102 @@ +/* + * #%L + * Alfresco Repository + * %% + * Copyright (C) 2025 - 2025 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ + +package org.alfresco.repo.virtual.ref; + +import static org.junit.Assert.*; + +import org.junit.Test; + +public class UuidNodeIdRadixHasherTest +{ + @Test + public void testRadix36Hashing() + { + NodeIdHasher nodeIdHasher = new UuidNodeIdRadixHasher(36); + String uuid = "0d3b26ff-c4c1-4680-8622-8608ea7ab4b2"; + + String hashedUuid = nodeIdHasher.hash(uuid); + + String expected = "s765ou6qn3lf446dbvrkv3qq"; + assertEquals(expected, hashedUuid); + } + + @Test + public void testRadix36Lookup() + { + NodeIdHasher nodeIdHasher = new UuidNodeIdRadixHasher(36); + String hashedUuid = "s765ou6qn3lf446dbvrkv3qq"; + + String uuid = nodeIdHasher.lookup(hashedUuid); + + String expected = "0d3b26ff-c4c1-4680-8622-8608ea7ab4b2"; + assertEquals(expected, uuid); + } + + @Test + public void testRadix16Hashing() + { + NodeIdHasher nodeIdHasher = new UuidNodeIdRadixHasher(16); + String uuid = "0d3b26ff-c4c1-4680-8622-8608ea7ab4b2"; + + String hashedUuid = nodeIdHasher.hash(uuid); + + // pragma: allowlist nextline secret its just hashed random uuid + String expected = "d3b26ffc4c1468086228608ea7ab4b2"; + assertEquals(expected, hashedUuid); + } + + @Test + public void testRadix16Lookup() + { + NodeIdHasher nodeIdHasher = new UuidNodeIdRadixHasher(16); + // pragma: allowlist nextline secret its just hashed random uuid + String hashedUuid = "d3b26ffc4c1468086228608ea7ab4b2"; + + String uuid = nodeIdHasher.lookup(hashedUuid); + + String expected = "0d3b26ff-c4c1-4680-8622-8608ea7ab4b2"; + assertEquals(expected, uuid); + } + + @Test(expected = RuntimeException.class) + public void testHashForEmptyUuid() + { + NodeIdHasher nodeIdHasher = new UuidNodeIdRadixHasher(36); + String uuid = ""; + + nodeIdHasher.hash(uuid); + } + + @Test(expected = RuntimeException.class) + public void testLookupForEmptyUuid() + { + NodeIdHasher nodeIdHasher = new UuidNodeIdRadixHasher(36); + String hashedUuid = ""; + + nodeIdHasher.lookup(hashedUuid); + } +}