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/CMakeLists.txt b/CMakeLists.txt
index 869fc48..3ff1182 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -63,7 +63,8 @@
 endif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
 
 if(NOT ${YOCTO_DEPENDENCIES}) # Download and unpack googletest at configure time
-  configure_file(CMakeLists.txt.in 3rdparty/CMakeLists.txt)
+  configure_file(${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt.in
+                 3rdparty/CMakeLists.txt)
   execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
                   WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/3rdparty)
   execute_process(COMMAND ${CMAKE_COMMAND} --build .
@@ -80,8 +81,20 @@
 add_definitions(-DBOOST_NO_TYPEID)
 # set(Boost_USE_STATIC_LIBS ON)
 
-find_package(Boost 1.64 REQUIRED)
-include_directories(${Boost_INCLUDE_DIRS})
+#find_package(Boost 1.66 REQUIRED)
+include_directories(${CMAKE_BINARY_DIR}/boost-src)
+
+# sdbusplus
+if(NOT ${YOCTO_DEPENDENCIES})
+  include_directories(${CMAKE_BINARY_DIR}/sdbusplus-src
+                     ${CMAKE_BINARY_DIR}/prefix/include)
+  set(WANT_TRANSACTION 0)
+
+  configure_file(${CMAKE_BINARY_DIR}/sdbusplus-src/sdbusplus/server.hpp.in
+                ${CMAKE_BINARY_DIR}/prefix/include/sdbusplus/server.hpp @ONLY)
+  configure_file(${CMAKE_BINARY_DIR}/sdbusplus-src/sdbusplus/bus.hpp.in
+                ${CMAKE_BINARY_DIR}/prefix/include/sdbusplus/bus.hpp @ONLY)
+endif()
 
 # Openssl
 find_package(OpenSSL REQUIRED)
@@ -96,6 +109,9 @@
   add_definitions(-DCROW_ENABLE_DEBUG)
 endif(CMAKE_BUILD_TYPE MATCHES Debug)
 
+#add_definitions(-DCROW_ENABLE_LOGGING)
+#add_definitions(-DCROW_ENABLE_DEBUG)
+
 add_definitions(-DCROW_ENABLE_SSL)
 include_directories(${CMAKE_CURRENT_SOURCE_DIR}/crow/include)
 
@@ -113,9 +129,6 @@
 
 add_definitions("-Wno-attributes")
 
-# Boost-dbus
-find_package(boost-dbus REQUIRED)
-
 # tinyxml2
 find_package(tinyxml2 REQUIRED)
 
@@ -168,7 +181,6 @@
   target_link_libraries(webtest ${GMOCK_LIBRARIES})
 
   target_link_libraries(webtest pthread)
-  target_link_libraries(webtest boost-dbus)
   target_link_libraries(webtest ${OPENSSL_LIBRARIES})
   target_link_libraries(webtest ${ZLIB_LIBRARIES})
   target_link_libraries(webtest pam)
@@ -182,7 +194,6 @@
 
 # bmcweb
 add_executable(bmcweb ${WEBSERVER_MAIN} ${HDR_FILES} ${SRC_FILES})
-target_link_libraries(bmcweb boost-dbus)
 target_link_libraries(bmcweb pthread)
 target_link_libraries(bmcweb ${OPENSSL_LIBRARIES})
 target_link_libraries(bmcweb ${ZLIB_LIBRARIES})
@@ -190,6 +201,7 @@
 target_link_libraries(bmcweb -lsystemd)
 target_link_libraries(bmcweb -lstdc++fs)
 target_link_libraries(bmcweb tinyxml2)
+target_link_libraries(bmcweb sdbusplus)
 install(TARGETS bmcweb DESTINATION bin)
 
 add_executable(getvideo src/getvideo_main.cpp)
diff --git a/CMakeLists.txt.in b/CMakeLists.txt.in
index ccce7d8..7025398 100644
--- a/CMakeLists.txt.in
+++ b/CMakeLists.txt.in
@@ -2,6 +2,29 @@
 
 include(ExternalProject)
 
+file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/prefix)
+file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/prefix/include)
+
+
+# add back GIT_TAG in with the correct SHA1 once
+# https://gerrit.openbmc-project.xyz/#/c/10278/ is merged
+#GIT_TAG
+#2a3af936625bc66cfc6bae1952b57138f141377e
+ExternalProject_Add(
+    sdbusplus
+    GIT_REPOSITORY
+    "https://gerrit.openbmc-project.xyz/openbmc/sdbusplus"
+    GIT_TAG
+    fce038ad5ac9f458b03d55b441253a9c05dadc3e 
+    SOURCE_DIR        "${CMAKE_BINARY_DIR}/sdbusplus-src"
+    BINARY_DIR        "${CMAKE_BINARY_DIR}/sdbusplus-build"
+    CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/prefix
+    CONFIGURE_COMMAND ""
+    BUILD_COMMAND ""
+    INSTALL_COMMAND cp -r "${CMAKE_BINARY_DIR}/sdbusplus-src/sdbusplus"
+                          "${CMAKE_BINARY_DIR}/prefix/include"
+)
+
 ExternalProject_Add(
     tinyxml2
     GIT_REPOSITORY
@@ -26,17 +49,6 @@
 )
 
 ExternalProject_Add(
-    boost-dbus
-    GIT_REPOSITORY
-    "ssh://git-amr-2.devtools.intel.com:29418/openbmc-boost-dbus"
-    GIT_TAG
-    895ef1b67f3aaac3808296e4729b991fcf276832
-    SOURCE_DIR        "${CMAKE_BINARY_DIR}/boost-dbus-src"
-    BINARY_DIR        "${CMAKE_BINARY_DIR}/boost-dbus-build"
-    CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/prefix -DBOOST_DBUS_BUILD_UT=OFF
-)
-
-ExternalProject_Add(
     gtest
     GIT_REPOSITORY
     "https://github.com/google/googletest.git"
@@ -46,4 +58,4 @@
     SOURCE_DIR        "${CMAKE_BINARY_DIR}/googletest-src"
     BINARY_DIR        "${CMAKE_BINARY_DIR}/googletest-build"
     CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/prefix
-)
\ No newline at end of file
+)
diff --git a/include/dbus_monitor.hpp b/include/dbus_monitor.hpp
index 0306183..ab7ebef 100644
--- a/include/dbus_monitor.hpp
+++ b/include/dbus_monitor.hpp
@@ -1,7 +1,6 @@
 #pragma once
