Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,9 @@ public synchronized void start() {

// Workers check and require that Temporal Server is available during start to fail-fast in case
// of configuration issues.
workflowClient.getWorkflowServiceStubs().connect(null);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

connect was already calling getServerCapabilities but then made a gRPC health check call after which is unnecessary and failed with API keys since it didn't have a namespace

// TODO(https://github.com/temporalio/sdk-java/issues/2060) consider using describeNamespace as
// a connection check.
workflowClient.getWorkflowServiceStubs().getServerCapabilities();

for (Worker worker : workers.values()) {
worker.start();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public WorkflowServiceStubsOptions createServiceStubOptions() {

stubsOptionsBuilder.setEnableHttps(Boolean.TRUE.equals(connectionProperties.isEnableHttps()));

if (connectionProperties.getApiKey() != null && connectionProperties.getApiKey().isEmpty()) {
if (connectionProperties.getApiKey() != null && !connectionProperties.getApiKey().isEmpty()) {
stubsOptionsBuilder.addApiKey(() -> connectionProperties.getApiKey());
Copy link

@nzuguem nzuguem Mar 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With Spring Boot (v1.28.1), for this to work, I have to configure TemporalOptionsCustomizer<WorkflowServiceStubsOptions.Builder> as follows :

    @Bean
    public TemporalOptionsCustomizer<WorkflowServiceStubsOptions.Builder>
    customServiceStubsOptions() {

        return optionsBuilder -> {

            try {
                optionsBuilder.setSslContext(
                        SimpleSslContextBuilder.noKeyOrCertChain().setUseInsecureTrustManager(false).build());
            } catch (SSLException e) {
                throw new RuntimeException(e);
            }

            return optionsBuilder;
        };
    }

To force the use of Java's default Trust Managers. I confess I don't understand why you need to do this (although with Temporal SDK directly I don't need it).

I based this on the configuration used on Quarkus : https://github.com/quarkiverse/quarkus-temporal/blob/6beb65c18520699577eb2682704bb01fc0d81566/extension/runtime/src/main/java/io/quarkiverse/temporal/WorkflowServiceStubsRecorder.java#L88

Without this configuration I have this stacktrace :

2025-03-18T07:09:26.876+01:00 ERROR 69044 --- [           main] o.s.boot.SpringApplication               : Application run failed

io.grpc.StatusRuntimeException: UNAVAILABLE: io exception
        at io.grpc.stub.ClientCalls.toStatusRuntimeException(ClientCalls.java:268) ~[grpc-stub-1.58.1.jar:1.58.1]
        at io.grpc.stub.ClientCalls.getUnchecked(ClientCalls.java:249) ~[grpc-stub-1.58.1.jar:1.58.1]
        at io.grpc.stub.ClientCalls.blockingUnaryCall(ClientCalls.java:167) ~[grpc-stub-1.58.1.jar:1.58.1]
        at io.temporal.api.workflowservice.v1.WorkflowServiceGrpc$WorkflowServiceBlockingStub.getSystemInfo(WorkflowServiceGrpc.java:6065) ~[temporal-serviceclient-1.28.1.jar:1.28.1]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is already fixed 48b7223 just not released yet

// Unless HTTPS is explicitly disabled, enable it by default for API keys
if (connectionProperties.isEnableHttps() == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@

package io.temporal.spring.boot.autoconfigure;

import io.temporal.authorization.AuthorizationGrpcMetadataProvider;
import io.temporal.client.WorkflowClient;
import io.temporal.serviceclient.WorkflowServiceStubs;
import io.temporal.spring.boot.autoconfigure.properties.TemporalProperties;
import org.junit.jupiter.api.*;
import org.springframework.beans.factory.annotation.Autowired;
Expand All @@ -38,6 +40,7 @@ public class ApiKeyAuthTest {

@Autowired TemporalProperties temporalProperties;
@Autowired WorkflowClient workflowClient;
@Autowired WorkflowServiceStubs workflowServiceStubs;

@BeforeEach
void setUp() {
Expand All @@ -47,6 +50,15 @@ void setUp() {
@Test
public void testProperties() {
Assertions.assertEquals("my-api-key", temporalProperties.getConnection().getApiKey());
Assertions.assertEquals(1, workflowServiceStubs.getOptions().getGrpcMetadataProviders().size());
Assertions.assertTrue(
workflowServiceStubs.getOptions().getGrpcMetadataProviders().stream()
.allMatch(
provider ->
provider
.getMetadata()
.get(AuthorizationGrpcMetadataProvider.AUTHORIZATION_HEADER_KEY)
.equals("Bearer my-api-key")));
}

@ComponentScan(
Expand Down
Loading