mongodb and java 8 - goto bloggotocon.com/dl/goto-amsterdam-2015/slides/emilforslund_and... · 6...
Post on 16-Apr-2018
254 Views
Preview:
TRANSCRIPT
MongoDB and Java 8
3
Agenda
Java8 Main Features MongoDB + Java8 Few Examples RX Driver
Java 8
MongoDB Java Driver is JAVA6+ Complaint
6
Java 8 Features and Improvements • Lambda Expressions • New Date API • Stream API • Type Annotations • Compact Profiles • Security Enhancements • JavaFX Improvements • Nashorn JS Engine • Unicode Enhancements • Selector Provider (IO & NIO) • Concurrency • …
http://www.oracle.com/technetwork/java/javase/8-whats-new-2157071.html
7
Java 8 Features and Improvements • Lambda Expressions • Stream API • New Date API • Type Annotations • Compact Profiles • Security Enhancements • JavaFX Improvements • Nashorn JS Engine • Unicode Enhancements • Selector Provider (IO & NIO) • Concurrency • …
http://www.oracle.com/technetwork/java/javase/8-whats-new-2157071.html
8
Lambda Function • Anonymous Functions
– Not bounded to an identifier – Inline definition – Passed as argument to higher-order
functions • Functional Java FTW
9
Lambda Function
….map(line -> Arrays.asList(line.split(SEPARATOR)))
…
i -> document.put(headers.get(i), values.get(i) )
• Anonymous Functions – Not bounded to an identifier – Inline definition – Passed as argument to higher-order
functions • Functional Java FTW
10
Stream API • Streams are free flowing
sequence of elements – Pipeline kind of processing
• Starts with a source of data (Collections)
– Processes elements of that data source in a parallelized fashion
– Intermediary processing steps
• Generally implemented by lambdas
– Terminator operators • Streams are immutable!
try(BufferedReader reader = new BufferedReader(fr)){return reader.lines().skip(1).map(line -> { Document document = new Document(); List<String> values = Arrays.asList(line.split(SEPARATOR)); IntStream.range(0, Math.min(values.size(), headers.size())) .forEach(i -> document.put(headers.get(i), values.get(i) )); return document;}).collect(Collectors.toList());
11
Stream API public List<Document> readRecords(List<String> headers) {
try (FileReader fr = new FileReader(this.source);BufferedReader reader = new BufferedReader(fr)) {
return reader.lines().skip(1).map(line -> {
Document document = new Document();List<String> values = Arrays.asList(line
.split(SEPARATOR));IntStream.range(0,
Math.min(values.size(), headers.size())).forEach(
i -> document.put(headers.get(i),values.get(i)));
return document;
}).collect(Collectors.toList());
} catch (IOException e) {throw new UncheckedIOException(e);
}}
12
New Date API
• There is no native support for new Date API • Our Codec API gives the possibility map this data
type ( Instant.class ) to encode to a driver supported data type and decode back to the original data type
InstantCodec instantCodec = new InstantCodec();
Map<BsonType, Class<?>> replacements = new HashMap<BsonType, Class<?>>();
replacements.put(BsonType.DATE_TIME, Instant.class);
13
New Date API public class InstantCodec implements Codec<Instant> {
public void encode(BsonWriter writer, Instant value,EncoderContext encoderContext) {
//will store Instant has Epoch Milliseconds writer.writeDateTime(value.toEpochMilli());
}
public Class<Instant> getEncoderClass() {return Instant.class;
} //return back on Instant.class
public Instant decode(BsonReader reader, DecoderContext decoderContext) {
return Instant.ofEpochMilli(reader.readDateTime());}
} http://mongodb.github.io/mongo-java-driver/3.0/bson/codecs/
14
New Date API public class InstantCodec implements Codec<Instant> {
public void encode(BsonWriter writer, Instant value,EncoderContext encoderContext) {
//will store Instant has Epoch Milliseconds writer.writeDateTime(value.toEpochMilli());
}
public Class<Instant> getEncoderClass() {return Instant.class;
} //return back on Instant.class
public Instant decode(BsonReader reader, DecoderContext decoderContext) {
return Instant.ofEpochMilli(reader.readDateTime());}
} http://mongodb.github.io/mongo-java-driver/3.0/bson/codecs/
15
New Date API InstantCodec instantCodec = new InstantCodec();Map<BsonType, Class<?>> replacements = new HashMap<BsonType, Class<?>>();replacements.put(BsonType.DATE_TIME, Instant.class);
CodecRegistry cr = CodecRegistries.fromRegistries(CodecRegistries.fromCodecs(instantCodec),CodecRegistries.fromProviders(documentCodecProvider),MongoClient.getDefaultCodecRegistry());
// add the new code registry has option.MongoClientOptions option = MongoClientOptions.builder()
.codecRegistry(cr).build();
mc = new MongoClient("localhost:27017", option);collection = mc.getDatabase("dates").getCollection("sample");
Document doc = new Document("java8date", Instant.now());
collection.insertOne(doc);
Extra: RX Driver
ReactiveX
Observable
Observer
18
MongoDB Reactive Streams Driver
• http://mongodb.github.io/mongo-java-driver-rx/
• Observer based rather than callback based! (Cold Observables)
• Built upon the MongoDB Async Driver & RxJava
Join the Java Courses
20
https://university.mongodb.com/courses/M101J
Engineering
Sales & Account Management Finance & People Operations
Pre-Sales Engineering Marketing
Join the Team
View all jobs and apply: http://grnh.se/pj10su
Obrigado! Norberto Leite Technical Evangelist norberto@mongodb.com @nleite https://github.com/nleite/java8demo
A SIMPLE GUIDE TOUSING AKKA
PERSISTENCEJoost Heijkoop
WHAT WILL THIS BE ABOUT?Using Akka with ScalaEvent SourcingHow to add Akka PersistenceHow to do Serialization with Stamina
WHO AM I?Joost HeijkoopI like to create/build/learn/share/teach stuffI'm a Software developer, Full Stack Developer, Back-endDeveloper, Consultant, ...I Work at XebiaAmsterdam.scala meetup (SUG) organisorSerial meetup / conference attendee
BUILD STUFF!
AKKA + SCALAAkka is an Actor Framework, similar to ErlangAkka is message driven, "extreme" OOScala hybrid programming language on the JVM
AKKA + SCALAclass Parrot extends Actor { var count = 0
override def receive: Receive = { case message: String => { count = count + 1 println(s"$count: $message") } }}
val parrot = system.actorOf(Parrot.props)parrot ! "Hello"parrot ! "Hello"
1: Hello2: Hello
WHAT IS EVENT SOURCINGAll truths spring from recording eventsThe current state is the sum of all eventsCommand -> Event -> UpdateRecording of delta instead of current stateYou can replay all of historyCQRS (Command Query Responsibility Segregation) - MartinFowler
EVENT SOURCING WITH AKKAPERSISTENCE
Get a commandCreate eventPersist/record the event to Event StoreUpdate the internal state
EVENT SOURCING WITH AKKAPERSISTENCE
final def persist[A](event: A)(handler: (A) => Unit): Unit
override def receiveCommand: Receive = { case message: String => persist(Incremented(count + 1, message))(update) println(s"$count: $message")}
def update: Receive = { case Incremented(newCount, message) => count = newCount}
EVENT SOURCING WITH AKKAPERSISTENCE
class Parrot extends PersistentActor { var count = 0 override def persistenceId = "parrot"
override def receiveRecover: Receive = { case event: Incremented => update(event) }
override def receiveCommand: Receive = { case message: String => persist(Incremented(count + 1, message))(update) println(s"$count: $message") }
def update = { case Incremented(newCount, message) => count = newCount }}
AKKA + SCALAclass Parrot extends Actor { var count = 0
override def receive: Receive = { case message: String => { count = count + 1 println(s"$count: $message") } }}
PERSISTED STATEBEFORE
1: Hello2: Hello[restart app]1: Hello
WITH AKKA PERSISTENCE1: Hello2: Hello[restart app]3: Hello
STANDARD SERIALIZATION IS A PAINJava serialization is standard
Incremented(count: Int)-> IncrementedV2(count: Int, message: String)
What you wantIncremented(count: Int)-> Incremented(count: Int, message: String)
STAMINAIt serializes to a non-binary formatThe default serialization is JSONAllows you to migrate before deserializationThe is a catch, for now
ADD STAMINASRC/MAIN/RESOURCES/APPLICATION.CONF
akka.actor { serializers { goto = "goto.PricingAkkaSerializer" } serialization-bindings { "stamina.Persistable" = goto }}
ADD STAMINAimport stamina._import stamina.json._import stamina.json.SprayJsonMacros._
case class Incremented(count: Int) extends Persistable
val parrotPersister = persister[Incremented]("increment")
class PricingAkkaSerializer(persisters: Persisters) extends StaminaAkkaSerializer(persisters) {
def this() { this(Persisters(List(Parrot.parrotPersister))) }}
STAMINA MIGRATIONcase class Incremented(count: Int, message: String) extends Persistable
persist(Incremented(count + 1, message))(update)
def update: Receive = { case Incremented(newCount, message) => count = newCount}
STAMINA MIGRATIONimport spray.json.lenses.JsonLenses._
val parrotPersister = persister[Incremented, V2]( "increment", from[V1].to[V2]( _.update('message ! set[String]("[empty message]"))))
STAMINAPROJECT/BUILD.SCALA
import sbt.{Build, Project, ProjectRef, uri}
object GotoBuild extends Build { lazy val root = Project("root", sbt.file(".")) .dependsOn(staminaCore, staminaJson)
lazy val staminaCore = ProjectRef( uri("git://github.com/scalapenos/stamina.git#master"), "stamina-core") lazy val staminaJson = ProjectRef( uri("git://github.com/scalapenos/stamina.git#master"), "stamina-json")}
QUESTIONSUsing Akka with Scala?Event Sourcing?How to add Akka Persistence?How to do Serialization with Stamina?Wat?!?
RESOURCESAkka Persistence Stamina exampleAkka Persistence documentationStamina - Akka Persistence serializationCQRS - Martin Fowler
Event Sourcing - Martin Fowler
Amsterdam.scala meetup groupXebia
Design for Quality in Java 8Emil Forslund
Speedment, Inc.
About meo Emil Forslund
o Code Monkey @ Speedment, Inc.
About the project Speedment is a java tool that
o generates a domain model from a database,
o organize that model in a graph-like manner, and
o let you write super-fast in-memory database transactions.
About the project Speedment has been in development for about 5 years and consist of roughly 1800 components.
When Java 8 was released, the entire code base was rewritten to make use of all the new language features.
Some words about inheritanceo Created as a means of reducing code repetition almost 50 years ago
o Makes it possible to organize code in a well established structure
And what tends to happen?o As a system grows, dependency trees tend to grow as well
o Often leads to coupled systems with bad maintainability
o Testability worsens with complex inheritance models
What is a trait?
o A reusable component that can be combined to create classes
o A description of a specific behavior or property
Trait definition?
o A set of methods that implement behavior
o Stateless
o Can be combined using the following operators:
– Symmetric sum
– Override (asymmetric sum)
– Alias
– Exclusion
An example in Scala
trait HasName {
def nameProperty() : Property[String]
def setName(name : String) {
nameProperty().set(name)
}
def getName(name : String) : Option[String] =
nameProperty().get(name)
}
Traits in Java? Was not possible... until recently with the release of Java 8
Default methods Using interface default methods, a concept similar to Traits can be achieved
Interfaces can
o be combined
o be overridden
o have a default implementation
o be referenced using the ”&” selector
What is the difference Interfaces doesn't cover all the features of traits from other languages
You still can’t:
o prioritize different traits
o do other operations than union
So how does it look in Java?
interface HasName {
Property<String> nameProperty();
default void setName(String name) {
nameProperty().setValue(name);
}
default Optional<String> getName() {
return Optional.ofNullable(nameProperty().getValue());
}
}
So how does it look in Java?
interface HasName {
Property<String> nameProperty();
default void setName(String name) {
nameProperty().setValue(name);
}
default Optional<String> getName() {
return Optional.ofNullable(nameProperty().getValue());
}
}
So how does it look in Java?
interface HasName {
Property<String> nameProperty();
default void setName(String name) {
nameProperty().setValue(name);
}
default Optional<String> getName() {
return Optional.ofNullable(nameProperty().getValue());
}
}
So how does it look in Java?
interface HasName {
Property<String> nameProperty();
default void setName(String name) {
nameProperty().setValue(name);
}
default Optional<String> getName() {
return Optional.ofNullable(nameProperty().getValue());
}
}
Write decoupled systems
class Person implements HasName {...}
class Pet implements HasName {...}
class Friend {
public void show(HasName a, HasName b) {
System.out.println(a.getName().orElse("no one")
+ " is a friend of "
+ b.getName().orElse("no one")
+ "."
);
}
}
Write decoupled systems
class Person implements HasName {...}
class Pet implements HasName {...}
class Friend {
public void show(HasName a, HasName b) {
System.out.println(a.getName().orElse("no one")
+ " is a friend of "
+ b.getName().orElse("no one")
+ "."
);
}
}
Write decoupled systems
class Person implements HasName {...}
class Pet implements HasName {...}
class Friend {
public void show(HasName a, HasName b) {
System.out.println(a.getName().orElse("no one")
+ " is a friend of "
+ b.getName().orElse("no one")
+ "."
);
}
}
Write decoupled systems
class Person implements HasName {...}
class Pet implements HasName {...}
class Friend {
public void show(HasName a, HasName b) {
System.out.println(a.getName().orElse("no one")
+ " is a friend of "
+ b.getName().orElse("no one")
+ "."
);
}
}
Write decoupled systems
class Person implements HasName {...}
class Pet implements HasName {...}
class Friend {
public void show(HasName a, HasName b) {
System.out.println(a.getName().orElse("no one")
+ " is a friend of "
+ b.getName().orElse("no one")
+ "."
);
}
}
Combine multiple traits
<T extends HasName & HasFields> String printFields(T obj) {
return obj.getName()
+ " has the following fields: "
+ obj.getFields().collect(joining("\n"))
;
}
Combine multiple traits
<T extends HasName & HasFields> String printFields(T obj) {
return obj.getName()
+ " has the following fields: "
+ obj.getFields().collect(joining("\n"))
;
}
Combine multiple traits
<T extends HasName & HasFields> String printFields(T obj) {
return obj.getName()
+ " has the following fields: "
+ obj.getFields().collect(joining("\n"))
;
}
Combine multiple traits
<T extends HasName & HasFields> String printFields(T obj) {
return obj.getName()
+ " has the following fields: "
+ obj.getFields().collect(joining("\n"))
;
}
Comparison More components to keep track of
More components to write tests for
Lower average file length
Easier to reuse code when scaling out functionality
Tests are more specific and might reveal more bugs
Real world exampleRefactoring Speedment took about 6 months
Maintainability measurements improved by 70%
Testability measurements improved by 40%
Complexity was reduced by 90%
Want to know more?
Interwebs: www.speedment.org
Github: www.github.org/speedment
Twitter: @Speedment
@emifors
top related