|
Post by hramasub on Sept 21, 2016 16:04:41 GMT
There are a few advanced Power configuration data that needs to be accessed via Redfish API.
I am looking for directions on how to add these extensions.
Reading through this guidelines (https://www.dmtf.org/sites/default/files/Redfish%20Modeling%20Guidelines_0.pptx, slide #6), the following appears to be the available options:
A) Add to existing schema: a) Add new property : --> HOW ? Please provide example. b) Add new embedded object : --> HOW ? Please provide example. c) Add new enum values : --> HOW ? Please provide example.
B) Create new schema type: a) Add new subordinate resource : --> HOW ? Please provide example. b) Add new top-level collection : --> HOW ? Please provide example.
Consider the following use case of adding the following properties for configuring *Processor Frequency Scaling* : 1) Frequency Scaling Status (String: Enabled/Disabled) 2) Frequency Scaling Stepping (Number: 0 to 100)
Would the following be the changes required (per approach (B) above) ? Change#1) Create a *new* schema file for aggregating vendor specific frequency scaling properties + File name = Contoso_FrequencyScaling.v1_0_0.json + title = "#FrequencyScaling.v1_0_0.FrequencyScaling" + $ref = "#/definitions/FrequencyScaling"
Change#2) Create a new Complex Property FrequencyScaling as follows: "FrequencyScaling": { "Status" : { "type": "string" "enum": [ "Disabled", "Enabled" ] }, "StepValuePercentage" : { "type": number, "minimum": 0, "maximum": 100 } }
Change#3) Return FrequencyScaling as a property under Power::Oem::Contoso, whose odata.type points to the property defined under the new schema.
Is there also a means to add this as a sub-property directly under Power (per approach (A) above) ?
|
|
|
Post by mraineri on Sept 22, 2016 12:30:33 GMT
Option B is the correct way to do this. If you want to add an OEM resource under Power, you'd have to add a navigation property within the OEM structure of Power, which in your case would be inside the "FrequencyScaling" structure. You can then make a different schema file for that OEM entity definition.
So, the overall response would look something like this:
{ "@odata.context": "/redfish/v1/$metadata#Power.Power", "@odata.id": <URI for Power Resource being returned>, "@odata.type": "#Power.v1_2_0.Power", "Id": "Power", <Insert standard Power properties as needed>, "Oem": { "Contoso": { "@odata.type": "#FrequencyScaling.v1_0_0.FrequencyScaling", "Status" : "Enabled", "StepValuePercentage": 50, "MyNewOemResourceLink: { "@odata.id": <Link to subordinate OEM resource> } } } } If you're going to be adding more things in the "Oem" structure of Power beyond FrequencyScaling, it might be a good idea to use a more generic name for the structure.
Also keep in mind you should be using your company name inside the "Oem" structure (and not Contoso).
|
|
|
Post by j2hilland on Sept 22, 2016 19:10:27 GMT
The PowerPoint is just some of the recommendations and isn't meant as a substitute for reading the spec (which has additional information). But you ask a very good question, so I'll comment. You can't add it to an existing anything. The additionalProperties=false in the JSONSchema and similar rules in CSDL prevent this. But notice that every single resource has "OEM" in it and that construct does have additionalProperties=true. So that's the place you add the extension. There is a good example of this in ComputerSystem mockups for System/1 for an extension for a fictional company called "Contoso". So let's assume your Company name or stock ticker is "XYZZY". You would do two things: 1) define a Schema in both CSDL and JSON Schema to match the payload you want to add and 2) put that Schema in the OEM section. Using your example of FrequencyScaling, I think it would go best in Processor resources under the processor collection. I don't think you should put it under ComputerSystem, but you might. You would never extend a collection. Those are un-versioned and really are just meant to be a "bag of stuff" with no properties/semantics other than being a bag. So the actual Resource, with my company name being XYZZY, would look something like this: { "@odata.context": "/redfish/v1/$metadata#Systems/Members/1/Processors/Members/$entity", "@odata.id": "/redfish/v1/Systems/1/Processors/1", "@odata.type": "#Processor.v1_0_0.Processor", "Name": "Processor", "Id": "1", "Socket": "CPU 1", "ProcessorType": "CPU", "ProcessorArchitecture": "x86", "InstructionSet": "x86-64", "Manufacturer": "Intel(R) Corporation", "Model": "Multi-Core Intel(R) Xeon(R) processor 7xxx Series", "ProcessorID": { <Snip> }, "MaxSpeedMHz": 3700, "TotalCores": 8, "TotalThreads": 16, "Status": { "State": "Enabled", "Health": "OK" } "Oem" : { "XYZZY" : { "@odata.type": "http://schemas.xyzzy.com/XyzzyProcessor.v1_0_0.XyzzyProcessor", "FrequencyScaling" { "Status" : { "State" : "Enabled" } "StepValuePercentage" : 10 } } } } Notice a couple of things here: 1) Both the local JSONSchema (resource off of the root at /redfish/v1) and the $metadata should have references to this oem schema and the links header should have a rel value that points to it as well. And I might just want to put that file at "http://schemas.xyzzy.com/XyzzyProcessor.v1_0_0.xml" and "http://schemas.xyzzy.com/XyzzyProcessor.v1_0_0.json" or register it with the DMTF. 2) Notice that I used the Status property from Resource and used State from it. This is the unification/leverage that is talked about in the powerpoint deck of "Inheritance By Copy". Don't invent your own state/status mechanism. use the one the DMTF defined, even in your own schema. 3) The Schema would, in fact, just be a complexType and not a navigation property as I don't have an @odata.id or anything else. An example of schemas for those would be IPAddress. You can take it, rename it and modify it. ONE MORE THING: This sounds like a pretty common feature that just wasn't included in Redfish (yet). You can almost be sure it will be at some point and will probably be different than what you have (we don't try to do that but it happens for technical reasons sometimes). We would greatly appreciate it if you would submit the idea through the DMTF Feedback Portal at www.dmtf.org/standards/feedback and if you did so within the next week or two, we should have it as part of the standard by the next release. In fact, I'll champion it myself if you would kindly submit it to be part of the standard.
|
|
|
Post by andruszamojski on Oct 26, 2016 8:47:43 GMT
Hello, I have a couple of question regarding OEM which seems to be suitable in the thread.
1) ComputerSystem.v1_1_0.json has property called Boot. The property has "additionalProperties" set to false. What if implementation requires to add some OEM properties strictly related with Boot? Where it could be placed to be coherent with Redfish???
2) The same schema has BootSource enum with specified values. What if particular Redfish implementation does not support all of possibilities mentioend for particular property? Is it allowed to shorten/extend possibilities in schema for such enums or other properties?
So instaed of: "BootSource": { "type": "string", "enum": [ "None", "Pxe", "Floppy", "Cd", "Usb", "Hdd", "BiosSetup", "Utilities", "Diags", "UefiShell", "UefiTarget", "SDCard", "UefiHttp" ],
Are we allowed to specify for instance only such set? : "BootSource": { "type": "string", "enum": [ "None", "Pxe", "Floppy", "Cd" ],
|
|
|
Post by j2hilland on Oct 26, 2016 19:48:10 GMT
1) You cannot add properties to BootSource as an OEM. They are a fixed enumeration as part of Redfish - that's how we get interoperability between implementations. You have a couple of choices: a) an OEM section that has a property like "additionalBootSource" or something or b) submit your enumeration additions to the DMTF through the feedback portal and see if they are willing to add them. If you want to discuss them here, we can give you a good idea if they are likely to make it in or not. 2) Yes, you do not have to have all of the values available in the array. That is why it is a property and not a schema definition. So you can do as you suggest.
|
|
|
Post by andruszamojski on Oct 27, 2016 4:50:22 GMT
Thank you for explanation. Regarding 2) Let's say I will limit BootSource enum elements. Am I right that my implementation should also return updated schema of the resource (with limited BootSource options) ? Or schema should be left untouched?
Another related question - OEM property of a resource will be filled with some OEM data (let's take an example from this thread 3 posts above). Should OEM section of initial schema file of the resource be updated or is it enough to have odata.type link ("@odata.type": "http://schemas.xyzzy.com/XyzzyProcessor.v1_0_0.XyzzyProcessor") to schema of the OEM field in the OEM resource and schema may be untouched then? So having in mind Processor example should we update OEM section of the resource schema or may it be untouched as in example below?
"Processor": { ... "properties": { "@odata.context": { "$ref": "http://redfish.dmtf.org/schemas/v1/odata.4.0.0.json#/definitions/context" }, "@odata.id": { "$ref": "http://redfish.dmtf.org/schemas/v1/odata.4.0.0.json#/definitions/id" }, "@odata.type": { "$ref": "http://redfish.dmtf.org/schemas/v1/odata.4.0.0.json#/definitions/type" }, "Oem": { "$ref": "http://redfish.dmtf.org/schemas/v1/Resource.json#/definitions/Oem", "description": "This is the manufacturer/provider specific extension moniker used to divide the Oem object into sections.", "longDescription": "The value of this string shall be of the format for the reserved word *Oem*." },
|
|
|
Post by jautor on Oct 28, 2016 2:45:22 GMT
Thank you for explanation. Regarding 2) Let's say I will limit BootSource enum elements. Am I right that my implementation should also return updated schema of the resource (with limited BootSource options) ? Or schema should be left untouched? While you could re-publish an edited (subset) schema, that isn't necessary nor something that would be expected. Redfish uses an "annotation" mechanism for properties like BootSourceOverrideTarget to inform the client what enumerations are supported by the implementation. This is done for certain read-write properties, so that the client can avoid trial-and-error PATCH requests. The annotation takes the form of a separate property with the same name and "@redfish.AllowableValues" appended. In this case, " [email protected]". For example: "Boot": { "BootSourceOverrideEnabled": "Once", "BootSourceOverrideTarget": "Pxe", "[email protected]": [ "None", "Pxe", "Cd", "Usb", "Hdd", "BiosSetup", "Utilities", "Diags", "SDCard", "UefiTarget" ] },
Cheers, Jeff
|
|
|
Post by jautor on Oct 28, 2016 2:50:31 GMT
Another related question - OEM property of a resource will be filled with some OEM data (let's take an example from this thread 3 posts above). Should OEM section of initial schema file of the resource be updated or is it enough to have odata.type link ("@odata.type": "http://schemas.xyzzy.com/XyzzyProcessor.v1_0_0.XyzzyProcessor") to schema of the OEM field in the OEM resource and schema may be untouched then? So having in mind Processor example should we update OEM section of the resource schema or may it be untouched as in example below? "Processor": { ... "properties": { "@odata.context": { "$ref": "http://redfish.dmtf.org/schemas/v1/odata.4.0.0.json#/definitions/context" }, "@odata.id": { "$ref": "http://redfish.dmtf.org/schemas/v1/odata.4.0.0.json#/definitions/id" }, "@odata.type": { "$ref": "http://redfish.dmtf.org/schemas/v1/odata.4.0.0.json#/definitions/type" }, "Oem": { "$ref": "http://redfish.dmtf.org/schemas/v1/Resource.json#/definitions/Oem", "description": "This is the manufacturer/provider specific extension moniker used to divide the Oem object into sections.", "longDescription": "The value of this string shall be of the format for the reserved word *Oem*." }, You don't need to touch the existing Processor schema at all. As shown in J2Hilland's example above, the OEM section has it's own @odata.type (schema definition). So you create a new, separate schema file just for that OEM data. From your original question, that OEM schema would have two properties, "FrequencyScaling" (itself an embedded object with a "Status" property) and "StepValuePercentage". Hope that helps, Jeff
|
|
|
Post by andruszamojski on Nov 7, 2016 19:53:58 GMT
Jeff, thank you for explanation!
|
|
|
Post by wesleyhunt on May 8, 2017 20:59:05 GMT
What is the *correct* thing to do when extending the schema.
Is it #1. Adding everything to the existing OEM field? #2. Deriving a new resource type that inherits from an existing resource?
The spec talks primarily about option #1, but for instance (https://hewlettpackard.github.io/ilo4-rest-api-docs/#hpserverpcislot) shows HP specific derived resource types for many resources. If option #2 is more right than #1 why have the OEM field at all?
I would very much appreciate any light on the subject.
|
|
|
Post by mraineri on Jun 1, 2017 23:53:36 GMT
There are some things to consider when trying to decide if it's best to put a set of properties into the Oem object or to create a new resource that a client can find via the Oem object. It largely comes down to what your use cases are and what's easiest for the client. Some questions to consider when designing your extensions: - Will the client be requesting this data periodically (such as one every 5 seconds, or per minute, etc)?
- Does the number of HTTP requests matter in the environment?
- Does the payload size matter?
- How many properties are being added in the Oem context?
- Are there particular ways to group the data that makes it easier for the client to consume?
For example, if EthernetInterface is being extended to include a few quality of service indicators (maybe some counters, bandwidth percentages, etc), then it might make sense to just put these properties inside of the Oem object on an EthernetInterface resource. However, if the quality of service extensions to EthernetInterface are going to be a large data set that includes statistical information about the current state of the interface and historic data that a client will poll frequently, then it might make more sense to create an OEM defined subordinate resource (or set of resources) to EthernetInterface that a client can find via the Oem object in a given EthernetInterface instance. In some cases, it might make more sense to do a mix of the two if that will make things easier for the client, where some high level data is inside of the Oem object, and large data sets are on subordinate resources. In the end though, to ensure clients and services don't break compatability, you shouldn't be creating a new resource that inherits from an existing resource as a means of extension. For example, if the intent is to extend EthernetInterface.v1_0_0.EthernetInterface, you should not be creating something like ContosoEthernetInterface.v1_0_0.ContosoEthernetInterface that inherits directly from EthernetInterface.v1_0_0.EthernetInterface. Doing that will mean that when EthernetInterface.v1_1_0.EthernetInterface comes out, you'll have to go back and create a ContosoEthernetInterface.v1_1_0.ContosoEthernetInterface and reimplement all of the old properties. Keeping all of the OEM extensions in the independent Oem object will avoid that scenario.
|
|