Build Status Build status Codacy Badge

Introduction to akka-ipp

This library allows for basic tcp queries by targeting the IPP/2.0 specifications. There are still many features which are missing but akka-ipp can already be used to

  • query a printer's capabilities
  • submit a job
  • query the status of a job
  • cancel jobs
  • do some polling on the job state

If your printer speaks IPP, then you can use this library in your Scala code and just print without any driver.


We suggest that you clone this repository and publish it locally.

sbt publishLocal

After that, you can use it in your sbt by adding the following dependency:

libraryDependencies += "de.envisia.akka" %% "akka-ipp" % "0.0.3"


Here is a simple usage example:

import de.envisia.akka.ipp.attributes.Attributes.WELL_KNOWN_PORT
import de.envisia.akka.ipp.IPPClient
import de.envisia.akka.ipp.Response
import de.envisia.akka.ipp.IPPConfig

import{ ActorMaterializer, Materializer }
import akka.http.scaladsl.Http
import scala.concurrent.{ Await, ExecutionContext, Future }
import scala.concurrent.duration._

implicit val actorSystem: ActorSystem = ActorSystem()
implicit val mat: Materializer = ActorMaterializer()
implicit val executionContext: ExecutionContext = actorSystem.dispatcher

val http = Http()
val client = new IPPClient(http)(mat, executionContext)

// all params except ip are optional
val config  = IPPConfig("", WELL_KNOWN_PORT, "print", Some("username"), 2.seconds) 
// Getting the printer attributes

val attrs: Future[Response.GetPrinterAttributesResponse] 
  = client.printerAttributes(config) // returns the Future of a response object

// Printing

import akka.util.ByteString
import java.nio.file.{ Files, Paths }

val x: ByteString = ByteString(Files.readAllBytes(Paths.get("examples/pdf-sample.pdf")))
val printJob = client.printJob(x, config)  // returns the Future of a PrintJob response

// Getting the Job Attributes

val jobAttrs: Future[Response.GetJobAttributesResponse] 
  = client.getJobAttributes(42, config) // returns the response data as a Scala Future

// Polling

val jobData: Future[Response.JobData] = client.poll(42, config) // polls the state of some job by job id

// Cancelling a job

val resp: Future[Response.CancelJobResponse] = client.cancelJob(42, config)

Usage with Dependency Injection (Guice) in PLAY

You can also use the library via DI, for example in your PLAY app.

class HttpExtProvider @Inject()(
  applicationLifecycle: ApplicationLifecycle
)(implicit actorSystem: ActorSystem, val executionContext: ExecutionContext, val mat: Materializer)
  extends Provider[HttpExt] {

  override lazy val get: HttpExt = {
    val innerHttp = Http()
    applicationLifecycle.addStopHook(() => innerHttp.shutdownAllConnectionPools())


class IppClientProvider @Inject()(
    http: HttpExt,
    applicationLifecycle: ApplicationLifecycle
)(implicit val executionContext: ExecutionContext, val mat: Materializer)
    extends Provider[IPPClient] {

  override lazy val get: IPPClient = {
    val innerClient = new IPPClient(http)
    applicationLifecycle.addStopHook(() => innerClient.shutdown())


Now you can just bind the IPPClient to the Provider:

class YourModule extends AbstractModule with AkkaGuiceSupport {
  override def configure(): Unit = {
    // IPP Printing Client
    // Akka HttpExt