Skip to content

Commit

Permalink
Merge pull request #439 from iRevive/rename-resource
Browse files Browse the repository at this point in the history
Rename `Resource` -> `TelemetryResource`
  • Loading branch information
iRevive authored Jan 18, 2024
2 parents f975b41 + 747e95f commit 6c5dc75
Show file tree
Hide file tree
Showing 14 changed files with 93 additions and 82 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,20 @@ package sdk
import cats.Hash
import cats.Show
import cats.syntax.all._
import org.typelevel.otel4s.sdk.Resource.ResourceInitializationError
import org.typelevel.otel4s.sdk.TelemetryResource.ResourceInitializationError
import org.typelevel.otel4s.semconv.resource.attributes.ResourceAttributes._

/** [[Resource]] serves as a representation of a resource that captures
/** [[TelemetryResource]] serves as a representation of a resource that captures
* essential identifying information regarding the entities associated with
* reported signals, such as statistics or traces.
*
* @see
* [[https://opentelemetry.io/docs/specs/otel/overview/#resources]]
*
* @see
* [[https://opentelemetry.io/docs/specs/otel/resource/sdk]]
*/
sealed trait Resource {
sealed trait TelemetryResource {

/** An [[Attributes]] associated with the resource.
*/
Expand All @@ -40,7 +43,7 @@ sealed trait Resource {
*/
def schemaUrl: Option[String]

/** Merges [[Resource]] into another [[Resource]].
/** Merges [[TelemetryResource]] into another [[TelemetryResource]].
*
* Schema URL merge outcomes:
* - if `this` resource's schema URL is empty then the `other` resource's
Expand All @@ -57,42 +60,44 @@ sealed trait Resource {
*
* @note
* if the same attribute exists in both resources, the attribute from the
* `other` [[Resource]] will be retained.
* `other` [[TelemetryResource]] will be retained.
*
* @param other
* the other [[Resource]] to merge with
* the other [[TelemetryResource]] to merge with
*
* @return
* a new [[Resource]] with the merged attributes
* a new [[TelemetryResource]] with the merged attributes
*/
def merge(other: Resource): Either[ResourceInitializationError, Resource]
def merge(
other: TelemetryResource
): Either[ResourceInitializationError, TelemetryResource]

/** Unsafe version of [[merge]] which throws an exception if the merge fails.
*
* @param other
* the other [[Resource]] to merge with
* the other [[TelemetryResource]] to merge with
*/
def mergeUnsafe(other: Resource): Resource
def mergeUnsafe(other: TelemetryResource): TelemetryResource

override final def hashCode(): Int =
Hash[Resource].hash(this)
Hash[TelemetryResource].hash(this)

override final def equals(obj: Any): Boolean =
obj match {
case other: Resource => Hash[Resource].eqv(this, other)
case _ => false
case other: TelemetryResource => Hash[TelemetryResource].eqv(this, other)
case _ => false
}

override final def toString: String =
Show[Resource].show(this)
Show[TelemetryResource].show(this)

}

object Resource {
private val Empty: Resource =
Resource(Attributes.empty, None)
object TelemetryResource {
private val Empty: TelemetryResource =
TelemetryResource(Attributes.empty, None)

private val Default: Resource = {
private val Default: TelemetryResource = {
val telemetrySdk = Attributes(
Attribute(TelemetrySdkName, "otel4s"),
Attribute(TelemetrySdkLanguage, TelemetrySdkLanguageValue.Scala.value),
Expand All @@ -103,60 +108,66 @@ object Resource {
Attribute(ServiceName, "unknown_service:scala")
)

Resource(telemetrySdk |+| mandatory, None)
TelemetryResource(telemetrySdk |+| mandatory, None)
}

sealed abstract class ResourceInitializationError extends Throwable
object ResourceInitializationError {
case object SchemaUrlConflict extends ResourceInitializationError
}

/** Creates a [[Resource]] with the given `attributes`. The `schemaUrl` will
* be `None.`
/** Creates a [[TelemetryResource]] with the given `attributes`. The
* `schemaUrl` will be `None.`
*
* @param attributes
* the attributes to associate with the resource
*/
def apply(attributes: Attributes): Resource =
def apply(attributes: Attributes): TelemetryResource =
Impl(attributes, None)

/** Creates a [[Resource]] with the given `attributes` and `schemaUrl`.
/** Creates a [[TelemetryResource]] with the given `attributes` and
* `schemaUrl`.
*
* @param attributes
* the attributes to associate with the resource
*
* @param schemaUrl
* schema URL to associate with the result
*/
def apply(attributes: Attributes, schemaUrl: Option[String]): Resource =
def apply(
attributes: Attributes,
schemaUrl: Option[String]
): TelemetryResource =
Impl(attributes, schemaUrl)

/** Returns an empty [[Resource]].
/** Returns an empty [[TelemetryResource]].
*
* It is strongly recommended to start with [[Resource.default]] instead of
* this method to include SDK required attributes.
* It is strongly recommended to start with [[TelemetryResource.default]]
* instead of this method to include SDK required attributes.
*/
def empty: Resource = Empty
def empty: TelemetryResource = Empty

/** Returns the default [[Resource]]. This resource contains the default
* attributes provided by the SDK.
/** Returns the default [[TelemetryResource]]. This resource contains the
* default attributes provided by the SDK.
*/
def default: Resource = Default
def default: TelemetryResource = Default

implicit val showResource: Show[Resource] =
r => show"Resource{attributes=${r.attributes}, schemaUrl=${r.schemaUrl}}"
implicit val showResource: Show[TelemetryResource] =
r =>
show"TelemetryResource{attributes=${r.attributes}, schemaUrl=${r.schemaUrl}}"

implicit val hashResource: Hash[Resource] =
implicit val hashResource: Hash[TelemetryResource] =
Hash.by(r => (r.attributes, r.schemaUrl))

private final case class Impl(
attributes: Attributes,
schemaUrl: Option[String]
) extends Resource {
) extends TelemetryResource {

def merge(other: Resource): Either[ResourceInitializationError, Resource] =
if (other == Resource.Empty) Right(this)
else if (this == Resource.Empty) Right(other)
def merge(
other: TelemetryResource
): Either[ResourceInitializationError, TelemetryResource] =
if (other == TelemetryResource.Empty) Right(this)
else if (this == TelemetryResource.Empty) Right(other)
else {
(other.schemaUrl, schemaUrl) match {
case (Some(otherUrl), Some(url)) if otherUrl != url =>
Expand All @@ -167,7 +178,7 @@ object Resource {
}
}

def mergeUnsafe(other: Resource): Resource =
def mergeUnsafe(other: TelemetryResource): TelemetryResource =
merge(other).fold(throw _, identity)

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ import munit.DisciplineSuite
import org.typelevel.otel4s.sdk.scalacheck.Arbitraries._
import org.typelevel.otel4s.sdk.scalacheck.Cogens._

class ResourceLawTests extends DisciplineSuite {
class TelemetryResourceLawTests extends DisciplineSuite {

checkAll("Resource.HashLaws", HashTests[Resource].hash)
checkAll("TelemetryResource.HashLaws", HashTests[TelemetryResource].hash)

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,21 @@ import munit.ScalaCheckSuite
import org.scalacheck.Prop.forAll
import org.typelevel.otel4s.sdk.scalacheck.Gens

class ResourceProps extends ScalaCheckSuite {
class TelemetryResourceProps extends ScalaCheckSuite {

property("Attributes#merge merges attributes") {
forAll(Gens.resource, Gens.resource) { (resource1, resource2) =>
val mergedEither = resource1.merge(resource2)
property("TelemetryResource#merge merges attributes") {
forAll(Gens.telemetryResource, Gens.telemetryResource) { (r1, r2) =>
val mergedEither = r1.merge(r2)
mergedEither match {
case Right(merged) =>
val mergedAttrs = merged.attributes
val keys =
resource1.attributes.toMap.keySet ++ resource2.attributes.toMap.keySet
r1.attributes.toMap.keySet ++ r2.attributes.toMap.keySet

mergedAttrs.size == keys.size && mergedAttrs.forall { a =>
resource2.attributes
r2.attributes
.get(a.key)
.orElse(resource1.attributes.get(a.key))
.orElse(r1.attributes.get(a.key))
.contains(a)
}
case Left(_) => true
Expand All @@ -45,12 +45,12 @@ class ResourceProps extends ScalaCheckSuite {
}
}

property("Show[Resource]") {
forAll(Gens.resource) { resource =>
property("Show[TelemetryResource]") {
forAll(Gens.telemetryResource) { resource =>
val expected =
show"Resource{attributes=${resource.attributes}, schemaUrl=${resource.schemaUrl}}"
show"TelemetryResource{attributes=${resource.attributes}, schemaUrl=${resource.schemaUrl}}"

assertEquals(Show[Resource].show(resource), expected)
assertEquals(Show[TelemetryResource].show(resource), expected)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,19 @@ package sdk

import cats.syntax.either._
import munit.FunSuite
import org.typelevel.otel4s.sdk.Resource.ResourceInitializationError
import org.typelevel.otel4s.sdk.Resource.ResourceInitializationError.SchemaUrlConflict
import org.typelevel.otel4s.sdk.TelemetryResource.ResourceInitializationError
import org.typelevel.otel4s.sdk.TelemetryResource.ResourceInitializationError.SchemaUrlConflict

class ResourceSuite extends FunSuite {
class TelemetryResourceSuite extends FunSuite {

def checkSchemaMerge(
leftSchemaUrl: Option[String],
rightSchemaUrl: Option[String],
expected: Either[ResourceInitializationError, Option[String]]
): Unit =
assertEquals(
Resource(Attributes.empty, leftSchemaUrl)
.merge(Resource(Attributes.empty, rightSchemaUrl))
TelemetryResource(Attributes.empty, leftSchemaUrl)
.merge(TelemetryResource(Attributes.empty, rightSchemaUrl))
.map(_.schemaUrl),
expected
)
Expand Down Expand Up @@ -83,8 +83,8 @@ class ResourceSuite extends FunSuite {
}

test("Resource#mergeInto - merge attributes and prioritize the latter") {
val that = Resource(Attributes(Attribute("key", "that")))
val other = Resource(Attributes(Attribute("key", "other")))
val that = TelemetryResource(Attributes(Attribute("key", "that")))
val other = TelemetryResource(Attributes(Attribute("key", "other")))

assertEquals(that.merge(other), Right(other))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@
package org.typelevel.otel4s.sdk.scalacheck

import org.scalacheck.Arbitrary
import org.typelevel.otel4s.sdk.Resource
import org.typelevel.otel4s.sdk.TelemetryResource
import org.typelevel.otel4s.sdk.common.InstrumentationScope

trait Arbitraries extends org.typelevel.otel4s.scalacheck.Arbitraries {

implicit val resourceArbitrary: Arbitrary[Resource] =
Arbitrary(Gens.resource)
implicit val telemetryResourceArbitrary: Arbitrary[TelemetryResource] =
Arbitrary(Gens.telemetryResource)

implicit val instrumentationScopeArbitrary: Arbitrary[InstrumentationScope] =
Arbitrary(Gens.instrumentationScope)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ package org.typelevel.otel4s.sdk.scalacheck

import org.scalacheck.Cogen
import org.typelevel.otel4s.Attributes
import org.typelevel.otel4s.sdk.Resource
import org.typelevel.otel4s.sdk.TelemetryResource
import org.typelevel.otel4s.sdk.common.InstrumentationScope

trait Cogens extends org.typelevel.otel4s.scalacheck.Cogens {

implicit val resourceCogen: Cogen[Resource] =
implicit val telemetryResourceCogen: Cogen[TelemetryResource] =
Cogen[(Attributes, Option[String])].contramap { r =>
(r.attributes, r.schemaUrl)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@
package org.typelevel.otel4s.sdk.scalacheck

import org.scalacheck.Gen
import org.typelevel.otel4s.sdk.Resource
import org.typelevel.otel4s.sdk.TelemetryResource
import org.typelevel.otel4s.sdk.common.InstrumentationScope

trait Gens extends org.typelevel.otel4s.scalacheck.Gens {

val resource: Gen[Resource] =
val telemetryResource: Gen[TelemetryResource] =
for {
attributes <- Gens.attributes
schemaUrl <- Gen.option(nonEmptyString)
} yield Resource(attributes, schemaUrl)
} yield TelemetryResource(attributes, schemaUrl)

val instrumentationScope: Gen[InstrumentationScope] =
for {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ private[trace] object SdkSpanBackend {
* the [[InstrumentationScope]] of the span
*
* @param resource
* the [[Resource]] of the span
* the [[TelemetryResource]] of the span
*
* @param kind
* the [[SpanKind]] of the span
Expand All @@ -253,7 +253,7 @@ private[trace] object SdkSpanBackend {
context: SpanContext,
name: String,
scopeInfo: InstrumentationScope,
resource: Resource,
resource: TelemetryResource,
kind: SpanKind,
parentContext: Option[SpanContext],
processor: SpanProcessor[F],
Expand Down Expand Up @@ -293,7 +293,7 @@ private[trace] object SdkSpanBackend {
scopeInfo: InstrumentationScope,
kind: SpanKind,
parentContext: Option[SpanContext],
resource: Resource,
resource: TelemetryResource,
links: Vector[LinkData],
startTimestamp: FiniteDuration
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import org.typelevel.otel4s.sdk.trace.samplers.Sampler

private final case class TracerSharedState[F[_]](
idGenerator: IdGenerator[F],
resource: Resource,
resource: TelemetryResource,
sampler: Sampler,
spanProcessor: SpanProcessor[F]
)
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ sealed trait SpanData {

/** The resource associated with the span.
*/
def resource: Resource
def resource: TelemetryResource

/** Whether the span has ended.
*/
Expand Down Expand Up @@ -155,7 +155,7 @@ object SpanData {
events: Vector[EventData],
links: Vector[LinkData],
instrumentationScope: InstrumentationScope,
resource: Resource
resource: TelemetryResource
): SpanData =
Impl(
name = name,
Expand Down Expand Up @@ -223,7 +223,7 @@ object SpanData {
events: Vector[EventData],
links: Vector[LinkData],
instrumentationScope: InstrumentationScope,
resource: Resource
resource: TelemetryResource
) extends SpanData

}
Loading

0 comments on commit 6c5dc75

Please sign in to comment.