Skip to content

Commit

Permalink
fix bugs with dubbo (open-telemetry#6640)
Browse files Browse the repository at this point in the history
1. fix NullPointerException with dubbo getMetadata request

2. fix dubbo trace passing problem

the trace is third-demo -> consumer-demo -> provider-deme, but the
parent of provider-demo is third-demo.
wrong data like this
<img width="1994" alt="image"
src="https://user-images.githubusercontent.com/22729740/190597029-ea26569e-96b4-4e30-8ac3-46ead3871b92.png">

after fixed 
<img width="2015" alt="image"
src="https://user-images.githubusercontent.com/22729740/190596923-d65f8646-377d-47ab-9e65-6d75f1407ce0.png">

Co-authored-by: Mateusz Rzeszutek <mrzeszutek@splunk.com>
  • Loading branch information
2 people authored and LironKS committed Dec 4, 2022
1 parent a3f10bf commit 9e61e4a
Show file tree
Hide file tree
Showing 7 changed files with 242 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.apachedubbo.v2_7

import io.opentelemetry.instrumentation.test.AgentTestTrait

class DubboTraceChainTest extends AbstractDubboTraceChainTest implements AgentTestTrait {
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ enum DubboHeadersSetter implements TextMapSetter<DubboRequest> {
@Override
public void set(DubboRequest request, String key, String value) {
request.context().setAttachment(key, value);
request.invocation().setAttachment(key, value);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ public Result invoke(Invoker<?> invoker, Invocation invocation) {
}

RpcContext rpcContext = RpcContext.getContext();
if (rpcContext.getUrl() == null) {
return invoker.invoke(invocation);
}

boolean isServer = rpcContext.isProviderSide();
Instrumenter<DubboRequest, Result> instrumenter =
isServer ? serverInstrumenter : clientInstrumenter;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.apachedubbo.v2_7

import io.opentelemetry.instrumentation.test.LibraryTestTrait

class DubboTraceChainTest extends AbstractDubboTraceChainTest implements LibraryTestTrait {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.apachedubbo.v2_7

import io.opentelemetry.api.trace.SpanKind
import io.opentelemetry.instrumentation.apachedubbo.v2_7.api.HelloService
import io.opentelemetry.instrumentation.apachedubbo.v2_7.api.MiddleService
import io.opentelemetry.instrumentation.apachedubbo.v2_7.impl.HelloServiceImpl
import io.opentelemetry.instrumentation.apachedubbo.v2_7.impl.MiddleServiceImpl
import io.opentelemetry.instrumentation.test.InstrumentationSpecification
import io.opentelemetry.instrumentation.test.utils.PortUtils
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
import org.apache.dubbo.common.utils.NetUtils
import org.apache.dubbo.config.ApplicationConfig
import org.apache.dubbo.config.ProtocolConfig
import org.apache.dubbo.config.ReferenceConfig
import org.apache.dubbo.config.RegistryConfig
import org.apache.dubbo.config.ServiceConfig
import org.apache.dubbo.config.bootstrap.DubboBootstrap
import org.apache.dubbo.rpc.service.GenericService
import spock.lang.Unroll

import static io.opentelemetry.api.trace.SpanKind.CLIENT
import static io.opentelemetry.api.trace.SpanKind.SERVER

@Unroll
abstract class AbstractDubboTraceChainTest extends InstrumentationSpecification {

def setupSpec() {
NetUtils.LOCAL_ADDRESS = InetAddress.getLoopbackAddress()
}

ReferenceConfig<HelloService> configureClient(int port) {
ReferenceConfig<HelloService> reference = new ReferenceConfig<>()
reference.setInterface(HelloService)
reference.setGeneric("true")
reference.setUrl("dubbo://localhost:" + port + "/?timeout=30000")
return reference
}

ReferenceConfig<HelloService> configureMiddleClient(int port) {
ReferenceConfig<MiddleService> reference = new ReferenceConfig<>()
reference.setInterface(MiddleService)
reference.setGeneric("true")
reference.setUrl("dubbo://localhost:" + port + "/?timeout=30000")
return reference
}

ServiceConfig configureServer() {
def registerConfig = new RegistryConfig()
registerConfig.setAddress("N/A")
ServiceConfig<HelloServiceImpl> service = new ServiceConfig<>()
service.setInterface(HelloService)
service.setRef(new HelloServiceImpl())
service.setRegistry(registerConfig)
return service
}

ServiceConfig configureMiddleServer(GenericService genericService) {
def registerConfig = new RegistryConfig()
registerConfig.setAddress("N/A")
ServiceConfig<MiddleServiceImpl> service = new ServiceConfig<>()
service.setInterface(MiddleService)
service.setRef(new MiddleServiceImpl(genericService))
service.setRegistry(registerConfig)
return service
}

def "test that context is propagated correctly in chained dubbo calls"() {
setup:
def port = PortUtils.findOpenPorts(2)
def middlePort = port + 1
def protocolConfig = new ProtocolConfig()
protocolConfig.setPort(port)

DubboBootstrap bootstrap = DubboBootstrap.newInstance()
bootstrap.application(new ApplicationConfig("dubbo-test-provider"))
.service(configureServer())
.protocol(protocolConfig)
.start()

def middleProtocolConfig = new ProtocolConfig()
middleProtocolConfig.setPort(middlePort)

def reference = configureClient(port)
DubboBootstrap middleBootstrap = DubboBootstrap.newInstance()
middleBootstrap.application(new ApplicationConfig("dubbo-demo-middle"))
.reference(reference)
.service(configureMiddleServer(reference.get()))
.protocol(middleProtocolConfig)
.start()


def consumerProtocolConfig = new ProtocolConfig()
consumerProtocolConfig.setRegister(false)

def middleReference = configureMiddleClient(middlePort)
DubboBootstrap consumerBootstrap = DubboBootstrap.newInstance()
consumerBootstrap.application(new ApplicationConfig("dubbo-demo-api-consumer"))
.reference(middleReference)
.protocol(consumerProtocolConfig)
.start()

when:
GenericService genericService = middleReference.get()
def response = runWithSpan("parent") {
genericService.$invoke("hello", [String.getName()] as String[], ["hello"] as Object[])
}

then:
response == "hello"
assertTraces(1) {
trace(0, 5) {
span(0) {
name "parent"
kind SpanKind.INTERNAL
hasNoParent()
}
span(1) {
name "org.apache.dubbo.rpc.service.GenericService/\$invoke"
kind CLIENT
childOf span(0)
attributes {
"$SemanticAttributes.RPC_SYSTEM" "apache_dubbo"
"$SemanticAttributes.RPC_SERVICE" "org.apache.dubbo.rpc.service.GenericService"
"$SemanticAttributes.RPC_METHOD" "\$invoke"
"$SemanticAttributes.NET_PEER_NAME" "localhost"
"$SemanticAttributes.NET_PEER_PORT" Long
}
}
span(2) {
name "io.opentelemetry.instrumentation.apachedubbo.v2_7.api.MiddleService/hello"
kind SERVER
childOf span(1)
attributes {
"$SemanticAttributes.RPC_SYSTEM" "apache_dubbo"
"$SemanticAttributes.RPC_SERVICE" "io.opentelemetry.instrumentation.apachedubbo.v2_7.api.MiddleService"
"$SemanticAttributes.RPC_METHOD" "hello"
"net.sock.peer.addr" String
"net.sock.peer.port" Long
"net.sock.family" { it == "inet6" || it == null }
}
}
span(3) {
name "org.apache.dubbo.rpc.service.GenericService/\$invoke"
kind CLIENT
childOf span(2)
attributes {
"$SemanticAttributes.RPC_SYSTEM" "apache_dubbo"
"$SemanticAttributes.RPC_SERVICE" "org.apache.dubbo.rpc.service.GenericService"
"$SemanticAttributes.RPC_METHOD" "\$invoke"
"$SemanticAttributes.NET_PEER_NAME" "localhost"
"$SemanticAttributes.NET_PEER_PORT" Long
}
}
span(4) {
name "io.opentelemetry.instrumentation.apachedubbo.v2_7.api.HelloService/hello"
kind SERVER
childOf span(3)
attributes {
"$SemanticAttributes.RPC_SYSTEM" "apache_dubbo"
"$SemanticAttributes.RPC_SERVICE" "io.opentelemetry.instrumentation.apachedubbo.v2_7.api.HelloService"
"$SemanticAttributes.RPC_METHOD" "hello"
"net.sock.peer.addr" String
"net.sock.peer.port" Long
"net.sock.family" { it == "inet6" || it == null }
}
}
}
}

cleanup:
bootstrap.destroy()
middleBootstrap.destroy()
consumerBootstrap.destroy()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.apachedubbo.v2_7.api;

public interface MiddleService {
String hello(String hello);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.apachedubbo.v2_7.impl;

import io.opentelemetry.instrumentation.apachedubbo.v2_7.api.MiddleService;
import org.apache.dubbo.rpc.service.GenericService;

public class MiddleServiceImpl implements MiddleService {

private final GenericService genericService;

public MiddleServiceImpl(GenericService genericService) {
this.genericService = genericService;
}

@Override
public String hello(String hello) {
return genericService
.$invoke("hello", new String[] {String.class.getName()}, new Object[] {hello})
.toString();
}
}

0 comments on commit 9e61e4a

Please sign in to comment.