What do you mean, Backwards Compatibility?
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

What do you mean, Backwards Compatibility?

on

  • 292 views

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

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

Statistics

Views

Total Views
292
Views on SlideShare
291
Embed Views
1

Actions

Likes
1
Downloads
1
Comments
0

1 Embed 1

http://www.slideee.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

What do you mean, Backwards Compatibility? Presentation Transcript

  • 1. Trisha Gee, Java Driver Developer #JFokus What do you mean, Backwards Compatibility? @trisha_gee
  • 2. Trisha Gee, Java Driver Developer #JFokus Stuff I Should Have Already Known @trisha_gee
  • 3. customer = { _id: "joe", name: "Joe Bookreader", address: { street: "123 Fake St", city: "Faketon", state: "MA", zip: 12345 } books: [ 27464, 747854, ...] }
  • 4. Replica Set
  • 5. MongoDB
  • 6. MongoDB NoSQL Sharding Replica Sets Document Database Scalable Dynamic Schema Strong Consistency Schema Design
  • 7. MongoDB NoSQL Sharding Replica Sets Document Database Scalable Dynamic Schema Strong Consistency Schema Design The shell Map reduce MMS Backup Aggregation Framework
  • 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. The Java Driver
  • 10. Te> xt Te> xt What do you want to do? _
  • 11. Te> xt Te> xt What do you want to do? _
  • 12. Common Problems
  • 13. Our Solutions
  • 14. ...not unique to us
  • 15. which is the point
  • 16. really.
  • 17. “Let me help you with that”
  • 18. We’re using different words
  • 19. Or the same words to mean different things
  • 20. Ubiquitous Language
  • 21. UML
  • 22. Documentation
  • 23. Your API is your UI
  • 24. Naming is Hard
  • 25. This takes ages...
  • 26. DO THIS FIRST
  • 27. The code is hard to debug and modify
  • 28. Re-write the whole driver
  • 29. Re-write the whole driver
  • 30. Anti Corruption Layer
  • 31. Instead of this...
  • 32. Separation of Concerns
  • 33. Pluggable APIs
  • 34. Backwards Compatible
  • 35. Scala Support
  • 36. Support other libraries
  • 37. Easier to maintain
  • 38. Confusing API
  • 39. Method Overloading
  • 40. Update
  • 41. Update
  • 42. Update collection.update(query, newValues);
  • 43. Update
  • 44. Update collection.update(query, newValues); collection.update(query, newValues, false, false, JOURNALED);
  • 45. DSL-ish
  • 46. Update
  • 47. Update collection.update(query, newValues);
  • 48. Update collection.update(query, newValues); collection.find(query).updateOne(newValues);
  • 49. Update collection.update(query, newValues); collection.find(query).updateOne(newValues);
  • 50. Update
  • 51. Update collection.update(query, newValues); collection.find(query).updateOne(newValues); collection.find(query) .withWriteConcern(JOURNALED) .updateOne(newValues);
  • 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. Self Documenting
  • 54. IDE-friendly
  • 55. Fewer choices
  • 56. Ctrl + space
  • 57. Testing is Hard and Boring
  • 58. ...and we can’t agree on style
  • 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. vs
  • 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. ...and the tests are confusing
  • 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. Spock!
  • 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. Really? Groovy?
  • 67. Our tests are our documentation
  • 68. BDD-ish thinking
  • 69. Test styles converging
  • 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. 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. 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. Java 8 is coming
  • 74. Lambdas
  • 75. New Collections API
  • 76. Date & Time
  • 77. ...and other stuff
  • 78. But we support 1.5
  • 79. But we support 1.5
  • 80. But we support 1.6
  • 81. Do Your Homework
  • 82. Single Method Interfaces
  • 83. External Iteration DBObject query = new BasicDBObject("name", theNameToFind); DBCursor results = collection.find(query); for (DBObject dbObject : results) { // do stuff with each result }
  • 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. Lambdas! Document query = new Document("name", theNameToFind); collection.find(query).forEach(document -> { // do stuff with each result });
  • 86. API supports lambdas
  • 87. (Mongo) Collection API Java 8-ish
  • 88. Separation of Concerns
  • 89. Pluggable Codecs
  • 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. 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. Custom Codecs MongoCollection<Customer> collection = database.getCollection("coll", new CustomerCodec()); Document query = new Document("name", theNameToFind); Customer customer = collection.find(query).getOne();
  • 93. Now With Generics!
  • 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. Decoding code in one place
  • 96. Can support new Date & Time
  • 97. Caveat: Under Construction
  • 98. Unfinished Business
  • 99. Codecs
  • 100. New Public API
  • 101. Clear testing definitions
  • 102. Continuous Delivery
  • 103. The Driver!!!
  • 104. Lessons Learnt
  • 105. It’s been done before:
  • 106. Domain Driven Design
  • 107. Separation of Concerns
  • 108. The API is your UI
  • 109. The tools exist
  • 110. Don’t wait for Java 8
  • 111. What’s in it for you?
  • 112. Try This At Home
  • 113. Try This At Work
  • 114. Download & use the new MongoDB driver
  • 115. is.gd/java3mongodb
  • 116. Come play
  • 117. http://is.gd/java3mongodb #JFokus Questions @trisha_gee
  • 118. I want to run the tests
  • 119. Every time before I check in
  • 120. I want good quality pull requests
  • 121. I want it to be easy for people to start
  • 122. If it can be automated, do it
  • 123. Gradle
  • 124. Painless Dependency Management
  • 125. Easy to introduce static analysis
  • 126. Wrapper = no extra overhead
  • 127. Easy to get started as a contributor
  • 128. Includes IDE Setup
  • 129. Performance Bottlenecks
  • 130. More Servers = More Delay
  • 131. Event Driven
  • 132. Async = Good
  • 133. Events = Good
  • 134. Scalable