DMTF / Redfish-Service-Validator

The Redfish Service Validator is a Python3 tool for checking conformance of any "device" with a Redfish service interface against Redfish CSDL schema
Other
37 stars 33 forks source link

error about "is expected to be an object containing @odata.id" #574

Closed shawnw-smc closed 5 months ago

shawnw-smc commented 5 months ago

Hi,

I was running the tool on tag 2.4.0 for my OpenBMC project, but it encountered an error. I couldn't understand the meaning of the error, so I'm seeking help.

To simplify the validation, I removed some of the irrelevant URIs. Here are the logs: ConformanceLog_02_02_2024_072201.txt

It seems to be indicating that the representation of Zones is not as expected. The schema can be found here:: https://github.com/openbmc/bmcweb/blob/master/static/redfish/v1/schema/OemManager_v1.xml

Initially, redfish only response the the response below, but I encountered the same issue.

                        "Zones": [
                            {
                                "@odata.id": "/redfish/v1/Managers/1#/Oem/OpenBmc/Fan/FanZones/Zone_1"
                            }
                        ]

Therefore, I modified the response for /redfish/v1/managers/1, yet I continued to receive the same error.

    "Model": "OpenBmc",
    "Name": "OpenBmc Manager",
    "Oem": {
        "OpenBmc": {
            "@odata.id": "/redfish/v1/Managers/1#/Oem/OpenBmc",
            "@odata.type": "#OemManager.OpenBmc",
            "Fan": {
                "@odata.id": "/redfish/v1/Managers/1#/Oem/OpenBmc/Fan",
                "@odata.type": "#OemManager.Fan",
                "FanControllers": {
                    "@odata.id": "/redfish/v1/Managers/1#/Oem/OpenBmc/Fan/FanControllers",
                    "@odata.type": "#OemManager.FanControllers",
                    "Fan_Zone1": {
                        "@odata.id": "/redfish/v1/Managers/1#/Oem/OpenBmc/Fan/FanControllers/Fan_Zone1",
                        "@odata.type": "#OemManager.FanController",
                        "FFGainCoefficient": 1.0,
                        ... 
                        "Zones": [
                            {
                                "@odata.id": "/redfish/v1/Managers/1#/Oem/OpenBmc/Fan/FanZones/Zone_1",
                                "@odata.type": "#OemManager.FanZone",
                                "Chassis": {
                                    "@odata.id": "/redfish/v1/Chassis/1"
                                },
                                "FailSafePercent": 100.0,
                                "MinThermalOutput": 10.0
                            }
                        ]
                    },

The error shows: image

Based on my understanding, the Zones property should be an array consisting of a FanZone object. Each FanZone object contains Chassis, FailSafePercent, and MinThermalOutput properties.

Could anyone kindly identify the error for me so I can address the issue?

Many thanks, Shawn

mraineri commented 5 months ago

When you're making @odata.id properties in embedded objects like that, you need to follow strict RFC6901 JSON pointer rules. So, using "Zone_1" at the end of that URI is illegal since the object is inside of an array; it's expected to be the array index.

However, I would recommend reviewing why you need @odata.id in these embedded objects in the first place. Do you model these objects as "referenceable members" and thus need to provide hardened linkage to them somewhere else in the model? If you're not using the "referenceable member" construct at all, then @odata.id shouldn't even be present in the first place.

shawnw-smc commented 5 months ago

@mraineri Thanks for your quick reply to point out the issue.

Yes, from the response, I guess that's what OpenBMC intends to do. There are a few Fan Zones representing the data.

                "FanZones": {
                    "@odata.id": "/redfish/v1/Managers/1#/Oem/OpenBmc/Fan/FanZones",
                    "@odata.type": "#OemManager.FanZones",
                    "Zone_1": {
                        "@odata.id": "/redfish/v1/Managers/1#/Oem/OpenBmc/Fan/FanZones/Zone_1",
                        "@odata.type": "#OemManager.FanZone",
                        "Chassis": {
                            "@odata.id": "/redfish/v1/Chassis/1"
                        },
                        "FailSafePercent": 100.0,
                        "MinThermalOutput": 10.0
                    },

The others could simply refer to these zones. For example:

                        "Zones": [
                            {
                                "@odata.id": "/redfish/v1/Managers/1#/Oem/OpenBmc/Fan/FanZones/Zone_1"
                            },
                            {
                                "@odata.id": "/redfish/v1/Managers/1#/Oem/OpenBmc/Fan/FanZones/Zone_2"
                            },
                            {
                                "@odata.id": "/redfish/v1/Managers/1#/Oem/OpenBmc/Fan/FanZones/Zone_3"
                            }
                        ]

I thought about the RelatedItem property in SoftwareInventory_v1.xml. It is of the Collection(Resource.Item) type. Is it because Resource.Item is described as "the base type for resources and members that can be linked to," does this mean it can be used in its current form for linking purposes?

    "RelatedItem": [
        {
            "@odata.id": "/redfish/v1/Managers/bmc"
        }
    ],

Regarding what OpenBMC intends to accomplish, I'm considering changing the type of Zones to Collection(Resource.Item), as it seems others have done the same. On the other hand, the FanZone would change to Resource.Resource. However, I'm not sure if this would break anything. Could you provide some advice on these changes?

Many Thanks, Shawn

mraineri commented 5 months ago

If the intent is to be able to use things like "RelatedItem" like that, then yes, you do need to make use of the referenceable member construct. However, I would advise against this since it has led to significant confusion from users.

At least based on your OEM schema today, the schema is not defined properly to use that construct. All of those objects are defined with "ComplexType" statements, which means they are not referenceable objects with @odata.id. This would need to be fixed to use "EntityType" with the base type pointing to Resource.ReferenceableMember. The property instances referencing those objects would also need to be modified to be "NavigationProperty" instead of just "Property".

You could also redefine the entire structure to use proper resources (using Resource.Resource as the base definition). That would mean instead of embedding everything in /redfish/v1/Managers/bmc, you'd create subordinate resources like "/redfish/v1/Managers/bmc/Oem/OpenBMC/FanZones". This is significantly more work, but if the cross linkage is needed, then it's worth evaluating this approach since it's more in line with how we model things in Redfish.

shawnw-smc commented 5 months ago

Thanks, @mraineri. I'll study it further. Your advice is very helpful to me. Thanks again. 👍