From 839c5e76b57d6b66bd16173dc29e8d2ed9d57b09 Mon Sep 17 00:00:00 2001 From: Kirill Kurdyukov Date: Tue, 20 Aug 2024 13:27:19 +0300 Subject: [PATCH 1/7] feat: update pom.xml version --- hibernate-dialect/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hibernate-dialect/pom.xml b/hibernate-dialect/pom.xml index 03012c1..7f470f6 100644 --- a/hibernate-dialect/pom.xml +++ b/hibernate-dialect/pom.xml @@ -6,7 +6,7 @@ tech.ydb.dialects hibernate-ydb-dialect - 0.9.4 + 0.9.5 jar From ce082100a5f7d13b48e9053b7df7efd4e3a8dd65 Mon Sep 17 00:00:00 2001 From: Kirill Kurdyukov Date: Wed, 21 Aug 2024 12:07:24 +0300 Subject: [PATCH 2/7] feat: shaded lock spring --- shaded-lock-ydb/pom.xml | 197 ++++++++++++++++++ .../ydb/lock/provider/YdbLockProperties.java | 21 ++ .../ydb/lock/provider/YdbLockProvider.java | 71 +++++++ .../YdbLockProviderConfiguration.java | 45 ++++ .../tech/ydb/lock/provider/package-info.java | 7 + .../main/resources/META-INF/spring.factories | 1 + .../java/tech/ydb/lock/provider/TestApp.java | 10 + .../lock/provider/YdbLockProviderTest.java | 45 ++++ .../core/convert/YdbMappingJdbcConverter.java | 1 + .../java/tech/ydb/data/core/package-info.java | 4 + 10 files changed, 402 insertions(+) create mode 100644 shaded-lock-ydb/pom.xml create mode 100644 shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbLockProperties.java create mode 100644 shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbLockProvider.java create mode 100644 shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbLockProviderConfiguration.java create mode 100644 shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/package-info.java create mode 100644 shaded-lock-ydb/src/main/resources/META-INF/spring.factories create mode 100644 shaded-lock-ydb/src/test/java/tech/ydb/lock/provider/TestApp.java create mode 100644 shaded-lock-ydb/src/test/java/tech/ydb/lock/provider/YdbLockProviderTest.java create mode 100644 spring-data-dialect/src/main/java/tech/ydb/data/core/package-info.java diff --git a/shaded-lock-ydb/pom.xml b/shaded-lock-ydb/pom.xml new file mode 100644 index 0000000..fd97513 --- /dev/null +++ b/shaded-lock-ydb/pom.xml @@ -0,0 +1,197 @@ + + + 4.0.0 + + tech.ydb.dialects + shaded-lock-ydb + 0.9.1 + + jar + + Shaded Lock Service YDB + Shaded Lock Service YDB Spring Starter + https://github.com/ydb-platform/ydb-java-dialects + + + + Kirill Kurdyukov + kurdyukov-kir@ydb.tech + YDB + https://ydb.tech/ + + + + + https://github.com/ydb-platform/ydb-java-dialects + scm:git:https://github.com/ydb-platform/ydb-java-dialects.git + scm:git:https://github.com/ydb-platform/ydb-java-dialects.git + + + + UTF-8 + + 17 + 17 + 17 + + 5.9.3 + 2.17.2 + 2.2.6 + 2.2.2 + 3.2.3 + 5.15.0 + + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0 + + + + + + + tech.ydb + ydb-sdk-bom + ${ydb.sdk.version} + pom + import + + + + + + + tech.ydb + ydb-sdk-coordination + + + net.javacrumbs.shedlock + shedlock-spring + ${shedlock-spring.version} + provided + + + tech.ydb.jdbc + ydb-jdbc-driver + ${ydb.jdbc.version} + provided + + + org.springframework.boot + spring-boot-autoconfigure + ${spring.boot.version} + provided + + + + org.springframework.boot + spring-boot-starter-test + ${spring.boot.version} + test + + + tech.ydb.test + ydb-junit5-support + test + + + org.junit.jupiter + junit-jupiter-api + ${junit5.version} + test + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.5.0 + + 17 + + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.2.1 + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.1.0 + + + true + + + + + + + + + ossrh-s01 + + false + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 3.1.0 + + + sign-artifacts + verify + + sign + + + + + + --pinentry-mode + loopback + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.13 + true + + ossrh-s01 + https://s01.oss.sonatype.org/ + false + + + + + + + \ No newline at end of file diff --git a/shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbLockProperties.java b/shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbLockProperties.java new file mode 100644 index 0000000..283a799 --- /dev/null +++ b/shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbLockProperties.java @@ -0,0 +1,21 @@ +package tech.ydb.lock.provider; + +import java.time.Duration; +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * @author Kirill Kurdyukov + */ +@ConfigurationProperties(prefix = "ydb.lock") +public class YdbLockProperties { + + public Duration acquireSemaphoreTimeout = Duration.ofSeconds(5); + + public void setAcquireSemaphoreTimeout(Duration acquireSemaphoreTimeout) { + this.acquireSemaphoreTimeout = acquireSemaphoreTimeout; + } + + public Duration getAcquireSemaphoreTimeout() { + return acquireSemaphoreTimeout; + } +} diff --git a/shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbLockProvider.java b/shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbLockProvider.java new file mode 100644 index 0000000..176da03 --- /dev/null +++ b/shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbLockProvider.java @@ -0,0 +1,71 @@ +package tech.ydb.lock.provider; + +import java.util.Optional; +import net.javacrumbs.shedlock.core.LockConfiguration; +import net.javacrumbs.shedlock.core.LockProvider; +import net.javacrumbs.shedlock.core.SimpleLock; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import tech.ydb.coordination.CoordinationClient; +import tech.ydb.coordination.SemaphoreLease; + +/** + * @author Kirill Kurdyukov + */ +public class YdbLockProvider implements LockProvider { + private static final Logger logger = LoggerFactory.getLogger(YdbLockProvider.class); + private static final String YDB_LOCK_NODE_NAME = "shared-lock-ydb"; + private static final int ATTEMPT_CREATE_NODE = 10; + + private final CoordinationClient coordinationClient; + private final YdbLockProperties ydbLockProperties; + + public YdbLockProvider(CoordinationClient coordinationClient, YdbLockProperties ydbLockProperties) { + this.coordinationClient = coordinationClient; + this.ydbLockProperties = ydbLockProperties; + } + + public void init() { + for (int i = 0; i < ATTEMPT_CREATE_NODE; i++) { + var status = coordinationClient.createNode(YDB_LOCK_NODE_NAME).join(); + + if (status.isSuccess()) { + return; + } + + if (i == ATTEMPT_CREATE_NODE - 1) { + status.expectSuccess("Failed created coordination service node: " + YDB_LOCK_NODE_NAME); + } + } + } + + @Override + public Optional lock(LockConfiguration lockConfiguration) { + var coordinationSession = coordinationClient.createSession(YDB_LOCK_NODE_NAME); + + coordinationSession.connect().join() + .expectSuccess("Failed creating coordination node session"); + + logger.debug("Created coordination node session"); + + coordinationSession.createSemaphore(lockConfiguration.getName(), 1).join() + .expectSuccess("Failed creating semaphore[" + lockConfiguration.getName() + + "], coordination node[" + YDB_LOCK_NODE_NAME + "]"); + + logger.debug("Created semaphore[" + lockConfiguration.getName() + "]"); + + var semaphoreLease = coordinationSession.acquireSemaphore(lockConfiguration.getName(), 1, + ydbLockProperties.acquireSemaphoreTimeout).join().getValue(); + + logger.debug("Semaphore acquired"); + + return Optional.of(new YdbSimpleLock(semaphoreLease)); + } + + private record YdbSimpleLock(SemaphoreLease semaphoreLease) implements SimpleLock { + @Override + public void unlock() { + semaphoreLease.release().join(); + } + } +} diff --git a/shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbLockProviderConfiguration.java b/shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbLockProviderConfiguration.java new file mode 100644 index 0000000..7af5f74 --- /dev/null +++ b/shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbLockProviderConfiguration.java @@ -0,0 +1,45 @@ +package tech.ydb.lock.provider; + +import java.sql.SQLException; +import javax.sql.DataSource; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import tech.ydb.coordination.CoordinationClient; +import tech.ydb.jdbc.YdbConnection; +import tech.ydb.jdbc.YdbDriver; + +/** + * @author Kirill Kurdyukov + */ + +@Configuration +@EnableConfigurationProperties(YdbLockProperties.class) +public class YdbLockProviderConfiguration { + + @Configuration + @ConditionalOnClass(YdbDriver.class) + public static class YdbLockProviderDataSourceConfiguration { + + @Bean + @ConditionalOnBean(DataSource.class) + public CoordinationClient coordinationClient(DataSource dataSource) throws SQLException { + try (var ydbConnection = dataSource.getConnection().unwrap(YdbConnection.class)) { + + return CoordinationClient.newClient(ydbConnection.getCtx().getGrpcTransport()); + } + } + } + + @Bean + public YdbLockProvider ydbLockProvider(CoordinationClient coordinationClient, + YdbLockProperties ydbLockProperties) { + var ydbLockProvider = new YdbLockProvider(coordinationClient, ydbLockProperties); + + ydbLockProvider.init(); + + return ydbLockProvider; + } +} diff --git a/shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/package-info.java b/shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/package-info.java new file mode 100644 index 0000000..6df55a8 --- /dev/null +++ b/shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/package-info.java @@ -0,0 +1,7 @@ +/** + * @author Kirill Kurdyukov + */ +@NonNullApi +package tech.ydb.lock.provider; + +import org.springframework.lang.NonNullApi; \ No newline at end of file diff --git a/shaded-lock-ydb/src/main/resources/META-INF/spring.factories b/shaded-lock-ydb/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..3bcab04 --- /dev/null +++ b/shaded-lock-ydb/src/main/resources/META-INF/spring.factories @@ -0,0 +1 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=tech.ydb.lock.provider.YdbLockProviderConfiguration \ No newline at end of file diff --git a/shaded-lock-ydb/src/test/java/tech/ydb/lock/provider/TestApp.java b/shaded-lock-ydb/src/test/java/tech/ydb/lock/provider/TestApp.java new file mode 100644 index 0000000..456e16c --- /dev/null +++ b/shaded-lock-ydb/src/test/java/tech/ydb/lock/provider/TestApp.java @@ -0,0 +1,10 @@ +package tech.ydb.lock.provider; + +import org.springframework.boot.test.context.SpringBootTest; + +/** + * @author Kirill Kurdyukov + */ +@SpringBootTest +public class TestApp { +} diff --git a/shaded-lock-ydb/src/test/java/tech/ydb/lock/provider/YdbLockProviderTest.java b/shaded-lock-ydb/src/test/java/tech/ydb/lock/provider/YdbLockProviderTest.java new file mode 100644 index 0000000..2c52c12 --- /dev/null +++ b/shaded-lock-ydb/src/test/java/tech/ydb/lock/provider/YdbLockProviderTest.java @@ -0,0 +1,45 @@ +package tech.ydb.lock.provider; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; +import tech.ydb.test.junit5.YdbHelperExtension; + +/** + * @author Kirill Kurdyukov + */ +@SpringBootTest(classes = TestApp.class) +public class YdbLockProviderTest { + + @RegisterExtension + private static final YdbHelperExtension ydb = new YdbHelperExtension(); + + @DynamicPropertySource + private static void propertySource(DynamicPropertyRegistry registry) { + registry.add("spring.datasource.url", YdbLockProviderTest::jdbcUrl); + } + + private static String jdbcUrl() { + StringBuilder jdbc = new StringBuilder("jdbc:ydb:") + .append(ydb.useTls() ? "grpcs://" : "grpc://") + .append(ydb.endpoint()) + .append(ydb.database()); + + if (ydb.authToken() != null) { + jdbc.append("?").append("token=").append(ydb.authToken()); + } + + return jdbc.toString(); + } + + @Autowired + private YdbLockProvider ydbLockProvider; + + @Test + public void integrationTest() { + + } +} diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YdbMappingJdbcConverter.java b/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YdbMappingJdbcConverter.java index 55f14a3..d0348f8 100644 --- a/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YdbMappingJdbcConverter.java +++ b/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YdbMappingJdbcConverter.java @@ -27,6 +27,7 @@ public SQLType getTargetSqlType(RelationalPersistentProperty property) { if (property.isAnnotationPresent(YdbType.class)) { return new YQLType(property.getRequiredAnnotation(YdbType.class).value()); } + return YdbJdbcUtil.targetSqlTypeFor(getColumnType(property)); } diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/core/package-info.java b/spring-data-dialect/src/main/java/tech/ydb/data/core/package-info.java new file mode 100644 index 0000000..26f310c --- /dev/null +++ b/spring-data-dialect/src/main/java/tech/ydb/data/core/package-info.java @@ -0,0 +1,4 @@ +/** + * @author Kirill Kurdyukov + */ +package tech.ydb.data.core; \ No newline at end of file From ade21aa3e43f084130efbcf1f3801eaac5a5b7bf Mon Sep 17 00:00:00 2001 From: Kirill Kurdyukov Date: Wed, 21 Aug 2024 14:41:21 +0300 Subject: [PATCH 3/7] feat: fix issues --- shaded-lock-ydb/pom.xml | 14 ++++-- ...> YdbCoordinationServiceLockProvider.java} | 44 +++++++++-------- .../ydb/lock/provider/YdbLockProperties.java | 21 -------- .../YdbLockProviderConfiguration.java | 30 +----------- .../java/tech/ydb/lock/provider/TestApp.java | 4 +- .../lock/provider/YdbLockProviderTest.java | 48 ++++++++++++++++++- .../src/test/resources/application.properties | 1 + 7 files changed, 85 insertions(+), 77 deletions(-) rename shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/{YdbLockProvider.java => YdbCoordinationServiceLockProvider.java} (59%) delete mode 100644 shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbLockProperties.java create mode 100644 shaded-lock-ydb/src/test/resources/application.properties diff --git a/shaded-lock-ydb/pom.xml b/shaded-lock-ydb/pom.xml index fd97513..d32ad15 100644 --- a/shaded-lock-ydb/pom.xml +++ b/shaded-lock-ydb/pom.xml @@ -60,6 +60,13 @@ pom import + + org.springframework.boot + spring-boot-dependencies + ${spring.boot.version} + import + pom + @@ -83,14 +90,12 @@ org.springframework.boot spring-boot-autoconfigure - ${spring.boot.version} provided org.springframework.boot spring-boot-starter-test - ${spring.boot.version} test @@ -99,9 +104,8 @@ test - org.junit.jupiter - junit-jupiter-api - ${junit5.version} + org.springframework.boot + spring-boot-starter-jdbc test diff --git a/shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbLockProvider.java b/shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbCoordinationServiceLockProvider.java similarity index 59% rename from shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbLockProvider.java rename to shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbCoordinationServiceLockProvider.java index 176da03..b93c502 100644 --- a/shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbLockProvider.java +++ b/shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbCoordinationServiceLockProvider.java @@ -1,6 +1,8 @@ package tech.ydb.lock.provider; +import java.sql.SQLException; import java.util.Optional; +import javax.annotation.PreDestroy; import net.javacrumbs.shedlock.core.LockConfiguration; import net.javacrumbs.shedlock.core.LockProvider; import net.javacrumbs.shedlock.core.SimpleLock; @@ -8,21 +10,22 @@ import org.slf4j.LoggerFactory; import tech.ydb.coordination.CoordinationClient; import tech.ydb.coordination.SemaphoreLease; +import tech.ydb.jdbc.YdbConnection; /** * @author Kirill Kurdyukov */ -public class YdbLockProvider implements LockProvider { - private static final Logger logger = LoggerFactory.getLogger(YdbLockProvider.class); +public class YdbCoordinationServiceLockProvider implements LockProvider { + private static final Logger logger = LoggerFactory.getLogger(YdbCoordinationServiceLockProvider.class); private static final String YDB_LOCK_NODE_NAME = "shared-lock-ydb"; private static final int ATTEMPT_CREATE_NODE = 10; + private final YdbConnection ydbConnection; private final CoordinationClient coordinationClient; - private final YdbLockProperties ydbLockProperties; - public YdbLockProvider(CoordinationClient coordinationClient, YdbLockProperties ydbLockProperties) { - this.coordinationClient = coordinationClient; - this.ydbLockProperties = ydbLockProperties; + public YdbCoordinationServiceLockProvider(YdbConnection ydbConnection) { + this.ydbConnection = ydbConnection; + this.coordinationClient = CoordinationClient.newClient(ydbConnection.getCtx().getGrpcTransport()); } public void init() { @@ -48,24 +51,27 @@ public Optional lock(LockConfiguration lockConfiguration) { logger.debug("Created coordination node session"); - coordinationSession.createSemaphore(lockConfiguration.getName(), 1).join() - .expectSuccess("Failed creating semaphore[" + lockConfiguration.getName() + - "], coordination node[" + YDB_LOCK_NODE_NAME + "]"); + var semaphoreLease = coordinationSession.acquireEphemeralSemaphore(lockConfiguration.getName(), true, + lockConfiguration.getLockAtMostFor()).join(); - logger.debug("Created semaphore[" + lockConfiguration.getName() + "]"); + if (semaphoreLease.isSuccess()) { + logger.debug("Semaphore acquired"); - var semaphoreLease = coordinationSession.acquireSemaphore(lockConfiguration.getName(), 1, - ydbLockProperties.acquireSemaphoreTimeout).join().getValue(); - - logger.debug("Semaphore acquired"); - - return Optional.of(new YdbSimpleLock(semaphoreLease)); + return Optional.of(new YdbSimpleLock(semaphoreLease.getValue())); + } else { + return Optional.empty(); + } } private record YdbSimpleLock(SemaphoreLease semaphoreLease) implements SimpleLock { @Override - public void unlock() { - semaphoreLease.release().join(); - } + public void unlock() { + semaphoreLease.release().join(); } + } + + @PreDestroy + private void close() throws SQLException { + ydbConnection.close(); + } } diff --git a/shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbLockProperties.java b/shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbLockProperties.java deleted file mode 100644 index 283a799..0000000 --- a/shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbLockProperties.java +++ /dev/null @@ -1,21 +0,0 @@ -package tech.ydb.lock.provider; - -import java.time.Duration; -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * @author Kirill Kurdyukov - */ -@ConfigurationProperties(prefix = "ydb.lock") -public class YdbLockProperties { - - public Duration acquireSemaphoreTimeout = Duration.ofSeconds(5); - - public void setAcquireSemaphoreTimeout(Duration acquireSemaphoreTimeout) { - this.acquireSemaphoreTimeout = acquireSemaphoreTimeout; - } - - public Duration getAcquireSemaphoreTimeout() { - return acquireSemaphoreTimeout; - } -} diff --git a/shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbLockProviderConfiguration.java b/shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbLockProviderConfiguration.java index 7af5f74..786f375 100644 --- a/shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbLockProviderConfiguration.java +++ b/shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbLockProviderConfiguration.java @@ -2,44 +2,18 @@ import java.sql.SQLException; import javax.sql.DataSource; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import tech.ydb.coordination.CoordinationClient; import tech.ydb.jdbc.YdbConnection; -import tech.ydb.jdbc.YdbDriver; /** * @author Kirill Kurdyukov */ @Configuration -@EnableConfigurationProperties(YdbLockProperties.class) public class YdbLockProviderConfiguration { - - @Configuration - @ConditionalOnClass(YdbDriver.class) - public static class YdbLockProviderDataSourceConfiguration { - - @Bean - @ConditionalOnBean(DataSource.class) - public CoordinationClient coordinationClient(DataSource dataSource) throws SQLException { - try (var ydbConnection = dataSource.getConnection().unwrap(YdbConnection.class)) { - - return CoordinationClient.newClient(ydbConnection.getCtx().getGrpcTransport()); - } - } - } - @Bean - public YdbLockProvider ydbLockProvider(CoordinationClient coordinationClient, - YdbLockProperties ydbLockProperties) { - var ydbLockProvider = new YdbLockProvider(coordinationClient, ydbLockProperties); - - ydbLockProvider.init(); - - return ydbLockProvider; + public YdbCoordinationServiceLockProvider ydbLockProvider(DataSource dataSource) throws SQLException { + return new YdbCoordinationServiceLockProvider(dataSource.getConnection().unwrap(YdbConnection.class)); } } diff --git a/shaded-lock-ydb/src/test/java/tech/ydb/lock/provider/TestApp.java b/shaded-lock-ydb/src/test/java/tech/ydb/lock/provider/TestApp.java index 456e16c..225f8d7 100644 --- a/shaded-lock-ydb/src/test/java/tech/ydb/lock/provider/TestApp.java +++ b/shaded-lock-ydb/src/test/java/tech/ydb/lock/provider/TestApp.java @@ -1,10 +1,10 @@ package tech.ydb.lock.provider; -import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.autoconfigure.SpringBootApplication; /** * @author Kirill Kurdyukov */ -@SpringBootTest +@SpringBootApplication public class TestApp { } diff --git a/shaded-lock-ydb/src/test/java/tech/ydb/lock/provider/YdbLockProviderTest.java b/shaded-lock-ydb/src/test/java/tech/ydb/lock/provider/YdbLockProviderTest.java index 2c52c12..e4c226e 100644 --- a/shaded-lock-ydb/src/test/java/tech/ydb/lock/provider/YdbLockProviderTest.java +++ b/shaded-lock-ydb/src/test/java/tech/ydb/lock/provider/YdbLockProviderTest.java @@ -1,5 +1,16 @@ package tech.ydb.lock.provider; +import java.time.Duration; +import java.time.Instant; +import java.util.ArrayList; +import java.util.Optional; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.atomic.AtomicInteger; +import net.javacrumbs.shedlock.core.LockConfiguration; +import net.javacrumbs.shedlock.core.SimpleLock; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.springframework.beans.factory.annotation.Autowired; @@ -36,10 +47,43 @@ private static String jdbcUrl() { } @Autowired - private YdbLockProvider ydbLockProvider; + private YdbCoordinationServiceLockProvider lockProvider; @Test - public void integrationTest() { + public void integrationTest() throws ExecutionException, InterruptedException { + var executorServer = Executors.newFixedThreadPool(10); + var atomicInt = new AtomicInteger(); + var futures = new ArrayList>(); + for (int i = 0; i < 100; i++) { + final var ii = i; + futures.add(executorServer.submit(() -> { + lockProvider.init(); + + Optional optinal = Optional.empty(); + + while (optinal.isEmpty()) { + optinal = lockProvider.lock( + new LockConfiguration(Instant.now(), "semaphore", Duration.ZERO, Duration.ZERO)); + + optinal.ifPresent(simpleLock -> { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + + atomicInt.addAndGet(ii); + simpleLock.unlock(); + }); + } + })); + } + + for (Future future : futures) { + future.get(); + } + + Assertions.assertEquals(4950, atomicInt.get()); } } diff --git a/shaded-lock-ydb/src/test/resources/application.properties b/shaded-lock-ydb/src/test/resources/application.properties new file mode 100644 index 0000000..09763b8 --- /dev/null +++ b/shaded-lock-ydb/src/test/resources/application.properties @@ -0,0 +1 @@ +spring.datasource.driver-class-name=tech.ydb.jdbc.YdbDriver \ No newline at end of file From 226a47473442b9ba2886d302ba8ef3f76ba629b9 Mon Sep 17 00:00:00 2001 From: Kirill Kurdyukov Date: Wed, 21 Aug 2024 15:05:52 +0300 Subject: [PATCH 4/7] feat: fix --- shaded-lock-ydb/pom.xml | 2 +- .../provider/YdbCoordinationServiceLockProvider.java | 1 + .../lock/provider/YdbLockProviderConfiguration.java | 6 +++++- .../tech/ydb/lock/provider/YdbLockProviderTest.java | 10 ++++++++-- 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/shaded-lock-ydb/pom.xml b/shaded-lock-ydb/pom.xml index d32ad15..855feb8 100644 --- a/shaded-lock-ydb/pom.xml +++ b/shaded-lock-ydb/pom.xml @@ -6,7 +6,7 @@ tech.ydb.dialects shaded-lock-ydb - 0.9.1 + 0.1.0 jar diff --git a/shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbCoordinationServiceLockProvider.java b/shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbCoordinationServiceLockProvider.java index b93c502..9238e96 100644 --- a/shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbCoordinationServiceLockProvider.java +++ b/shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbCoordinationServiceLockProvider.java @@ -57,6 +57,7 @@ public Optional lock(LockConfiguration lockConfiguration) { if (semaphoreLease.isSuccess()) { logger.debug("Semaphore acquired"); + System.out.println(semaphoreLease.getStatus()); return Optional.of(new YdbSimpleLock(semaphoreLease.getValue())); } else { return Optional.empty(); diff --git a/shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbLockProviderConfiguration.java b/shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbLockProviderConfiguration.java index 786f375..a3507bb 100644 --- a/shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbLockProviderConfiguration.java +++ b/shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbLockProviderConfiguration.java @@ -14,6 +14,10 @@ public class YdbLockProviderConfiguration { @Bean public YdbCoordinationServiceLockProvider ydbLockProvider(DataSource dataSource) throws SQLException { - return new YdbCoordinationServiceLockProvider(dataSource.getConnection().unwrap(YdbConnection.class)); + var provider = new YdbCoordinationServiceLockProvider(dataSource.getConnection().unwrap(YdbConnection.class)); + + provider.init(); + + return provider; } } diff --git a/shaded-lock-ydb/src/test/java/tech/ydb/lock/provider/YdbLockProviderTest.java b/shaded-lock-ydb/src/test/java/tech/ydb/lock/provider/YdbLockProviderTest.java index e4c226e..2666768 100644 --- a/shaded-lock-ydb/src/test/java/tech/ydb/lock/provider/YdbLockProviderTest.java +++ b/shaded-lock-ydb/src/test/java/tech/ydb/lock/provider/YdbLockProviderTest.java @@ -7,6 +7,7 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; import java.util.concurrent.Future; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import net.javacrumbs.shedlock.core.LockConfiguration; import net.javacrumbs.shedlock.core.SimpleLock; @@ -53,13 +54,12 @@ private static String jdbcUrl() { public void integrationTest() throws ExecutionException, InterruptedException { var executorServer = Executors.newFixedThreadPool(10); var atomicInt = new AtomicInteger(); + var locked = new AtomicBoolean(); var futures = new ArrayList>(); for (int i = 0; i < 100; i++) { final var ii = i; futures.add(executorServer.submit(() -> { - lockProvider.init(); - Optional optinal = Optional.empty(); while (optinal.isEmpty()) { @@ -67,6 +67,11 @@ public void integrationTest() throws ExecutionException, InterruptedException { new LockConfiguration(Instant.now(), "semaphore", Duration.ZERO, Duration.ZERO)); optinal.ifPresent(simpleLock -> { + if (locked.get()) { + throw new RuntimeException(); + } + locked.set(true); + try { Thread.sleep(100); } catch (InterruptedException e) { @@ -74,6 +79,7 @@ public void integrationTest() throws ExecutionException, InterruptedException { } atomicInt.addAndGet(ii); + locked.set(false); simpleLock.unlock(); }); } From cf7e2e78ac9e89b929c954ed9fe84bb064ef9b3d Mon Sep 17 00:00:00 2001 From: Kirill Kurdyukov Date: Wed, 21 Aug 2024 15:39:06 +0300 Subject: [PATCH 5/7] feat: rename module add ci + publish --- .github/workflows/ci-shedlock.yaml | 47 ++++++++++ .github/workflows/publish-shedlock-ydb.yaml | 85 +++++++++++++++++++ {shaded-lock-ydb => shedlock-ydb}/pom.xml | 6 +- .../YdbCoordinationServiceLockProvider.java | 1 + .../YdbLockProviderConfiguration.java | 0 .../tech/ydb/lock/provider/package-info.java | 0 .../main/resources/META-INF/spring.factories | 0 .../java/tech/ydb/lock/provider/TestApp.java | 0 .../lock/provider/YdbLockProviderTest.java | 0 .../src/test/resources/application.properties | 0 10 files changed, 136 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/ci-shedlock.yaml create mode 100644 .github/workflows/publish-shedlock-ydb.yaml rename {shaded-lock-ydb => shedlock-ydb}/pom.xml (97%) rename {shaded-lock-ydb => shedlock-ydb}/src/main/java/tech/ydb/lock/provider/YdbCoordinationServiceLockProvider.java (98%) rename {shaded-lock-ydb => shedlock-ydb}/src/main/java/tech/ydb/lock/provider/YdbLockProviderConfiguration.java (100%) rename {shaded-lock-ydb => shedlock-ydb}/src/main/java/tech/ydb/lock/provider/package-info.java (100%) rename {shaded-lock-ydb => shedlock-ydb}/src/main/resources/META-INF/spring.factories (100%) rename {shaded-lock-ydb => shedlock-ydb}/src/test/java/tech/ydb/lock/provider/TestApp.java (100%) rename {shaded-lock-ydb => shedlock-ydb}/src/test/java/tech/ydb/lock/provider/YdbLockProviderTest.java (100%) rename {shaded-lock-ydb => shedlock-ydb}/src/test/resources/application.properties (100%) diff --git a/.github/workflows/ci-shedlock.yaml b/.github/workflows/ci-shedlock.yaml new file mode 100644 index 0000000..cbec187 --- /dev/null +++ b/.github/workflows/ci-shedlock.yaml @@ -0,0 +1,47 @@ +name: YDB ShedLock CI with Maven + +on: + push: + paths: + - 'shedlock-ydb/**' + branches: + - main + pull_request: + paths: + - 'shedlock-ydb/**' + +env: + MAVEN_ARGS: --batch-mode --update-snapshots -Dstyle.color=always + +jobs: + build: + name: YDB ShedLock Lock Provider + runs-on: ubuntu-latest + + strategy: + matrix: + java: [ '17', '21' ] + + steps: + - uses: actions/checkout@v4 + + - name: Set up JDK ${{matrix.java}} + uses: actions/setup-java@v4 + with: + java-version: ${{matrix.java}} + distribution: 'temurin' + cache: maven + + - name: Extract YDB ShedLock Lock Provider version + working-directory: ./shedlock-ydb + run: | + VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) + echo "SHEDLOCK_VERSION=$VERSION" >> "$GITHUB_ENV" + + - name: Download ShedLock Lock Provider dependencies + working-directory: ./shedlock-ydb + run: mvn $MAVEN_ARGS dependency:go-offline + + - name: Build ShedLock Lock Provider + working-directory: ./shedlock-ydb + run: mvn $MAVEN_ARGS clean test diff --git a/.github/workflows/publish-shedlock-ydb.yaml b/.github/workflows/publish-shedlock-ydb.yaml new file mode 100644 index 0000000..a49604d --- /dev/null +++ b/.github/workflows/publish-shedlock-ydb.yaml @@ -0,0 +1,85 @@ +name: Publish YDB ShedLock + +on: + push: + tags: + - 'shedlock-ydb/v[0-9]+.[0-9]+.[0-9]+' + +env: + MAVEN_ARGS: --batch-mode --no-transfer-progress -Dstyle.color=always + +jobs: + validate: + name: Validate YDB ShedLock + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Extract shedlock ydb version + run: | + cd shedlock-ydb + SHEDLOCK_VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) + echo "SHEDLOCK_VERSION=$SHEDLOCK_VERSION" >> "$GITHUB_ENV" + + - name: Fail workflow if version is snapshot + if: endsWith(env.SHEDLOCK_VERSION, 'SNAPSHOT') + uses: actions/github-script@v6 + with: + script: core.setFailed('SNAPSHOT version cannot be published') + + - name: Fail workflow if version is not equal to tag name + if: format('shedlock-ydb/v{0}', env.SHEDLOCK_VERSION) != github.ref_name + uses: actions/github-script@v6 + with: + script: core.setFailed('Release name must be equal to project version') + + - name: Set up JDK + uses: actions/setup-java@v4 + with: + java-version: 17 + distribution: 'temurin' + cache: 'maven' + + - name: Download dependencies + run: | + cd shedlock-ydb + mvn $MAVEN_ARGS dependency:go-offline + + - name: Build with Maven + run: | + cd shedlock-ydb + mvn $MAVEN_ARGS package + + publish: + name: Publish YDB ShedLock + runs-on: ubuntu-latest + needs: validate + + steps: + - name: Install gpg secret key + run: | + # Install gpg secret key + cat <(echo -e "${{ secrets.MAVEN_OSSRH_GPG_SECRET_KEY }}") | gpg --batch --import + # Verify gpg secret key + gpg --list-secret-keys --keyid-format LONG + + - uses: actions/checkout@v4 + + - name: Set up Maven Central Repository + uses: actions/setup-java@v4 + with: + java-version: 17 + distribution: 'temurin' + cache: 'maven' + server-id: ossrh-s01 + server-username: MAVEN_USERNAME + server-password: MAVEN_PASSWORD + + - name: Publish package + run: | + cd shedlock-ydb + mvn $MAVEN_ARGS -Possrh-s01 -Dgpg.passphrase=${{ secrets.MAVEN_OSSRH_GPG_PASSWORD }} clean deploy + env: + MAVEN_USERNAME: ${{ secrets.MAVEN_OSSRH_USERNAME }} + MAVEN_PASSWORD: ${{ secrets.MAVEN_OSSRH_TOKEN }} diff --git a/shaded-lock-ydb/pom.xml b/shedlock-ydb/pom.xml similarity index 97% rename from shaded-lock-ydb/pom.xml rename to shedlock-ydb/pom.xml index 855feb8..82234b9 100644 --- a/shaded-lock-ydb/pom.xml +++ b/shedlock-ydb/pom.xml @@ -5,13 +5,13 @@ 4.0.0 tech.ydb.dialects - shaded-lock-ydb + shedlock-ydb 0.1.0 jar - Shaded Lock Service YDB - Shaded Lock Service YDB Spring Starter + ShedLock Service YDB + Lock Service YDB Spring Starter https://github.com/ydb-platform/ydb-java-dialects diff --git a/shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbCoordinationServiceLockProvider.java b/shedlock-ydb/src/main/java/tech/ydb/lock/provider/YdbCoordinationServiceLockProvider.java similarity index 98% rename from shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbCoordinationServiceLockProvider.java rename to shedlock-ydb/src/main/java/tech/ydb/lock/provider/YdbCoordinationServiceLockProvider.java index 9238e96..3226fe0 100644 --- a/shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbCoordinationServiceLockProvider.java +++ b/shedlock-ydb/src/main/java/tech/ydb/lock/provider/YdbCoordinationServiceLockProvider.java @@ -60,6 +60,7 @@ public Optional lock(LockConfiguration lockConfiguration) { System.out.println(semaphoreLease.getStatus()); return Optional.of(new YdbSimpleLock(semaphoreLease.getValue())); } else { + logger.debug("Semaphore is not acquired"); return Optional.empty(); } } diff --git a/shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbLockProviderConfiguration.java b/shedlock-ydb/src/main/java/tech/ydb/lock/provider/YdbLockProviderConfiguration.java similarity index 100% rename from shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/YdbLockProviderConfiguration.java rename to shedlock-ydb/src/main/java/tech/ydb/lock/provider/YdbLockProviderConfiguration.java diff --git a/shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/package-info.java b/shedlock-ydb/src/main/java/tech/ydb/lock/provider/package-info.java similarity index 100% rename from shaded-lock-ydb/src/main/java/tech/ydb/lock/provider/package-info.java rename to shedlock-ydb/src/main/java/tech/ydb/lock/provider/package-info.java diff --git a/shaded-lock-ydb/src/main/resources/META-INF/spring.factories b/shedlock-ydb/src/main/resources/META-INF/spring.factories similarity index 100% rename from shaded-lock-ydb/src/main/resources/META-INF/spring.factories rename to shedlock-ydb/src/main/resources/META-INF/spring.factories diff --git a/shaded-lock-ydb/src/test/java/tech/ydb/lock/provider/TestApp.java b/shedlock-ydb/src/test/java/tech/ydb/lock/provider/TestApp.java similarity index 100% rename from shaded-lock-ydb/src/test/java/tech/ydb/lock/provider/TestApp.java rename to shedlock-ydb/src/test/java/tech/ydb/lock/provider/TestApp.java diff --git a/shaded-lock-ydb/src/test/java/tech/ydb/lock/provider/YdbLockProviderTest.java b/shedlock-ydb/src/test/java/tech/ydb/lock/provider/YdbLockProviderTest.java similarity index 100% rename from shaded-lock-ydb/src/test/java/tech/ydb/lock/provider/YdbLockProviderTest.java rename to shedlock-ydb/src/test/java/tech/ydb/lock/provider/YdbLockProviderTest.java diff --git a/shaded-lock-ydb/src/test/resources/application.properties b/shedlock-ydb/src/test/resources/application.properties similarity index 100% rename from shaded-lock-ydb/src/test/resources/application.properties rename to shedlock-ydb/src/test/resources/application.properties From 7a9c81b98613fad4681539bdeb3f50d6a3fd7b31 Mon Sep 17 00:00:00 2001 From: Kirill Kurdyukov Date: Wed, 21 Aug 2024 15:42:56 +0300 Subject: [PATCH 6/7] feat: rename module add ci + publish --- .../ydb/lock/provider/YdbCoordinationServiceLockProvider.java | 1 - 1 file changed, 1 deletion(-) diff --git a/shedlock-ydb/src/main/java/tech/ydb/lock/provider/YdbCoordinationServiceLockProvider.java b/shedlock-ydb/src/main/java/tech/ydb/lock/provider/YdbCoordinationServiceLockProvider.java index 3226fe0..352de67 100644 --- a/shedlock-ydb/src/main/java/tech/ydb/lock/provider/YdbCoordinationServiceLockProvider.java +++ b/shedlock-ydb/src/main/java/tech/ydb/lock/provider/YdbCoordinationServiceLockProvider.java @@ -57,7 +57,6 @@ public Optional lock(LockConfiguration lockConfiguration) { if (semaphoreLease.isSuccess()) { logger.debug("Semaphore acquired"); - System.out.println(semaphoreLease.getStatus()); return Optional.of(new YdbSimpleLock(semaphoreLease.getValue())); } else { logger.debug("Semaphore is not acquired"); From 35d0a2bcc4f4be9522c9b03162b09782b70329b6 Mon Sep 17 00:00:00 2001 From: Kirill Kurdyukov Date: Wed, 21 Aug 2024 16:21:47 +0300 Subject: [PATCH 7/7] feat: update starter --- shedlock-ydb/src/main/resources/META-INF/spring.factories | 1 - ....springframework.boot.autoconfigure.AutoConfiguration.imports | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 shedlock-ydb/src/main/resources/META-INF/spring.factories create mode 100644 shedlock-ydb/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports diff --git a/shedlock-ydb/src/main/resources/META-INF/spring.factories b/shedlock-ydb/src/main/resources/META-INF/spring.factories deleted file mode 100644 index 3bcab04..0000000 --- a/shedlock-ydb/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=tech.ydb.lock.provider.YdbLockProviderConfiguration \ No newline at end of file diff --git a/shedlock-ydb/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/shedlock-ydb/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..67f34c0 --- /dev/null +++ b/shedlock-ydb/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +tech.ydb.lock.provider.YdbLockProviderConfiguration \ No newline at end of file