alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Akka/Scala example source code file (PojoSRTestSupport.scala)

This example Akka source code file (PojoSRTestSupport.scala) is included in my "Source Code Warehouse" project. The intent of this project is to help you more easily find Akka and Scala source code examples by using tags.

All credit for the original source code belongs to akka.io; I'm just trying to make examples easier to find. (For my Scala work, see my Scala examples and tutorials.)

Akka tags/keywords

bundledescriptorbuilder, class, collection, concurrent, duration, file, hashmap, maxwaitduration, osgi, reflection, servicereference, sleepytime, string, throwable, time, url

The PojoSRTestSupport.scala Akka example source code

/**
 * Copyright (C) 2009-2014 Typesafe Inc. <http://www.typesafe.com>
 */
package akka.osgi

import de.kalpatec.pojosr.framework.launch.{ BundleDescriptor, PojoServiceRegistryFactory, ClasspathScanner }

import scala.collection.JavaConversions.seqAsJavaList
import org.apache.commons.io.IOUtils.copy

import org.osgi.framework._
import java.net.URL
import java.util.jar.JarInputStream
import java.io._
import org.scalatest.{ BeforeAndAfterAll, Suite }
import java.util.{ UUID, Date, ServiceLoader, HashMap }
import scala.reflect.ClassTag
import scala.collection.immutable
import scala.concurrent.duration._
import scala.annotation.tailrec

/**
 * Trait that provides support for building akka-osgi tests using PojoSR
 */
trait PojoSRTestSupport extends Suite with BeforeAndAfterAll {

  val MaxWaitDuration = 12800.millis
  val SleepyTime = 50.millis

  /**
   * All bundles being found on the test classpath are automatically installed and started in the PojoSR runtime.
   * Implement this to define the extra bundles that should be available for testing.
   */
  def testBundles: immutable.Seq[BundleDescriptor]

  val bufferedLoadingErrors = new ByteArrayOutputStream()

  lazy val context: BundleContext = {
    val config = new HashMap[String, AnyRef]()
    System.setProperty("org.osgi.framework.storage", "target/akka-osgi/" + UUID.randomUUID().toString)

    val bundles = new ClasspathScanner().scanForBundles()
    bundles.addAll(testBundles)
    config.put(PojoServiceRegistryFactory.BUNDLE_DESCRIPTORS, bundles)

    val oldErr = System.err
    System.setErr(new PrintStream(bufferedLoadingErrors))
    try {
      ServiceLoader.load(classOf[PojoServiceRegistryFactory]).iterator.next.newPojoServiceRegistry(config).getBundleContext
    } catch {
      case e: Throwable ⇒ oldErr.write(bufferedLoadingErrors.toByteArray); throw e
    } finally {
      System.setErr(oldErr)
    }
  }

  // Ensure bundles get stopped at the end of the test to release resources and stop threads
  override protected def afterAll() = context.getBundles.foreach(_.stop)

  /**
   * Convenience method to find a bundle by symbolic name
   */
  def bundleForName(name: String) =
    context.getBundles.find(_.getSymbolicName == name).getOrElse(fail("Unable to find bundle with symbolic name %s".format(name)))

  /**
   * Convenience method to find a service by interface.  If the service is not already available in the OSGi Service
   * Registry, this method will wait for a few seconds for the service to appear.
   */
  def serviceForType[T](implicit t: ClassTag[T]): T =
    context.getService(awaitReference(t.runtimeClass)).asInstanceOf[T]

  def awaitReference[T](serviceType: Class[T]): ServiceReference[T] = awaitReference(serviceType, SleepyTime)

  def awaitReference[T](serviceType: Class[T], wait: FiniteDuration): ServiceReference[T] = {

    @tailrec def poll(step: Duration, deadline: Deadline): ServiceReference[T] = context.getServiceReference(serviceType.getName) match {
      case null ⇒
        if (deadline.isOverdue()) fail("Gave up waiting for service of type %s".format(serviceType))
        else {
          Thread.sleep((step min deadline.timeLeft max Duration.Zero).toMillis)
          poll(step, deadline)
        }
      case some ⇒ some.asInstanceOf[ServiceReference[T]]
    }

    poll(wait, Deadline.now + MaxWaitDuration)
  }

  protected def buildTestBundles(builders: immutable.Seq[BundleDescriptorBuilder]): immutable.Seq[BundleDescriptor] =
    builders map (_.build)

  def filterErrors()(block: ⇒ Unit): Unit =
    try block catch { case e: Throwable ⇒ System.err.write(bufferedLoadingErrors.toByteArray); throw e }
}

object PojoSRTestSupport {
  /**
   * Convenience method to define additional test bundles
   */
  def bundle(name: String) = new BundleDescriptorBuilder(name)
}

/**
 * Helper class to make it easier to define test bundles
 */
class BundleDescriptorBuilder(name: String) {

  import org.ops4j.pax.tinybundles.core.TinyBundles

  val tinybundle = TinyBundles.bundle.set(Constants.BUNDLE_SYMBOLICNAME, name)

  /**
   * Add a Blueprint XML file to our test bundle
   */
  def withBlueprintFile(name: String, contents: URL): BundleDescriptorBuilder = {
    tinybundle.add("OSGI-INF/blueprint/%s".format(name), contents)
    this
  }

  /**
   * Add a Blueprint XML file to our test bundle
   */
  def withBlueprintFile(contents: URL): BundleDescriptorBuilder = {
    val filename = contents.getFile.split("/").last
    withBlueprintFile(filename, contents)
  }

  /**
   * Add a Bundle activator to our test bundle
   */
  def withActivator(activator: Class[_ <: BundleActivator]): BundleDescriptorBuilder = {
    tinybundle.set(Constants.BUNDLE_ACTIVATOR, activator.getName)
    this
  }

  /**
   * Build the actual PojoSR BundleDescriptor instance
   */
  def build: BundleDescriptor = {
    val file: File = tinybundleToJarFile(name)
    new BundleDescriptor(getClass().getClassLoader(), new URL("jar:" + file.toURI().toString() + "!/"), extractHeaders(file))
  }

  def extractHeaders(file: File): HashMap[String, String] = {
    import scala.collection.JavaConverters.iterableAsScalaIterableConverter
    val headers = new HashMap[String, String]()
    val jis = new JarInputStream(new FileInputStream(file))
    try {
      for (entry ← jis.getManifest.getMainAttributes.entrySet.asScala)
        headers.put(entry.getKey.toString, entry.getValue.toString)
    } finally jis.close()

    headers
  }

  def tinybundleToJarFile(name: String): File = {
    val file = new File("target/%s-%tQ.jar".format(name, new Date()))
    val fos = new FileOutputStream(file)
    try copy(tinybundle.build(), fos) finally fos.close()

    file
  }
}

Other Akka source code examples

Here is a short list of links related to this Akka PojoSRTestSupport.scala source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.