001/*
002 * Copyright 2022-2026 Revetware LLC.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package com.soklet;
018
019import org.jspecify.annotations.NonNull;
020
021import static java.util.Objects.requireNonNull;
022
023/**
024 * Contract for generating {@link Request} identifiers of a particular type (for example, sequential {@link Long} values, random {@link java.util.UUID}s, etc.)
025 * <p>
026 * Useful for incorporating request data in nonlocal deployment environments (e.g. a tracing header like <a href="https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-request-tracing.html" target="_blank">{@code X-Amzn-Trace-Id}</a>).
027 * <p>
028 * Implementations may or may not guarantee uniqueness, ordering, or repeatability of generated identifiers. Callers should not assume any such guarantees unless documented by the implementation.
029 * <p>
030 * Standard threadsafe implementations can be acquired via these factory methods:
031 * <ul>
032 *   <li>{@link #defaultInstance()}</li>
033 *   <li>{@link #fromPrefix(String)}</li>
034 * </ul>
035 *
036 * @param <T> the type of identifier produced
037 * @author <a href="https://www.revetkn.com">Mark Allen</a>
038 */
039@FunctionalInterface
040public interface IdGenerator<T> {
041        /**
042         * Generates an identifier for the given {@link Request}.
043         * <p>
044         * Implementations may choose different strategies (sequential, random, host-based, etc.)
045         * and are not required to guarantee uniqueness unless explicitly documented.
046         * <p>
047         * Implementations may choose to incorporate request data (e.g. a tracing header like {@code X-Amzn-Trace-Id}).
048         *
049         * @param request the request for which an identifier is being generated
050         * @return the generated identifier (never {@code null})
051         */
052        @NonNull
053        T generateId(@NonNull Request request);
054
055        /**
056         * Acquires a threadsafe {@link IdGenerator} with a best-effort local IP prefix.
057         * <p>
058         * This method is guaranteed to return a new instance.
059         *
060         * @return an {@code IdGenerator} with default settings
061         */
062        @NonNull
063        static IdGenerator<String> defaultInstance() {
064                return DefaultIdGenerator.defaultInstance();
065        }
066
067
068        /**
069         * Acquires a threadsafe {@link IdGenerator} with the given prefix.
070         * <p>
071         * This method is guaranteed to return a new instance.
072         *
073         * @param prefix a string to prepend to the generated numeric ID
074         * @return an {@code IdGenerator} configured with the given prefix
075         */
076        @NonNull
077        static IdGenerator<String> fromPrefix(@NonNull String prefix) {
078                requireNonNull(prefix);
079                return DefaultIdGenerator.fromPrefix(prefix);
080        }
081}