Spencer Gibb,
@spencerbgibb,
sgibb@pivotal.io
Dave Syer,
@david_syer,
dsyer@pivotal.io
With thanks to @littleidea
Your app won’t always work first time. How to diagnose the problem?
cf logs
)spring-cloud-commons
: useful abstractions DiscoveryClient
, LoadBalancer
, @EnableServiceDiscovery
spring-cloud-netflix
: Eureka and Ribbonspring-cloud-consul
: Hashicorp Consulspring-cloud-zookeeper
: Zookeeperspring-cloud-cloudfoundry
: cloud controller APIspring-cloud-lattice
: receptor (diego controller) APIConnectors (using service name)
IRule
: Load-balancing algorithm (round-robin, random, etc…)
ServerList
: Where to get the list of servers to load-balance.
ConfigurationBasedServerList
:
ribbon.<clientname>.listOfServers
propertyDiscoveryEnabledNIWSServerList
: via eurekaConsulServerList
: via hashicorp consulZookeeperServerList
: …ServerListFilter
: filters list of servers.
@RibbonClients
@RibbonClient
annotations.@RibbonClient
: allows configuration for a named ribbon client.@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MyTests.Application.class)
@WebIntegrationTest(randomPort = true)
public class MyTests { /*...*/
@Configuration
@RibbonClient(name = "localapp",
configuration = LocalRibbonClientConfig.class)
protected static class Application { /*...*/ }
@Configuration
static class LocalRibbonClientConfig {
@Value("${local.server.port}")
private int port = 0;
@Bean
public ServerList<Server> ribbonServerList() {
return new StaticServerList<>(new Server("localhost", this.port));
}
}
}
High level:
Example tools/approaches:
Create Wiremock stubs using tests or dsl
Generates a MockMVC test and a Wiremock stub
import io.codearte.accurest.dsl.GroovyDsl
GroovyDsl groovyDsl = GroovyDsl.make {
request {
method 'GET'
url '/foo'
}
response {
status 200
headers {
header 'Content-Type' : 'application/json;charset=UTF-8'
}
body '''{ "value" : 42 }'''
}
}
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
.apply(documentationConfiguration()
.snippets().withDefaults(curlRequest(),
httpRequest(),
httpResponse(),
new WiremockStubSnippet()))
.build();
}
@Test
public void foo() {
this.mockMvc.perform(get("/foo")
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(document("foo"));
}
{
"request": {
"method": "GET",
"url": "/foo"
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json;charset=UTF-8"
},
"body": "{\"value\":42}"
}
}
@Controller
public class StubFleetLocationServiceApplication {
@RequestMapping("/locations")
public String home() {
return "forward:/stubs/locations.json";
}
...
}
Nice side effect: mock MVC and restdocs for tests and docs can be used to verify real service contract
application.yml
Stubrunner uses list of dependencies
App monitors its classpath and restarts when changes detected:
Browser plugin automatically refreshes views:
Hot reloading of “local” application code deployed on Cloud Foundry / Lattice
How does new code enter a build pipeline and get promoted to production?
How to wire up your application code to required middleware, and make the same code run in all environments?
/