Skip to content

Commit

Permalink
[WIP] Add deprecation use case narrative and examples
Browse files Browse the repository at this point in the history
  • Loading branch information
aj-stein-nist committed Feb 13, 2024
1 parent b4a50ab commit f2db641
Showing 1 changed file with 271 additions and 0 deletions.
271 changes: 271 additions & 0 deletions website/content/tutorials/3-constraints-expect/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -824,6 +824,277 @@ We can use the samples above to simulate a scenario where a developer or their t
| | `<!-- 2nd memory module -->`<br/>`<byte-size>1048576</byte-size>` | `(1048576 mod 1024) = 0` | true |
| memory-same-byte-size | Sequence of <br/> (`<memory>...<product-name>... (Module 1)</product-name><byte-size>1048555</byte-size></memory>`, <br/>`<memory>...<product-name>... (Module 2)</product-name><byte-size>1048576</byte-size></memory>`) | `(sum((8589934592, 8589934592)) mod 8589934592) = 0)` | true |

## Deprecation warnings with `expect`

With our use of the `expect` constraint for logical value testing, our stakeholders were very pleased we can develop and test small model enhancements incrementally and quickly. However, the adoption of a standard information model and data formats have surfaced some problems and challenges they were unaware of, so they need our help. An important group in their consortium identified a risk around using `byte-size` with binary base-two number for memory or storage capacity. [Binary prefixes](https://en.wikipedia.org/wiki/Binary_prefix) are ambiguous in the updated model. Some vendors use binary base-two sizes or decimal base-ten sizes, but this field in the model makes tooling inconsistent and document instances unclear. A majority in the consortium decided updates to documentation (sourced from our Metaschema modules) are not enough. There must be a way to identify size, its unit prefix (binary or decimal), and optionally a unit so developers and software do not need to compute the full byte size. Our stakeholders are very concerned because the consortium also wants to allow the old approach in our information model and mark this method as deprecated. The intent will be to remove after twelve to twenty four months.

Fortunately for us, this risk is worrisome to the stakeholders, but very relatable and easy to change for us Metaschema module developers. The `expect` constraints, paired with model changes with `choice` or other strategies, allow us to change the information model and data formats and standardize deprecation messaging across tools.

Given these new requirements we will add a new assembly, `size`. We will amend the model to allow using `bytes-size` like before or the new `size` assembly. And finally, we will amend the constraints to add a deprecation warning and recommend developers to transition software and existing documents to the new model structure.

```xml {linenos=table,hl_lines=["152-212","253-255"]}
<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="https://raw.githubusercontent.com/usnistgov/metaschema/develop/schema/xml/metaschema.xsd" type="application/xml" schematypens="http://www.w3.org/2001/XMLSchema"?>
<METASCHEMA xmlns="http://csrc.nist.gov/ns/oscal/metaschema/1.0">
<schema-name>Computer Model</schema-name>
<schema-version>0.0.9</schema-version>
<short-name>computer</short-name>
<namespace>http://example.com/ns/computer</namespace>
<json-base-uri>http://example.com/ns/computer</json-base-uri>
<define-assembly name="vendor">
<formal-name>Vendor Information</formal-name>
<description>Information about a vendor of a computer part.</description>
<define-flag name="id" as-type="string" required="yes">
<formal-name>Vendor Identifier</formal-name>
<description>An identifier for classifying a unique computer parts vendor.</description>
</define-flag>
<model>
<define-field name="name" min-occurs="1" max-occurs="1">
<formal-name>Vendor Name</formal-name>
<description>The registered company name of the vendor.</description>
</define-field>
<define-field name="address" min-occurs="1" max-occurs="1">
<formal-name>Vendor Address</formal-name>
<description>The physical address of an office location for the vendor.</description>
</define-field>
<define-field name="website" as-type="uri" min-occurs="1" max-occurs="1">
<formal-name>Vendor Website</formal-name>
<description>A public website made by the vendor documenting their parts as used in the computer.</description>
</define-field>
</model>
</define-assembly>
<define-field name="product-name" as-type="string">
<formal-name>Product Name</formal-name>
<description>The product name from the vendor of the computer part.</description>
</define-field>
<define-assembly name="computer">
<formal-name>Computer Assembly</formal-name>
<description>A container object for a computer, its parts, and its sub-parts.</description>
<root-name>computer</root-name>
<define-flag name="id" as-type="string" required="yes">
<formal-name>Computer Identifier</formal-name>
<description>An identifier for classifying a unique make and model of computer.</description>
</define-flag>
<model>
<define-assembly name="motherboard">
<formal-name>Motherboard Assembly</formal-name>
<description>A container object for a motherboard in a computer and its sub-parts.</description>
<model>
<assembly ref="vendor"/>
<define-field name="type" as-type="string" min-occurs="1" max-occurs="1">
<formal-name>Motherboard Type</formal-name>
<description>The type motherboard layout, <code>at</code>, <code>atx</code>, <code>mini-itx</code> or an alternative.</description>
</define-field>
<define-assembly name="cpu">
<formal-name>Motherboard Central Processing Unit (CPU)</formal-name>
<description>The model number of the CPU on the motherboard of a computer.</description>
<model>
<assembly ref="vendor"/>
<field ref="product-name" min-occurs="1" max-occurs="1"/>
<define-field name="architecture" as-type="string" min-occurs="1" max-occurs="1">
<formal-name>CPU Architecture</formal-name>
<description>The Instruction Set Architecture (ISA) approved by module stakeholders.</description>
<constraint>
<allowed-values target="." allow-other="no">
<enum value="amd64">Intel 64-bit systems, also known as x86-64 or em64t</enum>
<enum value="armhf">Arm v7 32-bit systems</enum>
<enum value="arm64">Arm v8 64-bit systems</enum>
<enum value="x86">Intel 32-bit x86 systems, for 686 class or newer</enum>
</allowed-values>
</constraint>
</define-field>
<define-field name="speed" as-type="string" min-occurs="1" max-occurs="1">
<formal-name>CPU Speed</formal-name>
<description>The clock speed of the CPU in megahertz or gigahertz.</description>
</define-field>
</model>
</define-assembly>
<define-assembly name="ata-socket">
<formal-name>Motherboard Advanced Technology Attachment (ATA) Socket</formal-name>
<description>The model number of ATA socket on the motherboard of a computer. There will only be one socket on any motherboard.</description>
<model>
<define-assembly name="vendor">
<formal-name>Vendor Information</formal-name>
<description>Information about a vendor of a computer part.</description>
<define-flag name="id" as-type="string" required="yes">
<formal-name>Vendor Identifier</formal-name>
<description>An identifier for classifying a unique computer parts vendor.</description>
</define-flag>
<model>
<define-field name="name" min-occurs="1" max-occurs="1">
<formal-name>Vendor Name</formal-name>
<description>The registered company name of the vendor.</description>
</define-field>
<define-field name="address" min-occurs="1" max-occurs="1">
<formal-name>Vendor Address</formal-name>
<description>The physical address of an office location for the vendor.</description>
</define-field>
<define-field name="website" as-type="uri" min-occurs="1" max-occurs="1">
<formal-name>Vendor Website</formal-name>
<description>A public website made by the vendor documenting their parts as used in the computer.</description>
</define-field>
</model>
</define-assembly>
<define-field name="product-name" as-type="string" min-occurs="1" max-occurs="1">
<formal-name>Product Name</formal-name>
<description>The product name from the vendor of the computer part.</description>
</define-field>
<define-field name="type" as-type="string" min-occurs="1" max-occurs="1">
<formal-name>ATA Socket Type</formal-name>
<description>The type of ATA socket on the motherboard with approved (but optional) values recommended by model stakeholders.</description>
<constraint>
<allowed-values target="." allow-other="yes">
<enum value="pata">Parallel ATA buses also known as AT-Attachment and IDE</enum>
<enum value="sata">Serial ATA buses supporting Advanced Host Controller Interface or legacy IDE modes</enum>
<enum value="esata">External Serial ATA buses for pluggable external devices using SATA</enum>
<enum value="esatap">External Serial ATA buses supporting SATA traffic and device power</enum>
</allowed-values>
</constraint>
</define-field>
</model>
</define-assembly>
<define-assembly name="memory" min-occurs="1" max-occurs="unbounded">
<formal-name>Motherboard Random Access Memory (RAM) Module(s)</formal-name>
<description>Random access memory hardware installed on the motherboard of a computer.</description>
<group-as name="memory-modules" in-json="ARRAY"/>
<model>
<define-assembly name="vendor">
<formal-name>Vendor Information</formal-name>
<description>Information about a vendor of a computer part.</description>
<define-flag name="id" as-type="string" required="yes">
<formal-name>Vendor Identifier</formal-name>
<description>An identifier for classifying a unique computer parts vendor.</description>
</define-flag>
<model>
<define-field name="name" min-occurs="1" max-occurs="1">
<formal-name>Vendor Name</formal-name>
<description>The registered company name of the vendor.</description>
</define-field>
<define-field name="address" min-occurs="1" max-occurs="1">
<formal-name>Vendor Address</formal-name>
<description>The physical address of an office location for the vendor.</description>
</define-field>
<define-field name="website" as-type="uri" min-occurs="1" max-occurs="1">
<formal-name>Vendor Website</formal-name>
<description>A public website made by the vendor documenting their parts as used in the computer.</description>
</define-field>
</model>
</define-assembly>
<define-field name="product-name" as-type="string" min-occurs="1" max-occurs="1">
<formal-name>Product Name</formal-name>
<description>The product name from the vendor of the computer part.</description>
</define-field>
<choice>
<define-field name="byte-size" as-type="positive-integer" min-occurs="1" max-occurs="1">
<formal-name>Memory Module Size</formal-name>
<description>Size of the memory module in binary, not SI base-10 units, meaning a kilobyte is 1024 bytes, not 1000 bytes.</description>
</define-field>
<define-field name="size" min-occurs="1" max-occurs="1">
<formal-name>Memory Module Size</formal-name>
<description>Size of memory module in binary or SI base-10 units, optionally with a size unit. This does not require to be in bits or bytes.</description>
<define-flag name="unit" required="yes">
<formal-name>Memory Module Size Unit</formal-name>
<description>The unit size for a memory module can either be bytes (B) or bits (b).</description>
<constraint>
<allowed-values allow-other="no">
<enum value="B">byte</enum>
<enum value="b">bit</enum>
</allowed-values>
</constraint>
</define-flag>
<define-flag name="base" required="yes">
<formal-name>Memory Module Size Unit Prefix Base</formal-name>
<description>The prefix type of module size, binary or decimal. This is useful if you will not specify an optional unit or unit base.</description>
<constraint>
<allowed-values allow-other="no">
<enum value="binary"/>
<enum value="decimal"/>
</allowed-values>
</constraint>
</define-flag>
<define-flag name="prefix">
<formal-name>Memory Module Size Unit Prefix</formal-name>
<description>The optional prefix the of unit from a given system.</description>
<constraint>
<allowed-values allow-other="yes">
<enum value="Gi"></enum>
<enum value="Ki"></enum>
<enum value="Mi"></enum>
<enum value="G"></enum>
<enum value="K"></enum>
<enum value="M"></enum>
</allowed-values>
</constraint>
</define-flag>
<define-flag name="prefix-system">
<formal-name>Memory Module Size Unit Prefix System</formal-name>
<description>An identifier for the organization associated with the specific usage of unit prefix. If absent, the International System of Units (SI) is the presumed default.</description>
<constraint>
<allowed-values allow-other="yes">
<enum value="iec">The International Electrotechnical Commission 60027-2 Amendment 2 Units</enum>
<enum value="jedec">JEDEC Solid State Technology Association Units</enum>
<enum value="si">International System of Units</enum>
</allowed-values>
</constraint>
</define-flag>
</define-field>
</choice>
</model>
<constraint>
<expect id="memory-byte-size-deprecated" level="WARNING" target="." test="count(./byte-size) = 0">
<message>All memory modules SHOULD use size because byte-size is now deprecated and byte-size will be removed.</message>
</expect>
</constraint>
</define-assembly>
<define-assembly name="expansion-card" min-occurs="0" max-occurs="unbounded">
<formal-name>Motherboard Expansion Card</formal-name>
<description>The model number of an expansion card connected to the motherboard of a computer.</description>
<group-as name="expansion-cards" in-json="ARRAY"/>
<model>
<define-assembly name="vendor">
<formal-name>Vendor Information</formal-name>
<description>Information about a vendor of a computer part.</description>
<define-flag name="id" as-type="string" required="yes">
<formal-name>Vendor Identifier</formal-name>
<description>An identifier for classifying a unique computer parts vendor.</description>
</define-flag>
<model>
<define-field name="name" min-occurs="1" max-occurs="1">
<formal-name>Vendor Name</formal-name>
<description>The registered company name of the vendor.</description>
</define-field>
<define-field name="address" min-occurs="1" max-occurs="1">
<formal-name>Vendor Address</formal-name>
<description>The physical address of an office location for the vendor.</description>
</define-field>
<define-field name="website" as-type="uri" min-occurs="1" max-occurs="1">
<formal-name>Vendor Website</formal-name>
<description>A public website made by the vendor documenting their parts as used in the computer.</description>
</define-field>
</model>
</define-assembly>
<define-field name="product-name" as-type="string" min-occurs="1" max-occurs="1">
<formal-name>Product Name</formal-name>
<description>The product name from the vendor of the computer part.</description>
</define-field>
<define-field name="type" as-type="string" min-occurs="1" max-occurs="1">
<formal-name>Expansion Card Type</formal-name>
<description>The type of expansion card on a motherboard of a computer, such as <code>pci</code> (PCI, e.g. Peripheral Component Interconnect), <code>pcie</code> (PCI Express), or an alternative.</description>
</define-field>
</model>
</define-assembly>
</model>
<constraint>
<expect id="memory-same-byte-size" level="CRITICAL" target="." test="if (count(./memory/byte-size) > 0) then (sum(./memory/byte-size) mod ./memory/byte-size[1]) = 0 else (sum(./memory/size) mod ./memory/size[1]) = 0">
<message>All memory modules SHOULD be the same size or byte-size for a computer.</message>
</expect>
</constraint>
</define-assembly>
</model>
</define-assembly>
</METASCHEMA>
```

## Conclusion

In this tutorial, we examined advanced usage of constraints to precisely control the structure of values without knowledge of an exhaustive, predetermined list.

0 comments on commit f2db641

Please sign in to comment.