Remove nlohmann::json::items()

nlohmann::json::items() throws an exception if the object in question is
not a json object.  This has the potential to cause problems, and isn't
in line with the standard that we code against.

Replace all uses of items with iterating the nlohmann::json::object_t.

This adds a new error check for pulling the object_t out of the
nlohmann::json object before each iteration, to ensure that we're
handling errors.

Tested: Redfish service validator passes.

Change-Id: I2934c9450ec296c76544c2a7c5855c9b519eae7f
Signed-off-by: Ed Tanous <ed@tanous.net>
diff --git a/include/event_service_store.hpp b/include/event_service_store.hpp
index f03bd79..f7f03ab 100644
--- a/include/event_service_store.hpp
+++ b/include/event_service_store.hpp
@@ -26,26 +26,27 @@
     std::vector<std::string> metricReportDefinitions;
 
     static std::shared_ptr<UserSubscription>
-        fromJson(const nlohmann::json& j, const bool loadFromOldConfig = false)
+        fromJson(const nlohmann::json::object_t& j,
+                 const bool loadFromOldConfig = false)
     {
         std::shared_ptr<UserSubscription> subvalue =
             std::make_shared<UserSubscription>();
-        for (const auto& element : j.items())
+        for (const auto& element : j)
         {
-            if (element.key() == "Id")
+            if (element.first == "Id")
             {
                 const std::string* value =
-                    element.value().get_ptr<const std::string*>();
+                    element.second.get_ptr<const std::string*>();
                 if (value == nullptr)
                 {
                     continue;
                 }
                 subvalue->id = *value;
             }
-            else if (element.key() == "Destination")
+            else if (element.first == "Destination")
             {
                 const std::string* value =
-                    element.value().get_ptr<const std::string*>();
+                    element.second.get_ptr<const std::string*>();
                 if (value == nullptr)
                 {
                     continue;
@@ -58,63 +59,68 @@
                 }
                 subvalue->destinationUrl = std::move(*url);
             }
-            else if (element.key() == "Protocol")
+            else if (element.first == "Protocol")
             {
                 const std::string* value =
-                    element.value().get_ptr<const std::string*>();
+                    element.second.get_ptr<const std::string*>();
                 if (value == nullptr)
                 {
                     continue;
                 }
                 subvalue->protocol = *value;
             }
-            else if (element.key() == "DeliveryRetryPolicy")
+            else if (element.first == "DeliveryRetryPolicy")
             {
                 const std::string* value =
-                    element.value().get_ptr<const std::string*>();
+                    element.second.get_ptr<const std::string*>();
                 if (value == nullptr)
                 {
                     continue;
                 }
                 subvalue->retryPolicy = *value;
             }
-            else if (element.key() == "Context")
+            else if (element.first == "Context")
             {
                 const std::string* value =
-                    element.value().get_ptr<const std::string*>();
+                    element.second.get_ptr<const std::string*>();
                 if (value == nullptr)
                 {
                     continue;
                 }
                 subvalue->customText = *value;
             }
-            else if (element.key() == "EventFormatType")
+            else if (element.first == "EventFormatType")
             {
                 const std::string* value =
-                    element.value().get_ptr<const std::string*>();
+                    element.second.get_ptr<const std::string*>();
                 if (value == nullptr)
                 {
                     continue;
                 }
                 subvalue->eventFormatType = *value;
             }
-            else if (element.key() == "SubscriptionType")
+            else if (element.first == "SubscriptionType")
             {
                 const std::string* value =
-                    element.value().get_ptr<const std::string*>();
+                    element.second.get_ptr<const std::string*>();
                 if (value == nullptr)
                 {
                     continue;
                 }
                 subvalue->subscriptionType = *value;
             }
-            else if (element.key() == "MessageIds")
+            else if (element.first == "MessageIds")
             {
-                const auto& obj = element.value();
-                for (const auto& val : obj.items())
+                const nlohmann::json::array_t* obj =
+                    element.second.get_ptr<const nlohmann::json::array_t*>();
+                if (obj == nullptr)
+                {
+                    continue;
+                }
+                for (const auto& val : *obj)
                 {
                     const std::string* value =
-                        val.value().get_ptr<const std::string*>();
+                        val.get_ptr<const std::string*>();
                     if (value == nullptr)
                     {
                         continue;
@@ -122,13 +128,18 @@
                     subvalue->registryMsgIds.emplace_back(*value);
                 }
             }
-            else if (element.key() == "RegistryPrefixes")
+            else if (element.first == "RegistryPrefixes")
             {
-                const auto& obj = element.value();
-                for (const auto& val : obj.items())
+                const nlohmann::json::array_t* obj =
+                    element.second.get_ptr<const nlohmann::json::array_t*>();
+                if (obj == nullptr)
+                {
+                    continue;
+                }
+                for (const auto& val : *obj)
                 {
                     const std::string* value =
-                        val.value().get_ptr<const std::string*>();
+                        val.get_ptr<const std::string*>();
                     if (value == nullptr)
                     {
                         continue;
@@ -136,13 +147,18 @@
                     subvalue->registryPrefixes.emplace_back(*value);
                 }
             }
-            else if (element.key() == "ResourceTypes")
+            else if (element.first == "ResourceTypes")
             {
-                const auto& obj = element.value();
-                for (const auto& val : obj.items())
+                const nlohmann::json::array_t* obj =
+                    element.second.get_ptr<const nlohmann::json::array_t*>();
+                if (obj == nullptr)
+                {
+                    continue;
+                }
+                for (const auto& val : *obj)
                 {
                     const std::string* value =
-                        val.value().get_ptr<const std::string*>();
+                        val.get_ptr<const std::string*>();
                     if (value == nullptr)
                     {
                         continue;
@@ -150,29 +166,39 @@
                     subvalue->resourceTypes.emplace_back(*value);
                 }
             }
-            else if (element.key() == "HttpHeaders")
+            else if (element.first == "HttpHeaders")
             {
-                const auto& obj = element.value();
-                for (const auto& val : obj.items())
+                const nlohmann::json::object_t* obj =
+                    element.second.get_ptr<const nlohmann::json::object_t*>();
+                if (obj == nullptr)
+                {
+                    continue;
+                }
+                for (const auto& val : *obj)
                 {
                     const std::string* value =
-                        val.value().get_ptr<const std::string*>();
+                        val.second.get_ptr<const std::string*>();
                     if (value == nullptr)
                     {
                         BMCWEB_LOG_ERROR("Failed to parse value for key{}",
-                                         val.key());
+                                         val.first);
                         continue;
                     }
-                    subvalue->httpHeaders.set(val.key(), *value);
+                    subvalue->httpHeaders.set(val.first, *value);
                 }
             }
-            else if (element.key() == "MetricReportDefinitions")
+            else if (element.first == "MetricReportDefinitions")
             {
-                const auto& obj = element.value();
-                for (const auto& val : obj.items())
+                const nlohmann::json::array_t* obj =
+                    element.second.get_ptr<const nlohmann::json::array_t*>();
+                if (obj == nullptr)
+                {
+                    continue;
+                }
+                for (const auto& val : *obj)
                 {
                     const std::string* value =
-                        val.value().get_ptr<const std::string*>();
+                        val.get_ptr<const std::string*>();
                     if (value == nullptr)
                     {
                         continue;
@@ -184,7 +210,7 @@
             {
                 BMCWEB_LOG_ERROR(
                     "Got unexpected property reading persistent file: {}",
-                    element.key());
+                    element.first);
                 continue;
             }
         }
@@ -210,23 +236,23 @@
     uint32_t retryAttempts = 3;
     uint32_t retryTimeoutInterval = 30;
 
-    void fromJson(const nlohmann::json& j)
+    void fromJson(const nlohmann::json::object_t& j)
     {
-        for (const auto& element : j.items())
+        for (const auto& element : j)
         {
-            if (element.key() == "ServiceEnabled")
+            if (element.first == "ServiceEnabled")
             {
-                const bool* value = element.value().get_ptr<const bool*>();
+                const bool* value = element.second.get_ptr<const bool*>();
                 if (value == nullptr)
                 {
                     continue;
                 }
                 enabled = *value;
             }
-            else if (element.key() == "DeliveryRetryAttempts")
+            else if (element.first == "DeliveryRetryAttempts")
             {
                 const uint64_t* value =
-                    element.value().get_ptr<const uint64_t*>();
+                    element.second.get_ptr<const uint64_t*>();
                 if ((value == nullptr) ||
                     (*value > std::numeric_limits<uint32_t>::max()))
                 {
@@ -234,10 +260,10 @@
                 }
                 retryAttempts = static_cast<uint32_t>(*value);
             }
-            else if (element.key() == "DeliveryRetryIntervalSeconds")
+            else if (element.first == "DeliveryRetryIntervalSeconds")
             {
                 const uint64_t* value =
-                    element.value().get_ptr<const uint64_t*>();
+                    element.second.get_ptr<const uint64_t*>();
                 if ((value == nullptr) ||
                     (*value > std::numeric_limits<uint32_t>::max()))
                 {