Prefix in CSW 2

The use of prefixes has been made more consistent in CSW 2.0.0. Before this update, Prefix was a dot-separated String starting with a subsystem, where the component name was considered to be the last item. The Subsystem was extracted from the String on creation.

e.g IRIS.imager.filterWheelAssembly => Subsystem: IRIS Component Name: filterWheelAssembly

There was some confusion about what was the Prefix: the entire string (IRIS.imager.filterWheelAssembly), or everything except the component name (IRIS.imager)?

With CSW 2, we expect this to be less confusing. Prefix is the whole string and is made up of exactly two parts: the subsystem (explicitly as a Subsystem type) and a String component name, where everything after the subsystem is considered to be the component name.

e.g. IRIS.imager.filterWheelAssembly => Subsystem: IRIS Component Name: imager.filterWheelAssembly

Prefixes can be still be constructed using a String, but it must have a part at the beginning before the first dot that matches one of the valid TMT subsystems as specified in the Subsystem.scala.

This change will have the following effects on your code:

Component Creation

ComponentInfo files now take a Prefix as a String instead of an ambiguous prefix and a component name. Similarly, Container configuration files also reference their components using Prefix instead of component name.

For example, in CSW 1:

name = "SampleHcd"
componentType = hcd
behaviorFactoryClassName = "org.tmt.nfiraos.samplehcd.SampleHcdBehaviorFactory"
prefix = "nfiraos.samplehcd"
locationServiceUsage = RegisterOnly

becomes in CSW 2:

prefix = "nfiraos.samplehcd"
componentType = hcd
behaviorFactoryClassName = "org.tmt.nfiraos.samplehcd.SampleHcdBehaviorFactory"
locationServiceUsage = RegisterOnly

Location Service

A ComponentId is now constructed from a Prefix and ComponentType instead of a component name String and a ComponentType. This allows registration of components from different subsystems with the same component name.

For example, in CSW 1:

val hcdConnection = AkkaConnection(ComponentId("hcd1"), ComponentType.HCD)

becomes in CSW 2:

val hcdConnection = AkkaConnection(ComponentId(Prefix(Subsystem.NFIRAOS, "hcd1"), ComponentType.HCD))

Alarm Service

Alarms are defined in the Alarm Configuration file using a Prefix instead of a subsystem and component name.

For example, in CSW 1:

alarms: [
  {
    subsystem = nfiraos
    component = tromboneAssembly
    name = tromboneAxisLowLimitAlarm
    description = "Warns when trombone axis has reached the low limit"
    location = "south side"
    alarmType = Absolute
    supportedSeverities = [Warning, Major, Critical]
    probableCause = "the trombone software has failed or the stage was driven into the low limit"
    operatorResponse = "go to the NFIRAOS engineering user interface and select the datum axis command"
    isAutoAcknowledgeable = false
    isLatchable = true
    activationStatus = Active
  }
]

becomes in CSW 2:

alarms: [
  {
    prefix = nfiraos.tromboneAssembly
    name = tromboneAxisLowLimitAlarm
    description = "Warns when trombone axis has reached the low limit"
    location = "south side"
    alarmType = Absolute
    supportedSeverities = [Warning, Major, Critical]
    probableCause = "the trombone software has failed or the stage was driven into the low limit"
    operatorResponse = "go to the NFIRAOS engineering user interface and select the datum axis command"
    isAutoAcknowledgeable = false
    isLatchable = true
    activationStatus = Active
  }
]

AlarmKey also takes Prefix instead of a subsystem and a component name:

CSW 1:

val alarmKey = AlarmKey(NFIRAOS, "trombone", "tromboneAxisLowLimitAlarm")

becomes in CSW 2:

val alarmKey = AlarmKey(Prefix(NFIRAOS, "trombone"), "tromboneAxisLowLimitAlarm")

Logging Service

The construction of a Logging Service is typically done using a LoggerFactory. LoggerFactory now takes a Prefix instead of just a component name String. For components, this is done automatically for you in the framework. This has the additional effect that the Subsystem and Component Name are now added to the log messages.

For example, in CSW 1:

{"@componentName":"my-component-name",
 "@host":"INsaloni.local",
 "@name":"LocationServiceExampleClient",
 "@severity":"INFO",
 "@version":"0.1",
 "actor": "akka://csw-examples-locationServiceClient@10.131.23.195:53618/user/$a",
 "class":"csw.location.LocationServiceExampleClient",
 "file":"LocationServiceExampleClientApp.scala",
 "line":149,
 "message":"Result of the find call: None",
 "timestamp":"2017-11-30T10:58:03.102Z" }

becomes in CSW 2:

{"@prefix":"CSW.my-component-name",
 "@subsystem":"CSW",
 "@componentName":"my-component-name",
 "@host":"INsaloni.local",
 "@name":"LocationServiceExampleClient",
 "@severity":"INFO",
 "@version":"0.1",
 "actor":
   "akka://csw-examples-locationServiceClient@10.131.23.195:53618/user/$a",
 "class":"csw.location.LocationServiceExampleClient",
 "file":"LocationServiceExampleClientApp.scala",
 "line":149,
 "message":"Result of the find call: None",
 "timestamp":"2017-11-30T10:58:03.102Z"
 }

Also, configuring default log levels in application configuration files must be specified using the entire Prefix.

CSW 1:

component-log-levels {
    trombonehcd = debug
    tromboneassembly = error
  }

becomes in CSW 2:

component-log-levels {
    TCS.trombonehcd = debug
    TCS.tromboneassembly = error
  }

or alternatively:

component-log-levels {
    TCS {
        trombonehcd = debug
        tromboneassembly = error
    }
  }

In addition, the Prefix and Subsystem classes have been moved from csw.params.core.models to csw.prefix.models, so imports will have be updated.