6. When This Architecture
Makes Sense
• Data is mostly read-only
– Transactional updates still require a server (but
can be simpler/smaller)
• User's view of data is small to medium
– Initial DB download of < 10K records is reasonable
– Not total DB size, but subset of data visible to user
Conference App has 3K
large records and
compresses to only 330KB
DB size
7. Cloud Data Advantages
• Offline Operation
– Once DB is cached, application works 100% offline
• Responsive Client Performance
– All DB queries are fast and local
• High Availability & Scalability
– 99.99% Availability
– Easily scales up to 100s of requests per second
But, with proper hashes scales up
to millions of requests per second!
8. Cloud Data Advantages (continued)
• Insanely cheap server costs!
Number of Users Monthly Cost*
3,000 Free (S3 free tier)
10,000 $0.28
100,000 $3.84
1,000,000 $39.48
* For 330KB of hosted data in Amazon S3
9. Cloud Data Advantages (continued)
• Insanely cheap server costs!
Number of Users Monthly Cost*
3,000 Free (S3 free tier)
10,000 $0.28
100,000 $3.84
1,000,000 $39.48
* For 330KB of hosted data in Amazon S3
10. Cloud Data Advantages (continued)
• Insanely cheap server costs!
Number of Users Monthly Cost*
3,000 Free (S3 free tier)
10,000 $0.28
100,000 $3.84
1,000,000 $39.48
* For 330KB of hosted data in Amazon S3
11. Cloud Data Advantages (continued)
• Insanely cheap server costs!
Number of Users Monthly Cost*
3,000 Free (S3 free tier)
10,000 $0.28
100,000 $3.84
1,000,000 $39.48
* For 330KB of hosted data in Amazon S3
13. JavaFX 2.0 Platform
Immersive Application Experience
Leverage your Java skills with modern
JavaFX APIs
• Cross-platform Animation, Video,
Charting
• Integrate Java, JavaScript, and HTML5
in the same application
• New graphics stack takes advantage of
hardware acceleration for 2D and 3D
applications
• Use your favorite IDE: NetBeans,
Eclipse, IntelliJ, etc.
14. What is Scala
2001 2006
• Scala Started • Scala v2.0
2003/2004 2011
• Scala v1.0 • Scala 2.9.2 (latest)
• Started in 2001 by Martin Odersky
• Compiles to Java bytecodes
• Pure object-oriented language
• Also a functional programming language
15. Why Scala?
• Shares many language features with
JavaFX Script that make GUI
programming easier:
– Static Type Checking – Catch your errors
at compile time
– Closures – Wrap behavior and pass it by
reference
– Declarative – Express the UI by describing
what it should look like
16. Why Scala? (continued)
• Scala also supports Type Safe DSLs!
– Implicit Conversions – type safe class
extension
– Operator Overloading – with standard
precedence rules
– DelayedInit / @specialized – advanced
language features
17. Java vs. Scala DSL
public class JavaFXEEDemo extends Application { object ConferenceUI extends JFXApp {
val model = ConferenceModel
public static void main(String[] args) { stage = new Stage {
launch(JavaFXEEDemo.class, args); width = 625
} height = 700
scene = new Scene(new StackPane()) {
private SpeakerModel speakerModel = getInstance(); fill = "#fcfcfc"
private TextField filter; children = Seq(
private ChoiceBox<String> items; new VBox {
children = Seq(
@Override new ImageView {
public void start(Stage primaryStage) { image = new Image(getClass().getResourceAsStream("JavaOneLogo.png"))
primaryStage.setTitle("JavaOne Speaker List"); },
speakerModel.load(); new Rectangle {
EventHandler<ActionEvent> filterAction = new EventHandler<ActionEvent>() { width = 625
public void handle(ActionEvent event) { height = 50
String field = items.selectionModelProperty().getValue().getSelectedItem(); fill = new LinearGradient(
String text = filter.getText(); endX = 0,
speakerModel.filter(field, text); stops = Stops(WHITE, "#d0cbc8")
} )
}; }
primaryStage.setScene(SceneBuilder.create() )
.width(625) },
.height(700) new VBox {
.fill(Color.web("#fcfcfc")) padding = Insets(100, 20, 20, 20)
.root(StackPaneBuilder.create().children( spacing = 30
// Background image and gradient children = Seq(
VBoxBuilder.create().children( new HBox {
ImageViewBuilder.create() val filter = new TextField();
83 Lines 88 Lines
.image(new Image(getClass().getResourceAsStream("JavaOneLogo.png"))).build(), val items = new ChoiceBox[ruco.TextField[Speaker]]() {
RectangleBuilder.create().width(625).height(50).fill(LinearGradientBuilder.create().endX(0).stops( items = ObservableBuffer(Speaker.firstName, Speaker.lastName, Speaker.jobTitle, Speaker.company)
StopBuilder.create().color(Color.WHITE).offset(0).build(), converter = StringConverter.toStringConverter({s:ruco.TextField[Speaker] => s.name})
StopBuilder.create().color(Color.web("#d0cbc8")).offset(1).build() }
).build()).build() alignment = Pos.BASELINE_LEFT
).build(), spacing = 15
// Foreground controls children = Seq(
VBoxBuilder.create() items,
2622 Characters 1452 Characters
.padding(new Insets(100, 20, 20, 20)) filter,
.spacing(30) new Button("Filter") {
.children(HBoxBuilder.create() onAction = { e:ActionEvent =>
.alignment(Pos.BASELINE_LEFT) model.filter(items.selectionModel().getSelectedItem(), filter.text())
.spacing(15) }
.children( },
items = new ChoiceBox<String>( new Button("Clear") {
FXCollections.observableArrayList(FIRST_NAME, LAST_NAME, JOB_TITLE, COMPANY) onAction = { e:ActionEvent =>
), filter.text = ""
filter = TextFieldBuilder.create().prefColumnCount(20).onAction(filterAction).build(), model.clear()
ButtonBuilder.create().text("Filter").onAction(filterAction).build(), }
ButtonBuilder.create().text("Clear").onAction(new EventHandler<ActionEvent>() { },
public void handle(ActionEvent event) { new Button("Reload") {
speakerModel.clearFilter(); onAction = { e:ActionEvent =>
} filter.text = ""
}).build(), model.load()
ButtonBuilder.create().text("Reload").onAction(new EventHandler<ActionEvent>() { }
public void handle(ActionEvent event) { }
speakerModel.load(); )
} items.selectionModel().selectFirst()
}).build() },
).build(), new TableView[Speaker](model.filteredSpeakers) {
TableViewBuilder.<Speaker>create().items(speakerModel.getFilteredData()).prefHeight(1000).columns( columns = Seq(
TableColumnBuilder.<Speaker, String>create() new TableColumn[Speaker, String] {
.text(FIRST_NAME) text = "First Name"
.cellValueFactory(new PropertyValueFactory<Speaker, String>(FIRST_NAME_FIELD)).build(), converter = {_.firstName()}
TableColumnBuilder.<Speaker, String>create() },
.text(LAST_NAME) new TableColumn[Speaker, String] {
.cellValueFactory(new PropertyValueFactory<Speaker, String>(LAST_NAME_FIELD)).build(), text = "Last Name"
TableColumnBuilder.<Speaker, String>create() converter = {_.lastName()}
.text(JOB_TITLE) },
.prefWidth(200) new TableColumn[Speaker, String] {
.cellValueFactory(new PropertyValueFactory<Speaker, String>(JOB_TITLE_FIELD)).build(), text = "Job Title"
TableColumnBuilder.<Speaker, String>create() converter = {_.jobTitle()}
.text(COMPANY) prefWidth = 200
.prefWidth(212) },
.cellValueFactory(new PropertyValueFactory<Speaker, String>(COMPANY_FIELD)).build() new TableColumn[Speaker, String] {
).build() text = "Company"
).build() converter = {_.company()}
).build() prefWidth = 212
).build() }
); )
items.getSelectionModel().selectFirst(); prefHeight = 1000
primaryStage.show(); }
} )
} }
)
}
onCloseRequest = {_:Any => Platform.exit}
}
}
18. ScalaFX Application
object ConferenceUI extends JFXApp {
val model = ConferenceModel
stage = new Stage {
width = 625
height = 700
scene = new Scene(new StackPane()) {
fill = "#fcfcfc"
children = Seq(
// create background
// create foreground
)
}
}
}
21. ScalaFX Table Construction
new TableView[Speaker](model.filteredSpeakers) {
columns = Seq(
new TableColumn[Speaker, String] {
text = "First Name"
converter = {_.firstName()}
},
new TableColumn[Speaker, String] {
text = "Last Name"
converter = {_.lastName()}
}
…
)
prefHeight = 1000
}
22. DATABASE
By RRZEicons (Own work) [CC-BY-SA-3.0 (http://creativecommons.org/licenses/by-sa/3.0)], via Wikimedia Commons
23. Java DB / Apache Derby
• Embedded Database
• Small Footprint (2.7MB)
• Standards Based (Java, JDBC, SQL)
• Extremely Easy to Configure
– With JDBC 4 / SE 6, just drop in the jar!
25. Embedded DB Config
orm.connection.driver=
org.apache.derby.jdbc.EmbeddedDriver
orm.connection.url=jdbc:derby:conferenceData
orm.connection.username=user1
orm.connection.password=user1
orm.defaultSchema=APP
26. Speaker Domain Object
class Speaker extends Record[String, Speaker] {
val id = "id".VARCHAR(255).NOT_NULL
val company = "company".VARCHAR(255)
val firstName = "firstName".VARCHAR(255)
val jobTitle = "jobTitle".VARCHAR(255)
val lastName = "lastName".VARCHAR(255)
def PRIMARY_KEY = id
def relation = Speaker
}
object Speaker extends Speaker with Table[String,
Speaker]
27. Query the Database
def clear() {
val speakers = Speaker.criteria.list()
filteredSpeakers.setAll(speakers)
}
def filter(field: TextField[Speaker],
filterString: String) {
val speakers = Speaker.criteria.add(
field LIKE "%" + filterString + "%").list()
filteredSpeakers.setAll(speakers)
}
29. An OSSM Persistence Store
• On-demand
• Self-service
• Scalable
• Measurable
• ™ Dave Nielsen, CloudCamp
@jclouds
30. open source
simple: feels like java (and clojure)unit testable
tested across multiple clouds
vibrant community
31. Portable APIs
BlobStore LoadBalancer
What do you
Compute
want?
Provider-Specific Hooks
Embeddable
github jclouds-examples
32. Anatomy of a BlobStore Project
1.Create context
2.Get BlobStore API
3.Do stuff
4.Close context
@jclouds
33. jclouds modularity
APIs are software
focused Providers are
offering focused
API + location + defaults
= Provider
34. Cloud Access in Scala
val context = ContextBuilder.newBuilder("aws-s3")
.credentials("identity", "secret")
.buildView(classOf[BlobStoreContext])
def loadFromCloud(container:String,
resource:String):InputStream = {
val blobStore = context.getBlobStore
val blob = blobStore.getBlob(container, resource)
blob.getPayload.getInput
}
def close() {
context.close()
}
35. Why jclouds?
• Data Portability
o APIs are not as compatible as they might appear
• Code Portability
o Currently 33 cloud providers
• Enterprise-grade
o Move petabytes of data
• Parallel operations without threading
concerns
o Outperforms many native SDKs
o GAE compatible
o Many tuning options
@jclouds
36. Why jclouds?
• OSGi compatible
• Clojure binding
• “Invented” many standard SDK features
o e.g. sync/async APIs
• Tested!
o “official” TCK for a number of cloud providers
o also supports offline/local testing
@jclouds
37. Why jclouds?
• Location metadata
o Don’t get locked in to a provider’s deployment policy
• Does the hard work so you don’t have to
o Multi-part in native SDKs vs. .multipart() in
jclouds
• Strong & active community
o ~65 contributors, commercial support
@jclouds