Dependency injection in scala using guice - junit

I have the following class
class MigrateJob #Inject()(
val resultsMetadataRepo: ResultsMetadataRepo,
val resultsMetadataDao: ResultsMetadataDao,
val tenantProvisioningDao: TenantProvisioningDao,
val migrationOffsetDao: MigrationOffsetDao) extends Job {
def startULFMigrationJob(tenantId: String): Unit = {}
}
To test this MigrateJob class i have this in the test. Whats the syntax for boot strap initialization i am not able to follow and did not find working samples either.
#Test def launchWorkflow(): Unit = {
var guiceBundle =
GuiceBundle.newBuilder[SchedulerApiConfiguration].
addModule(new SchedulerModule)
.enableAutoConfig(getClass.getPackage.getName)
.setConfigClass(classOf[SchedulerApiConfiguration]).build
guiceBundle.initialize(new Bootstrap[SchedulerApiConfiguration](new SchedulerApiConfiguration()))
val injector = guiceBundle.getInjector
val migrateToULFJob = new MigrateToULFJob(
injector.getInstance(classOf[ResultsMetadataRepo]),
injector.getInstance(classOf[ResultsMetadataDao]),
injector.getInstance(classOf[TenantProvisioningDao]),
injector.getInstance(classOf[MigrationOffsetDao]))
migrateToULFJob.startULFMigrationJob(tenantId)

Related

how to pack zeros in to bundles in chisel

I have a question on pack zeros into bundles. For example consider the next code:
class CmplxNum(val bitwidth: Int) extends Bundle {
val real = SInt(INPUT,bitwidth.W)
val imag = SInt(INPUT,bitwidth.W)
}
class MyClass extends Module {
val io = IO(new Bundle {
val in = new CmplxNum(16)
val load = Bool(INPUT)
val clr = Bool(INPUT)
...
})
...
val sample = RegEnable(io.in,0.S,io.load) // <-- how do i set the reset value
When(io.clr) {
sample <> sample.fromBits(0.S) // <-- I tried this it compiles, but dont know if it is correct
}
}
How do I pack zeros into this Bundle in the RegEnable & clr cases ?
For RegEnable I've got elaboration error of type miss-match which make sense
Here is one way. It relies on the relatively new BundleLiterals (new CmplxNum(16)).Lit(_.real -> 0.S, _.imag -> 0.S). I have also refactored your code a little bit to use the current chisel3 idioms. Without a specific need I would not recommend placing your Input/Output in Bundle. Also the more modern way is to wrap the IO fields in Input() or Output()
import chisel3._
import chisel3.util.RegEnable
import chisel3.experimental.BundleLiterals._
class CmplxNum(val bitwidth: Int) extends Bundle {
val real = SInt(bitwidth.W)
val imag = SInt(bitwidth.W)
}
class MyClass extends Module {
val io = IO(new Bundle {
val in = Input(new CmplxNum(16))
val load = Input(Bool())
val clr = Input(Bool())
...
})
...
val sample = RegEnable(
io.in,
init = (new CmplxNum(16)).Lit(_.real -> 0.S, _.imag -> 0.S),
enable = io.load
)
when(io.clr) {
sample <> sample.fromBits(0.S) // <-- I tried this it compiles, but dont know if it is correct
}
}

Extracting a case class with an upper bound

