Skip to content

Commit

Permalink
fix InventoryItem name and alias definition
Browse files Browse the repository at this point in the history
  • Loading branch information
Zschimmer committed Oct 31, 2024
1 parent ed4987b commit 29fbf39
Show file tree
Hide file tree
Showing 18 changed files with 132 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ final case class BoardPath private(string: String) extends UnsignedSimpleItemPat


object BoardPath extends UnsignedSimpleItemPath.Companion[BoardPath]:
// May deadlock: override val itemTypeName = Board.typeName
type Item = Board

protected def unchecked(string: String) = new BoardPath(string)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ extends UnsignedSimpleItemPath, InventoryItemPath.AttachableToAgent:


object CalendarPath extends UnsignedSimpleItemPath.Companion[CalendarPath]:
// May deadlock: override val itemTypeName = Calendar.typeName
type Item = Calendar

protected def unchecked(string: String) = new CalendarPath(string)
Expand Down
10 changes: 7 additions & 3 deletions js7-data/shared/src/main/scala/js7/data/item/InventoryItem.scala
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,12 @@ object InventoryItem:
trait Companion[A <: InventoryItem]:
type Item <: A
def cls: Class[A]

val typeName: String = getClass.simpleScalaName

protected lazy val typeNameAliases: Seq[String] =
Path.itemTypeNameAliases

type Key <: InventoryItemKey
def Key: InventoryItemKey.Companion[Key]

Expand All @@ -56,10 +60,10 @@ object InventoryItem:

type ItemState <: InventoryItemState

implicit def jsonCodec: Codec.AsObject[A]

def subtype: Subtype[A] =
Subtype(jsonCodec)(using ClassTag(cls))
Subtype[A](jsonCodec, aliases = typeNameAliases)(using ClassTag(cls))

implicit def jsonCodec: Codec.AsObject[A]

def jsonEncoder: Encoder.AsObject[A] =
jsonCodec
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package js7.data.item
import io.circe.{Codec, DecodingFailure, HCursor, Json}
import js7.base.circeutils.CirceUtils.*
import js7.base.problem.Checked
import js7.base.utils.Collections.implicits.RichIterable
import js7.base.utils.Collections.implicits.*
import js7.data.item.InventoryItemKey.*
import scala.math.Ordered.orderingToOrdered

Expand Down Expand Up @@ -35,10 +35,18 @@ object InventoryItemKey:

def itemTypeName: String

protected def itemTypeNameAliases: Seq[String]

def pathTypeName: String

protected def pathTypeNameAliases: Seq[String] =
itemTypeNameAliases

final def pathTypeNames: Seq[String] =
pathTypeName +: pathTypeNameAliases

def jsonCodec(companions: Iterable[Companion_]): Codec[InventoryItemKey] =
val typeToCompanion = companions.toKeyedMap(_.pathTypeName)
val typeToCompanion = companions.view.flatMap(o => o.pathTypeNames.map(_ -> o)).uniqueToMap

new Codec[InventoryItemKey]:
def apply(key: InventoryItemKey) = Json.fromString(key.toTypedString)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,15 @@ object InventoryItemPath:
GenericString.ordering[InventoryItemPath]

abstract class Companion[P <: InventoryItemPath: ClassTag] extends Js7PathValidating[P]:
private lazy val itemTypeName_ = name stripSuffix "Path"
private lazy val itemTypeName_ =
if name.endsWith("Path")
then name.stripSuffix("Path")
else name.stripSuffix("Id")

def itemTypeName: String = itemTypeName_

def itemTypeNameAliases: Seq[String] = Nil

def pathTypeName: String = itemTypeName

private lazy val defaultSourceTypeToFilenameExtension: Map[SourceType, String] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ object UnsignedVersionedItemId:

final lazy val itemTypeName = P.itemTypeName

final protected val itemTypeNameAliases: Seq[String] = Nil

implicit final val implicitCompanion: Companion[P] =
this

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ object VersionedItemId:

final lazy val itemTypeName = P.itemTypeName

protected def itemTypeNameAliases: Seq[String] = Nil

implicit final val implicitCompanion: Companion[P] =
this

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ object VersionedItemPath:
final lazy val NoId: VersionedItemId[P] = Anonymous ~ VersionId.Anonymous
implicit override final val self: Companion[P] = this

def pathTypeNameAliases: Seq[String] = Nil

private def P = this

override def checked(string: String): Checked[P] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ extends SignableSimpleItemPath, InventoryItemPath.AttachableToAgent:


object JobResourcePath extends SignableSimpleItemPath.Companion[JobResourcePath]:
// May deadlock: override val itemTypeName = JobResource.typeName

