Skip to content

Commit

Permalink
Bump Spring Boot from 3.3.5 to 3.4.1 (#10067)
Browse files Browse the repository at this point in the history
* Add a `hedera.mirror.importer.db.partition.enabled=true` property
* Bump Gradle from 8.10.1 to 8.11.1
* Bump Spring Boot from 3.3.5 to 3.4.1
* Bump Spring Cloud from 2023.0.4 to 2024.0.0
* Change deprecated `@MockBean` and `@SpyBean` to `@MockitoBean` and `@MockitoSpyBean`
* Change property classes to mark nested properties with now required `@Valid`
* Change to non-deprecated methods in `RandomStringUtils`
* Rename `hedera.mirror.importer.db.maintenance.cron` to `hedera.mirror.importer.db.partition.cron`
* Replace incompatible `testcontainers-redis` with a generic Redis container

Signed-off-by: Steven Sheehy <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • Loading branch information
steven-sheehy and dependabot[bot] authored Jan 9, 2025
1 parent 876290c commit c1fa7bc
Show file tree
Hide file tree
Showing 83 changed files with 265 additions and 203 deletions.
4 changes: 1 addition & 3 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ extra.apply {
set("nodeJsVersion", "18.20.5")
set("protobufVersion", "3.25.5")
set("reactorGrpcVersion", "1.2.4")
set("tomcat.version", "10.1.34") // Temporary until next Spring Boot version
set("vertxVersion", "4.5.11")
set("tuweniVersion", "2.3.1")
}
Expand Down Expand Up @@ -69,7 +68,6 @@ dependencies {
api("com.hedera.hashgraph:sdk:2.46.0")
api("com.ongres.scram:client:2.1")
api("com.playtika.testcontainers:embedded-google-pubsub:3.1.10")
api("com.redis.testcontainers:testcontainers-redis-junit-jupiter:1.4.6")
api("com.salesforce.servicelibs:reactor-grpc-stub:$reactorGrpcVersion")
api("commons-beanutils:commons-beanutils:1.9.4")
api("commons-io:commons-io:2.18.0")
Expand Down Expand Up @@ -100,7 +98,7 @@ dependencies {
api("org.mapstruct:mapstruct-processor:$mapStructVersion")
api("org.msgpack:jackson-dataformat-msgpack:0.9.8")
api("org.springdoc:springdoc-openapi-webflux-ui:1.8.0")
api("org.springframework.cloud:spring-cloud-dependencies:2023.0.4")
api("org.springframework.cloud:spring-cloud-dependencies:2024.0.0")
api("org.testcontainers:junit-jupiter:1.20.4")
api("org.mockito:mockito-inline:5.2.0")
api("software.amazon.awssdk:bom:2.29.45")
Expand Down
2 changes: 1 addition & 1 deletion buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ dependencies {
implementation("org.openapitools:openapi-generator-gradle-plugin:7.10.0")
implementation("org.owasp:dependency-check-gradle:11.1.1")
implementation("org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:6.0.1.5171")
implementation("org.springframework.boot:spring-boot-gradle-plugin:3.3.5")
implementation("org.springframework.boot:spring-boot-gradle-plugin:3.4.1")
implementation("org.testcontainers:postgresql:1.20.4")
implementation("org.web3j:web3j-gradle-plugin:4.12.3")
}
Expand Down
13 changes: 4 additions & 9 deletions buildSrc/src/main/kotlin/java-conventions.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -51,22 +51,17 @@ dependencies {
testImplementation("org.springframework.boot:spring-boot-starter-test")
}

tasks.compileJava {
// Disable serial, and this-escape warnings due to errors in generated code
tasks.withType<JavaCompile> {
// Disable serial and this-escape warnings due to errors in generated code
options.compilerArgs.addAll(
listOf("-Werror", "-Xlint:all", "-Xlint:-serial,-this-escape,-preview")
listOf("-parameters", "-Werror", "-Xlint:all", "-Xlint:-this-escape,-preview")
)
options.encoding = "UTF-8"
sourceCompatibility = "21"
targetCompatibility = "21"
}

tasks.compileTestJava {
options.compilerArgs.addAll(listOf("-Werror", "-Xlint:all", "-Xlint:-this-escape,-preview"))
options.encoding = "UTF-8"
sourceCompatibility = "21"
targetCompatibility = "21"
}
tasks.compileJava { options.compilerArgs.add("-Xlint:-serial") }

tasks.javadoc { options.encoding = "UTF-8" }

Expand Down
5 changes: 3 additions & 2 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,18 @@ value, it is recommended to only populate overridden properties in the custom `a
| `hedera.mirror.importer.db.connectionInitSql` | set temp_buffers='256MB'; set timezone TO 'UTC'; | Sql ran on each connection initialized from the datasource |
| `hedera.mirror.importer.db.host` | 127.0.0.1 | The IP or hostname used to connect to the database |
| `hedera.mirror.importer.db.loadBalance` | true | Whether to enable pgpool load balancing. If false, it sends all reads to the primary db backend instead of load balancing them across the primary and replicas. |
| `hedera.mirror.importer.db.metricRefreshInterval` | 5m | The interval which we wait to refresh database statistics. Specified as a spring duration expression |
| `hedera.mirror.importer.db.name` | mirror_node | The name of the database |
| `hedera.mirror.importer.db.owner` | mirror_node | The username of the db user with owner permissions to create and modify the schema |
| `hedera.mirror.importer.db.ownerPassword` | mirror_node_pass | The password for the owner user the processor uses to connect. |
| `hedera.mirror.importer.db.partition.cron` | 0 0 0 \* \* ? | The cron schedule for creating new partitions This is applicable to the v2 database schema |
| `hedera.mirror.importer.db.partition.enabled` | true | Whether new partitions should be created automatically. This is applicable to the v2 database schema |
| `hedera.mirror.importer.db.password` | mirror_importer_pass | The database password for the Importer user the processor uses to connect. |
| `hedera.mirror.importer.db.port` | 5432 | The port used to connect to the database |
| `hedera.mirror.importer.db.restPassword` | mirror_api_pass | The database password the API uses to connect. |
| `hedera.mirror.importer.db.restUsername` | mirror_api | The username the API uses to connect to the database |
| `hedera.mirror.importer.db.schema` | public | The name of the custom schema database objects will be created in. This is applicable from v2 of the data schema |
| `hedera.mirror.importer.db.username` | mirror_importer | The Importer username the processor uses to connect to the database |
| `hedera.mirror.importer.db.maintenance.cron` | 0 0 0 \* \* ? | The cron schedule for creating new partitions This is applicable from v2 of the data schema |
| `hedera.mirror.importer.db.metricRefreshInterval` | 5m | The interval which we wait to refresh database statistics. Specified as a spring duration expression |
| `hedera.mirror.importer.downloader.accessKey` | "" | The cloud storage access key |
| `hedera.mirror.importer.downloader.allowAnonymousAccess` | | Whether the cloud storage bucket allows for anonymous access. |
| `hedera.mirror.importer.downloader.balance.enabled` | false | Whether to enable balance file downloads |
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
3 changes: 1 addition & 2 deletions gradlew
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,7 @@ done
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
' "$PWD" ) || exit
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
@SpringBootTest
public abstract class CommonIntegrationTest {

public static final String REDIS_IMAGE = "redis:6-alpine";
protected final Logger log = LoggerFactory.getLogger(getClass());

@Resource
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (C) 2025 Hedera Hashgraph, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.hedera.mirror.common.config;

import org.slf4j.LoggerFactory;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.output.Slf4jLogConsumer;
import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.utility.DockerImageName;

@Configuration(proxyBeanMethods = false)
public class RedisTestConfiguration {
@Bean
@Lazy
@ServiceConnection("redis")
GenericContainer<?> redis() {
var logger = LoggerFactory.getLogger("RedisContainer");
return new GenericContainer<>(DockerImageName.parse("redis:7.4"))
.waitingFor(Wait.forLogMessage(".*Ready to accept connections.*\\n", 1))
.withExposedPorts(6379)
.withLogConsumer(new Slf4jLogConsumer(logger, true));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1187,11 +1187,11 @@ public byte[] nonZeroBytes(int length) {
}

public String text(int characters) {
return RandomStringUtils.randomAlphanumeric(characters);
return RandomStringUtils.secure().nextAlphanumeric(characters);
}

public String hash(int characters) {
return RandomStringUtils.random(characters, "0123456789abcdef");
return RandomStringUtils.secure().next(characters, "0123456789abcdef");
}

/**
Expand Down
1 change: 0 additions & 1 deletion hedera-mirror-grpc/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ dependencies {
)
runtimeOnly("org.postgresql:postgresql")
testImplementation(project(path = ":common", configuration = "testClasses"))
testImplementation("com.redis.testcontainers:testcontainers-redis-junit-jupiter")
testImplementation("io.projectreactor:reactor-test")
testImplementation("org.flywaydb:flyway-database-postgresql")
testImplementation("org.springframework.boot:spring-boot-testcontainers")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.hedera.mirror.grpc;

import com.hedera.mirror.grpc.config.NettyProperties;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import java.time.Duration;
Expand All @@ -38,5 +39,6 @@ public class GrpcProperties {
private int entityCacheSize = 50_000;

@NotNull
@Valid
private NettyProperties netty = new NettyProperties();
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.hedera.mirror.grpc.retriever;

import jakarta.validation.Valid;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import java.time.Duration;
Expand Down Expand Up @@ -44,6 +45,7 @@ public class RetrieverProperties {
private Duration timeout = Duration.ofSeconds(60L);

@NotNull
@Valid
private UnthrottledProperties unthrottled = new UnthrottledProperties();

@Data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,21 @@
package com.hedera.mirror.grpc;

import com.hedera.mirror.common.config.CommonIntegrationTest;
import com.hedera.mirror.common.config.RedisTestConfiguration;
import com.hedera.mirror.grpc.GrpcIntegrationTest.Configuration;
import com.redis.testcontainers.RedisContainer;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.TransactionOperations;
import org.springframework.transaction.support.TransactionTemplate;
import org.testcontainers.containers.output.Slf4jLogConsumer;
import org.testcontainers.utility.DockerImageName;

@Import(Configuration.class)
@Import({Configuration.class, RedisTestConfiguration.class})
public abstract class GrpcIntegrationTest extends CommonIntegrationTest {

@TestConfiguration(proxyBeanMethods = false)
static class Configuration {
@Bean
@ServiceConnection("redis")
RedisContainer redis() {
var logger = LoggerFactory.getLogger(RedisContainer.class);
return new RedisContainer(DockerImageName.parse(REDIS_IMAGE))
.withLogConsumer(new Slf4jLogConsumer(logger, true));
}

@Bean
@Primary
TransactionOperations transactionOperations(PlatformTransactionManager transactionManager) {
Expand Down
1 change: 0 additions & 1 deletion hedera-mirror-importer/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ dependencies {
testImplementation(project(path = ":common", configuration = "testClasses"))
testImplementation("com.github.vertical-blank:sql-formatter")
testImplementation("com.playtika.testcontainers:embedded-google-pubsub")
testImplementation("com.redis.testcontainers:testcontainers-redis-junit-jupiter")
testImplementation("commons-beanutils:commons-beanutils")
testImplementation("io.projectreactor:reactor-test")
testImplementation("org.apache.commons:commons-math3")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import com.hedera.mirror.importer.migration.MigrationProperties;
import com.hedera.mirror.importer.util.Utility;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
Expand Down Expand Up @@ -60,6 +61,7 @@ public class ImporterProperties {
private Path initialAddressBook;

@NotNull
@Valid
private Map<String, MigrationProperties> migration = new CaseInsensitiveMap<>();

@NotBlank
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,23 @@
@Named
@RequiredArgsConstructor
public class PartitionMaintenance {

private static final String RUN_MAINTENANCE_QUERY = "call create_mirror_node_time_partitions()";

@Owner
private final JdbcTemplate jdbcTemplate;

private final PartitionProperties partitionProperties;

@EventListener(ApplicationReadyEvent.class)
@Leader
@Retryable
@Scheduled(cron = "${hedera.mirror.importer.db.maintenance.cron:0 0 0 * * ?}")
@Scheduled(cron = "${hedera.mirror.importer.db.partition.cron:0 0 0 * * ?}")
public synchronized void runMaintenance() {
if (!partitionProperties.isEnabled()) {
return;
}

log.info("Running partition maintenance");
Stopwatch stopwatch = Stopwatch.createStarted();
jdbcTemplate.execute(RUN_MAINTENANCE_QUERY);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright (C) 2025 Hedera Hashgraph, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.hedera.mirror.importer.db;

import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;

@ConfigurationProperties("hedera.mirror.importer.db.partition")
@Data
@Validated
public class PartitionProperties {
@NotBlank
private String cron = "0 0 0 * * ?";

private boolean enabled = true;
}
Loading

0 comments on commit c1fa7bc

Please sign in to comment.