-#include <dbus/filter.hpp>
-#include <dbus/match.hpp>
 #include <dbus_singleton.hpp>
+#include <sdbusplus/bus/match.hpp>
 #include <crow/app.h>
 #include <boost/container/flat_map.hpp>
 
@@ -9,34 +8,38 @@
 namespace dbus_monitor {
 
 struct DbusWebsocketSession {
-  std::vector<std::unique_ptr<dbus::match>> matches;
-  std::vector<dbus::filter> filters;
+  std::vector<std::unique_ptr<sdbusplus::bus::match::match>> matches;
 };
 
 static boost::container::flat_map<crow::websocket::connection*,
                                   DbusWebsocketSession>
     sessions;
 
-void on_property_update(dbus::filter& filter, boost::system::error_code ec,
-                        dbus::message s) {
-  if (!ec) {
-    std::string object_name;
-    std::vector<std::pair<std::string, dbus::dbus_variant>> values;
-    s.unpack(object_name, values);
-    nlohmann::json j;
-    for (auto& value : values) {
-      boost::apply_visitor([&](auto val) { j[s.get_path()] = val; },
-                           value.second);
-    }
-    auto data_to_send = j.dump();
-
-    for (auto& session : sessions) {
-      session.first->send_text(data_to_send);
-    }
+int on_property_update(sd_bus_message* m, void* userdata,
+                       sd_bus_error* ret_error) {
+  if (ret_error == nullptr || sd_bus_error_is_set(ret_error)) {
+    CROW_LOG_ERROR << "Sdbus error in on_property_update";
+    return 0;
   }
-  filter.async_dispatch([&](boost::system::error_code ec, dbus::message s) {
-    on_property_update(filter, ec, s);
-  });
+  sdbusplus::message::message message(m);
+  std::string object_name;
+  std::vector<
+      std::pair<std::string, sdbusplus::message::variant<
+                                 std::string, bool, int64_t, uint64_t, double>>>
+      values;
+  message.read(object_name, values);
+  nlohmann::json j;
+  const std::string& path = message.get_path();
+  for (auto& value : values) {
+    mapbox::util::apply_visitor([&](auto&& val) { j[path] = val; },
+                                value.second);
+  }
+  std::string data_to_send = j.dump();
+
+  for (const std::pair<crow::websocket::connection*, DbusWebsocketSession>&
+           session : sessions) {
+    session.first->send_text(data_to_send);
+  }
 };
 
 template <typename... Middlewares>
@@ -56,19 +59,10 @@
             "interface='org.freedesktop.DBus.Properties',"
             "path_namespace='" +
             path_namespace + "'");
-        sessions[&conn].matches.push_back(std::make_unique<dbus::match>(
-            crow::connections::system_bus, std::move(match_string)));
-
-        sessions[&conn].filters.emplace_back(
-            crow::connections::system_bus, [path_namespace](dbus::message m) {
-              return m.get_member() == "PropertiesChanged" &&
-                     boost::starts_with(m.get_path(), path_namespace);
-            });
-        auto& this_filter = sessions[&conn].filters.back();
-        this_filter.async_dispatch(
-            [&](boost::system::error_code ec, dbus::message s) {
-              on_property_update(this_filter, ec, s);
-            });
+        sessions[&conn].matches.emplace_back(
+            std::make_unique<sdbusplus::bus::match::match>(
+                *crow::connections::system_bus, match_string,
+                on_property_update));
 
       })
       .onclose([&](crow::websocket::connection& conn,
@@ -78,5 +72,5 @@
         CROW_LOG_ERROR << "Got unexpected message from client on sensorws";
       });
 }