protected def unchecked(string: String) =
new JobResourcePath(string)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ final case class LockPath private(string: String) extends UnsignedSimpleItemPath


object LockPath extends UnsignedSimpleItemPath.Companion[LockPath]:
// May deadlock: override val itemTypeName = Lock.typeName
type Item = Lock

protected def unchecked(string: String) = new LockPath(string)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package js7.data.subagent

import io.circe.syntax.EncoderOps
import io.circe.{Codec, Decoder, Encoder, Json, JsonObject}
import js7.base.circeutils.typed.Subtype
import js7.data.item.{InventoryItemPath, ItemRevision, UnsignedItemPath, UnsignedSimpleItem}
import js7.data.value.expression.Expression
import js7.data.value.expression.Expression.NumericConstant
Expand Down Expand Up @@ -82,6 +81,3 @@ object SubagentBundle extends UnsignedSimpleItem.Companion[SubagentBundle]:

implicit val jsonCodec: Codec.AsObject[SubagentBundle] =
Codec.AsObject.from(jsonDecoder, jsonEncoder)

override val subtype: Subtype[SubagentBundle] =
Subtype[SubagentBundle](aliases = Seq("SubagentSelection"))
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ extends DelegateId.Companion[SubagentBundleId],

type Item = SubagentBundle

override val itemTypeName = "SubagentBundle"
override val pathTypeName: String = itemTypeName
override val itemTypeNameAliases = Seq("SubagentSelection"/*COMPATIBLE with v2.7.1*/)

protected def unchecked(string: String) =
new SubagentBundleId(string)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ extends UnsignedSimpleItemPath, DelegateId, AttachableToAgent:
object SubagentId
extends DelegateId.Companion[SubagentId], UnsignedSimpleItemPath.Companion[SubagentId]:

override val itemTypeName = "Subagent"
override val pathTypeName: String = itemTypeName
override val itemTypeNameAliases = Seq("SubagentRef")

protected def unchecked(string: String) =
new SubagentId(string)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package js7.data.subagent

import io.circe.Codec
import js7.base.circeutils.CirceUtils.deriveConfiguredCodec
import js7.base.circeutils.typed.Subtype
import js7.base.web.Uri
import js7.data.agent.AgentPath
import js7.data.item.{ItemRevision, UnsignedSimpleItem}
Expand Down Expand Up @@ -57,6 +56,3 @@ extends UnsignedSimpleItem.Companion[SubagentItem]:
val cls: Class[SubagentItem] = classOf[SubagentItem]

implicit val jsonCodec: Codec.AsObject[SubagentItem] = deriveConfiguredCodec[SubagentItem]

override val subtype: Subtype[SubagentItem] =
Subtype[SubagentItem](aliases = Seq("SubagentRef"))
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ extends UnsignedItemPath, VersionedControlPath, InventoryItemPath.AttachableToAg

object WorkflowControlPath extends VersionedControlPath.Companion[WorkflowControlPath]:

def pathTypeNameAliases: Seq[String] = Nil

protected def unchecked(string: String) = new WorkflowControlPath(WorkflowPath(string))

override def checked(string: String): Checked[WorkflowControlPath] =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package js7.data.subagent

import js7.base.test.OurTestSuite

final class SubagentBundleIdTest extends OurTestSuite:

"SubagentBundleId" in:
assert(SubagentBundleId("BUNDLE").toString == "SubagentBundle:BUNDLE")
assert(SubagentBundleId.pathTypeName == "SubagentBundle")
assert(SubagentBundleId.pathTypeNames == Seq("SubagentBundle", "SubagentSelection"))
assert(SubagentBundleId.itemTypeName == "SubagentBundle")
Original file line number Diff line number Diff line change
@@ -1,44 +1,84 @@
package js7.data.subagent

import js7.base.circeutils.CirceUtils.*
import js7.base.circeutils.typed.TypedJsonCodec
import js7.base.test.OurTestSuite
import js7.data.controller.ControllerState.inventoryItemJsonCodec
import js7.data.item.InventoryItem
import js7.data.agent.AgentPath
import js7.data.controller.ControllerState
import js7.data.controller.ControllerState.{inventoryItemJsonCodec, inventoryItemKeyJsonCodec}
import js7.data.item.BasicItemEvent.ItemAttached
import js7.data.item.{BasicItemEvent, InventoryItem, InventoryItemKey}
import js7.data.value.expression.Expression.NumericConstant
import js7.data.value.expression.ExpressionParser.expr
import js7.tester.CirceJsonTester.{testJson, testJsonDecoder}

final class SubagentBundleTest extends OurTestSuite:

