http://bit.ly/greach-micro
Jeff Beck
TechLead at ReachLocal
Over the course of acquisitions and expanding the products we have come out with a polyglot architecture including Java, Groovy, Ruby, PHP, Node, and PERL. In order to take advantage of our existing talent and software, we have started down the micro-service path.
Acts as the source of truth about subscriptions.
All our Grails micro services start out the same way.
We add scenarios, using cucumber allows us to keep our testing more DRY.
Scenario: Get nonexistent subscription by ID Given I am a valid api client And A valid subscription ID which does not match any subscription When I request a subscription by ID Then I get a 404 response
Scenario: Get existing subscription by ID Given I am a valid api client And A valid subscription ID which matches a subscription When I request a subscription by ID Then I get a 200 response
Given(~'^A valid subscription ID which matches a subscription$') { -> //Have a valid subscription which exposes an ID } Given(~'^A valid subscription ID which does not match any subscription$') { -> //Have an ID which is valid but no matching subscription } When(~'^I request a subscription by ID$') { -> //Do actual request } Then(~'^I get a (\\d+) response$') { int statusCode -> if (response.statusCode != statusCode) { println response.asString() } assert response.statusCode == statusCode }
To support reusable monitoring we expose a health check in a known way that attempts to be both human readable and programmatically useful.
Status Code 200
{ "dependencies": { "database":"OK", "file-access":"WARN" } }
Via a Grails plugin we share
We do server to server authentication with a token. So checking the Authorization header the plugin authenicates a client.
We use an internal Nexus repo, and release plugins to that.
We use puppet to automate our server setup. Using classes we share default setup for a Tomcat server.
class apps_subscription_api ( $heap_min = '256m', $heap_max = '1024m', $permgen_size = '1024m' ){ class { 'standard_tomcat7_web_server': minimum_heap => $heap_min, maximum_heap => $heap_max, permgen_size => $permgen_size, } include apps_subscription_api::config base::nagios::hostgroup { "rsubscription_api_servers": } base::nagios::hostparam { "_healthuri": value => '/health' } }
class apps_subscription_api::config { file { '/rl/path/configs/subscription-config.groovy': ensure => present, owner => tomcat7, group => tomcat7, mode => '0400', content => template('apps_subscription_api/subscription-config.groovy.erb'), require => File['/rl/path/configs'] } }
We automate our deployments via custom bash scripts kicked off by bamboo deployments.
Our spring integration apps tend to need the same filters and transformers for our Events. Grails apps are not the only users of these components.