Create a new project from scala seed
sbt new playframework/play-scala-seed.g8
Import in IntelliJ IDEA.
Open build.sbt and add:
Add as following
In plugin.sbt add the following
And enable the reverse plugin at build.sbt
Create a configuration file in project/scalikejdbc.properties
This configuration will allow us to create a model from existing db tables. Next step is to go a terminal (In IntelliJ IDEA there is a Terminal access on the botton, next to sbt terminal) in the root directory of your project and execute:
sbt "scalikejdbcGen messages Messages"
If all configurations are correct you will get a result like this:
After that a models package containing a Messages case class with the implementation of methods for CRUD are created in our project.
However the automation provided is awesome for this type of examples, since our table has a serial id we need to change the signature of our case class to exclude the id and to implement the date automatically (not provided by)
Amigos de la blogosfera, tenía muchas ganas de escribir este post. La idea original nació hace algún tiempo, en los años universitarios, tras leer el fantástico libro Travels amongst the great Andes of the Equator del Alpinista británico Edward Whymper pero por innumerables eventos (principalmente el abandono de este blog) nunca se concretó y hoy con el consecuente giro temático del mismo y contando la inspiración necesaria, me pongo manos a la obra.
Por cuestiones de trabajo suelo volar hasta la ciudad de Quito en numerosas ocasiones del año. Es una corta travesía que suele tomar entre 45 y 60 minutos dependiendo de las condiciones climáticas. Cuando estas son benévolas, el trayecto es tranquilo y permite disfrutar una vista a los colosos que se alinean a lo largo de la Avenida de los Volcanes, pero esto no es así siempre, siendo los Andes unos gigantes celosos, se suelen envolver en un manto nuboso que los distancia de ojos mortales.
If I had to suggest a place to visit while touring in Ecuador I would advise you to go downtown Quito. Although San Francisco de Quito, Ecuador’s capital city has grown as a vibrant metropolis with modern buildings and neighborhoods, what truly pays the visit of this city is its lovely colonial district (Centro Histórico). Hundreds of well-preserved buildings and churches of the Spanish Empire era can be found in this area. While walking through its narrow cobblestone streets you will feel like traveling back in time. Visiting the Church of «Compañia de Jesús» is a must. This magnificent church is one of the best examples of Baroque of Quito style being its most representative features the church’s volcanic rock facade and the imposing gold leaf details of its interior. It is, without a doubt Quito’s crown jewel, a place where the spirituality of its people meets the splendor of a long bygone era.
- Java 8+
- IDE: Eclipse.
- Apache Maven
- Create a Maven project with the option skip archetype selection.
- Add dependencies(selenium-java and TestNG* -can be replaced by JUnit-) to pom.xml. (hint can be found at https://mvnrepository.com)
- Create a TestNG class in src/test.
- Execute test.
Get TestNG eclipse plugin here: https://marketplace.eclipse.org/content/testng-eclipse
Do not forget to Download the Driver for your Browser (Chrome, although support for other exist)
- Postgres Driver /
- Flyway to add reactive non-blocking: flyway/flyway-play (play 2.4 +)/
- Scalikejdbc-async here
- Edit conf/application.conf add
play.modules.enabled += "org.flywaydb.play.PlayModule"
Add in conf/application.conf
# https://www.playframework.com/documentation/latest/Configuration play.modules.enabled += "org.flywaydb.play.PlayModule" # https://www.playframework.com/documentation/latest/Configuration # Database configuration # ~~~~~ # You can declare as many datasources as you want. # By convention, the default datasource is named `default` db.default.driver=org.postgresql.Driver db.default.url="jdbc:postgresql://locahost:5432/playapp" db.default.username=postgres db.default.password=sa logger.scalikejdbc=DEBUG # ScalikeJDBC original configuration #db.default.poolInitialSize=10 #db.default.poolMaxSize=10 #db.default.poolValidationQuery= scalikejdbc.global.loggingSQLAndTime.enabled=true scalikejdbc.global.loggingSQLAndTime.singleLineMode=false scalikejdbc.global.loggingSQLAndTime.logLevel=debug scalikejdbc.global.loggingSQLAndTime.warningEnabled=true scalikejdbc.global.loggingSQLAndTime.warningThresholdMillis=5 scalikejdbc.global.loggingSQLAndTime.warningLogLevel=warn play.modules.enabled += "scalikejdbc.PlayModule"
- Implement SuperMail model
- Create REST endpoints
- Add to routes
GET /bars:username controllers.Application.getSuperMails(username: String) POST /bars controllers.Application.createSuperMail
- Implement Controller
Original reactive post here.
More details to handle request here (Official lightbend)
Since a few days ago I’ve played (wink, wink) with Play, Lagom and Reactive Systems, I’ve found in the need of trying Some Scala and implement a REST API to access a Postgres Database, so instead of downloading, installing and configuring a database in my local machine I’ve felt tempted to use Vagrant instead.
Vagrant you say?
Vagrant is a tool for building and managing virtual machine environments in a single workflow. This tools “packages” our special box which is a small VM. A remarkable aspect is Vagrant relies on “providers” for virtualization. In this case, we’ll proceed first to install both Vagrant AND Virtualbox.
The beauty of Vagrant is that several boxes with preconfigured OSs, tools and services are ready to be implemented. Just search here for a Vagrant box of your needs.
sudo apt install virtualbox-qt
sudo apt install vagrant
Let’s get to it!
Get Postgres Vagrant box.
Open a Terminal. Create a directory in which you will download and place your Vagrant Machine.
The previous image comprises the following actions we have performed:
- Create a Postgres_Vagrant directory
- Download our Vagrant box.
- Open Vagranfile for this box.
Uncomment the following line of Vagrantfile
config.vm.network "private_network", ip: "192.168.33.10"
config.vm.network "forwarded_port", guest: 5432, host: 5432, host_ip: "127.0.0.1"
Save and close the Vagrantfile. Go back to your terminal and execute
This command will start the vm for this exercise.
Now we open VirtualBox and effectively our vm is ready.
That’s all! Now we can focus our effort on building our REST API to access a database, but that’s for another day).
Since I’m now in Russia, the Postgresql locale was set to “ru_RU.UTF-8”, but it’s necessary to change it to support locale to match my language “en_US.UTF-8”.
Change it like this
Part VI: Create a simple frontend App for our System.
- Create a new Scala module (microservice) for our project.
- Create the package.
- Create model WFForm
- Implement controllers.
- create package controllers
- create WFAbstractController
To be continued…
In previous post (available here.) we gave a try to Lagom and reactive microservices. We started by creating a sample Weather forecast App with three reactive microservices. Starting by the preparation and setup of tools needed, and the creation of service API and its implementation for the producer service that will deal with request that User will generate from a future UI (We’ll have the chance of play with Play framework).
In this part, we’ll create a consumer API and its implementation.
Part IV: Consumer API
- Open the project in the IDE and create a copy of the producer module and rename it as wf-consumer-api.
- Add this module to build.sbt.
- Go to model and refactor (rename):
- WFMessage to WeatherForecasting.
- Modify the Service API:
- Remove topic
- Change descriptor name to “wfconsumer”.
- Define functions to:
- Get Top Ten Weather Forecasts.
- Get one (the first) Weather Forecast. (findOneWFData)
- Get the latest Weather Forecast. (latestWF)
- Define the rest endpoints URI in descriptor to our consumer.
- Get for (findTopTenWFData)
- Get for (latestWF)
- Get for (latestWF)
- Remove the withTopics and withAutoAcl options of descriptor.
Part V: Implementing the Consumer Services
- Create model package and create the case class WeatherForecasting.
- Create companion object for Json serialization format.
- Modify the consumer’s WFCommand
- Extend ReplyType[T] (previously [Done])
- Create SaveNewWF case class and its companion object.
- Delete WF case class and its companion object.
- Rename WFSerializerRegistry to WFConsumerSerializerRegistry
- Add class to WFSerializerRegistry.
- EventTag does not require modification.
- Modify WFEvent. Refactor WFChanged to WFSaved and change its signature to receive a WeatherForecast object as parameter.
- Remove onReadOnlyCommand
- In onEvent change case and add message for detail of message.
- Modify WFEntity to implement saving messages to handle onCommand and on Event operations for all WFEvents. It is very important to note that this Entity manages components of CQRS/ES architecture.
- Modify WFLoader.
- Rename it to WFConsumerLoader
- Override load and loadDEvMode.
- Change abstract class WFConsumerApplication
- Add lazy vals for binding WFService client wfService and message repository (WFRepository).
- Override jsonSerializerRegistry.
- Add persistentEntityRegistry
- Add readSide.register(wire[WFEventProcessor])
- Implement WFRepository.
- Create package repositories.
- Create private [impl] class WFRepository its constructor receives CassandraSession.
- Implement method for data fetching according to rest endpoints:
- fetchWFData: to retrieve 10 elements
- fetchOneWFData: to retrieve one (first) register.
- Implement Consumer Service
- Create class WFConsumerServiceImpl.
- Override findTopTenWFData and findOneWFData
- change Loader in resources/application.conf
- Add binds to build.sbt.
In the next post, we’ll create a simple frontend for our Reactive System.
- Java 8
- IntelliJ IDEA
Part I: Preparation from Template
Create new lagom project from template.
sbt new lagom/lagom-scala.g8
- Import project into IDE.
- Refactor project-name-API to create producer API and IMPL.
- rename folder wfproducer-API.
- Rename module wfproducer-API.
- Change new names in
build.sbtlazy vals and bindings. Note: at this point you can remove lazy vals of stream services API and its implementation created by lagom template.
- Test by runAll. If you’ve done changes correct it’ll run.
Part II: Define a Producer Service API
- Delete stream-api and stream-impl services. Do not forget to remove their references (lazy val) from build.sbt
- Since we’re building a reactive Weather forecast system we’ll handle user events on wf-producer service.
- Rename wfreactiveService Scala class of wf-producer-API service. Take into consideration that a service API is an interface that in scala is declared with a trait, so make sure to rename using IDE’s refactor capabilities in order to keep consistency and find usages on other scala files.
- Extract model from service api implementation.
- Create model package inside api.
- Move class to the new model package.
- Rename class and its companion object to WFMessage.
- Open WFService.
- Change the topic to wfTemperature.
- Change signature of wfTemperature.
- Remove other functions definition.
- Rename greetingsTopic function to wfTopic and its signature.
- Include pathCall to wfTemperature in descriptor.
- Remove the addProperty Kafka part.
- Delete case class GreetingMessageChanged part.
Part III: Define a Producer Service Implementation (impl)
- Producer commands Creation:
- Sealed trait WFCommand
- Create companion objects for commands
- Create Serialized registry. Add all command case classes.
- Create system events:
- (sealed trait) WFEvent
- Create Event Tag (WFEventTag) for Service.
- Add system events case classes to Serialized registry.
- Create WFState
- Add WFState to Serialized registry.
- Modify WfreactiveEntity.
- Rename it to WFEntity.
- Change Initial State
- Implement WFLoader
- Rename it to WFLoader
- override lazy val jsonSerializerRegistry = WFSerializerRegistry
- Implement WFServiceImpl
- Change in application.conf values of Loader
play.application.loader = com.example.wfreactive.impl.WFLoader
(This is a guide, a draft, will be completed with images soon)