"JSON" in:
testJson[InventoryItem](
SubagentBundle(
"JSON" - {
"SubagentBundle" in:
testJson[InventoryItem](
SubagentBundle(
SubagentBundleId("BUNDLE"),
Map(
SubagentId("A-SUBAGENT") -> NumericConstant(1),
SubagentId("B-SUBAGENT") -> expr("min(100, (1 / $cpuLoad) ? 100)"))),
json"""{
"TYPE": "SubagentBundle",
"id": "BUNDLE",
"subagentToPriority": {
"A-SUBAGENT": 1,
"B-SUBAGENT": "min(100, (1 / $$cpuLoad) ? 100)"
}
}""")

"InventoryItemKey" in:
testJson[InventoryItemKey](
SubagentBundleId("BUNDLE"),
Map(
SubagentId("A-SUBAGENT") -> NumericConstant(1),
SubagentId("B-SUBAGENT") -> expr("min(100, (1 / $cpuLoad) ? 100)"))),
json"""{
"TYPE": "SubagentBundle",
"id": "BUNDLE",
"subagentToPriority": {
"A-SUBAGENT": 1,
"B-SUBAGENT": "min(100, (1 / $$cpuLoad) ? 100)"
}
}""")

"JSON until v2.7.1" in:
// COMPATIBLE with v2.7.1
testJsonDecoder[InventoryItem](
SubagentBundle(
json""" "SubagentBundle:BUNDLE" """)

"ItemAttached" in:
given TypedJsonCodec[BasicItemEvent] = BasicItemEvent.jsonCodec(ControllerState)

testJson[BasicItemEvent](
ItemAttached(SubagentBundleId("BUNDLE"), None, AgentPath("AGENT")),
json"""{
"TYPE": "ItemAttached",
"key": "SubagentBundle:BUNDLE",
"delegateId": "Agent:AGENT"
}""")
}

"JSON until v2.7.1" - {
"InventoryItem" in:
// COMPATIBLE with v2.7.1
testJsonDecoder[InventoryItem](
SubagentBundle(
SubagentBundleId("BUNDLE"),
Map(
SubagentId("A-SUBAGENT") -> NumericConstant(1),
SubagentId("B-SUBAGENT") -> expr("min(100, (1 / $cpuLoad) ? 100)"))),
json"""{
"TYPE": "SubagentSelection",
"id": "BUNDLE",
"subagentToPriority": {
"A-SUBAGENT": 1,
"B-SUBAGENT": "min(100, (1 / $$cpuLoad) ? 100)"
}
}""")

"InventoryItemKey" in:
testJsonDecoder[InventoryItemKey](
SubagentBundleId("BUNDLE"),
Map(
SubagentId("A-SUBAGENT") -> NumericConstant(1),
SubagentId("B-SUBAGENT") -> expr("min(100, (1 / $cpuLoad) ? 100)"))),
json"""{
"TYPE": "SubagentSelection",
"id": "BUNDLE",
"subagentToPriority": {
"A-SUBAGENT": 1,
"B-SUBAGENT": "min(100, (1 / $$cpuLoad) ? 100)"
}
}""")
json""" "SubagentSelection:BUNDLE" """)

"ItemAttached" in:
given TypedJsonCodec[BasicItemEvent] = BasicItemEvent.jsonCodec(ControllerState)

testJsonDecoder[BasicItemEvent](
ItemAttached(SubagentBundleId("BUNDLE"), None, AgentPath("AGENT")),
json"""{
"TYPE": "ItemAttached",
"key": "SubagentSelection:BUNDLE",
"delegateId": "Agent:AGENT"
}""")
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import js7.data.item.{InventoryItem, ItemRevision}
import js7.tester.CirceJsonTester.{testJson, testJsonDecoder}

final class SubagentItemTest extends OurTestSuite:

"JSON" in:
testJson[InventoryItem](
SubagentItem(
Expand All @@ -26,7 +27,7 @@ final class SubagentItemTest extends OurTestSuite:
"itemRevision": 1
}""")

// COMPATIBLE with v2.2.2
"JSON until v2.2.2" in: // COMPATIBLE
testJsonDecoder[InventoryItem](
SubagentItem(
SubagentId("SUBAGENT"),
Expand All @@ -40,3 +41,16 @@ final class SubagentItemTest extends OurTestSuite:
"uri": "https://example.com",
"itemRevision": 1
}""")

"JSON, a long time ago" in: // COMPATIBLE
testJsonDecoder[InventoryItem](
SubagentItem(
SubagentId("SUBAGENT"),
AgentPath("AGENT"),
Uri("https://example.com")),
json"""{
"TYPE": "SubagentRef",
"id": "SUBAGENT",
"agentPath": "AGENT",
"uri": "https://example.com"
}""")

0 comments on commit 29fbf39

Please sign in to comment.