@DebskiChris
#AtmosphereConf
Krzysztof Dębski Allegro Group
Let’s build a solid base for a scale
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
Agenda
The Allegro Situation How to build a new World? The way to improve What’s in it for you?
Allegro The New World Improvement WIIFY #AtmosphereConf @DebskiChris
The Allegro Situation
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
Allegro
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
Allegro
6 million LOC
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
400 people in IT
Allegro
Allegro The New World Improvement WIIFY #AtmosphereConf @DebskiChris
A New Hope
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
A New Hope
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
A New Hope
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
A New Hope?
Service
Oriented
Ambiguity
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
Domain Driven Design
Allegro The New World Improvement WIIFY #AtmosphereConf @DebskiChris
(Micro)Services
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
(Micro)Services
Business needs Offer
User
Transaction
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
(Micro)Services
Offer
User
Transaction
Independent
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
(Micro)Services
API Offer
User
Transaction
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
(Micro)Services
Polyglot
Cassandra
MongoDB
Oracle
Offer
User
Transaction
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
(Micro)Services
Smart Endpoints
Cassandra
MongoDB
Oracle
Offer
User
Transaction
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
The first approach
Service
Auto deployable Monitored Auto scalable Auto healable Auto discoverable
Allegro The New World Improvement WIIFY #AtmosphereConf @DebskiChris
How to build a new World?
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
The first project
Gradle Spring External Jetty server
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
Let’s REST
JAX-RS / JSR Compliant @Path("/users") @Consumes(CONTENT_TYPE_JSON) @Produces(CONTENT_TYPE_JSON) public class UsersEndpoint {
// [...] @GET public UserCollectionResponse findAllUsers() { //[...] }
}
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
Let’s expose our methods
Swagger @Path("/users") @Api(value = "/users") @Consumes(CONTENT_TYPE_JSON) @Produces(CONTENT_TYPE_JSON) public class UsersEndpoint {
// [...] @ApiOperation(value=“Get all users”, response=UserCollectionResponse.class) @GET public UserCollectionResponse findAllUsers() { //[...] }
}
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
Let’s expose our methods
Swagger
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
And make them discoverable
Offer
User
Discovery ZooKeeper
Register
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
And make them discoverable
Offer
User
Discovery ZooKeeper
Get User
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
And make them discoverable
Offer
User
Discovery ZooKeeper
Get User
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
And make them discoverable
Offer
User
Discovery ZooKeeper
Get User Get off
er for user
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
Multiple API versions
Header support public class UserMediaType {
public static final String V1_JSON = "application/vnd.allegro.user.v1+json” public static final String V2_JSON = "application/vnd.allegro.user.v2+json”
}
curl --dump-header - -H ”Accept: application/vnd.allegro.user.v2+json" -X GET http://localhost:8080/users
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
Multiple API versions
Content negotiation @Path("/users") @Consumes(AllegroUserMediaType.V1_JSON) @Produces(AllegroUserMediaType.V1_JSON) public class UsersEndpoint {
// [...] @GET @Produces(AllegroUserMediaType.V2_JSON) public UserCollectionResponse findAllUsers() { //[...] }
}
Allegro The New World Improvement WIIFY #AtmosphereConf @DebskiChris
How to configure it?
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
How to configure it?
Zookeper Environment properties Command-line options
Allegro The New World Improvement WIIFY #AtmosphereConf @DebskiChris
And it became slow
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
Lower startup time
External Jetty Embedded Jetty Embedded UnderTow
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
Easier deployment
Cargo deployment Built to zip package On immutable images
Allegro The New World Improvement WIIFY #AtmosphereConf @DebskiChris
Tests
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
Do you test your tests?
Pitest
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
Integration tests
Test without mocks Run from IDE
public class UsersIntegrationTest {
private static Map<String, String> overrideConfiguration = Maps.newHashMap();
static { overrideConfiguration.put("property.name", "This was overwritten value"); }
@ClassRule public static final RestServiceStarted DEPLOYED_SERVICE = new RestServiceStarted(overrideConfiguration);
private WebTarget getUsersResourceWebTarget() { return DEPLOYED_SERVICE.getWebTarget().path("users"); }
}
Allegro The New World Improvement WIIFY #AtmosphereConf @DebskiChris
Monitoring
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
Let’s see what happens
LogStash Kibana NxLog
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
Let’s see what happens
Graphite # Metrics metrics.reporters.graphite.enabled=true metrics.reporters.graphite.host=graphite.service metrics.reporters.graphite.port=2003 metrics.reporters.graphite.prefix=stats.Prod.service metrics.reporters.interval=30
Allegro The New World Improvement WIIFY #AtmosphereConf @DebskiChris
Monolith Alert
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
Monolith Alert
Multi module project support
Allegro The New World Improvement WIIFY #AtmosphereConf @DebskiChris
The way to improve
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
Authentication
OAuth2
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
Patch Support
Standardized by IETF https://tools.ietf.org/html/rfc6902
PATCH /user/1 HTTP/1.1 Host: user.service.local Content-Length: 312
Content-Type: application/json-patch+json [
{”op”: ”test”, ”path”: ”/firstname”, ”value”: ”Jane”}, {”op”: ”add”, ”path”: ”/maidenname”, ”value”: ”Smith”}, {”op”: ”replace”, ”path”: ”/lastname”, ”value”: ”Doe”},
{”op”: ”remove", ”path”: ”/meetings”}, {”op”: ”move”, ”from”: ”/balance”, ”path”: ”sharedbalance”}, {”op”: ”copy”, ”from”: ”/a”, ”path”: ”/b”}
]
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
Simplify annotations
Swagger? @Path("/users") @Api(value = "/users") @Consumes(CONTENT_TYPE_JSON) @Produces(CONTENT_TYPE_JSON) public class UsersEndpoint {
// [...] @ApiOperation(value=“Get all users”, response=UserCollectionResponse.class) @GET public UserCollectionResponse findAllUsers() { //[...] }
}
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
Deployment
Docker support
Allegro The New World Improvement WIIFY #AtmosphereConf @DebskiChris
What’s in it for you?
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
Use the latest tools
GradleW issue in Continuous Integration Environment and parent POM issues. Don’t do DDOS yourself and your partners’ sites.
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
Change is the only constant
HTTP Server Service API provider Dependency injection engine Deployment tools
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
Focus on right metrics
import org.junit.Test;
import static net.trajano...
public class MediaTypesTest {
@Test public void mediaTypesShouldBeValidUtilityClasses()
throws Throwable { assertUtilityClassWellDefined(UserMediaType.class); } }
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
Tools also lie
Metrics tend to lie – Default PHP metrics in SonarQube – Tested file
• 4535 CLOC • Whole code written using imperative programming
How many violations are there?
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
Tools also lie
How many violations are there?
4 At least according to Sonar
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
Learn to REST
REST is not so obvious
/api/bi/XYZ123/1
/recommendations/1/items
/offer/100?output=ESI/JSON
#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY
Community
Involve all developers in building the Bootstrap. Or they will build their own tools.
Łukasz Drumiński Mateusz Gajewski @wendigo
Allegro The New World Improvement WIIFY #AtmosphereConf @DebskiChris
Q & A