-}  // namespace redfish
+}  // namespace dbus_monitor
 }  // namespace crow
diff --git a/include/dbus_singleton.hpp b/include/dbus_singleton.hpp
index e2fd2d6..e6be81b 100644
--- a/include/dbus_singleton.hpp
+++ b/include/dbus_singleton.hpp
@@ -1,10 +1,21 @@
 #pragma once
-#include <dbus/connection.hpp>
+#include <sdbusplus/asio/connection.hpp>
+#include <iostream>
+
+namespace mapbox {
+template <typename T, typename... Types>
+const T* get_ptr(const mapbox::util::variant<Types...>& v) {
+  if (v.template is<std::remove_const_t<T>>()) {
+    return &v.template get_unchecked<std::remove_const_t<T>>();
+  } else {
+    return nullptr;
+  }
+}
+}  // namespace mapbox
 
 namespace crow {
 namespace connections {
+static std::shared_ptr<sdbusplus::asio::connection> system_bus;
 
-static std::shared_ptr<dbus::connection> system_bus;
-
-}  // namespace dbus
-}  // namespace crow
\ No newline at end of file
+}  // namespace connections
+}  // namespace crow
diff --git a/include/intel_oem.hpp b/include/intel_oem.hpp
index e821807..f2dc163 100644
--- a/include/intel_oem.hpp
+++ b/include/intel_oem.hpp
@@ -10,24 +10,29 @@
 template <typename... Middlewares>
 void request_routes(Crow<Middlewares...>& app) {
   CROW_ROUTE(app, "/intel/firmwareupload")
-      .methods("POST"_method)([](const crow::request& req) {
+      .methods(
+          "POST"_method)([](const crow::request& req, crow::response& res) {
         std::string filepath("/tmp/fw_update_image");
         std::ofstream out(filepath, std::ofstream::out | std::ofstream::binary |
                                         std::ofstream::trunc);
         out << req.body;
         out.close();
+        crow::connections::system_bus->async_method_call(
+            [&](boost::system::error_code ec) {
+              std::cout << "async_method_call callback\n";
+              if (ec) {
+                std::cerr << "error with async_method_call \n";
+                res.json_value["status"] = "Upload failed";
+              } else {
+                res.json_value["status"] = "Upload Successful";
+              }
+              res.end();
+            },
+            "xyz.openbmc_project.fwupdate1.server",
+            "/xyz/openbmc_project/fwupdate1", "xyz.openbmc_project.fwupdate1",
+            "start", "file://" + filepath);
 
-        auto m = dbus::message::new_call(
-            {"xyz.openbmc_project.fwupdate1.server",
-             "/xyz/openbmc_project/fwupdate1", "xyz.openbmc_project.fwupdate1"},
-            "start");
-
-        m.pack(std::string("file://") + filepath);
-        crow::connections::system_bus->send(m);
-        nlohmann::json j;
-        j["status"] = "Upload Successful";
-        return j;
       });
 }
-}  // namespace redfish
+}  // namespace intel_oem
 }  // namespace crow
