.github/workflows/build.yml
@@ -70,6 +70,62 @@ opendj-server-legacy/target/package/opendj/bin/ldapsearch --hostname localhost --port 1636 --bindDN "cn=Directory Manager" --bindPassword password --useSsl --trustAll --baseDN "ou=people,dc=example2,dc=com" --searchScope sub "(uid=user.*)" dn | grep ^dn: | wc -l | grep -q 10000 opendj-server-legacy/target/package/opendj/bin/stop-ds rm -rf opendj-server-legacy/target/package/opendj/{config,db,changelogDb,logs} - name: Test on Unix FIPS if: runner.os != 'Windows' run: | export OPENDJ_JAVA_ARGS="-server -Xmx512m" echo password > /tmp/opendj.keystore.pin keytool -genkey -alias server-cert -keyalg rsa \ -dname "CN=example.com,O=OpenDJ RSA Self-Signed Certificate" \ -keystore /tmp/opendj.bcfks -storetype BCFKS -validity 3650 -providername BCFIPS \ -provider org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider \ -providerpath ./opendj-server-legacy/target/package/opendj/lib/org.bouncycastle.bc-fips.jar:./opendj-server-legacy/target/package/opendj/lib/org.bouncycastle.bcpkix-fips.jar \ -keypass:file /tmp/opendj.keystore.pin -storepass:file /tmp/opendj.keystore.pin -keysize 2048 -sigalg SHA256WITHRSA keytool -selfcert -alias server-cert -keystore /tmp/opendj.bcfks \ -storetype BCFKS -validity 3650 -providername BCFIPS \ -provider org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider \ -providerpath ./opendj-server-legacy/target/package/opendj/lib/org.bouncycastle.bc-fips.jar:./opendj-server-legacy/target/package/opendj/lib/org.bouncycastle.bcpkix-fips.jar \ -storepass:file /tmp/opendj.keystore.pin keytool -genkey -alias admin-cert -keyalg rsa \ -dname "CN=example.com,O=Administration Connector RSA Self-Signed Certificate" \ -keystore /tmp/opendj.bcfks -storetype BCFKS -validity 3650 -providername BCFIPS \ -provider org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider \ -providerpath ./opendj-server-legacy/target/package/opendj/lib/org.bouncycastle.bc-fips.jar:./opendj-server-legacy/target/package/opendj/lib/org.bouncycastle.bcpkix-fips.jar \ -keypass:file /tmp/opendj.keystore.pin -storepass:file /tmp/opendj.keystore.pin -keysize 2048 -sigalg SHA256WITHRSA keytool -selfcert -alias admin-cert -keystore /tmp/opendj.bcfks \ -storetype BCFKS -validity 3650 -providername BCFIPS \ -provider org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider \ -providerpath ./opendj-server-legacy/target/package/opendj/lib/org.bouncycastle.bc-fips.jar:./opendj-server-legacy/target/package/opendj/lib/org.bouncycastle.bcpkix-fips.jar \ -storepass:file /tmp/opendj.keystore.pin echo "useBcfksKeystore=/tmp/opendj.bcfks keyStorePasswordFile=/tmp/opendj.keystore.pin" > /tmp/opendj-setup.properties.bcfks opendj-server-legacy/target/package/opendj/setup -h localhost -p 1389 --ldapsPort 1636 --adminConnectorPort 4444 \ --enableStartTLS --certNickname admin-cert --rootUserDN "cn=Directory Manager" --rootUserPassword password \ --baseDN dc=example,dc=com --sampleData 5000 --cli --acceptLicense --no-prompt \ --propertiesFilePath /tmp/opendj-setup.properties.bcfks --doNotStart opendj-server-legacy/target/package/opendj/bin/start-ds opendj-server-legacy/target/package/opendj/bin/status --bindDN "cn=Directory Manager" --bindPassword password --trustAll opendj-server-legacy/target/package/opendj/bin/ldapsearch --hostname localhost --port 1636 --bindDN "cn=Directory Manager" --bindPassword password --useSsl --trustAll --baseDN "dc=example,dc=com" --searchScope base "(objectClass=*)" 1.1 opendj-server-legacy/target/package/opendj/bin/ldapsearch --hostname localhost --port 1636 --bindDN "cn=Directory Manager" --bindPassword password --useSsl --trustAll --baseDN "ou=people,dc=example,dc=com" --searchScope sub "(uid=user.*)" dn | grep ^dn: | wc -l | grep -q 5000 opendj-server-legacy/target/package/opendj/bin/dsconfig create-backend --hostname localhost --port 4444 --bindDN "cn=Directory Manager" --bindPassword password --backend-name=example2 --type je --set=base-dn:dc=example2,dc=com --set=enabled:true --no-prompt --trustAll opendj-server-legacy/target/package/opendj/bin/makeldif -o /tmp/test.ldif -c suffix=dc=example2,dc=com opendj-server-legacy/target/package/opendj/config/MakeLDIF/example.template opendj-server-legacy/target/package/opendj/bin/stop-ds opendj-server-legacy/target/package/opendj/bin/import-ldif --offline --ldifFile /tmp/test.ldif --backendID=example2 opendj-server-legacy/target/package/opendj/bin/rebuild-index --offline --bindDN "cn=Directory Manager" --bindPassword password --baseDN "dc=example2,dc=com" --rebuildAll opendj-server-legacy/target/package/opendj/bin/start-ds opendj-server-legacy/target/package/opendj/bin/rebuild-index --bindDN "cn=Directory Manager" --bindPassword password --baseDN "dc=example2,dc=com" --rebuildAll --trustAll opendj-server-legacy/target/package/opendj/bin/ldapsearch --hostname localhost --port 1636 --bindDN "cn=Directory Manager" --bindPassword password --useSsl --trustAll --baseDN "ou=people,dc=example2,dc=com" --searchScope sub "(uid=user.*)" dn | grep ^dn: | wc -l | grep -q 10000 opendj-server-legacy/target/package/opendj/bin/stop-ds rm -rf opendj-server-legacy/target/package/opendj/{config,db,changelogDb,logs} - name: Test LDAP in Cassandra if: runner.os == 'Linux' run: | opendj-cli/src/main/java/com/forgerock/opendj/cli/ConnectionFactoryProvider.java
@@ -727,9 +727,9 @@ if (isFips) { keystore.load(null, keyStorePIN); } else { try (final FileInputStream fos = new FileInputStream(keyStoreFile)) { keystore.load(fos, keyStorePIN); } try (final FileInputStream fos = new FileInputStream(keyStoreFile)) { keystore.load(fos, keyStorePIN); } } if (isFips) { @@ -852,7 +852,7 @@ } if (isFips) { return TrustManagers.checkUsingPkcs11TrustStore(); return TrustManagers.checkUsingPkcs12TrustStore(); } return tm; opendj-core/pom.xml
@@ -92,18 +92,19 @@ <artifactId>jaxb-impl</artifactId> </dependency> <!-- BC FIPS Provider libs --> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bc-fips</artifactId> <version>${bc.fips.version}</version> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bctls-fips</artifactId> <version>${bctls.fips.version}</version> </dependency> <!-- BC FIPS Provider libs --> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bc-fips</artifactId> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bctls-fips</artifactId> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpkix-fips</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> @@ -113,8 +114,7 @@ <properties> <bc.fips.version>2.1.1</bc.fips.version> <bctls.fips.version>2.1.20</bctls.fips.version> <opendj.osgi.import.additional> com.sun.security.auth*;resolution:=optional opendj-core/src/main/java/com/forgerock/opendj/util/FipsStaticUtils.java
@@ -21,7 +21,11 @@ private static final String BC_FIPS_PROVIDER_CLASS_NAME = "org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider"; public static void registerBcProvider() { if (!StaticUtils.isFips()) { registerBcProvider(false); } public static void registerBcProvider(boolean force) { if(!"true".equals(System.getProperty("org.openidentityplatform.opendj.fips.register")) && !force) { return; } opendj-core/src/main/java/com/forgerock/opendj/util/StaticUtils.java
@@ -13,6 +13,8 @@ * * Copyright 2009-2010 Sun Microsystems, Inc. * Portions copyright 2011-2015 ForgeRock AS. * Portions copyright 2017-2025 3A Systems, LLC. * */ package com.forgerock.opendj.util; opendj-core/src/main/java/org/forgerock/opendj/ldap/TrustManagers.java
@@ -522,8 +522,8 @@ throw new NoSuchAlgorithmException(); } public static X509TrustManager checkUsingPkcs11TrustStore() throws GeneralSecurityException, IOException { final KeyStore keyStore = KeyStore.getInstance("PKCS11"); public static X509TrustManager checkUsingPkcs12TrustStore() throws GeneralSecurityException, IOException { final KeyStore keyStore = KeyStore.getInstance("PKCS12"); keyStore.load(null, null); final TrustManagerFactory tmf = opendj-core/src/test/java/org/forgerock/opendj/ldap/LDAPServer.java
@@ -13,6 +13,7 @@ * * Copyright 2010 Sun Microsystems, Inc. * Portions Copyright 2011-2016 ForgeRock AS. * Portions Copyright 2025 3A Systems LLC. */ package org.forgerock.opendj.ldap; @@ -22,10 +23,18 @@ import static org.forgerock.opendj.ldap.TestCaseUtils.loopbackWithDynamicPort; import java.io.IOException; import java.math.BigInteger; import java.net.InetSocketAddress; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.KeyStore; import java.security.SecureRandom; import java.security.Security; import java.security.cert.X509Certificate; import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -41,12 +50,20 @@ import javax.security.auth.callback.NameCallback; import javax.security.auth.callback.PasswordCallback; import javax.security.auth.callback.UnsupportedCallbackException; import javax.security.auth.x500.X500Principal; import javax.security.sasl.AuthorizeCallback; import javax.security.sasl.RealmCallback; import javax.security.sasl.Sasl; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.util.BigIntegers; import org.forgerock.opendj.io.ASN1; import org.forgerock.opendj.io.ASN1Reader; import org.forgerock.opendj.io.LDAP; @@ -77,9 +94,6 @@ import com.forgerock.opendj.ldap.controls.AccountUsabilityResponseControl; import com.forgerock.reactive.ServerConnectionFactoryAdapter; import sun.security.tools.keytool.CertAndKeyGen; import sun.security.x509.X500Name; /** * A simple ldap server that manages 1000 entries and used for running * testcases. @@ -520,14 +534,40 @@ static { final String password="keypassword"; try { CertAndKeyGen keyGen=new CertAndKeyGen("RSA","SHA256WithRSA",null); keyGen.generate(2048); X509Certificate[] chain=new X509Certificate[1]; chain[0]=keyGen.getSelfCertificate(new X500Name("CN=localhost"), (long)1*3600); if (Security.getProvider(BouncyCastleFipsProvider.PROVIDER_NAME) == null) { Security.addProvider(new BouncyCastleFipsProvider()); } String keyType = "RSA"; String signatureAlgorithm = "SHA256WithRSA"; int keySize = 2048; KeyPairGenerator generator = KeyPairGenerator.getInstance(keyType, BouncyCastleFipsProvider.PROVIDER_NAME); generator.initialize(keySize); KeyPair keyPair = generator.generateKeyPair(); X509Certificate[] chain = new X509Certificate[1]; BigInteger serial = BigIntegers.createRandomBigInteger(64, new SecureRandom()); Instant now = Instant.now(); Date notBeforeDate = Date.from(now); Date notAfterDate = Date.from(now.plus(1, ChronoUnit.DAYS)); X500Principal subject = new X500Principal("CN=localhost"); JcaX509v3CertificateBuilder builder = new JcaX509v3CertificateBuilder( subject, serial, notBeforeDate, notAfterDate, subject, keyPair.getPublic() ); ContentSigner signer = new JcaContentSignerBuilder(signatureAlgorithm) .setProvider(BouncyCastleFipsProvider.PROVIDER_NAME) .build(keyPair.getPrivate()); X509CertificateHolder holder = builder.build(signer); JcaX509CertificateConverter converter = new JcaX509CertificateConverter() .setProvider(BouncyCastleFipsProvider.PROVIDER_NAME); chain[0] = converter.getCertificate(holder); KeyStore ks = KeyStore.getInstance("JKS"); ks.load(null, null); ks.setKeyEntry("localhost", keyGen.getPrivateKey(),password.toCharArray(), chain); ks.setKeyEntry("localhost", keyPair.getPrivate(), password.toCharArray(), chain); KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); kmf.init(ks, password.toCharArray()); sslContext = new SSLContextBuilder().setKeyManager(kmf.getKeyManagers()[0]).getSSLContext(); opendj-server-legacy/pom.xml
@@ -321,6 +321,10 @@ <artifactId>mssql-jdbc</artifactId> <version>12.10.0.jre8</version> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpkix-fips</artifactId> </dependency> </dependencies> <build><finalName>${project.groupId}.${project.artifactId}</finalName> @@ -1274,6 +1278,8 @@ <org.opends.test.suppressOutput>true</org.opends.test.suppressOutput> <org.opends.test.pauseOnFailure>false</org.opends.test.pauseOnFailure> <org.opends.test.copyClassesToTestPackage>false</org.opends.test.copyClassesToTestPackage> <org.opends.test.timeout>600000</org.opends.test.timeout><!--15 mins--> <org.opends.test.trace.pattern>(org\.opends\.server\.replication\.service\..*)|(org\.opends\.server\.replication\.GenerationIdTest)|(org\.opends\.server\.types.\HostPortTest)</org.opends.test.trace.pattern> </systemPropertyVariables> <argLine>@{argLine}</argLine> <reuseForks>false</reuseForks> opendj-server-legacy/resource/bin/_script-util.bat
@@ -168,9 +168,9 @@ set PATH=%SystemRoot%;%PATH% set SCRIPT_NAME_ARG=-Dorg.opends.server.scriptName=%SCRIPT_NAME% set SET_ENVIRONMENT_VARS_DONE=true "%OPENDJ_JAVA_BIN%" --add-exports java.base/sun.security.x509=ALL-UNNAMED --add-exports java.base/sun.security.tools.keytool=ALL-UNNAMED --add-opens java.base/jdk.internal.loader=ALL-UNNAMED --version > NUL 2>&1 "%OPENDJ_JAVA_BIN%" --add-opens java.base/jdk.internal.loader=ALL-UNNAMED --version > NUL 2>&1 set RESULT_CODE=%errorlevel% if %RESULT_CODE% == 0 set OPENDJ_JAVA_ARGS=%OPENDJ_JAVA_ARGS% --add-exports java.base/sun.security.x509=ALL-UNNAMED --add-exports java.base/sun.security.tools.keytool=ALL-UNNAMED --add-opens java.base/jdk.internal.loader=ALL-UNNAMED if %RESULT_CODE% == 0 set OPENDJ_JAVA_ARGS=%OPENDJ_JAVA_ARGS% --add-opens java.base/jdk.internal.loader=ALL-UNNAMED goto scriptBegin :testJava opendj-server-legacy/resource/bin/_script-util.sh
@@ -184,7 +184,7 @@ SCRIPT_NAME_ARG=-Dorg.opends.server.scriptName=${SCRIPT_NAME} export SCRIPT_NAME_ARG "${OPENDJ_JAVA_BIN}" --add-exports java.base/sun.security.x509=ALL-UNNAMED --add-exports java.base/sun.security.tools.keytool=ALL-UNNAMED --add-opens java.base/jdk.internal.loader=ALL-UNNAMED --version > /dev/null 2>&1 "${OPENDJ_JAVA_BIN}" --add-opens java.base/jdk.internal.loader=ALL-UNNAMED --version > /dev/null 2>&1 RESULT_CODE=${?} if test ${RESULT_CODE} -eq 0 then opendj-server-legacy/src/main/java/org/opends/server/extensions/FileBasedKeyManagerProvider.java
@@ -32,6 +32,7 @@ import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManagerFactory; import com.forgerock.opendj.util.FipsStaticUtils; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.i18n.LocalizableMessageDescriptor.Arg2; import org.forgerock.i18n.LocalizableMessageDescriptor.Arg3; @@ -259,6 +260,9 @@ { try { if(cfg.getKeyStoreType().equals("BCFKS")) { FipsStaticUtils.registerBcProvider(true); } KeyStore.getInstance(cfg.getKeyStoreType()); return cfg.getKeyStoreType(); } opendj-server-legacy/src/main/java/org/opends/server/extensions/FileBasedTrustManagerProvider.java
@@ -16,6 +16,7 @@ */ package org.opends.server.extensions; import com.forgerock.opendj.util.FipsStaticUtils; import org.forgerock.i18n.LocalizableMessage; import java.io.File; import java.io.FileInputStream; @@ -204,6 +205,9 @@ final String trustStoreType = cfg.getTrustStoreType(); if (trustStoreType != null) { if(trustStoreType.equals("BCFKS")) { FipsStaticUtils.registerBcProvider(true); } try { KeyStore.getInstance(trustStoreType); opendj-server-legacy/src/main/java/org/opends/server/replication/service/ReplicationBroker.java
@@ -13,6 +13,7 @@ * * Copyright 2006-2010 Sun Microsystems, Inc. * Portions Copyright 2011-2016 ForgeRock AS. * Portions Copyright 2023-2025 3A Systems LLC. * Portions Copyright 2025 Wren Security. */ package org.opends.server.replication.service; @@ -2665,14 +2666,16 @@ { debugInfo("is stopping and will close the connection to RS(" + getRsServerId() + ")"); } synchronized (startStopLock) { if (shutdown) { return; } } domain.publishReplicaOfflineMsg(); synchronized (startStopLock) { if (shutdown) { return; } domain.publishReplicaOfflineMsg(); shutdown = true; setConnectedRS(ConnectedRS.stopped()); stopRSHeartBeatMonitoring(); opendj-server-legacy/src/main/java/org/opends/server/replication/service/ReplicationDomain.java
@@ -13,6 +13,7 @@ * * Copyright 2008-2010 Sun Microsystems, Inc. * Portions Copyright 2011-2016 ForgeRock AS. * Portions Copyright 2025 3A Systems LLC. */ package org.opends.server.replication.service; @@ -39,6 +40,9 @@ import java.util.Map.Entry; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; @@ -373,6 +377,11 @@ protected volatile long generationId; /** * Thread pool for export thread tasks */ private final ExecutorService exportThreadPool = Executors.newCachedThreadPool(); /** * Returns the {@link CSNGenerator} that will be used to * generate {@link CSN} for this domain. * @@ -879,7 +888,10 @@ // Do this work in a thread to allow replay thread continue working ExportThread exportThread = new ExportThread( initReqMsg.getSenderID(), initReqMsg.getInitWindow()); exportThread.start(); exportThreadPool.execute(() -> { Thread.currentThread().setName(exportThread.getName()); exportThread.run(); }); } } @@ -1075,6 +1087,9 @@ This server is not the initiator of the export so there is nothing more to do locally. */ if (logger.isTraceEnabled()) { logger.trace(LocalizableMessage.raw("[IE] got exception" + getName()), de); } } if (logger.isTraceEnabled()) @@ -3016,6 +3031,13 @@ { broker.stop(); } try { exportThreadPool.shutdown(); boolean timedOut = exportThreadPool.awaitTermination(100, TimeUnit.SECONDS); logger.info(LocalizableMessage.raw("export pool termination timed out: " + timedOut)); } catch (InterruptedException e) { // Give up waiting. } // Stop the listener thread if (listenerThread != null) opendj-server-legacy/src/main/java/org/opends/server/tools/InstallDS.java
@@ -40,6 +40,7 @@ import java.util.LinkedList; import java.util.List; import com.forgerock.opendj.util.FipsStaticUtils; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.i18n.LocalizableMessageDescriptor.Arg0; import org.forgerock.i18n.LocalizableMessageDescriptor.Arg1; @@ -326,6 +327,10 @@ return InstallReturnCode.ERROR_LICENSE_NOT_ACCEPTED.getReturnCode(); } if(argParser.useBcfksArg.isPresent()) { FipsStaticUtils.registerBcProvider(true); } final UserData uData = new UserData(); InstallReturnCode fillUserDataRC; try opendj-server-legacy/src/main/java/org/opends/server/tools/SSLConnectionFactory.java
@@ -122,7 +122,7 @@ trustManagers = blindTrustProvider.getTrustManagers(); } else if (trustStorePath == null) { if (isFips()) { TrustManager tm = TrustManagers.checkUsingPkcs11TrustStore(); TrustManager tm = TrustManagers.checkUsingPkcs12TrustStore(); trustManagers = new TrustManager[] { tm }; } else { trustManagers = PromptTrustManager.getTrustManagers(); opendj-server-legacy/src/main/java/org/opends/server/types/HostPort.java
@@ -13,6 +13,7 @@ * * Copyright 2006-2008 Sun Microsystems, Inc. * Portions Copyright 2013-2016 ForgeRock AS. * Portions Copyright 2025 3A Systems LLC. */ package org.opends.server.types; @@ -459,6 +460,9 @@ // Get and compare ports of RS1 and RS2 if (getPort() != other.getPort()) { if(logger.isTraceEnabled()) { logger.trace("port and host does not match " + this + "; " + other); } return false; } @@ -475,6 +479,9 @@ } else if (thisAddresses == null || otherAddresses == null) { if(logger.isTraceEnabled()) { logger.trace("port and host does not match: " + this + "=" + thisAddresses + "; " + other + "=" + otherAddresses); } // One local address and one non-local. return false; } @@ -490,10 +497,17 @@ } } } if(logger.isTraceEnabled()) { logger.trace("port and host does not match: " + this + "=" + thisAddresses + "; " + other + "=" + otherAddresses); } return false; } catch (UnknownHostException ex) { if(logger.isTraceEnabled()) { logger.traceException(ex, "got exception when resolving hosts: " + this + " and " + other ); } // Unknown RS: should not happen return false; } opendj-server-legacy/src/main/java/org/opends/server/util/Platform.java
@@ -13,30 +13,50 @@ * * Copyright 2009-2010 Sun Microsystems, Inc. * Portions Copyright 2013-2016 ForgeRock AS. * Portions Copyright 2025 Wren Security. * Portions Copyright 2025 3A Systems LLC. */ package org.opends.server.util; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.KeyPairGenerator; import java.security.KeyStore; import java.security.PrivateKey; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.math.BigInteger; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.PrivateKey; import java.security.SecureRandom; import java.security.Security; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.Date; import com.forgerock.opendj.util.StaticUtils; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.util.BigIntegers; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.util.Reject; import static org.opends.messages.UtilityMessages.*; import static org.opends.server.util.ServerConstants.CERTANDKEYGEN_PROVIDER; import static org.opends.messages.UtilityMessages.ERR_CERTMGR_ADD_CERT; import static org.opends.messages.UtilityMessages.ERR_CERTMGR_ALIAS_ALREADY_EXISTS; import static org.opends.messages.UtilityMessages.ERR_CERTMGR_ALIAS_INVALID; import static org.opends.messages.UtilityMessages.ERR_CERTMGR_CERT_REPLIES_INVALID; import static org.opends.messages.UtilityMessages.ERR_CERTMGR_DELETE_ALIAS; import static org.opends.messages.UtilityMessages.ERR_CERTMGR_GEN_SELF_SIGNED_CERT; import static org.opends.messages.UtilityMessages.ERR_CERTMGR_KEYSTORE_NONEXISTANT; import static org.opends.messages.UtilityMessages.ERR_CERTMGR_TRUSTED_CERT; /** * Provides a wrapper class that collects all of the JVM vendor and JDK version @@ -45,21 +65,6 @@ public final class Platform { /** Prefix that determines which security package to use. */ private static final String pkgPrefix; /** The two security package prefixes (IBM and SUN). */ private static final String IBM_SEC = "com.ibm.security"; private static final String SUN_SEC = "sun.security"; /** The CertAndKeyGen class is located in different packages depending on JVM environment. */ private static final String[] CERTANDKEYGEN_PATHS = new String[] { "sun.security.x509.CertAndKeyGen", // Oracle/Sun/OpenJDK 6,7 "sun.security.tools.keytool.CertAndKeyGen", // Oracle/Sun/OpenJDK 8 "com.ibm.security.x509.CertAndKeyGen", // IBM SDK 7 "com.ibm.security.tools.CertAndKeyGen" // IBM SDK 8 }; private static final PlatformIMPL IMPL; /** The minimum java supported version. */ @@ -67,16 +72,6 @@ static { String vendor = System.getProperty("java.vendor"); if (vendor.startsWith("IBM")) { pkgPrefix = IBM_SEC; } else { pkgPrefix = SUN_SEC; } IMPL = new DefaultPlatformIMPL(); } @@ -84,10 +79,10 @@ public static enum KeyType { /** RSA key algorithm with 2048 bits size and SHA256withRSA signing algorithm. */ RSA("rsa", 2048, "SHA256WithRSA"), RSA("RSA", 2048, "SHA256withRSA"), /** Elliptic Curve key algorithm with 233 bits size and SHA256withECDSA signing algorithm. */ EC("ec", 256, "SHA256withECDSA"); /** Elliptic Curve key algorithm with 256 bits size and SHA256withECDSA signing algorithm. */ EC("EC", 256, "SHA256withECDSA"); /** Default key type used when none can be determined. */ public final static KeyType DEFAULT = RSA; @@ -104,22 +99,6 @@ } /** * Check whether this key type is supported by the current JVM. * @return true if this key type is supported, false otherwise. */ public boolean isSupported() { try { return KeyPairGenerator.getInstance(keyAlgorithm.toUpperCase()) != null; } catch (NoSuchAlgorithmException e) { return false; } } /** * Get a KeyType based on the alias name. * * @param alias @@ -144,106 +123,13 @@ */ private static abstract class PlatformIMPL { /** Time values used in validity calculations. */ private static final int SEC_IN_DAY = 24 * 60 * 60; /** Methods pulled from the classes. */ private static final String GENERATE_METHOD = "generate"; private static final String GET_PRIVATE_KEY_METHOD = "getPrivateKey"; private static final String GET_SELFSIGNED_CERT_METHOD = "getSelfCertificate"; /** Classes needed to manage certificates. */ private static final Class<?> certKeyGenClass, X500NameClass; /** Constructors for each of the above classes. */ private static Constructor<?> certKeyGenCons, X500NameCons; /** Filesystem APIs */ static { String certAndKeyGen = getCertAndKeyGenClassName(); if(certAndKeyGen == null) { LocalizableMessage msg = ERR_CERTMGR_CERTGEN_NOT_FOUND.get(CERTANDKEYGEN_PROVIDER); throw new ExceptionInInitializerError(msg.toString()); } String X500Name = pkgPrefix + ".x509.X500Name"; try { certKeyGenClass = Class.forName(certAndKeyGen); X500NameClass = Class.forName(X500Name); certKeyGenCons = certKeyGenClass.getConstructor(String.class, String.class); X500NameCons = X500NameClass.getConstructor(String.class); } catch (ClassNotFoundException e) { LocalizableMessage msg = ERR_CERTMGR_CLASS_NOT_FOUND.get(e.getMessage()); throw new ExceptionInInitializerError(msg.toString()); } catch (SecurityException e) { LocalizableMessage msg = ERR_CERTMGR_SECURITY.get(e.getMessage()); throw new ExceptionInInitializerError(msg.toString()); } catch (NoSuchMethodException e) { LocalizableMessage msg = ERR_CERTMGR_NO_METHOD.get(e.getMessage()); throw new ExceptionInInitializerError(msg.toString()); } } /** * Try to decide which CertAndKeyGen class to use. * * @return a fully qualified class name or null */ private static String getCertAndKeyGenClassName() { String certAndKeyGen = System.getProperty(CERTANDKEYGEN_PROVIDER); if (certAndKeyGen != null) { return certAndKeyGen; } for (String className : CERTANDKEYGEN_PATHS) { if (classExists(className)) { return className; } } return null; } /** * A quick check to see if a class can be loaded. Doesn't check if * it can be instantiated. * * @param className full class name to check * @return true if the class is found */ private static boolean classExists(final String className) { try { Class.forName(className); return true; } catch (ClassNotFoundException | ClassCastException e) { return false; } } protected PlatformIMPL() { } private final void deleteAlias(KeyStore ks, String ksPath, String alias, char[] pwd) throws KeyStoreException char[] pwd) throws KeyStoreException { try { @@ -264,10 +150,8 @@ } } private final void addCertificate(KeyStore ks, String ksType, String ksPath, String alias, char[] pwd, String certPath) throws KeyStoreException String alias, char[] pwd, String certPath) throws KeyStoreException { try { @@ -284,7 +168,7 @@ throw new KeyStoreException(msg.toString()); } else if (!ks.containsAlias(alias) || ks.entryInstanceOf(alias, KeyStore.TrustedCertificateEntry.class)) || ks.entryInstanceOf(alias, KeyStore.TrustedCertificateEntry.class)) { try (InputStream inStream = new FileInputStream(certPath)) { trustedCert(alias, cf, ks, inStream); @@ -305,14 +189,17 @@ } } private static final KeyStore generateSelfSignedCertificate(KeyStore ks, String ksType, String ksPath, KeyType keyType, String alias, char[] pwd, String dn, int validity) throws KeyStoreException String ksType, String ksPath, KeyType keyType, String alias, char[] pwd, String dn, int validity) throws KeyStoreException { boolean isFips = StaticUtils.isFips(); try { if(!isFips) { Security.addProvider(new BouncyCastleFipsProvider()); } if (ks == null) { ks = KeyStore.getInstance(ksType); @@ -324,12 +211,11 @@ throw new KeyStoreException(msg.toString()); } final Object keypair = newKeyPair(keyType); final Object subject = newX500Name(dn); generate(keypair, keyType.keySize); final PrivateKey privateKey = getPrivateKey(keypair); final Certificate[] certificateChain = new Certificate[] { getSelfCertificate(keypair, subject, validity * SEC_IN_DAY) KeyPair keyPair = newKeyPair(keyType); PrivateKey privateKey = keyPair.getPrivate(); X500Name subject = new X500Name(dn); Certificate[] certificateChain = new Certificate[] { generateSelfCertificate(keyPair, keyType, subject, validity) }; ks.setKeyEntry(alias, privateKey, pwd, certificateChain); try (FileOutputStream fileOutStream = new FileOutputStream(ksPath)) { @@ -341,34 +227,41 @@ { throw new KeyStoreException(ERR_CERTMGR_GEN_SELF_SIGNED_CERT.get(alias, e.getMessage()).toString(), e); } finally { if(!isFips) { Security.removeProvider(BouncyCastleFipsProvider.PROVIDER_NAME); } } } private static Object newKeyPair(KeyType keyType) throws Exception private static KeyPair newKeyPair(KeyType keyType) throws Exception { return certKeyGenCons.newInstance(keyType.keyAlgorithm, keyType.signatureAlgorithm); KeyPairGenerator generator = KeyPairGenerator.getInstance(keyType.keyAlgorithm, BouncyCastleFipsProvider.PROVIDER_NAME); generator.initialize(keyType.keySize); return generator.generateKeyPair(); } private static Object newX500Name(String dn) throws Exception private static Certificate generateSelfCertificate(KeyPair keyPair, KeyType keyType, X500Name subject, int days) throws Exception { return X500NameCons.newInstance(dn); } BigInteger serial = BigIntegers.createRandomBigInteger(64, new SecureRandom()); Instant now = Instant.now(); Date notBeforeDate = Date.from(now); Date notAfterDate = Date.from(now.plus(days, ChronoUnit.DAYS)); private static void generate(Object keypair, int keySize) throws Exception { Method certAndKeyGenGenerate = certKeyGenClass.getMethod(GENERATE_METHOD, int.class); certAndKeyGenGenerate.invoke(keypair, keySize); } JcaX509v3CertificateBuilder builder = new JcaX509v3CertificateBuilder( subject, serial, notBeforeDate, notAfterDate, subject, keyPair.getPublic() ); ContentSigner signer = new JcaContentSignerBuilder(keyType.signatureAlgorithm) .setProvider(BouncyCastleFipsProvider.PROVIDER_NAME) .build(keyPair.getPrivate()); X509CertificateHolder holder = builder.build(signer); JcaX509CertificateConverter converter = new JcaX509CertificateConverter() .setProvider(BouncyCastleFipsProvider.PROVIDER_NAME); private static PrivateKey getPrivateKey(Object keypair) throws Exception { Method certAndKeyGetPrivateKey = certKeyGenClass.getMethod(GET_PRIVATE_KEY_METHOD); return (PrivateKey) certAndKeyGetPrivateKey.invoke(keypair); } private static Certificate getSelfCertificate(Object keypair, Object subject, int days) throws Exception { Method getSelfCertificate = certKeyGenClass.getMethod(GET_SELFSIGNED_CERT_METHOD, X500NameClass, long.class); return (Certificate) getSelfCertificate.invoke(keypair, subject, days); return converter.getCertificate(holder); } /** @@ -376,7 +269,7 @@ * only if it is self-signed. */ private void trustedCert(String alias, CertificateFactory cf, KeyStore ks, InputStream in) throws KeyStoreException InputStream in) throws KeyStoreException { try { @@ -398,8 +291,6 @@ } } /** * Check that the issuer and subject DNs match. */ @@ -409,15 +300,11 @@ } } /** Prevent instantiation. */ private Platform() { } /** * Add the certificate in the specified path to the provided keystore; * creating the keystore with the provided type and path if it doesn't exist. @@ -439,13 +326,11 @@ * If an error occurred adding the certificate to the keystore. */ public static void addCertificate(KeyStore ks, String ksType, String ksPath, String alias, char[] pwd, String certPath) throws KeyStoreException String alias, char[] pwd, String certPath) throws KeyStoreException { IMPL.addCertificate(ks, ksType, ksPath, alias, pwd, certPath); } /** * Delete the specified alias from the provided keystore. * @@ -461,13 +346,11 @@ * If an error occurred deleting the alias. */ public static void deleteAlias(KeyStore ks, String ksPath, String alias, char[] pwd) throws KeyStoreException char[] pwd) throws KeyStoreException { IMPL.deleteAlias(ks, ksPath, alias, pwd); } /** * Generate a self-signed certificate using the specified alias, dn string and * validity period. If the keystore does not exist, it will be created using @@ -494,8 +377,8 @@ * If the self-signed certificate cannot be generated. */ public static void generateSelfSignedCertificate(KeyStore ks, String ksType, String ksPath, KeyType keyType, String alias, char[] pwd, String dn, int validity) throws KeyStoreException String ksPath, KeyType keyType, String alias, char[] pwd, String dn, int validity) throws KeyStoreException { PlatformIMPL.generateSelfSignedCertificate(ks, ksType, ksPath, keyType, alias, pwd, dn, validity); } @@ -507,8 +390,6 @@ { } /** * Test if a platform java vendor property starts with the specified vendor * string. @@ -539,4 +420,4 @@ Reject.ifTrue(cpuMultiplier < 0, "Multiplier must be a positive number"); return Math.max(minimumValue, (int)(Runtime.getRuntime().availableProcessors() * cpuMultiplier)); } } } opendj-server-legacy/src/messages/org/opends/messages/utility.properties
@@ -352,14 +352,6 @@ null ERR_CERTMGR_VALUE_INVALID_294=The argument %s is invalid because it \ is either null, or has zero length ERR_CERTMGR_CLASS_NOT_FOUND_295=A security class cannot be found \ in this JVM because of the following reason: %s ERR_CERTMGR_SECURITY_296=The security classes could not be \ initialized because of the following reason: %s ERR_CERTMGR_NO_METHOD_297=A method needed in the security classes \ could not be located because of the following reason: %s ERR_CERTMGR_CERTGEN_NOT_FOUND_298=The CertAndKeyGen security class cannot be \ found, consider setting -D%s= WARN_EXPORT_LDIF_SET_PERMISSION_FAILED_300=An error occurred while \ setting file permissions for the LDIF file %s: %s ERR_LDIF_READ_ATTR_SKIP_301=Skipping entry %s because the following error \ @@ -440,4 +432,4 @@ ERR_EMBEDDED_SERVER_LDIF_MANAGEMENT_CONTEXT_342=An error occurred while attempting to \ read the configuration file '%s' ERR_EMBEDDED_SERVER_BUILD_VERSION_343=An error occurred while attempting to \ retrieve the build version of the directory server: '%s' retrieve the build version of the directory server: '%s' opendj-server-legacy/src/test/java/org/opends/server/DirectoryServerTestCase.java
@@ -13,6 +13,7 @@ * * Copyright 2006-2008 Sun Microsystems, Inc. * Portions Copyright 2013-2015 ForgeRock AS. * Portions Copyright 2025 3A Systems LLC. */ package org.opends.server; @@ -48,7 +49,7 @@ TestCaseUtils.suppressOutput(); } @AfterSuite @AfterSuite(alwaysRun = true) public final void shutdownServer() { TestCaseUtils.shutdownServer(LocalizableMessage.raw("The current test suite has finished.")); TestCaseUtils.unsupressOutput(); opendj-server-legacy/src/test/java/org/opends/server/TestCaseUtils.java
@@ -45,11 +45,12 @@ import java.io.OutputStream; import java.io.PrintStream; import java.io.StringReader; import java.lang.management.LockInfo; import java.lang.management.ManagementFactory; import java.lang.management.MonitorInfo; import java.lang.management.ThreadInfo; import java.lang.management.ThreadMXBean; import java.net.BindException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; @@ -542,6 +543,9 @@ ErrorLogger.getInstance().addLogPublisher( (ErrorLogPublisher) getServerStartupTextErrorPublisher(ERROR_TEXT_WRITER)); } public static void setupTrace() { DebugLogger.getInstance().addPublisherIfRequired(DEBUG_TEXT_WRITER); } @@ -742,11 +746,20 @@ { for (; port > 1024;) { ServerSocket res=null; try { return bindPort(port--); res=bindPort(port--); return res; } catch (BindException e){} catch (BindException e){ if (res!=null) { try { res.close(); } catch (IOException ex) {} } res=null; } } throw new BindException("Unable to bind to a free port"); } @@ -1927,20 +1940,71 @@ public static String generateThreadDump() { final StringBuilder dump = new StringBuilder(); final ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); final ThreadInfo[] threadInfos = threadMXBean.getThreadInfo(threadMXBean.getAllThreadIds(), 100); ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(true, true); for (ThreadInfo threadInfo : threadInfos) { dump.append('"'); dump.append(threadInfo.getThreadName()); dump.append("\" "); final Thread.State state = threadInfo.getThreadState(); dump.append("\n java.lang.Thread.State: "); dump.append(state); final StackTraceElement[] stackTraceElements = threadInfo.getStackTrace(); for (final StackTraceElement stackTraceElement : stackTraceElements) { dump.append("\n at "); dump.append(stackTraceElement); dump.append("\"" + threadInfo.getThreadName() + "\"" + (threadInfo.isDaemon() ? " daemon" : "") + " prio=" + threadInfo.getPriority() + " Id=" + threadInfo.getThreadId() + " " + threadInfo.getThreadState()); if (threadInfo.getLockName() != null) { dump.append(" on " + threadInfo.getLockName()); } if (threadInfo.getLockOwnerName() != null) { dump.append(" owned by \"" + threadInfo.getLockOwnerName() + "\" Id=" + threadInfo.getLockOwnerId()); } if (threadInfo.isSuspended()) { dump.append(" (suspended)"); } if (threadInfo.isInNative()) { dump.append(" (in native)"); } dump.append('\n'); StackTraceElement[] stackTrace = threadInfo.getStackTrace(); int i = 0; for (; i < stackTrace.length; i++) { StackTraceElement ste = stackTrace[i]; dump.append("\tat " + ste.toString()); dump.append('\n'); if (i == 0 && threadInfo.getLockInfo() != null) { Thread.State ts = threadInfo.getThreadState(); switch (ts) { case BLOCKED: dump.append("\t- blocked on " + threadInfo.getLockInfo()); dump.append('\n'); break; case WAITING: case TIMED_WAITING: dump.append("\t- waiting on " + threadInfo.getLockInfo()); dump.append('\n'); break; default: } } dump.append("\n\n"); for (MonitorInfo mi : threadInfo.getLockedMonitors()) { if (mi.getLockedStackDepth() == i) { dump.append("\t- locked " + mi); dump.append('\n'); } } } if (i < stackTrace.length) { dump.append("\t..."); dump.append('\n'); } LockInfo[] locks = threadInfo.getLockedSynchronizers(); if (locks.length > 0) { dump.append("\n\tNumber of locked synchronizers = " + locks.length); dump.append('\n'); for (LockInfo li : locks) { dump.append("\t- " + li); dump.append('\n'); } } dump.append('\n'); } return dump.toString(); } opendj-server-legacy/src/test/java/org/opends/server/TestListener.java
@@ -13,7 +13,7 @@ * * Copyright 2008 Sun Microsystems, Inc. * Portions Copyright 2013-2016 ForgeRock AS. * Portions Copyright 2023 3A Systems, LLC. * Portions Copyright 2023-2025 3A Systems, LLC. */ package org.opends.server; @@ -155,11 +155,26 @@ @Override public void onStart(ITestContext testContext) { super.onStart(testContext); if (testContext.getAllTestMethods().length>0) { TestCaseUtils.setTestName(testContext.getAllTestMethods()[0].getInstance().getClass().getName()); } long testTimeout = 0; try { testTimeout = Long.parseLong(System.getProperty("org.opends.test.timeout", "0")); } catch (NumberFormatException ignored) {} for (int i = 0; i < testContext.getAllTestMethods().length; i++) { testContext.getAllTestMethods()[i].setTimeOut(testTimeout); } if(System.getProperty("org.opends.test.trace.pattern") != null && testContext.getAllTestMethods().length > 0) { String tracePattern = System.getProperty("org.opends.test.trace.pattern"); if(testContext.getAllTestMethods()[0].getInstance().getClass().getName().matches(tracePattern)) { System.setProperty("org.opends.server.debug.target.1", "_global:enabled"); TestCaseUtils.setupTrace(); } } // Delete the previous report if it's there. new File(testContext.getOutputDirectory(), REPORT_FILE_NAME).delete(); } @@ -179,6 +194,7 @@ originalSystemErr.println("check state: "+paths.unitRoot); } } System.clearProperty("org.opends.server.debug.target.1"); } @Override @@ -335,6 +351,7 @@ @Override public void onTestStart(ITestResult tr) { super.onTestStart(tr); originalSystemOut.println("-- Executing test: " + tr.getMethod()); enforceTestClassTypeAndAnnotations(tr); checkForInterleavedBetweenClasses(tr); @@ -358,6 +375,11 @@ public void onTestFailure(ITestResult tr) { super.onTestFailure(tr); reportTestFailed(tr); printThreadDump(); } private void printThreadDump() { originalSystemErr.println(TestCaseUtils.generateThreadDump()); } private void reportTestFailed(ITestResult tr) opendj-server-legacy/src/test/java/org/opends/server/replication/GenerationIdTest.java
@@ -921,6 +921,8 @@ replServer3 = createReplicationServer(replServerId3, true, testCase); connectServer1ToReplServer(replServer1); Thread.sleep(2000); //wait for all RS handshakes to complete debugInfo("Expect genId are set in all replServers."); waitForStableGenerationId(EMPTY_DN_GENID); disconnectFromReplServer(replServer1); opendj-server-legacy/src/test/java/org/opends/server/replication/SchemaReplicationTest.java
@@ -13,6 +13,7 @@ * * Copyright 2008-2010 Sun Microsystems, Inc. * Portions Copyright 2012-2016 ForgeRock AS. * Portions Copyright 2025 3A Systems LLC. */ package org.opends.server.replication; @@ -234,6 +235,7 @@ @Override public void call() throws Exception { assertTrue(schemaFile.exists()); String fileStr = readAsString(schemaFile); assertTrue(fileStr.contains(stateStr), "The Schema persistentState (CSN:" + stateStr + ") has not been saved to " + schemaFile + " : " + fileStr); opendj-server-legacy/src/test/java/org/opends/server/replication/service/FakeReplicationDomain.java
@@ -13,6 +13,7 @@ * * Copyright 2008-2010 Sun Microsystems, Inc. * Portions Copyright 2013-2016 ForgeRock AS. * Portions Copyright 2025 3A Systems LLC. */ package org.opends.server.replication.service; @@ -42,8 +43,8 @@ private BlockingQueue<UpdateMsg> queue; /** A string that will be exported should exportBackend be called. */ private String exportString; /** A StringBuilder that will be used to build a new String should the import be called. */ private StringBuilder importString; /** A StringBuffer that will be used to build a new String should the import be called. */ private StringBuffer importString; private int exportedEntryCount; private FakeReplicationDomain(DN baseDN, int serverID, @@ -82,7 +83,7 @@ FakeReplicationDomain(DN baseDN, int serverID, SortedSet<String> replicationServers, long heartbeatInterval, String exportString, StringBuilder importString, int exportedEntryCount) String exportString, StringBuffer importString, int exportedEntryCount) throws ConfigException { this(baseDN, serverID, replicationServers, 100, heartbeatInterval, 1); opendj-server-legacy/src/test/java/org/opends/server/replication/service/ReplicationDomainTest.java
@@ -17,7 +17,10 @@ */ package org.opends.server.replication.service; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.SECONDS; import static org.opends.messages.ReplicationMessages.*; import static org.opends.server.TestCaseUtils.generateThreadDump; import static org.opends.server.util.CollectionUtils.*; import static org.testng.Assert.*; @@ -28,6 +31,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.i18n.slf4j.LocalizedLogger; import org.opends.server.TestCaseUtils; import org.opends.server.backends.task.Task; @@ -42,6 +46,7 @@ import org.opends.server.replication.service.ReplicationDomain.ImportExportContext; import org.forgerock.opendj.ldap.DN; import org.opends.server.types.DirectoryException; import org.opends.server.util.TestTimer; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -302,8 +307,7 @@ new ReplServerFakeConfiguration(replicationPort, dirName, 0, serverId, 0, windowSize, replServers)); } private void disable(ReplicationDomain... domains) { private void disable(ReplicationDomain... domains) throws InterruptedException { for (ReplicationDomain domain : domains) { if (domain != null) @@ -348,7 +352,7 @@ domain1 = new FakeReplicationDomain( testService, serverId1, servers, 0, exportedData, null, ENTRYCOUNT); StringBuilder importedData = new StringBuilder(); StringBuffer importedData = new StringBuffer(); domain2 = new FakeReplicationDomain( testService, serverId2, servers, 0, null, importedData, 0); @@ -419,10 +423,27 @@ domain1 = new FakeReplicationDomain( testService, 1, servers1, 0, exportedData, null, ENTRYCOUNT); StringBuilder importedData = new StringBuilder(); StringBuffer importedData = new StringBuffer(); domain2 = new FakeReplicationDomain( testService, 2, servers2, 0, null, importedData, 0); //wait for domains topology initialization { TestTimer timer = new TestTimer.Builder() .maxSleep(30, SECONDS) .sleepTimes(100, MILLISECONDS) .toTimer(); final FakeReplicationDomain finalDomain1 = domain1; final FakeReplicationDomain finalDomain2 = domain2; timer.repeatUntilSuccess(() -> { assertFalse(finalDomain1.getReplicaInfos().isEmpty()); assertEquals(2, finalDomain1.getRsInfos().size()); assertFalse(finalDomain2.getReplicaInfos().isEmpty()); assertEquals(2, finalDomain2.getRsInfos().size()); }); } domain2.initializeFromRemote(1, NO_INIT_TASK); waitEndExport(exportedData, importedData); @@ -445,18 +466,22 @@ return sb.toString(); } private void waitEndExport(String exportedData, StringBuilder importedData) throws Exception private void waitEndExport(String exportedData, StringBuffer importedData) throws Exception { int count = 0; while (importedData.length() < exportedData.length() && count < 500*5) { if(count % 100 == 0) { //capture thread dump on start and every 10 seconds logger.debug(LocalizableMessage.raw("waitEndExport: thread dump on count=" + count)); logger.debug(LocalizableMessage.raw(generateThreadDump())); } count ++; Thread.sleep(100); } } private void assertExportSucessful(ReplicationDomain domain1, ReplicationDomain domain2, String exportedData, StringBuilder importedData) ReplicationDomain domain2, String exportedData, StringBuffer importedData) { assertEquals(getLeftEntryCount(domain2), 0, "Wrong LeftEntryCount for export"); assertEquals(getLeftEntryCount(domain1), 0, "Wrong LeftEntryCount for import"); opendj-server-legacy/src/test/java/org/opends/server/util/TestTimer.java
@@ -12,13 +12,17 @@ * information: "Portions Copyright [year] [name of copyright owner]". * * Copyright 2015-2016 ForgeRock AS. * Portions Copyright 2025 3A Systems LLC. */ package org.opends.server.util; import java.util.concurrent.Callable; import java.util.concurrent.TimeUnit; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.i18n.slf4j.LocalizedLogger; import org.forgerock.util.Reject; import org.opends.server.TestCaseUtils; /** * Timer useful for testing: it helps to write loops that repeatedly runs code until some condition @@ -153,6 +157,7 @@ /** A {@link TestTimer} that sleeps in steps and sleeps at maximum {@code nbSteps * sleepTimes}. */ public static class SteppingTimer implements TestTimer { private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); private final long sleepTime; private final long totalNbSteps; private long nbStepsRemaining; @@ -204,6 +209,7 @@ { if (hasTimedOutNoSleep()) { logger.info(LocalizableMessage.raw("failed to wait for" + callable + "\n" + TestCaseUtils.generateThreadDump())); throw e; } } pom.xml
@@ -38,6 +38,9 @@ <commons.version>3.0.0-SNAPSHOT</commons.version> <freemarker.version>2.3.34</freemarker.version> <metrics-core.version>4.2.30</metrics-core.version> <bc.fips.version>2.1.1</bc.fips.version> <bctls.fips.version>2.1.20</bctls.fips.version> <bcpkix.fips.version>2.1.9</bcpkix.fips.version> <maven.compiler.target>11</maven.compiler.target> <maven.compiler.source>11</maven.compiler.source> <!-- OSGi bundles properties --> @@ -219,6 +222,22 @@ <artifactId>opendj-server-legacy</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bc-fips</artifactId> <version>${bc.fips.version}</version> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bctls-fips</artifactId> <version>${bctls.fips.version}</version> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpkix-fips</artifactId> <version>${bcpkix.fips.version}</version> </dependency> </dependencies> </dependencyManagement> @@ -687,7 +706,7 @@ <jdk>[17,)</jdk> </activation> <properties> <argLine>-Xmx512m --add-exports java.base/sun.security.x509=ALL-UNNAMED --add-exports java.base/sun.security.tools.keytool=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.util.regex=ALL-UNNAMED --add-opens java.base/java.security=ALL-UNNAMED --add-opens java.naming/javax.naming.spi=ALL-UNNAMED</argLine> <argLine>-Xmx512m --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.util.regex=ALL-UNNAMED --add-opens java.base/java.security=ALL-UNNAMED --add-opens java.naming/javax.naming.spi=ALL-UNNAMED</argLine> <maven.cargo.containerId>tomcat11x</maven.cargo.containerId> </properties> </profile>