diff --git a/temporal-spring-boot-autoconfigure/src/main/java/io/temporal/spring/boot/autoconfigure/properties/WorkerProperties.java b/temporal-spring-boot-autoconfigure/src/main/java/io/temporal/spring/boot/autoconfigure/properties/WorkerProperties.java index 882b1c65b..fb5d2ddff 100644 --- a/temporal-spring-boot-autoconfigure/src/main/java/io/temporal/spring/boot/autoconfigure/properties/WorkerProperties.java +++ b/temporal-spring-boot-autoconfigure/src/main/java/io/temporal/spring/boot/autoconfigure/properties/WorkerProperties.java @@ -385,6 +385,8 @@ public static class WorkerDeploymentConfigurationProperties { private final @Nullable String deploymentVersion; private final @Nullable Boolean useVersioning; private final @Nullable VersioningBehavior defaultVersioningBehavior; + private final @Nullable String deploymentName; + private final @Nullable String buildId; /** * Sets options that will be passed to {@link @@ -396,15 +398,25 @@ public static class WorkerDeploymentConfigurationProperties { * io.temporal.worker.WorkerDeploymentOptions.Builder#setUseVersioning(boolean)} * @param defaultVersioningBehavior defines {@link * io.temporal.worker.WorkerDeploymentOptions.Builder#setDefaultVersioningBehavior(VersioningBehavior)} + * @param deploymentName defines the deployment name component of {@link + * io.temporal.worker.WorkerDeploymentOptions.Builder#setVersion(WorkerDeploymentVersion)}. + * Exclusive with `deploymentVersion`. + * @param buildId defines the build id component of {@link + * io.temporal.worker.WorkerDeploymentOptions.Builder#setVersion(WorkerDeploymentVersion)}. + * Exclusive with `deploymentVersion`. */ @ConstructorBinding public WorkerDeploymentConfigurationProperties( - @Nullable String deploymentVersion, + @Deprecated @Nullable String deploymentVersion, @Nullable Boolean useVersioning, - @Nullable VersioningBehavior defaultVersioningBehavior) { + @Nullable VersioningBehavior defaultVersioningBehavior, + @Nullable String deploymentName, + @Nullable String buildId) { this.deploymentVersion = deploymentVersion; this.useVersioning = useVersioning; this.defaultVersioningBehavior = defaultVersioningBehavior; + this.deploymentName = deploymentName; + this.buildId = buildId; } @Nullable @@ -421,5 +433,15 @@ public Boolean getUseVersioning() { public VersioningBehavior getDefaultVersioningBehavior() { return defaultVersioningBehavior; } + + @Nullable + public String getDeploymentName() { + return deploymentName; + } + + @Nullable + public String getBuildId() { + return buildId; + } } } diff --git a/temporal-spring-boot-autoconfigure/src/main/java/io/temporal/spring/boot/autoconfigure/template/WorkerOptionsTemplate.java b/temporal-spring-boot-autoconfigure/src/main/java/io/temporal/spring/boot/autoconfigure/template/WorkerOptionsTemplate.java index daf965faa..c2c4e3880 100644 --- a/temporal-spring-boot-autoconfigure/src/main/java/io/temporal/spring/boot/autoconfigure/template/WorkerOptionsTemplate.java +++ b/temporal-spring-boot-autoconfigure/src/main/java/io/temporal/spring/boot/autoconfigure/template/WorkerOptionsTemplate.java @@ -132,10 +132,28 @@ WorkerOptions createWorkerOptions() { WorkerDeploymentOptions.Builder opts = WorkerDeploymentOptions.newBuilder(); Optional.ofNullable(workerDeploymentConfiguration.getUseVersioning()) .ifPresent(opts::setUseVersioning); - Optional.ofNullable(workerDeploymentConfiguration.getDeploymentVersion()) - .ifPresent((v) -> opts.setVersion(WorkerDeploymentVersion.fromCanonicalString(v))); Optional.ofNullable(workerDeploymentConfiguration.getDefaultVersioningBehavior()) .ifPresent(opts::setDefaultVersioningBehavior); + + if (workerDeploymentConfiguration.getDeploymentName() != null + || workerDeploymentConfiguration.getBuildId() != null) { + if (workerDeploymentConfiguration.getBuildId() == null + || workerDeploymentConfiguration.getDeploymentName() == null) { + throw new IllegalArgumentException( + "deploymentName and buildId must both be set when either is specified"); + } + if (workerDeploymentConfiguration.getDeploymentVersion() != null) { + throw new IllegalArgumentException( + "deploymentVersion is exclusive with deploymentName and buildId"); + } + opts.setVersion( + new WorkerDeploymentVersion( + workerDeploymentConfiguration.getDeploymentName(), + workerDeploymentConfiguration.getBuildId())); + } else { + Optional.ofNullable(workerDeploymentConfiguration.getDeploymentVersion()) + .ifPresent((v) -> opts.setVersion(WorkerDeploymentVersion.fromCanonicalString(v))); + } options.setDeploymentOptions(opts.build()); } } diff --git a/temporal-spring-boot-autoconfigure/src/test/java/io/temporal/spring/boot/autoconfigure/WorkerVersioningMissingAnnotationTest.java b/temporal-spring-boot-autoconfigure/src/test/java/io/temporal/spring/boot/autoconfigure/WorkerVersioningMissingAnnotationTest.java index 2942ec569..4137c34ec 100644 --- a/temporal-spring-boot-autoconfigure/src/test/java/io/temporal/spring/boot/autoconfigure/WorkerVersioningMissingAnnotationTest.java +++ b/temporal-spring-boot-autoconfigure/src/test/java/io/temporal/spring/boot/autoconfigure/WorkerVersioningMissingAnnotationTest.java @@ -29,6 +29,39 @@ void testFailsToLoad() { assertThat(e).hasMessageContaining("must have a VersioningBehavior set"); } + @Test + void testFailsWithMissingBuildId() { + BeanCreationException e = + assertThrows( + BeanCreationException.class, + () -> { + try (ConfigurableApplicationContext ignored = + new SpringApplicationBuilder(Configuration.class) + .profiles("worker-versioning-need-both-deployname-buildid") + .run()) { + fail("Should not load"); + } + }); + assertThat(e).hasMessageContaining("deploymentName and buildId must both be set"); + } + + @Test + void testFailsWithBothVersionOptions() { + BeanCreationException e = + assertThrows( + BeanCreationException.class, + () -> { + try (ConfigurableApplicationContext ignored = + new SpringApplicationBuilder(Configuration.class) + .profiles("worker-versioning-cant-use-old-version-and-new") + .run()) { + fail("Should not load"); + } + }); + assertThat(e) + .hasMessageContaining("deploymentVersion is exclusive with deploymentName and buildId"); + } + @ComponentScan( excludeFilters = @ComponentScan.Filter( diff --git a/temporal-spring-boot-autoconfigure/src/test/resources/application.yml b/temporal-spring-boot-autoconfigure/src/test/resources/application.yml index 31513d9e9..fd1f25257 100644 --- a/temporal-spring-boot-autoconfigure/src/test/resources/application.yml +++ b/temporal-spring-boot-autoconfigure/src/test/resources/application.yml @@ -190,7 +190,8 @@ spring: name: mainWorker deployment-properties: default-versioning-behavior: PINNED - deployment-version: "dname.bid" + deployment-name: "dname" + build-id: "bid" use-versioning: true --- @@ -210,3 +211,39 @@ spring: # missing default is the key thing here deployment-version: "dname.bid" use-versioning: true +--- +spring: + config: + activate: + on-profile: worker-versioning-need-both-deployname-buildid + temporal: + namespace: UnitTest + workers-auto-discovery: + packages: + - io.temporal.spring.boot.autoconfigure.workerversioning + workers: + - task-queue: UnitTest + name: mainWorker + deployment-properties: + use-versioning: true + default-versioning-behavior: PINNED + deployment-name: "dname" +--- +spring: + config: + activate: + on-profile: worker-versioning-cant-use-old-version-and-new + temporal: + namespace: UnitTest + workers-auto-discovery: + packages: + - io.temporal.spring.boot.autoconfigure.workerversioning + workers: + - task-queue: UnitTest + name: mainWorker + deployment-properties: + use-versioning: true + default-versioning-behavior: PINNED + deployment-name: "dname" + build-id: "bid" + deployment-version: "dname.bid"