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}