Running Operon from Scala

To use Operon with Scala, the minimum Scala versions are 2.13.0, 2.12.4, 2.11.12. This is an example of minimal sbt-build -file:

val scala3Version = "3.0.0"

lazy val root = project
  .in(file("."))
  .settings(
    name := "scala3-simple",
    version := "0.1.0",

    scalaVersion := scala3Version,

    libraryDependencies ++= Seq(
		"com.novocode" % "junit-interface" % "0.11" % "test",
		"io.operon" % "operon-runner" % "0.6.0-SNAPSHOT"
	),

	resolvers += "operon-runner" at "https://operon.io:/maven-repository"
  )

Example

import io.operon.runner.model.OperonConfigs
import io.operon.runner.OperonRunner
import io.operon.runner.node.`type`._

def query = """

  Select:
    -> http:{"url": "https://api.coindesk.com/v1/bpi/currentprice.json"}
    .body
    ..EUR
    [1]
    .rate_float

"""

@main
def main: OperonValue = {
  val configs: OperonConfigs = new OperonConfigs()
  configs.setOutputResult(false)
  val result: OperonValue = OperonRunner.doQuery(query, configs)
  println(result)
  result
}

Calling Scala-code from Operon

In this example we will use the call-component, building on previous application. We will add a BtcAnalyzer -class.

This is how BtcAnalyzer.scala looks like:

package org.acme

import io.operon.runner.node.`type`._
import io.operon.runner.model.exception.OperonGenericException
import io.operon.runner.OperonFunction
import io.operon.runner.statement.Statement

class BtcAnalyzer extends OperonFunction {
    
    @throws(classOf[OperonGenericException])
    def execute(stmt: Statement, params: OperonValue): OperonValue = {
        println("Analyzing...")
        val num: NumberType = params.evaluate().asInstanceOf[NumberType]
        var result: StringType = null
        if (num.getDoubleValue() < 10000) {
            result = StringType.create(stmt, "BUY")
        }
        else {
            result = StringType.create(stmt, "HODL")
        }
        return result
    }
}

Let's modify the query from our previous application:

def query = """
  Select:
    -> http:{"url": "https://api.coindesk.com/v1/bpi/currentprice.json"}
    .body
    ..EUR
    [1]
    .rate_float
    -> call:analyze:{"params": @}
"""
What is new here is the "-> call" -part, where we want to call the BtcAnalyzer and pass it the numeric value we have obtained from the coindesk's Bitcoin price-API. Note that we can also use the "id" -option instead of component-id: -> call:{"id": "analyze", "params": @}.

The final step is to register the BTC-Analyzer to Operon (in the main -function):

  val analyzer: BtcAnalyzer = new BtcAnalyzer()
  OperonRunner.registerFunction("analyze", analyzer)
  // ... create configs and do query