KEMBAR78
JavaFX and Scala in the Cloud | PPTX
Stephen Chin | Oracle      @steveonjava
       Andrew Phillips | jclouds   @jclouds




JavaFX and Scala in the Cloud
+
Heaven




Photo by Alberto Fernandez Fernandez
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
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!
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
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
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
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
UI
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.
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
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
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
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}
                                                                                                                               }
                                                                                                                             }
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
      )
    }
  }
}
Loading Images
new ImageView {
  image = new Image(
    getClass().getResourceAsStream(
      "JavaOneLogo.png"
    )
  )
}
Creating Buttons
new Button("Filter") {
  onAction = { e:ActionEvent =>
    model.filter(items.selectionModel().getSelectedItem(),
                 filter.text())
  }
}

new Button("Clear") {
  onAction = { e:ActionEvent =>
    filter.text = ""
    model.clear()
  }
}
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
}
DATABASE
By RRZEicons (Own work) [CC-BY-SA-3.0 (http://creativecommons.org/licenses/by-sa/3.0)], via Wikimedia Commons
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!
Circumflex ORM
• Scala-based ORM
  (Object-Relational
  Mapping)
• SQL-based Query Syntax
• DSL for Domain Object Definition
• Lazy and Eager Fetch Strategies
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
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]
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)
}
CLOUD
An OSSM Persistence Store

 •   On-demand
 •   Self-service
 •   Scalable
 •   Measurable


 • ™ Dave Nielsen, CloudCamp
@jclouds
open source
simple: feels like java (and clojure)unit testable
tested across multiple clouds
vibrant community
Portable APIs

      BlobStore   LoadBalancer

                   What do you
      Compute
                     want?

Provider-Specific Hooks
Embeddable

                  github jclouds-examples
Anatomy of a BlobStore Project

1.Create context
2.Get BlobStore API
3.Do stuff
4.Close context


@jclouds
jclouds modularity

APIs are software
focused Providers are
offering focused
API + location + defaults
= Provider
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()
}
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
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
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
Conference App Demo
Stephen Chin <stephen.chin@oracle.com> | Oracle @steveonjava
Andrew Phillips <andrew@jclouds.org> | jclouds @jclouds


                   Thank You!

JavaFX and Scala in the Cloud

  • 1.
    Stephen Chin |Oracle @steveonjava Andrew Phillips | jclouds @jclouds JavaFX and Scala in the Cloud
  • 2.
  • 3.
    Heaven Photo by AlbertoFernandez Fernandez
  • 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
  • 12.
  • 13.
    JavaFX 2.0 Platform ImmersiveApplication 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? • Sharesmany 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. ScalaDSL 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 ConferenceUIextends JFXApp { val model = ConferenceModel stage = new Stage { width = 625 height = 700 scene = new Scene(new StackPane()) { fill = "#fcfcfc" children = Seq( // create background // create foreground ) } } }
  • 19.
    Loading Images new ImageView{ image = new Image( getClass().getResourceAsStream( "JavaOneLogo.png" ) ) }
  • 20.
    Creating Buttons new Button("Filter"){ onAction = { e:ActionEvent => model.filter(items.selectionModel().getSelectedItem(), filter.text()) } } new Button("Clear") { onAction = { e:ActionEvent => filter.text = "" model.clear() } }
  • 21.
    ScalaFX Table Construction newTableView[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 (Ownwork) [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!
  • 24.
    Circumflex ORM • Scala-basedORM (Object-Relational Mapping) • SQL-based Query Syntax • DSL for Domain Object Definition • Lazy and Eager Fetch Strategies
  • 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 defclear() { 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) }
  • 28.
  • 29.
    An OSSM PersistenceStore • On-demand • Self-service • Scalable • Measurable • ™ Dave Nielsen, CloudCamp @jclouds
  • 30.
    open source simple: feelslike 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 aBlobStore Project 1.Create context 2.Get BlobStore API 3.Do stuff 4.Close context @jclouds
  • 33.
    jclouds modularity APIs aresoftware focused Providers are offering focused API + location + defaults = Provider
  • 34.
    Cloud Access inScala 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? • DataPortability 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? • OSGicompatible • 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? • Locationmetadata 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
  • 38.
  • 39.
    Stephen Chin <stephen.chin@oracle.com>| Oracle @steveonjava Andrew Phillips <andrew@jclouds.org> | jclouds @jclouds Thank You!

Editor's Notes