This is an automated email from the ASF dual-hosted git repository. reta pushed a commit to branch 3.5.x-fixes in repository https://gitbox.apache.org/repos/asf/cxf.git
commit 9e9890762e2383270c14e77f5f34898ce05520d0 Author: Andriy Redko <[email protected]> AuthorDate: Tue Aug 29 20:59:40 2023 -0400 CXF-8457: Provide OpenTelemetry support. Add OSGi support and example. (cherry picked from commit 982a7acf559e3e378555b599970626d32bffdb4c) --- .../jax_rs/tracing_opentelemetry_osgi/README.txt | 95 +++++++++++++++ .../jax_rs/tracing_opentelemetry_osgi/pom.xml | 134 ++++++++++++++++++++ .../java/demo/jaxrs/tracing/server/Catalog.java | 135 +++++++++++++++++++++ .../demo/jaxrs/tracing/server/CatalogStore.java | 71 +++++++++++ .../META-INF/services/javax.json.spi.JsonProvider | 1 + .../main/resources/OSGI-INF/blueprint/context.xml | 97 +++++++++++++++ distribution/src/main/release/samples/pom.xml | 1 + .../karaf/features/src/main/resources/features.xml | 7 ++ 8 files changed, 541 insertions(+) diff --git a/distribution/src/main/release/samples/jax_rs/tracing_opentelemetry_osgi/README.txt b/distribution/src/main/release/samples/jax_rs/tracing_opentelemetry_osgi/README.txt new file mode 100644 index 0000000000..faf4a974ba --- /dev/null +++ b/distribution/src/main/release/samples/jax_rs/tracing_opentelemetry_osgi/README.txt @@ -0,0 +1,95 @@ +JAX-RS OpenTelemetry/Jaeger Demo in OSGi container +================= + +The demo shows a basic usage of OpenTelemetry API tracing capabilities +with REST based Web Services using JAX-RS 2.0 (JSR-339), deployed inside OSGi +container. The server provides the following services at base URL +http://localhost:8181/cxf/catalog: + + GET http://localhost:8181/cxf/catalog + POST http://localhost:8181/cxf/catalog + GET http://localhost:8181/cxf/catalog/<id> + DELETE http://localhost:8181/cxf/catalog/<id> + + +Building and running the demo using Maven +--------------------------------------- + +From the base directory of this sample (i.e., where this README file is +located), the Maven pom.xml file can be used to build and run the demo. + +Using either UNIX or Windows: + + mvn install + +Starting Karaf (refer to http://karaf.apache.org/manual/latest-4.4.x/quick-start.html) + + bin/karaf + + + __ __ ____ + / //_/____ __________ _/ __/ + / ,< / __ `/ ___/ __ `/ /_ + / /| |/ /_/ / / / /_/ / __/ + /_/ |_|\__,_/_/ \__,_/_/ + + Apache Karaf (4.4.3) + + Hit '<tab>' for a list of available commands + and '[cmd] --help' for help on a specific command. + Hit '<ctrl-d>' or type 'system:shutdown' or 'logout' to shutdown Karaf. + + +In order to install CXF's features, you need to add the CXF's features repo using + + feature:repo-add cxf 3.n.m + +where 3.n.m corresponds to a valid CXF version number (e.g., 3.6.2). + +Install CXF's cxf-tracing-opentelemetry feature that installs all the required bundles +for this demo bundle. + + feature:install cxf-jaxrs + feature:install cxf-jsr-json + feature:install cxf-tracing-opentelemetry + feature:install aries-blueprint + +Install the exporter compatible with OpenTelemetry API, as in this example +we are using logging exporter: + + install -s wrap:mvn:io.opentelemetry/opentelemetry-sdk-common/1.29.0 + install -s wrap:mvn:io.opentelemetry/opentelemetry-sdk-metrics/1.29.0 + install -s wrap:mvn:io.opentelemetry/opentelemetry-sdk-trace/1.29.0 + install -s wrap:mvn:io.opentelemetry/opentelemetry-sdk-logs/1.29.0 + install -s wrap:mvn:io.opentelemetry/opentelemetry-sdk/1.29.0 + install -s wrap:mvn:io.opentelemetry/opentelemetry-exporter-common/1.29.0 + install -s wrap:mvn:io.opentelemetry/opentelemetry-exporter-logging/1.29.0 + +Install this demo bundle (using the appropriate bundle version number) + + install -s mvn:org.apache.cxf.samples/jax_rs_tracing_opentelemetry_osgi/3.n.m + +You can verify if the CXF JAX-RS OpenTelemetry Blueprint Demo is installed and started. + + karaf@root()> list + START LEVEL 100 , List Threshold: 50 + ID | State | Lvl | Version | Name + ----+--------+-----+-----------+--------------------------------------------------------------------- + 129 | Active | 80 | 0 | wrap_mvn_io.opentelemetry_opentelemetry-sdk-common_1.29.0 + 131 | Active | 80 | 0 | wrap_mvn_io.opentelemetry_opentelemetry-sdk-metrics_1.29.0 + 132 | Active | 80 | 0 | wrap_mvn_io.opentelemetry_opentelemetry-sdk-trace_1.29.0 + 133 | Active | 80 | 0 | wrap_mvn_io.opentelemetry_opentelemetry-sdk-logs_1.29.0 + 134 | Active | 80 | 0 | wrap_mvn_io.opentelemetry_opentelemetry-sdk_1.29.0 + 135 | Active | 80 | 0 | wrap_mvn_io.opentelemetry_opentelemetry-exporter-common_1.29.0 + 143 | Active | 80 | 0 | wrap_mvn_io.opentelemetry_opentelemetry-exporter-logging_1.29.0 + 149 | Active | 80 | 3.6.2.SNAPSHOT | JAX-RS Demo Using Distributed Tracing with OpenTelemetry API and OSGi + karaf@root()> + +Now, you will be able to access this CXF JAXRS demo service on your Karaf instance at + + http://localhost:8181/cxf/catalog + +The following sample traces should be available in Karaf logs: + + 20:49:19.850 INFO [BatchSpanProcessor_WorkerThread-1] 'Looking for books' : 9b12a38929dccef988a01e0855afcf58 9784703dce7ad842 INTERNAL [tracer: tracer:] {} + 20:49:19.851 INFO [BatchSpanProcessor_WorkerThread-1] 'GET /cxf/catalog' : 9b12a38929dccef988a01e0855afcf58 21dd42bf438a164a SERVER [tracer: tracer:] AttributesMap{data={http.status_code=200, http.url=http://localhost:8181/cxf/catalog, http.method=GET}, capacity=128, totalAddedValues=3} diff --git a/distribution/src/main/release/samples/jax_rs/tracing_opentelemetry_osgi/pom.xml b/distribution/src/main/release/samples/jax_rs/tracing_opentelemetry_osgi/pom.xml new file mode 100644 index 0000000000..d09eddf300 --- /dev/null +++ b/distribution/src/main/release/samples/jax_rs/tracing_opentelemetry_osgi/pom.xml @@ -0,0 +1,134 @@ +<?xml version="1.0"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <artifactId>jax_rs_tracing_opentelemetry_osgi</artifactId> + <name>JAX-RS Demo Using Distributed Tracing with OpenTelemetry API and OSGi</name> + <description>JAX-RS Demo Using Distributed Tracing with OpenTelemetry API and OSGi</description> + <packaging>bundle</packaging> + <parent> + <groupId>org.apache.cxf.samples</groupId> + <artifactId>cxf-samples</artifactId> + <version>3.5.7-SNAPSHOT</version> + <relativePath>../..</relativePath> + </parent> + <properties> + <cxf.version>${project.version}</cxf.version> + </properties> + <dependencies> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-transports-http</artifactId> + </dependency> + <!-- This dependency is needed if you're using the Jetty container --> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-transports-http-jetty</artifactId> + </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-frontend-jaxrs</artifactId> + </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-rs-client</artifactId> + </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-integration-tracing-opentelemetry</artifactId> + </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-rs-extension-providers</artifactId> + </dependency> + <dependency> + <groupId>jakarta.json</groupId> + <artifactId>jakarta.json-api</artifactId> + </dependency> + <dependency> + <groupId>org.apache.johnzon</groupId> + <artifactId>johnzon-core</artifactId> + </dependency> + <dependency> + <groupId>jakarta.ws.rs</groupId> + <artifactId>jakarta.ws.rs-api</artifactId> + </dependency> + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-webapp</artifactId> + </dependency> + <dependency> + <groupId>io.opentelemetry</groupId> + <artifactId>opentelemetry-api</artifactId> + </dependency> + <dependency> + <groupId>io.opentelemetry</groupId> + <artifactId>opentelemetry-context</artifactId> + </dependency> + <dependency> + <groupId>io.opentelemetry</groupId> + <artifactId>opentelemetry-sdk</artifactId> + </dependency> + <dependency> + <groupId>io.opentelemetry</groupId> + <artifactId>opentelemetry-exporter-otlp</artifactId> + </dependency> + <dependency> + <groupId>io.opentelemetry</groupId> + <artifactId>opentelemetry-exporter-sender-okhttp</artifactId> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <SPI-Consumer>*</SPI-Consumer> + <SPI-Provider>*</SPI-Provider> + <Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName> + <Import-Package> + javax.ws.rs, + javax.ws.rs.core, + javax.ws.rs.container, + org.apache.cxf.jaxrs.provider, + org.apache.cxf.jaxrs.provider.jsrjsonp, + org.apache.cxf.tracing.opentelemetry.jaxrs, + org.osgi.service.blueprint, + javax.annotation;version="[1.2,2)", + org.apache.johnzon.core, + io.opentelemetry.sdk, + io.opentelemetry.sdk.resources, + io.opentelemetry.sdk.trace, + io.opentelemetry.sdk.trace.export, + io.opentelemetry.sdk.trace.samplers, + * + </Import-Package> + <Export-Package> + </Export-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/distribution/src/main/release/samples/jax_rs/tracing_opentelemetry_osgi/src/main/java/demo/jaxrs/tracing/server/Catalog.java b/distribution/src/main/release/samples/jax_rs/tracing_opentelemetry_osgi/src/main/java/demo/jaxrs/tracing/server/Catalog.java new file mode 100644 index 0000000000..141effca85 --- /dev/null +++ b/distribution/src/main/release/samples/jax_rs/tracing_opentelemetry_osgi/src/main/java/demo/jaxrs/tracing/server/Catalog.java @@ -0,0 +1,135 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package demo.jaxrs.tracing.server; + + +import java.io.IOException; +import java.util.UUID; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +import javax.json.Json; +import javax.json.JsonObject; +import javax.ws.rs.DELETE; +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.NotFoundException; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.container.AsyncResponse; +import javax.ws.rs.container.Suspended; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; + +import org.apache.cxf.tracing.Traceable; +import org.apache.cxf.tracing.TracerContext; + +@Path("/catalog") +public class Catalog { + private final ExecutorService executor = Executors.newFixedThreadPool(2); + private final CatalogStore store; + + public Catalog() { + store = new CatalogStore(); + } + + @POST + @Produces(MediaType.APPLICATION_JSON) + public Response addBook(@Context final UriInfo uriInfo, @Context final TracerContext tracing, + @FormParam("title") final String title) { + try { + final String id = UUID.randomUUID().toString(); + + executor.submit( + tracing.wrap("Inserting New Book", + new Traceable<Void>() { + public Void call(final TracerContext context) throws Exception { + store.put(id, title); + return null; + } + } + ) + ).get(10, TimeUnit.SECONDS); + + return Response + .created(uriInfo.getRequestUriBuilder().path(id).build()) + .build(); + } catch (final Exception ex) { + return Response + .serverError() + .entity(Json + .createObjectBuilder() + .add("error", ex.getMessage()) + .build()) + .build(); + } + } + + @GET + @Produces(MediaType.APPLICATION_JSON) + public void getBooks(@Suspended final AsyncResponse response, + @Context final TracerContext tracing) throws Exception { + tracing.continueSpan(new Traceable<Void>() { + @Override + public Void call(final TracerContext context) throws Exception { + executor.submit(tracing.wrap("Looking for books", new Traceable<Void>() { + @Override + public Void call(final TracerContext context) throws Exception { + response.resume(store.scan()); + return null; + } + })); + + return null; + } + }); + } + + @GET + @Path("/{id}") + @Produces(MediaType.APPLICATION_JSON) + public JsonObject getBook(@PathParam("id") final String id) throws IOException { + final JsonObject book = store.get(id); + + if (book == null) { + throw new NotFoundException("Book with does not exists: " + id); + } + + return book; + } + + @DELETE + @Path("/{id}") + @Produces(MediaType.APPLICATION_JSON) + public Response delete(@PathParam("id") final String id) throws IOException { + if (!store.remove(id)) { + throw new NotFoundException("Book with does not exists: " + id); + } + + return Response.ok().build(); + } +} + + diff --git a/distribution/src/main/release/samples/jax_rs/tracing_opentelemetry_osgi/src/main/java/demo/jaxrs/tracing/server/CatalogStore.java b/distribution/src/main/release/samples/jax_rs/tracing_opentelemetry_osgi/src/main/java/demo/jaxrs/tracing/server/CatalogStore.java new file mode 100644 index 0000000000..d68ba668cf --- /dev/null +++ b/distribution/src/main/release/samples/jax_rs/tracing_opentelemetry_osgi/src/main/java/demo/jaxrs/tracing/server/CatalogStore.java @@ -0,0 +1,71 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package demo.jaxrs.tracing.server; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import javax.json.Json; +import javax.json.JsonArray; +import javax.json.JsonArrayBuilder; +import javax.json.JsonObject; + +public class CatalogStore { + private final Map<String, String> books = new ConcurrentHashMap<>(); + + public CatalogStore() { + } + + public boolean remove(final String key) throws IOException { + return books.remove(key) != null; + } + + public JsonObject get(final String key) throws IOException { + final String title = books.get(key); + + if (title != null) { + return Json.createObjectBuilder() + .add("id", key) + .add("title", title) + .build(); + } + + return null; + } + + public void put(final String key, final String title) throws IOException { + books.put(key, title); + } + + public JsonArray scan() throws IOException { + final JsonArrayBuilder builder = Json.createArrayBuilder(); + + for (final Map.Entry<String, String> entry: books.entrySet()) { + builder.add(Json.createObjectBuilder() + .add("id", entry.getKey()) + .add("title", entry.getValue()) + ); + } + + return builder.build(); + } + +} diff --git a/distribution/src/main/release/samples/jax_rs/tracing_opentelemetry_osgi/src/main/resources/META-INF/services/javax.json.spi.JsonProvider b/distribution/src/main/release/samples/jax_rs/tracing_opentelemetry_osgi/src/main/resources/META-INF/services/javax.json.spi.JsonProvider new file mode 100644 index 0000000000..10c8c574b4 --- /dev/null +++ b/distribution/src/main/release/samples/jax_rs/tracing_opentelemetry_osgi/src/main/resources/META-INF/services/javax.json.spi.JsonProvider @@ -0,0 +1 @@ +org.apache.johnzon.core.JsonProviderImpl \ No newline at end of file diff --git a/distribution/src/main/release/samples/jax_rs/tracing_opentelemetry_osgi/src/main/resources/OSGI-INF/blueprint/context.xml b/distribution/src/main/release/samples/jax_rs/tracing_opentelemetry_osgi/src/main/resources/OSGI-INF/blueprint/context.xml new file mode 100644 index 0000000000..ce2fd4390f --- /dev/null +++ b/distribution/src/main/release/samples/jax_rs/tracing_opentelemetry_osgi/src/main/resources/OSGI-INF/blueprint/context.xml @@ -0,0 +1,97 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<!-- START SNIPPET: blueprint --> +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:cxf="http://cxf.apache.org/blueprint/core" + xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs" + + xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd + http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd + http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/blueprint/jaxrs.xsd"> + + <!-- JAXRS providers --> + <bean id="jsonProvider" class="org.apache.cxf.jaxrs.provider.jsrjsonp.JsrJsonpProvider" /> + + <bean id="tracingFeature" class="org.apache.cxf.tracing.opentelemetry.jaxrs.OpenTelemetryFeature"> + <argument index="0"> + <bean factory-ref="withPropagators" factory-method="build"/> + </argument> + <argument index="1" value="tracer" /> + </bean> + + <bean id="openTelemetrySdk" class="io.opentelemetry.sdk.OpenTelemetrySdk" factory-method="builder" /> + <bean id="sdkTracerProvider" class="io.opentelemetry.sdk.trace.SdkTracerProvider" factory-method="builder" /> + + <bean id="withSampler" factory-ref="sdkTracerProvider" factory-method="setSampler"> + <argument index="0"> + <bean class="io.opentelemetry.sdk.trace.samplers.Sampler" factory-method="alwaysOn" /> + </argument> + </bean> + + <bean id="processor" class="io.opentelemetry.sdk.trace.export.BatchSpanProcessor" factory-method="builder"> + <argument index="0"> + <bean class="io.opentelemetry.exporter.logging.LoggingSpanExporter" factory-method="create" /> + </argument> + </bean> + + <bean id="withSpanProcessor" factory-ref="sdkTracerProvider" factory-method="addSpanProcessor"> + <argument index="0"> + <bean factory-ref="processor" factory-method="build"/> + </argument> + </bean> + + <bean id="withTracerProvider" factory-ref="openTelemetrySdk" factory-method="setTracerProvider"> + <argument index="0"> + <bean factory-ref="withSpanProcessor" factory-method="build"/> + </argument> + </bean> + + <bean id="withPropagators" factory-ref="withTracerProvider" factory-method="setPropagators"> + <argument index="0"> + <bean class="io.opentelemetry.context.propagation.ContextPropagators" factory-method="create"> + <argument index="0"> + <bean class="io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator" factory-method="getInstance" /> + </argument> + </bean> + </argument> + </bean> + + <!-- Application resources --> + <bean id="catalogResource" class="demo.jaxrs.tracing.server.Catalog" /> + + <cxf:bus> + <cxf:features> + <cxf:logging /> + </cxf:features> + </cxf:bus> + + <jaxrs:server id="catalogServer" address="/"> + <jaxrs:serviceBeans> + <ref component-id="catalogResource" /> + </jaxrs:serviceBeans> + <jaxrs:providers> + <ref component-id="jsonProvider" /> + <ref component-id="tracingFeature" /> + </jaxrs:providers> + </jaxrs:server> + +</blueprint> +<!-- END SNIPPET: blueprint --> diff --git a/distribution/src/main/release/samples/pom.xml b/distribution/src/main/release/samples/pom.xml index ac186e986c..86e1617985 100644 --- a/distribution/src/main/release/samples/pom.xml +++ b/distribution/src/main/release/samples/pom.xml @@ -105,6 +105,7 @@ <module>jax_rs/tracing_opentracing_camel</module> <module>jax_rs/tracing_opentracing_osgi</module> <module>jax_rs/tracing_opentelemetry</module> + <module>jax_rs/tracing_opentelemetry_osgi</module> <module>jax_rs/websocket</module> <module>jax_rs/websocket_osgi</module> <module>jax_rs/websocket_web</module> diff --git a/osgi/karaf/features/src/main/resources/features.xml b/osgi/karaf/features/src/main/resources/features.xml index 128564cac6..9b0fbda41a 100644 --- a/osgi/karaf/features/src/main/resources/features.xml +++ b/osgi/karaf/features/src/main/resources/features.xml @@ -316,6 +316,13 @@ <bundle start-level="35">wrap:mvn:io.opentracing/opentracing-util/${cxf.opentracing.version}</bundle> <bundle start-level="40">mvn:org.apache.cxf/cxf-integration-tracing-opentracing/${project.version}</bundle> </feature> + <feature name="cxf-tracing-opentelemetry" version="${project.version}"> + <feature version="${project.version}">cxf-core</feature> + <bundle start-level="35">wrap:mvn:io.opentelemetry/opentelemetry-api/${cxf.opentelemetry.version}</bundle> + <bundle start-level="35">wrap:mvn:io.opentelemetry/opentelemetry-context/${cxf.opentelemetry.version}</bundle> + <bundle start-level="35">wrap:mvn:io.opentelemetry/opentelemetry-semconv/${cxf.opentelemetry.semconv.version}</bundle> + <bundle start-level="40">mvn:org.apache.cxf/cxf-integration-tracing-opentelemetry/${project.version}</bundle> + </feature> <feature name="cxf-rs-description-swagger2" version="${project.version}"> <feature version="${project.version}">cxf-jaxrs</feature> <feature version="${project.version}">cxf-jackson</feature>
