Remove NTPServers duplicate values and null values
When saving the set NTPServers values from webUI, NTPServer may contain
duplicate values and null values and update them to D-Bus.
Now, need to parse and verify the value of the ntpServers attribute,and
remove duplicate values and null values.
Tested:save NTP and check it via D-Bus
without this patch:
NTPServers property as 3 "" "10.164.29.2" "10.164.29.2"
with this patch:
NTPServers property as 2 "" "10.164.29.2"
Signed-off-by: George Liu <liuxiwei@inspur.com>
Change-Id: I52291e4608efd635b179f3934c3d3e805afd2209
diff --git a/meson.build b/meson.build
index 7673112..863cad1 100644
--- a/meson.build
+++ b/meson.build
@@ -359,6 +359,7 @@
'redfish-core/ut/lock_test.cpp',
'redfish-core/ut/configfile_test.cpp',
'redfish-core/ut/time_utils_test.cpp',
+ 'redfish-core/ut/stl_utils_test.cpp',
'redfish-core/ut/hex_utils_test.cpp',
'http/ut/utility_test.cpp'
]
diff --git a/redfish-core/include/utils/stl_utils.hpp b/redfish-core/include/utils/stl_utils.hpp
new file mode 100644
index 0000000..04d02cb
--- /dev/null
+++ b/redfish-core/include/utils/stl_utils.hpp
@@ -0,0 +1,39 @@
+#pragma once
+
+#include <algorithm>
+#include <string>
+
+namespace redfish
+{
+
+namespace stl_utils
+{
+
+template <typename ForwardIterator>
+ForwardIterator firstDuplicate(ForwardIterator first, ForwardIterator last)
+{
+ auto newLast = first;
+
+ for (auto current = first; current != last; ++current)
+ {
+ if (std::find(first, newLast, *current) == newLast)
+ {
+ if (newLast != current)
+ {
+ *newLast = *current;
+ }
+ ++newLast;
+ }
+ }
+
+ return newLast;
+}
+
+template <typename T>
+void removeDuplicate(T& t)
+{
+ t.erase(firstDuplicate(t.begin(), t.end()), t.end());
+}
+
+} // namespace stl_utils
+} // namespace redfish
diff --git a/redfish-core/lib/network_protocol.hpp b/redfish-core/lib/network_protocol.hpp
index a06611f..0d93102 100644
--- a/redfish-core/lib/network_protocol.hpp
+++ b/redfish-core/lib/network_protocol.hpp
@@ -22,6 +22,7 @@
#include <app.hpp>
#include <registries/privilege_registry.hpp>
#include <utils/json_utils.hpp>
+#include <utils/stl_utils.hpp>
#include <optional>
#include <variant>
@@ -237,9 +238,19 @@
}
inline void
- handleNTPServersPatch(const std::vector<std::string>& ntpServers,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+ handleNTPServersPatch(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ std::vector<std::string>& ntpServers)
{
+ auto iter = stl_utils::firstDuplicate(ntpServers.begin(), ntpServers.end());
+ if (iter != ntpServers.end())
+ {
+ std::string pointer =
+ "NTPServers/" +
+ std::to_string(std::distance(ntpServers.begin(), iter));
+ messages::propertyValueIncorrect(asyncResp->res, pointer, *iter);
+ return;
+ }
+
crow::connections::systemBus->async_method_call(
[asyncResp](const boost::system::error_code ec) {
if (ec)
@@ -393,12 +404,8 @@
if (ntpServers)
{
- std::sort((*ntpServers).begin(), (*ntpServers).end());
- (*ntpServers)
- .erase(std::unique((*ntpServers).begin(),
- (*ntpServers).end()),
- (*ntpServers).end());
- handleNTPServersPatch(*ntpServers, asyncResp);
+ stl_utils::removeDuplicate(*ntpServers);
+ handleNTPServersPatch(asyncResp, *ntpServers);
}
}
diff --git a/redfish-core/ut/stl_utils_test.cpp b/redfish-core/ut/stl_utils_test.cpp
new file mode 100644
index 0000000..a5115bd
--- /dev/null
+++ b/redfish-core/ut/stl_utils_test.cpp
@@ -0,0 +1,21 @@
+#include "utils/stl_utils.hpp"
+
+#include <gmock/gmock.h>
+
+TEST(STLUtilesTest, RemoveDuplicates)
+{
+ std::vector<std::string> strVec = {"s1", "s4", "s1", "s2", "", "s3", "s3"};
+
+ auto iter =
+ redfish::stl_utils::firstDuplicate(strVec.begin(), strVec.end());
+ EXPECT_EQ(*iter, "s3");
+
+ redfish::stl_utils::removeDuplicate(strVec);
+
+ EXPECT_EQ(strVec.size(), 5);
+ EXPECT_EQ(strVec[0], "s1");
+ EXPECT_EQ(strVec[1], "s4");
+ EXPECT_EQ(strVec[2], "s2");
+ EXPECT_EQ(strVec[3], "");
+ EXPECT_EQ(strVec[4], "s3");
+}