diff --git a/.github/publish-maven.sh b/.github/publish-maven.sh index e9edc8660..bb938174b 100755 --- a/.github/publish-maven.sh +++ b/.github/publish-maven.sh @@ -56,7 +56,7 @@ cat <~/.m2/settings.xml true - ${PGP_PASSPHRASE} + diff --git a/.github/workflows/docs-cli-updates.yml b/.github/workflows/docs-cli-updates.yml index e927cd346..976b6931f 100644 --- a/.github/workflows/docs-cli-updates.yml +++ b/.github/workflows/docs-cli-updates.yml @@ -19,18 +19,18 @@ jobs: with: ruby-version: '3.1' - - name: Install Akka CLI + - name: Install Akka CLI and create the CLI docs id: install-cli run: | export CLI_INSTALL_PATH=$HOME/.akka/bin + export PATH=${PATH}:${CLI_INSTALL_PATH} mkdir -p ${CLI_INSTALL_PATH} - curl -sL https://docs.akka.io/install-cli.sh | bash -s -- -y -P ${CLI_INSTALL_PATH} - echo ${CLI_INSTALL_PATH} >> ${GITHUB_PATH} - echo "CLI_VERSION=$(${CLI_INSTALL_PATH}/akka version)" >> ${GITHUB_OUTPUT} - - - name: Script - run: | - sed -i '' "s/\(echo \":akka-cli-version: \)[^\"]*/\1${CLI_VERSION}/" Makefile + chmod +x docs/src-static/install-cli.sh + docs/src-static/install-cli.sh --force --prefix=${CLI_INSTALL_PATH} + CLI_VERSION=$(akka version) + echo "setting CLI version to ${CLI_VERSION}" + sed -i.bak "s/\(echo \":akka-cli-version: \)[^\"]*/\1${CLI_VERSION}/" Makefile + rm Makefile.bak gem install kramdown-asciidoc ./docs/bin/generate_cli_docs.sh gen-index diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index f14d43c44..99af1e008 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -41,23 +41,23 @@ jobs: SDK_VERSION="$(cat ~/akka-javasdk-version.txt)" echo "SDK version: '${SDK_VERSION}'" - - name: sbt publishSigned + - name: sbt publishSigned (Cloudsmith) env: PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }} PGP_SECRET: ${{ secrets.PGP_SECRET }} - PUBLISH_USER: ${{ secrets.CLOUDSMITH_MACHINE_USER }} - PUBLISH_PASSWORD: ${{ secrets.CLOUDSMITH_MACHINE_PASSWORD }} + PUBLISH_USER: ${{ secrets.PUBLISH_USER }} + PUBLISH_PASSWORD: ${{ secrets.PUBLISH_PASSWORD }} run: sbt publishSigned - name: sbt publishM2 run: sbt publishM2 - - name: mvn deploy + - name: mvn deploy (Sonatype) run: |- export SDK_VERSION="$(cat ~/akka-javasdk-version.txt)" ./.github/publish-maven.sh env: PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }} PGP_SECRET: ${{ secrets.PGP_SECRET }} - SONATYPE_USERNAME: ${{ secrets.TEST_SONATYPE_AKKA_IO_USER }} - SONATYPE_PASSWORD: ${{ secrets.TEST_SONATYPE_AKKA_IO_PASSWORD }} + SONATYPE_USERNAME: ${{ secrets.SONATYPE_AKKA_IO_USERNAME }} + SONATYPE_PASSWORD: ${{ secrets.SONATYPE_AKKA_IO_PASSWORD }} diff --git a/Makefile b/Makefile index eee00a625..b0121e16d 100644 --- a/Makefile +++ b/Makefile @@ -44,7 +44,7 @@ attributes: prepare > "${managed_partials}/attributes.adoc" docs/bin/version.sh | xargs -0 printf ":akka-javasdk-version: %s" \ > "${managed_partials}/attributes.adoc" - echo ":akka-cli-version: 3.0.5" >> "${managed_partials}/attributes.adoc" + echo ":akka-cli-version: 3.0.6" >> "${managed_partials}/attributes.adoc" echo ":akka-cli-min-version: 3.0.4" >> "${managed_partials}/attributes.adoc" # see https://adoptium.net/marketplace/ echo ":java-version: 21" \ diff --git a/akka-javasdk-testkit/src/main/java/akka/javasdk/testkit/EventSourcedTestKit.java b/akka-javasdk-testkit/src/main/java/akka/javasdk/testkit/EventSourcedTestKit.java index fdc8866e6..99c3c5ca5 100644 --- a/akka-javasdk-testkit/src/main/java/akka/javasdk/testkit/EventSourcedTestKit.java +++ b/akka-javasdk-testkit/src/main/java/akka/javasdk/testkit/EventSourcedTestKit.java @@ -27,12 +27,14 @@ public class EventSourcedTestKit> extends EventSourcedEntityEffectsRunner { private final ES entity; + private final String entityId; private final JsonMessageCodec messageCodec; - private EventSourcedTestKit(ES entity) { + private EventSourcedTestKit(ES entity, String entityId) { super(entity); this.entity = entity; + this.entityId = entityId; this.messageCodec = new JsonMessageCodec(); } @@ -72,7 +74,7 @@ public static > EventSourcedTestKit> EventSourcedTestKit of( String entityId, Function entityFactory) { EventSourcedEntityContext context = new TestKitEventSourcedEntityContext(entityId); - return new EventSourcedTestKit<>(entityFactory.apply(context)); + return new EventSourcedTestKit<>(entityFactory.apply(context), entityId); } /** @@ -99,7 +101,7 @@ public EventSourcedResult call(Function> * @return a EventSourcedResult */ public EventSourcedResult call(Function> func, Metadata metadata) { - return interpretEffects(() -> func.apply(entity), metadata); + return interpretEffects(() -> func.apply(entity), entityId, metadata); } @Override diff --git a/akka-javasdk-testkit/src/main/java/akka/javasdk/testkit/impl/EventSourcedEntityEffectsRunner.java b/akka-javasdk-testkit/src/main/java/akka/javasdk/testkit/impl/EventSourcedEntityEffectsRunner.java index 0fa381c7f..057b57c84 100644 --- a/akka-javasdk-testkit/src/main/java/akka/javasdk/testkit/impl/EventSourcedEntityEffectsRunner.java +++ b/akka-javasdk-testkit/src/main/java/akka/javasdk/testkit/impl/EventSourcedEntityEffectsRunner.java @@ -46,8 +46,8 @@ public List getAllEvents() { */ @SuppressWarnings("unchecked") // event type in loop protected EventSourcedResult interpretEffects( - Supplier> effect, Metadata metadata) { - var commandContext = new TestKitEventSourcedEntityCommandContext(metadata); + Supplier> effect, String entityId, Metadata metadata) { + var commandContext = new TestKitEventSourcedEntityCommandContext(entityId, metadata); EventSourcedEntity.Effect effectExecuted; try { entity._internalSetCommandContext(Optional.of(commandContext)); diff --git a/akka-javasdk-testkit/src/main/scala/akka/javasdk/testkit/impl/TestKitCommandContextTimed.scala b/akka-javasdk-testkit/src/main/scala/akka/javasdk/testkit/impl/TestKitCommandContextTimed.scala index 5a6c16d81..da3c84596 100644 --- a/akka-javasdk-testkit/src/main/scala/akka/javasdk/testkit/impl/TestKitCommandContextTimed.scala +++ b/akka-javasdk-testkit/src/main/scala/akka/javasdk/testkit/impl/TestKitCommandContextTimed.scala @@ -5,14 +5,13 @@ package akka.javasdk.testkit.impl import akka.javasdk.Metadata +import akka.javasdk.Tracing import akka.javasdk.impl.InternalContext import akka.javasdk.testkit.MockRegistry import akka.javasdk.timedaction.CommandContext -import io.opentelemetry.api.OpenTelemetry -import io.opentelemetry.api.trace.Tracer /** - * INTERNAL API Used by the generated testkit + * INTERNAL API Used by the testkit */ final class TestKitCommandContextTimed(metadata: Metadata, mockRegistry: MockRegistry = MockRegistry.EMPTY) extends AbstractTestKitContext(mockRegistry) @@ -29,5 +28,5 @@ final class TestKitCommandContextTimed(metadata: Metadata, mockRegistry: MockReg override def metadata() = metadata - override def getTracer: Tracer = OpenTelemetry.noop().getTracer("noop") + override def tracing(): Tracing = TestKitTracing } diff --git a/akka-javasdk-testkit/src/main/scala/akka/javasdk/testkit/impl/TestKitEventSourcedEntityCommandContext.scala b/akka-javasdk-testkit/src/main/scala/akka/javasdk/testkit/impl/TestKitEventSourcedEntityCommandContext.scala index 6bc39376c..b39b8b208 100644 --- a/akka-javasdk-testkit/src/main/scala/akka/javasdk/testkit/impl/TestKitEventSourcedEntityCommandContext.scala +++ b/akka-javasdk-testkit/src/main/scala/akka/javasdk/testkit/impl/TestKitEventSourcedEntityCommandContext.scala @@ -5,6 +5,7 @@ package akka.javasdk.testkit.impl import akka.javasdk.Metadata +import akka.javasdk.Tracing import akka.javasdk.eventsourcedentity.CommandContext import akka.javasdk.impl.InternalContext @@ -18,10 +19,12 @@ final class TestKitEventSourcedEntityCommandContext( extends CommandContext with InternalContext { - def this(metadata: Metadata) = { - this(metadata = metadata, commandName = "stubCommandName") + def this(entityId: String, metadata: Metadata) = { + this(metadata = metadata, commandName = "stubCommandName", entityId = entityId) } + override def tracing(): Tracing = TestKitTracing + } object TestKitEventSourcedEntityCommandContext { diff --git a/akka-javasdk-testkit/src/main/scala/akka/javasdk/testkit/impl/TestKitEventSourcedEntityContext.scala b/akka-javasdk-testkit/src/main/scala/akka/javasdk/testkit/impl/TestKitEventSourcedEntityContext.scala index 0a95ec8c2..b6d43b559 100644 --- a/akka-javasdk-testkit/src/main/scala/akka/javasdk/testkit/impl/TestKitEventSourcedEntityContext.scala +++ b/akka-javasdk-testkit/src/main/scala/akka/javasdk/testkit/impl/TestKitEventSourcedEntityContext.scala @@ -8,7 +8,7 @@ import akka.javasdk.eventsourcedentity.EventSourcedEntityContext import akka.javasdk.testkit.MockRegistry /** - * INTERNAL API Used by the generated testkit + * INTERNAL API Used by the testkit */ final class TestKitEventSourcedEntityContext( override val entityId: String, diff --git a/akka-javasdk-testkit/src/main/scala/akka/javasdk/testkit/impl/TestKitEventSourcedEntityEventContext.scala b/akka-javasdk-testkit/src/main/scala/akka/javasdk/testkit/impl/TestKitEventSourcedEntityEventContext.scala index e4166b9b0..e0e9d70f7 100644 --- a/akka-javasdk-testkit/src/main/scala/akka/javasdk/testkit/impl/TestKitEventSourcedEntityEventContext.scala +++ b/akka-javasdk-testkit/src/main/scala/akka/javasdk/testkit/impl/TestKitEventSourcedEntityEventContext.scala @@ -7,7 +7,7 @@ package akka.javasdk.testkit.impl import akka.javasdk.eventsourcedentity.EventContext /** - * INTERNAL API Used by the generated testkit + * INTERNAL API Used by the testkit */ final class TestKitEventSourcedEntityEventContext extends EventContext { override def entityId = "testkit-entity-id" diff --git a/akka-javasdk-testkit/src/main/scala/akka/javasdk/testkit/impl/TestKitKeyValueEntityCommandContext.scala b/akka-javasdk-testkit/src/main/scala/akka/javasdk/testkit/impl/TestKitKeyValueEntityCommandContext.scala index 64c959145..79d02f311 100644 --- a/akka-javasdk-testkit/src/main/scala/akka/javasdk/testkit/impl/TestKitKeyValueEntityCommandContext.scala +++ b/akka-javasdk-testkit/src/main/scala/akka/javasdk/testkit/impl/TestKitKeyValueEntityCommandContext.scala @@ -5,12 +5,13 @@ package akka.javasdk.testkit.impl import akka.javasdk.Metadata +import akka.javasdk.Tracing import akka.javasdk.keyvalueentity.CommandContext import akka.javasdk.keyvalueentity.KeyValueEntityContext import akka.javasdk.testkit.MockRegistry /** - * INTERNAL API Used by the generated testkit + * INTERNAL API Used by the testkit */ final class TestKitKeyValueEntityCommandContext( override val entityId: String, @@ -26,4 +27,6 @@ final class TestKitKeyValueEntityCommandContext( this(entityId = entityId, metadata = metadata, commandName = "stubCommandName") } + override def tracing(): Tracing = TestKitTracing + } diff --git a/akka-javasdk-testkit/src/main/scala/akka/javasdk/testkit/impl/TestKitKeyValueEntityContext.scala b/akka-javasdk-testkit/src/main/scala/akka/javasdk/testkit/impl/TestKitKeyValueEntityContext.scala index f7809c278..08e82e02d 100644 --- a/akka-javasdk-testkit/src/main/scala/akka/javasdk/testkit/impl/TestKitKeyValueEntityContext.scala +++ b/akka-javasdk-testkit/src/main/scala/akka/javasdk/testkit/impl/TestKitKeyValueEntityContext.scala @@ -8,7 +8,7 @@ import akka.javasdk.keyvalueentity.KeyValueEntityContext import akka.javasdk.testkit.MockRegistry /** - * INTERNAL API Used by the generated testkit + * INTERNAL API Used by the testkit */ final class TestKitKeyValueEntityContext(override val entityId: String, mockRegistry: MockRegistry = MockRegistry.EMPTY) extends AbstractTestKitContext(mockRegistry) diff --git a/akka-javasdk-testkit/src/main/scala/akka/javasdk/testkit/impl/TestKitTracing.scala b/akka-javasdk-testkit/src/main/scala/akka/javasdk/testkit/impl/TestKitTracing.scala new file mode 100644 index 000000000..0e9dd265a --- /dev/null +++ b/akka-javasdk-testkit/src/main/scala/akka/javasdk/testkit/impl/TestKitTracing.scala @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2021-2024 Lightbend Inc. + */ + +package akka.javasdk.testkit.impl + +import akka.javasdk.Tracing +import io.opentelemetry.api.trace.Span + +import java.util.Optional + +/** + * INTERNAL API + */ +object TestKitTracing extends Tracing { + + override def startSpan(name: String): Optional[Span] = Optional.empty() + + override def parentSpan(): Optional[Span] = Optional.empty() +} diff --git a/akka-javasdk-testkit/src/test/java/akka/javasdk/testkit/eventsourced/CounterEventSourcedEntity.java b/akka-javasdk-testkit/src/test/java/akka/javasdk/testkit/eventsourced/CounterEventSourcedEntity.java index ce1051b74..f0da2d474 100644 --- a/akka-javasdk-testkit/src/test/java/akka/javasdk/testkit/eventsourced/CounterEventSourcedEntity.java +++ b/akka-javasdk-testkit/src/test/java/akka/javasdk/testkit/eventsourced/CounterEventSourcedEntity.java @@ -10,24 +10,24 @@ public class CounterEventSourcedEntity extends EventSourcedEntity increaseBy(Integer value) { if (value <= 0) return effects().error("Can't increase with a negative value"); - else return effects().persist(new Increased(value)).thenReply(__ -> "Ok"); + else return effects().persist(new Increased(commandContext().entityId(), value)).thenReply(__ -> "Ok"); } public Effect increaseFromMeta() { - return effects().persist(new Increased(Integer.parseInt(commandContext().metadata().get("value").get()))).thenReply(__ -> "Ok"); + return effects().persist(new Increased(commandContext().entityId(), Integer.parseInt(commandContext().metadata().get("value").get()))).thenReply(__ -> "Ok"); } public Effect doubleIncreaseBy(Integer value) { if (value < 0) return effects().error("Can't increase with a negative value"); else { - Increased event = new Increased(value); + Increased event = new Increased(commandContext().entityId(), value); return effects().persist(event, event).thenReply(__ -> "Ok"); } } @Override public Integer applyEvent(Increased increased) { - if (currentState() == null) return increased.value; - else return currentState() + increased.value; + if (currentState() == null) return increased.value(); + else return currentState() + increased.value(); } } diff --git a/akka-javasdk-testkit/src/test/java/akka/javasdk/testkit/eventsourced/CounterEventSourcedEntityTest.java b/akka-javasdk-testkit/src/test/java/akka/javasdk/testkit/eventsourced/CounterEventSourcedEntityTest.java index 2bb1f9069..28e9a6188 100644 --- a/akka-javasdk-testkit/src/test/java/akka/javasdk/testkit/eventsourced/CounterEventSourcedEntityTest.java +++ b/akka-javasdk-testkit/src/test/java/akka/javasdk/testkit/eventsourced/CounterEventSourcedEntityTest.java @@ -8,6 +8,7 @@ import akka.javasdk.testkit.EventSourcedResult; import akka.javasdk.testkit.EventSourcedTestKit; import org.junit.jupiter.api.Test; + import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -19,20 +20,22 @@ public void testIncrease() { EventSourcedTestKit.of(ctx -> new CounterEventSourcedEntity()); EventSourcedResult result = testKit.call(entity -> entity.increaseBy(10)); assertTrue(result.isReply()); - assertEquals(result.getReply(), "Ok"); - assertEquals(testKit.getState(), 10); - assertEquals(testKit.getAllEvents().size(), 1); + assertEquals("Ok", result.getReply()); + assertEquals(10, testKit.getState()); + assertEquals(1, testKit.getAllEvents().size()); } @Test public void testIncreaseWithMetadata() { + String counterId = "123"; EventSourcedTestKit testKit = - EventSourcedTestKit.of(ctx -> new CounterEventSourcedEntity()); + EventSourcedTestKit.of(counterId, ctx -> new CounterEventSourcedEntity()); EventSourcedResult result = testKit.call(entity -> entity.increaseFromMeta(), Metadata.EMPTY.add("value", "10")); assertTrue(result.isReply()); - assertEquals(result.getReply(), "Ok"); - assertEquals(testKit.getState(), 10); - assertEquals(testKit.getAllEvents().size(), 1); + assertEquals(new Increased(counterId, 10), result.getNextEventOfType(Increased.class)); + assertEquals("Ok", result.getReply()); + assertEquals(10, testKit.getState()); + assertEquals(1, testKit.getAllEvents().size()); } @Test @@ -41,9 +44,9 @@ public void testDoubleIncrease() { EventSourcedTestKit.of(ctx -> new CounterEventSourcedEntity()); EventSourcedResult result = testKit.call(entity -> entity.doubleIncreaseBy(10)); assertTrue(result.isReply()); - assertEquals(result.getReply(), "Ok"); - assertEquals(testKit.getState(), 20); - assertEquals(testKit.getAllEvents().size(), 2); + assertEquals("Ok", result.getReply()); + assertEquals(20, testKit.getState()); + assertEquals(2, testKit.getAllEvents().size()); } @Test @@ -52,6 +55,6 @@ public void testIncreaseWithNegativeValue() { EventSourcedTestKit.of(ctx -> new CounterEventSourcedEntity()); EventSourcedResult result = testKit.call(entity -> entity.increaseBy(-10)); assertTrue(result.isError()); - assertEquals(result.getError(), "Can't increase with a negative value"); + assertEquals("Can't increase with a negative value", result.getError()); } } diff --git a/akka-javasdk-testkit/src/test/java/akka/javasdk/testkit/eventsourced/Increased.java b/akka-javasdk-testkit/src/test/java/akka/javasdk/testkit/eventsourced/Increased.java index cf9a31366..e09ad8d05 100644 --- a/akka-javasdk-testkit/src/test/java/akka/javasdk/testkit/eventsourced/Increased.java +++ b/akka-javasdk-testkit/src/test/java/akka/javasdk/testkit/eventsourced/Increased.java @@ -4,11 +4,5 @@ package akka.javasdk.testkit.eventsourced; -public class Increased { - - public final Integer value; - - public Increased(Integer value) { - this.value = value; - } +public record Increased(String counterId, Integer value) { } diff --git a/akka-javasdk-tests/src/test/java/akkajavasdk/components/jwt/HelloJwtEndpoint.java b/akka-javasdk-tests/src/test/java/akkajavasdk/components/jwt/HelloJwtEndpoint.java index b00c07f08..f7a8284be 100644 --- a/akka-javasdk-tests/src/test/java/akkajavasdk/components/jwt/HelloJwtEndpoint.java +++ b/akka-javasdk-tests/src/test/java/akkajavasdk/components/jwt/HelloJwtEndpoint.java @@ -8,7 +8,7 @@ import akka.javasdk.annotations.JWT; import akka.javasdk.annotations.http.HttpEndpoint; import akka.javasdk.annotations.http.Get; -import akka.javasdk.http.RequestContext; +import akka.javasdk.http.AbstractHttpEndpoint; import java.util.concurrent.CompletionStage; import static java.util.concurrent.CompletableFuture.completedStage; @@ -19,17 +19,12 @@ // tag::bearer-token[] @HttpEndpoint("/hello") @JWT(validate = JWT.JwtMethodMode.BEARER_TOKEN, bearerTokenIssuers = "my-issuer-123", staticClaims = { @JWT.StaticClaim(claim = "sub", pattern = "my-subject-123")}) -public class HelloJwtEndpoint { +public class HelloJwtEndpoint extends AbstractHttpEndpoint { // end::bearer-token[] - RequestContext context; - public HelloJwtEndpoint(RequestContext context){ - this.context = context; - } - @Get("/") public CompletionStage helloWorld() { - var claims = context.getJwtClaims(); + var claims = requestContext().getJwtClaims(); var issuer = claims.issuer().get(); var sub = claims.subject().get(); return completedStage("issuer: " + issuer + ", subject: " + sub); diff --git a/akka-javasdk-tests/src/test/java/akkajavasdk/components/jwt/MissingJwtEndpoint.java b/akka-javasdk-tests/src/test/java/akkajavasdk/components/jwt/MissingJwtEndpoint.java index 371a8026f..5ee1a29e4 100644 --- a/akka-javasdk-tests/src/test/java/akkajavasdk/components/jwt/MissingJwtEndpoint.java +++ b/akka-javasdk-tests/src/test/java/akkajavasdk/components/jwt/MissingJwtEndpoint.java @@ -19,6 +19,8 @@ @HttpEndpoint("/missingjwt") public class MissingJwtEndpoint { + // Note: leaving this with injected request context rather than extend AbstractHttpEndpoint to keep + // some test coverage RequestContext context; public MissingJwtEndpoint(RequestContext context){ this.context = context; diff --git a/akka-javasdk-tests/src/test/java/akkajavasdk/components/tracing/Batches.java b/akka-javasdk-tests/src/test/java/akkajavasdk/components/tracing/Batches.java deleted file mode 100644 index 10cceae8c..000000000 --- a/akka-javasdk-tests/src/test/java/akkajavasdk/components/tracing/Batches.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2021-2024 Lightbend Inc. - */ - -package akkajavasdk.components.tracing; - -import java.util.List; - -public record Batches(List batches ){ - - public record Batch(Resource resource, List scopeSpans){ - public record Resource(List attributes){} - - public record ScopeSpan(Scope scope, List spans){ - public record Scope(String name){} - public record Span(String traceId, String spanId, String name, String kind, List attributes){} - } - } - - public record Attribute(String key, Value value) { - public record Value(String stringValue) {} - } - -} - - - diff --git a/akka-javasdk-tests/src/test/java/akkajavasdk/components/tracing/Traces.java b/akka-javasdk-tests/src/test/java/akkajavasdk/components/tracing/Traces.java deleted file mode 100644 index 6a182828b..000000000 --- a/akka-javasdk-tests/src/test/java/akkajavasdk/components/tracing/Traces.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (C) 2021-2024 Lightbend Inc. - */ - -package akkajavasdk.components.tracing; - - -import java.util.List; - -public record Traces(List traces) { - public record Trace(String traceID, String rootServiceName, String rootTraceName) { - } -} diff --git a/akka-javasdk/src/main/java/akka/javasdk/Metadata.java b/akka-javasdk/src/main/java/akka/javasdk/Metadata.java index 89f5170c1..6ff6ba981 100644 --- a/akka-javasdk/src/main/java/akka/javasdk/Metadata.java +++ b/akka-javasdk/src/main/java/akka/javasdk/Metadata.java @@ -213,13 +213,6 @@ public interface Metadata extends Iterable { */ CloudEvent asCloudEvent(String id, URI source, String type); - - /** - * Get the trace context associated with this request metadata. - * @return The trace context. - */ - TraceContext traceContext(); - /** * Merge the given Metadata entries with this Metadata. If the same key is present in both, both values will be kept. * diff --git a/akka-javasdk/src/main/java/akka/javasdk/TraceContext.java b/akka-javasdk/src/main/java/akka/javasdk/TraceContext.java deleted file mode 100644 index 20175205a..000000000 --- a/akka-javasdk/src/main/java/akka/javasdk/TraceContext.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2021-2024 Lightbend Inc. - */ - -package akka.javasdk; - -import io.opentelemetry.context.Context; - -import java.util.Optional; - -/** Utility interface for trace context helper methods. */ -public interface TraceContext { - - /** - * Allows retrieving the trace context as an OpenTelemetry context for easier construction of - * child spans. If the trace context is not available, a new empty context will be returned. - * - * @return the trace context as an OpenTelemetry context. - */ - Context asOpenTelemetryContext(); - - /** - * Allows retrieving the trace parent for easier injection in external calls (e.g. HTTP request - * headers). - * - * @return the trace parent using W3C Trace Context format. - * @see W3C Trace - * Context section 3 - */ - Optional traceParent(); - - /** - * Allows retrieving the trace state for easier injection in external calls (e.g. HTTP request - * headers). - * - * @return the trace state using W3C Trace Context format. - * @see W3C Trace - * Context section 3 - */ - Optional traceState(); - - /** - * Allows retrieving the trace id of the trace parent if any. - * - * @return the traceId of the traceParent if any - */ - Optional traceId(); -} diff --git a/akka-javasdk/src/main/java/akka/javasdk/Tracing.java b/akka-javasdk/src/main/java/akka/javasdk/Tracing.java new file mode 100644 index 000000000..bb7d1e027 --- /dev/null +++ b/akka-javasdk/src/main/java/akka/javasdk/Tracing.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2021-2024 Lightbend Inc. + */ + +package akka.javasdk; + +import akka.annotation.DoNotInherit; +import io.opentelemetry.api.trace.Span; + +import java.util.Optional; + +/** + * Factory for manually creating open telemetry spans in addition to those automatically provided by + * the runtime and SDK. + * + *

