diff --git a/sdk-tests/src/test/java/io/dapr/it/testcontainers/DaprContainerIT.java b/sdk-tests/src/test/java/io/dapr/it/testcontainers/DaprContainerIT.java index 795227041..66c8e68f3 100644 --- a/sdk-tests/src/test/java/io/dapr/it/testcontainers/DaprContainerIT.java +++ b/sdk-tests/src/test/java/io/dapr/it/testcontainers/DaprContainerIT.java @@ -20,7 +20,9 @@ import io.dapr.client.domain.State; import io.dapr.config.Properties; +import io.dapr.testcontainers.Configuration; import io.dapr.testcontainers.DaprContainer; +import io.dapr.testcontainers.TracingConfigParameters; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; @@ -65,6 +67,9 @@ public class DaprContainerIT { private static final DaprContainer DAPR_CONTAINER = new DaprContainer("daprio/daprd") .withAppName("dapr-app") .withAppPort(8081) + .withConfiguration(new Configuration("my-config", + new TracingConfigParameters("1", true, + "localhost:4317", false, "grpc"))) .withAppChannelAddress("host.testcontainers.internal"); /** @@ -104,6 +109,19 @@ public void testDaprContainerDefaults() { DAPR_CONTAINER.getSubscriptions().size(), "A subscription should be configured by default if none is provided" ); + + assertEquals( + 1, + DAPR_CONTAINER.getConfigurations().size(), + "A configuration should be configured" + ); + + Configuration configuration = DAPR_CONTAINER.getConfigurations().iterator().next(); + assertEquals("1",configuration.getTracing().getSamplingRate()); + assertEquals(true,configuration.getTracing().getStdout()); + assertEquals("localhost:4317",configuration.getTracing().getOtelEndpoint()); + assertEquals("grpc",configuration.getTracing().getOtelProtocol()); + assertEquals(false,configuration.getTracing().getOtelIsSecure()); } @Test diff --git a/testcontainers-dapr/src/main/java/io/dapr/testcontainers/Configuration.java b/testcontainers-dapr/src/main/java/io/dapr/testcontainers/Configuration.java new file mode 100644 index 000000000..5bf1ebc4b --- /dev/null +++ b/testcontainers-dapr/src/main/java/io/dapr/testcontainers/Configuration.java @@ -0,0 +1,45 @@ +/* + * Copyright 2024 The Dapr Authors + * 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 io.dapr.testcontainers; + +/** + * Represents a Dapr component. + */ +public class Configuration { + private String name; + private TracingConfigParameters tracing; + + //@TODO: add httpPipeline + //@TODO: add secrets + //@TODO: add components + //@TODO: add accessControl + + /** + * Creates a new configuration. + * @param name Configuration name. + * @param tracing TracingConfigParameters tracing configuration parameters. + */ + public Configuration(String name, TracingConfigParameters tracing) { + this.name = name; + this.tracing = tracing; + } + + public String getName() { + return name; + } + + public TracingConfigParameters getTracing() { + return tracing; + } +} diff --git a/testcontainers-dapr/src/main/java/io/dapr/testcontainers/DaprContainer.java b/testcontainers-dapr/src/main/java/io/dapr/testcontainers/DaprContainer.java index 4ddbd7d6b..0ea4c67fa 100644 --- a/testcontainers-dapr/src/main/java/io/dapr/testcontainers/DaprContainer.java +++ b/testcontainers-dapr/src/main/java/io/dapr/testcontainers/DaprContainer.java @@ -45,6 +45,7 @@ public class DaprContainer extends GenericContainer { .forStatusCodeMatching(statusCode -> statusCode >= 200 && statusCode <= 399); private final Set components = new HashSet<>(); + private final Set configurations = new HashSet<>(); private final Set subscriptions = new HashSet<>(); private DaprProtocol protocol = DaprProtocol.HTTP; private String appName; @@ -86,6 +87,10 @@ public Set getSubscriptions() { return subscriptions; } + public Set getConfigurations() { + return configurations; + } + public DaprContainer withAppPort(Integer port) { this.appPort = port; return this; @@ -149,6 +154,11 @@ public DaprContainer withComponent(Path path) { return this; } + public DaprContainer withConfiguration(Configuration configuration) { + configurations.add(configuration); + return this; + } + public int getHttpPort() { return getMappedPort(DAPRD_DEFAULT_HTTP_PORT); } @@ -170,6 +180,41 @@ public DaprContainer withAppChannelAddress(String appChannelAddress) { return this; } + + /** + * Get a map of Dapr component details. + * @param configuration A Dapr Configuration. + * @return Map of component details. + */ + public Map configurationToMap(Configuration configuration) { + Map configurationProps = new HashMap<>(); + configurationProps.put("apiVersion", "dapr.io/v1alpha1"); + configurationProps.put("kind", "Configuration"); + + Map configurationMetadata = new LinkedHashMap<>(); + configurationMetadata.put("name", configuration.getName()); + configurationProps.put("metadata", configurationMetadata); + + Map configurationSpec = new HashMap<>(); + + + Map configurationTracing = new HashMap<>(); + Map configurationTracingOtel = new HashMap<>(); + if (configuration.getTracing() != null) { + configurationTracing.put("samplingRate", configuration.getTracing().getSamplingRate()); + configurationTracing.put("stdout", configuration.getTracing().getStdout()); + configurationTracingOtel.put("endpointAddress", configuration.getTracing().getOtelEndpoint()); + configurationTracingOtel.put("isSecure", configuration.getTracing().getOtelIsSecure()); + configurationTracingOtel.put("protocol", configuration.getTracing().getOtelProtocol()); + } + + configurationTracing.put("otel", configurationTracingOtel); + configurationSpec.put("tracing", configurationTracing); + + configurationProps.put("spec", configurationSpec); + return Collections.unmodifiableMap(configurationProps); + } + /** * Get a map of Dapr component details. * @param component A Dapr Component. @@ -275,6 +320,11 @@ protected void configure() { withCopyToContainer(Transferable.of(componentYaml), "/dapr-resources/" + component.getName() + ".yaml"); } + for (Configuration configuration : configurations) { + String configurationYaml = configurationToYaml(configuration); + withCopyToContainer(Transferable.of(configurationYaml), "/dapr-resources/" + configuration.getName() + ".yaml"); + } + for (Subscription subscription : subscriptions) { String subscriptionYaml = subscriptionToYaml(subscription); withCopyToContainer(Transferable.of(subscriptionYaml), "/dapr-resources/" + subscription.getName() + ".yaml"); @@ -293,6 +343,11 @@ public String componentToYaml(Component component) { return yaml.dumpAsMap(componentMap); } + public String configurationToYaml(Configuration configuration) { + Map configurationMap = configurationToMap(configuration); + return yaml.dumpAsMap(configurationMap); + } + public String getAppName() { return appName; } diff --git a/testcontainers-dapr/src/main/java/io/dapr/testcontainers/TracingConfigParameters.java b/testcontainers-dapr/src/main/java/io/dapr/testcontainers/TracingConfigParameters.java new file mode 100644 index 000000000..1983946d5 --- /dev/null +++ b/testcontainers-dapr/src/main/java/io/dapr/testcontainers/TracingConfigParameters.java @@ -0,0 +1,72 @@ +/* + * Copyright 2024 The Dapr Authors + * 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 io.dapr.testcontainers; + +/** + * Represents a Dapr tracing configuration parameters . + */ +public class TracingConfigParameters { + + private String samplingRate; + private Boolean stdout; + private String otelEndpoint; + private Boolean otelIsSecure; + private String otelProtocol; + + //@TODO: add zipkin parameters + + + /** + * Creates a new configuration. + */ + public TracingConfigParameters() { + } + + /** + * Creates a new configuration. + * @param samplingRate tracing sampling rate + * @param stdout if it should send traces to the system standard output + * @param otelEndpoint if using OpenTelemetry where the collector endpoint is + * @param otelIsSecure if using OpenTelemetry if the channel is secure + * @param otelProtocol if using OpenTelemetry which protocol is being used http or grpc + */ + public TracingConfigParameters(String samplingRate, Boolean stdout, + String otelEndpoint, Boolean otelIsSecure, String otelProtocol) { + this.samplingRate = samplingRate; + this.stdout = stdout; + this.otelEndpoint = otelEndpoint; + this.otelIsSecure = otelIsSecure; + this.otelProtocol = otelProtocol; + } + + public String getSamplingRate() { + return this.samplingRate; + } + + public Boolean getStdout() { + return this.stdout; + } + + public String getOtelEndpoint() { + return this.otelEndpoint; + } + + public Boolean getOtelIsSecure() { + return this.otelIsSecure; + } + + public String getOtelProtocol() { + return this.otelProtocol; + } +} diff --git a/testcontainers-dapr/src/test/java/io/dapr/testcontainers/DaprComponentTest.java b/testcontainers-dapr/src/test/java/io/dapr/testcontainers/DaprComponentTest.java index 2a5db5967..e91d57c0d 100644 --- a/testcontainers-dapr/src/test/java/io/dapr/testcontainers/DaprComponentTest.java +++ b/testcontainers-dapr/src/test/java/io/dapr/testcontainers/DaprComponentTest.java @@ -95,6 +95,40 @@ public void subscriptionSerializationTest() { assertEquals(expectedSubscriptionYaml, subscriptionYaml); } + + @Test + public void configurationSerializationTest() { + + DaprContainer dapr = new DaprContainer("daprio/daprd") + .withAppName("dapr-app") + .withAppPort(8081) + .withConfiguration(new Configuration("my-config", + new TracingConfigParameters("1", true, + "localhost:4317", false, "grpc"))) + .withAppChannelAddress("host.testcontainers.internal"); + + Set configurations = dapr.getConfigurations(); + assertEquals(1, configurations.size()); + + String configurationYaml = dapr.configurationToYaml(configurations.iterator().next()); + String expectedConfigurationYaml = "metadata:\n" + " name: my-config\n" + + "apiVersion: dapr.io/v1alpha1\n" + + "kind: Configuration\n" + + "spec:\n" + + " tracing:\n" +// + " samplingRate: \"1\"\n" + + " stdout: true\n" + + " samplingRate: '1'\n" + + " otel:\n" +// + " endpointAddress: \"localhost:4317\"\n" + + " endpointAddress: localhost:4317\n" +// + " protocol: \"grpc\"\n" + + " protocol: grpc\n" + + " isSecure: false\n"; + assertEquals(expectedConfigurationYaml, configurationYaml); + } + + @Test public void withComponentFromPath() { URL stateStoreYaml = this.getClass().getClassLoader().getResource("dapr-resources/statestore.yaml");