使用 Spring Cloud Dalston,我们构建了一个代理服务,当然也使用了 Zuul。我现在正在尝试添加 Spring Cloud Contract 测试,以从合同遵守的角度验证我们的代理服务是否按预期工作。奇怪的是,我可以发送请求并收到 200 状态码,但预期的响应正文、内容类型标头等为空,结果我的测试失败。
测试使用 Zuul 功能的服务是否有未在 Spring Cloud Contract 文档中指定的其他配置?
使用 Spring Cloud Dalston,我们构建了一个代理服务,当然也使用了 Zuul。我现在正在尝试添加 Spring Cloud Contract 测试,以从合同遵守的角度验证我们的代理服务是否按预期工作。奇怪的是,我可以发送请求并收到 200 状态码,但预期的响应正文、内容类型标头等为空,结果我的测试失败。
测试使用 Zuul 功能的服务是否有未在 Spring Cloud Contract 文档中指定的其他配置?
这里有一个例子https://github.com/spring-cloud/spring-cloud-contract/issues/450
/**
* Abstraction of configuration to test contracts with external microservices which are using a zuul-gateway in between.
*
* When a provider of data only allows communication through a Zuul-Gateway, a special way to ensure valid contracts is needed.
* The Goal is to emulate the Zuul-Interception to be able to use the contracts stored within the providing service.
*
* F.e.: Consumer-Service consumes the Provider-Service, but the provider can not be called directly.
* The Consumer-Service calls an URL with a prefix consisting of the name of the gateway ("gateway") and name of the
* service (in this example "Provider-Service"). For example: http://gateway/provider/path/to/resource.
* The contract provided by Provider-Service holds only a part of the provided URL (here: "/path/to/resource").
* The resolution of "gateway" and "provider" is done within this class.
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = EmbeddedZuulProxy.class,
properties = {"server.port: 8080",
"zuul.routes.provider.path: /provider/**",
"zuul.routes.provider.service-id: provider",
"zuul.routes.provider.url: http://localhost:9090/" //the url of the provider-stub is at port 9090
},
webEnvironment = WebEnvironment.DEFINED_PORT) //defined port is important! Ribbon points to zuul, which then points to the provider-stub
@AutoConfigureMockMvc
@AutoConfigureJsonTesters
//the stub runs on fixed port 9090, so that zuul can point to it
@AutoConfigureStubRunner(ids = "<group-id>:<artifact-id>:+:stubs:9090")
@DirtiesContext
public abstract class ZuulContractBase {
}
/**
* Configuration and Setup of an embedded Zuul-Gateway.
* This way it is possible to use contracts, stored in providing service
*/
@Configuration
@ComponentScan(basePackages = "<path.to.feign.client>") //autowiring feign client
@EnableAutoConfiguration
@EnableZuulProxy
@EnableFeignClients
@RibbonClient(name = "gateway", configuration = SimpleRibbonClientConfiguration.class)
class EmbeddedZuulProxy {
@Bean
RouteLocator routeLocator(DiscoveryClient discoveryClient,
ZuulProperties zuulProperties) {
return new DiscoveryClientRouteLocator("/", discoveryClient, zuulProperties);
}
}
/**
* Ribbon Load balancer with fixed server list for "simple" pointing to localhost,
* which holds the mocked zuul-gateway
*
* f.e. a call with feign would normally look like:
* http://gateway/provider/rest/path/to/your/{url}
* which is mapped to:
* http://localhost:{zuulport}/provider/rest/path/to/your/{url}
*/
@Configuration
class SimpleRibbonClientConfiguration {
@Value("${server.port}")
private Integer zuulPort;
@Bean
public ServerList<Server> ribbonServerList() {
return new StaticServerList<>(new Server("localhost", zuulPort));
}
}