Insert form data in Active MQ queue for send event.

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Insert form data in Active MQ queue for send event.

Rahul
Hi, Till on on click of send button the respective form data is sending to some external web service. Due to some mismatching session between portal and form runner I wanted to decide to send the form data in ActiveMQ queue for send button event. Now in order to customise the send method logic, I found the send method in "FormRunnerActions.scala" file as follows,

def trySend(params: ActionParams): Try[Any] =
        Try {
            implicit val formRunnerParams @ FormRunnerParams(app, form, formVersion, document, _) = FormRunnerParams()

            val propertyPrefixOpt = paramByNameOrDefault(params, "property")

            def findParamValue(name: String) = {

                def fromParam    = paramByName(params, name)
                def fromProperty = propertyPrefixOpt flatMap (prefix ⇒ formRunnerProperty(prefix + "." + name))
                def fromDefault  = DefaultSendParameters.get(name)

                fromParam orElse fromProperty orElse fromDefault
            }

            // This is used both as URL parameter and as submission parameter
            val dataVersion =
                findParamValue("data-format-version") map evaluateValueTemplate get

            val paramsToAppend =
                stringOptionToSet(findParamValue("parameters")).to[List]

            val paramValuesToAppend = paramsToAppend collect {
                case name @ "process"             ⇒ name → runningProcessId.get
                case name @ "app"                 ⇒ name → app
                case name @ "form"                ⇒ name → form
                case name @ "form-version"        ⇒ name → formVersion
                case name @ "document"            ⇒ name → document.get
                case name @ "valid"               ⇒ name → dataValid.toString
                case name @ "language"            ⇒ name → currentLang.stringValue
                case name @ "noscript"            ⇒ name → isNoscript.toString
                case name @ "data-format-version" ⇒ name → dataVersion
            }

            val propertiesAsPairs =
                SendParameterKeys map (key ⇒ key → findParamValue(key))

            // Append query parameters to the URL and evaluate XVTs
            val evaluatedPropertiesAsMap =
                propertiesAsPairs map {
                    case (n @ "uri",    s @ Some(_)) ⇒ n → (s map evaluateValueTemplate map (recombineQuery(_, paramValuesToAppend)))
                    case (n @ "method", s @ Some(_)) ⇒ n → (s map evaluateValueTemplate map (_.toLowerCase))
                    case (n,            s @ Some(_)) ⇒ n → (s map evaluateValueTemplate)
                    case other                       ⇒ other
                } toMap

            def findDefaultSerialization(method: String) = method match {
                case "post" | "put" ⇒ "application/xml"
                case _              ⇒ "none"
            }

            val effectiveSerialization =
                evaluatedPropertiesAsMap.get("serialization").flatten orElse
                    (evaluatedPropertiesAsMap.get("method").flatten map findDefaultSerialization)

            val evaluatedSendProperties =
                evaluatedPropertiesAsMap + ("serialization" → effectiveSerialization)

            // Create PDF if needed
            if (stringOptionToSet(evaluatedSendProperties("content")) exists Set("pdf", "pdf-url"))
                tryCreatePDFIfNeeded(EmptyActionParams).get

            // TODO: Remove duplication once @replace is an AVT
            val replace = if (evaluatedSendProperties.get("replace") exists (_ == Some("all"))) "all" else "none"

            // Set data-safe-override as we know we are not losing data upon navigation. This happens:
            // - with changing mode (tryChangeMode)
            // - when navigating away using the "send" action
            if (replace == "all")
                setvalue(persistenceInstance.rootElement \ "data-safe-override", "true")

            sendThrowOnError(s"fr-send-submission-$replace", evaluatedSendProperties)
        }

I have configured the send method control in "properties-local.xml" as follows,

<property
  as="xs:string"
  name="oxf.fr.detail.process.send.*.*"
  value='require-valid
         then send(uri = "http://localhost:9090/FRunner-portlet/html/jsp/formData.jsp", method="POST", content="xml")
                 then success-message("save-success")
                 recover error-message("database-error")'/>


Now i want to customise the send method as instead of sending the form data to specified URL, I want to insert the form data in the ActiveMQ queue. Let's say I have the following sample ActiveMQ code.

import java.io._
import javax.jms.Connection
import javax.jms.ConnectionFactory
import javax.jms.Destination
import javax.jms.JMSException
import javax.jms.MessageProducer
import javax.jms.Session
import javax.jms.TextMessage
import javax.portlet.PortletRequest
import javax.servlet.ServletException
import javax.servlet.annotation.WebServlet
import javax.servlet.http.Cookie
import javax.servlet.http.HttpServlet
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import org.apache.activemq.ActiveMQConnection
import org.apache.activemq.ActiveMQConnectionFactory
//remove if not needed
import scala.collection.JavaConversions._

