This document provides an overview of Scala web frameworks Play, Scalatra, and Spray. It begins with introducing the speakers, Massimiliano Dessì and Alberto Quario. The agenda then outlines topics to be covered including REST, JSON, routing, templates, actors, sessions, deployment, hot reloading, and testing. The bulk of the document dives into specifics of each framework, focusing particularly on Scalatra with descriptions of how to implement REST, routing, filters, handlers, requests/responses, binding, Gzip, flash messages, JSON, templates including SSP, Jade, Mustache and Scaml, and using actors. It also briefly discusses authentication and security in Scalatra.
The hitchhiker's guide to UXing without a UXer - Chrissy Welsh - Codemotion M...Codemotion
Sometimes you are tasked with building great things by yourself or in a small team. Bootstrapped start-ups don’t always have the budget for a dedicated Uxer to help you design the best apps, software or websites. This guide will get you started developing the right way and stop you making classic mistakes. Before you even consider touching your dev environment I will show you how to “Start with one idea”, “Think like a user” and set out your user journeys.
Collecting requirements or understanding a large system seems such a long and demanding activity. We can do al lot better than this: unlimited modelling space and all the key stakeholder in the same room, with some special spice. :-)
Domain-Driven Design has never been so efficient. This is where DDD meets Kanban, TOC and Management 3.0.
Slides of my Pecha Kucha short talk at #ALE14 in Krakow.
There's too much noise around software estimation, and one of the problem is that we try to use the same approach, when we're in practice estimating totally different things.
The amazing world of Game Design - Emanuele Bolognesi - Codemotion Milan 2016Codemotion
Game Design is the art of creating a game. It’s a very fascinating subject, under many aspects, as it requires knowledge of psychology, visual design, mathematics, software engineering, animation, user experience and much more. In this workshop we will introduce the definition of game and the main components of game design, presenting the challenges and the aspects of this science, analysing the design choices of some of the most popular titles of the past. We will also discover why many of the concepts of game design are also useful to web or mobile product designers in general.
Scala meetup - Milan, 25 May 2013
Dopo anni di sviluppo Web in Java con le Servlet come base, vediamo come poter sviluppare usando le stesse solide fondamenta con Scala. Scalatra è un toolkit minimale che ci permette di iniziare ad approcciare Scala sul web attraverso le Servlet permettendoci di integrare Scala (o di migrare) in delle WebApp già esistenti. Vedremo in questo quickie come delle funzionalità generiche ed avanzate, implementate con SpringMVC, possono essere implementate con Scalatra.
HTML5.tx 2013: Embedded JavaScript, HTML5 and the Internet of ThingsJesse Cravens
JavaScript is everywhere, but one of the most fascinating areas is in the crossroads of distributed, real time applications and microcontrollers. Take a look into the world of Node.js, HTML5 Connectivity APIs, and Embedded Linux, and how this world is changing the traditional client and server relationship. Explore the impact these trends are having on the HTML5 user interface, see demos of JavaScript powered microcontrollers (Arduino, XBee, Beaglebone, and the Raspberry Pi), learn asynchronous coding patterns, and discover some of the newer APIs that are helping JavaScript developers step out of the web browser and into the world of physical computing, robotics, and hardware.
When Old Meets New: Turning Maven into a High Scalable, Resource Efficient, C...Massimiliano Dessì
Turning Maven into a High Scalable, Resource Efficient, Cloud Ready Microservice
Embracing Microservice Architecture in a new project is something that most of developers want!
But how about the old and gold projects that are not designed and planned for it?
What about refactoring a real legacy piece of software that is stable and used by almost all Java developers out there?
Come to this talk to see how we transformed Maven builds in a Cloud Ready Microservice.
Some covered topics are:
-Live objects extracted from Maven Mojos and shared between different classloaders
-Cloud Native features, Configuration and in memory plugins
-Turn any Maven build into incremental ones
-Concurrent use of the same Maven compiler
-Turn into reusable Maven internal objects to decrease memory footprint and increase speed
-How fits in Drools and jBPM ecosystem
-Trade offs
The hitchhiker's guide to UXing without a UXer - Chrissy Welsh - Codemotion M...Codemotion
Sometimes you are tasked with building great things by yourself or in a small team. Bootstrapped start-ups don’t always have the budget for a dedicated Uxer to help you design the best apps, software or websites. This guide will get you started developing the right way and stop you making classic mistakes. Before you even consider touching your dev environment I will show you how to “Start with one idea”, “Think like a user” and set out your user journeys.
Collecting requirements or understanding a large system seems such a long and demanding activity. We can do al lot better than this: unlimited modelling space and all the key stakeholder in the same room, with some special spice. :-)
Domain-Driven Design has never been so efficient. This is where DDD meets Kanban, TOC and Management 3.0.
Slides of my Pecha Kucha short talk at #ALE14 in Krakow.
There's too much noise around software estimation, and one of the problem is that we try to use the same approach, when we're in practice estimating totally different things.
The amazing world of Game Design - Emanuele Bolognesi - Codemotion Milan 2016Codemotion
Game Design is the art of creating a game. It’s a very fascinating subject, under many aspects, as it requires knowledge of psychology, visual design, mathematics, software engineering, animation, user experience and much more. In this workshop we will introduce the definition of game and the main components of game design, presenting the challenges and the aspects of this science, analysing the design choices of some of the most popular titles of the past. We will also discover why many of the concepts of game design are also useful to web or mobile product designers in general.
Scala meetup - Milan, 25 May 2013
Dopo anni di sviluppo Web in Java con le Servlet come base, vediamo come poter sviluppare usando le stesse solide fondamenta con Scala. Scalatra è un toolkit minimale che ci permette di iniziare ad approcciare Scala sul web attraverso le Servlet permettendoci di integrare Scala (o di migrare) in delle WebApp già esistenti. Vedremo in questo quickie come delle funzionalità generiche ed avanzate, implementate con SpringMVC, possono essere implementate con Scalatra.
HTML5.tx 2013: Embedded JavaScript, HTML5 and the Internet of ThingsJesse Cravens
JavaScript is everywhere, but one of the most fascinating areas is in the crossroads of distributed, real time applications and microcontrollers. Take a look into the world of Node.js, HTML5 Connectivity APIs, and Embedded Linux, and how this world is changing the traditional client and server relationship. Explore the impact these trends are having on the HTML5 user interface, see demos of JavaScript powered microcontrollers (Arduino, XBee, Beaglebone, and the Raspberry Pi), learn asynchronous coding patterns, and discover some of the newer APIs that are helping JavaScript developers step out of the web browser and into the world of physical computing, robotics, and hardware.
When Old Meets New: Turning Maven into a High Scalable, Resource Efficient, C...Massimiliano Dessì
Turning Maven into a High Scalable, Resource Efficient, Cloud Ready Microservice
Embracing Microservice Architecture in a new project is something that most of developers want!
But how about the old and gold projects that are not designed and planned for it?
What about refactoring a real legacy piece of software that is stable and used by almost all Java developers out there?
Come to this talk to see how we transformed Maven builds in a Cloud Ready Microservice.
Some covered topics are:
-Live objects extracted from Maven Mojos and shared between different classloaders
-Cloud Native features, Configuration and in memory plugins
-Turn any Maven build into incremental ones
-Concurrent use of the same Maven compiler
-Turn into reusable Maven internal objects to decrease memory footprint and increase speed
-How fits in Drools and jBPM ecosystem
-Trade offs
Spring Security is a security solution for enterprise applications developed
using the Spring Framework.
Out of the box Spring Security provide support for OpenID, ACL, Groups, JSR 250 Security Annotation and can be easily integrated with OAuth and RESTful systems.
In this presentation we will see how to use Spring Security to switch a RESTful webapp from a classical authentication/authorization to OpenID authentication, OAuth authorization and how to use the Spring Security ACL for your Domain Objects.
Presentazione di Massimiliano Dessì al Javaday 2009 a Roma, dal titolo "Real Spring AOP, recipes for your everyday job. ", gli esempi sono tratti dal libro Spring 2.5 Aspect Oriented Programming edito dalla packt publishing a febbraio 2009
Accelerate your Kubernetes clusters with Varnish CachingThijs Feryn
A presentation about the usage and availability of Varnish on Kubernetes. This talk explores the capabilities of Varnish caching and shows how to use the Varnish Helm chart to deploy it to Kubernetes.
This presentation was delivered at K8SUG Singapore. See https://feryn.eu/presentations/accelerate-your-kubernetes-clusters-with-varnish-caching-k8sug-singapore-28-2024 for more details.
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Jeffrey Haguewood
Sidekick Solutions uses Bonterra Impact Management (fka Social Solutions Apricot) and automation solutions to integrate data for business workflows.
We believe integration and automation are essential to user experience and the promise of efficient work through technology. Automation is the critical ingredient to realizing that full vision. We develop integration products and services for Bonterra Case Management software to support the deployment of automations for a variety of use cases.
This video focuses on the notifications, alerts, and approval requests using Slack for Bonterra Impact Management. The solutions covered in this webinar can also be deployed for Microsoft Teams.
Interested in deploying notification automations for Bonterra Impact Management? Contact us at sales@sidekicksolutionsllc.com to discuss next steps.
Essentials of Automations: Optimizing FME Workflows with ParametersSafe Software
Are you looking to streamline your workflows and boost your projects’ efficiency? Do you find yourself searching for ways to add flexibility and control over your FME workflows? If so, you’re in the right place.
Join us for an insightful dive into the world of FME parameters, a critical element in optimizing workflow efficiency. This webinar marks the beginning of our three-part “Essentials of Automation” series. This first webinar is designed to equip you with the knowledge and skills to utilize parameters effectively: enhancing the flexibility, maintainability, and user control of your FME projects.
Here’s what you’ll gain:
- Essentials of FME Parameters: Understand the pivotal role of parameters, including Reader/Writer, Transformer, User, and FME Flow categories. Discover how they are the key to unlocking automation and optimization within your workflows.
- Practical Applications in FME Form: Delve into key user parameter types including choice, connections, and file URLs. Allow users to control how a workflow runs, making your workflows more reusable. Learn to import values and deliver the best user experience for your workflows while enhancing accuracy.
- Optimization Strategies in FME Flow: Explore the creation and strategic deployment of parameters in FME Flow, including the use of deployment and geometry parameters, to maximize workflow efficiency.
- Pro Tips for Success: Gain insights on parameterizing connections and leveraging new features like Conditional Visibility for clarity and simplicity.
We’ll wrap up with a glimpse into future webinars, followed by a Q&A session to address your specific questions surrounding this topic.
Don’t miss this opportunity to elevate your FME expertise and drive your projects to new heights of efficiency.
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...UiPathCommunity
💥 Speed, accuracy, and scaling – discover the superpowers of GenAI in action with UiPath Document Understanding and Communications Mining™:
See how to accelerate model training and optimize model performance with active learning
Learn about the latest enhancements to out-of-the-box document processing – with little to no training required
Get an exclusive demo of the new family of UiPath LLMs – GenAI models specialized for processing different types of documents and messages
This is a hands-on session specifically designed for automation developers and AI enthusiasts seeking to enhance their knowledge in leveraging the latest intelligent document processing capabilities offered by UiPath.
Speakers:
👨🏫 Andras Palfi, Senior Product Manager, UiPath
👩🏫 Lenka Dulovicova, Product Program Manager, UiPath
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Ramesh Iyer
In today's fast-changing business world, Companies that adapt and embrace new ideas often need help to keep up with the competition. However, fostering a culture of innovation takes much work. It takes vision, leadership and willingness to take risks in the right proportion. Sachin Dev Duggal, co-founder of Builder.ai, has perfected the art of this balance, creating a company culture where creativity and growth are nurtured at each stage.
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf91mobiles
91mobiles recently conducted a Smart TV Buyer Insights Survey in which we asked over 3,000 respondents about the TV they own, aspects they look at on a new TV, and their TV buying preferences.
Elevating Tactical DDD Patterns Through Object CalisthenicsDorra BARTAGUIZ
After immersing yourself in the blue book and its red counterpart, attending DDD-focused conferences, and applying tactical patterns, you're left with a crucial question: How do I ensure my design is effective? Tactical patterns within Domain-Driven Design (DDD) serve as guiding principles for creating clear and manageable domain models. However, achieving success with these patterns requires additional guidance. Interestingly, we've observed that a set of constraints initially designed for training purposes remarkably aligns with effective pattern implementation, offering a more ‘mechanical’ approach. Let's explore together how Object Calisthenics can elevate the design of your tactical DDD patterns, offering concrete help for those venturing into DDD for the first time!
UiPath Test Automation using UiPath Test Suite series, part 4DianaGray10
Welcome to UiPath Test Automation using UiPath Test Suite series part 4. In this session, we will cover Test Manager overview along with SAP heatmap.
The UiPath Test Manager overview with SAP heatmap webinar offers a concise yet comprehensive exploration of the role of a Test Manager within SAP environments, coupled with the utilization of heatmaps for effective testing strategies.
Participants will gain insights into the responsibilities, challenges, and best practices associated with test management in SAP projects. Additionally, the webinar delves into the significance of heatmaps as a visual aid for identifying testing priorities, areas of risk, and resource allocation within SAP landscapes. Through this session, attendees can expect to enhance their understanding of test management principles while learning practical approaches to optimize testing processes in SAP environments using heatmap visualization techniques
What will you get from this session?
1. Insights into SAP testing best practices
2. Heatmap utilization for testing
3. Optimization of testing processes
4. Demo
Topics covered:
Execution from the test manager
Orchestrator execution result
Defect reporting
SAP heatmap example with demo
Speaker:
Deepak Rai, Automation Practice Lead, Boundaryless Group and UiPath MVP
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...DanBrown980551
Do you want to learn how to model and simulate an electrical network from scratch in under an hour?
Then welcome to this PowSyBl workshop, hosted by Rte, the French Transmission System Operator (TSO)!
During the webinar, you will discover the PowSyBl ecosystem as well as handle and study an electrical network through an interactive Python notebook.
PowSyBl is an open source project hosted by LF Energy, which offers a comprehensive set of features for electrical grid modelling and simulation. Among other advanced features, PowSyBl provides:
- A fully editable and extendable library for grid component modelling;
- Visualization tools to display your network;
- Grid simulation tools, such as power flows, security analyses (with or without remedial actions) and sensitivity analyses;
The framework is mostly written in Java, with a Python binding so that Python developers can access PowSyBl functionalities as well.
What you will learn during the webinar:
- For beginners: discover PowSyBl's functionalities through a quick general presentation and the notebook, without needing any expert coding skills;
- For advanced developers: master the skills to efficiently apply PowSyBl functionalities to your real-world scenarios.
JMeter webinar - integration with InfluxDB and GrafanaRTTS
Watch this recorded webinar about real-time monitoring of application performance. See how to integrate Apache JMeter, the open-source leader in performance testing, with InfluxDB, the open-source time-series database, and Grafana, the open-source analytics and visualization application.
In this webinar, we will review the benefits of leveraging InfluxDB and Grafana when executing load tests and demonstrate how these tools are used to visualize performance metrics.
Length: 30 minutes
Session Overview
-------------------------------------------
During this webinar, we will cover the following topics while demonstrating the integrations of JMeter, InfluxDB and Grafana:
- What out-of-the-box solutions are available for real-time monitoring JMeter tests?
- What are the benefits of integrating InfluxDB and Grafana into the load testing stack?
- Which features are provided by Grafana?
- Demonstration of InfluxDB and Grafana using a practice web application
To view the webinar recording, go to:
https://www.rttsweb.com/jmeter-integration-webinar
JMeter webinar - integration with InfluxDB and Grafana
Codemotion 2013 scalatra_play_spray
1. Massimiliano Dessì
&
Alberto Quario
Scala On Web
Play - Scalatra - Spray
Google Technology User Group Sardegna
1
Thursday, March 28, 13 1
2. Speakers
Massimiliano Dessì & Alberto Quario GTUG Sardegna
Max has more than 13 years of experience in
programming. He’s a proud father of three.
Manager of GTUG Sardegna, Founder of
SpringFramework IT, co-founder of Jug Sardegna.
Author of Spring 2.5 AOP. He works in Energeya and
lives in Cagliari, Italy.
Alberto has more than 15 years experience in
developing software, he wrote his first programs on a
TI-99/4A and hasn't stopped since. Other than
languages and development, Alberto's passions
include squash, cooking and Monet paintings. He
lives and works in Milano, Italy.
2
Thursday, March 28, 13 2
3. Agenda
Massimiliano Dessì & Alberto Quario GTUG Sardegna
Scalatra -Playframework -Spray
REST
JSON
Routing
Template
Actors
Sessions
Deploy
Hot Reloading
Test
3
Thursday, March 28, 13 3
4. Massimiliano Dessì & Alberto Quario GTUG Sardegna
Scalatra
is a web microframework
written in Scala
inspired to Sinatra
a Ruby DSL to build webapp
http://www.scalatra.org
the BBC, LinkedIn,
the Guardian,
games website IGN,
UK government
rely on Scalatra.
4
Thursday, March 28, 13 4
5. REST
Massimiliano Dessì & Alberto Quario GTUG Sardegna
class JellyBeans extends ScalatraServlet {
get("/jellybs/:id") { ... }
post("/jellybs") { ... }
put("/jellybs/:id") { ... }
delete("/jellybs/:id") { ... }
}
For browser add PUT & DELETE support client side
X-HTTP-METHOD-OVERRIDE or _method=put _method=delete in the post body
class JellyBeansBrowser extends ScalatraFilter with MethodOverride
5
Thursday, March 28, 13 5
7. Filter
Massimiliano Dessì & Alberto Quario GTUG Sardegna
class JellyBeans extends ScalatraServlet {
before() {
db.acquireConnecion
contentType="text/html" Like Servlet Filter
} (or Aspect Oriented Programming)
You can add logic before or the
get("/") { routes
val menu = db.findWelcome()
templateEngine.layout("index.ssp", menu)
}
after() {
db.releaseConnection
}
}
7
Thursday, March 28, 13 7
9. Handlers
Massimiliano Dessì & Alberto Quario GTUG Sardegna
Handlers are top level methods for http routines
class JellyBeans extends ScalatraServlet {
notFound {
<h1>Not found</h1>
}
halt(status = 301, headers =
Map("Location" -> "http://www.codemotion.com/"))
get("/jellybs/names/*") {
"Name not found!"
}
}
9
Thursday, March 28, 13 9
10. Handlers
Massimiliano Dessì & Alberto Quario GTUG Sardegna
class JellyBeans extends ScalatraServlet {
get("/jellybs/names/:who") {
params("who") match {
case "Cherry" => "Found Cherry!"
case _ => pass() /* call the next matching route route, routes are
matched from bottom up*/
}
}
get("/jellybs/download/:id") {
jellyBeanService.find(params("id")) match {
case Some(jellybean) => Ok(jellybean)
case None => NotFound("Sorry, jellybean not found")
}
}
}
10
Thursday, March 28, 13 10
11. Request Response & Friends
Massimiliano Dessì & Alberto Quario GTUG Sardegna
class JellyBeans extends ScalatraServlet {
get("/jellybs/shows/:id") {
//access to request,response, session and params
request.body //request body as a string
request.cookies // cookie map
request.isAjax // is ajaxRequest
request.getSession // HttpServletSession
request.locale // user locale
response.getOutputStream //response outputstream
servletContext.get("myIntParam") //servlet context
val idString = params("id")
val id = params.getAs[Int]("id")
//val id = params.getOrElse("id", halt(500)) //another way
....
}
}
11
Thursday, March 28, 13 11
13. Binding
Massimiliano Dessì & Alberto Quario GTUG Sardegna
To avoid manual binding from http and our Object Scalatra provide a binding module
case class MyClass(id: Integer, name: String)
post("/myroute") {
val cmd = command[CreateMyClassCommand]
...
}
13
Thursday, March 28, 13 13
14. Binding
Massimiliano Dessì & Alberto Quario GTUG Sardegna
Under the hood
abstract class MyClassCommand[S](implicit mf: Manifest[S])
extends ModelCommand[S] with JsonCommand {
implicit def todoStringValidators(b: FieldDescriptor[String]) =
new MyClassStringValidations(b)
}
class CreateMyClassCommand extends MyClassCommand[MyClass] {
protected implicit val jsonFormats = DefaultFormats
val name: Field[String] = asType[String]("name").notBlank.minLength(3)
}
14
Thursday, March 28, 13 14
15. Binding
Massimiliano Dessì & Alberto Quario GTUG Sardegna
Under the hood
class MyClassStringValidations(b: FieldDescriptor[String]) {
def startsWithCap(message: String = "%s must start with a capital letter.") =
b.validateWith(_ =>
_ flatMap {
new PredicateValidator[String](
b.name,
"""^[A-Z,0-9]""".r.findFirstIn(_).isDefined,
message).validate(_)
)
}
)
}
15
Thursday, March 28, 13 15
16. Gzip
Massimiliano Dessì & Alberto Quario GTUG Sardegna
class GzipJellyBeans extends ScalatraServlet with GZipSupport{
get("/") {
<html>
<body>
<h1>This is
<a href="http://en.wikipedia.org/wiki/Sparta">
http/gzip
</a>!
</h1>
</body>
</html>
}
}
16
Thursday, March 28, 13 16
17. Flash message
Massimiliano Dessì & Alberto Quario GTUG Sardegna
class FlashServlet extends ScalatraServlet with FlashMapSupport{
post("/jellybs/create") {
flash("notice") = "jellybean created successfully"
redirect("/home")
}
get("/home") {
ssp("/home") //Scala Server Pages
}
17
Thursday, March 28, 13 17
18. JSON
Massimiliano Dessì & Alberto Quario GTUG Sardegna
Automatic Serialization and deserialization of any Case class
object JSONServlet extends ScalatraServlet with JacksonJsonSupport{
case class JellyBean(id: Int, name: String, flavor:String)
protected implicit val jsonFormats: Formats = DefaultFormats
before() {
contentType = formats("json")
}
....
18
Thursday, March 28, 13 18
19. JSON
Massimiliano Dessì & Alberto Quario GTUG Sardegna
Automatic Serialization and deserialization of any Case class
object JSONServlet extends ScalatraServlet with JacksonJsonSupport{
...
get("/jellybs/all"){
jellyBeanRepo.all //from class to json
}
post("/jellybs/create") {
val jb = parsedBody.extract[JellyBean] //from json to class
...
}
}
19
Thursday, March 28, 13 19
20. Template
Massimiliano Dessì & Alberto Quario GTUG Sardegna
Html inline,
Scalate
Twirl (Play2 template)
Scalate
mean
SSP (Scala Server Page)
Scaml
Mustache
Jade
20
Thursday, March 28, 13 20
21. Template
Massimiliano Dessì & Alberto Quario GTUG Sardegna
class ScalateServlet extends ScalatraServlet with ScalateSupport{
get("/"jellybeans/ssp) {
contentType="text/html"
ssp("/index", "foo" -> "uno", "bar" -> "two")
// the layout used it’s WEB-INF/layouts/default.ssp
}
get("/jellybeans/jade") {
jade("/index", "layout" -> "", "foo" -> "one", "bar" -> "two")
// render without a layout.
}
get("/jellybeans/direct") {
templateEngine.layout("/jellybeans/index.ssp")
//direct invoking of scalate
}
21
Thursday, March 28, 13 21
22. Template
Massimiliano Dessì & Alberto Quario GTUG Sardegna
SSP
<%@ var body: String %>
<%@ var title: String = "Some Default Title" %>
<%@ var head: String = "" %>
<html>
<head>
<title>${title}</title>
<%-- page specific head goes here --%>
${unescape(head)}
</head>
<body>
<p>layout header goes here...</p>
${unescape(body)}
<p>layout footer goes here...</p>
</body>
</html>
22
Thursday, March 28, 13 22
23. Template
Massimiliano Dessì & Alberto Quario GTUG Sardegna
JADE
!!! 5
html(lang="en")
head
title= pageTitle
:javascript
if (foo) {
bar()
}
body
h1 Jade - node template engine
#container
- if (youAreUsingJade)
p You are amazing
- else
p Get on it!
:coffeescript
alert "Hello, Coffee!"
23
Thursday, March 28, 13 23
24. Template
Massimiliano Dessì & Alberto Quario GTUG Sardegna
Mustache
Hello {{name}}
You have just won ${{value}}!
{{#in_ca}}
Well, ${{taxed_value}}, after taxes.
{{/in_ca}}
24
Thursday, March 28, 13 24
25. Template
Massimiliano Dessì & Alberto Quario GTUG Sardegna
SCAML
!!! XML
!!!
%html
%head
%title Myspace
%body
%h1 I am the international space station
%p Sign my guestbook
25
Thursday, March 28, 13 25
26. Actors
Massimiliano Dessì & Alberto Quario GTUG Sardegna
Non Blocking and Async
with
Akka and Actors
26
Thursday, March 28, 13 26
27. Actors
Massimiliano Dessì & Alberto Quario GTUG Sardegna
The routes can returns a Future
class MyActorServlet(system:ActorSystem, myActor:ActorRef)
extends ScalatraServlet with FutureSupport {
import _root_.akka.pattern.ask
implicit val timeout = Timeout(10)
protected implicit def executor: ExecutionContext = system.dispatcher
get("/async") {
myActor ? "Do stuff and give me an answer"
}
get("/fire-forget") {
myActor ! "Hey, you know what?"
Accepted() //if you do not want return a future
}
}
27
Thursday, March 28, 13 27
28. Actors
Massimiliano Dessì & Alberto Quario GTUG Sardegna
get("/async") {
myActor ? "Do stuff and give me an answer"
}
get("/fire-forget") {
myActor ! "Hey, you know what?"
Accepted() //if you don’t want return a future
}
class CodemotionActor extends Actor {
def receive = {
case "Do stuff and give me an answer" => sender ! "The answer is 42"
case "Hey, you know what?" => println("Yeah I know...")
}
}
}
28
Thursday, March 28, 13 28
29. Actors
Massimiliano Dessì & Alberto Quario GTUG Sardegna
Akka start in the Bootstrap of Scalatra
class ScalatraBootstrap extends LifeCycle {
val system = ActorSystem()
val codemotionActor = system.actorOf(Props[CodemotionActor])
override def init(context: ServletContext) {
context.mount(new JSONServlet, "/jellybs/*")
context.mount(new FrontServlet, "/template/*")
context.mount(new MyActorServlet(system, codemotionActor), "/actors/*")
}
override def destroy(context:ServletContext) {
system.shutdown()
}
}
29
Thursday, March 28, 13 29
30. Authentication & Security
Massimiliano Dessì & Alberto Quario GTUG Sardegna
Scalatra uses Scentry a porting of Ruby Warden authentication
class OurAuthStrategy(protected override val app: ScalatraBase, realm: String)
extends BasicAuthStrategy[User](app, realm) {
protected def validate(userName: String, password: String): Option[User] = {
if(userName == "myusername" && password == "secret") Some(User("myusername"))
else None
}
protected def getUserId(user: User): String = user.id
}
case class User(id: String)
30
Thursday, March 28, 13 30
31. Authentication & Security
Massimiliano Dessì & Alberto Quario GTUG Sardegna
Now we need to combine our strategy and ScentrySupport
trait AuthenticationSupport extends ScentrySupport[User] with BasicAuthSupport[User] {
self: ScalatraBase =>
val realm = "Scalatra Basic Auth Example"
protected def fromSession = { case id: String => User(id) }
protected def toSession = { case usr: User => usr.id }
protected val scentryConfig = (new ScentryConfig {}).asInstanceOf[ScentryConfiguration]
}
31
Thursday, March 28, 13 31
32. Authentication & Security
Massimiliano Dessì & Alberto Quario GTUG Sardegna
Now we need to combine our strategy and ScentrySupport
trait AuthenticationSupport extends ScentrySupport[User] with BasicAuthSupport[User] {
....
override protected def configureScentry = {
scentry.unauthenticated {
scentry.strategies("Basic").unauthenticated()
scentry.strategies("")
}
}
override protected def registerAuthStrategies = {
scentry.register("Basic", app => new OurBasicAuthStrategy(app, realm))
}
protected def validate(userName: String, password: String): Option[User] = {
if(userName == "scalatra" && password == "scalatra") Some(User("scalatra"))
else None
}
}
32
Thursday, March 28, 13 32
33. Authentication & Security
Massimiliano Dessì & Alberto Quario GTUG Sardegna
Now we can use the Authentication for all routes defined in our Authenticated Servlets
class AuthenticatedServlet extends ScalatraServlet with AuthenticationSupport{
//every route goes under authentication
}
Unauthenticated user will see a browser prompt login
33
Thursday, March 28, 13 33
34. Deployment
Massimiliano Dessì & Alberto Quario GTUG Sardegna
The simplest way to deploy
your Scalatra application
is as a
Web application ARchive file
34
Thursday, March 28, 13 34
35. Deployment
Massimiliano Dessì & Alberto Quario GTUG Sardegna
Scalatra is based on regular Java Servlet 3.0
it can start from:
Standalone from jetty embedded
From Servlet container
Heroku
Jelastic
CloudBees
GAE (not out of the box )
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<listener>
<listener-class>org.scalatra.servlet.ScalatraListener</listener-class>
</listener>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/img/*</url-pattern>
<url-pattern>/css/*</url-pattern>
<url-pattern>/js/*</url-pattern>
<url-pattern>/assets/*</url-pattern>
</servlet-mapping>
</web-app>
35
Thursday, March 28, 13 35
36. Test
Massimiliano Dessì & Alberto Quario GTUG Sardegna
Test with Specs2
class FrontServletSpec extends ScalatraSpec {
def is =
"GET / on FrontServlet" ^
"should return status 200" ! root200 ^
end
addServlet(classOf[FrontServlet], "/*")
def root200 = get("/") {
status must_== 200
}
}
36
Thursday, March 28, 13 36
37. Hot reloading
Massimiliano Dessì & Alberto Quario GTUG Sardegna
Thanks JRebel for free Scala plan !
37
Thursday, March 28, 13 37
40. Routing
Massimiliano Dessì & Alberto Quario GTUG Sardegna
conf/routes
GET /clients/all controllers.Clients.list()
GET /clients/:id controllers.Clients.show(id: Long)
GET /clients/$id<[0-9]+> controllers.Clients.show(id: Long)
GET /clients controllers.Clients.list(page: Int ?= 1)
GET /api/list-all controllers.Api.list(Option[version])
40
Thursday, March 28, 13 40
41. Session
Massimiliano Dessì & Alberto Quario GTUG Sardegna
def index = Action { implicit request =>
session.get("connected").map { user =>
Ok("Hello " + user)
}.getOrElse {
Unauthorized("Oops, you are not connected")
}
}
Ok("Welcome!").withSession(
"connected" -> "user@gmail.com"
)
Ok("Welcome!").withSession(
session + ("saidHello" -> "yes") - "theme"
)
41
Thursday, March 28, 13 41
48. Non-blocking IO /2
Massimiliano Dessì & Alberto Quario GTUG Sardegna
def race() = Action {
Async {
val start = System.currentTimeMillis()
def getLatency(r: Any): Long = System.currentTimeMillis() - start
val googleTime = WS.url("http://www.google.com").get().map(getLatency)
val yahooTime = WS.url("http://www.yahoo.com").get().map(getLatency)
val bingTime = WS.url("http://www.bing.com").get().map(getLatency)
Future.sequence(Seq(googleTime, yahooTime, bingTime)).map {
case times =>
Ok(Json.toJson(Map(
"google" -> times(0),
"yahoo" -> times(1),
"bing" -> times(2),
"total" -> getLatency(0))))
}
}
}
{"google":343,"yahoo":3043,"bing":1608,"total":3048}
48
Thursday, March 28, 13 48
49. Test
Massimiliano Dessì & Alberto Quario GTUG Sardegna
class ApplicationSpec extends Specification {
"Application" should {
"send 404 on a bad request" in {
running(FakeApplication()) {
route(FakeRequest(GET, "/boum")) must beNone
}
}
"render the index page" in {
running(FakeApplication()) {
val home = route(FakeRequest(GET, "/")).get
status(home) must equalTo(OK)
contentType(home) must beSome.which(_ == "text/html")
contentAsString(home) must contain ("Your new application is ready.")
}
}
}
}
49
Thursday, March 28, 13 49
50. Test /2
Massimiliano Dessì & Alberto Quario GTUG Sardegna
class IntegrationSpec extends Specification {
"Application" should {
"work in a server" in {
running(TestServer(3333)) {
await(WS.url("http://localhost:3333").get).status must equalTo(OK)
}
}
"work from within a browser" in {
running(TestServer(3333), HTMLUNIT) { browser =>
browser.goTo("http://localhost:3333/")
browser.pageSource must contain("Your new application is ready.")
}
}
}
}
50
Thursday, March 28, 13 50
51. Deploy
Massimiliano Dessì & Alberto Quario GTUG Sardegna
51
Thursday, March 28, 13 51
52. Deploy /2
Massimiliano Dessì & Alberto Quario GTUG Sardegna
Welcome to Play 2.1.0!
These commands are available:
-----------------------------
classpath Display the project classpath.
clean Clean all generated files.
compile Compile the current application.
console Launch the interactive Scala console (use :quit to exit).
dependencies Display the dependencies summary.
dist Construct standalone application package.
exit Exit the console.
h2-browser Launch the H2 Web browser.
license Display licensing informations.
package Package your application as a JAR.
play-version Display the Play version.
publish Publish your application in a remote repository.
publish-local Publish your application in the local repository.
reload Reload the current application build file.
run <port> Run the current application in DEV mode.
test Run Junit tests and/or Specs from the command line
eclipse generate eclipse project file
idea generate Intellij IDEA project file
sh <command to run> execute a shell command
start <port> Start the current application in another JVM in PROD mode.
update Update application dependencies.
52
Thursday, March 28, 13 52
53. Massimiliano Dessì & Alberto Quario GTUG Sardegna
spray is an open-source toolkit for REST/HTTP
and
low-level network IO on top of Scala and Akka.
aka Scala -IKEA
VMWare and Ebay use spray
for some internal projects
53
Thursday, March 28, 13 53
54. Routing
Massimiliano Dessì & Alberto Quario GTUG Sardegna
class PingServiceActor extends Actor {
def receive = {
case HttpRequest(GET, "/ping", _, _, _) =>
sender ! HttpResponse(200, "PONG")
}
}
54
Thursday, March 28, 13 54
55. Routing
Massimiliano Dessì & Alberto Quario GTUG Sardegna
path with name order => directive route
get and put => are inner route
~ =>route concatenation
class MyServiceActor extends Actor with Routing {
def receive = receiveFromRoute {
path("order" / HexIntNumber) { id =>
get {
completeWith {
"Received GET for order " + id
}
} ~
put {
completeWith { "Received PUT for order " + id
}
}
}
}
}
55
Thursday, March 28, 13 55
56. Routing
Massimiliano Dessì & Alberto Quario GTUG Sardegna
trait LongerService extends HttpService with MyApp {
val simpleCache = routeCache(maxCapacity = 1000, timeToIdle = Duration("30 min"))
val route = {
path("orders") {
authenticate(BasicAuth(realm = "admin area")) { user =>
get {
cache(simpleCache) {
encodeResponse(Deflate) {
complete {
getOrdersFromDB
}
}
}
} ~
post {
(decodeRequest(Gzip) | decodeRequest(NoEncoding)) {
entity(as[Order]) { order =>
detachTo(singleRequestServiceActor) {
complete {
// ... write order to DB
"Order received"
}
}
}
}
}
}
} ~
56
Thursday, March 28, 13 56
57. Routing
Massimiliano Dessì & Alberto Quario GTUG Sardegna
pathPrefix("order" / IntNumber) { orderId =>
path("") {
// method tunneling via query param
(put | parameter('method ! "put")) {
// form extraction from multipart or www-url-encoded forms
formFields('email, 'total.as[Money]).as(Order) { order =>
complete {
// complete with serialized Future result
(myDbActor ? Update(order)).mapTo[TransactionResult]
}
}
} ~
get {
jsonpWithParameter("callback") {
produce(instanceOf[Order]) { complete => ctx =>
processOrderRequest(orderId, complete)
}
}
}
} ~
57
Thursday, March 28, 13 57
58. Non-blocking IO
Massimiliano Dessì & Alberto Quario GTUG Sardegna
def race() {
val start = System.currentTimeMillis()
def getLatency(r: Any): Long = System.currentTimeMillis() - start
val googleFuture = httpClient.ask(Get("http://www.google.com"))
.mapTo[HttpResponse].map(getLatency)
val yahooFuture = httpClient.ask(Get("http://www.yahoo.com"))
.mapTo[HttpResponse].map(getLatency)
val bingFuture = httpClient.ask(Get("http://www.example.com"))
.mapTo[HttpResponse].map(getLatency)
Future.sequence(Seq(googleFuture, yahooFuture, bingFuture)).map {
case times =>
log.info(
"google" + times(0) +
" yahoo" + times(1) +
" bing" + times(2) +
" total: "+getLatency(0))
system.shutdown() // stops all actors
}
}
58
Thursday, March 28, 13 58
59. Test
Massimiliano Dessì & Alberto Quario GTUG Sardegna
class DemoServiceSpec extends Specification with Specs2RouteTest with DemoService {
def actorRefFactory = system
"The DemoService" should {
"return a greeting for GET requests to the root path" in {
Get() ~> demoRoute ~> check { entityAs[String] must contain("Say hello") }
}
"return a 'PONG!' response for GET requests to /ping" in {
Get("/ping") ~> demoRoute ~> check { entityAs[String] === "PONG!" }
}
"leave GET requests to other paths unhandled" in {
Get("/kermit") ~> demoRoute ~> check { handled must beFalse }
}
"return a MethodNotAllowed error for PUT requests to the root path" in {
Put() ~> sealRoute(demoRoute) ~> check {
status === MethodNotAllowed
entityAs[String] === "HTTP method not allowed, supported methods: GET"
}
}
}
}
59
Thursday, March 28, 13 59
60. Massimiliano Dessì & Alberto Quario GTUG Sardegna
Q&A
60
Thursday, March 28, 13 60
61. Agenda
Massimiliano Dessì & Alberto Quario GTUG Sardegna
Thanks for your attention!
Massimiliano: @desmax74 Alberto :@realrealbot
61
Thursday, March 28, 13 61