| | |
| | | * information: "Portions Copyright [year] [name of copyright owner]". |
| | | * |
| | | * Copyright 2013-2014 Manuel Gaupp |
| | | * Portions Copyright 2026 3A Systems, LLC. |
| | | */ |
| | | package org.forgerock.opendj.ldap; |
| | | |
| | |
| | | WARN_GSER_NO_VALID_INTEGER.get(gserValue.substring(pos, length)); |
| | | throw DecodeException.error(msg); |
| | | } |
| | | return Integer.valueOf(next(GSER_INTEGER)).intValue(); |
| | | final String integer = next(GSER_INTEGER); |
| | | try { |
| | | return Integer.parseInt(integer); |
| | | } catch (final NumberFormatException e) { |
| | | // The value matches the integer pattern but does not fit in an int. |
| | | throw DecodeException.error(WARN_GSER_NO_VALID_INTEGER.get(integer), e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | * information: "Portions Copyright [year] [name of copyright owner]". |
| | | * |
| | | * Copyright 2013-2016 ForgeRock AS. |
| | | * Portions Copyright 2026 3A Systems, LLC. |
| | | */ |
| | | package org.forgerock.opendj.ldap; |
| | | |
| | |
| | | } |
| | | |
| | | final int pageSize = pagedResults != null ? pagedResults.getSize() : 0; |
| | | final int offset = (pagedResults != null && !pagedResults.getCookie().isEmpty()) |
| | | ? Integer.valueOf(pagedResults.getCookie().toString()) : 0; |
| | | final int offset = decodePagedResultsCookie(pagedResults); |
| | | int numberOfResults = 0; |
| | | int position = 0; |
| | | for (final Entry entry : subtree.values()) { |
| | |
| | | resultHandler.handleResult(result); |
| | | } |
| | | |
| | | /** |
| | | * Returns the offset of the first entry to be returned, as encoded by this backend in the cookie |
| | | * of the previous page. |
| | | * |
| | | * @param pagedResults |
| | | * The simple paged results control, if present. |
| | | * @return The offset of the first entry to be returned. |
| | | * @throws LdapException |
| | | * If the cookie was not created by this backend. |
| | | */ |
| | | private static int decodePagedResultsCookie(final SimplePagedResultsControl pagedResults) throws LdapException { |
| | | if (pagedResults == null || pagedResults.getCookie().isEmpty()) { |
| | | return 0; |
| | | } |
| | | final String cookie = pagedResults.getCookie().toString(); |
| | | try { |
| | | return Integer.parseInt(cookie); |
| | | } catch (final NumberFormatException e) { |
| | | throw newLdapException(newResult(ResultCode.PROTOCOL_ERROR) |
| | | .setDiagnosticMessage( |
| | | "Invalid paged results cookie: " + pagedResults.getCookie().toHexString()) |
| | | .setCause(e)); |
| | | } |
| | | } |
| | | |
| | | private <R extends Result> R addResultControls(final Request request, final Entry before, |
| | | final Entry after, final R result) throws LdapException { |
| | | try { |
| | |
| | | * information: "Portions Copyright [year] [name of copyright owner]". |
| | | * |
| | | * Copyright 2013-2014 Manuel Gaupp |
| | | * Portions Copyright 2026 3A Systems, LLC. |
| | | */ |
| | | package org.forgerock.opendj.ldap; |
| | | |
| | |
| | | {"", false}, |
| | | {"0xFF", false}, |
| | | {"NULL", false}, |
| | | {"Not a Number", false} |
| | | {"Not a Number", false}, |
| | | {"2147483648", false}, |
| | | {"99999999999", false} |
| | | }; |
| | | } |
| | | |
| | |
| | | * information: "Portions Copyright [year] [name of copyright owner]". |
| | | * |
| | | * Copyright 2013-2016 ForgeRock AS. |
| | | * Portions Copyright 2026 3A Systems, LLC. |
| | | */ |
| | | package org.forgerock.opendj.ldap; |
| | | |
| | |
| | | } |
| | | |
| | | @Test |
| | | public void testSearchPagedResultsForgedCookie() throws Exception { |
| | | final Connection connection = getConnection(); |
| | | final SearchRequest search = |
| | | Requests.newSearchRequest("ou=people,dc=example,dc=com", SearchScope.WHOLE_SUBTREE, |
| | | "(uid=*)"); |
| | | search.addControl( |
| | | SimplePagedResultsControl.newControl(true, 2, ByteString.valueOfUtf8("forged"))); |
| | | try { |
| | | connection.search(search, new ArrayList<SearchResultEntry>()); |
| | | TestCaseUtils.failWasExpected(LdapException.class); |
| | | } catch (LdapException e) { |
| | | assertThat(e.getResult().getResultCode()).isEqualTo(ResultCode.PROTOCOL_ERROR); |
| | | } |
| | | } |
| | | |
| | | @Test |
| | | public void testSimpleBind() throws Exception { |
| | | final Connection connection = getConnection(); |
| | | connection.bind("uid=test1,ou=people,dc=example,dc=com", "password".toCharArray()); |
| | |
| | | import java.awt.Font; |
| | | import java.lang.reflect.InvocationTargetException; |
| | | import java.util.ArrayList; |
| | | import java.util.Arrays; |
| | | import java.util.Collection; |
| | | import java.util.Enumeration; |
| | | import java.util.Set; |
| | |
| | | sb.append(getURL()); |
| | | if (getReferral() != null) { |
| | | sb.append(" -> "); |
| | | sb.append(getReferral()); |
| | | sb.append(Arrays.toString(getReferral())); |
| | | } |
| | | toString = sb.toString(); |
| | | } |
| | |
| | | { |
| | | // == exact CSN |
| | | // validate provided CSN is correct |
| | | new CSN(filter.getAssertionValue().toString()); |
| | | validateCSN(filter.getAssertionValue()); |
| | | } |
| | | else if (filter.getFilterType() == FilterType.AND) |
| | | { |
| | |
| | | } |
| | | } |
| | | |
| | | private static void validateCSN(final ByteString assertionValue) |
| | | throws DirectoryException |
| | | { |
| | | try |
| | | { |
| | | new CSN(assertionValue.toString()); |
| | | } |
| | | catch (IllegalArgumentException e) |
| | | { |
| | | throw new DirectoryException(ResultCode.INVALID_ATTRIBUTE_SYNTAX, |
| | | LocalizableMessage.raw("Could not convert value '%s' to a CSN", assertionValue), e); |
| | | } |
| | | } |
| | | |
| | | private boolean matches(SearchFilter filter, FilterType filterType, String primaryName) |
| | | { |
| | | return filter.getFilterType() == filterType |
| | |
| | | * Header, with the fields enclosed by brackets [] replaced by your own identifying |
| | | * information: "Portions Copyright [year] [name of copyright owner]". |
| | | * |
| | | * Copyright 2024-2025 3A Systems, LLC. |
| | | * Copyright 2024-2026 3A Systems, LLC. |
| | | */ |
| | | package org.opends.server.backends.jdbc; |
| | | |
| | | import com.github.benmanes.caffeine.cache.Caffeine; |
| | | import com.github.benmanes.caffeine.cache.LoadingCache; |
| | | import com.github.benmanes.caffeine.cache.RemovalCause; |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | import org.forgerock.i18n.slf4j.LocalizedLogger; |
| | | |
| | | import java.sql.*; |
| | | import java.time.Duration; |
| | |
| | | import java.util.concurrent.*; |
| | | |
| | | public class CachedConnection implements Connection { |
| | | private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); |
| | | |
| | | static final String TTL_PROPERTY = "org.openidentityplatform.opendj.jdbc.ttl"; |
| | | static final long DEFAULT_TTL_MS = 15000; |
| | | |
| | | final Connection parent; |
| | | |
| | | static LoadingCache<String, BlockingQueue<CachedConnection>> cached = Caffeine.newBuilder() |
| | | .expireAfterAccess(Duration.ofMillis(Long.parseLong(System.getProperty("org.openidentityplatform.opendj.jdbc.ttl","15000")))) |
| | | .expireAfterAccess(Duration.ofMillis(getCacheTtlMillis())) |
| | | .removalListener((String key, BlockingQueue<CachedConnection> value, RemovalCause cause) -> { |
| | | for (CachedConnection con : value) { |
| | | try { |
| | |
| | | }) |
| | | .build(conStr -> new LinkedBlockingQueue<>()); |
| | | |
| | | /** |
| | | * Returns the time after which an idle pooled connection is closed, as configured by the |
| | | * {@value #TTL_PROPERTY} system property. An invalid value is ignored in favor of the default. |
| | | */ |
| | | private static long getCacheTtlMillis() { |
| | | final String ttl = System.getProperty(TTL_PROPERTY); |
| | | if (ttl != null) { |
| | | try { |
| | | final long millis = Long.parseLong(ttl.trim()); |
| | | if (millis >= 0) { |
| | | return millis; |
| | | } |
| | | } catch (NumberFormatException ignored) { |
| | | } |
| | | logger.warn(LocalizableMessage.raw("Ignoring invalid value \"%s\" of the %s property, using %d ms", |
| | | ttl, TTL_PROPERTY, DEFAULT_TTL_MS)); |
| | | } |
| | | return DEFAULT_TTL_MS; |
| | | } |
| | | |
| | | final String connectionString; |
| | | public CachedConnection(String connectionString, Connection parent) { |
| | | this.connectionString = connectionString; |
| | |
| | | * information: "Portions Copyright [year] [name of copyright owner]". |
| | | * |
| | | * Copyright 2015 ForgeRock AS. |
| | | * Portions Copyright 2026 3A Systems, LLC. |
| | | */ |
| | | package org.opends.server.backends.pluggable; |
| | | |
| | |
| | | @Override |
| | | public ByteString generateKey(String data) |
| | | { |
| | | return new EntryID(Long.parseLong(data)).toByteString(); |
| | | return new EntryID(ID2Entry.parseEntryID(data)).toByteString(); |
| | | } |
| | | |
| | | /** |
| | |
| | | import java.util.zip.InflaterInputStream; |
| | | import java.util.zip.InflaterOutputStream; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | import org.forgerock.i18n.LocalizedIllegalArgumentException; |
| | | import org.forgerock.i18n.slf4j.LocalizedLogger; |
| | | import org.forgerock.opendj.io.ASN1; |
| | | import org.forgerock.opendj.io.ASN1Reader; |
| | |
| | | @Override |
| | | public ByteString generateKey(String data) |
| | | { |
| | | EntryID entryID = new EntryID(Long.parseLong(data)); |
| | | return entryID.toByteString(); |
| | | return new EntryID(parseEntryID(data)).toByteString(); |
| | | } |
| | | |
| | | /** |
| | | * Returns the entry ID held by the provided string. |
| | | * |
| | | * @param data |
| | | * The string representation of an entry ID |
| | | * @return the parsed entry ID |
| | | * @throws LocalizedIllegalArgumentException |
| | | * If the provided string does not hold an entry ID |
| | | */ |
| | | static long parseEntryID(String data) |
| | | { |
| | | try |
| | | { |
| | | return Long.parseLong(data); |
| | | } |
| | | catch (NumberFormatException e) |
| | | { |
| | | throw new LocalizedIllegalArgumentException(LocalizableMessage.raw("Invalid entry ID: \"%s\"", data)); |
| | | } |
| | | } |
| | | } |
| | |
| | | * information: "Portions Copyright [year] [name of copyright owner]". |
| | | * |
| | | * Copyright 2015-2016 ForgeRock AS. |
| | | * Portions Copyright 2026 3A Systems, LLC. |
| | | */ |
| | | package org.opends.server.backends.pluggable; |
| | | |
| | |
| | | { |
| | | if (logger.isTraceEnabled()) |
| | | { |
| | | logger.trace("Skipping entry %s because reading" + "its attributes failed.", entryDN); |
| | | logger.trace("Skipping entry %s because reading its attributes failed.", entryDN); |
| | | } |
| | | logToSkipWriter(lines, ERR_LDIF_READ_ATTR_SKIP.get(entryDN, e.getMessage())); |
| | | return null; |
| | |
| | | { |
| | | if (logger.isTraceEnabled()) |
| | | { |
| | | logger.trace("Unable to generate a new password for user %s because no password generator has been defined" + |
| | | "in the associated password policy.", userDNString); |
| | | logger.trace("Unable to generate a new password for user %s because no password generator has been defined " |
| | | + "in the associated password policy.", userDNString); |
| | | } |
| | | |
| | | return null; |
| | |
| | | * |
| | | * Copyright 2013-2014 Manuel Gaupp |
| | | * Portions Copyright 2014-2016 ForgeRock AS. |
| | | * Portions Copyright 2026 3A Systems, LLC. |
| | | */ |
| | | package org.opends.server.protocols.asn1; |
| | | |
| | |
| | | .substring(pos,length)); |
| | | throw new GSERException(msg); |
| | | } |
| | | return Integer.valueOf(next(GSER_INTEGER)).intValue(); |
| | | final String integer = next(GSER_INTEGER); |
| | | try |
| | | { |
| | | return Integer.parseInt(integer); |
| | | } |
| | | catch (NumberFormatException e) |
| | | { |
| | | // The value matches the integer pattern but does not fit in an int. |
| | | throw new GSERException(ERR_GSER_NO_VALID_INTEGER.get(integer), e); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | import org.forgerock.i18n.LocalizedIllegalArgumentException; |
| | | import org.forgerock.opendj.ldap.ByteSequence; |
| | | import org.forgerock.opendj.ldap.ByteSequenceReader; |
| | | import org.forgerock.opendj.ldap.ByteString; |
| | |
| | | * @param s |
| | | * The string to be parsed. |
| | | * @return The parsed CSN. |
| | | * @throws LocalizedIllegalArgumentException |
| | | * If the provided string is not a valid {@link #toString()} representation of a CSN |
| | | * @see #toString() |
| | | */ |
| | | public static CSN valueOf(String s) |
| | |
| | | * |
| | | * @param str |
| | | * the string from which to create a {@link CSN} |
| | | * @throws LocalizedIllegalArgumentException |
| | | * If the provided string is not a valid {@link #toString()} representation of a CSN |
| | | */ |
| | | public CSN(String str) |
| | | { |
| | | String temp = str.substring(0, 16); |
| | | timeStamp = Long.parseLong(temp, 16); |
| | | if (str == null || str.length() < STRING_ENCODING_LENGTH) |
| | | { |
| | | throw new LocalizedIllegalArgumentException(LocalizableMessage.raw("Invalid CSN: \"%s\"", str)); |
| | | } |
| | | |
| | | temp = str.substring(16, 20); |
| | | serverId = Integer.parseInt(temp, 16); |
| | | |
| | | temp = str.substring(20, 28); |
| | | seqnum = Integer.parseInt(temp, 16); |
| | | try |
| | | { |
| | | timeStamp = Long.parseLong(str.substring(0, 16), 16); |
| | | serverId = Integer.parseInt(str.substring(16, 20), 16); |
| | | seqnum = Integer.parseInt(str.substring(20, STRING_ENCODING_LENGTH), 16); |
| | | } |
| | | catch (NumberFormatException e) |
| | | { |
| | | throw new LocalizedIllegalArgumentException(LocalizableMessage.raw("Invalid CSN: \"%s\"", str)); |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | * information: "Portions Copyright [year] [name of copyright owner]". |
| | | * |
| | | * Copyright 2014-2016 ForgeRock AS. |
| | | * Portions Copyright 2026 3A Systems, LLC. |
| | | */ |
| | | package org.opends.server.replication.protocol; |
| | | |
| | |
| | | */ |
| | | public int nextIntUTF8() throws DataFormatException |
| | | { |
| | | return Integer.valueOf(nextString()); |
| | | final String s = nextString(); |
| | | try |
| | | { |
| | | return Integer.parseInt(s); |
| | | } |
| | | catch (NumberFormatException e) |
| | | { |
| | | throw new DataFormatException("Expected an int but read \"" + s + "\""); |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | public long nextLongUTF8() throws DataFormatException |
| | | { |
| | | return Long.valueOf(nextString()); |
| | | final String s = nextString(); |
| | | try |
| | | { |
| | | return Long.parseLong(s); |
| | | } |
| | | catch (NumberFormatException e) |
| | | { |
| | | throw new DataFormatException("Expected a long but read \"" + s + "\""); |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | { |
| | | return CSN.valueOf(nextString()); |
| | | } |
| | | catch (IndexOutOfBoundsException e) |
| | | catch (LocalizedIllegalArgumentException | IndexOutOfBoundsException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | } |
| | |
| | | * information: "Portions Copyright [year] [name of copyright owner]". |
| | | * |
| | | * Copyright 2014-2016 ForgeRock AS. |
| | | * Portions Copyright 2026 3A Systems, LLC. |
| | | */ |
| | | package org.opends.server.replication.server.changelog.file; |
| | | |
| | |
| | | |
| | | import net.jcip.annotations.Immutable; |
| | | |
| | | import org.forgerock.i18n.LocalizedIllegalArgumentException; |
| | | import org.forgerock.opendj.config.server.ConfigException; |
| | | import org.forgerock.opendj.ldap.ByteString; |
| | | import org.forgerock.opendj.ldap.ByteStringBuilder; |
| | |
| | | @Override |
| | | public CSN decodeKeyFromString(String key) throws ChangelogException |
| | | { |
| | | return new CSN(key); |
| | | try |
| | | { |
| | | return new CSN(key); |
| | | } |
| | | catch (LocalizedIllegalArgumentException e) |
| | | { |
| | | throw new ChangelogException( |
| | | ERR_CHANGELOG_UNABLE_TO_DECODE_KEY_FROM_STRING.get(key), e); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | |
| | | * information: "Portions Copyright [year] [name of copyright owner]". |
| | | * |
| | | * Copyright 2014-2016 ForgeRock AS. |
| | | * Portions Copyright 2026 3A Systems, LLC. |
| | | */ |
| | | package org.opends.server.replication.server.changelog.file; |
| | | |
| | |
| | | } |
| | | return new CSN(line); |
| | | } |
| | | catch(LocalizedIllegalArgumentException e) |
| | | { |
| | | throw new ChangelogException(ERR_CHANGELOG_INVALID_REPLICA_OFFLINE_STATE_FILE.get( |
| | | domainDN.toString(), offlineFile.getPath()), e); |
| | | } |
| | | catch(IOException e) |
| | | { |
| | | throw new ChangelogException(ERR_CHANGELOG_UNABLE_TO_READ_REPLICA_OFFLINE_STATE_FILE.get( |
| | |
| | | } |
| | | |
| | | /** Find the next domain id to use. This is the lowest integer that is higher than all existing ids. */ |
| | | private String findNextDomainId() |
| | | private String findNextDomainId() throws ChangelogException |
| | | { |
| | | int nextId = 1; |
| | | for (final String domainId : domains.values()) |
| | | { |
| | | final Integer id = Integer.valueOf(domainId); |
| | | final int id; |
| | | try |
| | | { |
| | | id = Integer.parseInt(domainId); |
| | | } |
| | | catch (NumberFormatException e) |
| | | { |
| | | throw new ChangelogException(ERR_CHANGELOG_UNABLE_TO_READ_DOMAIN_STATE_FILE.get( |
| | | new File(replicationRootPath, DOMAINS_STATE_FILENAME).getPath()), e); |
| | | } |
| | | if (nextId <= id) |
| | | { |
| | | nextId = id + 1; |
| | |
| | | ResultCode.INVALID_ATTRIBUTE_SYNTAX, message); |
| | | } |
| | | |
| | | double fractionValue = Double.parseDouble(fractionBuffer.toString()); |
| | | long additionalMilliseconds = Math.round(fractionValue * multiplier); |
| | | |
| | | try |
| | | { |
| | | double fractionValue = Double.parseDouble(fractionBuffer.toString()); |
| | | long additionalMilliseconds = Math.round(fractionValue * multiplier); |
| | | |
| | | GregorianCalendar calendar = new GregorianCalendar(); |
| | | calendar.setLenient(false); |
| | | calendar.setTimeZone(timeZone); |
| | |
| | | import java.net.NetworkInterface; |
| | | import java.net.SocketException; |
| | | import java.net.UnknownHostException; |
| | | import java.util.Arrays; |
| | | import java.util.Enumeration; |
| | | import java.util.HashSet; |
| | | import java.util.Locale; |
| | |
| | | else if (thisAddresses == null || otherAddresses == null) |
| | | { |
| | | if(logger.isTraceEnabled()) { |
| | | logger.trace("port and host does not match: " + this + "=" + thisAddresses + "; " + other + "=" + otherAddresses); |
| | | logger.trace("port and host does not match: " + this + "=" + Arrays.toString(thisAddresses) |
| | | + "; " + other + "=" + Arrays.toString(otherAddresses)); |
| | | } |
| | | // One local address and one non-local. |
| | | return false; |
| | |
| | | } |
| | | } |
| | | if(logger.isTraceEnabled()) { |
| | | logger.trace("port and host does not match: " + this + "=" + thisAddresses + "; " + other + "=" + otherAddresses); |
| | | logger.trace("port and host does not match: " + this + "=" + Arrays.toString(thisAddresses) |
| | | + "; " + other + "=" + Arrays.toString(otherAddresses)); |
| | | } |
| | | |
| | | return false; |
| | |
| | | NoSuchElementException |
| | | { |
| | | final String s = nextValue(INT, INT_TOKEN); |
| | | return Integer.parseInt(s); |
| | | try |
| | | { |
| | | return Integer.parseInt(s); |
| | | } |
| | | catch (NumberFormatException e) |
| | | { |
| | | // The token matches the integer pattern but is too big to fit in an int. |
| | | throw new InputMismatchException(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | import static java.util.Collections.*; |
| | | |
| | | import static org.opends.messages.BackendMessages.*; |
| | | import static org.opends.messages.CoreMessages.ERR_BACKUPINFO_CANNOT_DECODE; |
| | | import static org.opends.messages.UtilityMessages.*; |
| | | import static org.opends.server.util.ServerConstants.*; |
| | | import static org.opends.server.util.StaticUtils.*; |
| | |
| | | private final NewBackupParams newBackupParams; |
| | | private final CryptoEngine cryptoEngine; |
| | | |
| | | NewBackupArchive(String backendID, NewBackupParams backupParams, CryptoEngine crypt) |
| | | NewBackupArchive(String backendID, NewBackupParams backupParams, CryptoEngine crypt) throws DirectoryException |
| | | { |
| | | this.backendID = backendID; |
| | | this.newBackupParams = backupParams; |
| | |
| | | { |
| | | Map<String, String> properties = backupParams.baseBackupInfo.getBackupProperties(); |
| | | latestFileName = properties.get(PROPERTY_LAST_LOGFILE_NAME); |
| | | latestFileSize = Long.parseLong(properties.get(PROPERTY_LAST_LOGFILE_SIZE)); |
| | | latestFileSize = parseLatestFileSize(backupParams, properties.get(PROPERTY_LAST_LOGFILE_SIZE)); |
| | | } |
| | | archiveFilename = BACKUP_BASE_FILENAME + backendID + "-" + backupParams.backupID; |
| | | } |
| | | |
| | | /** Returns the size recorded by the base backup for the last file it archived. */ |
| | | private static long parseLatestFileSize(NewBackupParams backupParams, String size) throws DirectoryException |
| | | { |
| | | try |
| | | { |
| | | return Long.parseLong(size); |
| | | } |
| | | catch (NumberFormatException e) |
| | | { |
| | | throw new DirectoryException(DirectoryServer.getCoreConfigManager().getServerErrorResultCode(), |
| | | ERR_BACKUPINFO_CANNOT_DECODE.get(backupParams.backupDir.getPath(), |
| | | PROPERTY_LAST_LOGFILE_SIZE + ": " + size), e); |
| | | } |
| | | } |
| | | |
| | | String getArchiveFilename() |
| | | { |
| | | return archiveFilename; |
| | |
| | | { |
| | | final File baseFile = new File(basePath).getCanonicalFile(); |
| | | final File[] existingFiles = baseFile.getParentFile().listFiles(); |
| | | final Pattern pattern = Pattern.compile(baseFile + "\\d*"); |
| | | final Pattern pattern = Pattern.compile(Pattern.quote(baseFile.getPath()) + "\\d*"); |
| | | int highestNumber = 0; |
| | | for (File file : existingFiles) |
| | | { |
| | |
| | | if (pattern.matcher(name).matches()) |
| | | { |
| | | String numberAsString = name.substring(baseFile.getPath().length()); |
| | | int number = numberAsString.isEmpty() ? 0 : Integer.valueOf(numberAsString); |
| | | int number = parseSuffixNumber(numberAsString); |
| | | highestNumber = number > highestNumber ? number : highestNumber; |
| | | } |
| | | } |
| | | return highestNumber; |
| | | } |
| | | |
| | | /** |
| | | * Returns the number held by the provided file name suffix, or 0 if the suffix is empty or holds a |
| | | * number which is too big to have been generated by this class. |
| | | */ |
| | | private static int parseSuffixNumber(final String numberAsString) |
| | | { |
| | | if (numberAsString.isEmpty()) |
| | | { |
| | | return 0; |
| | | } |
| | | try |
| | | { |
| | | return Integer.parseInt(numberAsString); |
| | | } |
| | | catch (NumberFormatException e) |
| | | { |
| | | logger.trace("Ignoring file suffix \"%s\" which is too big to have been generated by this class", |
| | | numberAsString); |
| | | return 0; |
| | | } |
| | | } |
| | | } |
| | |
| | | * information: "Portions Copyright [year] [name of copyright owner]". |
| | | * |
| | | * Copyright 2016 ForgeRock AS. |
| | | * Portions Copyright 2026 3A Systems, LLC. |
| | | */ |
| | | package org.opends.server.util; |
| | | |
| | |
| | | public static int parseRuleID(String definition) throws DirectoryException |
| | | { |
| | | // Reuse code of parseOID, even though this is not an OID |
| | | return Integer.parseInt(parseOID(definition, ERR_PARSING_DIT_STRUCTURE_RULE_RULEID)); |
| | | final String ruleID = parseOID(definition, ERR_PARSING_DIT_STRUCTURE_RULE_RULEID); |
| | | try |
| | | { |
| | | return Integer.parseInt(ruleID); |
| | | } |
| | | catch (NumberFormatException e) |
| | | { |
| | | throw new DirectoryException(ResultCode.INVALID_ATTRIBUTE_SYNTAX, |
| | | ERR_PARSING_DIT_STRUCTURE_RULE_RULEID.get(definition), e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | import java.util.Iterator; |
| | | import java.util.List; |
| | | |
| | | import org.forgerock.i18n.LocalizedIllegalArgumentException; |
| | | import org.opends.server.replication.ReplicationTestCase; |
| | | import org.opends.server.util.TimeThread; |
| | | import org.testng.annotations.DataProvider; |
| | |
| | | "The encoding/decoding of CSN is not reversible for toString()"); |
| | | } |
| | | |
| | | /** Create invalid CSN string representations. */ |
| | | @DataProvider(name = "invalidCSNStrings") |
| | | public Object[][] createInvalidCSNStrings() |
| | | { |
| | | return new Object[][] { |
| | | { null }, |
| | | { "" }, |
| | | { "\u0001" }, // truncated CSN read from a legacy replication message |
| | | { "0000000000012abc002d0000007" }, // one character too short |
| | | { "000000000001zabc002d0000007b" }, // non hexadecimal timestamp |
| | | { "0000000000012abc002d0000007z" }, // non hexadecimal seqnum |
| | | }; |
| | | } |
| | | |
| | | /** Test constructor from an invalid String. */ |
| | | @Test(dataProvider = "invalidCSNStrings", |
| | | expectedExceptions = LocalizedIllegalArgumentException.class) |
| | | public void csnDecodeInvalidString(String str) throws Exception |
| | | { |
| | | new CSN(str); |
| | | } |
| | | |
| | | /** Create CSN. */ |
| | | @DataProvider(name = "createCSN") |
| | | public Object[][] createCSNData() |
| | |
| | | * information: "Portions Copyright [year] [name of copyright owner]". |
| | | * |
| | | * Copyright 2014-2016 ForgeRock AS. |
| | | * Portions Copyright 2026 3A Systems, LLC. |
| | | */ |
| | | package org.opends.server.replication.protocol; |
| | | |
| | |
| | | } |
| | | |
| | | @Test(expectedExceptions = DataFormatException.class) |
| | | public void testByteArrayScanner_nextCSNUTF8_throwsExceptionWhenNonHexCSN() throws Exception |
| | | { |
| | | final byte[] bytes = new ByteArrayBuilder().appendString("000000000001zabc002d0000007b").toByteArray(); |
| | | new ByteArrayScanner(bytes).nextCSNUTF8(); |
| | | } |
| | | |
| | | @Test(expectedExceptions = DataFormatException.class) |
| | | public void testByteArrayScanner_nextDN_throwsExceptionWhenInvalidDN() throws Exception |
| | | { |
| | | final byte[] bytes = new ByteArrayBuilder().appendString("this is not a valid DN").toByteArray(); |