RandomValuePropertySource Class — spring-boot Architecture
Architecture documentation for the RandomValuePropertySource class in RandomValuePropertySource.java from the spring-boot codebase.
Entity Profile
Relationship Graph
Source Code
core/spring-boot/src/main/java/org/springframework/boot/env/RandomValuePropertySource.java lines 66–220
public class RandomValuePropertySource extends PropertySource<Random> {
/**
* Name of the random {@link PropertySource}.
*/
public static final String RANDOM_PROPERTY_SOURCE_NAME = "random";
private static final String PREFIX = "random.";
private static final Log logger = LogFactory.getLog(RandomValuePropertySource.class);
public RandomValuePropertySource() {
this(RANDOM_PROPERTY_SOURCE_NAME);
}
public RandomValuePropertySource(String name) {
super(name, new Random());
}
@Override
public @Nullable Object getProperty(String name) {
if (!name.startsWith(PREFIX)) {
return null;
}
logger.trace(LogMessage.format("Generating random property for '%s'", name));
return getRandomValue(name.substring(PREFIX.length()));
}
private Object getRandomValue(String type) {
if (type.equals("int")) {
return getSource().nextInt();
}
if (type.equals("long")) {
return getSource().nextLong();
}
String range = getRange(type, "int");
if (range != null) {
return getNextIntInRange(Range.of(range, Integer::parseInt));
}
range = getRange(type, "long");
if (range != null) {
return getNextLongInRange(Range.of(range, Long::parseLong));
}
if (type.equals("uuid")) {
return UUID.randomUUID().toString();
}
return getRandomBytes();
}
private @Nullable String getRange(String type, String prefix) {
if (type.startsWith(prefix)) {
int startIndex = prefix.length() + 1;
if (type.length() > startIndex) {
return type.substring(startIndex, type.length() - 1);
}
}
return null;
}
private int getNextIntInRange(Range<Integer> range) {
OptionalInt first = getSource().ints(1, range.getMin(), range.getMax()).findFirst();
assertPresent(first.isPresent(), range);
return first.getAsInt();
}
private long getNextLongInRange(Range<Long> range) {
OptionalLong first = getSource().longs(1, range.getMin(), range.getMax()).findFirst();
assertPresent(first.isPresent(), range);
return first.getAsLong();
}
private void assertPresent(boolean present, Range<?> range) {
Assert.state(present, () -> "Could not get random number for range '" + range + "'");
}
private Object getRandomBytes() {
byte[] bytes = new byte[16];
getSource().nextBytes(bytes);
return HexFormat.of().withLowerCase().formatHex(bytes);
}
/**
* Add a {@link RandomValuePropertySource} to the given {@link Environment}.
* @param environment the environment to add the random property source to
*/
public static void addToEnvironment(ConfigurableEnvironment environment) {
addToEnvironment(environment, logger);
}
/**
* Add a {@link RandomValuePropertySource} to the given {@link Environment}.
* @param environment the environment to add the random property source to
* @param logger logger used for debug and trace information
* @since 4.0.0
*/
public static void addToEnvironment(ConfigurableEnvironment environment, Log logger) {
MutablePropertySources sources = environment.getPropertySources();
PropertySource<?> existing = sources.get(RANDOM_PROPERTY_SOURCE_NAME);
if (existing != null) {
logger.trace("RandomValuePropertySource already present");
return;
}
RandomValuePropertySource randomSource = new RandomValuePropertySource(RANDOM_PROPERTY_SOURCE_NAME);
if (sources.get(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME) != null) {
sources.addAfter(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, randomSource);
}
else {
sources.addLast(randomSource);
}
logger.trace("RandomValuePropertySource add to Environment");
}
static final class Range<T extends Number> {
private final String value;
private final T min;
private final T max;
private Range(String value, T min, T max) {
this.value = value;
this.min = min;
this.max = max;
}
T getMin() {
return this.min;
}
T getMax() {
return this.max;
}
@Override
public String toString() {
return this.value;
}
static <T extends Number & Comparable<T>> Range<T> of(String value, Function<String, T> parse) {
T zero = parse.apply("0");
String[] tokens = StringUtils.commaDelimitedListToStringArray(value);
T min = parse.apply(tokens[0]);
if (tokens.length == 1) {
Assert.state(min.compareTo(zero) > 0, "Bound must be positive.");
return new Range<>(value, zero, min);
}
T max = parse.apply(tokens[1]);
Assert.state(min.compareTo(max) < 0, "Lower bound must be less than upper bound.");
return new Range<>(value, min, max);
}
}
}
Domain
Source
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free