Saturday, February 9, 2008

Scala and Lift snippet: taste of XML with Scala and Lift for simple XML over HTTP RPC protocol

The botlist application is a distributed system. Bots/Agents run in the background on some remote machine and send payloads to a web front end server. In this case, a J2EE server (botlist). Here is some of the code that makes that happen.

On the receiving end; a liftweb based application running on Tomcat:

The method remote_agent is associated with the remote_agent URI. It returns a XML response when a GET request is encountered. The remote_agent_send function is used to process POST requests from the stand-alone client.

import java.util.Random
import org.springframework.context.{ApplicationContext => AC}
import org.spirit.dao.impl.{BotListUserVisitLogDAOImpl => LogDAO}
import org.spirit.dao.impl.{BotListSessionRequestLogDAOImpl => SessDAO}
import org.spirit.bean.impl.{BotListUserVisitLog => Log}
import org.spirit.bean.impl.{BotListSessionRequestLog => Sess}
import net.liftweb.http._
import net.liftweb.http.S._
import net.liftweb.http.S
import scala.xml.{NodeSeq, Text, Group}
import net.liftweb.util.Helpers._
import javax.servlet.http.{HttpServlet, HttpServletRequest, HttpServletResponse, HttpSession}

import org.spirit.lift.agents._

class RemoteAgents (val request: RequestState, val httpRequest: HttpServletRequest) extends SimpleController {

def remote_agent_req : XmlResponse = {
// Cast to the user visit log bean (defined in the spring configuration)
val log_obj = AgentUtil.getAC(httpRequest).getBean("userVisitLogDaoBean")
val log_dao = log_obj.asInstanceOf[LogDAO]
val sess_obj = AgentUtil.getAC(httpRequest).getBean("sessionRequestLogDaoBean")
val sess_dao = sess_obj.asInstanceOf[SessDAO]
val uniq_id = AgentUtil.buildRequestSession(sess_dao, httpRequest, "request_auth", "true")
AgentUtil.auditLogPage(log_dao, httpRequest, "remote_agent")

<rdf:RDF xmlns:rdf="" >
<message>Hello my name is serverbot. Would you like some cake?</message>
<requestid>{ Text(uniq_id) }</requestid>
} // End of Method Request

def remote_agent_send : XmlResponse = {
var payload = ""
S.param("types_payload").map { (u => payload = u) }

if (S.post_?) XmlResponse { (
<rdf:RDF xmlns:rdf="" >
<message>Enjoy your cake</message>
</rdf:RDF>) }
else AgentUtil.invalidXMLResponse
} // End of Method Send


The client is a simple main application that connects to that URL and sends the XML payload request.

package org.spirit.spiderremote

import scala.xml._
import java.sql.{DriverManager}
import org.spirit.loadtest.{LoadTestManager}
import scala.collection.jcl.{HashMap, Map}

import org.spirit.spiderremote.model.AgentMessage

object SpiderRemote {

def main(args: Array[String]): Unit = {
Console.println("spider remote")
val conn = DriverManager.getConnection("jdbc:sqlite:../../../var/lib/spiderdb/contentdb/spider_queue.db")
val stat = conn.createStatement()
val rs = stat.executeQuery("select * from remotequeue")

while ( {
Console.println("name = " + rs.getString("url"))
// Connect to the server
val res_from_req = LoadTestManager.connectURL("", false)
val serv_agent_doc = XML.loadString(res_from_req(1))
val b = serv_agent_doc \\ "message"

// Post to server
val m = new java.util.HashMap
val map = new HashMap[String, String](m)
val types_msg_payload = new AgentMessage {
val message = "I enjoyed my cake."
val status = 200
val agentName = "botspiderremote"
val messageReqId = "123"

map("types_payload") = types_msg_payload.toXML.toString
val res_from_snd = LoadTestManager.postData(m, "", false)

Because my blog is at low-activity, I don't plan on explaining any further.

No comments: