Jan-2015
Why Play is great for RAD
A pattern for rapid deployment via Play amp AWS
Seamless Remote testing via Play
Hot code reloading
Swagger plugin
Junit built-in
Great for most environments Dev Integration QA
Very nice for production Just a bit slower to launch
Less secure
But can be optimized to both
The Concept ldquoStatelessrdquo machine image
No code no credentials no data
ldquoDependency Injectionrdquo of the environment parameters
Init script
Run app
Ideal for AWS - Play - Git AMI
User Data
Download code
Play
gitUrl httpsxxxsoftimizexxxgitassemblacomxxxgit
gitBranchmaster
gitTagV_10
keepExistingSourcestrue
projectDirldquoxxx-cloud-serviceldquo projectNameldquoxxxService
playCommand start -Dhttpport=80
Possible on Auto Scaling as well
USER_DATA=`wget -qO- http169254169254latestuser-data`
GIT_BRANCH=`echo $USER_DATA | jq gitBranch | sed -e s^ -e s$`
git remote add -t $GIT_BRANCH -f origin $GIT_URL
Any branchtag Dev INT QA Prod
Production robustness Not depending on repo availability
UpgradeDowngrade Just change the user data and reboot
adminPasspassword
environmentNameTest
dbProperties
shouldWorkWithInstanceRole true
accessKeyLocalDB
secretKeyLocalDB
rlRegionus-east-1
maxRetries4
failureMaxIntervalInMillis5000
Per-environment instance permissions
Per-environment dependent resources (DB storage etc)
import playtestHelpers
public class TestHelper extends Helpers
public void testMethod()
Result result =
callAction(xxxroutesrefXxxControlleryyyMethod()
fakeRequest()WithWhatever())
assertThat(status(result))isEqualTo(OK)
Great for local integrationbehavior testing but
What about real clients not running on the same machine as the server Different time zones clocks
Different locales and string formats
import playtestHelpers
public class TestHelper extends Helpers
public void testMethod()
Result result =
callApiAction(xxxroutesrefXxxControlleryyyMethod()
fakeRequest()WithWhatever() relativeURL reqParams)
assertThat(status(result))isEqualTo(OK)
Play test ndashDTestServerRemoteAddress=httplthostgtltportgtbaseURL
import playlibsWSWSRequestHolder
public Result callApiAction(HandlerRef ref FakeRequest
requestString parametersString methodName)
if (shouldTestRemote) return callAction(refrequest)
long timeoutAllowed=20000
String contentType=applicationx-www-form-urlencoded
Response response=new
WSRequestHolder(serverUrl+methodName)setContentType(contentType
)post(parameters)get(timeoutAllowed)
return playmvcResultsstatus(responsegetStatus()
responseasByteArray())
ldquoThe RampD team you wish to haverdquo Senior developers
Junior developers
Students
Guy Vinogradguysoftimizecoil
Guy Vinogradguysoftimizecoil
Why Play is great for RAD
A pattern for rapid deployment via Play amp AWS
Seamless Remote testing via Play
Hot code reloading
Swagger plugin
Junit built-in
Great for most environments Dev Integration QA
Very nice for production Just a bit slower to launch
Less secure
But can be optimized to both
The Concept ldquoStatelessrdquo machine image
No code no credentials no data
ldquoDependency Injectionrdquo of the environment parameters
Init script
Run app
Ideal for AWS - Play - Git AMI
User Data
Download code
Play
gitUrl httpsxxxsoftimizexxxgitassemblacomxxxgit
gitBranchmaster
gitTagV_10
keepExistingSourcestrue
projectDirldquoxxx-cloud-serviceldquo projectNameldquoxxxService
playCommand start -Dhttpport=80
Possible on Auto Scaling as well
USER_DATA=`wget -qO- http169254169254latestuser-data`
GIT_BRANCH=`echo $USER_DATA | jq gitBranch | sed -e s^ -e s$`
git remote add -t $GIT_BRANCH -f origin $GIT_URL
Any branchtag Dev INT QA Prod
Production robustness Not depending on repo availability
UpgradeDowngrade Just change the user data and reboot
adminPasspassword
environmentNameTest
dbProperties
shouldWorkWithInstanceRole true
accessKeyLocalDB
secretKeyLocalDB
rlRegionus-east-1
maxRetries4
failureMaxIntervalInMillis5000
Per-environment instance permissions
Per-environment dependent resources (DB storage etc)
import playtestHelpers
public class TestHelper extends Helpers
public void testMethod()
Result result =
callAction(xxxroutesrefXxxControlleryyyMethod()
fakeRequest()WithWhatever())
assertThat(status(result))isEqualTo(OK)
Great for local integrationbehavior testing but
What about real clients not running on the same machine as the server Different time zones clocks
Different locales and string formats
import playtestHelpers
public class TestHelper extends Helpers
public void testMethod()
Result result =
callApiAction(xxxroutesrefXxxControlleryyyMethod()
fakeRequest()WithWhatever() relativeURL reqParams)
assertThat(status(result))isEqualTo(OK)
Play test ndashDTestServerRemoteAddress=httplthostgtltportgtbaseURL
import playlibsWSWSRequestHolder
public Result callApiAction(HandlerRef ref FakeRequest
requestString parametersString methodName)
if (shouldTestRemote) return callAction(refrequest)
long timeoutAllowed=20000
String contentType=applicationx-www-form-urlencoded
Response response=new
WSRequestHolder(serverUrl+methodName)setContentType(contentType
)post(parameters)get(timeoutAllowed)
return playmvcResultsstatus(responsegetStatus()
responseasByteArray())
ldquoThe RampD team you wish to haverdquo Senior developers
Junior developers
Students
Guy Vinogradguysoftimizecoil
Guy Vinogradguysoftimizecoil
Hot code reloading
Swagger plugin
Junit built-in
Great for most environments Dev Integration QA
Very nice for production Just a bit slower to launch
Less secure
But can be optimized to both
The Concept ldquoStatelessrdquo machine image
No code no credentials no data
ldquoDependency Injectionrdquo of the environment parameters
Init script
Run app
Ideal for AWS - Play - Git AMI
User Data
Download code
Play
gitUrl httpsxxxsoftimizexxxgitassemblacomxxxgit
gitBranchmaster
gitTagV_10
keepExistingSourcestrue
projectDirldquoxxx-cloud-serviceldquo projectNameldquoxxxService
playCommand start -Dhttpport=80
Possible on Auto Scaling as well
USER_DATA=`wget -qO- http169254169254latestuser-data`
GIT_BRANCH=`echo $USER_DATA | jq gitBranch | sed -e s^ -e s$`
git remote add -t $GIT_BRANCH -f origin $GIT_URL
Any branchtag Dev INT QA Prod
Production robustness Not depending on repo availability
UpgradeDowngrade Just change the user data and reboot
adminPasspassword
environmentNameTest
dbProperties
shouldWorkWithInstanceRole true
accessKeyLocalDB
secretKeyLocalDB
rlRegionus-east-1
maxRetries4
failureMaxIntervalInMillis5000
Per-environment instance permissions
Per-environment dependent resources (DB storage etc)
import playtestHelpers
public class TestHelper extends Helpers
public void testMethod()
Result result =
callAction(xxxroutesrefXxxControlleryyyMethod()
fakeRequest()WithWhatever())
assertThat(status(result))isEqualTo(OK)
Great for local integrationbehavior testing but
What about real clients not running on the same machine as the server Different time zones clocks
Different locales and string formats
import playtestHelpers
public class TestHelper extends Helpers
public void testMethod()
Result result =
callApiAction(xxxroutesrefXxxControlleryyyMethod()
fakeRequest()WithWhatever() relativeURL reqParams)
assertThat(status(result))isEqualTo(OK)
Play test ndashDTestServerRemoteAddress=httplthostgtltportgtbaseURL
import playlibsWSWSRequestHolder
public Result callApiAction(HandlerRef ref FakeRequest
requestString parametersString methodName)
if (shouldTestRemote) return callAction(refrequest)
long timeoutAllowed=20000
String contentType=applicationx-www-form-urlencoded
Response response=new
WSRequestHolder(serverUrl+methodName)setContentType(contentType
)post(parameters)get(timeoutAllowed)
return playmvcResultsstatus(responsegetStatus()
responseasByteArray())
ldquoThe RampD team you wish to haverdquo Senior developers
Junior developers
Students
Guy Vinogradguysoftimizecoil
Guy Vinogradguysoftimizecoil
Great for most environments Dev Integration QA
Very nice for production Just a bit slower to launch
Less secure
But can be optimized to both
The Concept ldquoStatelessrdquo machine image
No code no credentials no data
ldquoDependency Injectionrdquo of the environment parameters
Init script
Run app
Ideal for AWS - Play - Git AMI
User Data
Download code
Play
gitUrl httpsxxxsoftimizexxxgitassemblacomxxxgit
gitBranchmaster
gitTagV_10
keepExistingSourcestrue
projectDirldquoxxx-cloud-serviceldquo projectNameldquoxxxService
playCommand start -Dhttpport=80
Possible on Auto Scaling as well
USER_DATA=`wget -qO- http169254169254latestuser-data`
GIT_BRANCH=`echo $USER_DATA | jq gitBranch | sed -e s^ -e s$`
git remote add -t $GIT_BRANCH -f origin $GIT_URL
Any branchtag Dev INT QA Prod
Production robustness Not depending on repo availability
UpgradeDowngrade Just change the user data and reboot
adminPasspassword
environmentNameTest
dbProperties
shouldWorkWithInstanceRole true
accessKeyLocalDB
secretKeyLocalDB
rlRegionus-east-1
maxRetries4
failureMaxIntervalInMillis5000
Per-environment instance permissions
Per-environment dependent resources (DB storage etc)
import playtestHelpers
public class TestHelper extends Helpers
public void testMethod()
Result result =
callAction(xxxroutesrefXxxControlleryyyMethod()
fakeRequest()WithWhatever())
assertThat(status(result))isEqualTo(OK)
Great for local integrationbehavior testing but
What about real clients not running on the same machine as the server Different time zones clocks
Different locales and string formats
import playtestHelpers
public class TestHelper extends Helpers
public void testMethod()
Result result =
callApiAction(xxxroutesrefXxxControlleryyyMethod()
fakeRequest()WithWhatever() relativeURL reqParams)
assertThat(status(result))isEqualTo(OK)
Play test ndashDTestServerRemoteAddress=httplthostgtltportgtbaseURL
import playlibsWSWSRequestHolder
public Result callApiAction(HandlerRef ref FakeRequest
requestString parametersString methodName)
if (shouldTestRemote) return callAction(refrequest)
long timeoutAllowed=20000
String contentType=applicationx-www-form-urlencoded
Response response=new
WSRequestHolder(serverUrl+methodName)setContentType(contentType
)post(parameters)get(timeoutAllowed)
return playmvcResultsstatus(responsegetStatus()
responseasByteArray())
ldquoThe RampD team you wish to haverdquo Senior developers
Junior developers
Students
Guy Vinogradguysoftimizecoil
Guy Vinogradguysoftimizecoil
The Concept ldquoStatelessrdquo machine image
No code no credentials no data
ldquoDependency Injectionrdquo of the environment parameters
Init script
Run app
Ideal for AWS - Play - Git AMI
User Data
Download code
Play
gitUrl httpsxxxsoftimizexxxgitassemblacomxxxgit
gitBranchmaster
gitTagV_10
keepExistingSourcestrue
projectDirldquoxxx-cloud-serviceldquo projectNameldquoxxxService
playCommand start -Dhttpport=80
Possible on Auto Scaling as well
USER_DATA=`wget -qO- http169254169254latestuser-data`
GIT_BRANCH=`echo $USER_DATA | jq gitBranch | sed -e s^ -e s$`
git remote add -t $GIT_BRANCH -f origin $GIT_URL
Any branchtag Dev INT QA Prod
Production robustness Not depending on repo availability
UpgradeDowngrade Just change the user data and reboot
adminPasspassword
environmentNameTest
dbProperties
shouldWorkWithInstanceRole true
accessKeyLocalDB
secretKeyLocalDB
rlRegionus-east-1
maxRetries4
failureMaxIntervalInMillis5000
Per-environment instance permissions
Per-environment dependent resources (DB storage etc)
import playtestHelpers
public class TestHelper extends Helpers
public void testMethod()
Result result =
callAction(xxxroutesrefXxxControlleryyyMethod()
fakeRequest()WithWhatever())
assertThat(status(result))isEqualTo(OK)
Great for local integrationbehavior testing but
What about real clients not running on the same machine as the server Different time zones clocks
Different locales and string formats
import playtestHelpers
public class TestHelper extends Helpers
public void testMethod()
Result result =
callApiAction(xxxroutesrefXxxControlleryyyMethod()
fakeRequest()WithWhatever() relativeURL reqParams)
assertThat(status(result))isEqualTo(OK)
Play test ndashDTestServerRemoteAddress=httplthostgtltportgtbaseURL
import playlibsWSWSRequestHolder
public Result callApiAction(HandlerRef ref FakeRequest
requestString parametersString methodName)
if (shouldTestRemote) return callAction(refrequest)
long timeoutAllowed=20000
String contentType=applicationx-www-form-urlencoded
Response response=new
WSRequestHolder(serverUrl+methodName)setContentType(contentType
)post(parameters)get(timeoutAllowed)
return playmvcResultsstatus(responsegetStatus()
responseasByteArray())
ldquoThe RampD team you wish to haverdquo Senior developers
Junior developers
Students
Guy Vinogradguysoftimizecoil
Guy Vinogradguysoftimizecoil
gitUrl httpsxxxsoftimizexxxgitassemblacomxxxgit
gitBranchmaster
gitTagV_10
keepExistingSourcestrue
projectDirldquoxxx-cloud-serviceldquo projectNameldquoxxxService
playCommand start -Dhttpport=80
Possible on Auto Scaling as well
USER_DATA=`wget -qO- http169254169254latestuser-data`
GIT_BRANCH=`echo $USER_DATA | jq gitBranch | sed -e s^ -e s$`
git remote add -t $GIT_BRANCH -f origin $GIT_URL
Any branchtag Dev INT QA Prod
Production robustness Not depending on repo availability
UpgradeDowngrade Just change the user data and reboot
adminPasspassword
environmentNameTest
dbProperties
shouldWorkWithInstanceRole true
accessKeyLocalDB
secretKeyLocalDB
rlRegionus-east-1
maxRetries4
failureMaxIntervalInMillis5000
Per-environment instance permissions
Per-environment dependent resources (DB storage etc)
import playtestHelpers
public class TestHelper extends Helpers
public void testMethod()
Result result =
callAction(xxxroutesrefXxxControlleryyyMethod()
fakeRequest()WithWhatever())
assertThat(status(result))isEqualTo(OK)
Great for local integrationbehavior testing but
What about real clients not running on the same machine as the server Different time zones clocks
Different locales and string formats
import playtestHelpers
public class TestHelper extends Helpers
public void testMethod()
Result result =
callApiAction(xxxroutesrefXxxControlleryyyMethod()
fakeRequest()WithWhatever() relativeURL reqParams)
assertThat(status(result))isEqualTo(OK)
Play test ndashDTestServerRemoteAddress=httplthostgtltportgtbaseURL
import playlibsWSWSRequestHolder
public Result callApiAction(HandlerRef ref FakeRequest
requestString parametersString methodName)
if (shouldTestRemote) return callAction(refrequest)
long timeoutAllowed=20000
String contentType=applicationx-www-form-urlencoded
Response response=new
WSRequestHolder(serverUrl+methodName)setContentType(contentType
)post(parameters)get(timeoutAllowed)
return playmvcResultsstatus(responsegetStatus()
responseasByteArray())
ldquoThe RampD team you wish to haverdquo Senior developers
Junior developers
Students
Guy Vinogradguysoftimizecoil
Guy Vinogradguysoftimizecoil
USER_DATA=`wget -qO- http169254169254latestuser-data`
GIT_BRANCH=`echo $USER_DATA | jq gitBranch | sed -e s^ -e s$`
git remote add -t $GIT_BRANCH -f origin $GIT_URL
Any branchtag Dev INT QA Prod
Production robustness Not depending on repo availability
UpgradeDowngrade Just change the user data and reboot
adminPasspassword
environmentNameTest
dbProperties
shouldWorkWithInstanceRole true
accessKeyLocalDB
secretKeyLocalDB
rlRegionus-east-1
maxRetries4
failureMaxIntervalInMillis5000
Per-environment instance permissions
Per-environment dependent resources (DB storage etc)
import playtestHelpers
public class TestHelper extends Helpers
public void testMethod()
Result result =
callAction(xxxroutesrefXxxControlleryyyMethod()
fakeRequest()WithWhatever())
assertThat(status(result))isEqualTo(OK)
Great for local integrationbehavior testing but
What about real clients not running on the same machine as the server Different time zones clocks
Different locales and string formats
import playtestHelpers
public class TestHelper extends Helpers
public void testMethod()
Result result =
callApiAction(xxxroutesrefXxxControlleryyyMethod()
fakeRequest()WithWhatever() relativeURL reqParams)
assertThat(status(result))isEqualTo(OK)
Play test ndashDTestServerRemoteAddress=httplthostgtltportgtbaseURL
import playlibsWSWSRequestHolder
public Result callApiAction(HandlerRef ref FakeRequest
requestString parametersString methodName)
if (shouldTestRemote) return callAction(refrequest)
long timeoutAllowed=20000
String contentType=applicationx-www-form-urlencoded
Response response=new
WSRequestHolder(serverUrl+methodName)setContentType(contentType
)post(parameters)get(timeoutAllowed)
return playmvcResultsstatus(responsegetStatus()
responseasByteArray())
ldquoThe RampD team you wish to haverdquo Senior developers
Junior developers
Students
Guy Vinogradguysoftimizecoil
Guy Vinogradguysoftimizecoil
adminPasspassword
environmentNameTest
dbProperties
shouldWorkWithInstanceRole true
accessKeyLocalDB
secretKeyLocalDB
rlRegionus-east-1
maxRetries4
failureMaxIntervalInMillis5000
Per-environment instance permissions
Per-environment dependent resources (DB storage etc)
import playtestHelpers
public class TestHelper extends Helpers
public void testMethod()
Result result =
callAction(xxxroutesrefXxxControlleryyyMethod()
fakeRequest()WithWhatever())
assertThat(status(result))isEqualTo(OK)
Great for local integrationbehavior testing but
What about real clients not running on the same machine as the server Different time zones clocks
Different locales and string formats
import playtestHelpers
public class TestHelper extends Helpers
public void testMethod()
Result result =
callApiAction(xxxroutesrefXxxControlleryyyMethod()
fakeRequest()WithWhatever() relativeURL reqParams)
assertThat(status(result))isEqualTo(OK)
Play test ndashDTestServerRemoteAddress=httplthostgtltportgtbaseURL
import playlibsWSWSRequestHolder
public Result callApiAction(HandlerRef ref FakeRequest
requestString parametersString methodName)
if (shouldTestRemote) return callAction(refrequest)
long timeoutAllowed=20000
String contentType=applicationx-www-form-urlencoded
Response response=new
WSRequestHolder(serverUrl+methodName)setContentType(contentType
)post(parameters)get(timeoutAllowed)
return playmvcResultsstatus(responsegetStatus()
responseasByteArray())
ldquoThe RampD team you wish to haverdquo Senior developers
Junior developers
Students
Guy Vinogradguysoftimizecoil
Guy Vinogradguysoftimizecoil
import playtestHelpers
public class TestHelper extends Helpers
public void testMethod()
Result result =
callAction(xxxroutesrefXxxControlleryyyMethod()
fakeRequest()WithWhatever())
assertThat(status(result))isEqualTo(OK)
Great for local integrationbehavior testing but
What about real clients not running on the same machine as the server Different time zones clocks
Different locales and string formats
import playtestHelpers
public class TestHelper extends Helpers
public void testMethod()
Result result =
callApiAction(xxxroutesrefXxxControlleryyyMethod()
fakeRequest()WithWhatever() relativeURL reqParams)
assertThat(status(result))isEqualTo(OK)
Play test ndashDTestServerRemoteAddress=httplthostgtltportgtbaseURL
import playlibsWSWSRequestHolder
public Result callApiAction(HandlerRef ref FakeRequest
requestString parametersString methodName)
if (shouldTestRemote) return callAction(refrequest)
long timeoutAllowed=20000
String contentType=applicationx-www-form-urlencoded
Response response=new
WSRequestHolder(serverUrl+methodName)setContentType(contentType
)post(parameters)get(timeoutAllowed)
return playmvcResultsstatus(responsegetStatus()
responseasByteArray())
ldquoThe RampD team you wish to haverdquo Senior developers
Junior developers
Students
Guy Vinogradguysoftimizecoil
Guy Vinogradguysoftimizecoil
import playtestHelpers
public class TestHelper extends Helpers
public void testMethod()
Result result =
callApiAction(xxxroutesrefXxxControlleryyyMethod()
fakeRequest()WithWhatever() relativeURL reqParams)
assertThat(status(result))isEqualTo(OK)
Play test ndashDTestServerRemoteAddress=httplthostgtltportgtbaseURL
import playlibsWSWSRequestHolder
public Result callApiAction(HandlerRef ref FakeRequest
requestString parametersString methodName)
if (shouldTestRemote) return callAction(refrequest)
long timeoutAllowed=20000
String contentType=applicationx-www-form-urlencoded
Response response=new
WSRequestHolder(serverUrl+methodName)setContentType(contentType
)post(parameters)get(timeoutAllowed)
return playmvcResultsstatus(responsegetStatus()
responseasByteArray())
ldquoThe RampD team you wish to haverdquo Senior developers
Junior developers
Students
Guy Vinogradguysoftimizecoil
Guy Vinogradguysoftimizecoil
Play test ndashDTestServerRemoteAddress=httplthostgtltportgtbaseURL
import playlibsWSWSRequestHolder
public Result callApiAction(HandlerRef ref FakeRequest
requestString parametersString methodName)
if (shouldTestRemote) return callAction(refrequest)
long timeoutAllowed=20000
String contentType=applicationx-www-form-urlencoded
Response response=new
WSRequestHolder(serverUrl+methodName)setContentType(contentType
)post(parameters)get(timeoutAllowed)
return playmvcResultsstatus(responsegetStatus()
responseasByteArray())
ldquoThe RampD team you wish to haverdquo Senior developers
Junior developers
Students
Guy Vinogradguysoftimizecoil
Guy Vinogradguysoftimizecoil
ldquoThe RampD team you wish to haverdquo Senior developers
Junior developers
Students
Guy Vinogradguysoftimizecoil
Guy Vinogradguysoftimizecoil
Guy Vinogradguysoftimizecoil