diff --git a/include/openbmc_dbus_rest.hpp b/include/openbmc_dbus_rest.hpp
index d42c04b..4257127 100644
--- a/include/openbmc_dbus_rest.hpp
+++ b/include/openbmc_dbus_rest.hpp
@@ -1,11 +1,6 @@
 #include <crow/app.h>
 
 #include <tinyxml2.h>
-#include <dbus/connection.hpp>
-#include <dbus/endpoint.hpp>
-#include <dbus/filter.hpp>
-#include <dbus/match.hpp>
-#include <dbus/message.hpp>
 #include <dbus_singleton.hpp>
 #include <boost/container/flat_set.hpp>
 
@@ -15,12 +10,11 @@
 void introspect_objects(crow::response &res, std::string process_name,
                         std::string path,
                         std::shared_ptr<nlohmann::json> transaction) {
-  dbus::endpoint introspect_endpoint(
-      process_name, path, "org.freedesktop.DBus.Introspectable", "Introspect");
   crow::connections::system_bus->async_method_call(
-      [&, process_name{std::move(process_name)}, object_path{std::move(path)} ](
-          const boost::system::error_code ec,
-          const std::string &introspect_xml) {
+      [
+        &res, transaction, process_name{std::move(process_name)},
+        object_path{std::move(path)}
+      ](const boost::system::error_code ec, const std::string &introspect_xml) {
         if (ec) {
           CROW_LOG_ERROR << "Introspect call failed with error: "
                          << ec.message() << " on process: " << process_name
@@ -35,7 +29,7 @@
           tinyxml2::XMLNode *pRoot = doc.FirstChildElement("node");
           if (pRoot == nullptr) {
             CROW_LOG_ERROR << "XML document failed to parse " << process_name
-                           << " " << path << "\n";
+                           << " " << object_path << "\n";
 
           } else {
             tinyxml2::XMLElement *node = pRoot->FirstChildElement("node");
@@ -61,14 +55,23 @@
           res.end();
         }
       },
-      introspect_endpoint);
+      process_name, path, "org.freedesktop.DBus.Introspectable", "Introspect");
 }
-using ManagedObjectType = std::vector<std::pair<
-    dbus::object_path, boost::container::flat_map<
-                           std::string, boost::container::flat_map<
-                                            std::string, dbus::dbus_variant>>>>;
 
-void get_manged_objects_for_enumerate(
+// A smattering of common types to unpack.  TODO(ed) this should really iterate
+// the sdbusplus object directly and build the json response
+using DbusRestVariantType = sdbusplus::message::variant<
+    std::vector<std::tuple<std::string, std::string, std::string>>, std::string,
+    int64_t, uint64_t, double, int32_t, uint32_t, int16_t, uint16_t, uint8_t,
+    bool>;
+
+using ManagedObjectType = std::vector<std::pair<
+    sdbusplus::message::object_path,
+    boost::container::flat_map<
+        std::string,
+        boost::container::flat_map<std::string, DbusRestVariantType>>>>;
+
+void get_managed_objects_for_enumerate(
     const std::string &object_name, const std::string &connection_name,
     crow::response &res, std::shared_ptr<nlohmann::json> transaction) {
   crow::connections::system_bus->async_method_call(
@@ -78,13 +81,29 @@
           CROW_LOG_ERROR << ec;
         } else {
           nlohmann::json &data_json = *transaction;
+
           for (auto &object_path : objects) {
-            nlohmann::json &object_json = data_json[object_path.first.value];
+            CROW_LOG_DEBUG << "Reading object "
+                           << static_cast<const std::string&>(object_path.first);
+            nlohmann::json &object_json =
+                data_json[static_cast<const std::string&>(object_path.first)];
+            if (object_json.is_null()) {
+              object_json = nlohmann::json::object();
+            }
             for (const auto &interface : object_path.second) {
               for (const auto &property : interface.second) {
-                boost::apply_visitor(
-                    [&](auto &&val) { object_json[property.first] = val; },
+                nlohmann::json &property_json = object_json[property.first];
+                mapbox::util::apply_visitor(
+                    [&property_json](auto &&val) { property_json = val; },
                     property.second);
+
+                // dbus-rest represents booleans as 1 or 0, implement to match
+                // TODO(ed) see if dbus-rest should be changed
+                const bool *property_bool =
+                    property_json.get_ptr<const bool *>();
+                if (property_bool != nullptr) {
+                  property_json = *property_bool ? 1 : 0;
+                }
               }
             }
           }
@@ -97,9 +116,9 @@
           res.end();
         }
       },
-      {connection_name, object_name, "org.freedesktop.DBus.ObjectManager",
-       "GetManagedObjects"});
-}  // namespace openbmc_mapper
+      connection_name, object_name, "org.freedesktop.DBus.ObjectManager",
+      "GetManagedObjects");
+}
 
 using GetSubTreeType = std::vector<
     std::pair<std::string,
