Move existing schemas into folders

Reorganize the existing schemas into folders under redfish core.

The existing schema system has some problems:
1. It's hard to add new schemas
2. We have to rerun the script any time we want to change what schemas
   we use.
3. Adding schemas optionally takes effort

In an effort to combat this, this patchset moves all the existing
schemas into folders that represent their namespace names

dmtf/csdl represents the CSDL that dmtf publishes
oem/openbmc represents the CSDL that OpenBMC publishes

In theory, this means that in the future we can relax OEM_SCHEMAS.md,
and allow folks to possibly implement their own schemas in a way that
doesn't have to effect all other systems.

This also has the advantage of not requiring changes to
update_schemas.py when we want to add, remove, or modify what version of
a schema we use.  "current" schemas are just symlinks, so they can be
updated using git, and not necessarily have merge conflicts with one
another.

Tested: Redfish service validator passes.

Change-Id: I6d4a130bba4cb874ef00a06ed579cc67f53dc7ae
Signed-off-by: Ed Tanous <ed@tanous.net>
diff --git a/scripts/update_schemas.py b/scripts/update_schemas.py
index 2e8487d..ea17d04 100755
--- a/scripts/update_schemas.py
+++ b/scripts/update_schemas.py
@@ -23,132 +23,6 @@
  * github organization.
  ***************************************************************/"""
 
-# To use a new schema, add to list and rerun tool
-include_list = [
-    "AccountService",
-    "ActionInfo",
-    "AggregationService",
-    "AggregationSource",
-    "AggregationSourceCollection",
-    "Assembly",
-    "AttributeRegistry",
-    "Bios",
-    "Cable",
-    "CableCollection",
-    "Certificate",
-    "CertificateCollection",
-    "CertificateLocations",
-    "CertificateService",
-    "Chassis",
-    "ChassisCollection",
-    "ComputerSystem",
-    "ComputerSystemCollection",
-    "ComponentIntegrity",
-    "ComponentIntegrityCollection",
-    "Drive",
-    "DriveCollection",
-    "EnvironmentMetrics",
-    "EthernetInterface",
-    "EthernetInterfaceCollection",
-    "Event",
-    "EventDestination",
-    "EventDestinationCollection",
-    "EventService",
-    "FabricAdapter",
-    "FabricAdapterCollection",
-    "Fan",
-    "FanCollection",
-    "IPAddresses",
-    "JsonSchemaFile",
-    "JsonSchemaFileCollection",  # redfish/v1/JsonSchemas
-    "LogEntry",
-    "LogEntryCollection",
-    "LogService",
-    "LogServiceCollection",
-    "Manager",
-    "ManagerAccount",
-    "ManagerAccountCollection",
-    "ManagerCollection",
-    "ManagerDiagnosticData",
-    "ManagerNetworkProtocol",
-    "Memory",
-    "MemoryCollection",
-    "Message",
-    "MessageRegistry",
-    "MessageRegistryCollection",
-    "MessageRegistryFile",
-    "MessageRegistryFileCollection",
-    "MetricDefinition",
-    "MetricDefinitionCollection",
-    "MetricReport",
-    "MetricReportCollection",
-    "MetricReportDefinition",
-    "MetricReportDefinitionCollection",
-    "OperatingConfig",
-    "OperatingConfigCollection",
-    "PCIeDevice",
-    "PCIeDeviceCollection",
-    "PCIeFunction",
-    "PCIeFunctionCollection",
-    "PhysicalContext",
-    "PCIeSlots",
-    "Port",
-    "PortCollection",
-    "Power",
-    "PowerSubsystem",
-    "PowerSupply",
-    "PowerSupplyCollection",
-    "Privileges",  # Used in Role
-    "Processor",
-    "ProcessorCollection",
-    "Protocol",
-    "RedfishError",
-    "RedfishExtensions",
-    "Redundancy",
-    "Resource",
-    "Role",
-    "RoleCollection",
-    "Sensor",
-    "SensorCollection",
-    "ServiceRoot",
-    "Session",
-    "SessionCollection",
-    "SessionService",
-    "Settings",
-    "SoftwareInventory",
-    "SoftwareInventoryCollection",
-    "Storage",
-    "StorageCollection",
-    "StorageController",
-    "StorageControllerCollection",
-    "Task",
-    "TaskCollection",
-    "TaskService",
-    "TelemetryService",
-    "Thermal",
-    "ThermalMetrics",
-    "ThermalSubsystem",
-    "Triggers",
-    "TriggersCollection",
-    "UpdateService",
-    "VirtualMedia",
-    "VirtualMediaCollection",
-    "odata",
-    "odata-v4",
-    "redfish-error",
-    "redfish-payload-annotations",
-    "redfish-schema",
-    "redfish-schema-v1",
-]
-
-# OEM schemas
-oem_schema_names = [
-    "OemManager",
-    "OemComputerSystem",
-    "OemVirtualMedia",
-    "OpenBMCAccountService",
-]
-
 SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
 
 proxies = {"https": os.environ.get("https_proxy", None)}
@@ -173,8 +47,12 @@
 )
 
 
-schema_path = os.path.join(static_path, "schema")
-json_schema_path = os.path.join(static_path, "JsonSchemas")
+schema_path = os.path.join(
+    SCRIPT_DIR, "..", "redfish-core", "schema", "dmtf", "csdl"
+)
+json_schema_path = os.path.join(
+    SCRIPT_DIR, "..", "redfish-core", "schema", "dmtf", "json-schema"
+)
 metadata_index_path = os.path.join(static_path, "$metadata", "index.xml")
 
 zipBytesIO = BytesIO(r.content)
@@ -249,9 +127,6 @@
     elif zip_file.filename.startswith("json-schema/"):
         filename = os.path.basename(zip_file.filename)
         filenamesplit = filename.split(".")
-        # exclude schemas again to save flash space
-        if filenamesplit[0] not in include_list:
-            continue
         json_schema_files[filenamesplit[0]].append(filename)
     elif zip_file.filename.startswith("openapi/"):
         pass
@@ -266,16 +141,11 @@
 json_schema_files = OrderedDict(
     sorted(json_schema_files.items(), key=lambda x: SchemaVersion(x[0]))
 )
-
-csdl_filenames.sort(key=SchemaVersion)
-
-# Create oem filenames - from oem json names
-oem_csdl_filenames = []
-for filename in oem_schema_names:
-    oem_csdl_filenames.append(filename + "_v1.xml")
-
-# Append Oem csdl files
-csdl_filenames += oem_csdl_filenames
+for csdl_file in csdl_filenames:
+    with open(os.path.join(schema_path, csdl_file), "wb") as schema_out:
+        content = zip_ref.read(os.path.join("csdl", csdl_file))
+        content = content.replace(b"\r\n", b"\n")
+        schema_out.write(content)
 
 with open(metadata_index_path, "w") as metadata_index:
     metadata_index.write('<?xml version="1.0" encoding="UTF-8"?>\n')
@@ -285,28 +155,20 @@
         ' Version="4.0">\n'
     )
 
-    for filename in csdl_filenames:
-        # filename looks like Zone_v1.xml
-        if filename in oem_csdl_filenames:
-            with open(
-                os.path.join(schema_path, filename), "rb"
-            ) as oem_csdl_in:
-                content = oem_csdl_in.read()
-                content = content.replace(b"\r\n", b"\n")
-        else:
-            with open(os.path.join(schema_path, filename), "wb") as schema_out:
-                content = zip_ref.read(os.path.join("csdl", filename))
-                content = content.replace(b"\r\n", b"\n")
-                schema_out.write(content)
-                filenamesplit = filename.split("_")
-                if filenamesplit[0] not in include_list:
-                    continue
+    schema_static_dir = os.path.join(
+        SCRIPT_DIR, "..", "static", "redfish", "v1", "schema"
+    )
+    for filename in sorted(os.listdir(schema_static_dir), key=SchemaVersion):
+        if not filename.endswith(".xml"):
+            continue
 
         metadata_index.write(
             '    <edmx:Reference Uri="/redfish/v1/schema/' + filename + '">\n'
         )
 
-        xml_root = ET.fromstring(content)
+        xml_root = ET.parse(
+            os.path.join(schema_static_dir, filename)
+        ).getroot()
         edmx = "{http://docs.oasis-open.org/odata/ns/edmx}"
         edm = "{http://docs.oasis-open.org/odata/ns/edm}"
         for edmx_child in xml_root:
@@ -344,13 +206,18 @@
 
 for schema, version in json_schema_files.items():
     zip_filepath = os.path.join("json-schema", version[0])
-    schemadir = os.path.join(json_schema_path, schema)
-    os.makedirs(schemadir)
 
-    with open(os.path.join(schemadir, schema + ".json"), "wb") as schema_file:
+    with open(os.path.join(json_schema_path, version[0]), "wb") as schema_file:
         schema_file.write(zip_ref.read(zip_filepath).replace(b"\r\n", b"\n"))
 
 with open(os.path.join(cpp_path, "schemas.hpp"), "w") as hpp_file:
+    schemas = []
+    for root, dirs, files in os.walk(
+        os.path.join(SCRIPT_DIR, "..", "static", "redfish", "v1", "schema")
+    ):
+        for csdl_file in sorted(files, key=SchemaVersion):
+            if csdl_file.endswith(".xml"):
+                schemas.append(csdl_file.replace("_v1.xml", ""))
     hpp_file.write(
         "#pragma once\n"
         "{WARNING}\n"
@@ -362,14 +229,11 @@
         "{{\n"
         "    constexpr std::array<std::string_view,{SIZE}> schemas {{\n".format(
             WARNING=WARNING,
-            SIZE=len(json_schema_files) + len(oem_schema_names),
+            SIZE=len(schemas),
         )
     )
-    for schema_file in json_schema_files:
-        hpp_file.write('        "{}",\n'.format(schema_file))
-
-    for schema_file in oem_schema_names:
-        hpp_file.write('        "{}",\n'.format(schema_file))
+    for schema in schemas:
+        hpp_file.write('        "{}",\n'.format(schema))
 
     hpp_file.write("    };\n}\n")
 
@@ -377,19 +241,3 @@
 
 generate_schema_enums.main()
 generate_top_collections()
-
-# Now delete the xml schema files we aren't supporting
-if os.path.exists(schema_path):
-    files = [
-        os.path.join(schema_path, f)
-        for f in os.listdir(schema_path)
-        if not any([f.startswith(prefix) for prefix in skip_prefixes])
-    ]
-    for filename in files:
-        # filename will include the absolute path
-        filenamesplit = filename.split("/")
-        name = filenamesplit.pop()
-        namesplit = name.split("_")
-        if namesplit[0] not in include_list:
-            print("excluding schema: " + filename)
-            os.remove(filename)