xref: /openbmc/bmcweb/redfish-core/src/registries.cpp (revision 4a102cd48c588d32c0a4d6610b4a9ed616f255f3)
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 
allRegistries()25 auto allRegistries() -> std::map<std::string, RegistryEntry>&
26 {
27     static std::map<std::string, RegistryEntry> registries;
28     return registries;
29 }
30 
getRegistryFromPrefix(const std::string & registryName)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 
getRegistryMessagesFromPrefix(const std::string & registryName)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 
getMessageFromRegistry(const std::string & messageKey,std::span<const MessageEntry> registry)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 
getMessage(std::string_view messageID)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