@@ -132,14 +151,14 @@
         auto transaction =
             std::make_shared<nlohmann::json>(nlohmann::json::object());
         for (const std::string &connection : connections) {
-          get_manged_objects_for_enumerate(object_path, connection, res,
-                                           transaction);
+          get_managed_objects_for_enumerate(object_path, connection, res,
+                                            transaction);
         }
 
       },
-      {"xyz.openbmc_project.ObjectMapper", "/xyz/openbmc_project/object_mapper",
-       "xyz.openbmc_project.ObjectMapper", "GetSubTree"},
-      object_path, (int32_t)0, std::array<std::string, 0>());
+      "xyz.openbmc_project.ObjectMapper", "/xyz/openbmc_project/object_mapper",
+      "xyz.openbmc_project.ObjectMapper", "GetSubTree", object_path, (int32_t)0,
+      std::array<std::string, 0>());
 }
 
 template <typename... Middlewares>
@@ -151,33 +170,32 @@
 
   CROW_ROUTE(app, "/bus/system/")
       .methods("GET"_method)([](const crow::request &req, crow::response &res) {
+
+        auto myCallback = [&res](const boost::system::error_code ec,
+                                 std::vector<std::string> &names) {
+          if (ec) {
+            res.code = 500;
+          } else {
+            std::sort(names.begin(), names.end());
+            nlohmann::json j{{"status", "ok"}};
+            auto &objects_sub = j["objects"];
+            for (auto &name : names) {
+              objects_sub.push_back({{"name", name}});
+            }
+            res.json_value = std::move(j);
+          }
+          res.end();
+        };
         crow::connections::system_bus->async_method_call(
-            [&](const boost::system::error_code ec,
-                std::vector<std::string> &names) {
-
-              if (ec) {
-                res.code = 500;
-              } else {
-                std::sort(names.begin(), names.end());
-                nlohmann::json j{{"status", "ok"}};
-                auto &objects_sub = j["objects"];
-                for (auto &name : names) {
-                  objects_sub.push_back({{"name", name}});
-                }
-                res.json_value = std::move(j);
-              }
-              res.end();
-            },
-            {"org.freedesktop.DBus", "/", "org.freedesktop.DBus", "ListNames"});
-
+            std::move(myCallback), "org.freedesktop.DBus", "/",
+            "org.freedesktop.DBus", "ListNames");
       });
 
   CROW_ROUTE(app, "/list/")
       .methods("GET"_method)([](const crow::request &req, crow::response &res) {
         crow::connections::system_bus->async_method_call(
-            [&](const boost::system::error_code ec,
-                const std::vector<std::string> &object_paths) {
-
+            [&res](const boost::system::error_code ec,
+                   const std::vector<std::string> &object_paths) {
               if (ec) {
                 res.code = 500;
               } else {
@@ -187,10 +205,10 @@
               }
               res.end();
             },
-            {"xyz.openbmc_project.ObjectMapper",
-             "/xyz/openbmc_project/object_mapper",
-             "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths"},
-            "", static_cast<int32_t>(99), std::array<std::string, 0>());
+            "xyz.openbmc_project.ObjectMapper",
+            "/xyz/openbmc_project/object_mapper",
+            "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "",
+            static_cast<int32_t>(99), std::array<std::string, 0>());
       });
 
   CROW_ROUTE(app, "/xyz/<path>")
