• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (C) 2019 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 
16 #pragma once
17 
18 #include <chrono>
19 #include <functional>
20 #include <memory>
21 #include <ostream>
22 #include <string>
23 #include <tuple>
24 #include <utility>
25 #include <variant>
26 #include <vector>
27 
28 #include "common/libs/utils/result.h"
29 #include "host/libs/web/credential_source.h"
30 #include "host/libs/web/http_client/http_client.h"
31 
32 namespace cuttlefish {
33 
34 class Artifact {
35  public:
36   Artifact(const Json::Value&);
Artifact(std::string name)37   Artifact(std::string name) : name_(std::move(name)) {}
38 
Name()39   const std::string& Name() const { return name_; }
Size()40   size_t Size() const { return size_; }
LastModifiedTime()41   unsigned long LastModifiedTime() const { return last_modified_time_; }
Md5()42   const std::string& Md5() const { return md5_; }
ContentType()43   const std::string& ContentType() const { return content_type_; }
Revision()44   const std::string& Revision() const { return revision_; }
CreationTime()45   unsigned long CreationTime() const { return creation_time_; }
Crc32()46   unsigned int Crc32() const { return crc32_; }
47 
48  private:
49   std::string name_;
50   size_t size_;
51   unsigned long last_modified_time_;
52   std::string md5_;
53   std::string content_type_;
54   std::string revision_;
55   unsigned long creation_time_;
56   unsigned int crc32_;
57 };
58 
59 struct DeviceBuild {
DeviceBuildDeviceBuild60   DeviceBuild(std::string id, std::string target)
61       : id(std::move(id)), target(std::move(target)) {}
62 
63   std::string id;
64   std::string target;
65   std::string product;
66 };
67 
68 std::ostream& operator<<(std::ostream&, const DeviceBuild&);
69 
70 struct DirectoryBuild {
71   // TODO(schuffelen): Support local builds other than "eng"
72   DirectoryBuild(std::vector<std::string> paths, std::string target);
73 
74   std::vector<std::string> paths;
75   std::string target;
76   std::string id;
77   std::string product;
78 };
79 
80 std::ostream& operator<<(std::ostream&, const DirectoryBuild&);
81 
82 using Build = std::variant<DeviceBuild, DirectoryBuild>;
83 
84 std::ostream& operator<<(std::ostream&, const Build&);
85 
86 class BuildApi {
87  public:
88   BuildApi();
89   BuildApi(std::unique_ptr<HttpClient>, std::unique_ptr<CredentialSource>);
90   BuildApi(std::unique_ptr<HttpClient>, std::unique_ptr<HttpClient>,
91            std::unique_ptr<CredentialSource>, std::string api_key,
92            const std::chrono::seconds retry_period);
93   ~BuildApi() = default;
94 
95   Result<std::string> LatestBuildId(const std::string& branch,
96                                     const std::string& target);
97 
98   // download the artifact from the build and apply the callback
99   Result<void> ArtifactToCallback(const DeviceBuild& build,
100                                   const std::string& artifact,
101                                   HttpClient::DataCallback callback);
102 
103   // determine the format of the build source argument and parse for the
104   // relevant build identifiers
105   Result<Build> ArgumentToBuild(const std::string& arg,
106                                 const std::string& default_build_target);
107 
108   Result<std::string> DownloadFile(const Build& build,
109                                    const std::string& target_directory,
110                                    const std::string& artifact_name);
111 
112   Result<std::string> DownloadFileWithBackup(
113       const Build& build, const std::string& target_directory,
114       const std::string& artifact_name,
115       const std::string& backup_artifact_name);
116 
117  private:
118   Result<std::vector<std::string>> Headers();
119 
120   Result<std::string> BuildStatus(const DeviceBuild&);
121 
122   Result<std::string> ProductName(const DeviceBuild&);
123 
124   Result<std::vector<Artifact>> Artifacts(
125       const DeviceBuild& build,
126       const std::vector<std::string>& artifact_filenames);
127 
128   Result<std::vector<Artifact>> Artifacts(
129       const DirectoryBuild& build,
130       const std::vector<std::string>& artifact_filenames);
131 
Artifacts(const Build & build,const std::vector<std::string> & artifact_filenames)132   Result<std::vector<Artifact>> Artifacts(
133       const Build& build, const std::vector<std::string>& artifact_filenames) {
134     auto res = std::visit(
135         [this, &artifact_filenames](auto&& arg) {
136           return Artifacts(arg, artifact_filenames);
137         },
138         build);
139     return CF_EXPECT(std::move(res));
140   }
141 
142   Result<void> ArtifactToFile(const DeviceBuild& build,
143                               const std::string& artifact,
144                               const std::string& path);
145 
146   Result<void> ArtifactToFile(const DirectoryBuild& build,
147                               const std::string& artifact,
148                               const std::string& path);
149 
ArtifactToFile(const Build & build,const std::string & artifact,const std::string & path)150   Result<void> ArtifactToFile(const Build& build, const std::string& artifact,
151                               const std::string& path) {
152     auto res = std::visit(
153         [this, &artifact, &path](auto&& arg) {
154           return ArtifactToFile(arg, artifact, path);
155         },
156         build);
157     CF_EXPECT(std::move(res));
158     return {};
159   }
160 
161   Result<std::string> DownloadTargetFile(const Build& build,
162                                          const std::string& target_directory,
163                                          const std::string& artifact_name);
164 
165   std::unique_ptr<HttpClient> http_client;
166   std::unique_ptr<HttpClient> inner_http_client;
167   std::unique_ptr<CredentialSource> credential_source;
168   std::string api_key_;
169   std::chrono::seconds retry_period_;
170 };
171 
172 std::string GetBuildZipName(const Build& build, const std::string& name);
173 
174 }  // namespace cuttlefish
175