~aleteoryx/muditaos

ref: a0677af340a1fec8e8652b64fb97ca7f0902de12 muditaos/module-services/service-desktop/endpoints/restore/RestoreHelper.cpp -rw-r--r-- 4.1 KiB
a0677af3 — Marek Niepieklo [CP-615] Update existing backup/restore implementation in OS 4 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <endpoints/Context.hpp>
#include <endpoints/restore/RestoreHelper.hpp>
#include <endpoints/JsonKeyNames.hpp>
#include <endpoints/message/Sender.hpp>
#include <service-desktop/DesktopMessages.hpp>
#include <service-desktop/ServiceDesktop.hpp>
#include <json11.hpp>
#include <purefs/filesystem_paths.hpp>

#include <filesystem>

namespace sdesktop::endpoints
{
    using sender::putToSendQueue;

    auto RestoreHelper::processGet(Context &context) -> ProcessResult
    {
        return checkState(context);
    }

    auto RestoreHelper::processPost(Context &context) -> ProcessResult
    {
        return executeRequest(context);
    }

    auto RestoreHelper::checkState(Context &context) -> ProcessResult
    {
        auto ownerService = static_cast<ServiceDesktop *>(owner);

        if (context.getBody()[json::taskId].is_string()) {
            if (ownerService->getBackupRestoreStatus().taskId == context.getBody()[json::taskId].string_value()) {
                context.setResponseStatus(http::Code::OK);
                context.setResponseBody(ownerService->getBackupRestoreStatus());
            }
            else {
                return {sent::no, ResponseContext{.status = http::Code::NotFound}};
            }
        }
        else if (context.getBody()[json::request].is_string()) {
            const std::string request(context.getBody()[json::request].string_value());

            if (request.compare(json::fileList)) {

                return {sent::no, ResponseContext{.status = http::Code::BadRequest}};
            }
            auto filesList = json11::Json::object{{json::files, BackupRestore::GetBackupFiles()}};
            context.setResponseBody(filesList);
        }

        LOG_DEBUG("Responding");
        putToSendQueue(context.createSimpleResponse());

        return {sent::yes, std::nullopt};
    }

    auto RestoreHelper::executeRequest(Context &context) -> ProcessResult
    {
        auto ownerService = static_cast<ServiceDesktop *>(owner);

        if (context.getBody()[json::restore].is_string()) {
            if (ownerService->getBackupRestoreStatus().state == BackupRestore::OperationState::Running) {
                LOG_WARN("Restore is running, try again later");

                return {sent::no, ResponseContext{.status = http::Code::NotAcceptable}};
            }
            else {
                const std::filesystem::path restorePoint(context.getBody()[json::restore].string_value());
                if (restorePoint.empty()) {
                    LOG_ERROR("no restorePoint in request");
                    context.setResponseBody(json11::Json::object({{json::reason, "No restore point passed"}}));

                    return {sent::no, ResponseContext{.status = http::Code::NotAcceptable}};
                }
                if (!std::filesystem::exists(purefs::dir::getBackupOSPath() / restorePoint)) {
                    LOG_ERROR("Restore point %s does not exist", (restorePoint).c_str());
                    context.setResponseBody(json11::Json::object({{json::reason, "Invalid restore point"}}));

                    return {sent::no, ResponseContext{.status = http::Code::NotFound}};
                }
                // initialize new restore information
                ownerService->prepareRestoreData(restorePoint);

                // start the request process
                ownerService->bus.sendUnicast(std::make_shared<sdesktop::RestoreMessage>(),
                                              service::name::service_desktop);

                // return new generated restore info
                context.setResponseBody(ownerService->getBackupRestoreStatus());
            }
        }
        else {
            // unknown request for backup endpoint

            return {sent::no, ResponseContext{.status = http::Code::BadRequest}};
        }

        LOG_DEBUG("Responding");
        putToSendQueue(context.createSimpleResponse());

        return {sent::yes, std::nullopt};
    }

} // namespace sdesktop::endpoints