@@ -242,9 +260,9 @@
 
         crow::connections::system_bus->async_method_call(
             [
-                  &, object_path{std::move(object_path)},
-                  dest_property{std::move(dest_property)},
-                  property_set_value{std::move(property_set_value)}, transaction
+              &res, &req, object_path{std::move(object_path)},
+              dest_property{std::move(dest_property)},
+              property_set_value{std::move(property_set_value)}, transaction
             ](const boost::system::error_code ec,
               const GetObjectType &object_names) {
               if (ec) {
@@ -260,17 +278,17 @@
               if (req.method == "GET"_method) {
                 for (auto &interface : object_names[0].second) {
                   crow::connections::system_bus->async_method_call(
-                      [&](const boost::system::error_code ec,
+                      [&res, transaction](
+                          const boost::system::error_code ec,
                           const std::vector<std::pair<
-                              std::string, dbus::dbus_variant>> &properties) {
+                              std::string, DbusRestVariantType>> &properties) {
                         if (ec) {
                           CROW_LOG_ERROR << "Bad dbus request error: " << ec;
                         } else {
                           for (auto &property : properties) {
-                            boost::apply_visitor(
-                                [&](auto val) {
-                                  (*transaction)[property.first] = val;
-                                },
+                            nlohmann::json &it = (*transaction)[property.first];
+                            mapbox::util::apply_visitor(
+                                [&it](auto &&val) { it = val; },
                                 property.second);
                           }
                         }
@@ -282,9 +300,8 @@
                           res.end();
                         }
                       },
-                      {object_names[0].first, object_path,
-                       "org.freedesktop.DBus.Properties", "GetAll"},
-                      interface);
+                      object_names[0].first, object_path,
+                      "org.freedesktop.DBus.Properties", "GetAll", interface);
                 }
               } else if (req.method == "PUT"_method) {
                 for (auto &interface : object_names[0].second) {
@@ -298,18 +315,19 @@
                             transaction
                       ](const boost::system::error_code ec,
                         const boost::container::flat_map<
-                            std::string, dbus::dbus_variant> &properties) {
+                            std::string, DbusRestVariantType> &properties) {
                         if (ec) {
                           CROW_LOG_ERROR << "Bad dbus request error: " << ec;
                         } else {
                           auto it = properties.find(dest_property);
                           if (it != properties.end()) {
                             // find the matched property in the interface
-                            dbus::dbus_variant property_value(
-                                property_set_value);  // create the dbus
-                                                      // variant for dbus call
+                            DbusRestVariantType property_value(
+                                property_set_value);
+                            // create the dbus variant for dbus call
                             crow::connections::system_bus->async_method_call(
-                                [&](const boost::system::error_code ec) {
+                                [transaction](
+                                    const boost::system::error_code ec) {
                                   // use the method "Set" to set the property
                                   // value
                                   if (ec) {
@@ -323,8 +341,8 @@
                                                   {"data", nullptr}};
 
                                 },
-                                {object_names[0].first, object_path,
-                                 "org.freedesktop.DBus.Properties", "Set"},
+                                object_names[0].first, object_path,
+                                "org.freedesktop.DBus.Properties", "Set",
                                 interface, dest_property, property_value);
                           }
                         }
@@ -350,16 +368,15 @@
                           return;
                         }
                       },
-                      {object_names[0].first, object_path,
-                       "org.freedesktop.DBus.Properties", "GetAll"},
-                      interface);
+                      object_names[0].first, object_path,
+                      "org.freedesktop.DBus.Properties", "GetAll", interface);
                 }
               }
             },
