From bcd6bad54abda5deb86f4a32dc2f7e39d54423f6 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Tue, 14 Feb 2023 10:10:41 +0100 Subject: [PATCH 1/6] Consistently use Docker creds for fetching images --- ci/pipeline.yml | 23 +++++++++-------------- ci/tasks/generate-changelog.yml | 8 +++----- ci/tasks/promote-version.yml | 2 ++ 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/ci/pipeline.yml b/ci/pipeline.yml index 9ebf52fd..d07176e5 100644 --- a/ci/pipeline.yml +++ b/ci/pipeline.yml @@ -13,10 +13,6 @@ anchors: ARTIFACTORY_SERVER: ((artifactory-server)) ARTIFACTORY_USERNAME: ((artifactory-username)) ARTIFACTORY_PASSWORD: ((artifactory-password)) - registry-mirror-vars: ®istry-mirror-vars - registry-mirror-host: ((registry-mirror-host)) - registry-mirror-username: ((registry-mirror-username)) - registry-mirror-password: ((registry-mirror-password)) sonatype-task-params: &sonatype-task-params SONATYPE_USERNAME: ((sonatype-username)) SONATYPE_PASSWORD: ((sonatype-password)) @@ -35,7 +31,7 @@ resource_types: source: <<: *registry-image-resource-source repository: springio/artifactory-resource - tag: 0.0.17 + tag: 0.0.18 - name: github-release type: registry-image source: @@ -63,8 +59,7 @@ resources: type: registry-image icon: docker source: - username: ((docker-hub-username)) - password: ((docker-hub-password)) + <<: *registry-image-resource-source tag: ((milestone)) repository: ((docker-hub-organization))/spring-graphql-ci-image - name: artifactory-repo @@ -106,7 +101,7 @@ jobs: image: ci-image vars: ci-image-name: ci-image - <<: *registry-mirror-vars + <<: *registry-image-resource-source - put: ci-image params: image: ci-image/image.tar @@ -183,7 +178,7 @@ jobs: params: RELEASE_TYPE: M <<: *artifactory-task-params - <<: *registry-mirror-vars + <<: *registry-image-resource-source - task: generate-changelog file: git-repo/ci/tasks/generate-changelog.yml params: @@ -191,7 +186,7 @@ jobs: GITHUB_USERNAME: ((github-username)) GITHUB_TOKEN: ((github-ci-release-token)) vars: - <<: *registry-mirror-vars + <<: *registry-image-resource-source - put: github-pre-release params: name: generated-changelog/tag @@ -233,7 +228,7 @@ jobs: params: RELEASE_TYPE: RC <<: *artifactory-task-params - <<: *registry-mirror-vars + <<: *registry-image-resource-source - task: generate-changelog file: git-repo/ci/tasks/generate-changelog.yml params: @@ -241,7 +236,7 @@ jobs: GITHUB_USERNAME: ((github-username)) GITHUB_TOKEN: ((github-ci-release-token)) vars: - <<: *registry-mirror-vars + <<: *registry-image-resource-source - put: github-pre-release params: name: generated-changelog/tag @@ -283,7 +278,7 @@ jobs: params: RELEASE_TYPE: RELEASE <<: *artifactory-task-params - <<: *registry-mirror-vars + <<: *registry-image-resource-source <<: *sonatype-task-params - name: create-github-release serial: true @@ -303,7 +298,7 @@ jobs: GITHUB_USERNAME: ((github-username)) GITHUB_TOKEN: ((github-ci-release-token)) vars: - <<: *registry-mirror-vars + <<: *registry-image-resource-source - put: github-release params: name: generated-changelog/tag diff --git a/ci/tasks/generate-changelog.yml b/ci/tasks/generate-changelog.yml index 48efb9fd..dc38cf49 100755 --- a/ci/tasks/generate-changelog.yml +++ b/ci/tasks/generate-changelog.yml @@ -4,11 +4,9 @@ image_resource: type: registry-image source: repository: springio/github-changelog-generator - tag: '0.0.7' - registry_mirror: - host: ((registry-mirror-host)) - username: ((registry-mirror-username)) - password: ((registry-mirror-password)) + tag: '0.0.8' + username: ((docker-hub-username)) + password: ((docker-hub-password)) inputs: - name: git-repo - name: artifactory-repo diff --git a/ci/tasks/promote-version.yml b/ci/tasks/promote-version.yml index c4f24c55..683482f8 100644 --- a/ci/tasks/promote-version.yml +++ b/ci/tasks/promote-version.yml @@ -5,6 +5,8 @@ image_resource: source: repository: springio/concourse-release-scripts tag: '0.3.4' + username: ((docker-hub-username)) + password: ((docker-hub-password)) inputs: - name: git-repo - name: artifactory-repo From 1d2fc21d0b0698429b6349d6adc4099869f1626b Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Tue, 14 Feb 2023 15:45:25 +0100 Subject: [PATCH 2/6] Fix parent Observation management in instrumentation Prior to this commit, the `GraphQlObservationInstrumentation` was incorrectly setting up the parent observation for both request execution and data fetching observations. In the case of the request execution, we were not looking into the `GraphQLContext` for an existing observation - this commit ensures that if such an observation exists, it is set as the parent. As for the data fetching observation, we were incorrectly assuming that the parent of all data fetching operations was the request execution one, whereas data fetching operations can be nested. This commit ensures that we only rely on the current observation in the GraphQL context. Fixes gh-611 --- .../GraphQlObservationInstrumentation.java | 44 ++++++++++++------- ...raphQlObservationInstrumentationTests.java | 28 +++++++++++- 2 files changed, 54 insertions(+), 18 deletions(-) diff --git a/spring-graphql/src/main/java/org/springframework/graphql/observation/GraphQlObservationInstrumentation.java b/spring-graphql/src/main/java/org/springframework/graphql/observation/GraphQlObservationInstrumentation.java index e7869107..c26507b9 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/observation/GraphQlObservationInstrumentation.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/observation/GraphQlObservationInstrumentation.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 the original author or authors. + * Copyright 2020-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ package org.springframework.graphql.observation; import java.util.concurrent.CompletionStage; import graphql.ExecutionResult; +import graphql.GraphQLContext; import graphql.execution.instrumentation.InstrumentationContext; import graphql.execution.instrumentation.InstrumentationState; import graphql.execution.instrumentation.SimpleInstrumentation; @@ -100,20 +101,21 @@ public class GraphQlObservationInstrumentation extends SimpleInstrumentation { InstrumentationState state) { if (state instanceof RequestObservationInstrumentationState instrumentationState) { ExecutionRequestObservationContext observationContext = new ExecutionRequestObservationContext(parameters.getExecutionInput()); + Observation parentObservation = parameters.getGraphQLContext().get(OBSERVATION_KEY); Observation requestObservation = instrumentationState.createRequestObservation(this.requestObservationConvention, observationContext, this.observationRegistry); + requestObservation.parentObservation(parentObservation); + parameters.getGraphQLContext().put(OBSERVATION_KEY, requestObservation); requestObservation.start(); return new SimpleInstrumentationContext<>() { @Override public void onCompleted(ExecutionResult result, Throwable exc) { observationContext.setResponse(result); if (exc != null) { - observationContext.setError(exc); requestObservation.error(exc); } - else { - requestObservation.stop(); - } + requestObservation.stop(); + instrumentationState.restoreParentObservation(parameters.getGraphQLContext(), parentObservation); } }; } @@ -126,58 +128,66 @@ public class GraphQlObservationInstrumentation extends SimpleInstrumentation { if (!parameters.isTrivialDataFetcher() && state instanceof RequestObservationInstrumentationState instrumentationState) { return (environment) -> { + GraphQLContext graphQLContext = parameters.getExecutionContext().getGraphQLContext(); + Observation parentObservation = graphQLContext.get(OBSERVATION_KEY); DataFetcherObservationContext observationContext = new DataFetcherObservationContext(parameters.getEnvironment()); Observation dataFetcherObservation = instrumentationState.createDataFetcherObservation( this.dataFetcherObservationConvention, observationContext, this.observationRegistry); - parameters.getExecutionContext().getGraphQLContext().put(OBSERVATION_KEY, dataFetcherObservation); + dataFetcherObservation.parentObservation(parentObservation); + graphQLContext.put(OBSERVATION_KEY, dataFetcherObservation); dataFetcherObservation.start(); try { Object value = dataFetcher.get(environment); if (value instanceof CompletionStage completion) { return completion.whenComplete((result, error) -> { + observationContext.setValue(result); if (error != null) { dataFetcherObservation.error(error); } - observationContext.setValue(result); dataFetcherObservation.stop(); + instrumentationState.restoreParentObservation(graphQLContext, parentObservation); }); } else { observationContext.setValue(value); dataFetcherObservation.stop(); + instrumentationState.restoreParentObservation(graphQLContext, parentObservation); return value; } } catch (Throwable throwable) { dataFetcherObservation.error(throwable); dataFetcherObservation.stop(); + instrumentationState.restoreParentObservation(graphQLContext, parentObservation); throw throwable; } }; } - return super.instrumentDataFetcher(dataFetcher, parameters, state); + return dataFetcher; } static class RequestObservationInstrumentationState implements InstrumentationState { - private Observation requestObservation; - - Observation createRequestObservation(ExecutionRequestObservationConvention convention, ExecutionRequestObservationContext context, ObservationRegistry registry) { - Observation observation = GraphQlObservationDocumentation.EXECUTION_REQUEST.observation(convention, + return GraphQlObservationDocumentation.EXECUTION_REQUEST.observation(convention, DEFAULT_REQUEST_CONVENTION, () -> context, registry); - this.requestObservation = observation; - return observation; } Observation createDataFetcherObservation(DataFetcherObservationConvention convention, DataFetcherObservationContext context, ObservationRegistry registry) { - Observation dataFetcherObservation = GraphQlObservationDocumentation.DATA_FETCHER.observation(convention, + return GraphQlObservationDocumentation.DATA_FETCHER.observation(convention, DEFAULT_DATA_FETCHER_CONVENTION, () -> context, registry); - dataFetcherObservation.parentObservation(requestObservation); - return dataFetcherObservation; + } + + void restoreParentObservation(GraphQLContext context, Observation parentObservation) { + if (parentObservation != null) { + context.put(OBSERVATION_KEY, parentObservation); + } + else { + context.delete(OBSERVATION_KEY); + } } } diff --git a/spring-graphql/src/test/java/org/springframework/graphql/observation/GraphQlObservationInstrumentationTests.java b/spring-graphql/src/test/java/org/springframework/graphql/observation/GraphQlObservationInstrumentationTests.java index cf6e6cd4..b686907f 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/observation/GraphQlObservationInstrumentationTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/observation/GraphQlObservationInstrumentationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 the original author or authors. + * Copyright 2020-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,8 @@ import java.util.List; import java.util.concurrent.CompletableFuture; import graphql.GraphqlErrorBuilder; +import io.micrometer.observation.Observation; +import io.micrometer.observation.ObservationRegistry; import io.micrometer.observation.tck.TestObservationRegistry; import io.micrometer.observation.tck.TestObservationRegistryAssert; import io.micrometer.observation.transport.ReceiverContext; @@ -199,6 +201,30 @@ class GraphQlObservationInstrumentationTests { .hasParentObservationContextMatching(context -> context instanceof ExecutionRequestObservationContext); } + @Test + void setIncomingObservationAsParent() { + String document = """ + { + bookById(id: 1) { + name + } + } + """; + ExecutionGraphQlRequest graphQlRequest = TestExecutionRequest.forDocument(document); + Observation incoming = Observation.start("incoming", ObservationRegistry.create()); + graphQlRequest.configureExecutionInput((input, builder) -> + builder.graphQLContext(contextBuilder -> contextBuilder.of("micrometer.observation", incoming)).build()); + Mono responseMono = graphQlSetup + .queryFetcher("bookById", env -> BookSource.getBookWithoutAuthor(1L)) + .toGraphQlService() + .execute(graphQlRequest); + ResponseHelper response = ResponseHelper.forResponse(responseMono); + + TestObservationRegistryAssert.assertThat(this.observationRegistry).hasObservationWithNameEqualTo("graphql.request") + .that().hasParentObservationEqualTo(incoming); + incoming.stop(); + } + @Test void inboundTracingInformationIsPropagated() { SimpleTracer simpleTracer = new SimpleTracer(); From 1d3701d3b4e71263b371e31e89a665fc9cb59960 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Tue, 14 Feb 2023 16:03:42 +0100 Subject: [PATCH 3/6] Upgrade to Micrometer 1.10.4 Closes gh-612 --- platform/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/build.gradle b/platform/build.gradle index 213371b6..e51455c8 100644 --- a/platform/build.gradle +++ b/platform/build.gradle @@ -10,7 +10,7 @@ dependencies { api(platform("org.springframework:spring-framework-bom:${springFrameworkVersion}")) api(platform("com.fasterxml.jackson:jackson-bom:2.14.1")) api(platform("io.projectreactor:reactor-bom:2022.0.1")) - api(platform("io.micrometer:micrometer-bom:1.10.2")) + api(platform("io.micrometer:micrometer-bom:1.10.4")) api(platform("io.micrometer:micrometer-tracing-bom:1.0.0")) api(platform("org.springframework.data:spring-data-bom:2022.0.0")) api(platform("org.springframework.security:spring-security-bom:6.0.1")) From 7489e95d9c54a9790700e235fe670da5e81d17aa Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Tue, 14 Feb 2023 16:04:24 +0100 Subject: [PATCH 4/6] Upgrade to Context Propagation 1.0.2 Closes gh-613 --- platform/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/build.gradle b/platform/build.gradle index e51455c8..cbec65a4 100644 --- a/platform/build.gradle +++ b/platform/build.gradle @@ -25,7 +25,7 @@ dependencies { constraints { api("com.graphql-java:graphql-java:${graphQlJavaVersion}") - api("io.micrometer:context-propagation:1.0.0") + api("io.micrometer:context-propagation:1.0.2") api("jakarta.annotation:jakarta.annotation-api:2.1.1") api("jakarta.servlet:jakarta.servlet-api:6.0.0") From e3b73e84e1f7be99dccbaf6ff6b1e9f06a8ff826 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Tue, 14 Feb 2023 16:04:57 +0100 Subject: [PATCH 5/6] Upgrade to Micrometer Tracing 1.0.2 Closes gh-614 --- platform/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/build.gradle b/platform/build.gradle index cbec65a4..23a3bf99 100644 --- a/platform/build.gradle +++ b/platform/build.gradle @@ -11,7 +11,7 @@ dependencies { api(platform("com.fasterxml.jackson:jackson-bom:2.14.1")) api(platform("io.projectreactor:reactor-bom:2022.0.1")) api(platform("io.micrometer:micrometer-bom:1.10.4")) - api(platform("io.micrometer:micrometer-tracing-bom:1.0.0")) + api(platform("io.micrometer:micrometer-tracing-bom:1.0.2")) api(platform("org.springframework.data:spring-data-bom:2022.0.0")) api(platform("org.springframework.security:spring-security-bom:6.0.1")) api(platform("com.querydsl:querydsl-bom:5.0.0")) From beafa43f25bf7a0b49ef202199123446f65188ee Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Tue, 14 Feb 2023 16:06:14 +0100 Subject: [PATCH 6/6] Upgrade other dependencies * Spring Framework 6.0.4 * Spring Data 2022.0.1 * Jackson 2.14.2 * Reactor 2022.0.2 --- build.gradle | 2 +- platform/build.gradle | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 5999bda6..436490b2 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ description = "Spring for GraphQL" ext { moduleProjects = [project(":spring-graphql"), project(":spring-graphql-test")] - springFrameworkVersion = "6.0.3" + springFrameworkVersion = "6.0.4" graphQlJavaVersion = "19.2" springBootVersion = "3.0.0" } diff --git a/platform/build.gradle b/platform/build.gradle index 23a3bf99..02f27e52 100644 --- a/platform/build.gradle +++ b/platform/build.gradle @@ -8,11 +8,11 @@ javaPlatform { dependencies { api(platform("org.springframework:spring-framework-bom:${springFrameworkVersion}")) - api(platform("com.fasterxml.jackson:jackson-bom:2.14.1")) - api(platform("io.projectreactor:reactor-bom:2022.0.1")) + api(platform("com.fasterxml.jackson:jackson-bom:2.14.2")) + api(platform("io.projectreactor:reactor-bom:2022.0.2")) api(platform("io.micrometer:micrometer-bom:1.10.4")) api(platform("io.micrometer:micrometer-tracing-bom:1.0.2")) - api(platform("org.springframework.data:spring-data-bom:2022.0.0")) + api(platform("org.springframework.data:spring-data-bom:2022.0.1")) api(platform("org.springframework.security:spring-security-bom:6.0.1")) api(platform("com.querydsl:querydsl-bom:5.0.0")) api(platform("io.rsocket:rsocket-bom:1.1.3"))