diff --git a/meson.build b/meson.build
index fe6f113..af2c69c 100644
--- a/meson.build
+++ b/meson.build
@@ -346,6 +346,7 @@
     'redfish-core/src/filter_expr_printer.cpp',
     'redfish-core/src/redfish.cpp',
     'redfish-core/src/registries.cpp',
+    'redfish-core/src/subscription.cpp',
     'redfish-core/src/utils/dbus_utils.cpp',
     'redfish-core/src/utils/json_utils.cpp',
     'redfish-core/src/utils/time_utils.cpp',
diff --git a/redfish-core/include/event_logs_object_type.hpp b/redfish-core/include/event_logs_object_type.hpp
new file mode 100644
index 0000000..e97e551
--- /dev/null
+++ b/redfish-core/include/event_logs_object_type.hpp
@@ -0,0 +1,25 @@
+/*
+Copyright (c) 2020 Intel Corporation
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+      http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+#pragma once
+#include <string>
+#include <vector>
+namespace redfish
+{
+struct EventLogObjectsType
+{
+    std::string id;
+    std::string timestamp;
+    std::string messageId;
+    std::vector<std::string> messageArgs;
+};
+} // namespace redfish
diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp
index 41f1be9..e376980 100644
--- a/redfish-core/include/event_service_manager.hpp
+++ b/redfish-core/include/event_service_manager.hpp
@@ -18,18 +18,13 @@
 #include "error_messages.hpp"
 #include "event_matches_filter.hpp"
 #include "event_service_store.hpp"
-#include "filter_expr_executor.hpp"
-#include "generated/enums/event.hpp"
-#include "generated/enums/log_entry.hpp"
-#include "http_client.hpp"
 #include "metric_report.hpp"
 #include "ossl_random.hpp"
 #include "persistent_data.hpp"
 #include "registries.hpp"
 #include "registries_selector.hpp"
 #include "str_utility.hpp"
-#include "utility.hpp"
-#include "utils/json_utils.hpp"
+#include "subscription.hpp"
 #include "utils/time_utils.hpp"
 
 #include <sys/inotify.h>
@@ -47,7 +42,6 @@
 #include <format>
 #include <fstream>
 #include <memory>
-#include <ranges>
 #include <span>
 #include <string>
 #include <string_view>
@@ -59,13 +53,9 @@
 static constexpr const char* eventFormatType = "Event";
 static constexpr const char* metricReportFormatType = "MetricReport";
 
-static constexpr const char* subscriptionTypeSSE = "SSE";
 static constexpr const char* eventServiceFile =
     "/var/lib/bmcweb/eventservice_config.json";
 
-static constexpr const uint8_t maxNoOfSubscriptions = 20;
-static constexpr const uint8_t maxNoOfSSESubscriptions = 10;
-
 // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
 static std::optional<boost::asio::posix::stream_descriptor> inotifyConn;
 static constexpr const char* redfishEventLogDir = "/var/log";
@@ -78,13 +68,6 @@
 static int dirWatchDesc = -1;
 // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
 static int fileWatchDesc = -1;
-struct EventLogObjectsType
-{
-    std::string id;
-    std::string timestamp;
-    std::string messageId;
-    std::vector<std::string> messageArgs;
-};
 
 namespace registries
 {
@@ -253,267 +236,6 @@
 
 } // namespace event_log
 
-class Subscription : public std::enable_shared_from_this<Subscription>
-{
-  public:
-    Subscription(const Subscription&) = delete;
-    Subscription& operator=(const Subscription&) = delete;
-    Subscription(Subscription&&) = delete;
-    Subscription& operator=(Subscription&&) = delete;
-
-    Subscription(std::shared_ptr<persistent_data::UserSubscription> userSubIn,
-                 const boost::urls::url_view_base& url,
-                 boost::asio::io_context& ioc) :
-        userSub{std::move(userSubIn)},
-        policy(std::make_shared<crow::ConnectionPolicy>())
-    {
-        userSub->destinationUrl = url;
-        client.emplace(ioc, policy);
-        // Subscription constructor
-        policy->invalidResp = retryRespHandler;
-    }
-
-    explicit Subscription(crow::sse_socket::Connection& connIn) :
-        userSub{std::make_shared<persistent_data::UserSubscription>()},
-        sseConn(&connIn)
-    {}
-
-    ~Subscription() = default;
-
-    // callback for subscription sendData
-    void resHandler(const std::shared_ptr<Subscription>& /*unused*/,
-                    const crow::Response& res)
-    {
-        BMCWEB_LOG_DEBUG("Response handled with return code: {}",
-                         res.resultInt());
-
-        if (!client)
-        {
-            BMCWEB_LOG_ERROR(
-                "Http client wasn't filled but http client callback was called.");
-            return;
-        }
-
-        if (userSub->retryPolicy != "TerminateAfterRetries")
-        {
-            return;
-        }
-        if (client->isTerminated())
-        {
-            if (deleter)
-            {
-                BMCWEB_LOG_INFO(
-                    "Subscription {} is deleted after MaxRetryAttempts",
-                    userSub->id);
-                deleter();
-            }
-        }
-    }
-
-    bool sendEventToSubscriber(std::string&& msg)
-    {
-        persistent_data::EventServiceConfig eventServiceConfig =
-            persistent_data::EventServiceStore::getInstance()
-                .getEventServiceConfig();
-        if (!eventServiceConfig.enabled)
-        {
-            return false;
-        }
-
-        if (client)
-        {
-            client->sendDataWithCallback(
-                std::move(msg), userSub->destinationUrl,
-                static_cast<ensuressl::VerifyCertificate>(
-                    userSub->verifyCertificate),
-                userSub->httpHeaders, boost::beast::http::verb::post,
-                std::bind_front(&Subscription::resHandler, this,
-                                shared_from_this()));
-            return true;
-        }
-
-        if (sseConn != nullptr)
-        {
-            eventSeqNum++;
-            sseConn->sendSseEvent(std::to_string(eventSeqNum), msg);
-        }
-        return true;
-    }
-
-    bool sendTestEventLog()
-    {
-        nlohmann::json::array_t logEntryArray;
-        nlohmann::json& logEntryJson = logEntryArray.emplace_back();
-
-        logEntryJson["EventId"] = "TestID";
-        logEntryJson["Severity"] = log_entry::EventSeverity::OK;
-        logEntryJson["Message"] = "Generated test event";
-        logEntryJson["MessageId"] = "OpenBMC.0.2.TestEventLog";
-        // MemberId is 0 : since we are sending one event record.
-        logEntryJson["MemberId"] = "0";
-        logEntryJson["MessageArgs"] = nlohmann::json::array();
-        logEntryJson["EventTimestamp"] =
-            redfish::time_utils::getDateTimeOffsetNow().first;
-        logEntryJson["Context"] = userSub->customText;
-
-        nlohmann::json msg;
-        msg["@odata.type"] = "#Event.v1_4_0.Event";
-        msg["Id"] = std::to_string(eventSeqNum);
-        msg["Name"] = "Event Log";
-        msg["Events"] = logEntryArray;
-
-        std::string strMsg =
-            msg.dump(2, ' ', true, nlohmann::json::error_handler_t::replace);
-        return sendEventToSubscriber(std::move(strMsg));
-    }
-
-    void filterAndSendEventLogs(
-        const std::vector<EventLogObjectsType>& eventRecords)
-    {
-        nlohmann::json::array_t logEntryArray;
-        for (const EventLogObjectsType& logEntry : eventRecords)
-        {
-            std::vector<std::string_view> messageArgsView(
-                logEntry.messageArgs.begin(), logEntry.messageArgs.end());
-
-            nlohmann::json::object_t bmcLogEntry;
-            if (event_log::formatEventLogEntry(
-                    logEntry.id, logEntry.messageId, messageArgsView,
-                    logEntry.timestamp, userSub->customText, bmcLogEntry) != 0)
-            {
-                BMCWEB_LOG_DEBUG("Read eventLog entry failed");
-                continue;
-            }
-
-            if (!eventMatchesFilter(*userSub, bmcLogEntry, ""))
-            {
-                BMCWEB_LOG_DEBUG("Event {} did not match the filter",
-                                 nlohmann::json(bmcLogEntry).dump());
-                continue;
-            }
-
-            if (filter)
-            {
-                if (!memberMatches(bmcLogEntry, *filter))
-                {
-                    BMCWEB_LOG_DEBUG("Filter didn't match");
-                    continue;
-                }
-            }
-
-            logEntryArray.emplace_back(std::move(bmcLogEntry));
-        }
-
-        if (logEntryArray.empty())
-        {
-            BMCWEB_LOG_DEBUG("No log entries available to be transferred.");
-            return;
-        }
-
-        nlohmann::json msg;
-        msg["@odata.type"] = "#Event.v1_4_0.Event";
-        msg["Id"] = std::to_string(eventSeqNum);
-        msg["Name"] = "Event Log";
-        msg["Events"] = std::move(logEntryArray);
-        std::string strMsg =
-            msg.dump(2, ' ', true, nlohmann::json::error_handler_t::replace);
-        sendEventToSubscriber(std::move(strMsg));
-        eventSeqNum++;
-    }
-
-    void filterAndSendReports(const std::string& reportId,
-                              const telemetry::TimestampReadings& var)
-    {
-        boost::urls::url mrdUri = boost::urls::format(
-            "/redfish/v1/TelemetryService/MetricReportDefinitions/{}",
-            reportId);
-
-        // Empty list means no filter. Send everything.
-        if (!userSub->metricReportDefinitions.empty())
-        {
-            if (std::ranges::find(userSub->metricReportDefinitions,
-                                  mrdUri.buffer()) ==
-                userSub->metricReportDefinitions.end())
-            {
-                return;
-            }
-        }
-
-        nlohmann::json msg;
-        if (!telemetry::fillReport(msg, reportId, var))
-        {
-            BMCWEB_LOG_ERROR("Failed to fill the MetricReport for DBus "
-                             "Report with id {}",
-                             reportId);
-            return;
-        }
-
-        // Context is set by user during Event subscription and it must be
-        // set for MetricReport response.
-        if (!userSub->customText.empty())
-        {
-            msg["Context"] = userSub->customText;
-        }
-
-        std::string strMsg =
-            msg.dump(2, ' ', true, nlohmann::json::error_handler_t::replace);
-        sendEventToSubscriber(std::move(strMsg));
-    }
-
-    void updateRetryConfig(uint32_t retryAttempts,
-                           uint32_t retryTimeoutInterval)
-    {
-        if (policy == nullptr)
-        {
-            BMCWEB_LOG_DEBUG("Retry policy was nullptr, ignoring set");
-            return;
-        }
-        policy->maxRetryAttempts = retryAttempts;
-        policy->retryIntervalSecs = std::chrono::seconds(retryTimeoutInterval);
-    }
-
-    uint64_t getEventSeqNum() const
-    {
-        return eventSeqNum;
-    }
-
-    bool matchSseId(const crow::sse_socket::Connection& thisConn)
-    {
-        return &thisConn == sseConn;
-    }
-
-    // Check used to indicate what response codes are valid as part of our retry
-    // policy.  2XX is considered acceptable
-    static boost::system::error_code retryRespHandler(unsigned int respCode)
-    {
-        BMCWEB_LOG_DEBUG(
-            "Checking response code validity for SubscriptionEvent");
-        if ((respCode < 200) || (respCode >= 300))
-        {
-            return boost::system::errc::make_error_code(
-                boost::system::errc::result_out_of_range);
-        }
-
-        // Return 0 if the response code is valid
-        return boost::system::errc::make_error_code(
-            boost::system::errc::success);
-    }
-
-    std::shared_ptr<persistent_data::UserSubscription> userSub;
-    std::function<void()> deleter;
-
-  private:
-    uint64_t eventSeqNum = 1;
-    boost::urls::url host;
-    std::shared_ptr<crow::ConnectionPolicy> policy;
-    crow::sse_socket::Connection* sseConn = nullptr;
-
-    std::optional<crow::HttpClient> client;
-
-  public:
-    std::optional<filter_ast::LogicalAnd> filter;
-};
-
 class EventServiceManager
 {
   private:
diff --git a/redfish-core/include/subscription.hpp b/redfish-core/include/subscription.hpp
new file mode 100644
index 0000000..62f7826
--- /dev/null
+++ b/redfish-core/include/subscription.hpp
@@ -0,0 +1,93 @@
+/*
+Copyright (c) 2020 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+#pragma once
+#include "event_logs_object_type.hpp"
+#include "event_service_store.hpp"
+#include "filter_expr_parser_ast.hpp"
+#include "metric_report.hpp"
+#include "server_sent_event.hpp"
+
+#include <boost/asio/io_context.hpp>
+#include <boost/url/url_view_base.hpp>
+
+#include <memory>
+#include <string>
+
+namespace redfish
+{
+
+static constexpr const char* subscriptionTypeSSE = "SSE";
+
+static constexpr const uint8_t maxNoOfSubscriptions = 20;
+static constexpr const uint8_t maxNoOfSSESubscriptions = 10;
+
+class Subscription : public std::enable_shared_from_this<Subscription>
+{
+  public:
+    Subscription(const Subscription&) = delete;
+    Subscription& operator=(const Subscription&) = delete;
+    Subscription(Subscription&&) = delete;
+    Subscription& operator=(Subscription&&) = delete;
+
+    Subscription(std::shared_ptr<persistent_data::UserSubscription> userSubIn,
+                 const boost::urls::url_view_base& url,
+                 boost::asio::io_context& ioc);
+
+    explicit Subscription(crow::sse_socket::Connection& connIn);
+
+    ~Subscription() = default;
+
+    // callback for subscription sendData
+    void resHandler(const std::shared_ptr<Subscription>& /*unused*/,
+                    const crow::Response& res);
+
+    bool sendEventToSubscriber(std::string&& msg);
+
+    bool sendTestEventLog();
+
+    void filterAndSendEventLogs(
+        const std::vector<EventLogObjectsType>& eventRecords);
+
+    void filterAndSendReports(const std::string& reportId,
+                              const telemetry::TimestampReadings& var);
+
+    void updateRetryConfig(uint32_t retryAttempts,
+                           uint32_t retryTimeoutInterval);
+
+    uint64_t getEventSeqNum() const;
+
+    bool matchSseId(const crow::sse_socket::Connection& thisConn);
+
+    // Check used to indicate what response codes are valid as part of our retry
+    // policy.  2XX is considered acceptable
+    static boost::system::error_code retryRespHandler(unsigned int respCode);
+
+    std::shared_ptr<persistent_data::UserSubscription> userSub;
+    std::function<void()> deleter;
+
+  private:
+    uint64_t eventSeqNum = 1;
+    boost::urls::url host;
+    std::shared_ptr<crow::ConnectionPolicy> policy;
+    crow::sse_socket::Connection* sseConn = nullptr;
+
+    std::optional<crow::HttpClient> client;
+
+  public:
+    std::optional<filter_ast::LogicalAnd> filter;
+};
+
+} // namespace redfish
diff --git a/redfish-core/src/subscription.cpp b/redfish-core/src/subscription.cpp
new file mode 100644
index 0000000..f74435d
--- /dev/null
+++ b/redfish-core/src/subscription.cpp
@@ -0,0 +1,286 @@
+/*
+Copyright (c) 2020 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+#include "subscription.hpp"
+
+#include "event_logs_object_type.hpp"
+#include "event_matches_filter.hpp"
+#include "event_service_manager.hpp"
+#include "event_service_store.hpp"
+#include "filter_expr_executor.hpp"
+#include "generated/enums/log_entry.hpp"
+#include "http_client.hpp"
+#include "http_response.hpp"
+#include "logging.hpp"
+#include "metric_report.hpp"
+#include "server_sent_event.hpp"
+#include "ssl_key_handler.hpp"
+#include "utils/time_utils.hpp"
+
+#include <boost/asio/io_context.hpp>
+#include <boost/beast/http/verb.hpp>
+#include <boost/system/errc.hpp>
+#include <boost/url/format.hpp>
+#include <boost/url/url_view_base.hpp>
+#include <nlohmann/json.hpp>
+
+#include <algorithm>
+#include <cstdint>
+#include <cstdlib>
+#include <ctime>
+#include <format>
+#include <functional>
+#include <memory>
+#include <span>
+#include <string>
+#include <string_view>
+#include <utility>
+#include <vector>
+
+namespace redfish
+{
+
+Subscription::Subscription(
+    std::shared_ptr<persistent_data::UserSubscription> userSubIn,
+    const boost::urls::url_view_base& url, boost::asio::io_context& ioc) :
+    userSub{std::move(userSubIn)},
+    policy(std::make_shared<crow::ConnectionPolicy>())
+{
+    userSub->destinationUrl = url;
+    client.emplace(ioc, policy);
+    // Subscription constructor
+    policy->invalidResp = retryRespHandler;
+}
+
+Subscription::Subscription(crow::sse_socket::Connection& connIn) :
+    userSub{std::make_shared<persistent_data::UserSubscription>()},
+    sseConn(&connIn)
+{}
+
+// callback for subscription sendData
+void Subscription::resHandler(const std::shared_ptr<Subscription>& /*unused*/,
+                              const crow::Response& res)
+{
+    BMCWEB_LOG_DEBUG("Response handled with return code: {}", res.resultInt());
+
+    if (!client)
+    {
+        BMCWEB_LOG_ERROR(
+            "Http client wasn't filled but http client callback was called.");
+        return;
+    }
+
+    if (userSub->retryPolicy != "TerminateAfterRetries")
+    {
+        return;
+    }
+    if (client->isTerminated())
+    {
+        if (deleter)
+        {
+            BMCWEB_LOG_INFO("Subscription {} is deleted after MaxRetryAttempts",
+                            userSub->id);
+            deleter();
+        }
+    }
+}
+
+bool Subscription::sendEventToSubscriber(std::string&& msg)
+{
+    persistent_data::EventServiceConfig eventServiceConfig =
+        persistent_data::EventServiceStore::getInstance()
+            .getEventServiceConfig();
+    if (!eventServiceConfig.enabled)
+    {
+        return false;
+    }
+
+    if (client)
+    {
+        client->sendDataWithCallback(
+            std::move(msg), userSub->destinationUrl,
+            static_cast<ensuressl::VerifyCertificate>(
+                userSub->verifyCertificate),
+            userSub->httpHeaders, boost::beast::http::verb::post,
+            std::bind_front(&Subscription::resHandler, this,
+                            shared_from_this()));
+        return true;
+    }
+
+    if (sseConn != nullptr)
+    {
+        eventSeqNum++;
+        sseConn->sendSseEvent(std::to_string(eventSeqNum), msg);
+    }
+    return true;
+}
+
+bool Subscription::sendTestEventLog()
+{
+    nlohmann::json::array_t logEntryArray;
+    nlohmann::json& logEntryJson = logEntryArray.emplace_back();
+
+    logEntryJson["EventId"] = "TestID";
+    logEntryJson["Severity"] = log_entry::EventSeverity::OK;
+    logEntryJson["Message"] = "Generated test event";
+    logEntryJson["MessageId"] = "OpenBMC.0.2.TestEventLog";
+    // MemberId is 0 : since we are sending one event record.
+    logEntryJson["MemberId"] = "0";
+    logEntryJson["MessageArgs"] = nlohmann::json::array();
+    logEntryJson["EventTimestamp"] =
+        redfish::time_utils::getDateTimeOffsetNow().first;
+    logEntryJson["Context"] = userSub->customText;
+
+    nlohmann::json msg;
+    msg["@odata.type"] = "#Event.v1_4_0.Event";
+    msg["Id"] = std::to_string(eventSeqNum);
+    msg["Name"] = "Event Log";
+    msg["Events"] = logEntryArray;
+
+    std::string strMsg =
+        msg.dump(2, ' ', true, nlohmann::json::error_handler_t::replace);
+    return sendEventToSubscriber(std::move(strMsg));
+}
+
+void Subscription::filterAndSendEventLogs(
+    const std::vector<EventLogObjectsType>& eventRecords)
+{
+    nlohmann::json::array_t logEntryArray;
+    for (const EventLogObjectsType& logEntry : eventRecords)
+    {
+        std::vector<std::string_view> messageArgsView(
+            logEntry.messageArgs.begin(), logEntry.messageArgs.end());
+
+        nlohmann::json::object_t bmcLogEntry;
+        if (event_log::formatEventLogEntry(
+                logEntry.id, logEntry.messageId, messageArgsView,
+                logEntry.timestamp, userSub->customText, bmcLogEntry) != 0)
+        {
+            BMCWEB_LOG_DEBUG("Read eventLog entry failed");
+            continue;
+        }
+
+        if (!eventMatchesFilter(*userSub, bmcLogEntry, ""))
+        {
+            BMCWEB_LOG_DEBUG("Event {} did not match the filter",
+                             nlohmann::json(bmcLogEntry).dump());
+            continue;
+        }
+
+        if (filter)
+        {
+            if (!memberMatches(bmcLogEntry, *filter))
+            {
+                BMCWEB_LOG_DEBUG("Filter didn't match");
+                continue;
+            }
+        }
+
+        logEntryArray.emplace_back(std::move(bmcLogEntry));
+    }
+
+    if (logEntryArray.empty())
+    {
+        BMCWEB_LOG_DEBUG("No log entries available to be transferred.");
+        return;
+    }
+
+    nlohmann::json msg;
+    msg["@odata.type"] = "#Event.v1_4_0.Event";
+    msg["Id"] = std::to_string(eventSeqNum);
+    msg["Name"] = "Event Log";
+    msg["Events"] = std::move(logEntryArray);
+    std::string strMsg =
+        msg.dump(2, ' ', true, nlohmann::json::error_handler_t::replace);
+    sendEventToSubscriber(std::move(strMsg));
+    eventSeqNum++;
+}
+
+void Subscription::filterAndSendReports(const std::string& reportId,
+                                        const telemetry::TimestampReadings& var)
+{
+    boost::urls::url mrdUri = boost::urls::format(
+        "/redfish/v1/TelemetryService/MetricReportDefinitions/{}", reportId);
+
+    // Empty list means no filter. Send everything.
+    if (!userSub->metricReportDefinitions.empty())
+    {
+        if (std::ranges::find(userSub->metricReportDefinitions,
+                              mrdUri.buffer()) ==
+            userSub->metricReportDefinitions.end())
+        {
+            return;
+        }
+    }
+
+    nlohmann::json msg;
+    if (!telemetry::fillReport(msg, reportId, var))
+    {
+        BMCWEB_LOG_ERROR("Failed to fill the MetricReport for DBus "
+                         "Report with id {}",
+                         reportId);
+        return;
+    }
+
+    // Context is set by user during Event subscription and it must be
+    // set for MetricReport response.
+    if (!userSub->customText.empty())
+    {
+        msg["Context"] = userSub->customText;
+    }
+
+    std::string strMsg =
+        msg.dump(2, ' ', true, nlohmann::json::error_handler_t::replace);
+    sendEventToSubscriber(std::move(strMsg));
+}
+
+void Subscription::updateRetryConfig(uint32_t retryAttempts,
+                                     uint32_t retryTimeoutInterval)
+{
+    if (policy == nullptr)
+    {
+        BMCWEB_LOG_DEBUG("Retry policy was nullptr, ignoring set");
+        return;
+    }
+    policy->maxRetryAttempts = retryAttempts;
+    policy->retryIntervalSecs = std::chrono::seconds(retryTimeoutInterval);
+}
+
+uint64_t Subscription::getEventSeqNum() const
+{
+    return eventSeqNum;
+}
+
+bool Subscription::matchSseId(const crow::sse_socket::Connection& thisConn)
+{
+    return &thisConn == sseConn;
+}
+
+// Check used to indicate what response codes are valid as part of our retry
+// policy.  2XX is considered acceptable
+boost::system::error_code Subscription::retryRespHandler(unsigned int respCode)
+{
+    BMCWEB_LOG_DEBUG("Checking response code validity for SubscriptionEvent");
+    if ((respCode < 200) || (respCode >= 300))
+    {
+        return boost::system::errc::make_error_code(
+            boost::system::errc::result_out_of_range);
+    }
+
+    // Return 0 if the response code is valid
+    return boost::system::errc::make_error_code(boost::system::errc::success);
+}
+
+} // namespace redfish