class HelloWorldApp() {

  var factory: ConnectionFactory = null

  var connection: Connection = null

  var session: Session = null

  var destination: Destination = null

  var producer: MessageProducer = null

  try {
    factory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_BROKER_URL)
    connection = factory.createConnection()
    connection.start()
    session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE)
    destination = session.createQueue("SAMPLEQUEUE")
    producer = session.createProducer(destination)
    val message = session.createTextMessage()
    message.setText(formData) // Here I need to insert the form data....
    producer.send(message)
    println("Sent: " + message)
  } catch {
    case e: JMSException => e.printStackTrace()
  }
}


How do I integrate my sample code with send method in order to insert the form data in the ActiveMQ for Send button click event.

Thanks in advance..
Reply | Threaded
Open this post in threaded view
|

Re: Insert form data in Active MQ queue for send event.

Alessandro  Vernet
Administrator
Hi Rahul,

You could modify the code for send(), but instead, I'd recommend you implement your own code as an HTTP service in a separate servlet/JSP, and that you setup send() to call that service, passing along the data. This way your code isn't entangled with Orbeon Forms' code, which makes it easier to understand, and makes upgrading Orbeon Forms easier. Would that work for you?

Alex

On Thu, Mar 19, 2015 at 7:50 AM Rahul <[hidden email]> wrote:
Hi, Till on on click of send button the respective form data is sending to
some external web service. Due to some mismatching session between portal
and form runner I wanted to decide to send the form data in ActiveMQ queue
for send button event. Now in order to customise the send method logic, I
found the send method in "FormRunnerActions.scala" file as follows,

def trySend(params: ActionParams): Try[Any] =
        Try {
            implicit val formRunnerParams @ FormRunnerParams(app, form,
formVersion, document, _) = FormRunnerParams()

            val propertyPrefixOpt = paramByNameOrDefault(params, "property")

            def findParamValue(name: String) = {

                def fromParam    = paramByName(params, name)
                def fromProperty = propertyPrefixOpt flatMap (prefix ⇒
formRunnerProperty(prefix + "." + name))
                def fromDefault  = DefaultSendParameters.get(name)

                fromParam orElse fromProperty orElse fromDefault
            }

            // This is used both as URL parameter and as submission
parameter
            val dataVersion =
                findParamValue("data-format-version") map
evaluateValueTemplate get

            val paramsToAppend =
                stringOptionToSet(findParamValue("parameters")).to[List]

            val paramValuesToAppend = paramsToAppend collect {
                case name @ "process"             ⇒ name →
runningProcessId.get
                case name @ "app"                 ⇒ name → app
                case name @ "form"                ⇒ name → form
                case name @ "form-version"        ⇒ name → formVersion
                case name @ "document"            ⇒ name → document.get
                case name @ "valid"               ⇒ name →
dataValid.toString
                case name @ "language"            ⇒ name →
currentLang.stringValue
                case name @ "noscript"            ⇒ name →
isNoscript.toString
                case name @ "data-format-version" ⇒ name → dataVersion
            }

            val propertiesAsPairs =
                SendParameterKeys map (key ⇒ key → findParamValue(key))

            // Append query parameters to the URL and evaluate XVTs
            val evaluatedPropertiesAsMap =
                propertiesAsPairs map {
                    case (n @ "uri",    s @ Some(_)) ⇒ n → (s map
evaluateValueTemplate map (recombineQuery(_, paramValuesToAppend)))
                    case (n @ "method", s @ Some(_)) ⇒ n → (s map
evaluateValueTemplate map (_.toLowerCase))
                    case (n,            s @ Some(_)) ⇒ n → (s map
evaluateValueTemplate)
                    case other                       ⇒ other
                } toMap

            def findDefaultSerialization(method: String) = method match {
                case "post" | "put" ⇒ "application/xml"
                case _              ⇒ "none"
            }

            val effectiveSerialization =
                evaluatedPropertiesAsMap.get("serialization").flatten orElse
                    (evaluatedPropertiesAsMap.get("method").flatten map
findDefaultSerialization)

            val evaluatedSendProperties =
                evaluatedPropertiesAsMap + ("serialization" →
effectiveSerialization)

            // Create PDF if needed
            if (stringOptionToSet(evaluatedSendProperties("content")) exists
Set("pdf", "pdf-url"))
                tryCreatePDFIfNeeded(EmptyActionParams).get

            // TODO: Remove duplication once @replace is an AVT
            val replace = if (evaluatedSendProperties.get("replace") exists
(_ == Some("all"))) "all" else "none"

            // Set data-safe-override as we know we are not losing data upon
navigation. This happens:
            // - with changing mode (tryChangeMode)
            // - when navigating away using the "send" action
            if (replace == "all")
                setvalue(persistenceInstance.rootElement \
"data-safe-override", "true")

            sendThrowOnError(s"fr-send-submission-$replace",
evaluatedSendProperties)
        }