-            {"xyz.openbmc_project.ObjectMapper",
-             "/xyz/openbmc_project/object_mapper",
-             "xyz.openbmc_project.ObjectMapper", "GetObject"},
-            object_path, std::array<std::string, 0>());
+            "xyz.openbmc_project.ObjectMapper",
+            "/xyz/openbmc_project/object_mapper",
+            "xyz.openbmc_project.ObjectMapper", "GetObject", object_path,
+            std::array<std::string, 0>());
       });
 
   CROW_ROUTE(app, "/bus/system/<str>/")
@@ -413,9 +430,6 @@
           res.end();
           return;
         }
-        dbus::endpoint introspect_endpoint(
-            process_name, object_path, "org.freedesktop.DBus.Introspectable",
-            "Introspect");
         if (interface_name.empty()) {
           crow::connections::system_bus->async_method_call(
               [
@@ -459,7 +473,8 @@
                 }
                 res.end();
               },
-              introspect_endpoint);
+              process_name, object_path, "org.freedesktop.DBus.Introspectable",
+              "Introspect");
         } else {
           crow::connections::system_bus->async_method_call(
               [
@@ -566,10 +581,11 @@
                 }
                 res.end();
               },
-              introspect_endpoint);
+              process_name, object_path, "org.freedesktop.DBus.Introspectable",
+              "Introspect");
         }
 
       });
-}
+}  // namespace openbmc_mapper
 }  // namespace openbmc_mapper
 }  // namespace crow
diff --git a/include/redfish_v1.hpp b/include/redfish_v1.hpp
index c28208d..03b9051 100644
--- a/include/redfish_v1.hpp
+++ b/include/redfish_v1.hpp
@@ -1,10 +1,6 @@
 #pragma once
 
-#include <dbus/connection.hpp>
-#include <dbus/endpoint.hpp>
-#include <dbus/filter.hpp>
-#include <dbus/match.hpp>
-#include <dbus/message.hpp>
+#include <dbus_singleton.hpp>
 #include <persistent_data_middleware.hpp>
 #include <token_authorization_middleware.hpp>
 #include <fstream>
@@ -43,10 +39,13 @@
   return result;
 }
 
+// GetManagedObjects unpack type.  Observe that variant has only one bool type,
+// because we don't actually use the values it provides
 using ManagedObjectType = std::vector<std::pair<