Not for user extension. Injectable into endpoint constructors or available through component + * command contexts. + */ +@DoNotInherit +public interface Tracing { + /** + * If tracing is enabled, create and start a new custom span with the given name, setting a parent + * for the span is done automatically so that the span is a child of the incoming request or + * component call. + * + * @return Optional of the span if tracing is enabled, empty option if tracing is not enabled. + */ + Optional startSpan(String name); + + /** + * If tracing is enabled, this returns the current parent span, to use for propagating trace + * parent through third party integrations. This span should only be used for observing, ending it + * or marking it as failed etc. is managed by the SDK and the runtime. + * + * @see {{@link #startSpan(String)}} for creating a custom span tied to some logic in a service. + */ + Optional parentSpan(); +} diff --git a/akka-javasdk/src/main/java/akka/javasdk/annotations/http/HttpEndpoint.java b/akka-javasdk/src/main/java/akka/javasdk/annotations/http/HttpEndpoint.java index c157929fe..e82d4fd4a 100644 --- a/akka-javasdk/src/main/java/akka/javasdk/annotations/http/HttpEndpoint.java +++ b/akka-javasdk/src/main/java/akka/javasdk/annotations/http/HttpEndpoint.java @@ -24,6 +24,8 @@ *

  • {@link io.opentelemetry.api.trace.Span}
  • *
  • Custom types provided by a {@link akka.javasdk.DependencyProvider} from the service setup
  • * + *

    If the annotated class extends {@link akka.javasdk.http.AbstractHttpEndpoint} the request context + * is available without constructor injection. */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) diff --git a/akka-javasdk/src/main/java/akka/javasdk/consumer/MessageContext.java b/akka-javasdk/src/main/java/akka/javasdk/consumer/MessageContext.java index c1a9e3be6..56223d348 100644 --- a/akka-javasdk/src/main/java/akka/javasdk/consumer/MessageContext.java +++ b/akka-javasdk/src/main/java/akka/javasdk/consumer/MessageContext.java @@ -6,6 +6,7 @@ import akka.javasdk.CloudEvent; import akka.javasdk.MetadataContext; +import akka.javasdk.Tracing; import io.opentelemetry.api.trace.Tracer; import java.util.Optional; @@ -19,11 +20,6 @@ public interface MessageContext extends MetadataContext { */ Optional eventSubject(); - /** - * Get an OpenTelemetry tracer for the current message. This will allow for building and automatic - * exporting of spans. - * - * @return A tracer for the current message, if tracing is configured. Otherwise, a noops tracer. - */ - Tracer getTracer(); + /** Access to tracing for custom app specific tracing. */ + Tracing tracing(); } diff --git a/akka-javasdk/src/main/java/akka/javasdk/eventsourcedentity/CommandContext.java b/akka-javasdk/src/main/java/akka/javasdk/eventsourcedentity/CommandContext.java index 22eebf9d8..325596d29 100644 --- a/akka-javasdk/src/main/java/akka/javasdk/eventsourcedentity/CommandContext.java +++ b/akka-javasdk/src/main/java/akka/javasdk/eventsourcedentity/CommandContext.java @@ -5,6 +5,7 @@ package akka.javasdk.eventsourcedentity; import akka.javasdk.MetadataContext; +import akka.javasdk.Tracing; /** An event sourced command context. */ public interface CommandContext extends MetadataContext { @@ -35,4 +36,7 @@ public interface CommandContext extends MetadataContext { * @return The entity id. */ String entityId(); + + /** Access to tracing for custom app specific tracing. */ + Tracing tracing(); } diff --git a/akka-javasdk/src/main/java/akka/javasdk/http/AbstractHttpEndpoint.java b/akka-javasdk/src/main/java/akka/javasdk/http/AbstractHttpEndpoint.java new file mode 100644 index 000000000..62e2ceba5 --- /dev/null +++ b/akka-javasdk/src/main/java/akka/javasdk/http/AbstractHttpEndpoint.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2021-2024 Lightbend Inc. + */ + +package akka.javasdk.http; + +import akka.annotation.InternalApi; + +/** + * Optional base class for HTTP endpoints giving access to a request context without additional constructor parameters + */ +abstract public class AbstractHttpEndpoint { + + volatile private RequestContext context; + + /** + * INTERNAL API + * + * @hidden + */ + @InternalApi + final public void _internalSetRequestContext(RequestContext context) { + this.context = context; + } + + /** + * Always available from request handling methods, not available from the constructor. + */ + protected final RequestContext requestContext() { + if (context == null) { + throw new IllegalStateException("The request context can only be accessed from the request handling methods of the endpoint."); + } + return context; + } + +} diff --git a/akka-javasdk/src/main/java/akka/javasdk/http/RequestContext.java b/akka-javasdk/src/main/java/akka/javasdk/http/RequestContext.java index 96bf41b2b..528820b38 100644 --- a/akka-javasdk/src/main/java/akka/javasdk/http/RequestContext.java +++ b/akka-javasdk/src/main/java/akka/javasdk/http/RequestContext.java @@ -8,11 +8,12 @@ import akka.javasdk.Context; import akka.javasdk.JwtClaims; import akka.javasdk.Principals; - -import java.util.Optional; +import akka.javasdk.Tracing; /** - * Not for user extension, can be injected as constructor parameter into HTTP endpoint components + * Not for user extension, can be injected as constructor parameter into HTTP endpoint components or + * accessible from {@link AbstractHttpEndpoint#requestContext()} if the endpoint class extends + * `AbstractHttpEndpoint`. */ @DoNotInherit public interface RequestContext extends Context { @@ -26,4 +27,7 @@ public interface RequestContext extends Context { /** @return The JWT claims, if any, associated with this request. */ JwtClaims getJwtClaims(); + + /** Access to tracing for custom app specific tracing. */ + Tracing tracing(); } diff --git a/akka-javasdk/src/main/java/akka/javasdk/keyvalueentity/CommandContext.java b/akka-javasdk/src/main/java/akka/javasdk/keyvalueentity/CommandContext.java index 38224a42f..dda78c979 100644 --- a/akka-javasdk/src/main/java/akka/javasdk/keyvalueentity/CommandContext.java +++ b/akka-javasdk/src/main/java/akka/javasdk/keyvalueentity/CommandContext.java @@ -5,6 +5,7 @@ package akka.javasdk.keyvalueentity; import akka.javasdk.MetadataContext; +import akka.javasdk.Tracing; /** A value based entity command context. */ public interface CommandContext extends MetadataContext { @@ -29,4 +30,7 @@ public interface CommandContext extends MetadataContext { * @return The entity id. */ String entityId(); + + /** Access to tracing for custom app specific tracing. */ + Tracing tracing(); } diff --git a/akka-javasdk/src/main/java/akka/javasdk/timedaction/CommandContext.java b/akka-javasdk/src/main/java/akka/javasdk/timedaction/CommandContext.java index f90cebbb7..ca24eab10 100644 --- a/akka-javasdk/src/main/java/akka/javasdk/timedaction/CommandContext.java +++ b/akka-javasdk/src/main/java/akka/javasdk/timedaction/CommandContext.java @@ -5,16 +5,12 @@ package akka.javasdk.timedaction; import akka.javasdk.MetadataContext; +import akka.javasdk.Tracing; import io.opentelemetry.api.trace.Tracer; /** Context for action calls. */ public interface CommandContext extends MetadataContext { - /** - * Get an OpenTelemetry tracer for the current action. This will allow for building and automatic - * exporting of spans. - * - * @return A tracer for the current action, if tracing is configured. Otherwise, a noops tracer. - */ - Tracer getTracer(); + /** Access to tracing for custom app specific tracing. */ + Tracing tracing(); } diff --git a/akka-javasdk/src/main/java/akka/javasdk/workflow/CommandContext.java b/akka-javasdk/src/main/java/akka/javasdk/workflow/CommandContext.java index a10412faf..018cefbb1 100644 --- a/akka-javasdk/src/main/java/akka/javasdk/workflow/CommandContext.java +++ b/akka-javasdk/src/main/java/akka/javasdk/workflow/CommandContext.java @@ -5,6 +5,7 @@ package akka.javasdk.workflow; import akka.javasdk.MetadataContext; +import akka.javasdk.Tracing; /** A value based workflow command context. */ public interface CommandContext extends MetadataContext { @@ -29,4 +30,7 @@ public interface CommandContext extends MetadataContext { * @return The workflow id. */ String workflowId(); + + /** Access to tracing for custom app specific tracing. */ + Tracing tracing(); } diff --git a/akka-javasdk/src/main/scala/akka/javasdk/impl/MetadataImpl.scala b/akka-javasdk/src/main/scala/akka/javasdk/impl/MetadataImpl.scala index 5db3bf450..8f25d98cc 100644 --- a/akka-javasdk/src/main/scala/akka/javasdk/impl/MetadataImpl.scala +++ b/akka-javasdk/src/main/scala/akka/javasdk/impl/MetadataImpl.scala @@ -18,7 +18,6 @@ import scala.jdk.OptionConverters._ import akka.annotation.InternalApi import akka.javasdk.CloudEvent import akka.javasdk.Metadata -import akka.javasdk.TraceContext import akka.javasdk.impl.telemetry.Telemetry import akka.javasdk.impl.telemetry.Telemetry.metadataGetter import com.google.protobuf.ByteString @@ -207,22 +206,16 @@ private[javasdk] class MetadataImpl private (val entries: Seq[MetadataEntry]) ex override def asMetadata(): Metadata = this - override lazy val traceContext: TraceContext = new TraceContext { - override def asOpenTelemetryContext(): OtelContext = W3CTraceContextPropagator + lazy val traceId: Option[String] = { + val otelContext = W3CTraceContextPropagator .getInstance() .extract(OtelContext.current(), asMetadata(), metadataGetter) - override def traceId(): Optional[String] = { - Span.fromContext(asOpenTelemetryContext()).getSpanContext.getTraceId match { - case "00000000000000000000000000000000" => - Optional.empty() // when no traceId returns io.opentelemetry.api.trace.TraceId.INVALID - case traceId => Some(traceId).toJava - } + Span.fromContext(otelContext).getSpanContext.getTraceId match { + case "00000000000000000000000000000000" => + None // when no traceId returns io.opentelemetry.api.trace.TraceId.INVALID + case traceId => Some(traceId) } - - override def traceParent(): Optional[String] = getScala(Telemetry.TRACE_PARENT_KEY).toJava - - override def traceState(): Optional[String] = getScala(Telemetry.TRACE_STATE_KEY).toJava } override def merge(other: Metadata): Metadata = { diff --git a/akka-javasdk/src/main/scala/akka/javasdk/impl/SdkRunner.scala b/akka-javasdk/src/main/scala/akka/javasdk/impl/SdkRunner.scala index 3ae544a27..172ef9880 100644 --- a/akka-javasdk/src/main/scala/akka/javasdk/impl/SdkRunner.scala +++ b/akka-javasdk/src/main/scala/akka/javasdk/impl/SdkRunner.scala @@ -58,7 +58,11 @@ import akka.javasdk.view.View import akka.javasdk.workflow.Workflow import akka.javasdk.workflow.WorkflowContext import akka.javasdk.JwtClaims +import akka.javasdk.http.AbstractHttpEndpoint +import akka.javasdk.Tracing import akka.javasdk.impl.http.JwtClaimsImpl +import akka.javasdk.impl.telemetry.SpanTracingImpl +import akka.javasdk.impl.telemetry.TraceInstrumentation import akka.runtime.sdk.spi.ComponentClients import akka.runtime.sdk.spi.HttpEndpointConstructionContext import akka.runtime.sdk.spi.HttpEndpointDescriptor @@ -75,7 +79,7 @@ import com.typesafe.config.Config import com.typesafe.config.ConfigFactory import io.opentelemetry.api.trace.Span import io.opentelemetry.api.trace.Tracer -import io.opentelemetry.context.Context +import io.opentelemetry.context.{ Context => OtelContext } import kalix.protocol.action.Actions import kalix.protocol.discovery.Discovery import kalix.protocol.event_sourced_entity.EventSourcedEntities @@ -267,6 +271,8 @@ private final class Sdk( private val applicationConfig = ApplicationConfig(system).getConfig private val sdkSettings = Settings(applicationConfig.getConfig("akka.javasdk")) + private val sdkTracerFactory = () => tracerFactory(TraceInstrumentation.InstrumentationScopeName) + private val httpClientProvider = new HttpClientProviderImpl( system, None, @@ -351,7 +357,6 @@ private final class Sdk( case h if h == classOf[HttpClientProvider] => httpClientProvider(span) case t if t == classOf[TimerScheduler] => timerScheduler(span) case m if m == classOf[Materializer] => sdkMaterializer - case s if s == classOf[Span] => span.getOrElse(Span.current()) } // FIXME mixing runtime config with sdk with user project config is tricky @@ -380,7 +385,7 @@ private final class Sdk( actionAndConsumerServices, runtimeComponentClients.timerClient, sdkExecutionContext, - tracerFactory)) + sdkTracerFactory)) } services.groupBy(_._2.getClass).foreach { @@ -393,23 +398,23 @@ private final class Sdk( eventSourcedServices, sdkSettings, sdkDispatcherName, - tracerFactory) + sdkTracerFactory) eventSourcedEntitiesEndpoint = Some(eventSourcedImpl) case (serviceClass, entityServices: Map[String, KeyValueEntityService[_, _]] @unchecked) if serviceClass == classOf[KeyValueEntityService[_, _]] => - valueEntitiesEndpoint = - Some(new KeyValueEntitiesImpl(classicSystem, entityServices, sdkSettings, sdkDispatcherName, tracerFactory)) + valueEntitiesEndpoint = Some( + new KeyValueEntitiesImpl(classicSystem, entityServices, sdkSettings, sdkDispatcherName, sdkTracerFactory)) case (serviceClass, workflowServices: Map[String, WorkflowService[_, _]] @unchecked) if serviceClass == classOf[WorkflowService[_, _]] => workflowEntitiesEndpoint = Some( new WorkflowImpl( - classicSystem, workflowServices, runtimeComponentClients.timerClient, sdkExecutionContext, - sdkDispatcherName)) + sdkDispatcherName, + sdkTracerFactory)) case (serviceClass, _: Map[String, TimedActionService[_]] @unchecked) if serviceClass == classOf[TimedActionService[_]] => @@ -556,23 +561,30 @@ private final class Sdk( private def httpEndpointFactory[E](httpEndpointClass: Class[E]): HttpEndpointConstructionContext => E = { (context: HttpEndpointConstructionContext) => - wiredInstance(httpEndpointClass) { + lazy val requestContext = new RequestContext { + override def getPrincipals: Principals = + PrincipalsImpl(context.principal.source, context.principal.service) + + override def getJwtClaims: JwtClaims = + context.jwt match { + case Some(jwtClaims) => new JwtClaimsImpl(jwtClaims) + case None => + throw new RuntimeException( + "There are no JWT claims defined but trying accessing the JWT claims. The class or the method needs to be annotated with @JWT.") + } + + override def tracing(): Tracing = new SpanTracingImpl(context.openTelemetrySpan, sdkTracerFactory) + } + val instance = wiredInstance(httpEndpointClass) { sideEffectingComponentInjects(context.openTelemetrySpan).orElse { - case p if p == classOf[RequestContext] => - new RequestContext { - override def getPrincipals: Principals = - PrincipalsImpl(context.principal.source, context.principal.service) - - override def getJwtClaims: JwtClaims = - context.jwt match { - case Some(jwtClaims) => new JwtClaimsImpl(jwtClaims) - case None => - throw new RuntimeException( - "There are no JWT claims defined but trying accessing the JWT claims. The class or the method needs to be annotated with @JWT.") - } - } + case p if p == classOf[RequestContext] => requestContext } } + instance match { + case withBaseClass: AbstractHttpEndpoint => withBaseClass._internalSetRequestContext(requestContext) + case _ => + } + instance } private def wiredInstance[T](clz: Class[T])(partial: PartialFunction[Class[_], Any]): T = { @@ -652,7 +664,7 @@ private final class Sdk( private def httpClientProvider(openTelemetrySpan: Option[Span]): HttpClientProvider = openTelemetrySpan match { case None => httpClientProvider - case Some(span) => httpClientProvider.withTraceContext(Context.current().`with`(span)) + case Some(span) => httpClientProvider.withTraceContext(OtelContext.current().`with`(span)) } } diff --git a/akka-javasdk/src/main/scala/akka/javasdk/impl/action/ActionsImpl.scala b/akka-javasdk/src/main/scala/akka/javasdk/impl/action/ActionsImpl.scala index 87bfc14e4..fd9148f31 100644 --- a/akka-javasdk/src/main/scala/akka/javasdk/impl/action/ActionsImpl.scala +++ b/akka-javasdk/src/main/scala/akka/javasdk/impl/action/ActionsImpl.scala @@ -9,6 +9,7 @@ import akka.NotUsed import akka.actor.ActorSystem import akka.annotation.InternalApi import akka.javasdk.Metadata +import akka.javasdk.Tracing import akka.javasdk.consumer.Consumer import akka.javasdk.consumer.MessageContext import akka.javasdk.consumer.MessageEnvelope @@ -24,6 +25,7 @@ import akka.javasdk.impl.telemetry.ActionCategory import akka.javasdk.impl.telemetry.ConsumerCategory import akka.javasdk.impl.telemetry.Telemetry import akka.javasdk.impl.telemetry.TraceInstrumentation +import akka.javasdk.impl.telemetry.SpanTracingImpl import akka.javasdk.impl.timedaction.TimedActionService import akka.javasdk.impl.timer.TimerSchedulerImpl import akka.javasdk.timedaction.CommandContext @@ -33,7 +35,7 @@ import akka.javasdk.timer.TimerScheduler import akka.runtime.sdk.spi.TimerClient import akka.stream.scaladsl.Source import io.grpc.Status -import io.opentelemetry.api.trace.SpanContext +import io.opentelemetry.api.trace.Span import io.opentelemetry.api.trace.Tracer import kalix.protocol.action.ActionCommand import kalix.protocol.action.ActionResponse @@ -95,7 +97,7 @@ private[akka] final class ActionsImpl( services: Map[String, Service], timerClient: TimerClient, sdkExecutionContext: ExecutionContext, - tracerFactory: String => Tracer) + tracerFactory: () => Tracer) extends Actions { import ActionsImpl._ @@ -173,7 +175,7 @@ private[akka] final class ActionsImpl( val fut = try { val messageContext = - createMessageContext(in, service.messageCodec, span.map(_.getSpanContext), service.componentId) + createMessageContext(in, service.messageCodec, span, service.componentId) val decodedPayload = service.messageCodec.decodeMessage( in.payload.getOrElse(throw new IllegalArgumentException("No command payload"))) val effect = service @@ -199,7 +201,7 @@ private[akka] final class ActionsImpl( val fut = try { val messageContext = - createConsumerMessageContext(in, service.messageCodec, span.map(_.getSpanContext), service.componentId) + createConsumerMessageContext(in, service.messageCodec, span, service.componentId) val decodedPayload = service.messageCodec.decodeMessage( in.payload.getOrElse(throw new IllegalArgumentException("No command payload"))) val effect = service @@ -225,21 +227,21 @@ private[akka] final class ActionsImpl( private def createMessageContext( in: ActionCommand, messageCodec: MessageCodec, - spanContext: Option[SpanContext], + span: Option[Span], serviceName: String): CommandContext = { val metadata = MetadataImpl.of(in.metadata.map(_.entries.toVector).getOrElse(Nil)) - val updatedMetadata = spanContext.map(metadata.withTracing).getOrElse(metadata) - new CommandContextImpl(updatedMetadata, messageCodec, system, timerClient, telemetries(serviceName)) + val updatedMetadata = span.map(metadata.withTracing).getOrElse(metadata) + new CommandContextImpl(updatedMetadata, messageCodec, system, timerClient, tracerFactory, span) } private def createConsumerMessageContext( in: ActionCommand, messageCodec: MessageCodec, - spanContext: Option[SpanContext], + span: Option[Span], serviceName: String): MessageContext = { val metadata = MetadataImpl.of(in.metadata.map(_.entries.toVector).getOrElse(Nil)) - val updatedMetadata = spanContext.map(metadata.withTracing).getOrElse(metadata) - new MessageContextImpl(updatedMetadata, messageCodec, timerClient, telemetries(serviceName)) + val updatedMetadata = span.map(metadata.withTracing).getOrElse(metadata) + new MessageContextImpl(updatedMetadata, messageCodec, timerClient, tracerFactory, span) } override def handleStreamedIn(in: Source[ActionCommand, NotUsed]): Future[ActionResponse] = { @@ -265,7 +267,8 @@ class CommandContextImpl( val messageCodec: MessageCodec, val system: ActorSystem, timerClient: TimerClient, - instrumentation: TraceInstrumentation) + tracerFactory: () => Tracer, + span: Option[Span]) extends AbstractContext with CommandContext { @@ -283,7 +286,5 @@ class CommandContextImpl( } } - override def getTracer: Tracer = - instrumentation.getTracer - + override def tracing(): Tracing = new SpanTracingImpl(span, tracerFactory) } diff --git a/akka-javasdk/src/main/scala/akka/javasdk/impl/consumer/ConsumersImpl.scala b/akka-javasdk/src/main/scala/akka/javasdk/impl/consumer/ConsumersImpl.scala index 73fe1f71e..a0bcfaa33 100644 --- a/akka-javasdk/src/main/scala/akka/javasdk/impl/consumer/ConsumersImpl.scala +++ b/akka-javasdk/src/main/scala/akka/javasdk/impl/consumer/ConsumersImpl.scala @@ -6,6 +6,7 @@ package akka.javasdk.impl.consumer import akka.annotation.InternalApi import akka.javasdk.Metadata +import akka.javasdk.Tracing import akka.javasdk.consumer.Consumer import akka.javasdk.consumer.MessageContext import akka.javasdk.consumer.MessageEnvelope @@ -15,11 +16,12 @@ import akka.javasdk.impl.JsonMessageCodec import akka.javasdk.impl.MessageCodec import akka.javasdk.impl.MetadataImpl import akka.javasdk.impl.Service +import akka.javasdk.impl.telemetry.SpanTracingImpl import akka.javasdk.impl.telemetry.Telemetry -import akka.javasdk.impl.telemetry.TraceInstrumentation import akka.javasdk.impl.timer.TimerSchedulerImpl import akka.javasdk.timer.TimerScheduler import akka.runtime.sdk.spi.TimerClient +import io.opentelemetry.api.trace.Span import io.opentelemetry.api.trace.Tracer import kalix.protocol.action.Actions import kalix.protocol.component.MetadataEntry @@ -62,7 +64,8 @@ private[impl] final class MessageContextImpl( override val metadata: Metadata, val messageCodec: MessageCodec, timerClient: TimerClient, - instrumentation: TraceInstrumentation) + tracerFactory: () => Tracer, + span: Option[Span]) extends AbstractContext with MessageContext { @@ -86,7 +89,5 @@ private[impl] final class MessageContextImpl( } } - override def getTracer: Tracer = - instrumentation.getTracer - + override def tracing(): Tracing = new SpanTracingImpl(span, tracerFactory) } diff --git a/akka-javasdk/src/main/scala/akka/javasdk/impl/eventsourcedentity/EventSourcedEntitiesImpl.scala b/akka-javasdk/src/main/scala/akka/javasdk/impl/eventsourcedentity/EventSourcedEntitiesImpl.scala index 26e857979..3412e5371 100644 --- a/akka-javasdk/src/main/scala/akka/javasdk/impl/eventsourcedentity/EventSourcedEntitiesImpl.scala +++ b/akka-javasdk/src/main/scala/akka/javasdk/impl/eventsourcedentity/EventSourcedEntitiesImpl.scala @@ -16,6 +16,7 @@ import akka.javasdk.impl.ErrorHandling.BadRequestException import EventSourcedEntityRouter.CommandResult import akka.annotation.InternalApi import akka.javasdk.Metadata +import akka.javasdk.Tracing import akka.javasdk.eventsourcedentity.CommandContext import akka.javasdk.eventsourcedentity.EventContext import akka.javasdk.eventsourcedentity.EventSourcedEntity @@ -32,8 +33,10 @@ import akka.javasdk.impl.effect.ErrorReplyImpl import akka.javasdk.impl.effect.MessageReplyImpl import akka.javasdk.impl.effect.SecondaryEffectImpl import akka.javasdk.impl.telemetry.EventSourcedEntityCategory +import akka.javasdk.impl.telemetry.SpanTracingImpl import akka.javasdk.impl.telemetry.Telemetry import akka.javasdk.impl.telemetry.TraceInstrumentation +import io.opentelemetry.api.trace.Span import io.opentelemetry.api.trace.Tracer import kalix.protocol.component.Failure import kalix.protocol.event_sourced_entity.EventSourcedStreamIn.Message.{ Command => InCommand } @@ -79,7 +82,7 @@ private[impl] final class EventSourcedEntitiesImpl( _services: Map[String, EventSourcedEntityService[_, _, _]], configuration: Settings, sdkDispatcherName: String, - tracerFactory: String => Tracer) + tracerFactory: () => Tracer) extends EventSourcedEntities { import akka.javasdk.impl.EntityExceptions._ @@ -186,7 +189,7 @@ private[impl] final class EventSourcedEntitiesImpl( ScalaPbAny.defaultInstance.withTypeUrl(AnySupport.JsonTypeUrlPrefix).withValue(ByteString.empty()))) val metadata = MetadataImpl.of(command.metadata.map(_.entries.toVector).getOrElse(Nil)) val context = - new CommandContextImpl(thisEntityId, sequence, command.name, command.id, metadata) + new CommandContextImpl(thisEntityId, sequence, command.name, command.id, metadata, span, tracerFactory) val CommandResult( events: Vector[Any], @@ -280,10 +283,14 @@ private[impl] final class EventSourcedEntitiesImpl( override val sequenceNumber: Long, override val commandName: String, override val commandId: Long, - override val metadata: Metadata) + override val metadata: Metadata, + span: Option[Span], + tracerFactory: () => Tracer) extends AbstractContext with CommandContext - with ActivatableContext + with ActivatableContext { + override def tracing(): Tracing = new SpanTracingImpl(span, tracerFactory) + } private class EventSourcedEntityContextImpl(override final val entityId: String) extends AbstractContext diff --git a/akka-javasdk/src/main/scala/akka/javasdk/impl/keyvalueentity/KeyValueEntitiesImpl.scala b/akka-javasdk/src/main/scala/akka/javasdk/impl/keyvalueentity/KeyValueEntitiesImpl.scala index dfc2db548..9893093a0 100644 --- a/akka-javasdk/src/main/scala/akka/javasdk/impl/keyvalueentity/KeyValueEntitiesImpl.scala +++ b/akka-javasdk/src/main/scala/akka/javasdk/impl/keyvalueentity/KeyValueEntitiesImpl.scala @@ -36,10 +36,13 @@ import org.slf4j.MDC import scala.language.existentials import scala.util.control.NonFatal import akka.javasdk.Metadata +import akka.javasdk.Tracing import akka.javasdk.impl.AnySupport import akka.javasdk.impl.effect.MessageReplyImpl import akka.javasdk.impl.keyvalueentity.KeyValueEntityEffectImpl.UpdateState import akka.javasdk.impl.keyvalueentity.KeyValueEntityRouter.CommandResult +import akka.javasdk.impl.telemetry.SpanTracingImpl +import io.opentelemetry.api.trace.Span import kalix.protocol.value_entity.ValueEntityAction.Action.Delete import kalix.protocol.value_entity.ValueEntityAction.Action.Update import kalix.protocol.value_entity.ValueEntityStreamIn.Message.{ Command => InCommand } @@ -71,7 +74,7 @@ private[impl] final class KeyValueEntitiesImpl( val services: Map[String, KeyValueEntityService[_, _]], configuration: Settings, sdkDispatcherName: String, - tracerFactory: String => Tracer) + tracerFactory: () => Tracer) extends ValueEntities { import akka.javasdk.impl.EntityExceptions._ @@ -155,9 +158,9 @@ private[impl] final class KeyValueEntitiesImpl( case InCommand(command) => val metadata = MetadataImpl.of(command.metadata.map(_.entries.toVector).getOrElse(Nil)) - + val instrumentation = instrumentations(service.componentId) if (log.isTraceEnabled) log.trace("Metadata entries [{}].", metadata.entries) - val span = instrumentations(service.componentId).buildSpan(service, command) + val span = instrumentation.buildSpan(service, command) span.foreach(s => MDC.put(Telemetry.TRACE_ID, s.getSpanContext.getTraceId)) try { @@ -167,7 +170,7 @@ private[impl] final class KeyValueEntitiesImpl( // FIXME smuggling 0 arity method called from component client through here ScalaPbAny.defaultInstance.withTypeUrl(AnySupport.JsonTypeUrlPrefix).withValue(ByteString.empty()))) val context = - new CommandContextImpl(thisEntityId, command.name, command.id, metadata, system) + new CommandContextImpl(thisEntityId, command.name, command.id, metadata, span, tracerFactory) val (CommandResult(effect: KeyValueEntityEffectImpl[_]), errorCode) = try { @@ -243,10 +246,15 @@ private[impl] final class CommandContextImpl( override val commandName: String, override val commandId: Long, override val metadata: Metadata, - system: ActorSystem) + span: Option[Span], + tracerFactory: () => Tracer) extends AbstractContext with CommandContext - with ActivatableContext + with ActivatableContext { + + override def tracing(): Tracing = + new SpanTracingImpl(span, tracerFactory) +} /** * INTERNAL API diff --git a/akka-javasdk/src/main/scala/akka/javasdk/impl/telemetry/SpanTracingImpl.scala b/akka-javasdk/src/main/scala/akka/javasdk/impl/telemetry/SpanTracingImpl.scala new file mode 100644 index 000000000..589964be3 --- /dev/null +++ b/akka-javasdk/src/main/scala/akka/javasdk/impl/telemetry/SpanTracingImpl.scala @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2021-2024 Lightbend Inc. + */ + +package akka.javasdk.impl.telemetry + +import akka.annotation.InternalApi +import akka.javasdk.Tracing +import io.opentelemetry.api.trace.Span +import io.opentelemetry.api.trace.Tracer +import io.opentelemetry.context.{ Context => OtelContext } + +import java.util.Optional +import scala.jdk.OptionConverters.RichOption + +/** + * INTERNAL API + */ +@InternalApi +final class SpanTracingImpl(span: Option[Span], tracerFactory: () => Tracer) extends Tracing { + override def startSpan(name: String): Optional[Span] = + span.map { s => + val parent = OtelContext.current().`with`(s) + tracerFactory() + .spanBuilder("ad-hoc span") + .setParent(parent) + .startSpan() + }.toJava + + override def parentSpan(): Optional[Span] = span.toJava +} diff --git a/akka-javasdk/src/main/scala/akka/javasdk/impl/telemetry/Telemetry.scala b/akka-javasdk/src/main/scala/akka/javasdk/impl/telemetry/Telemetry.scala index 814a21321..a8b8669d8 100644 --- a/akka-javasdk/src/main/scala/akka/javasdk/impl/telemetry/Telemetry.scala +++ b/akka-javasdk/src/main/scala/akka/javasdk/impl/telemetry/Telemetry.scala @@ -113,7 +113,7 @@ private[akka] object TraceInstrumentation { override def keys(carrier: MetadataEntry): lang.Iterable[String] = Collections.singleton(Telemetry.TRACE_PARENT_KEY) } - private val InstrumentationScopeName = "akka-javasdk" + val InstrumentationScopeName: String = "akka-javasdk" } /** @@ -123,7 +123,7 @@ private[akka] object TraceInstrumentation { private[akka] final class TraceInstrumentation( componentName: String, componentCategory: ComponentCategory, - tracerFactory: String => Tracer) { + val tracerFactory: () => Tracer) { import Telemetry._ import TraceInstrumentation._ @@ -135,7 +135,7 @@ private[akka] final class TraceInstrumentation( s"${componentCategory.name}: $simpleComponentName" } - private val tracer = getTracer + private val tracer = tracerFactory() private val enabled = tracer != OpenTelemetry.noop().getTracer(InstrumentationScopeName) /** @@ -168,7 +168,7 @@ private[akka] final class TraceInstrumentation( val spanName = s"$traceNamePrefix.${removeSyntheticName(commandName)}" var spanBuilder = - getTracer + tracer .spanBuilder(spanName) .setParent(parentContext) .setSpanKind(SpanKind.SERVER) @@ -179,8 +179,6 @@ private[akka] final class TraceInstrumentation( } } - def getTracer: Tracer = tracerFactory(InstrumentationScopeName) - private def removeSyntheticName(maybeSyntheticName: String): String = maybeSyntheticName .replace("KalixSyntheticMethodOnES", "") diff --git a/akka-javasdk/src/main/scala/akka/javasdk/impl/view/ViewsImpl.scala b/akka-javasdk/src/main/scala/akka/javasdk/impl/view/ViewsImpl.scala index 11a703831..027fe536e 100644 --- a/akka-javasdk/src/main/scala/akka/javasdk/impl/view/ViewsImpl.scala +++ b/akka-javasdk/src/main/scala/akka/javasdk/impl/view/ViewsImpl.scala @@ -23,8 +23,6 @@ import com.google.protobuf.any.{ Any => ScalaPbAny } import org.slf4j.LoggerFactory import org.slf4j.MDC -import scala.jdk.OptionConverters._ - /** * INTERNAL API */ @@ -97,7 +95,7 @@ final class ViewsImpl(_services: Map[String, ViewService[_]], sdkDispatcherName: val commandName = receiveEvent.commandName val msg = service.messageCodec.decodeMessage(receiveEvent.payload.get) val metadata = MetadataImpl.of(receiveEvent.metadata.map(_.entries.toVector).getOrElse(Nil)) - val addedToMDC = metadata.traceContext.traceId().toScala match { + val addedToMDC = metadata.traceId match { case Some(traceId) => MDC.put(Telemetry.TRACE_ID, traceId) true diff --git a/akka-javasdk/src/main/scala/akka/javasdk/impl/workflow/WorkflowImpl.scala b/akka-javasdk/src/main/scala/akka/javasdk/impl/workflow/WorkflowImpl.scala index 9b55aaebc..ca37d5410 100644 --- a/akka-javasdk/src/main/scala/akka/javasdk/impl/workflow/WorkflowImpl.scala +++ b/akka-javasdk/src/main/scala/akka/javasdk/impl/workflow/WorkflowImpl.scala @@ -4,47 +4,44 @@ package akka.javasdk.impl.workflow -import java.util.Optional -import scala.concurrent.ExecutionContext -import scala.concurrent.Future -import scala.jdk.OptionConverters._ -import scala.language.existentials -import scala.util.control.NonFatal import akka.NotUsed -import akka.actor.ActorSystem -import akka.javasdk.impl.ErrorHandling.BadRequestException -import akka.javasdk.impl.WorkflowExceptions.ProtocolException -import akka.javasdk.impl.WorkflowExceptions.WorkflowException -import akka.javasdk.impl.WorkflowExceptions.failureMessageForLog -import WorkflowEffectImpl.DeleteState -import WorkflowEffectImpl.End -import WorkflowEffectImpl.ErrorEffectImpl -import WorkflowEffectImpl.NoPersistence -import WorkflowEffectImpl.NoReply -import WorkflowEffectImpl.NoTransition -import WorkflowEffectImpl.Pause -import WorkflowEffectImpl.Persistence -import WorkflowEffectImpl.Reply -import WorkflowEffectImpl.ReplyValue -import WorkflowEffectImpl.StepTransition -import WorkflowEffectImpl.TransitionalEffectImpl -import WorkflowEffectImpl.UpdateState -import WorkflowRouter.CommandResult +import akka.annotation.InternalApi +import akka.javasdk.Metadata +import akka.javasdk.Tracing import akka.javasdk.impl.AbstractContext import akka.javasdk.impl.ActivatableContext +import akka.javasdk.impl.AnySupport import akka.javasdk.impl.ErrorHandling +import akka.javasdk.impl.ErrorHandling.BadRequestException import akka.javasdk.impl.JsonMessageCodec import akka.javasdk.impl.MessageCodec import akka.javasdk.impl.MetadataImpl import akka.javasdk.impl.Service import akka.javasdk.impl.StrictJsonMessageCodec +import akka.javasdk.impl.WorkflowExceptions.ProtocolException +import akka.javasdk.impl.WorkflowExceptions.WorkflowException +import akka.javasdk.impl.WorkflowExceptions.failureMessageForLog +import akka.javasdk.impl.telemetry.SpanTracingImpl import akka.javasdk.impl.timer.TimerSchedulerImpl +import akka.javasdk.impl.workflow.WorkflowEffectImpl.DeleteState +import akka.javasdk.impl.workflow.WorkflowEffectImpl.End +import akka.javasdk.impl.workflow.WorkflowEffectImpl.ErrorEffectImpl +import akka.javasdk.impl.workflow.WorkflowEffectImpl.NoPersistence +import akka.javasdk.impl.workflow.WorkflowEffectImpl.NoReply +import akka.javasdk.impl.workflow.WorkflowEffectImpl.NoTransition +import akka.javasdk.impl.workflow.WorkflowEffectImpl.Pause +import akka.javasdk.impl.workflow.WorkflowEffectImpl.Persistence +import akka.javasdk.impl.workflow.WorkflowEffectImpl.Reply +import akka.javasdk.impl.workflow.WorkflowEffectImpl.ReplyValue +import akka.javasdk.impl.workflow.WorkflowEffectImpl.StepTransition +import akka.javasdk.impl.workflow.WorkflowEffectImpl.TransitionalEffectImpl +import akka.javasdk.impl.workflow.WorkflowEffectImpl.UpdateState +import akka.javasdk.impl.workflow.WorkflowRouter.CommandResult import akka.javasdk.workflow.CommandContext import akka.javasdk.workflow.Workflow -import akka.runtime.sdk.spi.TimerClient -import Workflow.WorkflowDef -import akka.annotation.InternalApi +import akka.javasdk.workflow.Workflow.WorkflowDef import akka.javasdk.workflow.WorkflowContext +import akka.runtime.sdk.spi.TimerClient import akka.stream.scaladsl.Flow import akka.stream.scaladsl.Source import com.google.protobuf.ByteString @@ -52,6 +49,8 @@ import com.google.protobuf.any.{ Any => ScalaPbAny } import com.google.protobuf.duration import com.google.protobuf.duration.Duration import io.grpc.Status +import io.opentelemetry.api.trace.Span +import io.opentelemetry.api.trace.Tracer import kalix.protocol.component import kalix.protocol.component.{ Reply => ProtoReply } import kalix.protocol.workflow_entity.RecoverStrategy @@ -62,9 +61,9 @@ import kalix.protocol.workflow_entity.WorkflowEffect import kalix.protocol.workflow_entity.WorkflowEntities import kalix.protocol.workflow_entity.WorkflowEntityInit import kalix.protocol.workflow_entity.WorkflowStreamIn +import kalix.protocol.workflow_entity.WorkflowStreamIn.Message import kalix.protocol.workflow_entity.WorkflowStreamIn.Message.Empty import kalix.protocol.workflow_entity.WorkflowStreamIn.Message.Init -import kalix.protocol.workflow_entity.WorkflowStreamIn.Message import kalix.protocol.workflow_entity.WorkflowStreamIn.Message.Step import kalix.protocol.workflow_entity.WorkflowStreamIn.Message.Transition import kalix.protocol.workflow_entity.WorkflowStreamIn.Message.{ Command => InCommand } @@ -75,10 +74,14 @@ import kalix.protocol.workflow_entity.{ NoTransition => ProtoNoTransition } import kalix.protocol.workflow_entity.{ Pause => ProtoPause } import kalix.protocol.workflow_entity.{ StepTransition => ProtoStepTransition } import org.slf4j.LoggerFactory -import akka.javasdk.Metadata -import akka.javasdk.impl.AnySupport +import java.util.Optional +import scala.concurrent.ExecutionContext +import scala.concurrent.Future import scala.jdk.CollectionConverters._ +import scala.jdk.OptionConverters._ +import scala.language.existentials +import scala.util.control.NonFatal /** * INTERNAL API @@ -102,11 +105,11 @@ final class WorkflowService[S, W <: Workflow[S]]( */ @InternalApi final class WorkflowImpl( - system: ActorSystem, val services: Map[String, WorkflowService[_, _]], timerClient: TimerClient, sdkExcutionContext: ExecutionContext, - sdkDispatcherName: String) + sdkDispatcherName: String, + tracerFactory: () => Tracer) extends kalix.protocol.workflow_entity.WorkflowEntities { private implicit val ec: ExecutionContext = sdkExcutionContext @@ -287,7 +290,15 @@ final class WorkflowImpl( case InCommand(command) => val metadata = MetadataImpl.of(command.metadata.map(_.entries.toVector).getOrElse(Nil)) - val context = new CommandContextImpl(workflowId, command.name, command.id, metadata, system) + val context = + new CommandContextImpl( + workflowId, + command.name, + command.id, + metadata, + // FIXME we'd need to start a parent span for the command here to have one to base custom user spans of off? + None, + tracerFactory) val timerScheduler = new TimerSchedulerImpl(service.strictMessageCodec, timerClient, context.componentCallMetadata) @@ -314,7 +325,14 @@ final class WorkflowImpl( case Step(executeStep) => val context = - new CommandContextImpl(workflowId, executeStep.stepName, executeStep.commandId, Metadata.EMPTY, system) + new CommandContextImpl( + workflowId, + executeStep.stepName, + executeStep.commandId, + Metadata.EMPTY, + // FIXME we'd need to start a parent span for the step here to have one to base custom user spans of off? + None, + tracerFactory) val timerScheduler = new TimerSchedulerImpl(service.strictMessageCodec, timerClient, context.componentCallMetadata) val stepResponse = @@ -391,10 +409,15 @@ private[akka] final class CommandContextImpl( override val commandName: String, override val commandId: Long, override val metadata: Metadata, - system: ActorSystem) + span: Option[Span], + tracerFactory: () => Tracer) extends AbstractContext with CommandContext - with ActivatableContext + with ActivatableContext { + + override def tracing(): Tracing = + new SpanTracingImpl(span, tracerFactory) +} /** * INTERNAL API diff --git a/akka-javasdk/src/test/java/akka/javasdk/timedaction/TestTracing.java b/akka-javasdk/src/test/java/akka/javasdk/timedaction/TestTracing.java index e0ffa2e6a..0c5f6c70e 100644 --- a/akka-javasdk/src/test/java/akka/javasdk/timedaction/TestTracing.java +++ b/akka-javasdk/src/test/java/akka/javasdk/timedaction/TestTracing.java @@ -8,6 +8,9 @@ import akka.javasdk.consumer.Consumer; import akka.javasdk.eventsourcedentity.TestESEvent; import akka.javasdk.eventsourcedentity.TestEventSourcedEntity; +import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator; +import io.opentelemetry.context.Context; +import io.opentelemetry.context.propagation.TextMapSetter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import akka.javasdk.annotations.ComponentId; @@ -20,7 +23,20 @@ public class TestTracing extends Consumer { public Effect consume(TestESEvent.Event2 event) { logger.info("registering a logging event"); - return effects().produce( - messageContext().metadata().traceContext().traceParent().orElse("not-found")); + + // test expects a w3c encoded trace parent so here are some hoops to get that + // FIXME if this turns out to be a common need we could provide the w3c encoded traceparent from Tracing + // but for now leaving otel hoops to users is fine enough + String[] w3cEncodedTraceParent = {"not-enabled"}; + messageContext().tracing().parentSpan().ifPresent(span -> { + var contextWithSpan = Context.current().with(span); + W3CTraceContextPropagator.getInstance().inject(contextWithSpan, null, + (carrier, key, value) -> { + if (key.equals("traceparent")) { + w3cEncodedTraceParent[0] = value; + } + }); + }); + return effects().produce(w3cEncodedTraceParent[0]); } } diff --git a/akka-javasdk/src/test/scala/akka/javasdk/impl/ConsumersImplSpec.scala b/akka-javasdk/src/test/scala/akka/javasdk/impl/ConsumersImplSpec.scala index 820aaffbf..1ef1f09cd 100644 --- a/akka-javasdk/src/test/scala/akka/javasdk/impl/ConsumersImplSpec.scala +++ b/akka-javasdk/src/test/scala/akka/javasdk/impl/ConsumersImplSpec.scala @@ -56,7 +56,9 @@ class ConsumersImplSpec private val classicSystem = system.toClassic - def create(service: ConsumerService[_], tracerFactory: String => Tracer = OpenTelemetry.noop.getTracer _): Actions = { + def create( + service: ConsumerService[_], + tracerFactory: () => Tracer = () => OpenTelemetry.noop.getTracer("test")): Actions = { new ActionsImpl( classicSystem, Map(service.descriptor.getFullName -> service), @@ -117,7 +119,7 @@ class ConsumersImplSpec .builder() .build() - val service = create(consumerProvider, openTelemetryInstance.getTracer) + val service = create(consumerProvider, () => openTelemetryInstance.getTracer("test")) val serviceName = consumerProvider.descriptor.getFullName val cmd1 = ScalaPbAny.fromJavaProto(JsonSupport.encodeJson(new TestESEvent.Event2(123))) diff --git a/akka-javasdk/src/test/scala/akka/javasdk/impl/action/TimedActionHandlerSpec.scala b/akka-javasdk/src/test/scala/akka/javasdk/impl/action/TimedActionHandlerSpec.scala index 0e6b3bb67..49e8d124b 100644 --- a/akka-javasdk/src/test/scala/akka/javasdk/impl/action/TimedActionHandlerSpec.scala +++ b/akka-javasdk/src/test/scala/akka/javasdk/impl/action/TimedActionHandlerSpec.scala @@ -68,7 +68,7 @@ class TimedActionHandlerSpec override def removeTimer(name: String): Future[Done] = ??? }, classicSystem.dispatcher, - OpenTelemetry.noop().getTracer _) + () => OpenTelemetry.noop().getTracer("test")) } "The action service" should { diff --git a/docs/README.md b/docs/README.md index 1add137e1..2cd6ac033 100644 --- a/docs/README.md +++ b/docs/README.md @@ -18,7 +18,7 @@ make managed 2. Create the full site ```bash -make local +make local open ``` This command will execute a Docker-based build process that compiles the documentation. The generated documentation will be output to the `target/site` directory. diff --git a/docs/src-static/.htaccess b/docs/src-static/.htaccess index b927be13f..a65591909 100644 --- a/docs/src-static/.htaccess +++ b/docs/src-static/.htaccess @@ -228,6 +228,14 @@ RedirectMatch 301 ^/(api|japi)/akka-http/10.2.\d+(/?|/.*)$ ht RedirectMatch 301 ^/docs/akka-http/10.4(\.\d+)(/?|/.*)$ https://doc.akka.io/libraries/akka-http/10.4$1$2 RedirectMatch 301 ^/(api|japi)/akka-http/10.4.\d+(/?|/.*)$ https://doc.akka.io/$1/akka-http/10.4$2 +# =================================== +# Akka Insights +# =================================== + +# Fix links from https://doc.akka.io/libraries/akka-dependencies/current/#akka-insights +# e.g. From https://doc.akka.io/libraries/akka-insights/2.20/home.html to https://doc.akka.io/libraries/akka-insights/2.20.x/home.html +RedirectMatch 301 ^/libraries/akka-insights/(\d+\.\d+)?(/?|/.*)$ https://doc.akka.io/libraries/akka-insights/$1.x$2 + # =================================== # Akka Management # =================================== @@ -307,8 +315,8 @@ RedirectMatch 301 ^/docs/akka-persistence-r2dbc/1.2(\.\d+)(/?|/.*)$ h # =================================== # Akka Projection # =================================== -RedirectMatch 301 ^/docs/akka-distributed-cluster/(\d+\.\d+(\.\d+)?)(/?|/.*)$ https://doc.akka.io/libraries/akka-edge/current$2 -RedirectMatch 301 ^/docs/akka-edge/(\d+\.\d+(\.\d+)?)(/?|/.*)$ https://doc.akka.io/libraries/akka-distributed-cluster/current$2 +RedirectMatch 301 ^/docs/akka-distributed-cluster/(\d+\.\d+(\.\d+)?)(/?|/.*)$ https://doc.akka.io/libraries/akka-distributed-cluster/current$2 +RedirectMatch 301 ^/docs/akka-edge/(\d+\.\d+(\.\d+)?)(/?|/.*)$ https://doc.akka.io/libraries/akka-edge/current$2 # versions RedirectMatch 301 ^/docs/akka-projection/1.0(\.\d+)?(/?|/.*)$ https://doc.akka.io/libraries/akka-projection/1.0$2 @@ -415,4 +423,4 @@ RedirectMatch 301 ^/libraries/(a[^/]+)/?$ https://doc.akka.io/libraries/$1/curr RedirectMatch 301 ^/docs/([^/]+)/(.*)$ https://doc.akka.io/libraries/$1/$2 # TODO remove once the real docs are published -RedirectMatch 301 ^/akka-cli(/?|/.*)$ https://doc.akka.io/snapshots/akka-documentation/akka-cli$1 +RedirectMatch 301 ^/akka-cli(/?|/.*)$ https://doc.akka.io/snapshots/akka-documentation/akka-cli$1 \ No newline at end of file diff --git a/docs/src-static/install-cli.sh b/docs/src-static/install-cli.sh old mode 100644 new mode 100755 diff --git a/docs/src/modules/ROOT/pages/index.adoc b/docs/src/modules/ROOT/pages/index.adoc index c771624f4..fc668e4dd 100644 --- a/docs/src/modules/ROOT/pages/index.adoc +++ b/docs/src/modules/ROOT/pages/index.adoc @@ -53,12 +53,15 @@ Akka's event-sourced model is fundamentally streaming-based, providing a robust == Getting Started with Akka There are multiple ways to get started with Akka. -* *Deploy, scale, and replicate a service.* Take the 5 minute walk-through by creating a free account at https://console.akka.io/register[akka.io]. -* *Learn* the Akka xref:concepts:architecture-model.adoc[] for architects and developers. -* *Learn* the Akka xref:concepts:deployment-model.adoc[] for operators. -* *Learn* the Akka xref:concepts:development-process.adoc[] -* *Start a local development environment* Getting started with Integrated Development Environment (IDE) integration, local debugging, and packing services into images. xref:java:running-locally.adoc[] -* *Learn how to implement a "Hello World" service.* xref:java:author-your-first-service.adoc[] -* *Review a pre-built service implementation.* See some Akka components in the xref:java:shopping-cart-quickstart.adoc[] +* Hands-on +** *Deploy, scale, and replicate a pre-built service.* Take the 5 minute walk-through by creating a free account at https://console.akka.io/register[akka.io]. +** *Implement a "Hello World" service.* xref:java:author-your-first-service.adoc[]. +** *Review a pre-built service implementation.* See some Akka components in the xref:java:shopping-cart-quickstart.adoc[]. + +* Understand +** ... the Akka xref:concepts:architecture-model.adoc[] for architects and developers. +** ... the Akka xref:concepts:deployment-model.adoc[] for operators. +** ... the Akka xref:concepts:development-process.adoc[]. +* *Start a local development environment* Getting started with Integrated Development Environment (IDE) integration, local debugging, and packing services into images. See xref:java:running-locally.adoc[]. * *Setup* CI/CD pipelines, external Docker repositories, external messaging brokers, or 3rd party observability. See xref:operations:index.adoc[Operating Services] for more information. diff --git a/docs/src/modules/java/images/workflow-execution.png b/docs/src/modules/java/images/workflow-execution.png new file mode 100644 index 000000000..f8e1a61bc Binary files /dev/null and b/docs/src/modules/java/images/workflow-execution.png differ diff --git a/docs/src/modules/java/pages/access-control.adoc b/docs/src/modules/java/pages/access-control.adoc index 97be95b20..45569d03f 100644 --- a/docs/src/modules/java/pages/access-control.adoc +++ b/docs/src/modules/java/pages/access-control.adoc @@ -185,19 +185,16 @@ Note that in local development, the services don’t actually authenticate with == Programmatically accessing principals -The current principal associated with a request can be accessed through the `RequestContext`. The `RequestContext` -can be injected in the endpoint constructor. +The current principal associated with a request can be accessed through the `RequestContext`. -NOTE: Endpoints are stateless and each request is served by a new Endpoint instance. Therefore, the -injected `RequestContext` is always a new instance and is associated with the request currently being handled. +NOTE: Endpoints are stateless and each request is served by a new Endpoint instance. Therefore, the `RequestContext` is always a new instance and is associated with the request currently being handled. [source, java, indent=0] .{sample-base-url}/doc-snippets/src/main/java/com/example/acl/UserEndpoint.java[UserEndpoint.java] ---- include::example$doc-snippets/src/main/java/com/example/acl/UserEndpoint.java[tags=endpoint-class;request-context] ---- - -<1> Inject `RequestContext` on your endpoint constructor to gain access to the request specific context. +<1> Let your endpoint extend link:_attachments/api/akka/javasdk/http/AbstractHttpEndpoint.html[AbstractHttpEndpoint] to get access to the request specific `RequestContext` through `requestContext()`. You can access the current Principals through method `RequestContext.getPrincipals()` diff --git a/docs/src/modules/java/pages/auth-with-jwts.adoc b/docs/src/modules/java/pages/auth-with-jwts.adoc index f5d276252..a5901e741 100644 --- a/docs/src/modules/java/pages/auth-with-jwts.adoc +++ b/docs/src/modules/java/pages/auth-with-jwts.adoc @@ -90,15 +90,15 @@ include::example$endpoint-jwt/src/main/java/hellojwt/api/HelloJwtEndpoint.java[t ---- The token extracted from the bearer token must have one of the two issuers defined in the annotation. -Akka will place the claims from the validated token in the link:_attachments/api/akka/javasdk/http/RequestContext.html[RequestContext], so you can access them from your service via `getJwtClaims()`. The `RequestContext` can be injected into the endpoint constructor, so you can retrieve the JWT claims like this: +Akka will place the claims from the validated token in the link:_attachments/api/akka/javasdk/http/RequestContext.html[RequestContext], so you can access them from your service via `getJwtClaims()`. The `RequestContext` is accessed by letting the endpoint extend link:_attachments/api/akka/javasdk/http/AbstractHttpEndpoint.html[AbstractHttpEndpoint] which provides the method `requestContext()`, so you can retrieve the JWT claims like this: [source, java, indent=0] .{sample-base-url}/endpoint-jwt/src/main/java/hellojwt/api/HelloJwtEndpoint.java[HelloJwtEndpoint.java] ---- include::example$endpoint-jwt/src/main/java/hellojwt/api/HelloJwtEndpoint.java[tag=accessing-claims] ---- -<1> Access the claims in the request. Note that while the `get()` is generally a bad practice, here we know the claims must be present given the `@JWT` configuration. - +<1> Access the claims from the request context. +<2> Note that while calling `Optional#get()` is generally a bad practice, here we know the claims must be present given the `@JWT` configuration. == Running locally with JWT support diff --git a/docs/src/modules/java/pages/author-your-first-service.adoc b/docs/src/modules/java/pages/author-your-first-service.adoc index b0c0e59bc..60deccb4f 100644 --- a/docs/src/modules/java/pages/author-your-first-service.adoc +++ b/docs/src/modules/java/pages/author-your-first-service.adoc @@ -16,7 +16,7 @@ NOTE: If you'd rather skip past this and want to review an already completed app == Prerequisites -include::ROOT:partial$cloud-dev-prerequisites.adoc[] +include::ROOT:partial$local-dev-prerequisites.adoc[] == Generate and build the skeleton project @@ -152,27 +152,18 @@ curl localhost:9000/hello/hello/Bob/30 === Request body === -To accept an HTTP JSON body, specify a parameter that is a class that https://github.com/FasterXML/jackson?tab=readme-ov-file#what-is-jackson[Jackson] can deserialize: +To accept an HTTP JSON body, specify a parameter that is a Java record. [source,java] .HelloWorldEndpoint.java ---- include::example$doc-snippets/src/main/java/com/example/api/ExampleEndpoint.java[tag=request-body] ---- -<1> A class that Jackson can serialize and deserialize to JSON +<1> The record will serialized and deserialized as JSON <2> A parameter of the request body type <3> When combining request body with path variables <4> The body must come last in the parameter list -Additionally, the request body parameter can be of the following types: - - * `String` for any request with a text content type, the body decoded into a string - * `java.util.List` where `T` is a type Jackson can deserialize, accepts a JSON array. - * `akka.http.javadsl.model.HttpEntity.Strict` for the entire request body as bytes together with the content type for - arbitrary payload handling. - * `akka.http.javadsl.model.HttpRequest` for a low level, streaming representation of the entire request - including headers. See xref:http-endpoints.adoc#_low_level_requests[] below for more details - You can now call these commands as well [source, command line] ---- @@ -182,25 +173,14 @@ curl -i -XPOST -H "Content-Type: application/json" localhost:9000/hello/hello -d === Response body === -To return response with JSON, the return value can be a class that Jackson can serialize: +To return response with JSON, the return value can be a record that gets serialized as JSON: [source,java] .HelloWorldEndpoint.java ---- include::example$doc-snippets/src/main/java/com/example/api/ExampleEndpoint.java[tag=response-body] ---- -<1> Returning an object that Jackson can serialize into JSON - -In addition to an object that can be turned to JSON, a request handler can return the following: - - * `null` or `void` to return an empty body. - * `String` to return a UTF-8 encoded `text/plain` HTTP response. - * `CompletionStage` to respond based on an asynchronous result. - ** When the completion stage is completed with a `T` it is - turned into a response. - ** If it is instead failed, the failure leads to an error response according to - the error handling explained in xref:http-endpoints.adoc#_error_responses[error responses]. - * `akka.http.javadsl.model.HttpResponse` for complete control over the response, see xref:http-endpoints.adoc#_low_level_responses[] below +<1> Returning a record that gets serialized as JSON [source, command line] ---- @@ -208,4 +188,4 @@ curl localhost:9000/hello/hello/Bob/30 ---- == Next steps -Now that you have a basic service running, it's time to learn more about building real services in Akka. See the xref:java:shopping-cart-quickstart.adoc[] to build a more realistic application. +Now that you have a basic service running, it's time to learn more about building real services in Akka. See the xref:java:shopping-cart-quickstart.adoc[] to build a more realistic application and learn how to deploy it to https://console.akka.io[akka.io]. diff --git a/docs/src/modules/java/pages/setup-and-dependency-injection.adoc b/docs/src/modules/java/pages/setup-and-dependency-injection.adoc index e6f396a21..bb1380728 100644 --- a/docs/src/modules/java/pages/setup-and-dependency-injection.adoc +++ b/docs/src/modules/java/pages/setup-and-dependency-injection.adoc @@ -57,7 +57,7 @@ Furthermore, the following component specific types can also be injected: | Injectable classes | Endpoint -|`io.opentelemetry.api.trace.Span` for creating custom traces +|`akka.javasdk.http.RequestContext` with access to request related things. |Workflow |`akka.javasdk.workflow.WorkflowContext` for access to the workflow id |Event Sourced Entity diff --git a/docs/src/modules/java/pages/workflows.adoc b/docs/src/modules/java/pages/workflows.adoc index f65c262a4..cade3075e 100644 --- a/docs/src/modules/java/pages/workflows.adoc +++ b/docs/src/modules/java/pages/workflows.adoc @@ -4,6 +4,10 @@ include::ROOT:partial$include.adoc[] Workflows implement long-running, multi-step business processes while allowing developers to focus exclusively on domain and business logic. Workflows provide durability, consistency and the ability to call other components and services. Business transactions can be modeled in one central place, and the Workflow will keep them running smoothly, or roll back if something goes wrong. +Users can see the workflow execution details in the console (both xref:running-locally.adoc#_local_console[locally] and in the https://console.akka.io[cloud]). + +image:workflow-execution.png[] + include::partial$entity-sharding.adoc[] [#_effect_api] @@ -113,7 +117,7 @@ include::example$transfer-workflow/src/main/java/com/example/transfer/applicatio <6> This time we return an effect that will stop workflow processing, by using special `end` method. <7> We collect all steps to form a workflow definition. -IMPORTANT: In the following example all `WalletEntity` interactions are not idempotent. It means that if the workflow step retries, it will make the deposit or withdraw again. In a real-world scenario, you should consider making all interactions idempotent with a proper deduplication mechanism. +IMPORTANT: In the following example all `WalletEntity` interactions are not idempotent. It means that if the workflow step retries, it will make the deposit or withdraw again. In a real-world scenario, you should consider making all interactions idempotent with a proper deduplication mechanism. A very basic example of handling retries for workflows can be found in https://github.com/akka/akka-sdk/blob/main/samples/transfer-workflow-compensation/src/main/java/com/example/wallet/domain/Wallet.java[this] sample. == Retrieving state diff --git a/docs/src/modules/libraries/pages/index.adoc b/docs/src/modules/libraries/pages/index.adoc index ea8ba28b8..045518a21 100644 --- a/docs/src/modules/libraries/pages/index.adoc +++ b/docs/src/modules/libraries/pages/index.adoc @@ -70,7 +70,7 @@ TIP: Find the latest Akka library versions at https://doc.akka.io/libraries/akka * https://doc.akka.io/libraries/akka-distributed-cluster/current/index.html[Distributed Cluster]: Connect Akka services built on Akka libraries across geographical locations for lower latency and higher availability. -* https://doc.akka.io/libraries/akka-distributed-cluster/current/index.html[Edge]: Move your endpoints to the edge of the cloud for lower latency and higher availability. Akka Edge Rust extends the power of Akka's event-driven model to resource-constrained devices. +* https://doc.akka.io/libraries/akka-edge/current/index.html[Edge]: Move your endpoints to the edge of the cloud for lower latency and higher availability. Akka Edge Rust extends the power of Akka's event-driven model to resource-constrained devices. -- [.grid-item] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka.adoc index e23a34062..ee20c218d 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka.adoc @@ -26,21 +26,21 @@ Welcome to the Akka CLI, for more information on its usage please visit the docu * link:akka_auth.html[akka auth] - Manage Akka authentication. * link:akka_completion.html[akka completion] - Generate shell completion scripts -* link:akka_config.html[akka config] - Manage the local Akka configuration. -* link:akka_container-registry.html[akka container-registry] - Manage the Akka Container Registry. -* link:akka_docker.html[akka docker] - Manage Docker credentials for Akka projects. -* link:akka_docs.html[akka docs] - Opens the Akka documentation page -* link:akka_local.html[akka local] - Helps with local development. +* link:akka_config.html[akka config] - Manage configuration and context for the Akka CLI. +* link:akka_container-registry.html[akka container-registry] - Manage and push service images to the Akka Container Registry. +* link:akka_docker.html[akka docker] - Manage credentials for projects using private Docker registries. +* link:akka_docs.html[akka docs] - Open the Akka documentation page +* link:akka_local.html[akka local] - Interact with and manage Akka services running locally. * link:akka_logs.html[akka logs] - Display the last few lines of logs for a specific service. * link:akka_organizations.html[akka organizations] - Manage your organizations on Akka * link:akka_projects.html[akka projects] - Manage your Akka projects. * link:akka_quickstart.html[akka quickstart] - Akka quickstart project samples. -* link:akka_regions.html[akka regions] - Manage regions on Akka +* link:akka_regions.html[akka regions] - Manage available regions. * link:akka_roles.html[akka roles] - Manage the user roles for an Akka project. * link:akka_routes.html[akka routes] - Manage routes for your Akka project. * link:akka_secrets.html[akka secrets] - Manage secrets for an Akka project. * link:akka_services.html[akka services] - Manage and deploy services on Akka. -* link:akka_version.html[akka version] - Prints the akka version +* link:akka_version.html[akka version] - Print the akka CLI version [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_auth.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_auth.adoc index 788d6880a..6726a6cbf 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_auth.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_auth.adoc @@ -31,12 +31,12 @@ When authorized, you can use the CLI to perform the same operations available in == SEE ALSO * link:akka.html[akka] - Akka control -* link:akka_auth_container-registry.html[akka auth container-registry] - Manage the Akka Container Registry configuration. +* link:akka_auth_container-registry.html[akka auth container-registry] - Manage configuration for Akka Container Registry. * link:akka_auth_current-login.html[akka auth current-login] - Get details for the current logged in user. * link:akka_auth_login.html[akka auth login] - Log in to Akka. * link:akka_auth_logout.html[akka auth logout] - Log out the current user. -* link:akka_auth_signup.html[akka auth signup] - Opens the registration page. -* link:akka_auth_tokens.html[akka auth tokens] - Manage Akka authentication tokens. +* link:akka_auth_signup.html[akka auth signup] - Open the registration page. +* link:akka_auth_tokens.html[akka auth tokens] - Manage Akka authentication tokens for your user. * link:akka_auth_use-token.html[akka auth use-token] - Login using a token. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_container-registry.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_container-registry.adoc index 8378066bb..e159d4c65 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_container-registry.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_container-registry.adoc @@ -1,10 +1,14 @@ = akka auth container-registry -Manage the Akka Container Registry configuration. +Manage configuration for Akka Container Registry. == Synopsis -The Akka Container Registry (ACR) can be used by all Akka users to deploy services and is available in all Akka regions. +The Akka Container Registry (ACR) can be used by all users to deploy their services. +ACR uses an access token generated via Akka for authentication. +This command allows you to configure the Docker credential helper for ACR. + +NOTE: to use this command, the current user must be logged into Akka and Docker must be installed and accessible for the current user. == Options @@ -32,8 +36,8 @@ The Akka Container Registry (ACR) can be used by all Akka users to deploy servic * link:akka_auth.html[akka auth] - Manage Akka authentication. * link:akka_auth_container-registry_clear-cached-token.html[akka auth container-registry clear-cached-token] - Clear the cached Akka Container Registry access token. * link:akka_auth_container-registry_configure.html[akka auth container-registry configure] - Configure the Akka Container Registry docker credential helper. -* link:akka_auth_container-registry_credentials.html[akka auth container-registry credentials] - Retrieves an Akka Container Registry access token for the current user. -* link:akka_auth_container-registry_install-helper.html[akka auth container-registry install-helper] - Installs the Akka Docker credential helper in the selected directory. +* link:akka_auth_container-registry_credentials.html[akka auth container-registry credentials] - Retrieve an Akka Container Registry access token for the current user. +* link:akka_auth_container-registry_install-helper.html[akka auth container-registry install-helper] - Install the Akka Docker credential helper in the selected directory. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_container-registry_clear-cached-token.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_container-registry_clear-cached-token.adoc index c9f75388e..61f04c1df 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_container-registry_clear-cached-token.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_container-registry_clear-cached-token.adoc @@ -31,7 +31,7 @@ akka auth container-registry clear-cached-token [flags] == SEE ALSO -* link:akka_auth_container-registry.html[akka auth container-registry] - Manage the Akka Container Registry configuration. +* link:akka_auth_container-registry.html[akka auth container-registry] - Manage configuration for Akka Container Registry. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_container-registry_configure.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_container-registry_configure.adoc index ee0e62dca..77c89823f 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_container-registry_configure.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_container-registry_configure.adoc @@ -33,7 +33,7 @@ akka auth container-registry configure [flags] == SEE ALSO -* link:akka_auth_container-registry.html[akka auth container-registry] - Manage the Akka Container Registry configuration. +* link:akka_auth_container-registry.html[akka auth container-registry] - Manage configuration for Akka Container Registry. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_container-registry_credentials.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_container-registry_credentials.adoc index 8b3e90c1a..87bf5e850 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_container-registry_credentials.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_container-registry_credentials.adoc @@ -1,6 +1,6 @@ = akka auth container-registry credentials -Retrieves an Akka Container Registry access token for the current user. +Retrieve an Akka Container Registry access token for the current user. ---- akka auth container-registry credentials [flags] @@ -32,7 +32,7 @@ akka auth container-registry credentials [flags] == SEE ALSO -* link:akka_auth_container-registry.html[akka auth container-registry] - Manage the Akka Container Registry configuration. +* link:akka_auth_container-registry.html[akka auth container-registry] - Manage configuration for Akka Container Registry. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_container-registry_install-helper.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_container-registry_install-helper.adoc index 90e11728e..5fb899be1 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_container-registry_install-helper.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_container-registry_install-helper.adoc @@ -1,6 +1,6 @@ = akka auth container-registry install-helper -Installs the Akka Docker credential helper in the selected directory. +Install the Akka Docker credential helper in the selected directory. == Synopsis @@ -33,7 +33,7 @@ akka auth container-registry install-helper [flags] == SEE ALSO -* link:akka_auth_container-registry.html[akka auth container-registry] - Manage the Akka Container Registry configuration. +* link:akka_auth_container-registry.html[akka auth container-registry] - Manage configuration for Akka Container Registry. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_signup.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_signup.adoc index 78f2aab0c..98f4d971c 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_signup.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_signup.adoc @@ -1,6 +1,6 @@ = akka auth signup -Opens the registration page. +Open the registration page. ---- akka auth signup [flags] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_tokens.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_tokens.adoc index f9015a1c9..f2aff97f9 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_tokens.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_tokens.adoc @@ -1,6 +1,10 @@ = akka auth tokens -Manage Akka authentication tokens. +Manage Akka authentication tokens for your user. + +== Synopsis + +The command `akka auth tokens` manage the authentication tokens for your user allowing you to revoke any token at any time, but also to create new tokens for use in CI/CD pipelines for machine-user accounts. == Options diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_tokens_create.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_tokens_create.adoc index fda93603f..d85ff5870 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_tokens_create.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_tokens_create.adoc @@ -43,7 +43,7 @@ Token created: 0123456789abcdef0123456789abcdef0123456789abcdef == SEE ALSO -* link:akka_auth_tokens.html[akka auth tokens] - Manage Akka authentication tokens. +* link:akka_auth_tokens.html[akka auth tokens] - Manage Akka authentication tokens for your user. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_tokens_list.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_tokens_list.adoc index 50c6acd36..bec1126ae 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_tokens_list.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_tokens_list.adoc @@ -35,7 +35,7 @@ akka auth tokens list [flags] == SEE ALSO -* link:akka_auth_tokens.html[akka auth tokens] - Manage Akka authentication tokens. +* link:akka_auth_tokens.html[akka auth tokens] - Manage Akka authentication tokens for your user. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_tokens_revoke.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_tokens_revoke.adoc index 14430ed80..a3ea54703 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_tokens_revoke.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_auth_tokens_revoke.adoc @@ -37,7 +37,7 @@ akka auth tokens revoke ID [flags] == SEE ALSO -* link:akka_auth_tokens.html[akka auth tokens] - Manage Akka authentication tokens. +* link:akka_auth_tokens.html[akka auth tokens] - Manage Akka authentication tokens for your user. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_config.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_config.adoc index f346a4f0e..4a6490161 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_config.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_config.adoc @@ -1,10 +1,13 @@ = akka config -Manage the local Akka configuration. +Manage configuration and context for the Akka CLI. == Synopsis The `akka config` commands display and set configuration contexts and values that apply to subsequent commands. +These are often useful to make your CLI experience more fluid. +For example, by having set a default _project_, you can avoid specifying the project id or name in every command. + Configuration settings are stored in a file on your local system, by default at `.akka/config.yaml` in your home directory. This location can be adjusted with the `--config` flag. diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_config_clear-cache.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_config_clear-cache.adoc index 4f4315885..056d5e5fe 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_config_clear-cache.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_config_clear-cache.adoc @@ -33,7 +33,7 @@ akka config clear-cache [flags] == SEE ALSO -* link:akka_config.html[akka config] - Manage the local Akka configuration. +* link:akka_config.html[akka config] - Manage configuration and context for the Akka CLI. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_config_clear.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_config_clear.adoc index 006369fe7..29871879d 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_config_clear.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_config_clear.adoc @@ -33,7 +33,7 @@ akka config clear KEY [flags] == SEE ALSO -* link:akka_config.html[akka config] - Manage the local Akka configuration. +* link:akka_config.html[akka config] - Manage configuration and context for the Akka CLI. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_config_current-context.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_config_current-context.adoc index 7b79505a3..10b2089ef 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_config_current-context.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_config_current-context.adoc @@ -34,7 +34,7 @@ akka config current-context [flags] == SEE ALSO -* link:akka_config.html[akka config] - Manage the local Akka configuration. +* link:akka_config.html[akka config] - Manage configuration and context for the Akka CLI. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_config_delete-context.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_config_delete-context.adoc index 00c893486..77869f69d 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_config_delete-context.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_config_delete-context.adoc @@ -33,7 +33,7 @@ akka config delete-context CONTEXT [flags] == SEE ALSO -* link:akka_config.html[akka config] - Manage the local Akka configuration. +* link:akka_config.html[akka config] - Manage configuration and context for the Akka CLI. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_config_get-organization.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_config_get-organization.adoc index e5310b1b2..cb6340968 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_config_get-organization.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_config_get-organization.adoc @@ -29,7 +29,7 @@ akka config get-organization [flags] == SEE ALSO -* link:akka_config.html[akka config] - Manage the local Akka configuration. +* link:akka_config.html[akka config] - Manage configuration and context for the Akka CLI. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_config_get-project.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_config_get-project.adoc index 5cba549d2..f6b64f0e0 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_config_get-project.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_config_get-project.adoc @@ -29,7 +29,7 @@ akka config get-project [flags] == SEE ALSO -* link:akka_config.html[akka config] - Manage the local Akka configuration. +* link:akka_config.html[akka config] - Manage configuration and context for the Akka CLI. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_config_get.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_config_get.adoc index 34eb39b0b..b642bc642 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_config_get.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_config_get.adoc @@ -33,7 +33,7 @@ akka config get KEY [flags] == SEE ALSO -* link:akka_config.html[akka config] - Manage the local Akka configuration. +* link:akka_config.html[akka config] - Manage configuration and context for the Akka CLI. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_config_list-contexts.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_config_list-contexts.adoc index 2381426e7..1282b354d 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_config_list-contexts.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_config_list-contexts.adoc @@ -33,7 +33,7 @@ akka config list-contexts [flags] == SEE ALSO -* link:akka_config.html[akka config] - Manage the local Akka configuration. +* link:akka_config.html[akka config] - Manage configuration and context for the Akka CLI. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_config_list.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_config_list.adoc index 7ffd9c805..a31c4a871 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_config_list.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_config_list.adoc @@ -33,7 +33,7 @@ akka config list [flags] == SEE ALSO -* link:akka_config.html[akka config] - Manage the local Akka configuration. +* link:akka_config.html[akka config] - Manage configuration and context for the Akka CLI. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_config_rename-context.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_config_rename-context.adoc index c29f1bbe7..2f0a70124 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_config_rename-context.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_config_rename-context.adoc @@ -33,7 +33,7 @@ akka config rename-context CONTEXT [flags] == SEE ALSO -* link:akka_config.html[akka config] - Manage the local Akka configuration. +* link:akka_config.html[akka config] - Manage configuration and context for the Akka CLI. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_config_set.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_config_set.adoc index 489d4e2a6..a218af9bc 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_config_set.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_config_set.adoc @@ -37,7 +37,7 @@ akka config set KEY VALUE [flags] == SEE ALSO -* link:akka_config.html[akka config] - Manage the local Akka configuration. +* link:akka_config.html[akka config] - Manage configuration and context for the Akka CLI. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_config_use-context.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_config_use-context.adoc index 38200bb43..f597a1ef4 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_config_use-context.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_config_use-context.adoc @@ -37,7 +37,7 @@ akka config use-context CONTEXT [flags] == SEE ALSO -* link:akka_config.html[akka config] - Manage the local Akka configuration. +* link:akka_config.html[akka config] - Manage configuration and context for the Akka CLI. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_container-registry.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_container-registry.adoc index 6077a67d1..cc7137a2d 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_container-registry.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_container-registry.adoc @@ -1,10 +1,13 @@ = akka container-registry -Manage the Akka Container Registry. +Manage and push service images to the Akka Container Registry. == Synopsis -The Akka Container Registry (ACR) can be used by all Akka users to deploy services and is available in all Akka regions. +The Akka Container Registry (ACR) can be used by all users to deploy their services. +ACR makes service container images available to Akka in all regions automatically. + +NOTE: to use an external Docker registry instead, refer to the documentation https://doc.akka.io/operations/projects/external-container-registries.html . == Options @@ -30,11 +33,11 @@ The Akka Container Registry (ACR) can be used by all Akka users to deploy servic == SEE ALSO * link:akka.html[akka] - Akka control -* link:akka_container-registry_delete-image.html[akka container-registry delete-image] - delete image from the Akka Container Registry. -If no tag is provided, it deletes all tags +* link:akka_container-registry_delete-image.html[akka container-registry delete-image] - Delete image from the Akka Container Registry. +If no tag is provided, it deletes all tags. * link:akka_container-registry_list.html[akka container-registry list] - List the Akka Container Registry and region. * link:akka_container-registry_list-images.html[akka container-registry list-images] - list images from the Akka Container Registry. -* link:akka_container-registry_list-tags.html[akka container-registry list-tags] - list all images tags. +* link:akka_container-registry_list-tags.html[akka container-registry list-tags] - List all images tags. * link:akka_container-registry_print.html[akka container-registry print] - Print the path of the Akka Container Registry. * link:akka_container-registry_push.html[akka container-registry push] - Push an Akka service image for a particular Akka project. diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_container-registry_delete-image.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_container-registry_delete-image.adoc index e913bf793..ec17fd203 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_container-registry_delete-image.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_container-registry_delete-image.adoc @@ -1,10 +1,10 @@ = akka container-registry delete-image -delete image from the Akka Container Registry. -If no tag is provided, it deletes all tags +Delete image from the Akka Container Registry. +If no tag is provided, it deletes all tags. ---- -akka container-registry delete-image [:] [flags] +akka container-registry delete-image _image_[:] [flags] ---- == Options @@ -30,7 +30,7 @@ akka container-registry delete-image [:] [flags] == SEE ALSO -* link:akka_container-registry.html[akka container-registry] - Manage the Akka Container Registry. +* link:akka_container-registry.html[akka container-registry] - Manage and push service images to the Akka Container Registry. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_container-registry_list-images.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_container-registry_list-images.adoc index e2aa6af21..626cdfedc 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_container-registry_list-images.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_container-registry_list-images.adoc @@ -31,7 +31,7 @@ akka container-registry list-images [flags] == SEE ALSO -* link:akka_container-registry.html[akka container-registry] - Manage the Akka Container Registry. +* link:akka_container-registry.html[akka container-registry] - Manage and push service images to the Akka Container Registry. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_container-registry_list-tags.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_container-registry_list-tags.adoc index 868f14643..2ea416e30 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_container-registry_list-tags.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_container-registry_list-tags.adoc @@ -1,6 +1,6 @@ = akka container-registry list-tags -list all images tags. +List all images tags. == Synopsis @@ -35,7 +35,7 @@ akka container-registry list-tags IMAGE [flags] == SEE ALSO -* link:akka_container-registry.html[akka container-registry] - Manage the Akka Container Registry. +* link:akka_container-registry.html[akka container-registry] - Manage and push service images to the Akka Container Registry. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_container-registry_list.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_container-registry_list.adoc index 45fbcc1d9..82de78658 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_container-registry_list.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_container-registry_list.adoc @@ -29,7 +29,7 @@ akka container-registry list [flags] == SEE ALSO -* link:akka_container-registry.html[akka container-registry] - Manage the Akka Container Registry. +* link:akka_container-registry.html[akka container-registry] - Manage and push service images to the Akka Container Registry. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_container-registry_print.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_container-registry_print.adoc index e01619bb7..cb176eeec 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_container-registry_print.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_container-registry_print.adoc @@ -29,7 +29,7 @@ akka container-registry print [flags] == SEE ALSO -* link:akka_container-registry.html[akka container-registry] - Manage the Akka Container Registry. +* link:akka_container-registry.html[akka container-registry] - Manage and push service images to the Akka Container Registry. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_container-registry_push.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_container-registry_push.adoc index 519900b1f..22118e27a 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_container-registry_push.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_container-registry_push.adoc @@ -4,15 +4,15 @@ Push an Akka service image for a particular Akka project. == Synopsis -The `akka container-registry push ` command will push the given container image to the Akka container registry. +The `akka container-registry push _image_` command will push the given container image to the Akka container registry. The provided image name must be a valid Docker image tag and not an image hash/SHA-256. -This command will replace the `HOST[:PORT_NUMBER]` portion of the specified ++++++with the appropriate Akka container registry hostname if it does not match the expected hostname. +This command will replace the `HOST[:PORT_NUMBER]` portion of the specified _image_ with the appropriate Akka container registry hostname if it does not match the expected hostname. This command is also multi-region aware. -If the current (or specified) Akka project is a multi-region project, the provided ++++++will be tagged with a new tag for each Akka region where the project resides and this command will push the image to each of those regions for you.++++++++++++ +If the current (or specified) Akka project is a multi-region project, the provided _image_ will be tagged with a new tag for each Akka region where the project resides and this command will push the image to each of those regions for you. -NOTE: You must have the source ++++++in your local Docker service image catalog for this command to function. -If the image is not locally stored, you can pull it (via `docker pull ++++++` first before running this command.++++++++++++ +NOTE: You must have the source _image_ in your local Docker service image catalog for this command to function. +If the image is not locally stored, you can pull it (via `docker pull _image_` first before running this command. ---- akka container-registry push IMAGE [flags] @@ -43,7 +43,7 @@ akka container-registry push IMAGE [flags] == SEE ALSO -* link:akka_container-registry.html[akka container-registry] - Manage the Akka Container Registry. +* link:akka_container-registry.html[akka container-registry] - Manage and push service images to the Akka Container Registry. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_docker.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_docker.adoc index 1cf4193ef..fee0d4a1e 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_docker.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_docker.adoc @@ -1,6 +1,6 @@ = akka docker -Manage Docker credentials for Akka projects. +Manage credentials for projects using private Docker registries. == Synopsis diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_docker_add-credentials.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_docker_add-credentials.adoc index 3c8a8be94..2f8c0a9d9 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_docker_add-credentials.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_docker_add-credentials.adoc @@ -5,6 +5,7 @@ Add Docker credentials to an Akka project. == Synopsis Use the `akka docker add-credentials [flags]` command to add a set of Docker credentials to the project. +With this, any service in the project can be deployed based on images from the private Docker registry. ---- akka docker add-credentials [flags] @@ -45,7 +46,7 @@ akka docker add-credentials [flags] == SEE ALSO -* link:akka_docker.html[akka docker] - Manage Docker credentials for Akka projects. +* link:akka_docker.html[akka docker] - Manage credentials for projects using private Docker registries. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_docker_list-credentials.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_docker_list-credentials.adoc index 266d3b951..9a1a3bcea 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_docker_list-credentials.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_docker_list-credentials.adoc @@ -38,7 +38,7 @@ akka docker list-credentials [flags] == SEE ALSO -* link:akka_docker.html[akka docker] - Manage Docker credentials for Akka projects. +* link:akka_docker.html[akka docker] - Manage credentials for projects using private Docker registries. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_docker_remove-credentials.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_docker_remove-credentials.adoc index ee63bf95e..8ff52509c 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_docker_remove-credentials.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_docker_remove-credentials.adoc @@ -38,7 +38,7 @@ akka docker remove-credentials SECRET [flags] == SEE ALSO -* link:akka_docker.html[akka docker] - Manage Docker credentials for Akka projects. +* link:akka_docker.html[akka docker] - Manage credentials for projects using private Docker registries. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_docs.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_docs.adoc index d7789f933..bbc3b75dc 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_docs.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_docs.adoc @@ -1,6 +1,6 @@ = akka docs -Opens the Akka documentation page +Open the Akka documentation page ---- akka docs [flags] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_local.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_local.adoc index 63e65bc80..a6822f6e3 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_local.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_local.adoc @@ -1,10 +1,10 @@ = akka local -Helps with local development. +Interact with and manage Akka services running locally. == Synopsis -The `akka local` commands help with local development. +The `akka local` commands help with local development by providing ways to interact with, discover and explore Akka services and its data when running them locally. == Options diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_local_console.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_local_console.adoc index 4912d2220..6a4087f5d 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_local_console.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_local_console.adoc @@ -34,7 +34,7 @@ akka local console [flags] == SEE ALSO -* link:akka_local.html[akka local] - Helps with local development. +* link:akka_local.html[akka local] - Interact with and manage Akka services running locally. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services.adoc index 1e85ed8d9..3ccffe7f9 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services.adoc @@ -4,7 +4,7 @@ Manage Akka services locally. == Synopsis -The `akka local services` commands are used to manage and modify the services in your Akka project. +The `akka local services` commands are used for development purposes to interact with Akka services running locally. == Options @@ -29,8 +29,8 @@ The `akka local services` commands are used to manage and modify the services in == SEE ALSO -* link:akka_local.html[akka local] - Helps with local development. -* link:akka_local_services_components.html[akka local services components] - Manage the components of a service. +* link:akka_local.html[akka local] - Interact with and manage Akka services running locally. +* link:akka_local_services_components.html[akka local services components] - Inspect components of a service. * link:akka_local_services_connectivity.html[akka local services connectivity] - Summarize all services connectivity and status. * link:akka_local_services_list.html[akka local services list] - List all services. * link:akka_local_services_views.html[akka local services views] - Manage views. diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_components.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_components.adoc index a26ec98ff..9e7803072 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_components.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_components.adoc @@ -1,6 +1,10 @@ = akka local services components -Manage the components of a service. +Inspect components of a service. + +== Synopsis + +The `akka service components` commands provides a way to inspect the components of a service but also to peek at the data stored in the different entities. == Options diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_components_get-state.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_components_get-state.adoc index 02d9c5a1b..3963948ba 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_components_get-state.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_components_get-state.adoc @@ -37,7 +37,7 @@ akka local services components get-state SERVICE_NAME COMPONENT_NAME ID [flags] == SEE ALSO -* link:akka_local_services_components.html[akka local services components] - Manage the components of a service. +* link:akka_local_services_components.html[akka local services components] - Inspect components of a service. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_components_get-workflow.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_components_get-workflow.adoc index 71c31dd9a..2424670e4 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_components_get-workflow.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_components_get-workflow.adoc @@ -37,7 +37,7 @@ akka local services components get-workflow SERVICE_NAME COMPONENT_NAME WORKFLOW == SEE ALSO -* link:akka_local_services_components.html[akka local services components] - Manage the components of a service. +* link:akka_local_services_components.html[akka local services components] - Inspect components of a service. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_components_list-events.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_components_list-events.adoc index ff28dc70d..83b15e1ab 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_components_list-events.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_components_list-events.adoc @@ -41,7 +41,7 @@ akka local services components list-events SERVICE_NAME COMPONENT_NAME ENTITY_ID == SEE ALSO -* link:akka_local_services_components.html[akka local services components] - Manage the components of a service. +* link:akka_local_services_components.html[akka local services components] - Inspect components of a service. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_components_list-ids.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_components_list-ids.adoc index 46b1131aa..16f2c92bc 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_components_list-ids.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_components_list-ids.adoc @@ -39,7 +39,7 @@ akka local services components list-ids SERVICE_NAME COMPONENT_NAME [flags] == SEE ALSO -* link:akka_local_services_components.html[akka local services components] - Manage the components of a service. +* link:akka_local_services_components.html[akka local services components] - Inspect components of a service. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_components_list-timers.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_components_list-timers.adoc index d12027bc8..5bfae8019 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_components_list-timers.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_components_list-timers.adoc @@ -41,7 +41,7 @@ akka local services components list-timers SERVICE_NAME [flags] == SEE ALSO -* link:akka_local_services_components.html[akka local services components] - Manage the components of a service. +* link:akka_local_services_components.html[akka local services components] - Inspect components of a service. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_components_list.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_components_list.adoc index 4e31b41c7..51abfc410 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_components_list.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_components_list.adoc @@ -36,7 +36,7 @@ akka local services components list SERVICE [flags] == SEE ALSO -* link:akka_local_services_components.html[akka local services components] - Manage the components of a service. +* link:akka_local_services_components.html[akka local services components] - Inspect components of a service. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_list.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_list.adoc index 659ed583a..6b4c3303e 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_list.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_list.adoc @@ -5,6 +5,7 @@ List all services. == Synopsis The `akka local services list` command lists a one-line summary of all services under your current project. +By default, it shows information for the primary region of the configured project only. ---- akka local services list [flags] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_views.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_views.adoc index 388916586..26701f763 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_views.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_local_services_views.adoc @@ -2,6 +2,10 @@ Manage views. +== Synopsis + +The `akka local service views` commands manage the views for an Akka project, including listing of existing views and deleting views and their data when a view is no longer used. + == Options ---- diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_organizations.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_organizations.adoc index 3ca09cb98..1ad19cb8c 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_organizations.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_organizations.adoc @@ -5,6 +5,8 @@ Manage your organizations on Akka == Synopsis The `akka organizations` commands manage the organizations in your Akka account. +Organizations are the root of the management hierarchy and serve as a container for all Projects where Services are deployed. +For more details on organizations, see https://doc.akka.io/operations/organizations/index.html . == Options @@ -32,8 +34,8 @@ The `akka organizations` commands manage the organizations in your Akka account. * link:akka.html[akka] - Akka control * link:akka_organizations_auth.html[akka organizations auth] - Manage authentication for your organization on Akka * link:akka_organizations_get.html[akka organizations get] - Get organization information. -* link:akka_organizations_invitations.html[akka organizations invitations] - invitations -* link:akka_organizations_list.html[akka organizations list] - List all organizations of which the user is a member. +* link:akka_organizations_invitations.html[akka organizations invitations] - Invite new users to the organization with a specific role. +* link:akka_organizations_list.html[akka organizations list] - List all organizations of which the user is a member of. * link:akka_organizations_users.html[akka organizations users] - Manage organization users. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_organizations_auth.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_organizations_auth.adoc index 0e16cb04a..fec238992 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_organizations_auth.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_organizations_auth.adoc @@ -5,6 +5,7 @@ Manage authentication for your organization on Akka == Synopsis The `akka organizations auth` commands manage the authentication for organizations in Akka. +For example, you can configure your organization to use OpenID Connect (OIDC) for authentication. == Options diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_organizations_invitations.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_organizations_invitations.adoc index 6522ae69a..c30cf7b8c 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_organizations_invitations.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_organizations_invitations.adoc @@ -1,6 +1,6 @@ = akka organizations invitations -invitations +Invite new users to the organization with a specific role. == Options diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_organizations_invitations_cancel.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_organizations_invitations_cancel.adoc index d0bcb3ae7..0903706ce 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_organizations_invitations_cancel.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_organizations_invitations_cancel.adoc @@ -31,7 +31,7 @@ akka organizations invitations cancel --email INVITEE'S_EMAIL [flags] == SEE ALSO -* link:akka_organizations_invitations.html[akka organizations invitations] - invitations +* link:akka_organizations_invitations.html[akka organizations invitations] - Invite new users to the organization with a specific role. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_organizations_invitations_create.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_organizations_invitations_create.adoc index 4432590df..c7f91e489 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_organizations_invitations_create.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_organizations_invitations_create.adoc @@ -32,7 +32,7 @@ akka organizations invitations create --email EMAIL --role ROLE [flags] == SEE ALSO -* link:akka_organizations_invitations.html[akka organizations invitations] - invitations +* link:akka_organizations_invitations.html[akka organizations invitations] - Invite new users to the organization with a specific role. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_organizations_invitations_list.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_organizations_invitations_list.adoc index 29766e9c1..89cef930a 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_organizations_invitations_list.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_organizations_invitations_list.adoc @@ -30,7 +30,7 @@ akka organizations invitations list [flags] == SEE ALSO -* link:akka_organizations_invitations.html[akka organizations invitations] - invitations +* link:akka_organizations_invitations.html[akka organizations invitations] - Invite new users to the organization with a specific role. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_organizations_list.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_organizations_list.adoc index 467037089..586fb8561 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_organizations_list.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_organizations_list.adoc @@ -1,6 +1,6 @@ = akka organizations list -List all organizations of which the user is a member. +List all organizations of which the user is a member of. ---- akka organizations list [flags] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects.adoc index 272985da9..97b2fbea1 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects.adoc @@ -5,6 +5,8 @@ Manage your Akka projects. == Synopsis The `akka projects` commands manipulate the projects in your Akka account, where a project is a collection of services. +A project can be deployed to one or more regions. +For more details on projects, see https://doc.akka.io/operations/projects/index.html == Options @@ -36,10 +38,10 @@ The `akka projects` commands manipulate the projects in your Akka account, where * link:akka_projects_hostnames.html[akka projects hostnames] - Manage hostnames for your Akka project. * link:akka_projects_list.html[akka projects list] - List all projects. * link:akka_projects_new.html[akka projects new] - Create a new Akka project. -* link:akka_projects_observability.html[akka projects observability] - Manage the observability settings for your Akka project -* link:akka_projects_open.html[akka projects open] - Opens the current project in the console. -* link:akka_projects_regions.html[akka projects regions] - Manage the regions for your Akka project -* link:akka_projects_tokens.html[akka projects tokens] - Manage your Akka project service tokens +* link:akka_projects_observability.html[akka projects observability] - Manage the observability settings for your Akka project. +* link:akka_projects_open.html[akka projects open] - Open the current project in the console. +* link:akka_projects_regions.html[akka projects regions] - Manage the regions assigned to your Akka project. +* link:akka_projects_tokens.html[akka projects tokens] - Manage your Akka project service tokens. * link:akka_projects_update.html[akka projects update] - Update project attributes such as name and description. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_delete.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_delete.adoc index 6c881a12a..48213b9d5 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_delete.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_delete.adoc @@ -4,7 +4,8 @@ Delete a project. == Synopsis -The `akka projects delete PROJECT` command will delete the project. +The `akka projects delete _project-name_` command will delete the project. +If the project still has running services, you will need to delete them first. TIP: Use `akka projects list` to identify a project. diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_get.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_get.adoc index effcbb732..48492535f 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_get.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_get.adoc @@ -4,9 +4,10 @@ Get project information. == Synopsis -The `akka projects get _id_` command will display information about the project with the id _id_, if it exists. +The `akka projects get _name_` command will display information about the project with name _name_, if it exists. +Using the _id_ of the project is also supported. -TIP: Use `akka projects list` to identify a project's _id_. +TIP: Use `akka projects list` to confirm the project's _name_ or _id_. ---- akka projects get PROJECT [flags] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability.adoc index 3be556471..923607213 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability.adoc @@ -1,10 +1,11 @@ = akka projects observability -Manage the observability settings for your Akka project +Manage the observability settings for your Akka project. == Synopsis -The `akka project observability` command manages the observability settings for your Akka project. +The `akka project observability` command manages the observability settings for your Akka project, allowing you to configure exporters for metrics, logs, and traces so you can ship those to your observability platform of choice. +These observability settings are applied to all services in your project. == Options @@ -30,13 +31,13 @@ The `akka project observability` command manages the observability settings for == SEE ALSO * link:akka_projects.html[akka projects] - Manage your Akka projects. -* link:akka_projects_observability_apply.html[akka projects observability apply] - Applies an observability descriptor to the currently configured project. -* link:akka_projects_observability_config.html[akka projects observability config] - Manage the observability configuration for your Akka project +* link:akka_projects_observability_apply.html[akka projects observability apply] - Apply an observability descriptor to the currently configured project. +* link:akka_projects_observability_config.html[akka projects observability config] - Manage the observability configuration for your Akka project. * link:akka_projects_observability_edit.html[akka projects observability edit] - Edit observability configuration for your Akka project. -* link:akka_projects_observability_export.html[akka projects observability export] - Exports an observability descriptor from the currently configured project. +* link:akka_projects_observability_export.html[akka projects observability export] - Export an observability descriptor from the currently configured project. * link:akka_projects_observability_get.html[akka projects observability get] - Get observability configuration for your Akka project. -* link:akka_projects_observability_set.html[akka projects observability set] - Set the observability settings for your Akka project -* link:akka_projects_observability_unset.html[akka projects observability unset] - Unset the observability settings for your Akka project +* link:akka_projects_observability_set.html[akka projects observability set] - Set the observability settings for your Akka project. +* link:akka_projects_observability_unset.html[akka projects observability unset] - Unset the observability settings for your Akka project. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_apply.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_apply.adoc index 9accc1577..3c2c227b1 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_apply.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_apply.adoc @@ -1,6 +1,6 @@ = akka projects observability apply -Applies an observability descriptor to the currently configured project. +Apply an observability descriptor to the currently configured project. == Synopsis @@ -45,7 +45,7 @@ akka project observability apply -f _file-name_ == SEE ALSO -* link:akka_projects_observability.html[akka projects observability] - Manage the observability settings for your Akka project +* link:akka_projects_observability.html[akka projects observability] - Manage the observability settings for your Akka project. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_config.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_config.adoc index f3f389860..5549351f0 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_config.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_config.adoc @@ -1,6 +1,6 @@ = akka projects observability config -Manage the observability configuration for your Akka project +Manage the observability configuration for your Akka project. == Synopsis @@ -29,8 +29,8 @@ The `akka project observability config` command manages the observability config == SEE ALSO -* link:akka_projects_observability.html[akka projects observability] - Manage the observability settings for your Akka project -* link:akka_projects_observability_config_traces.html[akka projects observability config traces] - Configure traces sampling for your Akka project +* link:akka_projects_observability.html[akka projects observability] - Manage the observability settings for your Akka project. +* link:akka_projects_observability_config_traces.html[akka projects observability config traces] - Configure traces sampling for your Akka project. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_config_traces.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_config_traces.adoc index de583a9c0..3624fa67c 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_config_traces.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_config_traces.adoc @@ -1,6 +1,6 @@ = akka projects observability config traces -Configure traces sampling for your Akka project +Configure traces sampling for your Akka project. == Synopsis @@ -39,7 +39,7 @@ akka projects observability config traces [flags] == SEE ALSO -* link:akka_projects_observability_config.html[akka projects observability config] - Manage the observability configuration for your Akka project +* link:akka_projects_observability_config.html[akka projects observability config] - Manage the observability configuration for your Akka project. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_edit.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_edit.adoc index c330764c7..f323644dc 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_edit.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_edit.adoc @@ -38,7 +38,7 @@ akka projects observability edit [flags] == SEE ALSO -* link:akka_projects_observability.html[akka projects observability] - Manage the observability settings for your Akka project +* link:akka_projects_observability.html[akka projects observability] - Manage the observability settings for your Akka project. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_export.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_export.adoc index 0799895dc..0ae4d2c9b 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_export.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_export.adoc @@ -1,6 +1,6 @@ = akka projects observability export -Exports an observability descriptor from the currently configured project. +Export an observability descriptor from the currently configured project. == Synopsis @@ -45,7 +45,7 @@ akka project observability export -f _file-name_ == SEE ALSO -* link:akka_projects_observability.html[akka projects observability] - Manage the observability settings for your Akka project +* link:akka_projects_observability.html[akka projects observability] - Manage the observability settings for your Akka project. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_get.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_get.adoc index 84e0a716a..9453514af 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_get.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_get.adoc @@ -37,7 +37,7 @@ akka projects observability get [flags] == SEE ALSO -* link:akka_projects_observability.html[akka projects observability] - Manage the observability settings for your Akka project +* link:akka_projects_observability.html[akka projects observability] - Manage the observability settings for your Akka project. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set.adoc index abad55d37..98d5cb42c 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set.adoc @@ -1,6 +1,6 @@ = akka projects observability set -Set the observability settings for your Akka project +Set the observability settings for your Akka project. == Synopsis @@ -29,11 +29,11 @@ The `akka project observability set` command sets the observability settings for == SEE ALSO -* link:akka_projects_observability.html[akka projects observability] - Manage the observability settings for your Akka project -* link:akka_projects_observability_set_default.html[akka projects observability set default] - Set the default exporter for your Akka project -* link:akka_projects_observability_set_logs.html[akka projects observability set logs] - Set the logs exporter for your Akka project -* link:akka_projects_observability_set_metrics.html[akka projects observability set metrics] - Set the metrics exporter for your Akka project -* link:akka_projects_observability_set_traces.html[akka projects observability set traces] - Set the traces exporter for your Akka project +* link:akka_projects_observability.html[akka projects observability] - Manage the observability settings for your Akka project. +* link:akka_projects_observability_set_default.html[akka projects observability set default] - Set the default exporter for your Akka project. +* link:akka_projects_observability_set_logs.html[akka projects observability set logs] - Set the logs exporter for your Akka project. +* link:akka_projects_observability_set_metrics.html[akka projects observability set metrics] - Set the metrics exporter for your Akka project. +* link:akka_projects_observability_set_traces.html[akka projects observability set traces] - Set the traces exporter for your Akka project. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_default.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_default.adoc index dafda39ab..b56d03f03 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_default.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_default.adoc @@ -1,10 +1,10 @@ = akka projects observability set default -Set the default exporter for your Akka project +Set the default exporter for your Akka project. == Synopsis -The `akka project observability set default` command sets the default exporter for your Kalix project. +The `akka project observability set default` command sets the default exporter for your Akka project. Setting a default exporter will unset all other exporters configured for your project. @@ -31,7 +31,7 @@ Setting a default exporter will unset all other exporters configured for your pr == SEE ALSO -* link:akka_projects_observability_set.html[akka projects observability set] - Set the observability settings for your Akka project +* link:akka_projects_observability_set.html[akka projects observability set] - Set the observability settings for your Akka project. * link:akka_projects_observability_set_default_akka-console.html[akka projects observability set default akka-console] - Set your project to export metrics to the Akka console. This will unset all other exporter configuration. * link:akka_projects_observability_set_default_google-cloud.html[akka projects observability set default google-cloud] - Set your project to export default to Google Cloud. diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_default_akka-console.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_default_akka-console.adoc index 7087f002e..3132df575 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_default_akka-console.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_default_akka-console.adoc @@ -35,7 +35,7 @@ akka projects observability set default akka-console [flags] == SEE ALSO -* link:akka_projects_observability_set_default.html[akka projects observability set default] - Set the default exporter for your Akka project +* link:akka_projects_observability_set_default.html[akka projects observability set default] - Set the default exporter for your Akka project. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_default_google-cloud.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_default_google-cloud.adoc index 0a9e1fd14..745f02c42 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_default_google-cloud.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_default_google-cloud.adoc @@ -35,7 +35,7 @@ akka projects observability set default google-cloud [flags] == SEE ALSO -* link:akka_projects_observability_set_default.html[akka projects observability set default] - Set the default exporter for your Akka project +* link:akka_projects_observability_set_default.html[akka projects observability set default] - Set the default exporter for your Akka project. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_default_otlp.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_default_otlp.adoc index 4078accec..af6d29f9d 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_default_otlp.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_default_otlp.adoc @@ -41,7 +41,7 @@ akka projects observability set default otlp [flags] == SEE ALSO -* link:akka_projects_observability_set_default.html[akka projects observability set default] - Set the default exporter for your Akka project +* link:akka_projects_observability_set_default.html[akka projects observability set default] - Set the default exporter for your Akka project. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_default_splunk-hec.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_default_splunk-hec.adoc index 7acf29b61..00d1a1ea0 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_default_splunk-hec.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_default_splunk-hec.adoc @@ -44,7 +44,7 @@ akka projects observability set default splunk-hec [flags] == SEE ALSO -* link:akka_projects_observability_set_default.html[akka projects observability set default] - Set the default exporter for your Akka project +* link:akka_projects_observability_set_default.html[akka projects observability set default] - Set the default exporter for your Akka project. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_logs.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_logs.adoc index e546de491..86ba89bfd 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_logs.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_logs.adoc @@ -1,6 +1,6 @@ = akka projects observability set logs -Set the logs exporter for your Akka project +Set the logs exporter for your Akka project. == Synopsis @@ -29,7 +29,7 @@ The `akka project observability set logs` command sets the logs exporter for you == SEE ALSO -* link:akka_projects_observability_set.html[akka projects observability set] - Set the observability settings for your Akka project +* link:akka_projects_observability_set.html[akka projects observability set] - Set the observability settings for your Akka project. * link:akka_projects_observability_set_logs_google-cloud.html[akka projects observability set logs google-cloud] - Set your project to export logs to Google Cloud. * link:akka_projects_observability_set_logs_otlp.html[akka projects observability set logs otlp] - Set your project to export logs to an OTLP collector. * link:akka_projects_observability_set_logs_splunk-hec.html[akka projects observability set logs splunk-hec] - Set your project to export logs to a Splunk HEC endpoint. diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_logs_google-cloud.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_logs_google-cloud.adoc index 15884835c..e5005dee2 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_logs_google-cloud.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_logs_google-cloud.adoc @@ -35,7 +35,7 @@ akka projects observability set logs google-cloud [flags] == SEE ALSO -* link:akka_projects_observability_set_logs.html[akka projects observability set logs] - Set the logs exporter for your Akka project +* link:akka_projects_observability_set_logs.html[akka projects observability set logs] - Set the logs exporter for your Akka project. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_logs_otlp.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_logs_otlp.adoc index 87c848a6f..68823155a 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_logs_otlp.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_logs_otlp.adoc @@ -41,7 +41,7 @@ akka projects observability set logs otlp [flags] == SEE ALSO -* link:akka_projects_observability_set_logs.html[akka projects observability set logs] - Set the logs exporter for your Akka project +* link:akka_projects_observability_set_logs.html[akka projects observability set logs] - Set the logs exporter for your Akka project. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_logs_splunk-hec.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_logs_splunk-hec.adoc index d3eadcec0..654e215fc 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_logs_splunk-hec.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_logs_splunk-hec.adoc @@ -44,7 +44,7 @@ akka projects observability set logs splunk-hec [flags] == SEE ALSO -* link:akka_projects_observability_set_logs.html[akka projects observability set logs] - Set the logs exporter for your Akka project +* link:akka_projects_observability_set_logs.html[akka projects observability set logs] - Set the logs exporter for your Akka project. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_metrics.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_metrics.adoc index 34329c1a9..92ad8d60b 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_metrics.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_metrics.adoc @@ -1,6 +1,6 @@ = akka projects observability set metrics -Set the metrics exporter for your Akka project +Set the metrics exporter for your Akka project. == Synopsis @@ -29,7 +29,7 @@ The `akka project observability set metrics` command sets the metrics exporter f == SEE ALSO -* link:akka_projects_observability_set.html[akka projects observability set] - Set the observability settings for your Akka project +* link:akka_projects_observability_set.html[akka projects observability set] - Set the observability settings for your Akka project. * link:akka_projects_observability_set_metrics_google-cloud.html[akka projects observability set metrics google-cloud] - Set your project to export metrics to Google Cloud. * link:akka_projects_observability_set_metrics_otlp.html[akka projects observability set metrics otlp] - Set your project to export metrics to an OTLP collector. * link:akka_projects_observability_set_metrics_prometheus.html[akka projects observability set metrics prometheus] - Set your project to export metrics to a Prometheus instance via the Prometheus remote write protocol. diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_metrics_google-cloud.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_metrics_google-cloud.adoc index 5f19af4e4..d553ade37 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_metrics_google-cloud.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_metrics_google-cloud.adoc @@ -35,7 +35,7 @@ akka projects observability set metrics google-cloud [flags] == SEE ALSO -* link:akka_projects_observability_set_metrics.html[akka projects observability set metrics] - Set the metrics exporter for your Akka project +* link:akka_projects_observability_set_metrics.html[akka projects observability set metrics] - Set the metrics exporter for your Akka project. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_metrics_otlp.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_metrics_otlp.adoc index 6bc67d0ad..bfcddacd3 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_metrics_otlp.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_metrics_otlp.adoc @@ -41,7 +41,7 @@ akka projects observability set metrics otlp [flags] == SEE ALSO -* link:akka_projects_observability_set_metrics.html[akka projects observability set metrics] - Set the metrics exporter for your Akka project +* link:akka_projects_observability_set_metrics.html[akka projects observability set metrics] - Set the metrics exporter for your Akka project. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_metrics_prometheus.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_metrics_prometheus.adoc index 98125fcb8..6b96a0a16 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_metrics_prometheus.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_metrics_prometheus.adoc @@ -41,7 +41,7 @@ akka projects observability set metrics prometheus [flags] == SEE ALSO -* link:akka_projects_observability_set_metrics.html[akka projects observability set metrics] - Set the metrics exporter for your Akka project +* link:akka_projects_observability_set_metrics.html[akka projects observability set metrics] - Set the metrics exporter for your Akka project. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_metrics_splunk-hec.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_metrics_splunk-hec.adoc index 57e79896b..3896d1de8 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_metrics_splunk-hec.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_metrics_splunk-hec.adoc @@ -44,7 +44,7 @@ akka projects observability set metrics splunk-hec [flags] == SEE ALSO -* link:akka_projects_observability_set_metrics.html[akka projects observability set metrics] - Set the metrics exporter for your Akka project +* link:akka_projects_observability_set_metrics.html[akka projects observability set metrics] - Set the metrics exporter for your Akka project. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_traces.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_traces.adoc index 664194886..ff208ae4b 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_traces.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_traces.adoc @@ -1,6 +1,6 @@ = akka projects observability set traces -Set the traces exporter for your Akka project +Set the traces exporter for your Akka project. == Synopsis @@ -29,7 +29,7 @@ The `akka project observability set traces` command sets the traces exporter for == SEE ALSO -* link:akka_projects_observability_set.html[akka projects observability set] - Set the observability settings for your Akka project +* link:akka_projects_observability_set.html[akka projects observability set] - Set the observability settings for your Akka project. * link:akka_projects_observability_set_traces_google-cloud.html[akka projects observability set traces google-cloud] - Set your project to export traces to Google Cloud. * link:akka_projects_observability_set_traces_otlp.html[akka projects observability set traces otlp] - Set your project to export traces to an OTLP collector. diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_traces_google-cloud.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_traces_google-cloud.adoc index b2abd3517..c4e854d7b 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_traces_google-cloud.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_traces_google-cloud.adoc @@ -35,7 +35,7 @@ akka projects observability set traces google-cloud [flags] == SEE ALSO -* link:akka_projects_observability_set_traces.html[akka projects observability set traces] - Set the traces exporter for your Akka project +* link:akka_projects_observability_set_traces.html[akka projects observability set traces] - Set the traces exporter for your Akka project. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_traces_otlp.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_traces_otlp.adoc index 1461bf75b..328bd6d06 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_traces_otlp.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_set_traces_otlp.adoc @@ -41,7 +41,7 @@ akka projects observability set traces otlp [flags] == SEE ALSO -* link:akka_projects_observability_set_traces.html[akka projects observability set traces] - Set the traces exporter for your Akka project +* link:akka_projects_observability_set_traces.html[akka projects observability set traces] - Set the traces exporter for your Akka project. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_unset.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_unset.adoc index b70c07a5f..01e654815 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_unset.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_unset.adoc @@ -1,6 +1,6 @@ = akka projects observability unset -Unset the observability settings for your Akka project +Unset the observability settings for your Akka project. == Synopsis @@ -29,7 +29,7 @@ The `akka project observability unset` command unsets the observability settings == SEE ALSO -* link:akka_projects_observability.html[akka projects observability] - Manage the observability settings for your Akka project +* link:akka_projects_observability.html[akka projects observability] - Manage the observability settings for your Akka project. * link:akka_projects_observability_unset_default.html[akka projects observability unset default] - Unset the observability configuration at the default scope of your project. * link:akka_projects_observability_unset_logs.html[akka projects observability unset logs] - Unset the observability configuration at the logs scope of your project. * link:akka_projects_observability_unset_metrics.html[akka projects observability unset metrics] - Unset the observability configuration at the metrics scope of your project. diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_unset_default.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_unset_default.adoc index 111b3ca58..b0fe55b38 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_unset_default.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_unset_default.adoc @@ -34,7 +34,7 @@ akka projects observability unset default [flags] == SEE ALSO -* link:akka_projects_observability_unset.html[akka projects observability unset] - Unset the observability settings for your Akka project +* link:akka_projects_observability_unset.html[akka projects observability unset] - Unset the observability settings for your Akka project. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_unset_logs.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_unset_logs.adoc index 181d116ac..30aaab55a 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_unset_logs.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_unset_logs.adoc @@ -34,7 +34,7 @@ akka projects observability unset logs [flags] == SEE ALSO -* link:akka_projects_observability_unset.html[akka projects observability unset] - Unset the observability settings for your Akka project +* link:akka_projects_observability_unset.html[akka projects observability unset] - Unset the observability settings for your Akka project. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_unset_metrics.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_unset_metrics.adoc index 1f7bc36a2..f0c87736f 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_unset_metrics.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_unset_metrics.adoc @@ -34,7 +34,7 @@ akka projects observability unset metrics [flags] == SEE ALSO -* link:akka_projects_observability_unset.html[akka projects observability unset] - Unset the observability settings for your Akka project +* link:akka_projects_observability_unset.html[akka projects observability unset] - Unset the observability settings for your Akka project. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_unset_traces.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_unset_traces.adoc index cdc9a01ea..ac5ffa74b 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_unset_traces.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_observability_unset_traces.adoc @@ -34,7 +34,7 @@ akka projects observability unset traces [flags] == SEE ALSO -* link:akka_projects_observability_unset.html[akka projects observability unset] - Unset the observability settings for your Akka project +* link:akka_projects_observability_unset.html[akka projects observability unset] - Unset the observability settings for your Akka project. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_open.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_open.adoc index d49b9721c..c7bcd81b8 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_open.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_open.adoc @@ -1,6 +1,6 @@ = akka projects open -Opens the current project in the console. +Open the current project in the console. ---- akka projects open [flags] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_regions.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_regions.adoc index 30fe6975a..463ca52e5 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_regions.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_regions.adoc @@ -1,10 +1,11 @@ = akka projects regions -Manage the regions for your Akka project +Manage the regions assigned to your Akka project. == Synopsis The `akka projects regions` commands manages the regions for your Akka project. +The available regions are the regions assigned to the organization that the project belongs to. == Options diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_regions_add.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_regions_add.adoc index 6c46b5954..0d61119bf 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_regions_add.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_regions_add.adoc @@ -35,7 +35,7 @@ akka projects regions add [flags] == SEE ALSO -* link:akka_projects_regions.html[akka projects regions] - Manage the regions for your Akka project +* link:akka_projects_regions.html[akka projects regions] - Manage the regions assigned to your Akka project. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_regions_list.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_regions_list.adoc index ad1a8a160..9e6963764 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_regions_list.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_regions_list.adoc @@ -35,7 +35,7 @@ akka projects regions list [flags] == SEE ALSO -* link:akka_projects_regions.html[akka projects regions] - Manage the regions for your Akka project +* link:akka_projects_regions.html[akka projects regions] - Manage the regions assigned to your Akka project. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_regions_set-primary.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_regions_set-primary.adoc index 82f84ad7f..7616d22a8 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_regions_set-primary.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_regions_set-primary.adoc @@ -35,7 +35,7 @@ akka projects regions set-primary [flags] == SEE ALSO -* link:akka_projects_regions.html[akka projects regions] - Manage the regions for your Akka project +* link:akka_projects_regions.html[akka projects regions] - Manage the regions assigned to your Akka project. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_tokens.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_tokens.adoc index 590f498bb..2e95883f4 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_tokens.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_tokens.adoc @@ -1,10 +1,13 @@ = akka projects tokens -Manage your Akka project service tokens +Manage your Akka project service tokens. == Synopsis The `akka projects tokens` commands manipulate the service tokens that have access to your Akka project. +These service tokens are tied to a single project and allow for authenticating and performing actions on that project. +Often used for automation and CI/CD pipelines. +See more details at https://doc.akka.io/operations/integrating-cicd/index.html . == Options diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_tokens_create.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_tokens_create.adoc index 5ae032999..c5614251f 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_tokens_create.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_tokens_create.adoc @@ -37,7 +37,7 @@ akka projects tokens create [flags] == SEE ALSO -* link:akka_projects_tokens.html[akka projects tokens] - Manage your Akka project service tokens +* link:akka_projects_tokens.html[akka projects tokens] - Manage your Akka project service tokens. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_tokens_list.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_tokens_list.adoc index 0a9bcca24..ac3c5d9eb 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_tokens_list.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_tokens_list.adoc @@ -35,7 +35,7 @@ akka projects tokens list [flags] == SEE ALSO -* link:akka_projects_tokens.html[akka projects tokens] - Manage your Akka project service tokens +* link:akka_projects_tokens.html[akka projects tokens] - Manage your Akka project service tokens. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_tokens_revoke.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_tokens_revoke.adoc index ece84453d..5ad3fa575 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_tokens_revoke.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_projects_tokens_revoke.adoc @@ -35,7 +35,7 @@ akka projects tokens revoke ID [flags] == SEE ALSO -* link:akka_projects_tokens.html[akka projects tokens] - Manage your Akka project service tokens +* link:akka_projects_tokens.html[akka projects tokens] - Manage your Akka project service tokens. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_regions.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_regions.adoc index e2e1defb8..69620b159 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_regions.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_regions.adoc @@ -1,10 +1,14 @@ = akka regions -Manage regions on Akka +Manage available regions. == Synopsis The `akka regions` commands manage the regions in your Akka account. +The regions are the locations available to which your services can be deployed. +The regions available to you are the regions available to the organization(s) you are part of. + +For more details on regions, see https://doc.akka.io/operations/regions/index.html . == Options diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_regions_list.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_regions_list.adoc index 085e950be..ca4ab9302 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_regions_list.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_regions_list.adoc @@ -30,7 +30,7 @@ akka regions list [flags] == SEE ALSO -* link:akka_regions.html[akka regions] - Manage regions on Akka +* link:akka_regions.html[akka regions] - Manage available regions. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_roles.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_roles.adoc index dbbc913c2..9cb61950a 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_roles.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_roles.adoc @@ -5,6 +5,8 @@ Manage the user roles for an Akka project. == Synopsis The `akka roles` commands associate user roles (authorizations) with the current project. +Different roles grant different levels of access to the project. +For details on roles, see https://doc.akka.io/operations/projects/manage-project-access.html . == Options diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_routes.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_routes.adoc index 75a33a52a..7d1778e6c 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_routes.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_routes.adoc @@ -5,6 +5,20 @@ Manage routes for your Akka project. == Synopsis The `akka routes` commands manipulate ingress routes for your Akka project. +Routes are used to map incoming requests to services in your project. +Each route has a hostname and a set of paths that map to services. + +== Examples + +---- + +> akka route create my-ecommerce-project \ + --hostname ecommerce.acme.org \ + --path /carts=shopping-cart \ + --path /products=product-info + +For other examples, see https://doc.akka.io/operations/services/invoke-service.html#_managing_routes . +---- == Options diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_secrets.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_secrets.adoc index 67cbfc9e6..fe68be3ef 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_secrets.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_secrets.adoc @@ -5,6 +5,9 @@ Manage secrets for an Akka project. == Synopsis The `akka secrets` command manages secrets for the currently configured project. +These secrets can then be referenced when configuring other properties (e.g. +JWTs) or can be made available to the service as environment variables. +See more details at https://doc.akka.io/operations/projects/secrets.html . == Options @@ -30,7 +33,7 @@ The `akka secrets` command manages secrets for the currently configured project. == SEE ALSO * link:akka.html[akka] - Akka control -* link:akka_secrets_create.html[akka secrets create] - Creates or updates a secret in the current project. +* link:akka_secrets_create.html[akka secrets create] - Create or update a secret in the current project. * link:akka_secrets_delete.html[akka secrets delete] - Delete a secret from the current project. * link:akka_secrets_get.html[akka secrets get] - Get a secret and its keys in the current project. * link:akka_secrets_list.html[akka secrets list] - List the secrets in the current project. diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_secrets_create.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_secrets_create.adoc index 251af1e97..fbebb4fc1 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_secrets_create.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_secrets_create.adoc @@ -1,6 +1,6 @@ = akka secrets create -Creates or updates a secret in the current project. +Create or update a secret in the current project. == Synopsis diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_secrets_create_asymmetric.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_secrets_create_asymmetric.adoc index 89196fb8c..00f25e198 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_secrets_create_asymmetric.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_secrets_create_asymmetric.adoc @@ -47,7 +47,7 @@ akka secrets create asymmetric SECRET_NAME [flags] == SEE ALSO -* link:akka_secrets_create.html[akka secrets create] - Creates or updates a secret in the current project. +* link:akka_secrets_create.html[akka secrets create] - Create or update a secret in the current project. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_secrets_create_generic.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_secrets_create_generic.adoc index b7726a2d1..98bb8ec8d 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_secrets_create_generic.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_secrets_create_generic.adoc @@ -46,7 +46,7 @@ akka secrets create generic SECRET_NAME [flags] == SEE ALSO -* link:akka_secrets_create.html[akka secrets create] - Creates or updates a secret in the current project. +* link:akka_secrets_create.html[akka secrets create] - Create or update a secret in the current project. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_secrets_create_symmetric.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_secrets_create_symmetric.adoc index 8b8fdd4ce..781df1647 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_secrets_create_symmetric.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_secrets_create_symmetric.adoc @@ -46,7 +46,7 @@ akka secrets create symmetric SECRET_NAME [flags] == SEE ALSO -* link:akka_secrets_create.html[akka secrets create] - Creates or updates a secret in the current project. +* link:akka_secrets_create.html[akka secrets create] - Create or update a secret in the current project. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_secrets_create_tls-ca.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_secrets_create_tls-ca.adoc index 61da6ab99..43e468350 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_secrets_create_tls-ca.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_secrets_create_tls-ca.adoc @@ -45,7 +45,7 @@ akka secrets create tls-ca SECRET_NAME [flags] == SEE ALSO -* link:akka_secrets_create.html[akka secrets create] - Creates or updates a secret in the current project. +* link:akka_secrets_create.html[akka secrets create] - Create or update a secret in the current project. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_secrets_create_tls.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_secrets_create_tls.adoc index 43b2224cb..41e0305b8 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_secrets_create_tls.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_secrets_create_tls.adoc @@ -47,7 +47,7 @@ akka secrets create tls SECRET_NAME [flags] == SEE ALSO -* link:akka_secrets_create.html[akka secrets create] - Creates or updates a secret in the current project. +* link:akka_secrets_create.html[akka secrets create] - Create or update a secret in the current project. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_services.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_services.adoc index b67ae24a8..03875b97c 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_services.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_services.adoc @@ -30,24 +30,24 @@ The `akka services` commands are used to manage and modify the services in your == SEE ALSO * link:akka.html[akka] - Akka control -* link:akka_services_apply.html[akka services apply] - Applies a service descriptor to the currently configured project. -* link:akka_services_components.html[akka services components] - Manage the components of a service. +* link:akka_services_apply.html[akka services apply] - Apply a service descriptor to the currently configured project. +* link:akka_services_components.html[akka services components] - Inspect components of a service. * link:akka_services_connectivity.html[akka services connectivity] - Summarize all services connectivity and status. * link:akka_services_data.html[akka services data] - Manage the data of a service. * link:akka_services_delete.html[akka services delete] - Delete a service. -* link:akka_services_deploy.html[akka services deploy] - Deploys a service to the currently configured project. -* link:akka_services_edit.html[akka services edit] - Edits a service descriptor in the currently configured project. -* link:akka_services_export.html[akka services export] - Exports a service as its service descriptor +* link:akka_services_deploy.html[akka services deploy] - Deploy a service to the currently configured project. +* link:akka_services_edit.html[akka services edit] - Edit a service descriptor in the currently configured project. +* link:akka_services_export.html[akka services export] - Export a service as its service descriptor. * link:akka_services_expose.html[akka services expose] - Expose a service. * link:akka_services_get.html[akka services get] - Describe a specific service. -* link:akka_services_jwts.html[akka services jwts] - Manage JWTs. +* link:akka_services_jwts.html[akka services jwts] - Manage JWT keys of a service. * link:akka_services_list.html[akka services list] - List all services. * link:akka_services_logging.html[akka services logging] - Change the log level configration of a service. -* link:akka_services_pause.html[akka services pause] - Pauses a service, scaling it to zero. +* link:akka_services_pause.html[akka services pause] - Pause a service, scaling it to zero instances. * link:akka_services_proxy.html[akka services proxy] - Create an HTTP proxy to a service. -* link:akka_services_restart.html[akka services restart] - Restarts all service instances using the newest image. -* link:akka_services_restore.html[akka services restore] - Restores a service that was deleted in the past two weeks. -* link:akka_services_resume.html[akka services resume] - Resumes a service, scaling it back up. +* link:akka_services_restart.html[akka services restart] - Restart all service instances using the newest image. +* link:akka_services_restore.html[akka services restore] - Restore a service that was deleted in the past two weeks. +* link:akka_services_resume.html[akka services resume] - Resume a service, scaling it back up. * link:akka_services_unexpose.html[akka services unexpose] - Unexpose a service. * link:akka_services_views.html[akka services views] - Manage views. diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_apply.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_apply.adoc index f475ad1a3..08b076dad 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_apply.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_apply.adoc @@ -1,6 +1,6 @@ = akka services apply -Applies a service descriptor to the currently configured project. +Apply a service descriptor to the currently configured project. == Synopsis diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_components.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_components.adoc index 94d2beb75..ef086f6c7 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_components.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_components.adoc @@ -1,6 +1,10 @@ = akka services components -Manage the components of a service. +Inspect components of a service. + +== Synopsis + +The `akka service components` commands provides a way to inspect the components of a service but also to peek at the data stored in the different entities. == Options diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_components_get-state.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_components_get-state.adoc index 5120d2c99..078551cf2 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_components_get-state.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_components_get-state.adoc @@ -37,7 +37,7 @@ akka services components get-state SERVICE_NAME COMPONENT_NAME ID [flags] == SEE ALSO -* link:akka_services_components.html[akka services components] - Manage the components of a service. +* link:akka_services_components.html[akka services components] - Inspect components of a service. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_components_get-workflow.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_components_get-workflow.adoc index 915dd9285..e11405a7d 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_components_get-workflow.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_components_get-workflow.adoc @@ -37,7 +37,7 @@ akka services components get-workflow SERVICE_NAME COMPONENT_NAME WORKFLOW_ID [f == SEE ALSO -* link:akka_services_components.html[akka services components] - Manage the components of a service. +* link:akka_services_components.html[akka services components] - Inspect components of a service. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_components_list-events.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_components_list-events.adoc index 5d2469f5f..11b7577a0 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_components_list-events.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_components_list-events.adoc @@ -41,7 +41,7 @@ akka services components list-events SERVICE_NAME COMPONENT_NAME ENTITY_ID [flag == SEE ALSO -* link:akka_services_components.html[akka services components] - Manage the components of a service. +* link:akka_services_components.html[akka services components] - Inspect components of a service. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_components_list-ids.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_components_list-ids.adoc index 06d402fa1..cbeb8c57d 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_components_list-ids.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_components_list-ids.adoc @@ -39,7 +39,7 @@ akka services components list-ids SERVICE_NAME COMPONENT_NAME [flags] == SEE ALSO -* link:akka_services_components.html[akka services components] - Manage the components of a service. +* link:akka_services_components.html[akka services components] - Inspect components of a service. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_components_list-timers.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_components_list-timers.adoc index 28f9d7031..72fdcdac4 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_components_list-timers.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_components_list-timers.adoc @@ -41,7 +41,7 @@ akka services components list-timers SERVICE_NAME [flags] == SEE ALSO -* link:akka_services_components.html[akka services components] - Manage the components of a service. +* link:akka_services_components.html[akka services components] - Inspect components of a service. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_components_list.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_components_list.adoc index b7e58ba69..631df68b8 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_components_list.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_components_list.adoc @@ -36,7 +36,7 @@ akka services components list SERVICE [flags] == SEE ALSO -* link:akka_services_components.html[akka services components] - Manage the components of a service. +* link:akka_services_components.html[akka services components] - Inspect components of a service. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_deploy.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_deploy.adoc index d789e9faf..f94eed497 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_deploy.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_deploy.adoc @@ -1,12 +1,14 @@ = akka services deploy -Deploys a service to the currently configured project. +Deploy a service to the currently configured project. == Synopsis The `akka service deploy _service-name_ _docker-image_` command deploys a service with name _service-name_ using the _docker-image_. +This command is meant for rapid experimentation and development. +For production use cases, we recommend deploying through a service descriptor, using the `akka service apply` command. -NOTE: You will need Docker credentials to be set up in order for Akka to be able to pull from your private image repository. +NOTE: If using a private image repository, you will need Docker credentials to be set up in order for Akka to be able to pull from your images. For more info see `akka docker` ---- diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_edit.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_edit.adoc index e540f0ff1..e147bba69 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_edit.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_edit.adoc @@ -1,6 +1,6 @@ = akka services edit -Edits a service descriptor in the currently configured project. +Edit a service descriptor in the currently configured project. == Synopsis diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_export.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_export.adoc index c1bd8c74f..8ef01ab5a 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_export.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_export.adoc @@ -1,6 +1,6 @@ = akka services export -Exports a service as its service descriptor +Export a service as its service descriptor. == Synopsis diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_expose.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_expose.adoc index 4350678bf..827f617dc 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_expose.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_expose.adoc @@ -6,6 +6,8 @@ Expose a service. The `akka services expose _service-name_` command creates a route to expose a service for inbound traffic. You may optionally enable HTTP CORS with the `--enable-cors` flag. +When a _hostname_ is not provided, the service is exposed with a generated hostname. +For more information on exposing services, see https://doc.akka.io/operations/services/invoke-service.html. ---- akka services expose SERVICE [flags] @@ -24,12 +26,12 @@ akka services expose my-service --force-global force an existing regional resource to be configured as a global resource --force-regional force an existing global resource to be configured as a regional resource -h, --help help for expose - --hostname string service route hostname + --hostname string specify a service route hostname --once-per-region expose the service once per region --owner string the owner of the project to use, needed if you have two projects with the same name from different owners --project string project to use if not using the default configured project --region string region to use if project has more than one region - --uri-prefix string service URI prefix (default "/") + --uri-prefix string set a service URI prefix. Incoming requests will be routed to the service only if the URI path starts with this prefix. (default "/") ---- == Options inherited from parent commands diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_get.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_get.adoc index 757bbbde7..644ddc51e 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_get.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_get.adoc @@ -4,7 +4,7 @@ Describe a specific service. == Synopsis -The `akka services get _service-name_` command shows the description of a given service, including container statuses. +The `akka services get _service-name_` command shows the details of a given service, including versions, container image, routes, and other runtime concerns. ---- akka services get SERVICE [flags] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_jwts.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_jwts.adoc index bc133b6a8..ba76d2942 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_jwts.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_jwts.adoc @@ -1,6 +1,6 @@ = akka services jwts -Manage JWTs. +Manage JWT keys of a service. == Options diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_jwts_add.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_jwts_add.adoc index a296eb3b5..3b997cc45 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_jwts_add.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_jwts_add.adoc @@ -49,7 +49,7 @@ akka services jwts add [SERVICE] [flags] == SEE ALSO -* link:akka_services_jwts.html[akka services jwts] - Manage JWTs. +* link:akka_services_jwts.html[akka services jwts] - Manage JWT keys of a service. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_jwts_generate.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_jwts_generate.adoc index f87dbd503..5c7e13be1 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_jwts_generate.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_jwts_generate.adoc @@ -49,7 +49,7 @@ akka services jwts generate [SERVICE] [flags] == SEE ALSO -* link:akka_services_jwts.html[akka services jwts] - Manage JWTs. +* link:akka_services_jwts.html[akka services jwts] - Manage JWT keys of a service. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_jwts_list-algorithms.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_jwts_list-algorithms.adoc index 7a21d92a5..5cc56cc47 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_jwts_list-algorithms.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_jwts_list-algorithms.adoc @@ -33,7 +33,7 @@ akka services jwts list-algorithms [flags] == SEE ALSO -* link:akka_services_jwts.html[akka services jwts] - Manage JWTs. +* link:akka_services_jwts.html[akka services jwts] - Manage JWT keys of a service. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_jwts_list.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_jwts_list.adoc index ed917f605..b459089bf 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_jwts_list.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_jwts_list.adoc @@ -46,7 +46,7 @@ my-key HS256 my-issuer-name == SEE ALSO -* link:akka_services_jwts.html[akka services jwts] - Manage JWTs. +* link:akka_services_jwts.html[akka services jwts] - Manage JWT keys of a service. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_jwts_remove.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_jwts_remove.adoc index a176fd82d..5a425d8bd 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_jwts_remove.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_jwts_remove.adoc @@ -45,7 +45,7 @@ akka services jwts remove [SERVICE] [flags] == SEE ALSO -* link:akka_services_jwts.html[akka services jwts] - Manage JWTs. +* link:akka_services_jwts.html[akka services jwts] - Manage JWT keys of a service. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_jwts_update.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_jwts_update.adoc index c75f51b4f..4e1c1905d 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_jwts_update.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_jwts_update.adoc @@ -49,7 +49,7 @@ akka services jwts update [SERVICE] [flags] == SEE ALSO -* link:akka_services_jwts.html[akka services jwts] - Manage JWTs. +* link:akka_services_jwts.html[akka services jwts] - Manage JWT keys of a service. [discrete] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_list.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_list.adoc index 454e0d625..4a484206d 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_list.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_list.adoc @@ -5,6 +5,7 @@ List all services. == Synopsis The `akka services list` command lists a one-line summary of all services under your current project. +By default, it shows information for the primary region of the configured project only. ---- akka services list [flags] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_pause.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_pause.adoc index 24655cb2d..ae520c0ed 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_pause.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_pause.adoc @@ -1,10 +1,11 @@ = akka services pause -Pauses a service, scaling it to zero. +Pause a service, scaling it to zero instances. == Synopsis -The `akka service pause _service-name_` command pauses a service, scaling it to zero but keeping its data. +The `akka service pause _service-name_` command pauses a service, scaling it to zero instances but keeping its data intact. +TIP: To resume the service, use the `akka service resume _service-name_` command. ---- akka services pause SERVICE [flags] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_proxy.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_proxy.adoc index 4c9450bc7..f1954c807 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_proxy.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_proxy.adoc @@ -5,6 +5,7 @@ Create an HTTP proxy to a service. == Synopsis The `akka service proxy` command creates an HTTP proxy that forwards all traffic to the service. +This allows you to interact with the service as if it was running locally. ---- akka services proxy SERVICE [flags] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_restart.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_restart.adoc index 3a06a6258..0784279f2 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_restart.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_restart.adoc @@ -1,6 +1,6 @@ = akka services restart -Restarts all service instances using the newest image. +Restart all service instances using the newest image. == Synopsis diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_restore.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_restore.adoc index cd6ae0f6b..c4171540f 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_restore.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_restore.adoc @@ -1,6 +1,6 @@ = akka services restore -Restores a service that was deleted in the past two weeks. +Restore a service that was deleted in the past two weeks. == Synopsis diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_resume.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_resume.adoc index cbe0116b6..9c7f3b874 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_resume.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_resume.adoc @@ -1,10 +1,10 @@ = akka services resume -Resumes a service, scaling it back up. +Resume a service, scaling it back up. == Synopsis -The `akka service resume _service-name_` command resumes a previously paused service, scaling it back up. +The `akka service resume _service-name_` command resumes a previously paused service, scaling it back up to the minimum number of instances configured for the service. ---- akka services resume SERVICE [flags] diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_views.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_views.adoc index 90e8e3f54..5b5a6409e 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_services_views.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_services_views.adoc @@ -2,6 +2,10 @@ Manage views. +== Synopsis + +The `akka service views` commands manage the views for an Akka project, including listing of existing views and deleting views and their data when a view is no longer used. + == Options ---- diff --git a/docs/src/modules/reference/pages/cli/akka-cli/akka_version.adoc b/docs/src/modules/reference/pages/cli/akka-cli/akka_version.adoc index 9fe629af6..de7373fd3 100644 --- a/docs/src/modules/reference/pages/cli/akka-cli/akka_version.adoc +++ b/docs/src/modules/reference/pages/cli/akka-cli/akka_version.adoc @@ -1,6 +1,6 @@ = akka version -Prints the akka version +Print the akka CLI version ---- akka version [flags] diff --git a/docs/src/modules/reference/pages/release-notes.adoc b/docs/src/modules/reference/pages/release-notes.adoc index a9addf7c2..34ca0b627 100644 --- a/docs/src/modules/reference/pages/release-notes.adoc +++ b/docs/src/modules/reference/pages/release-notes.adoc @@ -12,6 +12,10 @@ Current versions == November 2024 +* https://github.com/akka/akka-projection/releases/tag/v1.6.2[Akka Projections 1.6.2] + +* https://github.com/akka/akka-persistence-dynamodb/releases/tag/v2.0.1[Akka DynamoDB 2.0.1] + * Akka Runtime 1.2.2 - Disable projection scaling until issue has been investigated and fixed - fix problem with read only commands in workflows diff --git a/samples/doc-snippets/src/main/java/com/example/acl/UserEndpoint.java b/samples/doc-snippets/src/main/java/com/example/acl/UserEndpoint.java index 01faec3d8..895495045 100644 --- a/samples/doc-snippets/src/main/java/com/example/acl/UserEndpoint.java +++ b/samples/doc-snippets/src/main/java/com/example/acl/UserEndpoint.java @@ -5,7 +5,7 @@ import akka.javasdk.annotations.http.Get; import akka.javasdk.annotations.http.HttpEndpoint; import akka.javasdk.annotations.http.Post; -import akka.javasdk.http.RequestContext; +import akka.javasdk.http.AbstractHttpEndpoint; /* // tag::class-level-acl[] @@ -20,32 +20,25 @@ */ // tag::endpoint-class[] @HttpEndpoint("/user") -public class UserEndpoint { +public class UserEndpoint extends AbstractHttpEndpoint { // <1> // ... // end::endpoint-class[] - // tag::request-context[] - final private RequestContext requestContext; - - public UserEndpoint(RequestContext requestContext) { // <1> - this.requestContext = requestContext; - } - // end::request-context[] - public record CreateUser(String username, String email) { } // tag::checking-principals[] @Get public String checkingPrincipals() { - if (requestContext.getPrincipals().isInternet()) { + var principals = requestContext().getPrincipals(); + if (principals.isInternet()) { return "accessed from the Internet"; - } else if (requestContext.getPrincipals().isSelf()) { + } else if (principals.isSelf()) { return "accessed from Self (internal call from current service)"; - } else if (requestContext.getPrincipals().isBackoffice()) { + } else if (principals.isBackoffice()) { return "accessed from Backoffice API"; } else { return "accessed from another service: " + - requestContext.getPrincipals().getLocalService(); + principals.getLocalService(); } } // end::checking-principals[] diff --git a/samples/doc-snippets/src/main/java/com/example/api/ExampleEndpoint.java b/samples/doc-snippets/src/main/java/com/example/api/ExampleEndpoint.java index 8ca35dd0d..32eff24f3 100644 --- a/samples/doc-snippets/src/main/java/com/example/api/ExampleEndpoint.java +++ b/samples/doc-snippets/src/main/java/com/example/api/ExampleEndpoint.java @@ -16,6 +16,7 @@ import akka.javasdk.annotations.http.HttpEndpoint; // end::basic-endpoint[] import akka.javasdk.annotations.http.Post; +import akka.javasdk.http.AbstractHttpEndpoint; import akka.javasdk.http.HttpException; import akka.javasdk.http.HttpResponses; import akka.stream.Materializer; @@ -28,7 +29,7 @@ @HttpEndpoint("/example") // <1> @Acl(allow = @Acl.Matcher(principal = Acl.Principal.ALL)) // <2> // tag::lower-level-request[] -public class ExampleEndpoint { +public class ExampleEndpoint extends AbstractHttpEndpoint { // end::basic-endpoint[] private final Materializer materializer; diff --git a/samples/doc-snippets/src/main/java/com/example/jwt/HelloJwtAction.java b/samples/doc-snippets/src/main/java/com/example/jwt/HelloJwtAction.java deleted file mode 100644 index 7ba22082b..000000000 --- a/samples/doc-snippets/src/main/java/com/example/jwt/HelloJwtAction.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.example.jwt; - -import akka.javasdk.timedaction.TimedAction; -import akka.javasdk.annotations.ComponentId; -import akka.javasdk.annotations.JWT; - -//TODO migrate to endpoint is needed -// tag::bearer-token[] -@ComponentId("hello-jwt") -@JWT(validate = JWT.JwtMethodMode.BEARER_TOKEN, - bearerTokenIssuers = "my-issuer") // <1> -public class HelloJwtAction extends TimedAction { - - public Effect message(String msg) { - //.. - // end::bearer-token[] - return effects().done(); - // tag::bearer-token[] - } - - @JWT(validate = JWT.JwtMethodMode.BEARER_TOKEN, - bearerTokenIssuers = "my-other-issuer") - public Effect messageWithIssuer(String msg) { // <3> - //.. - // end::bearer-token[] - return effects().done(); - // tag::bearer-token[] - } -} -// end::bearer-token[] diff --git a/samples/doc-snippets/src/main/java/com/example/jwt/HelloJwtEndpoint.java b/samples/doc-snippets/src/main/java/com/example/jwt/HelloJwtEndpoint.java new file mode 100644 index 000000000..033fdb0df --- /dev/null +++ b/samples/doc-snippets/src/main/java/com/example/jwt/HelloJwtEndpoint.java @@ -0,0 +1,31 @@ +package com.example.jwt; + +import akka.javasdk.annotations.Acl; +import akka.javasdk.annotations.http.HttpEndpoint; +import akka.javasdk.http.AbstractHttpEndpoint; +import akka.javasdk.annotations.JWT; + +// tag::bearer-token[] +@HttpEndpoint("/example-jwt") // <1> +@Acl(allow = @Acl.Matcher(principal = Acl.Principal.ALL)) // <2> +@JWT(validate = JWT.JwtMethodMode.BEARER_TOKEN, + bearerTokenIssuers = "my-issuer") // <1> +public class HelloJwtEndpoint extends AbstractHttpEndpoint { + + public String message(String msg) { + //.. + // end::bearer-token[] + return "ok! Claims: " + String.join(",", requestContext().getJwtClaims().allClaimNames()); + // tag::bearer-token[] + } + + @JWT(validate = JWT.JwtMethodMode.BEARER_TOKEN, + bearerTokenIssuers = "my-other-issuer") + public String messageWithIssuer(String msg) { // <3> + //.. + // end::bearer-token[] + return "ok! Claims: " + String.join(",", requestContext().getJwtClaims().allClaimNames()); + // tag::bearer-token[] + } +} +// end::bearer-token[] diff --git a/samples/endpoint-jwt/src/main/java/hellojwt/api/HelloJwtEndpoint.java b/samples/endpoint-jwt/src/main/java/hellojwt/api/HelloJwtEndpoint.java index 4dea92dcc..43926e5c5 100644 --- a/samples/endpoint-jwt/src/main/java/hellojwt/api/HelloJwtEndpoint.java +++ b/samples/endpoint-jwt/src/main/java/hellojwt/api/HelloJwtEndpoint.java @@ -10,7 +10,7 @@ import akka.javasdk.annotations.http.Get; // tag::accessing-claims[] -import akka.javasdk.http.RequestContext; +import akka.javasdk.http.AbstractHttpEndpoint; // end::accessing-claims[] @@ -24,16 +24,9 @@ @HttpEndpoint("/hello") @JWT(validate = JWT.JwtMethodMode.BEARER_TOKEN, bearerTokenIssuers = "my-issuer") // <1> // tag::accessing-claims[] -public class HelloJwtEndpoint { +public class HelloJwtEndpoint extends AbstractHttpEndpoint { // end::bearer-token[] // end::accessing-claims[] - // tag::accessing-claims[] - - RequestContext context; - public HelloJwtEndpoint(RequestContext context){ - this.context = context; - } - // end::accessing-claims[] @Get("/") public CompletionStage hello() { @@ -47,9 +40,9 @@ public CompletionStage hello() { // end::multiple-bearer-token-issuers[] @Get("/claims") public CompletionStage helloClaims() { - var claims = context.getJwtClaims(); - var issuer = claims.issuer().get(); // <1> - var sub = claims.subject().get(); // <1> + var claims = requestContext().getJwtClaims(); // <1> + var issuer = claims.issuer().get(); // <2> + var sub = claims.subject().get(); // <2> return completedStage("issuer: " + issuer + ", subject: " + sub); } // tag::bearer-token[] diff --git a/samples/shopping-cart-quickstart/src/main/java/shoppingcart/domain/ShoppingCart.java b/samples/shopping-cart-quickstart/src/main/java/shoppingcart/domain/ShoppingCart.java index 57c4984d8..42f79227e 100644 --- a/samples/shopping-cart-quickstart/src/main/java/shoppingcart/domain/ShoppingCart.java +++ b/samples/shopping-cart-quickstart/src/main/java/shoppingcart/domain/ShoppingCart.java @@ -27,21 +27,21 @@ public LineItem withQuantity(int quantity) { // tag::itemAdded[] public ShoppingCart onItemAdded(ShoppingCartEvent.ItemAdded itemAdded) { var item = itemAdded.item(); - var lineItem = updateItem(item, this); // <1> - List lineItems = removeItemByProductId(this, item.productId()); // <2> + var lineItem = updateItem(item); // <1> + List lineItems = removeItemByProductId(item.productId()); // <2> lineItems.add(lineItem); // <3> lineItems.sort(Comparator.comparing(LineItem::productId)); return new ShoppingCart(cartId, lineItems, checkedOut); // <4> } - private static LineItem updateItem(LineItem item, ShoppingCart cart) { - return cart.findItemByProductId(item.productId()) + private LineItem updateItem(LineItem item) { + return findItemByProductId(item.productId()) .map(li -> li.withQuantity(li.quantity() + item.quantity())) .orElse(item); } - private static List removeItemByProductId(ShoppingCart cart, String productId) { - return cart.items().stream() + private List removeItemByProductId(String productId) { + return items().stream() .filter(lineItem -> !lineItem.productId().equals(productId)) .collect(Collectors.toList()); } @@ -56,7 +56,7 @@ public Optional findItemByProductId(String productId) { public ShoppingCart onItemRemoved(ShoppingCartEvent.ItemRemoved itemRemoved) { List updatedItems = - removeItemByProductId(this, itemRemoved.productId()); + removeItemByProductId(itemRemoved.productId()); updatedItems.sort(Comparator.comparing(LineItem::productId)); return new ShoppingCart(cartId, updatedItems, checkedOut); } diff --git a/samples/tracing/README.md b/samples/tracing/README.md index 8184a8b29..16e06a173 100644 --- a/samples/tracing/README.md +++ b/samples/tracing/README.md @@ -20,35 +20,38 @@ mvn compile ## Running Locally -When running an Akka service locally. -To start your service locally, run: +First start a local Jaeger in docker using the prepared docker compose file from the sample project directory: ```shell -TRACING_ENABLED=true COLLECTOR_ENDPOINT="http://localhost:4317" mvn compile exec:java +docker compose up ``` -This command will start your Akka service, with tracing enabled and exporting the generated -traces to the Jaeger container referred below. - -To start Jaeger locally, run: +Then start your service locally, with tracing enabled and reporting to the local Jaeger instance: ```shell -docker compose up +TRACING_ENABLED=true COLLECTOR_ENDPOINT="http://localhost:4317" mvn compile exec:java ``` ## Exercising the service With your Akka service running, any defined endpoints should be available at `http://localhost:9000`. -- Add a new user +Report a custom span around an async task inside an endpoint: + +```shell +curl -i -XPOST localhost:9000/tracing/custom/5 +``` + +Schedule a timed action which reports a custom span when executing an async call to an external service: ```shell - curl -i -XPOST -H "Content-Type: application/json" localhost:9000/tracing -d '{"id":"2454cb46-1b16-408a-b7f8-bd2d5c376969"}' +curl -i -XPOST -H "Content-Type: application/json" localhost:9000/tracing -d '{"id":"2454cb46-1b16-408a-b7f8-bd2d5c376969"}' ``` +Now you can see the trace in Jaeger UI at http://localhost:16686 -- Now you can see the trace in Jaeger UI at http://localhost:16686 - - select "runtime" and "Find all traces" to explore the trace +Select "runtime" and "Find all traces" to explore the traces, you should see "POST /tracing/custom/{id}" and "POST /tracing/" +for the respective two calls above. ## Deploying diff --git a/samples/tracing/docker-compose.yml b/samples/tracing/docker-compose.yml index 979333f06..4e7f4459b 100644 --- a/samples/tracing/docker-compose.yml +++ b/samples/tracing/docker-compose.yml @@ -1,4 +1,3 @@ -version: "3" services: jaeger: image: jaegertracing/all-in-one:1.54 diff --git a/samples/tracing/src/main/java/com/example/tracing/api/TracingEndpoint.java b/samples/tracing/src/main/java/com/example/tracing/api/TracingEndpoint.java index 4eee3a99c..6d50a5f9d 100644 --- a/samples/tracing/src/main/java/com/example/tracing/api/TracingEndpoint.java +++ b/samples/tracing/src/main/java/com/example/tracing/api/TracingEndpoint.java @@ -1,26 +1,38 @@ package com.example.tracing.api; import akka.Done; +import akka.http.javadsl.model.HttpResponse; +import akka.javasdk.annotations.Acl; import akka.javasdk.annotations.http.HttpEndpoint; import akka.javasdk.annotations.http.Post; import akka.javasdk.client.ComponentClient; -import com.example.tracing.application.TracingAction; +import akka.javasdk.http.HttpResponses; +import akka.javasdk.http.RequestContext; import akka.javasdk.timer.TimerScheduler; +import com.example.tracing.application.TracingAction; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.StatusCode; import java.time.Duration; +import java.util.Optional; import java.util.UUID; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; +// Opened up for access from the public internet to make the sample service easy to try out. +// For actual services meant for production this must be carefully considered, and often set more limited +@Acl(allow = @Acl.Matcher(principal = Acl.Principal.INTERNET)) @HttpEndpoint("/tracing") public class TracingEndpoint { private final ComponentClient componentClient; private final TimerScheduler timerScheduler; + private final RequestContext requestContext; - - public TracingEndpoint(ComponentClient componentClient, TimerScheduler timerScheduler) { + public TracingEndpoint(ComponentClient componentClient, TimerScheduler timerScheduler, RequestContext requestContext) { this.componentClient = componentClient; this.timerScheduler = timerScheduler; + this.requestContext = requestContext; } private record PostId(String id){} @@ -35,4 +47,34 @@ public CompletionStage postDelayed(PostId id) { ); } + @Post("/custom/{id}") + public CompletionStage customSpan(String id) { + Optional maybeSpan = requestContext.tracing().startSpan("ad-hoc endpoint span"); + + maybeSpan.ifPresent(span -> span.setAttribute("id", id)); + + // do some stuff + // potentially async, might throw + var result = CompletableFuture.supplyAsync(() -> { + maybeSpan.ifPresent(span -> span.addEvent("Spawned async task")); + return Integer.valueOf(id); + }); + + return result.handle((ok, error) -> { + if (error != null) { + maybeSpan.ifPresent(span -> { + span.setStatus(StatusCode.ERROR, error.getMessage()); + span.end(); + }); + return HttpResponses.internalServerError("Boom"); + } else { + maybeSpan.ifPresent(span -> { + span.setStatus(StatusCode.OK); + span.end(); + }); + return HttpResponses.ok("Ok!"); + } + }); + } + } diff --git a/samples/tracing/src/main/java/com/example/tracing/application/TracingAction.java b/samples/tracing/src/main/java/com/example/tracing/application/TracingAction.java index af3a1160d..3793c10f7 100644 --- a/samples/tracing/src/main/java/com/example/tracing/application/TracingAction.java +++ b/samples/tracing/src/main/java/com/example/tracing/application/TracingAction.java @@ -1,37 +1,43 @@ package com.example.tracing.application; - import akka.javasdk.annotations.ComponentId; import akka.javasdk.timedaction.TimedAction; -import com.example.tracing.domain.Typicode; +import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.StatusCode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.net.http.HttpResponse; +import java.util.Optional; +import java.util.concurrent.CompletionStage; + @ComponentId("tracing-action") public class TracingAction extends TimedAction { - private final static Logger logger = LoggerFactory.getLogger(TracingAction.class); - - private final Typicode typicode = new Typicode(); - - public Effect callAnotherService(String postID){ - logger.info("Calling to [{}].", Typicode.url + "/" + postID); - var newSpan = commandContext().getTracer() - .spanBuilder("ad-hoc span calling to: " + Typicode.url) - .setParent(commandContext().metadata().traceContext().asOpenTelemetryContext()) - .startSpan() - .setAttribute("post", postID); - - return effects().asyncEffect( - typicode.callAsyncService(postID) - .whenComplete((response, ex) -> { - if (ex != null) { - newSpan.setStatus(StatusCode.ERROR, ex.getMessage()).end(); - } else { - newSpan.setAttribute("result", response.body().title()).end(); - } - }) - .thenApply(__ -> effects().done() )); - } + private final static Logger logger = LoggerFactory.getLogger(TracingAction.class); + + private final Typicode typicode = new Typicode(); + + public Effect callAnotherService(String postID) { + logger.info("Calling to [{}].", Typicode.url + "/" + postID); + Optional maybeSpan = commandContext().tracing().startSpan("ad-hoc span calling to: " + Typicode.url); + + maybeSpan.ifPresent(span -> span.setAttribute("post", postID)); + + CompletionStage> asyncResult = typicode.callAsyncService(postID, maybeSpan); + + maybeSpan.ifPresent(span -> + asyncResult.whenComplete((response, ex) -> { + + if (ex != null) { + span.setStatus(StatusCode.ERROR, ex.getMessage()).end(); + } else { + span.setAttribute("response-status", response.statusCode()).end(); + } + }) + ); + + + return effects().asyncEffect(asyncResult.thenApply(__ -> effects().done())); + } } \ No newline at end of file diff --git a/samples/tracing/src/main/java/com/example/tracing/domain/Typicode.java b/samples/tracing/src/main/java/com/example/tracing/application/Typicode.java similarity index 52% rename from samples/tracing/src/main/java/com/example/tracing/domain/Typicode.java rename to samples/tracing/src/main/java/com/example/tracing/application/Typicode.java index 81fc101ea..b23622a87 100644 --- a/samples/tracing/src/main/java/com/example/tracing/domain/Typicode.java +++ b/samples/tracing/src/main/java/com/example/tracing/application/Typicode.java @@ -1,33 +1,59 @@ -package com.example.tracing.domain; +package com.example.tracing.application; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.base.Charsets; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator; +import io.opentelemetry.context.Context; +import io.opentelemetry.context.propagation.TextMapSetter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.IOException; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; +import java.util.Optional; import java.util.concurrent.CompletionStage; public class Typicode { + + private static final Logger log = LoggerFactory.getLogger(Typicode.class); + public static final String url = "https://jsonplaceholder.typicode.com/posts"; + // using a third party HTTP client here rather than the built in `akka.javasdk.http.HttpClient` - // in order to showcase external/manual tracing + // in order to showcase external/manual tracing and propagating context manually private final HttpClient httpClient = HttpClient.newHttpClient(); + private final TextMapSetter setter = + (carrier, key, value) -> carrier.setHeader(key, value); + public record TypicodePost(String userId, String id, String title, String body) {} - public CompletionStage> callAsyncService(String postID) { - HttpRequest httpRequest = HttpRequest.newBuilder() - .uri(URI.create(url + "/" + postID)) - .build(); + public CompletionStage> callAsyncService(String postID, Optional parentSpan) { + var requestBuilder = HttpRequest.newBuilder() + .uri(URI.create(url + "/" + postID)); + + parentSpan.ifPresent(span -> { + // propagate trace parent to third party service + var contextWithSpan = Context.current().with(span); + W3CTraceContextPropagator.getInstance().inject(contextWithSpan, requestBuilder, setter); + }); + + HttpRequest httpRequest = requestBuilder.build(); + + parentSpan.ifPresent(__ -> { + log.info("Request headers propagating open telemetry trace parent: {}", httpRequest.headers().toString()); + }); + //Async call to external service return httpClient.sendAsync(httpRequest, new JsonResponseHandler<>(TypicodePost.class)); } - public static class JsonResponseHandler implements HttpResponse.BodyHandler { + private static class JsonResponseHandler implements HttpResponse.BodyHandler { private final Class responseType; public JsonResponseHandler(Class responseType){ diff --git a/samples/transfer-workflow-compensation/src/it/java/com/example/transfer/TransferWorkflowIntegrationTest.java b/samples/transfer-workflow-compensation/src/it/java/com/example/transfer/TransferWorkflowIntegrationTest.java index 38454bed1..4dc510b04 100644 --- a/samples/transfer-workflow-compensation/src/it/java/com/example/transfer/TransferWorkflowIntegrationTest.java +++ b/samples/transfer-workflow-compensation/src/it/java/com/example/transfer/TransferWorkflowIntegrationTest.java @@ -164,7 +164,7 @@ public void shouldTimedOutTransferWorkflow() { } - private String randomId() { + public static String randomId() { return UUID.randomUUID().toString().substring(0, 8); } diff --git a/samples/transfer-workflow-compensation/src/it/java/com/example/wallet/application/WalletEntityIntegrationTest.java b/samples/transfer-workflow-compensation/src/it/java/com/example/wallet/application/WalletEntityIntegrationTest.java new file mode 100644 index 000000000..63fa529c8 --- /dev/null +++ b/samples/transfer-workflow-compensation/src/it/java/com/example/wallet/application/WalletEntityIntegrationTest.java @@ -0,0 +1,66 @@ +package com.example.wallet.application; + +import akka.javasdk.testkit.TestKitSupport; +import com.example.wallet.application.WalletEntity.WalletResult; +import com.example.wallet.domain.WalletCommand; +import org.junit.jupiter.api.Test; + +import static com.example.transfer.TransferWorkflowIntegrationTest.randomId; +import static org.assertj.core.api.Assertions.assertThat; + +class WalletEntityIntegrationTest extends TestKitSupport { + + @Test + public void shouldDeduplicateWithdrawCommand() { + // given + var walletId = randomId(); + var withdraw = new WalletCommand.Withdraw(randomId(), 10); + await(componentClient.forEventSourcedEntity(walletId) + .method(WalletEntity::create) + .invokeAsync(100)); + + // when + withdraw(walletId, withdraw); + withdraw(walletId, withdraw); + withdraw(walletId, withdraw); + + // then + Integer balance = await(componentClient.forEventSourcedEntity(walletId) + .method(WalletEntity::get) + .invokeAsync()); + assertThat(balance).isEqualTo(100 - 10); + } + + @Test + public void shouldDeduplicateDepositCommand() { + // given + var walletId = randomId(); + var deposit = new WalletCommand.Deposit(randomId(), 10); + await(componentClient.forEventSourcedEntity(walletId) + .method(WalletEntity::create) + .invokeAsync(100)); + + // when + deposit(walletId, deposit); + deposit(walletId, deposit); + deposit(walletId, deposit); + + // then + Integer balance = await(componentClient.forEventSourcedEntity(walletId) + .method(WalletEntity::get) + .invokeAsync()); + assertThat(balance).isEqualTo(100 + 10); + } + + private WalletResult deposit(String walletId, WalletCommand.Deposit deposit) { + return await(componentClient.forEventSourcedEntity(walletId) + .method(WalletEntity::deposit) + .invokeAsync(deposit)); + } + + private WalletResult withdraw(String walletId, WalletCommand.Withdraw withdraw) { + return await(componentClient.forEventSourcedEntity(walletId) + .method(WalletEntity::withdraw) + .invokeAsync(withdraw)); + } +} \ No newline at end of file diff --git a/samples/transfer-workflow-compensation/src/it/java/com/example/wallet/domain/WalletTest.java b/samples/transfer-workflow-compensation/src/it/java/com/example/wallet/domain/WalletTest.java new file mode 100644 index 000000000..22c14c773 --- /dev/null +++ b/samples/transfer-workflow-compensation/src/it/java/com/example/wallet/domain/WalletTest.java @@ -0,0 +1,27 @@ +package com.example.wallet.domain; + +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; + +class WalletTest { + + @Test + public void shouldLimitCommandIdsSize() { + //given + Wallet wallet = new Wallet("w1", 100, new ArrayList<>()); + + //when + for (int i = 0; i < 10000; i++) { + List events = wallet.handle(new WalletCommand.Deposit(UUID.randomUUID().toString(), 10)); + wallet = wallet.applyEvent(events.get(0)); + } + + //then + assertThat(wallet.commandIds()).hasSize(1000); + } +} \ No newline at end of file diff --git a/samples/transfer-workflow-compensation/src/main/java/com/example/transfer/application/TransferWorkflow.java b/samples/transfer-workflow-compensation/src/main/java/com/example/transfer/application/TransferWorkflow.java index 5ffa32f31..574e54fea 100644 --- a/samples/transfer-workflow-compensation/src/main/java/com/example/transfer/application/TransferWorkflow.java +++ b/samples/transfer-workflow-compensation/src/main/java/com/example/transfer/application/TransferWorkflow.java @@ -10,6 +10,8 @@ import com.example.wallet.application.WalletEntity.WalletResult; import com.example.wallet.application.WalletEntity.WalletResult.Failure; import com.example.wallet.application.WalletEntity.WalletResult.Success; +import com.example.wallet.domain.WalletCommand.Deposit; +import com.example.wallet.domain.WalletCommand.Withdraw; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -26,20 +28,8 @@ import static java.time.Duration.ofHours; import static java.time.Duration.ofSeconds; -// tag::class[] @ComponentId("transfer") // <1> -public class TransferWorkflow extends Workflow { // <2> - - public record Withdraw(String from, int amount) { - } - - // end::class[] - - // tag::definition[] - public record Deposit(String to, int amount) { - } - - // end::definition[] +public class TransferWorkflow extends Workflow { private static final Logger logger = LoggerFactory.getLogger(TransferWorkflow.class); @@ -58,14 +48,14 @@ public WorkflowDef definition() { logger.info("Running: " + cmd); // cancelling the timer in case it was scheduled return timers().cancel("acceptationTimout-" + currentState().transferId()).thenCompose(__ -> - componentClient.forEventSourcedEntity(cmd.from) + componentClient.forEventSourcedEntity(currentState().transfer().from()) .method(WalletEntity::withdraw) - .invokeAsync(cmd.amount)); + .invokeAsync(cmd)); }) .andThen(WalletResult.class, result -> { switch (result) { case Success __ -> { - Deposit depositInput = new Deposit(currentState().transfer().to(), currentState().transfer().amount()); + Deposit depositInput = new Deposit(currentState().depositId(), currentState().transfer().amount()); return effects() .updateState(currentState().withStatus(WITHDRAW_SUCCEED)) .transitionTo("deposit", depositInput); @@ -87,9 +77,9 @@ public WorkflowDef definition() { // end::compensation[] logger.info("Running: " + cmd); // tag::compensation[] - return componentClient.forEventSourcedEntity(cmd.to) + return componentClient.forEventSourcedEntity(currentState().transfer().to()) .method(WalletEntity::deposit) - .invokeAsync(cmd.amount); + .invokeAsync(cmd); }) .andThen(WalletResult.class, result -> { // <1> switch (result) { @@ -116,9 +106,13 @@ public WorkflowDef definition() { logger.info("Running withdraw compensation"); // tag::compensation[] var transfer = currentState().transfer(); + // end::compensation[] + // depositId is reused for the compensation, just to have a stable commandId and simplify the example + // tag::compensation[] + String commandId = currentState().depositId(); return componentClient.forEventSourcedEntity(transfer.from()) .method(WalletEntity::deposit) - .invokeAsync(transfer.amount()); + .invokeAsync(new Deposit(commandId, transfer.amount())); }) .andThen(WalletResult.class, result -> { switch (result) { @@ -185,29 +179,30 @@ public WorkflowDef definition() { .addStep(failoverHandler); } - - public Effect startTransfer(Transfer transfer) { if (currentState() != null) { return effects().error("transfer already started"); } else if (transfer.amount() <= 0) { return effects().error("transfer amount should be greater than zero"); - } else if (transfer.amount() > 1000) { - logger.info("Waiting for acceptation: " + transfer); - TransferState waitingForAcceptationState = new TransferState(commandContext().workflowId(), transfer) - .withStatus(WAITING_FOR_ACCEPTATION); - return effects() - .updateState(waitingForAcceptationState) - .transitionTo("wait-for-acceptation") - .thenReply("transfer started, waiting for acceptation"); } else { - logger.info("Running: " + transfer); - TransferState initialState = new TransferState(commandContext().workflowId(), transfer); - Withdraw withdrawInput = new Withdraw(transfer.from(), transfer.amount()); - return effects() - .updateState(initialState) - .transitionTo("withdraw", withdrawInput) - .thenReply("transfer started"); + String workflowId = commandContext().workflowId(); + if (transfer.amount() > 1000) { + logger.info("Waiting for acceptation: " + transfer); + TransferState waitingForAcceptationState = TransferState.create(workflowId, transfer) + .withStatus(WAITING_FOR_ACCEPTATION); + return effects() + .updateState(waitingForAcceptationState) + .transitionTo("wait-for-acceptation") + .thenReply("transfer started, waiting for acceptation"); + } else { + logger.info("Running: " + transfer); + TransferState initialState = TransferState.create(workflowId, transfer); + Withdraw withdrawInput = new Withdraw(initialState.withdrawId(), transfer.amount()); + return effects() + .updateState(initialState) + .transitionTo("withdraw", withdrawInput) + .thenReply("transfer started"); + } } } @@ -234,7 +229,7 @@ public Effect accept() { // end::resuming[] logger.info("Accepting transfer: " + transfer); // tag::resuming[] - Withdraw withdrawInput = new Withdraw(transfer.from(), transfer.amount()); + Withdraw withdrawInput = new Withdraw(currentState().withdrawId(), transfer.amount()); return effects() .transitionTo("withdraw", withdrawInput) .thenReply("transfer accepted"); diff --git a/samples/transfer-workflow-compensation/src/main/java/com/example/transfer/domain/TransferState.java b/samples/transfer-workflow-compensation/src/main/java/com/example/transfer/domain/TransferState.java index 92e6ad525..8afdcd63a 100644 --- a/samples/transfer-workflow-compensation/src/main/java/com/example/transfer/domain/TransferState.java +++ b/samples/transfer-workflow-compensation/src/main/java/com/example/transfer/domain/TransferState.java @@ -1,8 +1,11 @@ package com.example.transfer.domain; -import static com.example.transfer.domain.TransferState.TransferStatus.*; +import java.util.UUID; -public record TransferState(String transferId, Transfer transfer, TransferStatus status) { +import static com.example.transfer.domain.TransferState.TransferStatus.STARTED; + +public record TransferState(String transferId, Transfer transfer, TransferStatus status, String withdrawId, + String depositId) { public record Transfer(String from, String to, int amount) { } @@ -11,11 +14,14 @@ public enum TransferStatus { STARTED, WITHDRAW_FAILED, WITHDRAW_SUCCEED, DEPOSIT_FAILED, COMPLETED, COMPENSATION_COMPLETED, WAITING_FOR_ACCEPTATION, TRANSFER_ACCEPTATION_TIMED_OUT, REQUIRES_MANUAL_INTERVENTION } - public TransferState(String transferId, Transfer transfer) { - this(transferId, transfer, STARTED); + public static TransferState create(String transferId, Transfer transfer) { + // commandIds must be the same for every attempt, that's why we keep them as a part of the state + String withdrawId = UUID.randomUUID().toString(); + String depositId = UUID.randomUUID().toString(); + return new TransferState(transferId, transfer, STARTED, withdrawId, depositId); } public TransferState withStatus(TransferStatus newStatus) { - return new TransferState(transferId, transfer, newStatus); + return new TransferState(transferId, transfer, newStatus, withdrawId, depositId); } } diff --git a/samples/transfer-workflow-compensation/src/main/java/com/example/wallet/api/WalletEndpoint.java b/samples/transfer-workflow-compensation/src/main/java/com/example/wallet/api/WalletEndpoint.java index 6e894c42d..3094ba8e7 100644 --- a/samples/transfer-workflow-compensation/src/main/java/com/example/wallet/api/WalletEndpoint.java +++ b/samples/transfer-workflow-compensation/src/main/java/com/example/wallet/api/WalletEndpoint.java @@ -10,9 +10,12 @@ import com.example.wallet.application.WalletEntity; import com.example.wallet.application.WalletEntity.WalletResult.Failure; import com.example.wallet.application.WalletEntity.WalletResult.Success; +import com.example.wallet.domain.WalletCommand.Deposit; +import com.example.wallet.domain.WalletCommand.Withdraw; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.UUID; import java.util.concurrent.CompletionStage; // Opened up for access from the public internet to make the sample service easy to try out. @@ -48,7 +51,7 @@ public CompletionStage create(String id, int initialAmount) { @Post("/{id}/deposit/{amount}") public CompletionStage deposit(String id, int amount) { return componentClient.forEventSourcedEntity(id) - .method(WalletEntity::deposit).invokeAsync(amount) + .method(WalletEntity::deposit).invokeAsync(new Deposit(UUID.randomUUID().toString(), amount)) .thenApply(walletResult -> switch (walletResult) { case Success __ -> HttpResponses.ok(); @@ -63,7 +66,7 @@ public CompletionStage deposit(String id, int amount) { @Post("/{id}/withdraw/{amount}") public CompletionStage withdraw(String id, int amount) { return componentClient.forEventSourcedEntity(id) - .method(WalletEntity::withdraw).invokeAsync(amount) + .method(WalletEntity::withdraw).invokeAsync(new Withdraw(UUID.randomUUID().toString(), amount)) .thenApply(walletResult -> switch (walletResult) { case Success __ -> HttpResponses.ok(); diff --git a/samples/transfer-workflow-compensation/src/main/java/com/example/wallet/application/WalletEntity.java b/samples/transfer-workflow-compensation/src/main/java/com/example/wallet/application/WalletEntity.java index 55cba84d8..b6bba7df8 100644 --- a/samples/transfer-workflow-compensation/src/main/java/com/example/wallet/application/WalletEntity.java +++ b/samples/transfer-workflow-compensation/src/main/java/com/example/wallet/application/WalletEntity.java @@ -6,28 +6,30 @@ import com.example.wallet.application.WalletEntity.WalletResult.Failure; import com.example.wallet.application.WalletEntity.WalletResult.Success; import com.example.wallet.domain.Wallet; +import com.example.wallet.domain.WalletCommand; import com.example.wallet.domain.WalletEvent; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.List; + import static akka.Done.done; -// tag::wallet[] @ComponentId("wallet") public class WalletEntity extends EventSourcedEntity { - // end::wallet[] private static final Logger logger = LoggerFactory.getLogger(WalletEntity.class); + @Override + public Wallet emptyState() { + return Wallet.EMPTY; + } + @Override public Wallet applyEvent(WalletEvent event) { - return switch(event) { - case WalletEvent.Created c -> new Wallet(eventContext().entityId(), c.initialBalance()); - case WalletEvent.Withdrawn w -> currentState().withdraw(w.amount()); - case WalletEvent.Deposited d -> currentState().deposit(d.amount()); - }; + return currentState().applyEvent(event); } @JsonTypeInfo(use = JsonTypeInfo.Id.NAME) @@ -42,50 +44,44 @@ record Success() implements WalletResult { } } - // tag::wallet[] public Effect create(int initialBalance) { // <1> - if (currentState() != null){ + if (!currentState().isEmpty()){ return effects().error("Wallet already exists"); } else { - return effects().persist(new WalletEvent.Created(initialBalance)) + return effects().persist(new WalletEvent.Created(commandContext().entityId(), initialBalance)) .thenReply(__ -> done()); } } - public Effect withdraw(int amount) { // <2> - if (currentState() == null){ + public Effect withdraw(WalletCommand.Withdraw withdraw) { // <2> + if (currentState().isEmpty()){ return effects().error("Wallet does not exist"); - } else if (currentState().balance() < amount) { + } else if (currentState().balance() < withdraw.amount()) { return effects().reply(new Failure("Insufficient balance")); } else { - // end::wallet[] - logger.info("Withdraw walletId: [{}] amount -{}", currentState().id(), amount); - // tag::wallet[] - return effects().persist(new WalletEvent.Withdrawn(amount)) + logger.info("Withdraw walletId: [{}] amount -{}", currentState().id(), withdraw.amount()); + List events = currentState().handle(withdraw); + return effects().persistAll(events) .thenReply(__ -> new WalletResult.Success()); } } - public Effect deposit(int amount) { // <3> - if (currentState() == null){ + public Effect deposit(WalletCommand.Deposit deposit) { // <3> + if (currentState().isEmpty()){ return effects().error("Wallet does not exist"); - } else if (currentState() == null) { - return effects().reply(new Failure("Wallet [" + commandContext().entityId() + "] not exists")); } else { - // end::wallet[] - logger.info("Deposit walletId: [{}] amount +{}", currentState().id(), amount); - // tag::wallet[] - return effects().persist(new WalletEvent.Deposited(amount)) + logger.info("Deposit walletId: [{}] amount +{}", currentState().id(), deposit.amount()); + List events = currentState().handle(deposit); + return effects().persistAll(events) .thenReply(__ -> new WalletResult.Success()); } } public Effect get() { // <4> - if (currentState() == null){ + if (currentState().isEmpty()){ return effects().error("Wallet does not exist"); } else { return effects().reply(currentState().balance()); } } } -// end::wallet[] diff --git a/samples/transfer-workflow-compensation/src/main/java/com/example/wallet/domain/Wallet.java b/samples/transfer-workflow-compensation/src/main/java/com/example/wallet/domain/Wallet.java index 2a0a47b0d..5026dab19 100644 --- a/samples/transfer-workflow-compensation/src/main/java/com/example/wallet/domain/Wallet.java +++ b/samples/transfer-workflow-compensation/src/main/java/com/example/wallet/domain/Wallet.java @@ -1,12 +1,56 @@ package com.example.wallet.domain; -public record Wallet(String id, int balance) { +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; - public Wallet withdraw(int amount) { - return new Wallet(id, balance - amount); +import java.util.ArrayList; +import java.util.List; + +public record Wallet(String id, int balance, List commandIds) { + + private static final Logger logger = LoggerFactory.getLogger(Wallet.class); + public static final int COMMAND_IDS_MAX_SIZE = 1000; + public static Wallet EMPTY = new Wallet("", 0, new ArrayList<>()); + + public boolean isEmpty(){ + return id.equals(""); + } + + public List handle(WalletCommand command) { + if (commandIds.contains(command.commandId())) { + logger.info("Command already processed: [{}]", command.commandId()); + return List.of(); + } + return switch (command) { + case WalletCommand.Deposit deposit -> + List.of(new WalletEvent.Deposited(command.commandId(), deposit.amount())); + case WalletCommand.Withdraw withdraw -> + List.of(new WalletEvent.Withdrawn(command.commandId(), withdraw.amount())); + }; + } + + + public Wallet applyEvent(WalletEvent event) { + return switch (event) { + case WalletEvent.Created created -> + new Wallet(created.walletId(), created.initialBalance(), new ArrayList<>()); + case WalletEvent.Withdrawn withdrawn -> + new Wallet(id, balance - withdrawn.amount(), addCommandId(withdrawn.commandId())); + case WalletEvent.Deposited deposited -> + new Wallet(id, balance + deposited.amount(), addCommandId(deposited.commandId())); + }; } - public Wallet deposit(int amount) { - return new Wallet(id, balance + amount); + private List addCommandId(String commandId) { + // To avoid infinite growth of the list with limit the size to 1000. + // This implementation is not very efficient, so you might want to use a more dedicated data structure for it. + // When using other collections, make sure that the state is serializable and deserializable. + // Another way to put some constraints on the list size is to remove commandIds based on time + // e.g. remove commandIds that are older than 1 hour. + if (commandIds.size() >= COMMAND_IDS_MAX_SIZE) { + commandIds.removeFirst(); + } + commandIds.add(commandId); + return commandIds; } } \ No newline at end of file diff --git a/samples/transfer-workflow-compensation/src/main/java/com/example/wallet/domain/WalletCommand.java b/samples/transfer-workflow-compensation/src/main/java/com/example/wallet/domain/WalletCommand.java new file mode 100644 index 000000000..2832fa6b7 --- /dev/null +++ b/samples/transfer-workflow-compensation/src/main/java/com/example/wallet/domain/WalletCommand.java @@ -0,0 +1,11 @@ +package com.example.wallet.domain; + +public sealed interface WalletCommand { + + String commandId(); + + record Withdraw(String commandId, int amount) implements WalletCommand { + } + record Deposit(String commandId, int amount) implements WalletCommand { + } +} diff --git a/samples/transfer-workflow-compensation/src/main/java/com/example/wallet/domain/WalletEvent.java b/samples/transfer-workflow-compensation/src/main/java/com/example/wallet/domain/WalletEvent.java index 145ff34a0..ad6fbd560 100644 --- a/samples/transfer-workflow-compensation/src/main/java/com/example/wallet/domain/WalletEvent.java +++ b/samples/transfer-workflow-compensation/src/main/java/com/example/wallet/domain/WalletEvent.java @@ -5,15 +5,15 @@ public sealed interface WalletEvent { @TypeName("created") - record Created(int initialBalance) implements WalletEvent { + record Created(String walletId, int initialBalance) implements WalletEvent { } @TypeName("withdrawn") - record Withdrawn(int amount) implements WalletEvent { + record Withdrawn(String commandId, int amount) implements WalletEvent { } @TypeName("deposited") - record Deposited(int amount) implements WalletEvent { + record Deposited(String commandId, int amount) implements WalletEvent { } }