I have configured the send method control in "properties-local.xml" as
follows,

<property
  as="xs:string"
  name="oxf.fr.detail.process.send.*.*"
  value='require-valid
         then send(uri =
"http://localhost:9090/FRunner-portlet/html/jsp/formData.jsp",
method="POST", content="xml")
                 then success-message("save-success")
                 recover error-message("database-error")'/>


Now i want to customise the send method as instead of sending the form data
to specified URL, I want to insert the form data in the ActiveMQ queue.
Let's say I have the following sample ActiveMQ code.

import java.io._
import javax.jms.Connection
import javax.jms.ConnectionFactory
import javax.jms.Destination
import javax.jms.JMSException
import javax.jms.MessageProducer
import javax.jms.Session
import javax.jms.TextMessage
import javax.portlet.PortletRequest
import javax.servlet.ServletException
import javax.servlet.annotation.WebServlet
import javax.servlet.http.Cookie
import javax.servlet.http.HttpServlet
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import org.apache.activemq.ActiveMQConnection
import org.apache.activemq.ActiveMQConnectionFactory
//remove if not needed
import scala.collection.JavaConversions._

class HelloWorldApp() {

  var factory: ConnectionFactory = null

  var connection: Connection = null

  var session: Session = null

  var destination: Destination = null

  var producer: MessageProducer = null

  try {
    factory = new
ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_BROKER_URL)
    connection = factory.createConnection()
    connection.start()
    session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE)
    destination = session.createQueue("SAMPLEQUEUE")
    producer = session.createProducer(destination)
    val message = session.createTextMessage()
    message.setText(formData) // Here I need to insert the form data....
    producer.send(message)
    println("Sent: " + message)
  } catch {
    case e: JMSException => e.printStackTrace()
  }
}


How do I integrate my sample code with send method in order to insert the
form data in the ActiveMQ for Send button click event.

Thanks in advance..


--
View this message in context: http://discuss.orbeon.com/Insert-form-data-in-Active-MQ-queue-for-send-event-tp4659688.html
Sent from the Orbeon Forms community mailing list mailing list archive at Nabble.com.

--
You received this message because you are subscribed to the Google Groups "Orbeon Forms" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].

--
You received this message because you are subscribed to the Google Groups "Orbeon Forms" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
--
Follow Orbeon on Twitter: @orbeon
Follow me on Twitter: @avernet
Reply | Threaded
Open this post in threaded view
|

Re: Insert form data in Active MQ queue for send event.

Rahul
This post was updated on .
Dear Alex,

Till now I am doing the same way what you suggested me. I have created a separate HTTP service in my life ray portlet and sending data to that portlet. But the issue is the session sharing is not happening between portlet and the form runner. For the same reason I have created my own proxy portlet and rendering the form runner in my own proxy portlet still the session sharing is not possible. But at any cost I have to use the orbeon forms in portal. I tried all possible ways and wasted many days with experimenting to share the session, still no use. So finally I decided to add a logic in send method code that while sending the form data to some other external services I also wanted to add the form data in Activemq queue.

So please help me that how to send form data in Activemq queue for send event? I just need to send only form data which is there in xml format.

I will take care of version updates using some kind of hooks.

Can you please help me Where exactly are we getting the formData in xml format in "FormRunnerAction.scala" class so that I will store that xml format form data in a string format and will insert in to queue.

Thanks in advance.
Reply | Threaded
Open this post in threaded view
|

Re: Insert form data in Active MQ queue for send event.

Erik Bruchez
Administrator
This is a bit tricky: the Scala code only does part of the work (but it should probably do all of it in the future). At the end if delegates the actual sending to an XForms submission:

    sendThrowOnError(s"fr-send-submission-$replace", evaluatedSendProperties)

That submission is implemented in [universal-submission.xml][1].

There the XML is obtained in a few different ways, based on the value of `@content`, You could hookup there, calling Java from XPath. See how the call to `migration:dataMaybeMigratedFrom()` is done for example, with the namespace declaration:

    xmlns:migration="java:org.orbeon.oxf.fr.DataMigration"

I hope this helps,

-Erik

[1] https://github.com/orbeon/orbeon-forms/blob/e8933d7a192ff728cc166f4194b06f4001004cc7/src/resources/apps/fr/components/universal-submission.xml