-    dbus::object_path, boost::container::flat_map<
-                           std::string, boost::container::flat_map<
-                                            std::string, dbus::dbus_variant>>>>;
+    sdbusplus::message::object_path,
+    boost::container::flat_map<
+        std::string, boost::container::flat_map<
+                         std::string, sdbusplus::message::variant<bool>>>>>;
 
 template <typename... Middlewares>
 void request_routes(Crow<Middlewares...>& app) {
@@ -79,7 +78,8 @@
                 nlohmann::json member_array = nlohmann::json::array();
                 int user_index = 0;
                 for (auto& user : users) {
-                  const std::string& path = user.first.value;
+                  const std::string& path =
+                      static_cast<std::string>(user.first);
                   std::size_t last_index = path.rfind("/");
                   if (last_index == std::string::npos) {
                     last_index = 0;
@@ -94,8 +94,8 @@
               }
               res.end();
             },
-            {"xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
-             "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"});
+            "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
+            "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
       });
 
   CROW_ROUTE(app, "/redfish/v1/AccountService/Accounts/<str>/")
@@ -110,7 +110,8 @@
                 res.code = 500;
               } else {
                 for (auto& user : users) {
-                  const std::string& path = user.first.value;
+                  const std::string& path =
+                      static_cast<std::string>(user.first);
                   std::size_t last_index = path.rfind("/");
                   if (last_index == std::string::npos) {
                     last_index = 0;
@@ -145,8 +146,8 @@
               }
               res.end();
             },
-            {"xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
-             "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"});
+            "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
+            "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
       });
 }
 }  // namespace redfish
diff --git a/include/token_authorization_middleware.hpp b/include/token_authorization_middleware.hpp
index 59e9cca..07540d4 100644
--- a/include/token_authorization_middleware.hpp
+++ b/include/token_authorization_middleware.hpp
@@ -173,7 +173,8 @@
   bool is_on_whitelist(const crow::request& req) const {
     // it's allowed to GET root node without authentication
     if ("GET"_method == req.method) {
-      if (req.url == "/redfish/v1") {
+      CROW_LOG_DEBUG << "TESTING ROUTE " << req.url;
+      if (req.url == "/redfish/v1" || req.url == "/redfish/v1/") {
         return true;
       } else if (crow::webassets::routes.find(req.url) !=
                  crow::webassets::routes.end()) {
@@ -183,7 +184,8 @@
 
     // it's allowed to POST on session collection & login without authentication
     if ("POST"_method == req.method) {
-      if ((req.url == "/redfish/v1/SessionService/Sessions") ||
+      if ((req.url == "/redfish/v1/SessionService/Sessions" ||
+           req.url == "/redfish/v1/SessionService/Sessions/") ||
           (req.url == "/login") || (req.url == "/logout")) {
         return true;
       }
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
diff --git a/src/webserver_main.cpp b/src/webserver_main.cpp
index 16180ae..7531503 100644
--- a/src/webserver_main.cpp
+++ b/src/webserver_main.cpp
@@ -1,11 +1,13 @@
 #include <systemd/sd-daemon.h>
-#include <dbus/connection.hpp>
 #include <dbus_monitor.hpp>
 #include <dbus_singleton.hpp>
 #include <intel_oem.hpp>
 #include <openbmc_dbus_rest.hpp>
 #include <persistent_data_middleware.hpp>
 #include <redfish_v1.hpp>
+#include <sdbusplus/asio/connection.hpp>
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/server.hpp>
 #include <security_headers_middleware.hpp>
 #include <ssl_key_handler.hpp>
 #include <token_authorization_middleware.hpp>
@@ -73,12 +75,11 @@
   CROW_LOG_INFO << "bmcweb (" << __DATE__ << ": " << __TIME__ << ')';
   setup_socket(app);
 
-  // Start dbus connection
   crow::connections::system_bus =
-      std::make_shared<dbus::connection>(*io, dbus::bus::system);
-
+      std::make_shared<sdbusplus::asio::connection>(*io);
   redfish::RedfishService redfish(app);
 
   app.run();
   io->run();
+
 }