mongodb and java 8 - goto bloggotocon.com/dl/goto-amsterdam-2015/slides/emilforslund_and... · 6...

Post on 16-Apr-2018

274 Views

Category:

Documents

2 Downloads

Preview:

Click to see full reader

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