1 // SPDX-License-Identifier: Apache-2.0 2 // SPDX-FileCopyrightText: Copyright OpenBMC Authors 3 #include "registries.hpp" 4 5 // We need the registries_selector pulled into some cpp part so that the 6 // registration hooks run. 7 // NOLINTNEXTLINE(misc-include-cleaner) 8 #include "registries_selector.hpp" 9 #include "str_utility.hpp" 10 11 #include <algorithm> 12 #include <cstring> 13 #include <functional> 14 #include <map> 15 #include <optional> 16 #include <ranges> 17 #include <span> 18 #include <string> 19 #include <string_view> 20 #include <vector> 21 22 namespace redfish::registries 23 { 24 25 auto allRegistries() -> std::map<std::string, RegistryEntry>& 26 { 27 static std::map<std::string, RegistryEntry> registries; 28 return registries; 29 } 30 31 auto getRegistryFromPrefix(const std::string& registryName) 32 -> std::optional<RegistryEntryRef> 33 { 34 auto& registries = allRegistries(); 35 if (auto it = registries.find(registryName); it != registries.end()) 36 { 37 return std::ref(it->second); 38 } 39 40 return std::nullopt; 41 } 42 43 auto getRegistryMessagesFromPrefix(const std::string& registryName) 44 -> MessageEntries 45 { 46 auto registry = getRegistryFromPrefix(registryName); 47 if (!registry) 48 { 49 return {}; 50 } 51 52 return registry->get().entries; 53 } 54 55 const Message* getMessageFromRegistry(const std::string& messageKey, 56 std::span<const MessageEntry> registry) 57 { 58 std::span<const MessageEntry>::iterator messageIt = std::ranges::find_if( 59 registry, [&messageKey](const MessageEntry& messageEntry) { 60 return std::strcmp(messageEntry.first, messageKey.c_str()) == 0; 61 }); 62 if (messageIt != registry.end()) 63 { 64 return &messageIt->second; 65 } 66 67 return nullptr; 68 } 69 70 const Message* getMessage(std::string_view messageID) 71 { 72 // Redfish MessageIds are in the form 73 // RegistryName.MajorVersion.MinorVersion.MessageKey, so parse it to find 74 // the right Message 75 std::vector<std::string> fields; 76 fields.reserve(4); 77 bmcweb::split(fields, messageID, '.'); 78 if (fields.size() != 4) 79 { 80 return nullptr; 81 } 82 83 const std::string& registryName = fields[0]; 84 const std::string& messageKey = fields[3]; 85 86 // Find the right registry and check it for the MessageKey 87 return getMessageFromRegistry(messageKey, 88 getRegistryMessagesFromPrefix(registryName)); 89 } 90 91 } // namespace redfish::registries 92