xmlrpc

Module that gives full compatibility with XML-RPC for Scala

License

License

GroupId

GroupId

com.github.jvican
ArtifactId

ArtifactId

xmlrpc_2.12
Last Version

Last Version

1.2.1
Release Date

Release Date

Type

Type

jar
Description

Description

xmlrpc
Module that gives full compatibility with XML-RPC for Scala
Project URL

Project URL

https://github.com/jvican/xmlrpc
Project Organization

Project Organization

com.github.jvican
Source Code Management

Source Code Management

https://github.com/jvican/xmlrpc.git

Download xmlrpc_2.12

How to add to project

<!-- https://jarcasting.com/artifacts/com.github.jvican/xmlrpc_2.12/ -->
<dependency>
    <groupId>com.github.jvican</groupId>
    <artifactId>xmlrpc_2.12</artifactId>
    <version>1.2.1</version>
</dependency>
// https://jarcasting.com/artifacts/com.github.jvican/xmlrpc_2.12/
implementation 'com.github.jvican:xmlrpc_2.12:1.2.1'
// https://jarcasting.com/artifacts/com.github.jvican/xmlrpc_2.12/
implementation ("com.github.jvican:xmlrpc_2.12:1.2.1")
'com.github.jvican:xmlrpc_2.12:jar:1.2.1'
<dependency org="com.github.jvican" name="xmlrpc_2.12" rev="1.2.1">
  <artifact name="xmlrpc_2.12" type="jar" />
</dependency>
@Grapes(
@Grab(group='com.github.jvican', module='xmlrpc_2.12', version='1.2.1')
)
libraryDependencies += "com.github.jvican" % "xmlrpc_2.12" % "1.2.1"
[com.github.jvican/xmlrpc_2.12 "1.2.1"]

Dependencies

compile (4)

Group / Artifact Type Version
org.scala-lang : scala-library jar 2.12.1
org.scalaz : scalaz-core_2.12 jar 7.2.8
com.typesafe.akka : akka-http-xml_2.12 jar 10.0.2
com.chuusai : shapeless_2.12 jar 2.3.2

test (1)

Group / Artifact Type Version
org.scalatest : scalatest_2.12 jar 3.0.1

Project Modules

There are no modules declared in this project.

Xmlrpc for Scala Build Status

This is a Scala library to talk to servers and clients via XML-RPC, originally created to connect to my university servers. This implementation is compliant with the specification.

What is XML-RPC?

Chances are, that if you are reading this, you already know what XML-RPC is. But, for the sake of completeness, here it is the definition from the specification:

XML-RPC is a Remote Procedure Calling protocol that works over the Internet. An XML-RPC message is an HTTP-POST request. The body of the request is in XML. A procedure executes on the server and the value it returns is also formatted in XML.

Despite that more powerful and modern rpc protocols are used nowadays, I have written this to support connection to older servers.

Dependencies

This library uses Akka HTTP to connect to any HTTP server. It would be easy to change that if one wants to use another library like Dispatch. You are free to fork this project and make the necesssary changes in Xmlrpc.scala, located in the main package.

Thanks to Scalaz, it offers good feedback in case of any failure with the help of Validation[T]. Validation is applicative, this means that all the errors in the process of deserialization will be accumulated.

Using Shapeless, we solve the problem of writing boilerplate code for any arity of case classes and tuples. If you are more interested in a library for serialization using Shapeless, you can check PicoPickle, an extensible, more powerful library entirely written in Shapeless.

Import to your project

This project cross-compiles to Scala 2.11 and 2.12.

In order to add it to your project, write the following in your build.sbt:

libraryDependencies ++= Seq("com.github.jvican" %% "xmlrpc" % "1.2.1")

What does this solve?

It solves the problem of serializing and deserializing types in a fancy way. Moreover, it does so simpler than other libraries, using the power of type classes and implicits. This technique was proposed by David McIver in sbinary and it's very powerful, being used broadly in json and xml libraries.

Usage

Serializing and Deserializing

A tiny example using case classes. Tuples, Option[T] and roughly any standard type can be used to read and write XML-RPC messages (if you want for some type in particular, please let me know). This example only shows the serialization and deserialization but not the use of invokeMethod. If you are implementing a server, you may use only this feature to reply the client.

import xmlrpc.protocol.XmlrpcProtocol._

// As you see, no boilerplate code is needed
case class Subject(code: Int, title: String)
case class Student(name: String, age: Int, currentGrade: Double, favorite: Subject)

val history = Subject(1, "Contemporary History")
val charles = Student("Charles de Gaulle", 42, 7.2, history)

// The only restriction is to explicitly mark the type
writeXmlRequest[Student]("addStudent", Some(charles))

// This is a confirmation from the server
case class Confirmation(message: String)

// Make sure you always mark the return type
readXmlResponse[Confirmation](<methodResponse>
  <params>
    <param>
      <value><string>{"Ok"}</string></value>
    </param>
  </params>
</methodResponse>)

Connecting to the server

First, import the library:

import xmlrpc.protocol.XmlrpcProtocol._
import xmlrpc.Xmlrpc._

If you don't have an Actor System in scope or you don't have an environment created for Akka HTTP, you must set it up:

implicit val system = ActorSystem()
implicit val ma = ActorMaterializer()
implicit val timeout = Timeout(5 seconds)
import system.dispatcher

Now, we set up the XML-RPC server and invoke any method:

implicit val testServer = XmlrpcServer("http://betty.userland.com/RPC2")
val response: XmlrpcResponse[Int] = invokeMethod[String, Int]("methodName", "Hello World!")

You don't have to explicit the type of the response. If you want to have a Future[Int], you can access the attribute underlying of the response. XmlrpcResponse is a wrapper useful when we want to invoke several methods, because it allow us to use for-comprehensions and chain them.

Issues

At this moment, it's not possible to serialize and deserialize Seq[Any]. For example, you cannot serialize List("a", 1). In case you need this, it's better to use case classes if the appearances of these types are cyclic, e.g. List("a", 1, "a", 1). When I have more time, I would include this functionality in the library.

Versions

Version
1.2.1
1.2