diff --git a/.github/workflows/plugins-test.yaml b/.github/workflows/plugins-test.yaml index 83cbdb232ae7eabcbf3b7bf17b4f080814471e0d..884c50974502914b2ba902d9f37fcb1c33107d9d 100644 --- a/.github/workflows/plugins-test.yaml +++ b/.github/workflows/plugins-test.yaml @@ -149,6 +149,8 @@ jobs: run: bash test/plugin/run.sh customize-scenario - name: Run canal 1.0.24-1.1.2 (5) run: bash test/plugin/run.sh canal-scenario + - name: Run Feign_Canal_Pulsar 2.2.0-2.4.1 (7) + run: bash test/plugin/run.sh pulsar-scenario Hystrix_SofaRPC_Spring30x: runs-on: ubuntu-18.04 diff --git a/test/plugin/runner-helper/src/main/java/org/apache/skywalking/plugin/test/helper/DockerComposeRunningGenerator.java b/test/plugin/runner-helper/src/main/java/org/apache/skywalking/plugin/test/helper/DockerComposeRunningGenerator.java index 0d325652b54e892054d553f09684135889cc606b..39574ab771e35c6f9791884b7863ae772dfd415d 100644 --- a/test/plugin/runner-helper/src/main/java/org/apache/skywalking/plugin/test/helper/DockerComposeRunningGenerator.java +++ b/test/plugin/runner-helper/src/main/java/org/apache/skywalking/plugin/test/helper/DockerComposeRunningGenerator.java @@ -102,6 +102,7 @@ public class DockerComposeRunningGenerator extends AbstractRunningGenerator { service.setImageName(imageName); service.setExpose(dependency.getExpose()); service.setLinks(dependency.getDepends_on()); + service.setStartScript(dependency.getStartScript()); service.setHostname(dependency.getHostname()); service.setDepends_on(dependency.getDepends_on()); service.setEntrypoint(dependency.getEntrypoint()); diff --git a/test/plugin/runner-helper/src/main/java/org/apache/skywalking/plugin/test/helper/vo/DependencyComponent.java b/test/plugin/runner-helper/src/main/java/org/apache/skywalking/plugin/test/helper/vo/DependencyComponent.java index 5210f87660270b20f2a50bdbd8ab1eda601abaa9..9a61b6d58734dbffd21a3f735ce568a11ef5cd71 100644 --- a/test/plugin/runner-helper/src/main/java/org/apache/skywalking/plugin/test/helper/vo/DependencyComponent.java +++ b/test/plugin/runner-helper/src/main/java/org/apache/skywalking/plugin/test/helper/vo/DependencyComponent.java @@ -22,6 +22,7 @@ public class DependencyComponent { private String image; private String hostname; private String version; + private List startScript; private List links; private List expose; private List entrypoint; @@ -100,4 +101,12 @@ public class DependencyComponent { public void setHealthcheck(List healthcheck) { this.healthcheck = healthcheck; } + + public List getStartScript() { + return startScript; + } + + public void setStartScript(List startScript) { + this.startScript = startScript; + } } diff --git a/test/plugin/runner-helper/src/main/java/org/apache/skywalking/plugin/test/helper/vo/DockerService.java b/test/plugin/runner-helper/src/main/java/org/apache/skywalking/plugin/test/helper/vo/DockerService.java index dbc4ff9b92bf5163071c81f9e6c290f0da5e6ff2..c0997fd259de560285a8b3ab7c4e0d36fdf26464 100644 --- a/test/plugin/runner-helper/src/main/java/org/apache/skywalking/plugin/test/helper/vo/DockerService.java +++ b/test/plugin/runner-helper/src/main/java/org/apache/skywalking/plugin/test/helper/vo/DockerService.java @@ -22,6 +22,7 @@ public class DockerService { private String name; private String imageName; private String hostname; + private List startScript; private List links; private List expose; private List entrypoint; @@ -100,4 +101,12 @@ public class DockerService { public void setEnvironment(List environment) { this.environment = environment; } + + public List getStartScript() { + return startScript; + } + + public void setStartScript(List startScript) { + this.startScript = startScript; + } } diff --git a/test/plugin/runner-helper/src/main/resources/docker-compose.template b/test/plugin/runner-helper/src/main/resources/docker-compose.template index f73097044d3bf7556ae17f2ef9d3ee006eb45f66..7d68a44aa0a3948401a8c7b94b7d00d1e53355c5 100644 --- a/test/plugin/runner-helper/src/main/resources/docker-compose.template +++ b/test/plugin/runner-helper/src/main/resources/docker-compose.template @@ -76,6 +76,12 @@ services: - ${expose} + <#if service.startScript??> + command: + <#list service.startScript as startScript> + - ${startScript} + + <#if service.depends_on??> depends_on: <#list service.depends_on as item> diff --git a/test/plugin/scenarios/pulsar-scenario/bin/startup.sh b/test/plugin/scenarios/pulsar-scenario/bin/startup.sh new file mode 100644 index 0000000000000000000000000000000000000000..e845a2ea45580f23132f3f05331e24ae218fe5be --- /dev/null +++ b/test/plugin/scenarios/pulsar-scenario/bin/startup.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# +# 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. + +home="$(cd "$(dirname $0)"; pwd)" + +java -Dservice.url=${PULSAR_STANDALONE} -jar ${agent_opts} ${home}/../libs/pulsar-scenario.jar & \ No newline at end of file diff --git a/test/plugin/scenarios/pulsar-scenario/config/expectedData.yaml b/test/plugin/scenarios/pulsar-scenario/config/expectedData.yaml new file mode 100644 index 0000000000000000000000000000000000000000..8adc16d546a8039b96c7d230df789ff4218772c3 --- /dev/null +++ b/test/plugin/scenarios/pulsar-scenario/config/expectedData.yaml @@ -0,0 +1,100 @@ +# 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. + +registryItems: + applications: + - {pulsar-scenario: nq 0} + instances: + - {pulsar-scenario: nq 0} + operationNames: + - pulsar-scenario: [Pulsar/test/Producer, /case/pulsar-case, Pulsar/test/Consumer/test] +segmentItems: +- applicationCode: pulsar-scenario + segmentSize: ge 3 + segments: + - segmentId: not null + spans: + - operationName: Pulsar/test/Producer + operationId: 0 + parentSpanId: 0 + spanId: 1 + spanLayer: MQ + startTime: nq 0 + endTime: nq 0 + componentId: 73 + componentName: '' + isError: false + spanType: Exit + peer: not null + peerId: 0 + tags: + - {key: mq.broker, value: not null} + - {key: mq.topic, value: 'test'} + - operationName: /case/pulsar-case + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 14 + componentName: '' + isError: false + spanType: Entry + peer: '' + peerId: 0 + tags: + - {key: url, value: 'http://localhost:8080/pulsar-scenario/case/pulsar-case'} + - {key: http.method, value: GET} + - segmentId: not null + spans: + - operationName: Pulsar/Producer/Callback + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: MQ + startTime: nq 0 + endTime: nq 0 + componentId: 73 + componentName: '' + isError: false + spanType: Local + peer: '' + peerId: 0 + tags: + - {key: mq.topic, value: 'test'} + refs: + - {parentEndpointId: 0, parentEndpoint: /case/pulsar-case, networkAddressId: 0, entryEndpointId: 0, refType: CrossThread, parentSpanId: 1, parentTraceSegmentId: '${pulsar-scenario[0]}', parentServiceInstanceId: nq 0, networkAddress: '', entryEndpoint: /case/pulsar-case, entryServiceInstanceId: nq 0 } + - segmentId: not null + spans: + - operationName: Pulsar/test/Consumer/test + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: MQ + startTime: nq 0 + endTime: nq 0 + componentId: 74 + componentName: '' + isError: false + spanType: Entry + peer: '' + peerId: 0 + tags: + - {key: mq.broker, value: not null} + - {key: mq.topic, value: 'test'} + refs: + - {parentEndpointId: 0, parentEndpoint: /case/pulsar-case, networkAddressId: 0, entryEndpointId: 0, refType: CrossProcess, parentSpanId: 1, parentTraceSegmentId: '${pulsar-scenario[0]}', parentServiceInstanceId: nq 0, networkAddress: not null, entryEndpoint: /case/pulsar-case, entryServiceInstanceId: nq 0} diff --git a/test/plugin/scenarios/pulsar-scenario/configuration.yml b/test/plugin/scenarios/pulsar-scenario/configuration.yml new file mode 100644 index 0000000000000000000000000000000000000000..e6c0aac4b3b0ad66647233fd5b2b8e429ded7ec6 --- /dev/null +++ b/test/plugin/scenarios/pulsar-scenario/configuration.yml @@ -0,0 +1,32 @@ +# 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. + +type: jvm +entryService: http://localhost:8080/pulsar-scenario/case/pulsar-case +healthCheck: http://localhost:8080/pulsar-scenario/case/healthCheck +startScript: ./bin/startup.sh +framework: pulsar +environment: + - PULSAR_STANDALONE=pulsar-standalone:6650 +depends_on: + - pulsar-standalone +dependencies: + pulsar-standalone: + image: apachepulsar/pulsar:2.4.1 + hostname: pulsar-standalone + startScript: ["bin/pulsar","standalone"] + expose: + - 6650 \ No newline at end of file diff --git a/test/plugin/scenarios/pulsar-scenario/pom.xml b/test/plugin/scenarios/pulsar-scenario/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..c00b7b18b9ddd6f188908e525a6d00223e60d90f --- /dev/null +++ b/test/plugin/scenarios/pulsar-scenario/pom.xml @@ -0,0 +1,139 @@ + + + + + 4.0.0 + + org.apache.skywalking + pulsar-scenario + 5.0.0 + skywalking-pulsar-scenario + + + UTF-8 + 1.8 + 2.4.0 + spring + + 2.6.2 + 4.3.8.RELEASE + 1.5.2.RELEASE + + + + + org.apache.pulsar + pulsar-client + ${test.framework.version} + + + + org.springframework.boot + spring-boot-starter + ${spring-boot-version} + + + org.apache.logging.log4j + log4j-api + ${log4j.version} + + + org.apache.logging.log4j + log4j-core + ${log4j.version} + + + org.apache.logging.log4j + log4j-slf4j-impl + ${log4j.version} + + + org.apache.logging.log4j + log4j-jcl + ${log4j.version} + + + org.springframework.boot + spring-boot-starter-tomcat + ${spring-boot-version} + + + org.springframework.boot + spring-boot-starter-web + ${spring-boot-version} + + + + + pulsar-scenario + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + maven-compiler-plugin + + ${compiler.version} + ${compiler.version} + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-assembly-plugin + + + assemble + package + + single + + + + src/main/assembly/assembly.xml + + ./target/ + + + + + + + + + + spring-snapshots + http://repo.spring.io/snapshot + + + spring-milestones + http://repo.spring.io/milestone + + + diff --git a/test/plugin/scenarios/pulsar-scenario/src/main/assembly/assembly.xml b/test/plugin/scenarios/pulsar-scenario/src/main/assembly/assembly.xml new file mode 100644 index 0000000000000000000000000000000000000000..9c6f49988343ca0f1461bc32e439e38c3ffc0ac2 --- /dev/null +++ b/test/plugin/scenarios/pulsar-scenario/src/main/assembly/assembly.xml @@ -0,0 +1,41 @@ + + + + + zip + + + + + ./bin + 0775 + + + + + + ${project.build.directory}/pulsar-scenario.jar + ./libs + 0775 + + + diff --git a/test/plugin/scenarios/pulsar-scenario/src/main/java/test/org/apache/skywalking/apm/testcase/pulsar/Application.java b/test/plugin/scenarios/pulsar-scenario/src/main/java/test/org/apache/skywalking/apm/testcase/pulsar/Application.java new file mode 100644 index 0000000000000000000000000000000000000000..3262bb3dcae3ac4c231a457e613b8a0b4e5ab677 --- /dev/null +++ b/test/plugin/scenarios/pulsar-scenario/src/main/java/test/org/apache/skywalking/apm/testcase/pulsar/Application.java @@ -0,0 +1,38 @@ +/* + * 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 test.org.apache.skywalking.apm.testcase.pulsar; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; + +@EnableAutoConfiguration +@SpringBootApplication() +@ComponentScan("test.org.apache.skywalking.apm.testcase.pulsar") +public class Application { + + public static void main(String[] args) { + try { + SpringApplication.run(Application.class, args); + } catch (Exception e) { + // Never do this + } + } +} diff --git a/test/plugin/scenarios/pulsar-scenario/src/main/java/test/org/apache/skywalking/apm/testcase/pulsar/controller/CaseController.java b/test/plugin/scenarios/pulsar-scenario/src/main/java/test/org/apache/skywalking/apm/testcase/pulsar/controller/CaseController.java new file mode 100644 index 0000000000000000000000000000000000000000..2f24868d32d0fc61304f5aaff8483819b8ce2567 --- /dev/null +++ b/test/plugin/scenarios/pulsar-scenario/src/main/java/test/org/apache/skywalking/apm/testcase/pulsar/controller/CaseController.java @@ -0,0 +1,136 @@ +/* + * 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 test.org.apache.skywalking.apm.testcase.pulsar.controller; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.pulsar.client.api.Consumer; +import org.apache.pulsar.client.api.Message; +import org.apache.pulsar.client.api.Producer; +import org.apache.pulsar.client.api.PulsarClient; +import org.apache.pulsar.client.api.PulsarClientException; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.PropertySource; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +@RequestMapping("/case") +@PropertySource("classpath:application.properties") +public class CaseController { + + private Logger logger = LogManager.getLogger(CaseController.class); + + private static final String PULSAR_DOMAIN = "pulsar://"; + + @Value("${service.url:127.0.0.1:6650}") + private String serviceUrl; + + @RequestMapping("/pulsar-case") + @ResponseBody + public String pulsarCase() throws PulsarClientException, InterruptedException { + + String topic = "test"; + + PulsarClient pulsarClient = PulsarClient.builder() + .serviceUrl(PULSAR_DOMAIN + serviceUrl) + .build(); + + Producer producer = pulsarClient.newProducer() + .topic(topic) + .create(); + + Consumer consumer = pulsarClient.newConsumer() + .topic(topic) + .subscriptionName("test") + .subscribe(); + + producer.newMessage() + .key("testKey") + .value(Integer.toString(1).getBytes()) + .property("TEST", "TEST") + .send(); + + CountDownLatch latch = new CountDownLatch(1); + + Thread t = new Thread(() -> { + try { + Message msg = consumer.receive(3, TimeUnit.SECONDS); + if (msg != null) { + String propertiesFormat = "key = %s, value = %s"; + StringBuilder builder = new StringBuilder(); + msg.getProperties().forEach((k, v) -> builder.append(String.format(propertiesFormat, k, v)).append(", ")); + logger.info("Received message with messageId = {}, key = {}, value = {}, properties = {}", + msg.getMessageId(), msg.getKey(), new String(msg.getValue()), builder.toString()); + + } + consumer.acknowledge(msg); + } catch (PulsarClientException e) { + logger.error("Receive message error", e); + } finally { + latch.countDown(); + } + }); + + t.start(); + + try { + latch.await(3, TimeUnit.SECONDS); + } catch (InterruptedException e) { + logger.error("Can get message from consumer", e); + t.interrupt(); + throw e; + } + + producer.close(); + consumer.close(); + + return "Success"; + } + + @RequestMapping("/healthCheck") + @ResponseBody + public String healthCheck() throws InterruptedException { + try(PulsarClient pulsarClient = PulsarClient.builder() + .serviceUrl(PULSAR_DOMAIN + serviceUrl) + .build(); + Producer producer = pulsarClient.newProducer() + .topic("healthCheck") + .create()) { + if (producer.isConnected()) { + return "Success"; + } else { + throw new RuntimeException("Health check error, the reason is test producer is disconnected!"); + } + } catch (PulsarClientException e) { + if (e instanceof PulsarClientException.BrokerMetadataException) { + // Broker is not ready, retry here + Thread.sleep(1000); + return healthCheck(); + } else { + throw new RuntimeException(e); + } + } + } +} diff --git a/test/plugin/scenarios/pulsar-scenario/src/main/resources/application.properties b/test/plugin/scenarios/pulsar-scenario/src/main/resources/application.properties new file mode 100644 index 0000000000000000000000000000000000000000..3a564964476032a7566a9cb38e296fe8b3b00caf --- /dev/null +++ b/test/plugin/scenarios/pulsar-scenario/src/main/resources/application.properties @@ -0,0 +1,20 @@ +# +# 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. +# +# + +server.port=8080 +server.contextPath=/pulsar-scenario \ No newline at end of file diff --git a/test/plugin/scenarios/pulsar-scenario/src/main/resources/log4j2.xml b/test/plugin/scenarios/pulsar-scenario/src/main/resources/log4j2.xml new file mode 100644 index 0000000000000000000000000000000000000000..97b22611aa5fd49c1976db36557291eda715b1b7 --- /dev/null +++ b/test/plugin/scenarios/pulsar-scenario/src/main/resources/log4j2.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/plugin/scenarios/pulsar-scenario/support-version.list b/test/plugin/scenarios/pulsar-scenario/support-version.list new file mode 100644 index 0000000000000000000000000000000000000000..36dd69659dc6029ccbccaddc0d74706675571f39 --- /dev/null +++ b/test/plugin/scenarios/pulsar-scenario/support-version.list @@ -0,0 +1,23 @@ +# 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 +# "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. + +2.2.0 +2.2.1 +2.3.0 +2.3.1 +2.3.2 +2.4.0 +2.4.1 \ No newline at end of file