Skip to content

Commit 5e72013

Browse files
feat: add OpenTelemetry traces (#969)
* feat: add OpenTelemetry tracing * use EDC telemetry API instead of OTel directly * fix participant delete event
1 parent fb74a6b commit 5e72013

24 files changed

Lines changed: 145 additions & 44 deletions

File tree

core/identity-hub-core/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ dependencies {
2929
implementation(libs.edc.spi.identity.did)
3030
implementation(libs.edc.vc.ldp)
3131
implementation(libs.edc.vc.jwt) // JtiValidationRule
32-
32+
implementation(libs.opentelemetry.instrumentation.annotations)
3333

3434
testImplementation(project(":core:common-core"))
3535
testImplementation(libs.junit.jupiter.api)

core/identity-hub-core/src/main/java/org/eclipse/edc/identityhub/core/services/query/CredentialQueryResolverImpl.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
package org.eclipse.edc.identityhub.core.services.query;
1616

17+
import io.opentelemetry.api.trace.SpanKind;
18+
import io.opentelemetry.instrumentation.annotations.WithSpan;
1719
import org.eclipse.edc.iam.decentralizedclaims.spi.model.PresentationQueryMessage;
1820
import org.eclipse.edc.iam.verifiablecredentials.spi.model.RevocationServiceRegistry;
1921
import org.eclipse.edc.identityhub.spi.transformation.ScopeToCriterionTransformer;
@@ -55,6 +57,7 @@ public CredentialQueryResolverImpl(CredentialStore credentialStore, ScopeToCrite
5557
}
5658

5759
@Override
60+
@WithSpan(value = "presentation.credential-query", kind = SpanKind.INTERNAL)
5861
public QueryResult query(String participantContextId, PresentationQueryMessage query, List<String> accessTokenScopes) {
5962
if (query.getPresentationDefinition() != null) {
6063
throw new UnsupportedOperationException("Querying with a DIF Presentation Exchange definition is not yet supported.");

core/identity-hub-core/src/main/java/org/eclipse/edc/identityhub/core/services/verifiablecredential/CredentialRequestManagerImpl.java

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414

1515
package org.eclipse.edc.identityhub.core.services.verifiablecredential;
1616

17+
import io.opentelemetry.api.GlobalOpenTelemetry;
18+
import io.opentelemetry.api.trace.SpanKind;
19+
import io.opentelemetry.instrumentation.annotations.WithSpan;
1720
import jakarta.json.JsonObject;
1821
import okhttp3.MediaType;
1922
import okhttp3.Request;
@@ -39,6 +42,7 @@
3942
import org.eclipse.edc.spi.response.StatusResult;
4043
import org.eclipse.edc.spi.result.Result;
4144
import org.eclipse.edc.spi.result.ServiceResult;
45+
import org.eclipse.edc.spi.telemetry.Telemetry;
4246
import org.eclipse.edc.statemachine.AbstractStateEntityManager;
4347
import org.eclipse.edc.statemachine.Processor;
4448
import org.eclipse.edc.statemachine.ProcessorImpl;
@@ -83,15 +87,19 @@ private CredentialRequestManagerImpl() {
8387

8488
}
8589

90+
@WithSpan(value = "credential-request.initiate", kind = SpanKind.INTERNAL)
8691
@Override
8792
public ServiceResult<String> initiateRequest(String participantContextId, String issuerDid, String holderPid, List<RequestedCredential> requestedCredentials) {
8893

94+
var traceContext = new Telemetry(GlobalOpenTelemetry.get()).getCurrentTraceContext();
95+
8996
var newRequest = HolderCredentialRequest.Builder.newInstance()
9097
.id(holderPid)
9198
.issuerDid(issuerDid)
9299
.requestedCredentials(requestedCredentials)
93100
.participantContextId(participantContextId)
94101
.state(CREATED.code())
102+
.traceContext(traceContext)
95103
.build();
96104

97105
try {
@@ -170,13 +178,16 @@ private ProcessorImpl<HolderCredentialRequest> createProcessor(Function<HolderCr
170178
private CompletableFuture<StatusResult<Void>> processInitial(HolderCredentialRequest holderCredentialRequest) {
171179
monitor.debug("Processing '%s' request '%s'".formatted(holderCredentialRequest.stateAsString(), holderCredentialRequest.getHolderPid()));
172180

173-
var result = getCredentialRequestEndpoint(holderCredentialRequest)
174-
.compose(endpoint -> sendCredentialRequest(holderCredentialRequest, endpoint))
175-
.compose(issuerPid -> handleCredentialResponse(issuerPid, holderCredentialRequest))
176-
.onFailure(failure -> transactionContext.execute(() -> transitionError(holderCredentialRequest, failure.getFailureDetail())));
181+
return new Telemetry(GlobalOpenTelemetry.get()).contextPropagationMiddleware(() -> {
182+
var result = getCredentialRequestEndpoint(holderCredentialRequest)
183+
.compose(endpoint -> sendCredentialRequest(holderCredentialRequest, endpoint))
184+
.compose(issuerPid -> handleCredentialResponse(issuerPid, holderCredentialRequest))
185+
.onFailure(failure -> transactionContext.execute(() -> transitionError(holderCredentialRequest, failure.getFailureDetail())));
186+
187+
StatusResult<Void> statusResult = result.succeeded() ? StatusResult.success() : StatusResult.failure(ResponseStatus.FATAL_ERROR, result.getFailureDetail());
188+
return CompletableFuture.completedFuture(statusResult);
189+
}, holderCredentialRequest).get();
177190

178-
StatusResult<Void> statusResult = result.succeeded() ? StatusResult.success() : StatusResult.failure(ResponseStatus.FATAL_ERROR, result.getFailureDetail());
179-
return CompletableFuture.completedFuture(statusResult);
180191
}
181192

182193
/**

core/identity-hub-core/src/main/java/org/eclipse/edc/identityhub/core/services/verifiablepresentation/generators/JwtEnvelopedPresentationGenerator.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
package org.eclipse.edc.identityhub.core.services.verifiablepresentation.generators;
1616

17+
import io.opentelemetry.api.trace.SpanKind;
18+
import io.opentelemetry.instrumentation.annotations.WithSpan;
1719
import org.eclipse.edc.iam.verifiablecredentials.spi.model.CredentialFormat;
1820
import org.eclipse.edc.iam.verifiablecredentials.spi.model.VerifiableCredentialContainer;
1921
import org.eclipse.edc.identityhub.spi.verifiablecredentials.generator.PresentationGenerator;
@@ -62,6 +64,7 @@ public String generatePresentation(List<VerifiableCredentialContainer> credentia
6264
}
6365

6466
@Override
67+
@WithSpan(value = "presentation.create", kind = SpanKind.INTERNAL)
6568
public String generatePresentation(String participantContextId, List<VerifiableCredentialContainer> credentials, String privateKeyAlias, String publicKeyId, String issuerId, Map<String, Object> additionalData) {
6669
var violatingCredentials = credentials.stream().filter(vc -> vc.format() != CredentialFormat.VC2_0_JOSE).toList();
6770

core/identity-hub-core/src/main/java/org/eclipse/edc/identityhub/core/services/verifiablepresentation/generators/JwtPresentationGenerator.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
package org.eclipse.edc.identityhub.core.services.verifiablepresentation.generators;
1616

17+
import io.opentelemetry.api.trace.SpanKind;
18+
import io.opentelemetry.instrumentation.annotations.WithSpan;
1719
import org.eclipse.edc.iam.verifiablecredentials.spi.VcConstants;
1820
import org.eclipse.edc.iam.verifiablecredentials.spi.model.VerifiableCredentialContainer;
1921
import org.eclipse.edc.identityhub.spi.verifiablecredentials.generator.PresentationGenerator;
@@ -81,6 +83,7 @@ public String generatePresentation(List<VerifiableCredentialContainer> credentia
8183
* @throws EdcException If signing the JWT fails.
8284
*/
8385
@Override
86+
@WithSpan(value = "presentation.create", kind = SpanKind.INTERNAL)
8487
public String generatePresentation(String participantContextId, List<VerifiableCredentialContainer> credentials, String privateKeyAlias, String publicKeyId, String issuerId, Map<String, Object> additionalData) {
8588

8689
// check if expected data is there

core/identity-hub-core/src/main/java/org/eclipse/edc/identityhub/core/services/verifiablepresentation/generators/LdpPresentationGenerator.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
import com.apicatalog.vc.suite.SignatureSuite;
1818
import com.fasterxml.jackson.core.JsonProcessingException;
19+
import io.opentelemetry.api.trace.SpanKind;
20+
import io.opentelemetry.instrumentation.annotations.WithSpan;
1921
import jakarta.json.Json;
2022
import jakarta.json.JsonArray;
2123
import jakarta.json.JsonArrayBuilder;
@@ -108,6 +110,7 @@ public JsonObject generatePresentation(List<VerifiableCredentialContainer> crede
108110
* or if one or more VerifiableCredentials cannot be represented in the JSON-LD format.
109111
*/
110112
@Override
113+
@WithSpan(value = "presentation.create", kind = SpanKind.INTERNAL)
111114
public JsonObject generatePresentation(String participantContextId, List<VerifiableCredentialContainer> credentials, String privateKeyAlias, String publicKeyId, String issuerId, Map<String, Object> additionalData) {
112115
if (!additionalData.containsKey(TYPE_ADDITIONAL_DATA)) {
113116
throw new IllegalArgumentException("Must provide additional data: '%s'".formatted(TYPE_ADDITIONAL_DATA));

core/identity-hub-did/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ dependencies {
1010
implementation(libs.edc.spi.transaction)
1111
implementation(libs.edc.lib.common.crypto)
1212
implementation(libs.edc.lib.store)
13+
implementation(libs.opentelemetry.api)
14+
implementation(libs.opentelemetry.instrumentation.annotations)
1315

1416
testImplementation(libs.edc.lib.query)
1517
testImplementation(libs.edc.junit)

core/identity-hub-did/src/main/java/org/eclipse/edc/identityhub/did/DidDocumentServiceImpl.java

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414

1515
package org.eclipse.edc.identityhub.did;
1616

17+
import io.opentelemetry.api.GlobalOpenTelemetry;
18+
import io.opentelemetry.api.trace.SpanKind;
19+
import io.opentelemetry.instrumentation.annotations.WithSpan;
1720
import org.eclipse.edc.iam.did.spi.document.DidDocument;
1821
import org.eclipse.edc.iam.did.spi.document.Service;
1922
import org.eclipse.edc.iam.did.spi.document.VerificationMethod;
@@ -38,11 +41,14 @@
3841
import org.eclipse.edc.spi.result.AbstractResult;
3942
import org.eclipse.edc.spi.result.ServiceResult;
4043
import org.eclipse.edc.spi.result.StoreResult;
44+
import org.eclipse.edc.spi.telemetry.Telemetry;
45+
import org.eclipse.edc.spi.telemetry.TraceCarrier;
4146
import org.eclipse.edc.transaction.spi.TransactionContext;
4247

4348
import java.security.KeyPair;
4449
import java.security.PublicKey;
4550
import java.util.Collection;
51+
import java.util.function.Supplier;
4652
import java.util.stream.Collectors;
4753

4854
import static org.eclipse.edc.participantcontext.spi.types.ParticipantResource.queryByParticipantContextId;
@@ -72,6 +78,7 @@ public DidDocumentServiceImpl(TransactionContext transactionContext, DidResource
7278
}
7379

7480
@Override
81+
@WithSpan(value = "did-document.store", kind = SpanKind.INTERNAL)
7582
public ServiceResult<Void> store(DidDocument document, String participantContextId) {
7683
return transactionContext.execute(() -> {
7784
var res = DidResource.Builder.newInstance()
@@ -244,17 +251,30 @@ public ServiceResult<Void> removeService(String did, String serviceId) {
244251
@Override
245252
public <E extends Event> void on(EventEnvelope<E> eventEnvelope) {
246253
var payload = eventEnvelope.getPayload();
247-
if (payload instanceof ParticipantContextUpdated event) {
248-
updated(event);
249-
} else if (payload instanceof KeyPairRevoked event) {
250-
keypairRevoked(event);
251-
} else if (payload instanceof KeyPairActivated event) {
252-
keyPairActivated(event);
254+
255+
256+
var s = (Supplier<Void>) () -> {
257+
if (payload instanceof ParticipantContextUpdated event) {
258+
updated(event);
259+
} else if (payload instanceof KeyPairRevoked event) {
260+
keypairRevoked(event);
261+
} else if (payload instanceof KeyPairActivated event) {
262+
keyPairActivated(event);
263+
} else {
264+
monitor.warning("Received event with unexpected payload type: %s".formatted(payload.getClass()));
265+
}
266+
return null;
267+
};
268+
269+
if (payload instanceof TraceCarrier carrier) {
270+
new Telemetry(GlobalOpenTelemetry.get()).contextPropagationMiddleware(s, carrier).get();
253271
} else {
254-
monitor.warning("Received event with unexpected payload type: %s".formatted(payload.getClass()));
272+
s.get();
255273
}
274+
256275
}
257276

277+
@WithSpan(value = "did-document.keypair-activated", kind = SpanKind.INTERNAL)
258278
private void keyPairActivated(KeyPairActivated event) {
259279
transactionContext.execute(() -> {
260280
var didResources = findByParticipantContextId(event.getParticipantContextId());
@@ -294,6 +314,7 @@ private void keyPairActivated(KeyPairActivated event) {
294314
});
295315
}
296316

317+
@WithSpan(value = "did-document.keypair-revoked", kind = SpanKind.INTERNAL)
297318
private void keypairRevoked(KeyPairRevoked event) {
298319
var didResources = findByParticipantContextId(event.getParticipantContextId());
299320
var keyId = event.getKeyId();
@@ -310,6 +331,7 @@ private void keypairRevoked(KeyPairRevoked event) {
310331
}
311332
}
312333

334+
@WithSpan(value = "did-document.updated", kind = SpanKind.INTERNAL)
313335
private void updated(ParticipantContextUpdated event) {
314336
var newState = event.getNewState();
315337
var forParticipant = findByParticipantContextId(event.getParticipantContextId());

core/identity-hub-keypairs/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ dependencies {
2121
api(libs.edc.spi.transaction)
2222
implementation(project(":core:lib:keypair-lib"))
2323
implementation(libs.edc.lib.common.crypto)
24+
implementation(libs.opentelemetry.api)
25+
implementation(libs.opentelemetry.instrumentation.annotations)
2426
runtimeOnly(libs.edc.core.connector)
2527
testImplementation(libs.edc.junit)
2628
}

core/identity-hub-keypairs/src/main/java/org/eclipse/edc/identityhub/keypairs/KeyPairServiceImpl.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
package org.eclipse.edc.identityhub.keypairs;
1616

17+
import io.opentelemetry.api.trace.SpanKind;
18+
import io.opentelemetry.instrumentation.annotations.WithSpan;
1719
import org.eclipse.edc.identityhub.spi.keypair.KeyPairService;
1820
import org.eclipse.edc.identityhub.spi.keypair.events.KeyPairObservable;
1921
import org.eclipse.edc.identityhub.spi.keypair.model.KeyPairResource;
@@ -72,6 +74,7 @@ public KeyPairServiceImpl(KeyPairResourceStore keyPairResourceStore, Vault vault
7274
}
7375

7476
@Override
77+
@WithSpan(value = "keypairs.add", kind = SpanKind.INTERNAL)
7578
public ServiceResult<Void> addKeyPair(String participantContextId, KeyDescriptor keyDescriptor, boolean makeDefault) {
7679

7780
return transactionContext.execute(() -> {

0 commit comments

Comments
 (0)