diff --git a/demo/demo-etcd/README.md b/demo/demo-etcd/README.md
new file mode 100644
index 0000000000..046bec6c96
--- /dev/null
+++ b/demo/demo-etcd/README.md
@@ -0,0 +1,5 @@
+# Notice
+
+This integration tests is designed for Etcd registry and configuration. And extra test cases include:
+
+* Test cases related to SpringMVC annotations that demo-springmvc can not cover.
diff --git a/demo/demo-etcd/consumer/pom.xml b/demo/demo-etcd/consumer/pom.xml
new file mode 100644
index 0000000000..cbccb498a4
--- /dev/null
+++ b/demo/demo-etcd/consumer/pom.xml
@@ -0,0 +1,88 @@
+
+
+
+ 4.0.0
+
+
+ org.apache.servicecomb.demo
+ demo-etcd
+ 3.3.0-SNAPSHOT
+
+
+ etcd-consumer
+ Java Chassis::Demo::Etcd::CONSUMER
+ jar
+
+
+
+ org.apache.servicecomb
+ java-chassis-spring-boot-starter-standalone
+
+
+ com.google.protobuf
+ protobuf-java
+ 3.25.3
+ runtime
+
+
+ org.apache.servicecomb
+ registry-etcd
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
+ docker
+
+
+
+ io.fabric8
+ docker-maven-plugin
+
+
+ org.commonjava.maven.plugins
+ directory-maven-plugin
+
+
+ com.github.odavid.maven.plugins
+ mixin-maven-plugin
+
+
+
+ org.apache.servicecomb.demo
+ docker-build-config
+ ${project.version}
+
+
+
+
+
+
+
+
+
diff --git a/demo/demo-etcd/consumer/src/main/java/org/apache/servicecomb/samples/ClientWebsocketController.java b/demo/demo-etcd/consumer/src/main/java/org/apache/servicecomb/samples/ClientWebsocketController.java
new file mode 100644
index 0000000000..f71738a9ed
--- /dev/null
+++ b/demo/demo-etcd/consumer/src/main/java/org/apache/servicecomb/samples/ClientWebsocketController.java
@@ -0,0 +1,52 @@
+/*
+ * 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 org.apache.servicecomb.samples;
+
+import org.apache.servicecomb.core.CoreConst;
+import org.apache.servicecomb.core.annotation.Transport;
+import org.apache.servicecomb.provider.pojo.RpcReference;
+import org.apache.servicecomb.provider.rest.common.RestSchema;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import io.vertx.core.http.ServerWebSocket;
+import io.vertx.core.http.WebSocket;
+
+@RestSchema(schemaId = "ClientWebsocketController")
+@RequestMapping(path = "/ws")
+public class ClientWebsocketController {
+ interface ProviderService {
+ WebSocket websocket();
+ }
+
+ @RpcReference(schemaId = "WebsocketController", microserviceName = "provider")
+ private ProviderService providerService;
+
+ @PostMapping("/websocket")
+ @Transport(name = CoreConst.WEBSOCKET)
+ public void websocket(ServerWebSocket serverWebsocket) {
+ WebSocket providerWebSocket = providerService.websocket();
+ providerWebSocket.closeHandler(v -> serverWebsocket.close());
+ providerWebSocket.textMessageHandler(m -> {
+ serverWebsocket.writeTextMessage(m);
+ });
+ serverWebsocket.textMessageHandler(m -> {
+ providerWebSocket.writeTextMessage(m);
+ });
+ }
+}
diff --git a/demo/demo-etcd/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerController.java b/demo/demo-etcd/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerController.java
new file mode 100644
index 0000000000..e5dd86d9d6
--- /dev/null
+++ b/demo/demo-etcd/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerController.java
@@ -0,0 +1,42 @@
+/*
+ * 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 org.apache.servicecomb.samples;
+
+import org.apache.servicecomb.provider.pojo.RpcReference;
+import org.apache.servicecomb.provider.rest.common.RestSchema;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+@RestSchema(schemaId = "ConsumerController")
+@RequestMapping(path = "/")
+public class ConsumerController {
+ @RpcReference(schemaId = "ProviderController", microserviceName = "provider")
+ private ProviderService providerService;
+
+ // consumer service which delegate the implementation to provider service.
+ @GetMapping("/sayHello")
+ public String sayHello(@RequestParam("name") String name) {
+ return providerService.sayHello(name);
+ }
+
+ @GetMapping("/getConfig")
+ public String getConfig(@RequestParam("key") String key) {
+ return providerService.getConfig(key);
+ }
+}
diff --git a/demo/demo-etcd/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerHeaderParamWithListSchema.java b/demo/demo-etcd/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerHeaderParamWithListSchema.java
new file mode 100644
index 0000000000..f0e894d674
--- /dev/null
+++ b/demo/demo-etcd/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerHeaderParamWithListSchema.java
@@ -0,0 +1,55 @@
+/*
+ * 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 org.apache.servicecomb.samples;
+
+import java.util.List;
+
+import org.apache.servicecomb.demo.api.IHeaderParamWithListSchemaSpringMvc;
+import org.apache.servicecomb.provider.pojo.RpcReference;
+import org.apache.servicecomb.provider.rest.common.RestSchema;
+
+@RestSchema(schemaId = "ConsumerHeaderParamWithListSchema", schemaInterface = IHeaderParamWithListSchemaSpringMvc.class)
+public class ConsumerHeaderParamWithListSchema implements IHeaderParamWithListSchemaSpringMvc {
+ @RpcReference(microserviceName = "provider", schemaId = "HeaderParamWithListSchema")
+ private IHeaderParamWithListSchemaSpringMvc provider;
+
+ @Override
+ public String headerListDefault(List headerList) {
+ return provider.headerListDefault(headerList);
+ }
+
+ @Override
+ public String headerListCSV(List headerList) {
+ return provider.headerListCSV(headerList);
+ }
+
+ @Override
+ public String headerListMULTI(List headerList) {
+ return provider.headerListMULTI(headerList);
+ }
+
+ @Override
+ public String headerListSSV(List headerList) {
+ return provider.headerListSSV(headerList);
+ }
+
+ @Override
+ public String headerListPIPES(List headerList) {
+ return provider.headerListPIPES(headerList);
+ }
+}
diff --git a/demo/demo-etcd/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerReactiveStreamController.java b/demo/demo-etcd/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerReactiveStreamController.java
new file mode 100644
index 0000000000..aa169801cf
--- /dev/null
+++ b/demo/demo-etcd/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerReactiveStreamController.java
@@ -0,0 +1,84 @@
+/*
+ * 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 org.apache.servicecomb.samples;
+
+
+import org.apache.servicecomb.core.CoreConst;
+import org.apache.servicecomb.core.annotation.Transport;
+import org.apache.servicecomb.provider.pojo.RpcReference;
+import org.apache.servicecomb.provider.rest.common.RestSchema;
+import org.reactivestreams.Publisher;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+@RestSchema(schemaId = "ReactiveStreamController")
+@RequestMapping(path = "/")
+public class ConsumerReactiveStreamController {
+ interface ProviderReactiveStreamController {
+ Publisher sseString();
+
+ Publisher sseModel();
+ }
+
+ @RpcReference(microserviceName = "provider", schemaId = "ReactiveStreamController")
+ ProviderReactiveStreamController controller;
+
+ public static class Model {
+ private String name;
+
+ private int age;
+
+ public Model() {
+
+ }
+
+ public Model(String name, int age) {
+ this.name = name;
+ this.age = age;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public Model setAge(int age) {
+ this.age = age;
+ return this;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Model setName(String name) {
+ this.name = name;
+ return this;
+ }
+ }
+
+ @GetMapping("/sseString")
+ @Transport(name = CoreConst.RESTFUL)
+ public Publisher sseString() {
+ return controller.sseString();
+ }
+
+ @GetMapping("/sseModel")
+ @Transport(name = CoreConst.RESTFUL)
+ public Publisher sseModel() {
+ return controller.sseModel();
+ }
+}
diff --git a/demo/demo-etcd/consumer/src/main/java/org/apache/servicecomb/samples/EtcdConsumerApplication.java b/demo/demo-etcd/consumer/src/main/java/org/apache/servicecomb/samples/EtcdConsumerApplication.java
new file mode 100644
index 0000000000..2101e6512f
--- /dev/null
+++ b/demo/demo-etcd/consumer/src/main/java/org/apache/servicecomb/samples/EtcdConsumerApplication.java
@@ -0,0 +1,33 @@
+/*
+ * 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 org.apache.servicecomb.samples;
+
+import org.springframework.boot.WebApplicationType;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+
+@SpringBootApplication
+public class EtcdConsumerApplication {
+ public static void main(String[] args) throws Exception {
+ try {
+ new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(EtcdConsumerApplication.class).run(args);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/demo/demo-etcd/consumer/src/main/java/org/apache/servicecomb/samples/ProviderService.java b/demo/demo-etcd/consumer/src/main/java/org/apache/servicecomb/samples/ProviderService.java
new file mode 100644
index 0000000000..fe71314c9f
--- /dev/null
+++ b/demo/demo-etcd/consumer/src/main/java/org/apache/servicecomb/samples/ProviderService.java
@@ -0,0 +1,24 @@
+/*
+ * 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 org.apache.servicecomb.samples;
+
+public interface ProviderService {
+ String sayHello(String name);
+
+ String getConfig(String key);
+}
diff --git a/demo/demo-etcd/consumer/src/main/resources/application.yml b/demo/demo-etcd/consumer/src/main/resources/application.yml
new file mode 100644
index 0000000000..a63a165189
--- /dev/null
+++ b/demo/demo-etcd/consumer/src/main/resources/application.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.
+## ---------------------------------------------------------------------------
+servicecomb:
+ service:
+ application: demo-etcd
+ version: 0.0.1
+ name: consumer
+ properties:
+ group: red
+ registry:
+ etcd:
+ connectString: http://127.0.0.1:2379
+
+ rest:
+ address: 0.0.0.0:9092?websocketEnabled=true
+ server:
+ websocket-prefix: /ws
diff --git a/demo/demo-etcd/consumer/src/main/resources/log4j2.xml b/demo/demo-etcd/consumer/src/main/resources/log4j2.xml
new file mode 100644
index 0000000000..c51f7ad503
--- /dev/null
+++ b/demo/demo-etcd/consumer/src/main/resources/log4j2.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demo/demo-etcd/gateway/pom.xml b/demo/demo-etcd/gateway/pom.xml
new file mode 100644
index 0000000000..b2eb1e51df
--- /dev/null
+++ b/demo/demo-etcd/gateway/pom.xml
@@ -0,0 +1,91 @@
+
+
+
+ 4.0.0
+
+
+ org.apache.servicecomb.demo
+ demo-etcd
+ 3.3.0-SNAPSHOT
+
+
+ etcd-gateway
+ Java Chassis::Demo::Etcd::GATEWAY
+ jar
+
+
+
+ org.apache.servicecomb
+ java-chassis-spring-boot-starter-standalone
+
+
+ org.apache.servicecomb
+ edge-core
+
+
+ com.google.protobuf
+ protobuf-java
+ 3.25.3
+ runtime
+
+
+ org.apache.servicecomb
+ registry-etcd
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
+ docker
+
+
+
+ io.fabric8
+ docker-maven-plugin
+
+
+ org.commonjava.maven.plugins
+ directory-maven-plugin
+
+
+ com.github.odavid.maven.plugins
+ mixin-maven-plugin
+
+
+
+ org.apache.servicecomb.demo
+ docker-build-config
+ ${project.version}
+
+
+
+
+
+
+
+
+
diff --git a/demo/demo-etcd/gateway/src/main/java/org/apache/servicecomb/samples/GatewayApplication.java b/demo/demo-etcd/gateway/src/main/java/org/apache/servicecomb/samples/GatewayApplication.java
new file mode 100644
index 0000000000..7d58caafd9
--- /dev/null
+++ b/demo/demo-etcd/gateway/src/main/java/org/apache/servicecomb/samples/GatewayApplication.java
@@ -0,0 +1,33 @@
+/*
+ * 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 org.apache.servicecomb.samples;
+
+import org.springframework.boot.WebApplicationType;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+
+@SpringBootApplication
+public class GatewayApplication {
+ public static void main(String[] args) throws Exception {
+ try {
+ new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(GatewayApplication.class).run(args);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/demo/demo-etcd/gateway/src/main/resources/application.yml b/demo/demo-etcd/gateway/src/main/resources/application.yml
new file mode 100644
index 0000000000..f526eb3de7
--- /dev/null
+++ b/demo/demo-etcd/gateway/src/main/resources/application.yml
@@ -0,0 +1,53 @@
+#
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+servicecomb:
+ service:
+ application: demo-etcd
+ version: 0.0.1
+ name: gateway
+ registry:
+ etcd:
+ enabled: true
+ connectString: http://127.0.0.1:2379
+
+ rest:
+ address: 0.0.0.0:9090?websocketEnabled=true
+ server:
+ websocket-prefix: /ws
+
+ http:
+ dispatcher:
+ edge:
+ default:
+ enabled: false
+ url:
+ enabled: true
+ pattern: /(.*)
+ mappings:
+ consumer:
+ prefixSegmentCount: 0
+ path: "/.*"
+ microserviceName: consumer
+ versionRule: 0.0.0+
+ websocket:
+ mappings:
+ consumer:
+ prefixSegmentCount: 0
+ path: "/ws/.*"
+ microserviceName: consumer
+ versionRule: 0.0.0+
diff --git a/demo/demo-etcd/gateway/src/main/resources/log4j2.xml b/demo/demo-etcd/gateway/src/main/resources/log4j2.xml
new file mode 100644
index 0000000000..c51f7ad503
--- /dev/null
+++ b/demo/demo-etcd/gateway/src/main/resources/log4j2.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demo/demo-etcd/pom.xml b/demo/demo-etcd/pom.xml
new file mode 100644
index 0000000000..bda7b06fe8
--- /dev/null
+++ b/demo/demo-etcd/pom.xml
@@ -0,0 +1,61 @@
+
+
+
+
+ 4.0.0
+
+
+ org.apache.servicecomb.demo
+ demo-parent
+ 3.3.0-SNAPSHOT
+
+ demo-etcd
+ Java Chassis::Demo::Etcd
+ pom
+
+
+ org.apache.servicecomb.demo
+ demo-schema
+
+
+ org.apache.servicecomb
+ solution-basic
+
+
+ org.apache.logging.log4j
+ log4j-slf4j-impl
+
+
+ org.apache.logging.log4j
+ log4j-core
+
+
+ org.apache.logging.log4j
+ log4j-api
+
+
+
+
+ provider
+ consumer
+ gateway
+ test-client
+
+
+
diff --git a/demo/demo-etcd/provider/pom.xml b/demo/demo-etcd/provider/pom.xml
new file mode 100644
index 0000000000..c1413de54c
--- /dev/null
+++ b/demo/demo-etcd/provider/pom.xml
@@ -0,0 +1,97 @@
+
+
+
+
+ 4.0.0
+
+
+ org.apache.servicecomb.demo
+ demo-etcd
+ 3.3.0-SNAPSHOT
+
+
+ etcd-provider
+ Java Chassis::Demo::Etcd::PROVIDER
+ jar
+
+
+
+
+
+
+ org.apache.servicecomb
+ java-chassis-spring-boot-starter-standalone
+
+
+ com.google.protobuf
+ protobuf-java
+ 3.25.3
+ runtime
+
+
+ org.apache.servicecomb
+ registry-etcd
+
+
+
+ io.reactivex.rxjava3
+ rxjava
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
+ docker
+
+
+
+ io.fabric8
+ docker-maven-plugin
+
+
+ org.commonjava.maven.plugins
+ directory-maven-plugin
+
+
+ com.github.odavid.maven.plugins
+ mixin-maven-plugin
+
+
+
+ org.apache.servicecomb.demo
+ docker-build-config
+ ${project.version}
+
+
+
+
+
+
+
+
+
diff --git a/demo/demo-etcd/provider/src/main/java/org/apache/servicecomb/samples/EtcdProviderApplication.java b/demo/demo-etcd/provider/src/main/java/org/apache/servicecomb/samples/EtcdProviderApplication.java
new file mode 100644
index 0000000000..388b962dc6
--- /dev/null
+++ b/demo/demo-etcd/provider/src/main/java/org/apache/servicecomb/samples/EtcdProviderApplication.java
@@ -0,0 +1,33 @@
+/*
+ * 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 org.apache.servicecomb.samples;
+
+import org.springframework.boot.WebApplicationType;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+
+@SpringBootApplication
+public class EtcdProviderApplication {
+ public static void main(String[] args) throws Exception {
+ try {
+ new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(EtcdProviderApplication.class).run(args);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/demo/demo-etcd/provider/src/main/java/org/apache/servicecomb/samples/HeaderParamWithListSchema.java b/demo/demo-etcd/provider/src/main/java/org/apache/servicecomb/samples/HeaderParamWithListSchema.java
new file mode 100644
index 0000000000..8a773f91c7
--- /dev/null
+++ b/demo/demo-etcd/provider/src/main/java/org/apache/servicecomb/samples/HeaderParamWithListSchema.java
@@ -0,0 +1,51 @@
+/*
+ * 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 org.apache.servicecomb.samples;
+
+import java.util.List;
+
+import org.apache.servicecomb.demo.api.IHeaderParamWithListSchemaSpringMvc;
+import org.apache.servicecomb.provider.rest.common.RestSchema;
+
+@RestSchema(schemaId = "HeaderParamWithListSchema", schemaInterface = IHeaderParamWithListSchemaSpringMvc.class)
+public class HeaderParamWithListSchema implements IHeaderParamWithListSchemaSpringMvc {
+ @Override
+ public String headerListDefault(List headerList) {
+ return headerList == null ? "null" : headerList.size() + ":" + headerList;
+ }
+
+ @Override
+ public String headerListCSV(List headerList) {
+ return headerList == null ? "null" : headerList.size() + ":" + headerList;
+ }
+
+ @Override
+ public String headerListMULTI(List headerList) {
+ return headerList == null ? "null" : headerList.size() + ":" + headerList;
+ }
+
+ @Override
+ public String headerListSSV(List headerList) {
+ return headerList == null ? "null" : headerList.size() + ":" + headerList;
+ }
+
+ @Override
+ public String headerListPIPES(List headerList) {
+ return headerList == null ? "null" : headerList.size() + ":" + headerList;
+ }
+}
diff --git a/demo/demo-etcd/provider/src/main/java/org/apache/servicecomb/samples/ProviderController.java b/demo/demo-etcd/provider/src/main/java/org/apache/servicecomb/samples/ProviderController.java
new file mode 100644
index 0000000000..8fc333cee1
--- /dev/null
+++ b/demo/demo-etcd/provider/src/main/java/org/apache/servicecomb/samples/ProviderController.java
@@ -0,0 +1,53 @@
+/*
+ * 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 org.apache.servicecomb.samples;
+
+import org.apache.servicecomb.provider.rest.common.RestSchema;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+@RestSchema(schemaId = "ProviderController")
+@RequestMapping(path = "/")
+public class ProviderController implements InitializingBean {
+ private Environment environment;
+
+ @Autowired
+ public void setEnvironment(Environment environment) {
+ this.environment = environment;
+ }
+
+ // a very simple service to echo the request parameter
+ @GetMapping("/sayHello")
+ public String sayHello(@RequestParam("name") String name) {
+// return "Hello " + environment.getProperty("servicecomb.rest.address");
+ return "Hello " + name;
+ }
+
+ @GetMapping("/getConfig")
+ public String getConfig(@RequestParam("key") String key) {
+ return environment.getProperty(key);
+ }
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ }
+}
diff --git a/demo/demo-etcd/provider/src/main/java/org/apache/servicecomb/samples/ReactiveStreamController.java b/demo/demo-etcd/provider/src/main/java/org/apache/servicecomb/samples/ReactiveStreamController.java
new file mode 100644
index 0000000000..8108d15fd4
--- /dev/null
+++ b/demo/demo-etcd/provider/src/main/java/org/apache/servicecomb/samples/ReactiveStreamController.java
@@ -0,0 +1,78 @@
+/*
+ * 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 org.apache.servicecomb.samples;
+
+
+import java.util.concurrent.TimeUnit;
+
+import org.apache.servicecomb.core.CoreConst;
+import org.apache.servicecomb.core.annotation.Transport;
+import org.apache.servicecomb.provider.rest.common.RestSchema;
+import org.reactivestreams.Publisher;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import io.reactivex.rxjava3.core.Flowable;
+
+@RestSchema(schemaId = "ReactiveStreamController")
+@RequestMapping(path = "/")
+@Transport(name = CoreConst.RESTFUL)
+public class ReactiveStreamController {
+ public static class Model {
+ private String name;
+
+ private int age;
+
+ public Model() {
+
+ }
+
+ public Model(String name, int age) {
+ this.name = name;
+ this.age = age;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public Model setAge(int age) {
+ this.age = age;
+ return this;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Model setName(String name) {
+ this.name = name;
+ return this;
+ }
+ }
+
+ @GetMapping("/sseString")
+ public Publisher sseString() {
+ return Flowable.fromArray("a", "b", "c");
+ }
+
+ @GetMapping("/sseModel")
+ public Publisher sseModel() {
+ return Flowable.intervalRange(0, 5, 0, 1, TimeUnit.SECONDS)
+ .map(item -> new Model("jack", item.intValue()));
+ }
+}
diff --git a/demo/demo-etcd/provider/src/main/java/org/apache/servicecomb/samples/WebsocketController.java b/demo/demo-etcd/provider/src/main/java/org/apache/servicecomb/samples/WebsocketController.java
new file mode 100644
index 0000000000..5f4f9719ca
--- /dev/null
+++ b/demo/demo-etcd/provider/src/main/java/org/apache/servicecomb/samples/WebsocketController.java
@@ -0,0 +1,67 @@
+/*
+ * 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 org.apache.servicecomb.samples;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.servicecomb.core.CoreConst;
+import org.apache.servicecomb.core.annotation.Transport;
+import org.apache.servicecomb.provider.rest.common.RestSchema;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import io.vertx.core.http.ServerWebSocket;
+
+@RestSchema(schemaId = "WebsocketController")
+@RequestMapping(path = "/ws")
+public class WebsocketController {
+ @PostMapping("/websocket")
+ @Transport(name = CoreConst.WEBSOCKET)
+ public void websocket(ServerWebSocket serverWebsocket) {
+ // Client may have not registered message handler, and messages sent may get lost.
+ // So we sleep for a while to send message.
+ AtomicInteger receiveCount = new AtomicInteger(0);
+ serverWebsocket.textMessageHandler(s -> {
+ receiveCount.getAndIncrement();
+ });
+ serverWebsocket.closeHandler((v) -> System.out.println("closed"));
+
+ new Thread(() -> {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ serverWebsocket.writeTextMessage("hello", r -> {
+ });
+
+ for (int i = 0; i < 5; i++) {
+ serverWebsocket.writeTextMessage("hello " + i, r -> {
+ });
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ serverWebsocket.writeTextMessage("total " + receiveCount.get());
+ serverWebsocket.close();
+ }).start();
+ }
+}
diff --git a/demo/demo-etcd/provider/src/main/resources/application.yml b/demo/demo-etcd/provider/src/main/resources/application.yml
new file mode 100644
index 0000000000..75b6dee9ea
--- /dev/null
+++ b/demo/demo-etcd/provider/src/main/resources/application.yml
@@ -0,0 +1,44 @@
+#
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+# spring boot configurations
+servicecomb:
+ service:
+ application: demo-etcd
+ version: 0.0.1
+ name: provider
+ properties:
+ group: green
+ registry:
+ etcd:
+ connectString: http://127.0.0.1:2379
+
+ rest:
+ address: 0.0.0.0:9094?websocketEnabled=true
+ server:
+ websocket-prefix: /ws
+
+ cors:
+ enabled: true
+ origin: "*"
+ allowCredentials: false
+ allowedMethod: "*"
+ maxAge: 3600
+
+key1: 1
+key2: 3
+key3: 5
diff --git a/demo/demo-etcd/provider/src/main/resources/log4j2.xml b/demo/demo-etcd/provider/src/main/resources/log4j2.xml
new file mode 100644
index 0000000000..c51f7ad503
--- /dev/null
+++ b/demo/demo-etcd/provider/src/main/resources/log4j2.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demo/demo-etcd/test-client/pom.xml b/demo/demo-etcd/test-client/pom.xml
new file mode 100644
index 0000000000..0c050adcb8
--- /dev/null
+++ b/demo/demo-etcd/test-client/pom.xml
@@ -0,0 +1,213 @@
+
+
+
+
+ 4.0.0
+
+
+ org.apache.servicecomb.demo
+ demo-etcd
+ 3.3.0-SNAPSHOT
+
+
+ etcd-test-client
+ Java Chassis::Demo::Etcd::TEST-CLIENT
+ jar
+
+
+
+
+
+
+ org.apache.servicecomb
+ java-chassis-spring-boot-starter-standalone
+
+
+ org.apache.servicecomb.demo
+ demo-schema
+
+
+ org.apache.servicecomb
+ registry-local
+
+
+
+
+
+ docker
+
+
+
+
+ io.fabric8
+ docker-maven-plugin
+
+
+
+ bitnami/etcd:latest
+ etcd
+
+ alias
+
+ etcdserver
+
+
+ 2379
+
+
+
+
+
+ etcd.port:2379
+
+
+ yes
+
+
+
+
+ etcd-provider:${project.version}
+ etcd-provider
+
+ alias
+
+
+ -Dservicecomb.registry.etcd.connectString=http://etcd:2379
+ -Dservicecomb.config.etcd.connectString=http://etcd:2379
+
+ /maven/maven/etcd-provider-${project.version}.jar
+
+
+ etcd:etcd
+
+
+ ServiceComb is ready
+
+
+ 9094
+
+
+
+
+
+ 9094:9094
+
+
+
+
+ etcd-consumer:${project.version}
+ etcd-consumer
+
+ alias
+
+
+ -Dservicecomb.registry.etcd.connectString=http://etcd:2379
+
+ /maven/maven/etcd-consumer-${project.version}.jar
+
+
+ etcd:etcd
+
+
+ ServiceComb is ready
+
+
+ 9092
+
+
+
+
+
+ 9092:9092
+
+
+
+
+ etcd-gateway:${project.version}
+ etcd-gateway
+
+ alias
+
+
+ -Dservicecomb.registry.etcd.connectString=http://etcd:2379
+
+ /maven/maven/etcd-gateway-${project.version}.jar
+
+
+ etcd:etcd
+
+
+ ServiceComb is ready
+
+
+ 9090
+
+
+
+
+
+ 9090:9090
+
+
+
+
+
+
+
+ start
+ pre-integration-test
+
+ start
+
+
+
+ stop
+ post-integration-test
+
+ stop
+
+
+
+
+
+
+
+
+
+ io.fabric8
+ docker-maven-plugin
+
+
+ com.github.odavid.maven.plugins
+ mixin-maven-plugin
+
+
+
+ org.apache.servicecomb.demo
+ docker-run-config
+ ${project.version}
+
+
+
+
+
+
+
+
+
diff --git a/demo/demo-etcd/test-client/src/main/java/org/apache/servicecomb/samples/Config.java b/demo/demo-etcd/test-client/src/main/java/org/apache/servicecomb/samples/Config.java
new file mode 100644
index 0000000000..2e9105cdd4
--- /dev/null
+++ b/demo/demo-etcd/test-client/src/main/java/org/apache/servicecomb/samples/Config.java
@@ -0,0 +1,22 @@
+/*
+ * 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 org.apache.servicecomb.samples;
+
+public interface Config {
+ String GATEWAY_URL = "http://localhost:9090";
+}
diff --git a/demo/demo-etcd/test-client/src/main/java/org/apache/servicecomb/samples/HeaderParamWithListSchemaIT.java b/demo/demo-etcd/test-client/src/main/java/org/apache/servicecomb/samples/HeaderParamWithListSchemaIT.java
new file mode 100644
index 0000000000..1b129acc2c
--- /dev/null
+++ b/demo/demo-etcd/test-client/src/main/java/org/apache/servicecomb/samples/HeaderParamWithListSchemaIT.java
@@ -0,0 +1,98 @@
+/*
+ * 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 org.apache.servicecomb.samples;
+
+import org.apache.servicecomb.demo.CategorizedTestCase;
+import org.apache.servicecomb.demo.TestMgr;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.stereotype.Component;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.client.RestOperations;
+import org.springframework.web.client.RestTemplate;
+
+@Component
+public class HeaderParamWithListSchemaIT implements CategorizedTestCase {
+ RestOperations template = new RestTemplate();
+
+ @Override
+ public void testRestTransport() throws Exception {
+ testHeaderListDefault();
+ testHeaderListMulti();
+ testHeaderListCSV();
+ testHeaderListSSV();
+ testHeaderListPipes();
+ }
+
+ // default to multi
+ private void testHeaderListDefault() {
+ MultiValueMap headers = new HttpHeaders();
+ headers.add("headerList", "a");
+ headers.add("headerList", "b");
+ headers.add("headerList", "c");
+ HttpEntity entity = new HttpEntity<>(headers);
+ String result = template
+ .exchange(Config.GATEWAY_URL + "/headerList/headerListDefault", HttpMethod.GET, entity, String.class).getBody();
+ TestMgr.check("3:[a, b, c]", result);
+ }
+
+ private void testHeaderListPipes() {
+ MultiValueMap headers = new HttpHeaders();
+ headers.add("headerList", "a|b|c");
+ HttpEntity entity = new HttpEntity<>(headers);
+ String result = template
+ .exchange(Config.GATEWAY_URL + "/headerList/headerListPIPES", HttpMethod.GET, entity, String.class).getBody();
+ TestMgr.check("3:[a, b, c]", result);
+ }
+
+ private void testHeaderListSSV() {
+ MultiValueMap headers = new HttpHeaders();
+ headers.add("headerList", "a b c");
+ HttpEntity entity = new HttpEntity<>(headers);
+ String result = template
+ .exchange(Config.GATEWAY_URL + "/headerList/headerListSSV", HttpMethod.GET, entity, String.class).getBody();
+ TestMgr.check("3:[a, b, c]", result);
+ }
+
+ private void testHeaderListCSV() {
+ MultiValueMap headers = new HttpHeaders();
+ headers.add("headerList", "a,b,c");
+ HttpEntity entity = new HttpEntity<>(headers);
+ String result = template
+ .exchange(Config.GATEWAY_URL + "/headerList/headerListCSV", HttpMethod.GET, entity, String.class).getBody();
+ TestMgr.check("3:[a, b, c]", result);
+
+ headers.add("headerList", "a, b, c");
+ entity = new HttpEntity<>(headers);
+ result = template
+ .exchange(Config.GATEWAY_URL + "/headerList/headerListCSV", HttpMethod.GET, entity, String.class).getBody();
+ TestMgr.check("3:[a, b, c]", result);
+ }
+
+ private void testHeaderListMulti() {
+ MultiValueMap headers = new HttpHeaders();
+ headers.add("headerList", "a");
+ headers.add("headerList", "b");
+ headers.add("headerList", "c");
+ HttpEntity entity = new HttpEntity<>(headers);
+ String result = template
+ .exchange(Config.GATEWAY_URL + "/headerList/headerListMULTI", HttpMethod.GET, entity, String.class).getBody();
+ TestMgr.check("3:[a, b, c]", result);
+ }
+}
diff --git a/demo/demo-etcd/test-client/src/main/java/org/apache/servicecomb/samples/HelloWorldIT.java b/demo/demo-etcd/test-client/src/main/java/org/apache/servicecomb/samples/HelloWorldIT.java
new file mode 100644
index 0000000000..97e883fb45
--- /dev/null
+++ b/demo/demo-etcd/test-client/src/main/java/org/apache/servicecomb/samples/HelloWorldIT.java
@@ -0,0 +1,68 @@
+/*
+ * 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 org.apache.servicecomb.samples;
+
+import org.apache.servicecomb.demo.CategorizedTestCase;
+import org.apache.servicecomb.demo.TestMgr;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Component;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.client.RestOperations;
+import org.springframework.web.client.RestTemplate;
+
+@Component
+public class HelloWorldIT implements CategorizedTestCase {
+ RestOperations template = new RestTemplate();
+
+ @Override
+ public void testRestTransport() throws Exception {
+ testHelloWorld();
+ testGetConfig();
+ }
+
+ private void testGetConfig() {
+ String result = template
+ .getForObject(Config.GATEWAY_URL + "/getConfig?key=key1", String.class);
+ TestMgr.check("1", result);
+ result = template
+ .getForObject(Config.GATEWAY_URL + "/getConfig?key=key2", String.class);
+ TestMgr.check("3", result);
+ result = template
+ .getForObject(Config.GATEWAY_URL + "/getConfig?key=key3", String.class);
+ TestMgr.check("5", result);
+ }
+
+ private void testHelloWorld() {
+ String result = template
+ .getForObject(Config.GATEWAY_URL + "/sayHello?name=World", String.class);
+ TestMgr.check("Hello World", result);
+
+ // test trace id added
+ MultiValueMap headers = new HttpHeaders();
+ headers.add("X-B3-TraceId", "81de2eb7691c2bbb");
+ HttpEntity