Move bmcweb over to sdbusplus

This patchset moves bmcweb from using boost-dbus over entirely to
sdbusplus.  This has some nice improvements in performance (about 30%
of CPU cycles saved in dbus transactions), as well as makes this
project manuver closer to the upstream way of thinking.

Changes to bmcweb are largely ceremonial, and fall into a few
categories:
1. Moves async_method_call instances to the new format, and deletes any
use of the "endpoint" object in leiu of the sdbusplus style interface
2. sdbus object_path object doesn't allow access to the string
directly, so code that uses it moves to explicit casts.
3. The mapbox variant, while attempting to recreate boost::variant,
misses a T* get<T*>() method implementation, which allows using variant
without exceptions.  Currently, there is an overload for
mapbox::get_ptr implementation which replecates the functionality.

Tested by: Booting the bmcweb on a target, iterating through redfish
basic phosphor-webui usage, and websockets usage

Change-Id: I2d95882908d6eb6dba00b9219a221dd96449ca7b
Signed-off-by: Ed Tanous <ed.tanous@intel.com>
diff --git a/redfish-core/lib/chassis.hpp b/redfish-core/lib/chassis.hpp
index c7f7b95..7db9357 100644
--- a/redfish-core/lib/chassis.hpp
+++ b/redfish-core/lib/chassis.hpp
@@ -24,14 +24,16 @@
  * DBus types primitives for several generic DBus interfaces
  * TODO(Pawel) consider move this to separate file into boost::dbus
  */
-using ManagedObjectsType = std::vector<
-    std::pair<dbus::object_path,
-              std::vector<std::pair<
-                  std::string,
-                  std::vector<std::pair<std::string, dbus::dbus_variant>>>>>>;
+// Note, this is not a very useful variant, but because it isn't used to get
+// values, it should be as simple as possible
+// TODO(ed) invent a nullvariant type
+using VariantType = sdbusplus::message::variant<std::string>;
+using ManagedObjectsType = std::vector<std::pair<
+    sdbusplus::message::object_path,
+    std::vector<std::pair<std::string,
+                          std::vector<std::pair<std::string, VariantType>>>>>>;
 
-using PropertiesType =
-    boost::container::flat_map<std::string, dbus::dbus_variant>;
+using PropertiesType = boost::container::flat_map<std::string, VariantType>;
 
 /**
  * OnDemandChassisProvider
@@ -79,7 +81,8 @@
                     {"serial_number", "SerialNumber"}}}) {
             PropertiesType::const_iterator it = properties.find(p.first);
             if (it != properties.end()) {
-              const std::string *s = boost::get<std::string>(&it->second);
+              const std::string *s =
+                  mapbox::get_ptr<const std::string>(it->second);
               if (s != nullptr) {
                 output[p.second] = *s;
               }
@@ -88,9 +91,9 @@
           // Callback with success, and hopefully data.
           callback(true, output);
         },
-        {"xyz.openbmc_project.EntityManager",
-         "/xyz/openbmc_project/Inventory/Item/Chassis/" + res_name,
-         "org.freedesktop.DBus.Properties", "GetAll"},
+        "xyz.openbmc_project.EntityManager",
+        "/xyz/openbmc_project/Inventory/Item/Chassis/" + res_name,
+        "org.freedesktop.DBus.Properties", "GetAll",
         "xyz.openbmc_project.Configuration.Chassis");
   }
 
@@ -126,7 +129,7 @@
               if (interface.first ==
                   "xyz.openbmc_project.Configuration.Chassis") {
                 // Cut out everything until last "/", ...
-                const std::string &chassis_id = objpath.first.value;
+                const std::string &chassis_id = objpath.first.str;
                 std::size_t last_pos = chassis_id.rfind("/");
                 if (last_pos != std::string::npos) {
                   // and put it into output vector.
@@ -138,9 +141,9 @@
           // Finally make a callback with useful data
           callback(true, chassis_list);
         },
-        {"xyz.openbmc_project.EntityManager",
-         "/xyz/openbmc_project/Inventory/Item/Chassis",
-         "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"});
+        "xyz.openbmc_project.EntityManager",
+        "/xyz/openbmc_project/Inventory/Item/Chassis",
+        "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
   };
 };
 
diff --git a/redfish-core/lib/ethernet.hpp b/redfish-core/lib/ethernet.hpp
index 88ce9f2..ea465fb 100644
--- a/redfish-core/lib/ethernet.hpp
+++ b/redfish-core/lib/ethernet.hpp
@@ -24,14 +24,19 @@
  * DBus types primitives for several generic DBus interfaces
  * TODO(Pawel) consider move this to separate file into boost::dbus
  */