I want to extract a case class from a JSON String, and reuse the code for every class.
Something like this question would have been perfect. But this means that I have to write for every class I want to extract.
I was hoping to do something like:
abstract class SocialMonitorParser[C <: SocialMonitorData] extends Serializable {
def toJSON(socialMonitorData: C): String = {
Requirements.notNull(socialMonitorData, "This field cannot be NULL!")
implicit val formats = DefaultFormats
write(socialMonitorData)
}
def fromJSON(json: String): Option[C] = {
implicit val formats = DefaultFormats // Brings in default date formats etc.
val jsonObj = liftweb.json.parse(json)
try {
val socialData = jsonObj.extract[C]
Some(socialData)
} catch {
case e: Exception => {
Logger.get(this.getClass.getName).warn("Unable to parse the following JSON:\n" + json + "\nException:\n" + e.toString())
None
}
}
}
}
But it gives me the following error:
Error:(43, 39) No Manifest available for C.
val socialData = jsonObj.extract[C]
Error:(43, 39) not enough arguments for method extract: (implicit formats: net.liftweb.json.Formats, implicit mf: scala.reflect.Manifest[C])C.
Unspecified value parameter mf.
val socialData = jsonObj.extract[C]
I was hoping I could do something like this, and maybe there is a way. But I can't wrap my head around this.
I will try to extend the question with some other information. Supposing I have Twitter and Facebook data, in case class like these:
case class FacebookData(raw_data: String, id: String, social: String) extends SocialMonitorData
case class TwitterData(...) extends SocialMonitorData{ ...}
I wish I could reuse the fromJSON and toJSON just once passing the Upper Bound type
class TwitterParser extends SocialMonitorParser[TwitterData] {
override FromJSON}
class FacebookParser extends SocialMonitorParser[FacebookData]
Much obliged.
I'm not sure why you want SocialMonitorParser to be abstract or Serializable or how are you going to use it but if you look closer at the error you may see that the compilers wants a Manifest for C. Manifest is a Scala way to preserve type information through the type erasure enforced onto generics by JVM. And if you fix that, then the code like this compiles:
import net.liftweb.json._
import net.liftweb.json.Serialization._
trait SocialMonitorData
case class FacebookData(raw_data: String, id: String, social: String) extends SocialMonitorData
class SocialMonitorParser[C <: SocialMonitorData : Manifest] extends Serializable {
def toJSON(socialMonitorData: C): String = {
// Requirements.notNull(socialMonitorData, "This field cannot be NULL!")
implicit val formats = DefaultFormats
write(socialMonitorData)
}
def fromJSON(json: String): Option[C] = {
implicit val formats = DefaultFormats // Brings in default date formats etc.
val jsonObj = parse(json)
try {
val socialData = jsonObj.extract[C]
Some(socialData)
} catch {
case e: Exception => {
// Logger.get(this.getClass.getName).warn("Unable to parse the following JSON:\n" + json + "\nException:\n" + e.toString())
None
}
}
}
}
and you can use it as
def test(): Unit = {
val parser = new SocialMonitorParser[FacebookData]
val src = FacebookData("fb_raw_data", "fb_id", "fb_social")
println(s"src = $src")
val json = parser.toJSON(src)
println(s"json = $json")
val back = parser.fromJSON(json)
println(s"back = $back")
}
to get the output exactly as one would expect.

Getting "No Json serializer found for type scala.concurrent.Future..." exception in Scala Play application

