Play Module

Specific Commands

Recipe Test
  • route : the string next to route decides the url path for this module
route "valey-api"
  • role-ref : actions, command actions, views are protected by these roles, user logged in with mentioned role only can execute the action
role-ref Supervisor("Supervisor"), Worker("Worker")
  • contextual-role-ref : For every contextual role mentioned within the action, a class gets generated under /app/writer/<writer name>/<action name>RoleResolver.scala. Need to provide the implementation of the method resolve(). The method returns boolean to decide the execution of the action is possible with the role with which the user logged in.
contextual-role-ref FlowSupervisor("FlowSupervisor"), TaskSupervisor("TaskSupervisor")
  • role-group :A convenience utility, instead of mentioning multiple roles within actions, can create a group and mention that to protect the action
role-group Assembler(Supervisor,Worker)
  • web-writer : Hosts multiple actions/command actions. FlowWebWriterTrait and FlowWebWriterCode gets generated,and all the actions are listed as ‘def’ under these class. First one is the interface and the later one implements that. FlowWebWriterTrait is under src-gen and anytime defintion changes in ‘kplay’, its get regenerated, and compiler guides us to fix the mismatch. Any action gets added to the definition then FlowWebWriterTrait has the code under commented section that needs to be added in FlowWebWriterCode.
web-writer Flow {
    domain-ref flowDomain:ValeyDomain::Flow //This play module must depend on ValeyDomain
    //command-action (POST/DELETE/HEAD/OPTIONS/PUT)
    command-action create(POST) ValeyDomain::Flow.create {
        {authenticate {contextual(FlowSupervisor)}}
        provide-input whoCreated = `authUser(request)`
        pre {
            require flowNameExists  => flowDomain.flowNameExists(input.fqFlowName)
        }
    }
    //action (POST/DELETE/HEAD/OPTIONS/PUT)
    action canCreateDocument(POST){ //("ccd"){ url path for canCreateDocument can be altered . Now path will be "/ccd"
        {authenticate {contextual(FlowSupervisor)}}
        input(fqFlowName: String, initDocument: String)
        pre {
            require flowNameExists  => flowDomain.flowNameExists(input.fqFlowName)
        }
        output(Boolean)
    }
}
  • web-reader : Hosts multiple views. FlowWebReaderTrait and FlowWebReaderCode gets generated, and all the views are listed as def under these classes. First one is the interface and the later one implements that. FlowWebReaderTrait is under src-gen and anytime defintion changes in ‘kplay’, its get regenerated, and compiler guides us to fix the mismatch. Any view gets added to the definition in kplay then FlowWebReaderTrait has the code under commented section that needs to be added in FlowWebReaderCode.
web-reader Flow {
    domain-ref flowDomain:ValeyDomain::Flow //This play module must depend on ValeyDomain
    query-ref flowQuery:ValeyQuery::Flow //This play module must depend on ValeyQuery
    view getInitDocumentSchema(GET) { //("gIs") { url path for getInitDocumentSchema can be altered . Now path will be "/gis"
        {authenticate {contextual(FlowSupervisor)}}
        input(fqFlowName: String)
        pre {
            require flowNameExists  => flowDomain.flowNameExists(input.fqFlowName)
        }
        output(initDocumentSchema : String)
    }
  • swagger : writer and reader api(s) expose here to test them through browser
swagger api {
    writer LotteryPlay::Lottery
    reader LotteryPlay::Lottery
}

Recipes

web-writer/web-reader : Write code for actions/views which are under FlowWebWriterCode/FlowWebReaderCode. (??Details on request response??)

  override def getInitDocumentSchema: Request[GetInitDocumentSchemaView.Input] => GetInitDocumentSchemaView.Output = {
  import GetInitDocumentSchemaView._
  request: Request[Input] =>
    val input = request.body
    SmileApi.getFlow(input.fqFlowName).map {
      flow =>
        GetInitDocumentSchemaView.Output(initDocumentSchema = flow.initDocumentSchema(input.netName))
    }.getOrElse(GetInitDocumentSchemaView.Output("{}"))
}
swagger: >run
Browse http://localhost:9000/swagger and explore api

Test

Test play module api through swagger(localhost:9000/swagger), however for each web-writer and web-reader one test file gets generated under test/writer(or reader) dir. Write code there to test the module

class <web-reader name>ReaderTestSuite extends FunSuite with SmilePerTest {
    test("test1", Tag("tag1")) {
}
> test //This will run entire test cases
> test-only *.<ClassName>.scala -- -n <tagName>