-using PropertiesMapType =
-    boost::container::flat_map<std::string, dbus::dbus_variant>;
+using PropertiesMapType = boost::container::flat_map<
+    std::string,
+    sdbusplus::message::variant<std::string, bool, uint8_t, int16_t, uint16_t,
+                                int32_t, uint32_t, int64_t, uint64_t, double>>;
 
 using GetManagedObjectsType = boost::container::flat_map<
-    dbus::object_path,
-    boost::container::flat_map<std::string, PropertiesMapType>>;
-
-using GetAllPropertiesType = PropertiesMapType;
+    sdbusplus::message::object_path,
+    boost::container::flat_map<
+        std::string,
+        boost::container::flat_map<
+            std::string, sdbusplus::message::variant<
+                             std::string, bool, uint8_t, int16_t, uint16_t,
+                             int32_t, uint32_t, int64_t, uint64_t, double>>>>;
 
 /**
  * Structure for keeping IPv4 data required by Redfish
@@ -76,8 +81,8 @@
   // Helper function that allows to extract GetAllPropertiesType from
   // GetManagedObjectsType, based on object path, and interface name
   const PropertiesMapType *extractInterfaceProperties(
-      const dbus::object_path &objpath, const std::string &interface,
-      const GetManagedObjectsType &dbus_data) {
+      const sdbusplus::message::object_path &objpath,
+      const std::string &interface, const GetManagedObjectsType &dbus_data) {
     const auto &dbus_obj = dbus_data.find(objpath);
     if (dbus_obj != dbus_data.end()) {
       const auto &iface = dbus_obj->second.find(interface);
@@ -89,22 +94,22 @@
   }
 
   // Helper Wrapper that does inline object_path conversion from string
-  // into dbus::object_path type
+  // into sdbusplus::message::object_path type
   inline const PropertiesMapType *extractInterfaceProperties(
       const std::string &objpath, const std::string &interface,
       const GetManagedObjectsType &dbus_data) {
-    const auto &dbus_obj = dbus::object_path{objpath};
+    const auto &dbus_obj = sdbusplus::message::object_path{objpath};
     return extractInterfaceProperties(dbus_obj, interface, dbus_data);
   }
 
   // Helper function that allows to get pointer to the property from
   // GetAllPropertiesType native, or extracted by GetAllPropertiesType
   template <typename T>
-  inline const T *extractProperty(const PropertiesMapType &properties,
-                                  const std::string &name) {
+  inline T const *const extractProperty(const PropertiesMapType &properties,
+                                        const std::string &name) {
     const auto &property = properties.find(name);
     if (property != properties.end()) {
-      return boost::get<T>(&property->second);
+      return mapbox::get_ptr<const T>(property->second);
     }
     return nullptr;
   }
@@ -177,7 +182,7 @@
     for (auto &objpath : dbus_data) {
       // Check if proper patter for object path appears
       if (boost::starts_with(
-              objpath.first.value,
+              static_cast<std::string>(objpath.first),
               "/xyz/openbmc_project/network/" + ethiface_id + "/ipv4/")) {
         // and get approrpiate interface
         const auto &interface =
@@ -244,7 +249,7 @@
           this, ethiface_id{std::move(ethiface_id)},
           callback{std::move(callback)}
         ](const boost::system::error_code error_code,
-          const GetManagedObjectsType &resp) {
+          GetManagedObjectsType &resp) {
 
           EthernetInterfaceData eth_data{};
           std::vector<IPv4AddressData> ipv4_data;
@@ -273,8 +278,8 @@
           // Finally make a callback with useful data
           callback(true, eth_data, ipv4_data);
         },
-        {"xyz.openbmc_project.Network", "/xyz/openbmc_project/network",
-         "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"});
+        "xyz.openbmc_project.Network", "/xyz/openbmc_project/network",
+        "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
   };
 
   /**
@@ -288,7 +293,7 @@
     crow::connections::system_bus->async_method_call(
         [ this, callback{std::move(callback)} ](
             const boost::system::error_code error_code,
-            const GetManagedObjectsType &resp) {
+            GetManagedObjectsType &resp) {
           // Callback requires vector<string> to retrieve all available ethernet
           // interfaces
           std::vector<std::string> iface_list;
@@ -310,8 +315,9 @@
               // this is what we're looking for.
               if (interface.first ==
                   "xyz.openbmc_project.Network.EthernetInterface") {
-                // Cut out everything until last "/", ...
-                const std::string &iface_id = objpath.first.value;
+                // Cut out everyting until last "/", ...
+                const std::string iface_id =
+                    static_cast<std::string>(objpath.first);
                 std::size_t last_pos = iface_id.rfind("/");
                 if (last_pos != std::string::npos) {
                   // and put it into output vector.
@@ -323,8 +329,8 @@
           // Finally make a callback with useful data
           callback(true, iface_list);
         },
-        {"xyz.openbmc_project.Network", "/xyz/openbmc_project/network",
-         "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"});
+        "xyz.openbmc_project.Network", "/xyz/openbmc_project/network",
+        "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
   };
 };
 
diff --git a/redfish-core/lib/network_protocol.hpp b/redfish-core/lib/network_protocol.hpp
index 1410122..581eb03 100644
--- a/redfish-core/lib/network_protocol.hpp
+++ b/redfish-core/lib/network_protocol.hpp
@@ -95,10 +95,10 @@
     }
   }
 
-  std::map<int, std::string> portToProtocolMap{
+  boost::container::flat_map<int, std::string> portToProtocolMap{
       {22, "SSH"}, {80, "HTTP"}, {443, "HTTPS"}, {623, "IPMI"}, {1900, "SSDP"}};
 
-  std::set<int> listeningPorts;
+  boost::container::flat_set<int> listeningPorts;
 };
 
 }  // namespace redfish
diff --git a/redfish-core/lib/sensors.hpp b/redfish-core/lib/sensors.hpp
index f427909..b0cbbe1 100644
--- a/redfish-core/lib/sensors.hpp
+++ b/redfish-core/lib/sensors.hpp
@@ -21,8 +21,6 @@
 #include <boost/algorithm/string/split.hpp>
 #include <boost/container/flat_map.hpp>
 #include <boost/range/algorithm/replace_copy_if.hpp>
-#include <boost/variant.hpp>
-#include <boost/variant/get.hpp>
 
 namespace redfish {
 
@@ -32,11 +30,12 @@
     std::pair<std::string,
               std::vector<std::pair<std::string, std::vector<std::string>>>>>;
 
+using SensorVariant = sdbusplus::message::variant<int64_t, double>;
+
 using ManagedObjectsVectorType = std::vector<std::pair<
-    dbus::object_path,
+    sdbusplus::message::object_path,
     boost::container::flat_map<
-        std::string,
-        boost::container::flat_map<dbus::string, dbus::dbus_variant>>>>;
+        std::string, boost::container::flat_map<std::string, SensorVariant>>>>;
 
 /**
  * AsyncResp
@@ -83,9 +82,6 @@
   const std::string path = "/xyz/openbmc_project/Sensors";
   const std::array<std::string, 1> interfaces = {
       "xyz.openbmc_project.Sensor.Value"};
-  const dbus::endpoint object_mapper(
-      "xyz.openbmc_project.ObjectMapper", "/xyz/openbmc_project/object_mapper",
-      "xyz.openbmc_project.ObjectMapper", "GetSubTree");
 
   // Response handler for parsing objects subtree
   auto resp_handler = [ callback{std::move(callback)}, asyncResp, sensorNames ](
@@ -136,8 +132,10 @@
   };
 
   // Make call to ObjectMapper to find all sensors objects
-  crow::connections::system_bus->async_method_call(resp_handler, object_mapper,
-                                                   path, 2, interfaces);
+  crow::connections::system_bus->async_method_call(
+      resp_handler, "xyz.openbmc_project.ObjectMapper",
+      "/xyz/openbmc_project/object_mapper", "xyz.openbmc_project.ObjectMapper",
+      "GetSubTree", path, 2, interfaces);
 }
 
 /**
@@ -149,10 +147,6 @@
 void getChassis(const std::shared_ptr<AsyncResp>& asyncResp,
                 Callback&& callback) {
   CROW_LOG_DEBUG << "getChassis Done";
-  const dbus::endpoint entityManager = {
-      "xyz.openbmc_project.EntityManager",
-      "/xyz/openbmc_project/Inventory/Item/Chassis",
-      "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"};
 
   // Process response from EntityManager and extract chassis data
   auto resp_handler = [ callback{std::move(callback)}, asyncResp ](
@@ -170,10 +164,11 @@
     CROW_LOG_DEBUG << "Chassis Prefix " << chassis_prefix;
     bool foundChassis = false;
     for (const auto& objDictEntry : resp) {
-      if (boost::starts_with(objDictEntry.first.value, chassis_prefix)) {
+      if (boost::starts_with(static_cast<std::string>(objDictEntry.first),
+                             chassis_prefix)) {
         foundChassis = true;
         const std::string sensorName =
-            objDictEntry.first.value.substr(chassis_prefix.size());
+            std::string(objDictEntry.first).substr(chassis_prefix.size());
         // Make sure this isn't a subobject (like a threshold)
         const std::size_t sensorPos = sensorName.find('/');
         if (sensorPos == std::string::npos) {
@@ -194,7 +189,10 @@
   };
 
   // Make call to EntityManager to find all chassis objects
-  crow::connections::system_bus->async_method_call(resp_handler, entityManager);
+  crow::connections::system_bus->async_method_call(
+      resp_handler, "xyz.openbmc_project.EntityManager",
+      "/xyz/openbmc_project/Inventory/Item/Chassis",
+      "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
 }
 
 /**
@@ -209,8 +207,7 @@
 void objectInterfacesToJson(
     const std::string& sensorName, const std::string& sensorType,
     const boost::container::flat_map<
-        std::string,
-        boost::container::flat_map<dbus::string, dbus::dbus_variant>>&
+        std::string, boost::container::flat_map<std::string, SensorVariant>>&
         interfacesDict,
     nlohmann::json& sensor_json) {
   // We need a value interface before we can do anything with it
@@ -226,7 +223,8 @@
   auto scale_it = value_it->second.find("Scale");
   // If a scale exists, pull value as int64, and use the scaling.
   if (scale_it != value_it->second.end()) {
-    const int64_t* int64Value = boost::get<int64_t>(&scale_it->second);
+    const int64_t* int64Value =
+        mapbox::get_ptr<const int64_t>(scale_it->second);
     if (int64Value != nullptr) {
       scaleMultiplier = *int64Value;
     }
@@ -289,10 +287,12 @@
     if (interfaceProperties != interfacesDict.end()) {
       auto value_it = interfaceProperties->second.find(std::get<1>(p));
       if (value_it != interfaceProperties->second.end()) {
-        const dbus::dbus_variant& valueVariant = value_it->second;
+        const SensorVariant& valueVariant = value_it->second;
         nlohmann::json& value_it = sensor_json[std::get<2>(p)];
+
         // Attempt to pull the int64 directly
-        const int64_t* int64Value = boost::get<int64_t>(&valueVariant);
+        const int64_t* int64Value =
+            mapbox::get_ptr<const int64_t>(valueVariant);
 
         if (int64Value != nullptr) {
           if (forceToInt || scaleMultiplier >= 0) {
@@ -303,7 +303,7 @@
           }
         }
         // Attempt to pull the float directly
-        const double* doubleValue = boost::get<double>(&valueVariant);
+        const double* doubleValue = mapbox::get_ptr<const double>(valueVariant);
 
         if (doubleValue != nullptr) {
           if (!forceToInt) {
@@ -342,7 +342,8 @@
               // Go through all objects and update response with
               // sensor data
               for (const auto& objDictEntry : resp) {
-                const std::string& objPath = objDictEntry.first.value;
+                const std::string& objPath =
+                    static_cast<std::string>(objDictEntry.first);
                 CROW_LOG_DEBUG << "getManagedObjectsCb parsing object "
                                << objPath;
                 if (!boost::starts_with(objPath, DBUS_SENSOR_PREFIX)) {
@@ -406,11 +407,9 @@
               }
             };
 
-            dbus::endpoint ep(connection, "/xyz/openbmc_project/Sensors",
-                              "org.freedesktop.DBus.ObjectManager",
-                              "GetManagedObjects");
             crow::connections::system_bus->async_method_call(
-                getManagedObjectsCb, ep);
+                getManagedObjectsCb, connection, "/xyz/openbmc_project/Sensors",
+                "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
           };
         };
     // Get connections and then pass it to get sensors