All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.tbk.spring.testcontainer.bitcoind.config.BitcoindContainerProperties Maven / Gradle / Ivy

package org.tbk.spring.testcontainer.bitcoind.config;

import com.google.common.annotations.Beta;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import org.tbk.spring.testcontainer.core.AbstractContainerProperties;
import org.testcontainers.shaded.com.google.common.base.CharMatcher;

import java.util.List;
import java.util.Optional;

import static com.google.common.base.Preconditions.checkArgument;

/**
 * Properties for bitcoind testcontainer.
 *
 * 

Mainnet * JSON-RPC/REST: 8332 * P2P: 8333 * *

Testnet * Testnet JSON-RPC: 18332 * P2P: 18333 * *

Regtest * JSON-RPC/REST: 18443 (since 0.16+, otherwise 18332) * P2P: 18444 */ @Data @EqualsAndHashCode(callSuper = false) @ConfigurationProperties( prefix = "org.tbk.spring.testcontainer.bitcoind", ignoreUnknownFields = false ) public class BitcoindContainerProperties extends AbstractContainerProperties implements Validator { private static final int MAINNET_DEFAULT_RPC_PORT = 8332; private static final int MAINNET_DEFAULT_P2P_PORT = 8333; private static final int TESTNET_DEFAULT_RPC_PORT = 18332; private static final int TESTNET_DEFAULT_P2P_PORT = 18333; private static final int REGTEST_DEFAULT_RPC_PORT = 18443; private static final int REGTEST_DEFAULT_P2P_PORT = 18444; private static final Chain DEFAULT_CHAIN = Chain.regtest; @Beta private static final List reservedCommands = ImmutableList.builder() .add("rpcuser") .add("rpcpassword") .add("chain") .add("testnet") .add("regtest") .build(); public enum Chain { mainnet, testnet, regtest; } public BitcoindContainerProperties() { super(reservedCommands); } private Chain chain; /** * RPC username. */ private String rpcuser; /** * RPC password. */ private String rpcpassword; public Chain getChain() { return this.chain != null ? this.chain : DEFAULT_CHAIN; } public Optional getRpcuser() { return Optional.ofNullable(rpcuser); } public Optional getRpcpassword() { return Optional.ofNullable(rpcpassword); } public Optional getCommandValueByKey(String key) { String commandWithPrefix = "-" + key; return this.getCommands().stream() .filter(it -> it.startsWith(commandWithPrefix)) .map(it -> { boolean withoutValue = commandWithPrefix.length() == it.length(); if (withoutValue) { return ""; } checkArgument('=' == it.charAt(commandWithPrefix.length())); return it.split(commandWithPrefix + "=", 2)[1]; }) .findFirst(); } @Override public boolean supports(Class clazz) { return clazz == BitcoindContainerProperties.class; } /** * Validate the container properties. * *

Keep in mind that Testcontainers splits commands on whitespaces. * This means, every property that is part of a command, must not contain whitespaces. * {@inheritDoc} */ @Override public void validate(Object target, Errors errors) { BitcoindContainerProperties properties = (BitcoindContainerProperties) target; String rpcuserValue = properties.getRpcuser().orElse(null); if (rpcuserValue != null) { if (rpcuserValue.isBlank()) { String errorMessage = "'rpcuser' must not be empty"; errors.rejectValue("rpcuser", "rpcuser.invalid", errorMessage); } else if (containsWhitespaces(rpcuserValue)) { String errorMessage = String.format("'rpcuser' must not contain whitespaces - unsupported value: '%s'", rpcuserValue); errors.rejectValue("rpcuser", "rpcuser.unsupported", errorMessage); } } String rpcpasswordValue = properties.getRpcpassword().orElse(null); if (rpcpasswordValue != null) { if (rpcpasswordValue.isBlank()) { String errorMessage = "'rpcpassword' must not be empty"; errors.rejectValue("rpcpassword", "rpcpassword.invalid", errorMessage); } else if (containsWhitespaces(rpcpasswordValue)) { String errorMessage = "'rpcpassword' must not contain whitespaces - unsupported value"; errors.rejectValue("rpcpassword", "rpcpassword.unsupported", errorMessage); } } reservedCommands.stream() .filter(val -> properties.getCommandValueByKey(val).isPresent()) .forEach(reservedKey -> { String errorMessage = String.format("'commands' entry must not contain key '%s'", reservedKey); errors.rejectValue("commands", "commands.reserved", errorMessage); }); for (String command : properties.getCommands()) { if (Strings.isNullOrEmpty(command)) { String errorMessage = "'commands' entry must not be empty"; errors.rejectValue("commands", "commands.invalid", errorMessage); } else { boolean startsWithHyphen = command.startsWith("-"); if (!startsWithHyphen) { String errorMessage = String.format( "'commands' entry must start with '-': invalid value: %s", command ); errors.rejectValue("commands", "commands.invalid", errorMessage); } if (containsWhitespaces(command)) { String errorMessage = String.format( "'commands' entry must not contain whitespaces: unsupported value: %s", command ); errors.rejectValue("commands", "commands.unsupported", errorMessage); } } } } private static boolean containsWhitespaces(String value) { return CharMatcher.WHITESPACE.matchesAnyOf(value); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy