diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 81dcf70..4452a25 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -9,3 +9,8 @@ updates: directory: "/" schedule: interval: "weekly" + - package-ecosystem: "github-actions" + # Workflow files stored in the default location of `.github/workflows`. (You don't need to specify `/.github/workflows` for `directory`. You can use `directory: "/"`.) + directory: "/" + schedule: + interval: "weekly" diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index d750a71..33aef3f 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -4,9 +4,6 @@ on: workflow_dispatch: push: branches: [ 'develop', 'master', 'releases/**' ] - pull_request: - # The branches below must be a subset of the branches above - branches: [ 'develop', 'master', 'releases/**' ] schedule: - cron: '0 2 * * 4' @@ -19,4 +16,5 @@ jobs: # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] # Use only 'java' to analyze code written in Java, Kotlin or both # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both - # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support \ No newline at end of file + # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support + java_version: 21 \ No newline at end of file diff --git a/.github/workflows/maven-deploy.yml b/.github/workflows/maven-deploy.yml index 6b87317..88b9811 100644 --- a/.github/workflows/maven-deploy.yml +++ b/.github/workflows/maven-deploy.yml @@ -34,6 +34,7 @@ jobs: with: environment: internal-publish release_type: snapshot + java_version: 21 secrets: username: ${{ secrets.MAVEN_CENTRAL_USERNAME }} password: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} @@ -45,6 +46,7 @@ jobs: with: environment: ${{ inputs.environment }} release_type: ${{ inputs.release_type }} + java_version: 21 secrets: username: ${{ secrets.MAVEN_CENTRAL_USERNAME }} password: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} diff --git a/.github/workflows/maven-test.yml b/.github/workflows/maven-test.yml index 5f4e4c1..ae3692d 100644 --- a/.github/workflows/maven-test.yml +++ b/.github/workflows/maven-test.yml @@ -16,4 +16,6 @@ on: jobs: maven-tests: - uses: wultra/wultra-infrastructure/.github/workflows/maven-test.yml@develop \ No newline at end of file + uses: wultra/wultra-infrastructure/.github/workflows/maven-test.yml@develop + with: + java_version: 21 \ No newline at end of file diff --git a/.github/workflows/maven-update-version.yml b/.github/workflows/maven-update-version.yml new file mode 100644 index 0000000..056791a --- /dev/null +++ b/.github/workflows/maven-update-version.yml @@ -0,0 +1,45 @@ +name: Update version with Maven +# - validate that there is no dependency on snapshot +# - update version to non-snapshot +# - commit and tag +# - update version to snapshot +# - push changes + +on: + workflow_dispatch: + inputs: + update_type: + description: Update type + required: true + type: choice + options: + # `major` not yet supported + - minor + - bugfix + +jobs: + update-version: + name: Update version + runs-on: ubuntu-latest + permissions: + contents: write + + steps: + - uses: actions/checkout@v4 + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: 21 + distribution: 'temurin' + cache: maven + - name: Run Maven release:prepare + run: | + echo ${{ inputs.update_type }} + if [ ${{ inputs.update_type }} == "minor" ]; then + mvn -B -U -DdryRun=true release:prepare -DtagNameFormat=@{project.version} -DprojectVersionPolicyId=SemVerVersionPolicy + elif [ ${{ inputs.update_type }} == "bugfix" ]; then + mvn -B -U -DdryRun=true release:prepare -DtagNameFormat=@{project.version} + else + echo "Not supported type: ${{ inputs.update_type }}" + exit 1 + fi diff --git a/annotations/pom.xml b/annotations/pom.xml index fb70499..5907a57 100644 --- a/annotations/pom.xml +++ b/annotations/pom.xml @@ -7,7 +7,7 @@ io.getlime.core lime-java-core-parent - 1.9.0 + 1.10.0 annotations diff --git a/audit-base/pom.xml b/audit-base/pom.xml index b5b17bf..5215551 100644 --- a/audit-base/pom.xml +++ b/audit-base/pom.xml @@ -6,7 +6,7 @@ io.getlime.core lime-java-core-parent - 1.9.0 + 1.10.0 audit-base diff --git a/audit-base/src/main/java/com/wultra/core/audit/base/database/DatabaseAuditWriter.java b/audit-base/src/main/java/com/wultra/core/audit/base/database/DatabaseAuditWriter.java index 137e296..a4d75ea 100644 --- a/audit-base/src/main/java/com/wultra/core/audit/base/database/DatabaseAuditWriter.java +++ b/audit-base/src/main/java/com/wultra/core/audit/base/database/DatabaseAuditWriter.java @@ -31,6 +31,7 @@ import org.springframework.jdbc.core.PreparedStatementCallback; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; +import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.support.TransactionTemplate; import org.springframework.util.StringUtils; @@ -159,6 +160,7 @@ public void flush() { } synchronized (FLUSH_LOCK) { + transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); transactionTemplate.executeWithoutResult(status -> { while (!queue.isEmpty()) { try { @@ -258,11 +260,11 @@ public void cleanup() { final LocalDateTime cleanupLimit = LocalDateTime.now().minusDays(cleanupDays); synchronized (CLEANUP_LOCK) { transactionTemplate.executeWithoutResult(status -> { - jdbcTemplate.execute("DELETE FROM " + tableNameAudit + " WHERE timestamp_created < ?", (PreparedStatementCallback) ps -> { + jdbcTemplate.execute("DELETE FROM " + tableNameParam + " WHERE timestamp_created < ?", (PreparedStatementCallback) ps -> { ps.setTimestamp(1, Timestamp.valueOf(cleanupLimit)); return ps.execute(); }); - jdbcTemplate.execute("DELETE FROM " + tableNameParam + " WHERE timestamp_created < ?", (PreparedStatementCallback) ps -> { + jdbcTemplate.execute("DELETE FROM " + tableNameAudit + " WHERE timestamp_created < ?", (PreparedStatementCallback) ps -> { ps.setTimestamp(1, Timestamp.valueOf(cleanupLimit)); return ps.execute(); }); @@ -274,7 +276,7 @@ public void cleanup() { /** * Scheduled flush of persistence of audit data. */ - @Scheduled(fixedDelayString = "${audit.flush.delay.fixed:1000}", initialDelayString = "${powerauth.audit.flush.delay.initial:1000}") + @Scheduled(fixedDelayString = "${audit.flush.delay.fixed:1000}", initialDelayString = "${audit.flush.delay.initial:1000}") public void scheduledFlush() { logger.debug("Scheduled audit log flush called"); flush(); @@ -283,7 +285,7 @@ public void scheduledFlush() { /** * Scheduled cleanup of audit data in database. */ - @Scheduled(fixedDelayString = "${audit.cleanup.delay.fixed:3600000}", initialDelayString = "${powerauth.audit.cleanup.delay.initial:1000}") + @Scheduled(fixedDelayString = "${audit.cleanup.delay.fixed:3600000}", initialDelayString = "${audit.cleanup.delay.initial:1000}") public void scheduledCleanup() { logger.debug("Scheduled audit log cleanup called"); cleanup(); diff --git a/audit-base/src/test/java/com/wultra/core/audit/base/AuditParamEnabledTest.java b/audit-base/src/test/java/com/wultra/core/audit/base/AuditParamEnabledTest.java index e5c7e68..d5ab7b8 100644 --- a/audit-base/src/test/java/com/wultra/core/audit/base/AuditParamEnabledTest.java +++ b/audit-base/src/test/java/com/wultra/core/audit/base/AuditParamEnabledTest.java @@ -33,7 +33,11 @@ import static org.junit.jupiter.api.Assertions.*; -@SpringBootTest(classes = TestApplication.class, properties = {"audit.db.table.param.enabled=true"}) +@SpringBootTest(classes = TestApplication.class, properties = { + "audit.db.table.param.enabled=true", + "audit.db.cleanup.days=-1", // time shift to the future to enable cleanup test + "audit.cleanup.delay.initial=60000" // delay the job start due to slow builds +}) @Sql(scripts = "/db_schema.sql") class AuditParamEnabledTest { @@ -122,4 +126,33 @@ void testAuditMoreParams() { assertEquals(new JsonUtil().serializeObject(timestamp), rs3.getString("param_value")); } + @Test + void testAuditCleanup() { + final Audit audit = auditFactory.getAudit(); + audit.info("test message", AuditDetail.builder().param("my_id", "test_id").build()); + audit.flush(); + + assertEquals(1, countAuditLogs()); + assertEquals(1, countAuditParams()); + + audit.cleanup(); + + assertEquals(0, countAuditLogs()); + assertEquals(0, countAuditParams()); + } + + private int countAuditLogs() { + return count("audit_log"); + } + + private int countAuditParams() { + return count("audit_param"); + } + + private int count(final String tableName) { + final SqlRowSet rs = jdbcTemplate.queryForRowSet("SELECT COUNT(*) FROM " + tableName); + assertTrue(rs.next()); + return rs.getInt(1); + } + } \ No newline at end of file diff --git a/audit-base/src/test/java/com/wultra/core/audit/base/AuditTest.java b/audit-base/src/test/java/com/wultra/core/audit/base/AuditTest.java index c921a91..e568832 100644 --- a/audit-base/src/test/java/com/wultra/core/audit/base/AuditTest.java +++ b/audit-base/src/test/java/com/wultra/core/audit/base/AuditTest.java @@ -17,6 +17,7 @@ import com.wultra.core.audit.base.model.AuditDetail; import com.wultra.core.audit.base.model.AuditLevel; +import org.awaitility.Awaitility; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -26,6 +27,7 @@ import org.springframework.test.context.jdbc.Sql; import java.sql.Timestamp; +import java.time.Duration; import static org.junit.jupiter.api.Assertions.*; @@ -219,4 +221,14 @@ void testAuditTrace() { assertTrue(rs.next()); assertEquals(0, rs.getInt(1)); } + + @Test + void testScheduledFlush() { + Audit audit = auditFactory.getAudit(); + audit.info("test message"); + + Awaitility.await() + .atMost(Duration.ofSeconds(5)) + .until(() -> jdbcTemplate.queryForRowSet("SELECT * FROM audit_log").next()); + } } diff --git a/audit-base/src/test/resources/application.properties b/audit-base/src/test/resources/application.properties index d47f7a9..cb3d705 100644 --- a/audit-base/src/test/resources/application.properties +++ b/audit-base/src/test/resources/application.properties @@ -1,2 +1,4 @@ # Audit configuration spring.application.name=test-application + +spring.datasource.hikari.auto-commit=false diff --git a/bom/pom.xml b/bom/pom.xml index 1c2c933..aa45a5c 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -7,7 +7,7 @@ io.getlime.core lime-java-core-parent - 1.9.0 + 1.10.0 core-bom diff --git a/http-common/pom.xml b/http-common/pom.xml index 6adf198..f7d9a97 100644 --- a/http-common/pom.xml +++ b/http-common/pom.xml @@ -7,7 +7,7 @@ io.getlime.core lime-java-core-parent - 1.9.0 + 1.10.0 http-common diff --git a/pom.xml b/pom.xml index 43c093f..402acf4 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ Wultra - Core Java Libraries io.getlime.core lime-java-core-parent - 1.9.0 + 1.10.0 pom 2017 @@ -56,12 +56,12 @@ 17 ${java.version} - 3.12.1 - 3.2.5 + 3.13.0 + 3.3.1 + 3.5.0 - 3.2.3 - 3.0.1 + 3.3.2 @@ -105,7 +105,7 @@ org.apache.maven.plugins maven-source-plugin - 3.3.0 + 3.3.1 attach-sources @@ -119,7 +119,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.6.3 + 3.8.0 false @@ -135,11 +135,12 @@ org.apache.maven.plugins maven-deploy-plugin - 3.1.1 + 3.1.2 org.apache.maven.plugins maven-enforcer-plugin + ${maven-enforcer-plugin.version} enforce-banned-dependencies diff --git a/rest-client-base/pom.xml b/rest-client-base/pom.xml index bab834d..19bc353 100644 --- a/rest-client-base/pom.xml +++ b/rest-client-base/pom.xml @@ -6,7 +6,7 @@ io.getlime.core lime-java-core-parent - 1.9.0 + 1.10.0 rest-client-base @@ -19,11 +19,6 @@ org.springframework.boot spring-boot-starter-webflux - - com.google.code.findbugs - annotations - ${findbugs-annotations.version} - org.springframework.boot spring-boot-starter diff --git a/rest-client-base/src/main/java/com/wultra/core/rest/client/base/DefaultRestClient.java b/rest-client-base/src/main/java/com/wultra/core/rest/client/base/DefaultRestClient.java index 1a1741a..2b51367 100644 --- a/rest-client-base/src/main/java/com/wultra/core/rest/client/base/DefaultRestClient.java +++ b/rest-client-base/src/main/java/com/wultra/core/rest/client/base/DefaultRestClient.java @@ -68,6 +68,12 @@ public class DefaultRestClient implements RestClient { private static final Logger logger = LoggerFactory.getLogger(DefaultRestClient.class); + /** + * Default max connections. + * As same value as in {@link reactor.netty.tcp.TcpResources#get()} avoid default to {@code 2 * available number of processors} only. + */ + private static final int DEFAULT_POOL_MAX_CONNECTIONS = 500; + private WebClient webClient; private final RestClientConfiguration config; private final Collection modules; @@ -240,26 +246,27 @@ private static HttpClient configureKeepAlive(final HttpClient httpClient, final } /** - * Create HttpClient with default HttpConnectionProvider or custom one, if specified in the given config. - * @param config Config to create connection provider if specified. + * Create HttpClient with custom ConnectionProvider with options specified in the given config. + * @param config Config to create connection provider. * @return Http client. */ private static HttpClient createHttpClient(final RestClientConfiguration config) { + final ConnectionProvider.Builder providerBuilder = ConnectionProvider.builder("custom") + .maxConnections(DEFAULT_POOL_MAX_CONNECTIONS) + .pendingAcquireTimeout(Duration.ofMillis(ConnectionProvider.DEFAULT_POOL_ACQUIRE_TIMEOUT)); + final Duration maxIdleTime = config.getMaxIdleTime(); final Duration maxLifeTime = config.getMaxLifeTime(); if (maxIdleTime != null || maxLifeTime != null) { logger.info("Configuring custom connection provider, maxIdleTime={}, maxLifeTime={}", maxIdleTime, maxLifeTime); - final ConnectionProvider.Builder providerBuilder = ConnectionProvider.builder("custom"); if (maxIdleTime != null) { providerBuilder.maxIdleTime(maxIdleTime); } if (maxLifeTime != null) { providerBuilder.maxLifeTime(maxLifeTime); } - return HttpClient.create(providerBuilder.build()); - } else { - return HttpClient.create(); } + return HttpClient.create(providerBuilder.build()); } private static Optional createObjectMapper(final RestClientConfiguration config, Collection modules) { diff --git a/rest-model-base/pom.xml b/rest-model-base/pom.xml index d9118ff..199826a 100644 --- a/rest-model-base/pom.xml +++ b/rest-model-base/pom.xml @@ -6,7 +6,7 @@ io.getlime.core lime-java-core-parent - 1.9.0 + 1.10.0 rest-model-base