xref: /openbmc/bmcweb/redfish-core/src/registries.cpp (revision d9495964cd857f8775677f3f5c1f35f0cf00c0a6)
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 <utility>
21 #include <vector>
22 
23 namespace redfish::registries
24 {
25 
allRegistries()26 auto allRegistries() -> std::map<std::string, RegistryEntry>&
27 {
28     static std::map<std::string, RegistryEntry> registries;
29     return registries;
30 }
31 
getRegistryFromPrefix(const std::string & registryName)32 auto getRegistryFromPrefix(const std::string& registryName)
33     -> std::optional<RegistryEntryRef>
34 {
35     auto& registries = allRegistries();
36     if (auto it = registries.find(registryName); it != registries.end())
37     {
38         return std::ref(it->second);
39     }
40 
41     return std::nullopt;
42 }
43 
getRegistryMessagesFromPrefix(const std::string & registryName)44 auto getRegistryMessagesFromPrefix(const std::string& registryName)
45     -> MessageEntries
46 {
47     auto registry = getRegistryFromPrefix(registryName);
48     if (!registry)
49     {
50         return {};
51     }
52 
53     return registry->get().entries;
54 }
55 
getMessageFromRegistry(const std::string & messageKey,std::span<const MessageEntry> registry)56 const Message* getMessageFromRegistry(const std::string& messageKey,
57                                       std::span<const MessageEntry> registry)
58 {
59     std::span<const MessageEntry>::iterator messageIt = std::ranges::find_if(
60         registry, [&messageKey](const MessageEntry& messageEntry) {
61             return std::strcmp(messageEntry.first, messageKey.c_str()) == 0;
62         });
63     if (messageIt != registry.end())
64     {
65         return &messageIt->second;
66     }
67 
68     return nullptr;
69 }
70 
getMessageComponents(std::string_view message)71 std::optional<MessageId> getMessageComponents(std::string_view message)
72 {
73     // Redfish Message are in the form
74     // RegistryName.MajorVersion.MinorVersion.MessageKey
75     std::vector<std::string> fields;
76     fields.reserve(4);
77     bmcweb::split(fields, message, '.');
78     if (fields.size() != 4)
79     {
80         return std::nullopt;
81     }
82 
83     return MessageId(std::move(fields[0]), std::move(fields[1]),
84                      std::move(fields[2]), std::move(fields[3]));
85 }
86 
getMessage(std::string_view messageID)87 const Message* getMessage(std::string_view messageID)
88 {
89     std::optional<MessageId> msgComponents = getMessageComponents(messageID);
90     if (!msgComponents)
91     {
92         return nullptr;
93     }
94 
95     // Find the right registry and check it for the MessageKey
96     return getMessageFromRegistry(
97         msgComponents->messageKey,
98         getRegistryMessagesFromPrefix(msgComponents->registryName));
99 }
100 
101 } // namespace redfish::registries
102