Trisha Gee, Java Driver Developer
#JFokus
What do you mean,
Backwards Compatibility?
@trisha_gee
Trisha Gee, Java Driver Developer
#JFokus
Stuff I Should Have Already
Known
@trisha_gee
customer = {
_id: "joe",
name: "Joe Bookreader",
address: {
street: "123 Fake St",
city: "Faketon",
state: "MA",
zip: 1234...
Replica Set
MongoDB
MongoDB
NoSQL
Sharding
Replica Sets
Document Database
Scalable
Dynamic Schema
Strong
Consistency
Schema Design
MongoDB
NoSQL
Sharding
Replica Sets
Document Database
Scalable
Dynamic Schema
Strong
Consistency
Schema Design
The shell
M...
MongoDB
NoSQL
Python
Perl
PHP
Ruby
Node.js
C#
Java
Sharding
Replica Sets
Document Database
Scalable
Dynamic Schema
Strong
...
The Java Driver
Te>
xt
Te>
xt
What do you want
to do?
_
Te>
xt
Te>
xt
What do you want
to do?
_
Common Problems
Our Solutions
...not unique to us
which is the point
really.
“Let me help you
with that”
We’re using different
words
Or the same words to
mean different things
Ubiquitous Language
UML
Documentation
Your API is your UI
Naming is Hard
This takes ages...
DO THIS FIRST
The code is hard to
debug and modify
Re-write the whole
driver
Re-write the whole
driver
Anti Corruption
Layer
Instead of this...
Separation of
Concerns
Pluggable APIs
Backwards Compatible
Scala Support
Support other
libraries
Easier to maintain
Confusing API
Method Overloading
Update
Update
Update
collection.update(query, newValues);
Update
Update
collection.update(query, newValues);
collection.update(query, newValues, false, false, JOURNALED);
DSL-ish
Update
Update
collection.update(query, newValues);
Update
collection.update(query, newValues);
collection.find(query).updateOne(newValues);
Update
collection.update(query, newValues);
collection.find(query).updateOne(newValues);
Update
Update
collection.update(query, newValues);
collection.find(query).updateOne(newValues);
collection.find(query)
.withWrite...
Update
collection.update(query, newValues);
collection.find(query).updateOne(newValues);
collection.find(query)
.withWrite...
Self Documenting
IDE-friendly
Fewer choices
Ctrl + space
Testing is Hard and
Boring
...and we can’t agree
on style
BDD-ish
@Test
public void shouldIgnoreCaseWhenCheckingIfACollectionExists() {
// Given
database.getCollection("foo1").drop...
vs
@Test
public void testInvalid() throws UnknownHostException {
try {
new DBAddress(null);
fail();
} catch (NullPointerExcep...
...and the tests are
confusing
@Test
public void testMaxScan() {
countResults(new DBCursor(collection,
new BasicDBObject(),
new BasicDBObject(),
primary(...
Spock!
def 'should throw duplicate key when response has a duplicate key
error code'() {
given:
def commandResult = new CommandRe...
Really? Groovy?
Our tests are our
documentation
BDD-ish thinking
Test styles
converging
Data Driven Testing
def '#wc should return write concern document #commandDocument'()
{
expect:
wc.asDocument() == command...
Data Driven Testing
def '#wc should return write concern document #commandDocument'()
{
expect:
wc.asDocument() == command...
Lesser Evil
def 'should throw IllegalArgumentException when required
parameter is not supplied for challenge-response'() {...
Java 8 is coming
Lambdas
New Collections API
Date & Time
...and other stuff
But we support 1.5
But we support 1.5
But we support 1.6
Do Your Homework
Single Method
Interfaces
External Iteration
DBObject query = new BasicDBObject("name", theNameToFind);
DBCursor results = collection.find(query);
f...
Anonymous Inner Classes
Document query = new Document("name", theNameToFind);
collection.find(query).forEach(new Block<Doc...
Lambdas!
Document query = new Document("name", theNameToFind);
collection.find(query).forEach(document -> {
// do stuff wi...
API supports
lambdas
(Mongo) Collection
API Java 8-ish
Separation of
Concerns
Pluggable Codecs
Decoding
MongoCollection<Document> collection =
database.getCollection("coll");
Document query = new Document("name", theN...
Decoding
MongoCollection<Document> collection =
database.getCollection("coll");
Document query = new Document("name", theN...
Custom Codecs
MongoCollection<Customer> collection =
database.getCollection("coll", new CustomerCodec());
Document query =...
Now With Generics!
Separation of concerns
MongoCollection<Customer> collection =
database.getCollection("coll", new CustomerCodec());
Documen...
Decoding code in
one place
Can support new
Date & Time
Caveat: Under
Construction
Unfinished Business
Codecs
New Public API
Clear testing
definitions
Continuous Delivery
The Driver!!!
Lessons Learnt
It’s been done
before:
Domain Driven
Design
Separation of
Concerns
The API is your UI
The tools exist
Don’t wait for Java 8
What’s in it for you?
Try This At Home
Try This At Work
Download & use the
new MongoDB driver
is.gd/java3mongodb
Come play
http://is.gd/java3mongodb
#JFokus
Questions
@trisha_gee
I want to run the
tests
Every time before I
check in
I want good quality
pull requests
I want it to be easy
for people to start
If it can be
automated, do it
Gradle
Painless Dependency
Management
Easy to introduce
static analysis
Wrapper = no extra
overhead
Easy to get started
as a contributor
Includes IDE Setup
Performance
Bottlenecks
More Servers =
More Delay
Event Driven
Async = Good
Events = Good
Scalable
What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?
Upcoming SlideShare
Loading in...5
×

What do you mean, Backwards Compatibility?

297

Published on

Lessons learnt developing the new Java driver for MongoDB. This is a totally different version of my backwards compatibility talk, delivered at JFokus.

Published in: Technology
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
297
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
3
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

What do you mean, Backwards Compatibility?

  1. 1. Trisha Gee, Java Driver Developer #JFokus What do you mean, Backwards Compatibility? @trisha_gee
  2. 2. Trisha Gee, Java Driver Developer #JFokus Stuff I Should Have Already Known @trisha_gee
  3. 3. customer = { _id: "joe", name: "Joe Bookreader", address: { street: "123 Fake St", city: "Faketon", state: "MA", zip: 12345 } books: [ 27464, 747854, ...] }
  4. 4. Replica Set
  5. 5. MongoDB
  6. 6. MongoDB NoSQL Sharding Replica Sets Document Database Scalable Dynamic Schema Strong Consistency Schema Design
  7. 7. MongoDB NoSQL Sharding Replica Sets Document Database Scalable Dynamic Schema Strong Consistency Schema Design The shell Map reduce MMS Backup Aggregation Framework
  8. 8. MongoDB NoSQL Python Perl PHP Ruby Node.js C# Java Sharding Replica Sets Document Database Scalable Dynamic Schema Strong Consistency Schema Design The shell Map reduce MMS Backup Aggregation Framework Scala C C++Go Erlang Python JavaScript
  9. 9. The Java Driver
  10. 10. Te> xt Te> xt What do you want to do? _
  11. 11. Te> xt Te> xt What do you want to do? _
  12. 12. Common Problems
  13. 13. Our Solutions
  14. 14. ...not unique to us
  15. 15. which is the point
  16. 16. really.
  17. 17. “Let me help you with that”
  18. 18. We’re using different words
  19. 19. Or the same words to mean different things
  20. 20. Ubiquitous Language
  21. 21. UML
  22. 22. Documentation
  23. 23. Your API is your UI
  24. 24. Naming is Hard
  25. 25. This takes ages...
  26. 26. DO THIS FIRST
  27. 27. The code is hard to debug and modify
  28. 28. Re-write the whole driver
  29. 29. Re-write the whole driver
  30. 30. Anti Corruption Layer
  31. 31. Instead of this...
  32. 32. Separation of Concerns
  33. 33. Pluggable APIs
  34. 34. Backwards Compatible
  35. 35. Scala Support
  36. 36. Support other libraries
  37. 37. Easier to maintain
  38. 38. Confusing API
  39. 39. Method Overloading
  40. 40. Update
  41. 41. Update
  42. 42. Update collection.update(query, newValues);
  43. 43. Update
  44. 44. Update collection.update(query, newValues); collection.update(query, newValues, false, false, JOURNALED);
  45. 45. DSL-ish
  46. 46. Update
  47. 47. Update collection.update(query, newValues);
  48. 48. Update collection.update(query, newValues); collection.find(query).updateOne(newValues);
  49. 49. Update collection.update(query, newValues); collection.find(query).updateOne(newValues);
  50. 50. Update
  51. 51. Update collection.update(query, newValues); collection.find(query).updateOne(newValues); collection.find(query) .withWriteConcern(JOURNALED) .updateOne(newValues);
  52. 52. Update collection.update(query, newValues); collection.find(query).updateOne(newValues); collection.find(query) .withWriteConcern(JOURNALED) .updateOne(newValues); collection.update(query, newValues, false, false, JOURNALED);
  53. 53. Self Documenting
  54. 54. IDE-friendly
  55. 55. Fewer choices
  56. 56. Ctrl + space
  57. 57. Testing is Hard and Boring
  58. 58. ...and we can’t agree on style
  59. 59. BDD-ish @Test public void shouldIgnoreCaseWhenCheckingIfACollectionExists() { // Given database.getCollection("foo1").drop(); assertFalse(database.collectionExists("foo1")); // When database.createCollection("foo1", new BasicDBObject()); // Then assertTrue(database.collectionExists("foo1")); assertTrue(database.collectionExists("FOO1")); assertTrue(database.collectionExists("fOo1")); // Finally database.getCollection("foo1").drop(); }
  60. 60. vs
  61. 61. @Test public void testInvalid() throws UnknownHostException { try { new DBAddress(null); fail(); } catch (NullPointerException e) { // NOPMD // all good } try { new DBAddress(" tn"); fail(); } catch (IllegalArgumentException e) { // NOPMD // all good } }
  62. 62. ...and the tests are confusing
  63. 63. @Test public void testMaxScan() { countResults(new DBCursor(collection, new BasicDBObject(), new BasicDBObject(), primary()) .addSpecial("$maxScan", 4), 4); countResults(new DBCursor(collection, new BasicDBObject(), new BasicDBObject(), primary()) .maxScan(4), 4); }
  64. 64. Spock!
  65. 65. def 'should throw duplicate key when response has a duplicate key error code'() { given: def commandResult = new CommandResult(new ServerAddress(), ['ok' : 1, 'err' : 'E11000', 'code': 11000] as Document, 1); when: ProtocolHelper.getWriteResult(commandResult) then: def e = thrown(MongoDuplicateKeyException) e.getErrorCode() == 11000 }
  66. 66. Really? Groovy?
  67. 67. Our tests are our documentation
  68. 68. BDD-ish thinking
  69. 69. Test styles converging
  70. 70. Data Driven Testing def '#wc should return write concern document #commandDocument'() { expect: wc.asDocument() == commandDocument; where: wc | commandDocument WriteConcern.ACKNOWLEDGED | ['w' : 1] WriteConcern.JOURNALED | ['w' : 1, 'j': true] WriteConcern.FSYNCED | ['w' : 1, 'fsync': true] new WriteConcern('majority') | ['w': 'majority'] new WriteConcern(2, 100) | ['w' : 2, 'wtimeout': 100] }
  71. 71. Data Driven Testing def '#wc should return write concern document #commandDocument'() { expect: wc.asDocument() == commandDocument; where: wc | commandDocument WriteConcern.ACKNOWLEDGED | ['w' : 1] WriteConcern.JOURNALED | ['w' : 1, 'j': true] WriteConcern.FSYNCED | ['w' : 1, 'fsync': true] new WriteConcern('majority') | ['w': 'majority'] new WriteConcern(2, 100) | ['w' : 2, 'wtimeout': 100] } is.gd/ddTest
  72. 72. Lesser Evil def 'should throw IllegalArgumentException when required parameter is not supplied for challenge-response'() { when: MongoCredential.createMongoCRCredential(null, 'test', ...); then: thrown(IllegalArgumentException) when: MongoCredential.createMongoCRCredential('user', null, ...); then: thrown(IllegalArgumentException) when: MongoCredential.createMongoCRCredential('user', 'test', ...); then: thrown(IllegalArgumentException) }
  73. 73. Java 8 is coming
  74. 74. Lambdas
  75. 75. New Collections API
  76. 76. Date & Time
  77. 77. ...and other stuff
  78. 78. But we support 1.5
  79. 79. But we support 1.5
  80. 80. But we support 1.6
  81. 81. Do Your Homework
  82. 82. Single Method Interfaces
  83. 83. External Iteration DBObject query = new BasicDBObject("name", theNameToFind); DBCursor results = collection.find(query); for (DBObject dbObject : results) { // do stuff with each result }
  84. 84. Anonymous Inner Classes Document query = new Document("name", theNameToFind); collection.find(query).forEach(new Block<Document>() { public boolean run(Document document) { // do stuff with each result } });
  85. 85. Lambdas! Document query = new Document("name", theNameToFind); collection.find(query).forEach(document -> { // do stuff with each result });
  86. 86. API supports lambdas
  87. 87. (Mongo) Collection API Java 8-ish
  88. 88. Separation of Concerns
  89. 89. Pluggable Codecs
  90. 90. Decoding MongoCollection<Document> collection = database.getCollection("coll"); Document query = new Document("name", theNameToFind); Document result = collection.find(query).getOne(); Document addressDocument = (Document)result.get("address"); Customer customer = new Customer(result.getString("name"), new Address(addressDocument.getString("street"), addressDocument.getString("city"), addressDocument.getString("state"), addressDocument.getInteger("zip")), (List<Document>) result.get("books"));
  91. 91. Decoding MongoCollection<Document> collection = database.getCollection("coll"); Document query = new Document("name", theNameToFind); Document result = collection.find(query).getOne(); Document addressDocument = (Document)result.get("address"); Customer customer = new Customer(result.getString("name"), new Address(addressDocument.getString("street"), addressDocument.getString("city"), addressDocument.getString("state"), addressDocument.getInteger("zip")), (List<Document>) result.get("books"));
  92. 92. Custom Codecs MongoCollection<Customer> collection = database.getCollection("coll", new CustomerCodec()); Document query = new Document("name", theNameToFind); Customer customer = collection.find(query).getOne();
  93. 93. Now With Generics!
  94. 94. Separation of concerns MongoCollection<Customer> collection = database.getCollection("coll", new CustomerCodec()); Document query = new Document("name", theNameToFind); Customer customer = collection.find(query).getOne();
  95. 95. Decoding code in one place
  96. 96. Can support new Date & Time
  97. 97. Caveat: Under Construction
  98. 98. Unfinished Business
  99. 99. Codecs
  100. 100. New Public API
  101. 101. Clear testing definitions
  102. 102. Continuous Delivery
  103. 103. The Driver!!!
  104. 104. Lessons Learnt
  105. 105. It’s been done before:
  106. 106. Domain Driven Design
  107. 107. Separation of Concerns
  108. 108. The API is your UI
  109. 109. The tools exist
  110. 110. Don’t wait for Java 8
  111. 111. What’s in it for you?
  112. 112. Try This At Home
  113. 113. Try This At Work
  114. 114. Download & use the new MongoDB driver
  115. 115. is.gd/java3mongodb
  116. 116. Come play
  117. 117. http://is.gd/java3mongodb #JFokus Questions @trisha_gee
  118. 118. I want to run the tests
  119. 119. Every time before I check in
  120. 120. I want good quality pull requests
  121. 121. I want it to be easy for people to start
  122. 122. If it can be automated, do it
  123. 123. Gradle
  124. 124. Painless Dependency Management
  125. 125. Easy to introduce static analysis
  126. 126. Wrapper = no extra overhead
  127. 127. Easy to get started as a contributor
  128. 128. Includes IDE Setup
  129. 129. Performance Bottlenecks
  130. 130. More Servers = More Delay
  131. 131. Event Driven
  132. 132. Async = Good
  133. 133. Events = Good
  134. 134. Scalable
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×