I am trying a web application with Scala Play 2, Slick 3 and PostgreSQL. My purpose to return JSON from controller.
These are the Dependencies -
libraryDependencies ++= Seq(
"org.postgresql" % "postgresql" % "9.4-1201-jdbc41",
"com.typesafe.slick" %% "slick" % "3.0.0",
"com.typesafe.play" %% "play-slick" % "1.0.1",
"com.typesafe.play" %% "play-slick-evolutions" % "1.0.1",
specs2 % Test
)
This is one of my Model -
package models
import play.api.libs.json.Json
import slick.driver.PostgresDriver.api._
import play.api.mvc._
import play.api.libs.json._
import play.api.libs.functional.syntax._
case class User (id: String, name: String)
class UserModel (tag: Tag) extends Table[User](tag, "USERS") {
def id = column[String]("ID", O.PrimaryKey)
def email = column[String]("EMAIL")
def * = (id, email) <> (User.tupled, User.unapply _)
}
object Users extends ModelInit {
lazy val users = TableQuery[UserModel]
implicit val userFormat = Json.format[User]
def all = {
db.run(users.result)
}
}
This is my Controller -
package controllers
import models.Users
import play.api.libs.json.Json
import play.api.mvc._
class Application extends Controller {
def index = Action {
val users = Users.all
val json = Json.toJson(users)
println(json)
Ok(views.html.index("Your new application is ready."))
}
}
Currently I am getting following exception-
No Json serializer found for type scala.concurrent.Future[Seq[models.UserModel#TableElementType]]. Try to implement an implicit Writes or Format for this type.
class Application extends Controller {
8 def index = Action {
9 val users = Users.all
10 val json = Json.toJson(users)
11 println(json)
12 Ok(views.html.index("Your new application is ready."))
13 }
14}
You need to do something like this :
class Application extends Controller {
def index = Action {
val users = Users.all
users.map(js => println(Json.toJson(js))) // this will give you Future[Unit] but instead of printing you can simply get Future[Json], i.e you can map one future into another future.
Ok(views.html.index("Your new application is ready."))
}
}
or
You can do a await on you future (Not recommended) and then serialize it.
import concurrent.duration._
val users = Await.result(Users.all,5.seconds)
val json = Json.toJson(users)
println(json)
PS: I have not tested it but that seems to be the solution.
You're trying to serialize Future (fancy callbacks). Future indicates data that will be awailable soon but now it's not. You can transform contents of futures however you want using map or flatMap(if it's nested, google monads for more details).
So to fix it.
def index = Action {
val users = Users.all
val json = Json.toJson(users)
json.map{ actualJson=>
//do something fancy
}
Ok(views.html.index("Your new application is ready."))
}
Although that code is blocking your thread. I suggest using Action.async which is asynchronous version of Action. It's pretty similar but it requires you to return Future[Result]. Which is pretty simple.
def index = Action.async {
val users = Users.all
val json = Json.toJson(users)
json.map{ actualJson =>
//do something fancy
println(actualJson)
Ok(views.html.index("Your new application is ready."))
}
}
Moving Json formatter to controller solved the issue.
My current Model -
package models
import play.api.libs.json.Json
import slick.driver.PostgresDriver.api._
import scala.concurrent.Future
case class User(id: String, name: String)
object Users extends ModelInit {
class UserModel(tag: Tag) extends Table[User](tag, "USERS") {
def id = column[String]("ID", O.PrimaryKey)
def email = column[String]("EMAIL")
def * = (id, email) <> (User.tupled, User.unapply)
}
lazy val users = TableQuery[UserModel]
def all = {
db.run(users.result)
}
def create(user: User): Future[Int] = {
db.run(users += user)
}
def getById(name: String) = {
val selectQuery = users.map(_.id)
val selectAction = selectQuery.result
db.run(selectAction)
}
}
And current Controller -
package controllers
import models.Users
import play.api.mvc._
import play.api.libs.concurrent.Execution.Implicits._
import play.api.libs.json._
class Application extends Controller {
def index = Action {
implicit val userFormat = Json.format[UserModel]
Users.all.map(user => println(Json.toJson(user)))
Ok(views.html.index("Your new application is ready."))
}
}
I'm using typesafe-activator play scala + slick and was having same issue. If JSON automated mapping is using companion objects, which i'm not actually sure about, makes sense why it cant find the formatter. moving formatter to controller like ASDF said and fixed the issue for now but i feel like it would be nicer to have in model file still
https://www.playframework.com/documentation/2.5.x/ScalaJsonAutomated
http://slick.lightbend.com/doc/3.0.0/schemas.html#mapped-tables

How can I infer widths from a flattened Bundle?

I am trying to wire a BlackBox to an arbitrary Bundle, but width inference does not seem to work with the fromBits function. The following compiles fine:
class testBundle extends Bundle {
val io1 = Bool(INPUT)
val io2 = UInt(INPUT,10)
}
class testBox extends BlackBox {
val io = new Bundle {
val in = Bits(INPUT) # Width inference works fine here
val out = Bits(OUTPUT,(new testBundle).getWidth) # But it doesn't work here!
}
}
class test extends Module {
val io = new Bundle {
val in = new testBundle
val out = (new testBundle).flip()
}
val testbox = Module(new testBox)
testbox.io.in := io.in.toBits
io.out := io.out.fromBits(testbox.io.out)
}
But if I remove the (new testBundle).getWidth argument, Chisel cannot infer the width of the output port and errors out. How can I get testBox to connect to arbitrary bundles?
For now I am solving this by passing in the bundle as an argument to the BlackBox:
class testBox(b:Bundle) extends BlackBox {
val w = b.getWidth
val io = new Bundle {
val in = Bits(INPUT,w)
val out = Bits(OUTPUT,w)
}
}
class test extends Module {
val io = new Bundle {
val in = new testBundle
val out = (new testBundle).flip()
}
val testbox = Module(new testBox(io.in))
testbox.io.in := io.in.toBits
io.out := io.out.fromBits(testbox.io.out)
}
I'd welcome a cleaner solution, though.

Spray json marshalling

I'm on a quest to create a JSON API where some of the models could be nicely generalized. I'm a newbie in Spray, so I started out a spike with an over simplified example.
However I can't figure out what is going on with the bellow code...
I have imported both
my custom implicits and
spray.httpx.SprayJsonSupport._
As I understand this is what I have to do in order to have an implicit in scope that can convert from JsonFormat to Marshaller.
Compiler error:
TestService.scala:15: could not find implicit value for parameter um: spray.httpx.unmarshalling.FromRequestUnmarshaller[my.company.Test[my.company.X]]
Code:
package my.company
import spray.routing.HttpService
import spray.json.{JsValue, JsObject, JsonFormat, DefaultJsonProtocol}
trait TestService extends HttpService {
import my.company.TestImplicits._
import spray.httpx.SprayJsonSupport._
val test =
path("test") {
post {
entity(as[Test[X]]) {
test => {
complete(s"type: ${test.common}")
}
}
}
}
}
trait Common {
def commonData: String
}
case class X(id: Long, commonData: String) extends Common
case class Y(commonData: String) extends Common
case class Test[T <: Common](comment: String, common: T)
object TestImplicits extends DefaultJsonProtocol {
implicit val xFormat = jsonFormat2(X)
implicit val yFormat = jsonFormat1(Y)
implicit val yTestFormat: JsonFormat[Test[Y]] = new JsonFormat[Test[Y]] {
def write(test: Test[Y]) = JsObject()
def read(js: JsValue) = Test("test", Y("y"))
}
implicit val xTestFormat: JsonFormat[Test[X]] = new JsonFormat[Test[X]] {
def write(test: Test[X]) = JsObject()
def read(js: JsValue) = Test("test", X(1L, "y"))
}
}
I would appreciate any help. Thanks in advance.
SOLVED
Solution was (as #jrudolp suggested) both to:
Move implicit definitions on top of the file (surprising)
Create RootJsonFormat rather than JsonFormat.