All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.snice.gatling.diameter.protocol.DiameterConfig.scala Maven / Gradle / Ivy

The newest version!
package io.snice.gatling.diameter.protocol

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.module.SimpleModule
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module
import com.fasterxml.jackson.module.scala.{DefaultScalaModule, ScalaObjectMapper}
import com.typesafe.config.{ConfigValue, ConfigValueType}
import io.gatling.core.config.GatlingConfiguration
import io.snice.functional.Maps
import io.snice.networking.config.{NetworkInterfaceConfiguration, NetworkInterfaceDeserializer}
import io.snice.networking.diameter.peer.PeerConfiguration

import scala.collection.JavaConverters._

object DiameterConfig {

  /**
   * Extract out the diameter configuration out of the Gatling config object.
   * If there is no diameter section defined, then create a default configuration
   * object.
   */
  def apply(gatlingConfiguration: GatlingConfiguration): DiameterConfig = {
    val gatling = gatlingConfiguration.config.getObject("gatling")
    val conf  = Option(gatling.get("diameter")) match {
      case Some(v) => flattenGatlingConf(v)
      case None => defaultConfiguration()
    }

    DiameterConfig(conf)
  }

  /**
   * This is quite annoying. The Lightbend Config stuff is quite nice but this conversion between
   * scala/java, special flat mapping and what not is really annoying.
   *
   * And looking at what Gatling themselves are doing doing, they manually will extract out all keys
   * and build up the objects, which is what I'm trying to avoid here. I just want to be able
   * to map to case classes and be done with it.
   */
  def flattenGatlingConf(value: ConfigValue): Map[String, Any] = {
    if (value.valueType() != ConfigValueType.OBJECT) {
      throw new IllegalArgumentException(s"Unexpected type ${value.valueType()}. " +
        s"It is expected that the diameter section of type ${ConfigValueType.OBJECT}")
    }

    // Note: not correct. Could be a list as well.
    val raw = value.unwrapped().asInstanceOf[java.util.Map[String, Object]]
    val interfaces: List[Map[String, Any]] = Option(raw.get("interfaces")) match {
      case Some(ifs) => Maps.flatten("name", ifs).asScala.toStream.map(_.asScala.toMap).toList
      case None => List(defaultInterfaceConfig())
    }

    val peers: List[Map[String, Any]] = Option(raw.get("peers")) match {
      case Some(ifs) => Maps.flatten("name", ifs).asScala.toStream.map(_.asScala.toMap).toList
      case None => List(defaultPeerConfig())
    }

    Map("interfaces" -> interfaces, "peers" -> peers)
  }

  def apply(conf: Map[String, Any]): DiameterConfig = {
    val mapper = new ObjectMapper() with ScalaObjectMapper
    mapper.registerModule(new Jdk8Module)
    mapper.registerModule(DefaultScalaModule)

    val module = new SimpleModule
    module.addDeserializer(classOf[NetworkInterfaceConfiguration], new NetworkInterfaceDeserializer)
    mapper.registerModule(module)

    val json = mapper.writeValueAsString(conf)
    mapper.readValue[DiameterConfig](json)
  }

  /**
   * The default configuration if the user did not specify one.
   */
  private def defaultConfiguration() : Map[String, Any] = {
    val interfaces = List(defaultInterfaceConfig())
    val peers = List(defaultPeerConfig())
    Map("interfaces" -> interfaces, "peers" -> peers)
  }

  /**
   * Default interface configuration if the user did not specify one.
   *
   * Note that these default values are part of the public contract and as such,
   * if you do change them you will also have to update the public documentation.
   */
  private def defaultInterfaceConfig() : Map[String, Any] =
    Map("name" -> "default", "address" -> "aaa://*:3868", "isDefault" -> true)

  /**
   * Default peer configuration if the user did not specify one.
   *
   * Note that these default values are part of the public contract and as such,
   * if you do change them you will also have to update the public documentation.
   */
  private def defaultPeerConfig() : Map[String, Any] = Map("name" -> "default")
}

/**
 * Class containing the configuration of the underlying diameter stack.
 */
final case class DiameterConfig(interfaces: List[NetworkInterfaceConfiguration], peers: List[PeerConfiguration])

/**
 *
 * @param name
 * @param address
 * @param isDefault
 */
final case class InterfaceConfig(name: String, address: String, isDefault: Boolean = false)

/**
 * Case class containing the configuration of an individual peer.
 */
final case class PeerConfig(name: String)




© 2015 - 2024 Weber Informatics LLC | Privacy Policy