summaryrefslogtreecommitdiff
path: root/src/buildtool/serve_api/serve_service/target.hpp
blob: df42a87bdd06f2310a0ffc372dee2e93a88a6a6f (plain)
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// Copyright 2023 Huawei Cloud Computing Technology Co., Ltd.
//
// 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.

#ifndef INCLUDED_SRC_BUILD_SERVE_API_SERVE_SERVICE_TARGET_HPP
#define INCLUDED_SRC_BUILD_SERVE_API_SERVE_SERVICE_TARGET_HPP

#include <filesystem>
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <variant>
#include <vector>

#include "gsl/gsl"
#include "justbuild/just_serve/just_serve.grpc.pb.h"
#include "nlohmann/json.hpp"
#include "src/buildtool/common/artifact_digest.hpp"
#include "src/buildtool/common/remote/remote_common.hpp"
#include "src/buildtool/execution_api/common/create_execution_api.hpp"
#include "src/buildtool/execution_api/common/execution_api.hpp"
#include "src/buildtool/execution_api/remote/config.hpp"
#include "src/buildtool/logging/logger.hpp"

class TargetService final : public justbuild::just_serve::Target::Service {
  public:
    // Given a target-level caching key, returns the computed value. In doing
    // so, it can build on the associated end-point passing the
    // RemoteExecutionProperties contained in the ServeTargetRequest.
    //
    // If the status has a code different from `OK`, the response MUST not be
    // used.
    //
    // Errors:
    // * `FAILED_PRECONDITION`: Failed to find required information in the CAS
    //   or the target cache key is malformed.
    // * `UNAVAILABLE`: Could not communicate with the remote execution
    //   endpoint.
    // * `INTERNAL`: Internally, something is very broken.
    auto ServeTarget(
        ::grpc::ServerContext* /*context*/,
        const ::justbuild::just_serve::ServeTargetRequest* /*request*/,
        ::justbuild::just_serve::ServeTargetResponse* /*response*/)
        -> ::grpc::Status override;

    // Given the target-level root tree and the name of an export target,
    // returns the list of flexible variables from that target's description.
    //
    // If the status has a code different from `OK`, the response MUST not be
    // used.
    //
    // Errors:
    // * `FAILED_PRECONDITION`: An error occurred in retrieving the
    //   configuration of the requested target, such as missing entries
    //   (target-root, target file, target name), unparsable target file, or
    //   requested target not being of "type" : "export".
    // * `INTERNAL`: Internally, something is very broken.
    auto ServeTargetVariables(
        ::grpc::ServerContext* /*context*/,
        const ::justbuild::just_serve::ServeTargetVariablesRequest* request,
        ::justbuild::just_serve::ServeTargetVariablesResponse* response)
        -> ::grpc::Status override;

    // Given the target-level root tree and the name of an export target,
    // returns the digest of the blob containing the flexible variables field,
    // as well as the documentation fields pertaining tho the target and
    // its configuration variables, as taken from the target's description.
    // This information should be enough for a client to produce locally a
    // full description of said target.
    //
    // The server MUST make the returned blob available in the remote CAS.
    //
    // If the status has a code different from `OK`, the response MUST not be
    // used.
    //
    // Errors:
    // * `FAILED_PRECONDITION`: An error occurred in retrieving the
    //   configuration of the requested target, such as missing entries
    //   (target-root, target file, target name), unparsable target file, or
    //   requested target not being of "type" : "export".
    // * `UNAVAILABLE`: Could not communicate with the remote CAS.
    // * `INTERNAL`: Internally, something is very broken.
    auto ServeTargetDescription(
        ::grpc::ServerContext* /*context*/,
        const ::justbuild::just_serve::ServeTargetDescriptionRequest* request,
        ::justbuild::just_serve::ServeTargetDescriptionResponse* response)
        -> ::grpc::Status override;

  private:
    std::shared_ptr<Logger> logger_{std::make_shared<Logger>("target-service")};

    // type of dispatch list; reduces verbosity
    using dispatch_t = std::vector<
        std::pair<std::map<std::string, std::string>, ServerAddress>>;

    // remote execution endpoint used for remote building
    gsl::not_null<IExecutionApi::Ptr> const remote_api_{
        CreateExecutionApi(RemoteExecutionConfig::RemoteAddress(),
                           std::nullopt,
                           "serve-remote-execution")};
    // used for storing and retrieving target-level cache entries
    gsl::not_null<IExecutionApi::Ptr> const local_api_{
        CreateExecutionApi(std::nullopt)};

    /// \brief Get from remote and parse the endpoint configuration. The method
    /// also ensures the content has the expected format.
    /// \returns An error + data union, with a pair of grpc status at index 0
    /// and the dispatch list stored as a JSON object at index 1.
    auto GetDispatchList(ArtifactDigest const& dispatch_digest) noexcept
        -> std::variant<::grpc::Status, dispatch_t>;
};

#endif  // INCLUDED_SRC_BUILD_SERVE_API_SERVE_SERVICE_TARGET_HPP