root / trunk / Pithos.Network / CloudFilesClient.cs @ c945b450
History | View | Annotate | Download (61.1 kB)
1 | 255f5f86 | Panagiotis Kanavos | #region |
---|---|---|---|
2 | 255f5f86 | Panagiotis Kanavos | /* ----------------------------------------------------------------------- |
3 | 255f5f86 | Panagiotis Kanavos | * <copyright file="CloudFilesClient.cs" company="GRNet"> |
4 | 255f5f86 | Panagiotis Kanavos | * |
5 | 255f5f86 | Panagiotis Kanavos | * Copyright 2011-2012 GRNET S.A. All rights reserved. |
6 | 255f5f86 | Panagiotis Kanavos | * |
7 | 255f5f86 | Panagiotis Kanavos | * Redistribution and use in source and binary forms, with or |
8 | 255f5f86 | Panagiotis Kanavos | * without modification, are permitted provided that the following |
9 | 255f5f86 | Panagiotis Kanavos | * conditions are met: |
10 | 255f5f86 | Panagiotis Kanavos | * |
11 | 255f5f86 | Panagiotis Kanavos | * 1. Redistributions of source code must retain the above |
12 | 255f5f86 | Panagiotis Kanavos | * copyright notice, this list of conditions and the following |
13 | 255f5f86 | Panagiotis Kanavos | * disclaimer. |
14 | 255f5f86 | Panagiotis Kanavos | * |
15 | 255f5f86 | Panagiotis Kanavos | * 2. Redistributions in binary form must reproduce the above |
16 | 255f5f86 | Panagiotis Kanavos | * copyright notice, this list of conditions and the following |
17 | 255f5f86 | Panagiotis Kanavos | * disclaimer in the documentation and/or other materials |
18 | 255f5f86 | Panagiotis Kanavos | * provided with the distribution. |
19 | 255f5f86 | Panagiotis Kanavos | * |
20 | 255f5f86 | Panagiotis Kanavos | * |
21 | 255f5f86 | Panagiotis Kanavos | * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS |
22 | 255f5f86 | Panagiotis Kanavos | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
23 | 255f5f86 | Panagiotis Kanavos | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
24 | 255f5f86 | Panagiotis Kanavos | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR |
25 | 255f5f86 | Panagiotis Kanavos | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
26 | 255f5f86 | Panagiotis Kanavos | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
27 | 255f5f86 | Panagiotis Kanavos | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
28 | 255f5f86 | Panagiotis Kanavos | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
29 | 255f5f86 | Panagiotis Kanavos | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
30 | 255f5f86 | Panagiotis Kanavos | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
31 | 255f5f86 | Panagiotis Kanavos | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
32 | 255f5f86 | Panagiotis Kanavos | * POSSIBILITY OF SUCH DAMAGE. |
33 | 255f5f86 | Panagiotis Kanavos | * |
34 | 255f5f86 | Panagiotis Kanavos | * The views and conclusions contained in the software and |
35 | 255f5f86 | Panagiotis Kanavos | * documentation are those of the authors and should not be |
36 | 255f5f86 | Panagiotis Kanavos | * interpreted as representing official policies, either expressed |
37 | 255f5f86 | Panagiotis Kanavos | * or implied, of GRNET S.A. |
38 | 255f5f86 | Panagiotis Kanavos | * </copyright> |
39 | 255f5f86 | Panagiotis Kanavos | * ----------------------------------------------------------------------- |
40 | 255f5f86 | Panagiotis Kanavos | */ |
41 | 255f5f86 | Panagiotis Kanavos | #endregion |
42 | f3d080df | Panagiotis Kanavos | |
43 | f3d080df | Panagiotis Kanavos | // **CloudFilesClient** provides a simple client interface to CloudFiles and Pithos |
44 | 5ce54458 | Panagiotis Kanavos | // |
45 | 5ce54458 | Panagiotis Kanavos | // The class provides methods to upload/download files, delete files, manage containers |
46 | 5ce54458 | Panagiotis Kanavos | |
47 | 5ce54458 | Panagiotis Kanavos | |
48 | 5ce54458 | Panagiotis Kanavos | using System; |
49 | d78cbf09 | Panagiotis Kanavos | using System.Collections.Generic; |
50 | aba9e6d9 | Panagiotis Kanavos | using System.Collections.Specialized; |
51 | d78cbf09 | Panagiotis Kanavos | using System.ComponentModel.Composition; |
52 | 692ec33b | Panagiotis Kanavos | using System.Diagnostics; |
53 | d78cbf09 | Panagiotis Kanavos | using System.Diagnostics.Contracts; |
54 | d78cbf09 | Panagiotis Kanavos | using System.IO; |
55 | d78cbf09 | Panagiotis Kanavos | using System.Linq; |
56 | d78cbf09 | Panagiotis Kanavos | using System.Net; |
57 | db8a9589 | Panagiotis Kanavos | using System.Reflection; |
58 | d78cbf09 | Panagiotis Kanavos | using System.Security.Cryptography; |
59 | d78cbf09 | Panagiotis Kanavos | using System.Text; |
60 | 2341c603 | pkanavos | using System.Threading; |
61 | b5061ac8 | Panagiotis Kanavos | using System.Threading.Tasks; |
62 | d78cbf09 | Panagiotis Kanavos | using Newtonsoft.Json; |
63 | d78cbf09 | Panagiotis Kanavos | using Pithos.Interfaces; |
64 | 5120f3cb | Panagiotis Kanavos | using log4net; |
65 | d78cbf09 | Panagiotis Kanavos | |
66 | d78cbf09 | Panagiotis Kanavos | namespace Pithos.Network |
67 | d78cbf09 | Panagiotis Kanavos | { |
68 | d78cbf09 | Panagiotis Kanavos | [Export(typeof(ICloudClient))] |
69 | d78cbf09 | Panagiotis Kanavos | public class CloudFilesClient:ICloudClient |
70 | d78cbf09 | Panagiotis Kanavos | { |
71 | db8a9589 | Panagiotis Kanavos | private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
72 | db8a9589 | Panagiotis Kanavos | |
73 | 5ce54458 | Panagiotis Kanavos | //CloudFilesClient uses *_baseClient* internally to communicate with the server |
74 | 5ce54458 | Panagiotis Kanavos | //RestClient provides a REST-friendly interface over the standard WebClient. |
75 | 9c4346c9 | Panagiotis Kanavos | private RestClient _baseClient; |
76 | 5ce54458 | Panagiotis Kanavos | |
77 | c53aa229 | Panagiotis Kanavos | |
78 | 5ce54458 | Panagiotis Kanavos | //During authentication the client provides a UserName |
79 | d78cbf09 | Panagiotis Kanavos | public string UserName { get; set; } |
80 | 5ce54458 | Panagiotis Kanavos | |
81 | 5ce54458 | Panagiotis Kanavos | //and and ApiKey to the server |
82 | 5ce54458 | Panagiotis Kanavos | public string ApiKey { get; set; } |
83 | 5ce54458 | Panagiotis Kanavos | |
84 | 5ce54458 | Panagiotis Kanavos | //And receives an authentication Token. This token must be provided in ALL other operations, |
85 | 5ce54458 | Panagiotis Kanavos | //in the X-Auth-Token header |
86 | c53aa229 | Panagiotis Kanavos | private string _token; |
87 | c53aa229 | Panagiotis Kanavos | public string Token |
88 | c53aa229 | Panagiotis Kanavos | { |
89 | c53aa229 | Panagiotis Kanavos | get { return _token; } |
90 | c53aa229 | Panagiotis Kanavos | set |
91 | c53aa229 | Panagiotis Kanavos | { |
92 | c53aa229 | Panagiotis Kanavos | _token = value; |
93 | c53aa229 | Panagiotis Kanavos | _baseClient.Headers["X-Auth-Token"] = value; |
94 | c53aa229 | Panagiotis Kanavos | } |
95 | c53aa229 | Panagiotis Kanavos | } |
96 | c53aa229 | Panagiotis Kanavos | |
97 | 5ce54458 | Panagiotis Kanavos | //The client also receives a StorageUrl after authentication. All subsequent operations must |
98 | 5ce54458 | Panagiotis Kanavos | //use this url |
99 | 5ce54458 | Panagiotis Kanavos | public Uri StorageUrl { get; set; } |
100 | cfed7823 | Panagiotis Kanavos | |
101 | c53aa229 | Panagiotis Kanavos | |
102 | 496595a5 | pkanavos | public Uri RootAddressUri { get; set; } |
103 | cfed7823 | Panagiotis Kanavos | |
104 | 34bdb91d | Panagiotis Kanavos | /* private WebProxy _proxy; |
105 | 65282d58 | Panagiotis Kanavos | public WebProxy Proxy |
106 | 65282d58 | Panagiotis Kanavos | { |
107 | 65282d58 | Panagiotis Kanavos | get { return _proxy; } |
108 | 65282d58 | Panagiotis Kanavos | set |
109 | 65282d58 | Panagiotis Kanavos | { |
110 | 65282d58 | Panagiotis Kanavos | _proxy = value; |
111 | 65282d58 | Panagiotis Kanavos | if (_baseClient != null) |
112 | 65282d58 | Panagiotis Kanavos | _baseClient.Proxy = value; |
113 | 65282d58 | Panagiotis Kanavos | } |
114 | 65282d58 | Panagiotis Kanavos | } |
115 | 34bdb91d | Panagiotis Kanavos | */ |
116 | 65282d58 | Panagiotis Kanavos | |
117 | 65282d58 | Panagiotis Kanavos | /* private Uri _proxy; |
118 | c53aa229 | Panagiotis Kanavos | public Uri Proxy |
119 | c53aa229 | Panagiotis Kanavos | { |
120 | c53aa229 | Panagiotis Kanavos | get { return _proxy; } |
121 | c53aa229 | Panagiotis Kanavos | set |
122 | c53aa229 | Panagiotis Kanavos | { |
123 | c53aa229 | Panagiotis Kanavos | _proxy = value; |
124 | c53aa229 | Panagiotis Kanavos | if (_baseClient != null) |
125 | c53aa229 | Panagiotis Kanavos | _baseClient.Proxy = new WebProxy(value); |
126 | c53aa229 | Panagiotis Kanavos | } |
127 | 65282d58 | Panagiotis Kanavos | }*/ |
128 | b5061ac8 | Panagiotis Kanavos | |
129 | b5061ac8 | Panagiotis Kanavos | public double DownloadPercentLimit { get; set; } |
130 | b5061ac8 | Panagiotis Kanavos | public double UploadPercentLimit { get; set; } |
131 | 79736291 | Panagiotis Kanavos | |
132 | 79736291 | Panagiotis Kanavos | public string AuthenticationUrl { get; set; } |
133 | 79736291 | Panagiotis Kanavos | |
134 | 1482f9ad | Panagiotis Kanavos | |
135 | 1482f9ad | Panagiotis Kanavos | public string VersionPath |
136 | 1482f9ad | Panagiotis Kanavos | { |
137 | 1482f9ad | Panagiotis Kanavos | get { return UsePithos ? "v1" : "v1.0"; } |
138 | 1482f9ad | Panagiotis Kanavos | } |
139 | 2c053915 | Panagiotis Kanavos | |
140 | 2c053915 | Panagiotis Kanavos | public bool UsePithos { get; set; } |
141 | d78cbf09 | Panagiotis Kanavos | |
142 | 3c43ec9b | Panagiotis Kanavos | |
143 | 5120f3cb | Panagiotis Kanavos | |
144 | c53aa229 | Panagiotis Kanavos | public CloudFilesClient(string userName, string apiKey) |
145 | d78cbf09 | Panagiotis Kanavos | { |
146 | c53aa229 | Panagiotis Kanavos | UserName = userName; |
147 | c53aa229 | Panagiotis Kanavos | ApiKey = apiKey; |
148 | c53aa229 | Panagiotis Kanavos | } |
149 | c53aa229 | Panagiotis Kanavos | |
150 | c53aa229 | Panagiotis Kanavos | public CloudFilesClient(AccountInfo accountInfo) |
151 | c53aa229 | Panagiotis Kanavos | { |
152 | c53aa229 | Panagiotis Kanavos | if (accountInfo==null) |
153 | c53aa229 | Panagiotis Kanavos | throw new ArgumentNullException("accountInfo"); |
154 | c53aa229 | Panagiotis Kanavos | Contract.Ensures(!String.IsNullOrWhiteSpace(Token)); |
155 | c53aa229 | Panagiotis Kanavos | Contract.Ensures(StorageUrl != null); |
156 | cfed7823 | Panagiotis Kanavos | Contract.Ensures(_baseClient != null); |
157 | c53aa229 | Panagiotis Kanavos | Contract.Ensures(RootAddressUri != null); |
158 | 422c9598 | Panagiotis Kanavos | Contract.EndContractBlock(); |
159 | cfed7823 | Panagiotis Kanavos | |
160 | c53aa229 | Panagiotis Kanavos | _baseClient = new RestClient |
161 | c53aa229 | Panagiotis Kanavos | { |
162 | c53aa229 | Panagiotis Kanavos | BaseAddress = accountInfo.StorageUri.ToString(), |
163 | c53aa229 | Panagiotis Kanavos | Timeout = 10000, |
164 | 65282d58 | Panagiotis Kanavos | Retries = 3, |
165 | c53aa229 | Panagiotis Kanavos | }; |
166 | c53aa229 | Panagiotis Kanavos | StorageUrl = accountInfo.StorageUri; |
167 | c53aa229 | Panagiotis Kanavos | Token = accountInfo.Token; |
168 | c53aa229 | Panagiotis Kanavos | UserName = accountInfo.UserName; |
169 | c53aa229 | Panagiotis Kanavos | |
170 | c53aa229 | Panagiotis Kanavos | //Get the root address (StorageUrl without the account) |
171 | c53aa229 | Panagiotis Kanavos | var storageUrl = StorageUrl.AbsoluteUri; |
172 | c53aa229 | Panagiotis Kanavos | var usernameIndex = storageUrl.LastIndexOf(UserName); |
173 | c53aa229 | Panagiotis Kanavos | var rootUrl = storageUrl.Substring(0, usernameIndex); |
174 | c53aa229 | Panagiotis Kanavos | RootAddressUri = new Uri(rootUrl); |
175 | c53aa229 | Panagiotis Kanavos | } |
176 | d78cbf09 | Panagiotis Kanavos | |
177 | 3c43ec9b | Panagiotis Kanavos | |
178 | c53aa229 | Panagiotis Kanavos | public AccountInfo Authenticate() |
179 | c53aa229 | Panagiotis Kanavos | { |
180 | c53aa229 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(UserName)) |
181 | c53aa229 | Panagiotis Kanavos | throw new InvalidOperationException("UserName is empty"); |
182 | c53aa229 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(ApiKey)) |
183 | c53aa229 | Panagiotis Kanavos | throw new InvalidOperationException("ApiKey is empty"); |
184 | c53aa229 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(AuthenticationUrl)) |
185 | c53aa229 | Panagiotis Kanavos | throw new InvalidOperationException("AuthenticationUrl is empty"); |
186 | c53aa229 | Panagiotis Kanavos | Contract.Ensures(!String.IsNullOrWhiteSpace(Token)); |
187 | c53aa229 | Panagiotis Kanavos | Contract.Ensures(StorageUrl != null); |
188 | c53aa229 | Panagiotis Kanavos | Contract.Ensures(_baseClient != null); |
189 | c53aa229 | Panagiotis Kanavos | Contract.Ensures(RootAddressUri != null); |
190 | c53aa229 | Panagiotis Kanavos | Contract.EndContractBlock(); |
191 | c53aa229 | Panagiotis Kanavos | |
192 | c53aa229 | Panagiotis Kanavos | |
193 | c53aa229 | Panagiotis Kanavos | Log.InfoFormat("[AUTHENTICATE] Start for {0}", UserName); |
194 | d78cbf09 | Panagiotis Kanavos | |
195 | c92e02f3 | Panagiotis Kanavos | var groups = new List<Group>(); |
196 | c92e02f3 | Panagiotis Kanavos | |
197 | 9c4346c9 | Panagiotis Kanavos | using (var authClient = new RestClient{BaseAddress=AuthenticationUrl}) |
198 | 65282d58 | Panagiotis Kanavos | { |
199 | 34bdb91d | Panagiotis Kanavos | /* if (Proxy != null) |
200 | 34bdb91d | Panagiotis Kanavos | authClient.Proxy = Proxy;*/ |
201 | d78cbf09 | Panagiotis Kanavos | |
202 | cfed7823 | Panagiotis Kanavos | Contract.Assume(authClient.Headers!=null); |
203 | cfed7823 | Panagiotis Kanavos | |
204 | 4d301e8e | Panagiotis Kanavos | authClient.Headers.Add("X-Auth-User", UserName); |
205 | 4d301e8e | Panagiotis Kanavos | authClient.Headers.Add("X-Auth-Key", ApiKey); |
206 | 0eea575a | Panagiotis Kanavos | |
207 | cd7c162f | Panagiotis Kanavos | authClient.DownloadStringWithRetry(VersionPath, 3); |
208 | 0eea575a | Panagiotis Kanavos | |
209 | 4d301e8e | Panagiotis Kanavos | authClient.AssertStatusOK("Authentication failed"); |
210 | 0eea575a | Panagiotis Kanavos | |
211 | cd7c162f | Panagiotis Kanavos | var storageUrl = authClient.GetHeaderValue("X-Storage-Url"); |
212 | 0eea575a | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(storageUrl)) |
213 | 0eea575a | Panagiotis Kanavos | throw new InvalidOperationException("Failed to obtain storage url"); |
214 | c53aa229 | Panagiotis Kanavos | |
215 | c53aa229 | Panagiotis Kanavos | _baseClient = new RestClient |
216 | c53aa229 | Panagiotis Kanavos | { |
217 | c53aa229 | Panagiotis Kanavos | BaseAddress = storageUrl, |
218 | c53aa229 | Panagiotis Kanavos | Timeout = 10000, |
219 | 65282d58 | Panagiotis Kanavos | Retries = 3, |
220 | 34bdb91d | Panagiotis Kanavos | //Proxy=Proxy |
221 | c53aa229 | Panagiotis Kanavos | }; |
222 | c53aa229 | Panagiotis Kanavos | |
223 | 0eea575a | Panagiotis Kanavos | StorageUrl = new Uri(storageUrl); |
224 | d9643dd6 | Panagiotis Kanavos | |
225 | cfed7823 | Panagiotis Kanavos | //Get the root address (StorageUrl without the account) |
226 | cfed7823 | Panagiotis Kanavos | var usernameIndex=storageUrl.LastIndexOf(UserName); |
227 | cfed7823 | Panagiotis Kanavos | var rootUrl = storageUrl.Substring(0, usernameIndex); |
228 | cfed7823 | Panagiotis Kanavos | RootAddressUri = new Uri(rootUrl); |
229 | cfed7823 | Panagiotis Kanavos | |
230 | 4d301e8e | Panagiotis Kanavos | var token = authClient.GetHeaderValue("X-Auth-Token"); |
231 | b6c72f62 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(token)) |
232 | b6c72f62 | Panagiotis Kanavos | throw new InvalidOperationException("Failed to obtain token url"); |
233 | b6c72f62 | Panagiotis Kanavos | Token = token; |
234 | c53aa229 | Panagiotis Kanavos | |
235 | c92e02f3 | Panagiotis Kanavos | /* var keys = authClient.ResponseHeaders.AllKeys.AsQueryable(); |
236 | c92e02f3 | Panagiotis Kanavos | groups = (from key in keys |
237 | c92e02f3 | Panagiotis Kanavos | where key.StartsWith("X-Account-Group-") |
238 | c92e02f3 | Panagiotis Kanavos | let name = key.Substring(16) |
239 | c92e02f3 | Panagiotis Kanavos | select new Group(name, authClient.ResponseHeaders[key])) |
240 | c92e02f3 | Panagiotis Kanavos | .ToList(); |
241 | c92e02f3 | Panagiotis Kanavos | |
242 | c92e02f3 | Panagiotis Kanavos | */ |
243 | b6c72f62 | Panagiotis Kanavos | } |
244 | d78cbf09 | Panagiotis Kanavos | |
245 | c53aa229 | Panagiotis Kanavos | Log.InfoFormat("[AUTHENTICATE] End for {0}", UserName); |
246 | ebc37b0d | pkanavos | Debug.Assert(_baseClient!=null); |
247 | 9c4346c9 | Panagiotis Kanavos | |
248 | c92e02f3 | Panagiotis Kanavos | return new AccountInfo {StorageUri = StorageUrl, Token = Token, UserName = UserName,Groups=groups}; |
249 | 2c053915 | Panagiotis Kanavos | |
250 | b5061ac8 | Panagiotis Kanavos | } |
251 | d78cbf09 | Panagiotis Kanavos | |
252 | d78cbf09 | Panagiotis Kanavos | |
253 | cfed7823 | Panagiotis Kanavos | |
254 | cfed7823 | Panagiotis Kanavos | public IList<ContainerInfo> ListContainers(string account) |
255 | 9c4346c9 | Panagiotis Kanavos | { |
256 | 9c4346c9 | Panagiotis Kanavos | using (var client = new RestClient(_baseClient)) |
257 | 9c4346c9 | Panagiotis Kanavos | { |
258 | cfed7823 | Panagiotis Kanavos | if (!String.IsNullOrWhiteSpace(account)) |
259 | cfed7823 | Panagiotis Kanavos | client.BaseAddress = GetAccountUrl(account); |
260 | cfed7823 | Panagiotis Kanavos | |
261 | 9c4346c9 | Panagiotis Kanavos | client.Parameters.Clear(); |
262 | 9c4346c9 | Panagiotis Kanavos | client.Parameters.Add("format", "json"); |
263 | 5ce54458 | Panagiotis Kanavos | var content = client.DownloadStringWithRetry("", 3); |
264 | 9c4346c9 | Panagiotis Kanavos | client.AssertStatusOK("List Containers failed"); |
265 | 9c4346c9 | Panagiotis Kanavos | |
266 | 9c4346c9 | Panagiotis Kanavos | if (client.StatusCode == HttpStatusCode.NoContent) |
267 | 9c4346c9 | Panagiotis Kanavos | return new List<ContainerInfo>(); |
268 | 9c4346c9 | Panagiotis Kanavos | var infos = JsonConvert.DeserializeObject<IList<ContainerInfo>>(content); |
269 | 5750d7cc | Panagiotis Kanavos | |
270 | 5750d7cc | Panagiotis Kanavos | foreach (var info in infos) |
271 | 5750d7cc | Panagiotis Kanavos | { |
272 | 5750d7cc | Panagiotis Kanavos | info.Account = account; |
273 | 5750d7cc | Panagiotis Kanavos | } |
274 | 9c4346c9 | Panagiotis Kanavos | return infos; |
275 | 9c4346c9 | Panagiotis Kanavos | } |
276 | 4d301e8e | Panagiotis Kanavos | |
277 | d78cbf09 | Panagiotis Kanavos | } |
278 | d78cbf09 | Panagiotis Kanavos | |
279 | cfed7823 | Panagiotis Kanavos | private string GetAccountUrl(string account) |
280 | cfed7823 | Panagiotis Kanavos | { |
281 | 4f6d51d4 | Panagiotis Kanavos | return new Uri(RootAddressUri, new Uri(account,UriKind.Relative)).AbsoluteUri; |
282 | cfed7823 | Panagiotis Kanavos | } |
283 | cfed7823 | Panagiotis Kanavos | |
284 | cfed7823 | Panagiotis Kanavos | public IList<ShareAccountInfo> ListSharingAccounts(DateTime? since=null) |
285 | cfed7823 | Panagiotis Kanavos | { |
286 | 4f6d51d4 | Panagiotis Kanavos | using (ThreadContext.Stacks["Share"].Push("List Accounts")) |
287 | cfed7823 | Panagiotis Kanavos | { |
288 | 5120f3cb | Panagiotis Kanavos | if (Log.IsDebugEnabled) Log.DebugFormat("START"); |
289 | cfed7823 | Panagiotis Kanavos | |
290 | 5120f3cb | Panagiotis Kanavos | using (var client = new RestClient(_baseClient)) |
291 | 5120f3cb | Panagiotis Kanavos | { |
292 | 5120f3cb | Panagiotis Kanavos | client.Parameters.Clear(); |
293 | 5120f3cb | Panagiotis Kanavos | client.Parameters.Add("format", "json"); |
294 | 5120f3cb | Panagiotis Kanavos | client.IfModifiedSince = since; |
295 | cfed7823 | Panagiotis Kanavos | |
296 | 5120f3cb | Panagiotis Kanavos | //Extract the username from the base address |
297 | 5120f3cb | Panagiotis Kanavos | client.BaseAddress = RootAddressUri.AbsoluteUri; |
298 | cfed7823 | Panagiotis Kanavos | |
299 | 5120f3cb | Panagiotis Kanavos | var content = client.DownloadStringWithRetry(@"", 3); |
300 | cfed7823 | Panagiotis Kanavos | |
301 | 5120f3cb | Panagiotis Kanavos | client.AssertStatusOK("ListSharingAccounts failed"); |
302 | 5120f3cb | Panagiotis Kanavos | |
303 | 5120f3cb | Panagiotis Kanavos | //If the result is empty, return an empty list, |
304 | 5120f3cb | Panagiotis Kanavos | var infos = String.IsNullOrWhiteSpace(content) |
305 | 5120f3cb | Panagiotis Kanavos | ? new List<ShareAccountInfo>() |
306 | 5120f3cb | Panagiotis Kanavos | //Otherwise deserialize the account list into a list of ShareAccountInfos |
307 | 5120f3cb | Panagiotis Kanavos | : JsonConvert.DeserializeObject<IList<ShareAccountInfo>>(content); |
308 | 5120f3cb | Panagiotis Kanavos | |
309 | 5120f3cb | Panagiotis Kanavos | Log.DebugFormat("END"); |
310 | 5120f3cb | Panagiotis Kanavos | return infos; |
311 | 5120f3cb | Panagiotis Kanavos | } |
312 | cfed7823 | Panagiotis Kanavos | } |
313 | cfed7823 | Panagiotis Kanavos | } |
314 | cfed7823 | Panagiotis Kanavos | |
315 | 5ce54458 | Panagiotis Kanavos | //Request listing of all objects in a container modified since a specific time. |
316 | 5ce54458 | Panagiotis Kanavos | //If the *since* value is missing, return all objects |
317 | cfed7823 | Panagiotis Kanavos | public IList<ObjectInfo> ListSharedObjects(DateTime? since = null) |
318 | cfed7823 | Panagiotis Kanavos | { |
319 | cfed7823 | Panagiotis Kanavos | |
320 | 4f6d51d4 | Panagiotis Kanavos | using (ThreadContext.Stacks["Share"].Push("List Objects")) |
321 | cfed7823 | Panagiotis Kanavos | { |
322 | 5120f3cb | Panagiotis Kanavos | if (Log.IsDebugEnabled) Log.DebugFormat("START"); |
323 | 99e6329f | Panagiotis Kanavos | //'since' is not used here because we need to have ListObjects return a NoChange result |
324 | 99e6329f | Panagiotis Kanavos | //for all shared accounts,containers |
325 | 99e6329f | Panagiotis Kanavos | var accounts = ListSharingAccounts(); |
326 | 126f90b3 | Panagiotis Kanavos | var items = from account in accounts |
327 | 126f90b3 | Panagiotis Kanavos | let containers = ListContainers(account.name) |
328 | 126f90b3 | Panagiotis Kanavos | from container in containers |
329 | 99e6329f | Panagiotis Kanavos | select ListObjects(account.name, container.Name,since); |
330 | 126f90b3 | Panagiotis Kanavos | var objects=items.SelectMany(r=> r).ToList(); |
331 | 126f90b3 | Panagiotis Kanavos | /* |
332 | 126f90b3 | Panagiotis Kanavos | var objects = new List<ObjectInfo>(); |
333 | 126f90b3 | Panagiotis Kanavos | foreach (var containerObjects in items) |
334 | cfed7823 | Panagiotis Kanavos | { |
335 | 126f90b3 | Panagiotis Kanavos | objects.AddRange(containerObjects); |
336 | cfed7823 | Panagiotis Kanavos | } |
337 | 126f90b3 | Panagiotis Kanavos | */ |
338 | 5120f3cb | Panagiotis Kanavos | if (Log.IsDebugEnabled) Log.DebugFormat("END"); |
339 | 5120f3cb | Panagiotis Kanavos | return objects; |
340 | cfed7823 | Panagiotis Kanavos | } |
341 | cfed7823 | Panagiotis Kanavos | } |
342 | cfed7823 | Panagiotis Kanavos | |
343 | ff26eb71 | Panagiotis Kanavos | public void SetTags(ObjectInfo target,IDictionary<string,string> tags) |
344 | ff26eb71 | Panagiotis Kanavos | { |
345 | ff26eb71 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(Token)) |
346 | ff26eb71 | Panagiotis Kanavos | throw new InvalidOperationException("The Token is not set"); |
347 | ff26eb71 | Panagiotis Kanavos | if (StorageUrl == null) |
348 | ff26eb71 | Panagiotis Kanavos | throw new InvalidOperationException("The StorageUrl is not set"); |
349 | ff26eb71 | Panagiotis Kanavos | if (target == null) |
350 | ff26eb71 | Panagiotis Kanavos | throw new ArgumentNullException("target"); |
351 | ff26eb71 | Panagiotis Kanavos | Contract.EndContractBlock(); |
352 | ff26eb71 | Panagiotis Kanavos | |
353 | 4f6d51d4 | Panagiotis Kanavos | using (ThreadContext.Stacks["Share"].Push("Share Object")) |
354 | ff26eb71 | Panagiotis Kanavos | { |
355 | ff26eb71 | Panagiotis Kanavos | if (Log.IsDebugEnabled) Log.DebugFormat("START"); |
356 | ff26eb71 | Panagiotis Kanavos | |
357 | ff26eb71 | Panagiotis Kanavos | using (var client = new RestClient(_baseClient)) |
358 | ff26eb71 | Panagiotis Kanavos | { |
359 | ff26eb71 | Panagiotis Kanavos | |
360 | ff26eb71 | Panagiotis Kanavos | client.BaseAddress = GetAccountUrl(target.Account); |
361 | ff26eb71 | Panagiotis Kanavos | |
362 | ff26eb71 | Panagiotis Kanavos | client.Parameters.Clear(); |
363 | ff26eb71 | Panagiotis Kanavos | client.Parameters.Add("update", ""); |
364 | ff26eb71 | Panagiotis Kanavos | |
365 | ff26eb71 | Panagiotis Kanavos | foreach (var tag in tags) |
366 | ff26eb71 | Panagiotis Kanavos | { |
367 | ff26eb71 | Panagiotis Kanavos | var headerTag = String.Format("X-Object-Meta-{0}", tag.Key); |
368 | ff26eb71 | Panagiotis Kanavos | client.Headers.Add(headerTag, tag.Value); |
369 | ff26eb71 | Panagiotis Kanavos | } |
370 | ff26eb71 | Panagiotis Kanavos | |
371 | 4f6d51d4 | Panagiotis Kanavos | client.DownloadStringWithRetry(target.Container, 3); |
372 | ff26eb71 | Panagiotis Kanavos | |
373 | ff26eb71 | Panagiotis Kanavos | |
374 | ff26eb71 | Panagiotis Kanavos | client.AssertStatusOK("SetTags failed"); |
375 | ff26eb71 | Panagiotis Kanavos | //If the status is NOT ACCEPTED we have a problem |
376 | ff26eb71 | Panagiotis Kanavos | if (client.StatusCode != HttpStatusCode.Accepted) |
377 | ff26eb71 | Panagiotis Kanavos | { |
378 | ff26eb71 | Panagiotis Kanavos | Log.Error("Failed to set tags"); |
379 | ff26eb71 | Panagiotis Kanavos | throw new Exception("Failed to set tags"); |
380 | ff26eb71 | Panagiotis Kanavos | } |
381 | ff26eb71 | Panagiotis Kanavos | |
382 | ff26eb71 | Panagiotis Kanavos | if (Log.IsDebugEnabled) Log.DebugFormat("END"); |
383 | ff26eb71 | Panagiotis Kanavos | } |
384 | ff26eb71 | Panagiotis Kanavos | } |
385 | ff26eb71 | Panagiotis Kanavos | |
386 | ff26eb71 | Panagiotis Kanavos | |
387 | ff26eb71 | Panagiotis Kanavos | } |
388 | ff26eb71 | Panagiotis Kanavos | |
389 | cfed7823 | Panagiotis Kanavos | public void ShareObject(string account, string container, string objectName, string shareTo, bool read, bool write) |
390 | cfed7823 | Panagiotis Kanavos | { |
391 | cfed7823 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(Token)) |
392 | cfed7823 | Panagiotis Kanavos | throw new InvalidOperationException("The Token is not set"); |
393 | cfed7823 | Panagiotis Kanavos | if (StorageUrl==null) |
394 | cfed7823 | Panagiotis Kanavos | throw new InvalidOperationException("The StorageUrl is not set"); |
395 | cfed7823 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(container)) |
396 | cfed7823 | Panagiotis Kanavos | throw new ArgumentNullException("container"); |
397 | cfed7823 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(objectName)) |
398 | cfed7823 | Panagiotis Kanavos | throw new ArgumentNullException("objectName"); |
399 | cfed7823 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(account)) |
400 | cfed7823 | Panagiotis Kanavos | throw new ArgumentNullException("account"); |
401 | cfed7823 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(shareTo)) |
402 | cfed7823 | Panagiotis Kanavos | throw new ArgumentNullException("shareTo"); |
403 | cfed7823 | Panagiotis Kanavos | Contract.EndContractBlock(); |
404 | cfed7823 | Panagiotis Kanavos | |
405 | 4f6d51d4 | Panagiotis Kanavos | using (ThreadContext.Stacks["Share"].Push("Share Object")) |
406 | cfed7823 | Panagiotis Kanavos | { |
407 | 5120f3cb | Panagiotis Kanavos | if (Log.IsDebugEnabled) Log.DebugFormat("START"); |
408 | 5120f3cb | Panagiotis Kanavos | |
409 | 5120f3cb | Panagiotis Kanavos | using (var client = new RestClient(_baseClient)) |
410 | 5120f3cb | Panagiotis Kanavos | { |
411 | cfed7823 | Panagiotis Kanavos | |
412 | 5120f3cb | Panagiotis Kanavos | client.BaseAddress = GetAccountUrl(account); |
413 | cfed7823 | Panagiotis Kanavos | |
414 | 5120f3cb | Panagiotis Kanavos | client.Parameters.Clear(); |
415 | 5120f3cb | Panagiotis Kanavos | client.Parameters.Add("format", "json"); |
416 | 5120f3cb | Panagiotis Kanavos | |
417 | 5120f3cb | Panagiotis Kanavos | string permission = ""; |
418 | 5120f3cb | Panagiotis Kanavos | if (write) |
419 | 5120f3cb | Panagiotis Kanavos | permission = String.Format("write={0}", shareTo); |
420 | 5120f3cb | Panagiotis Kanavos | else if (read) |
421 | 5120f3cb | Panagiotis Kanavos | permission = String.Format("read={0}", shareTo); |
422 | 5120f3cb | Panagiotis Kanavos | client.Headers.Add("X-Object-Sharing", permission); |
423 | cfed7823 | Panagiotis Kanavos | |
424 | 5120f3cb | Panagiotis Kanavos | var content = client.DownloadStringWithRetry(container, 3); |
425 | cfed7823 | Panagiotis Kanavos | |
426 | 5120f3cb | Panagiotis Kanavos | client.AssertStatusOK("ShareObject failed"); |
427 | cfed7823 | Panagiotis Kanavos | |
428 | 5120f3cb | Panagiotis Kanavos | //If the result is empty, return an empty list, |
429 | 5120f3cb | Panagiotis Kanavos | var infos = String.IsNullOrWhiteSpace(content) |
430 | 5120f3cb | Panagiotis Kanavos | ? new List<ObjectInfo>() |
431 | 5120f3cb | Panagiotis Kanavos | //Otherwise deserialize the object list into a list of ObjectInfos |
432 | 5120f3cb | Panagiotis Kanavos | : JsonConvert.DeserializeObject<IList<ObjectInfo>>(content); |
433 | 5120f3cb | Panagiotis Kanavos | |
434 | 5120f3cb | Panagiotis Kanavos | if (Log.IsDebugEnabled) Log.DebugFormat("END"); |
435 | 5120f3cb | Panagiotis Kanavos | } |
436 | cfed7823 | Panagiotis Kanavos | } |
437 | cfed7823 | Panagiotis Kanavos | |
438 | 5120f3cb | Panagiotis Kanavos | |
439 | cfed7823 | Panagiotis Kanavos | } |
440 | cfed7823 | Panagiotis Kanavos | |
441 | 0bd56b7c | Panagiotis Kanavos | public AccountInfo GetAccountPolicies(AccountInfo accountInfo) |
442 | 0bd56b7c | Panagiotis Kanavos | { |
443 | 0bd56b7c | Panagiotis Kanavos | if (accountInfo==null) |
444 | 0bd56b7c | Panagiotis Kanavos | throw new ArgumentNullException("accountInfo"); |
445 | 0bd56b7c | Panagiotis Kanavos | Contract.EndContractBlock(); |
446 | 0bd56b7c | Panagiotis Kanavos | |
447 | 4f6d51d4 | Panagiotis Kanavos | using (ThreadContext.Stacks["Account"].Push("GetPolicies")) |
448 | 0bd56b7c | Panagiotis Kanavos | { |
449 | 0bd56b7c | Panagiotis Kanavos | if (Log.IsDebugEnabled) Log.DebugFormat("START"); |
450 | 0bd56b7c | Panagiotis Kanavos | |
451 | 0bd56b7c | Panagiotis Kanavos | using (var client = new RestClient(_baseClient)) |
452 | 0bd56b7c | Panagiotis Kanavos | { |
453 | 0bd56b7c | Panagiotis Kanavos | if (!String.IsNullOrWhiteSpace(accountInfo.UserName)) |
454 | 0bd56b7c | Panagiotis Kanavos | client.BaseAddress = GetAccountUrl(accountInfo.UserName); |
455 | 0bd56b7c | Panagiotis Kanavos | |
456 | 0bd56b7c | Panagiotis Kanavos | client.Parameters.Clear(); |
457 | 0bd56b7c | Panagiotis Kanavos | client.Parameters.Add("format", "json"); |
458 | 0bd56b7c | Panagiotis Kanavos | client.Head(String.Empty, 3); |
459 | 0bd56b7c | Panagiotis Kanavos | |
460 | 0bd56b7c | Panagiotis Kanavos | var quotaValue=client.ResponseHeaders["X-Account-Policy-Quota"]; |
461 | 0bd56b7c | Panagiotis Kanavos | var bytesValue= client.ResponseHeaders["X-Account-Bytes-Used"]; |
462 | 0bd56b7c | Panagiotis Kanavos | |
463 | 0bd56b7c | Panagiotis Kanavos | long quota, bytes; |
464 | 0bd56b7c | Panagiotis Kanavos | if (long.TryParse(quotaValue, out quota)) |
465 | 0bd56b7c | Panagiotis Kanavos | accountInfo.Quota = quota; |
466 | 0bd56b7c | Panagiotis Kanavos | if (long.TryParse(bytesValue, out bytes)) |
467 | 0bd56b7c | Panagiotis Kanavos | accountInfo.BytesUsed = bytes; |
468 | 0bd56b7c | Panagiotis Kanavos | |
469 | 0bd56b7c | Panagiotis Kanavos | return accountInfo; |
470 | 0bd56b7c | Panagiotis Kanavos | |
471 | 0bd56b7c | Panagiotis Kanavos | } |
472 | 0bd56b7c | Panagiotis Kanavos | |
473 | 0bd56b7c | Panagiotis Kanavos | } |
474 | 0bd56b7c | Panagiotis Kanavos | } |
475 | 0bd56b7c | Panagiotis Kanavos | |
476 | aba9e6d9 | Panagiotis Kanavos | public void UpdateMetadata(ObjectInfo objectInfo) |
477 | aba9e6d9 | Panagiotis Kanavos | { |
478 | aba9e6d9 | Panagiotis Kanavos | if (objectInfo == null) |
479 | aba9e6d9 | Panagiotis Kanavos | throw new ArgumentNullException("objectInfo"); |
480 | aba9e6d9 | Panagiotis Kanavos | Contract.EndContractBlock(); |
481 | aba9e6d9 | Panagiotis Kanavos | |
482 | 4f6d51d4 | Panagiotis Kanavos | using (ThreadContext.Stacks["Objects"].Push("UpdateMetadata")) |
483 | aba9e6d9 | Panagiotis Kanavos | { |
484 | aba9e6d9 | Panagiotis Kanavos | if (Log.IsDebugEnabled) Log.DebugFormat("START"); |
485 | aba9e6d9 | Panagiotis Kanavos | |
486 | aba9e6d9 | Panagiotis Kanavos | |
487 | aba9e6d9 | Panagiotis Kanavos | using(var client=new RestClient(_baseClient)) |
488 | aba9e6d9 | Panagiotis Kanavos | { |
489 | aba9e6d9 | Panagiotis Kanavos | |
490 | aba9e6d9 | Panagiotis Kanavos | client.BaseAddress = GetAccountUrl(objectInfo.Account); |
491 | aba9e6d9 | Panagiotis Kanavos | |
492 | aba9e6d9 | Panagiotis Kanavos | client.Parameters.Clear(); |
493 | aba9e6d9 | Panagiotis Kanavos | |
494 | aba9e6d9 | Panagiotis Kanavos | |
495 | aba9e6d9 | Panagiotis Kanavos | //Set Tags |
496 | aba9e6d9 | Panagiotis Kanavos | foreach (var tag in objectInfo.Tags) |
497 | aba9e6d9 | Panagiotis Kanavos | { |
498 | aba9e6d9 | Panagiotis Kanavos | var headerTag = String.Format("X-Object-Meta-{0}", tag.Key); |
499 | aba9e6d9 | Panagiotis Kanavos | client.Headers.Add(headerTag, tag.Value); |
500 | aba9e6d9 | Panagiotis Kanavos | } |
501 | aba9e6d9 | Panagiotis Kanavos | |
502 | aba9e6d9 | Panagiotis Kanavos | //Set Permissions |
503 | aba9e6d9 | Panagiotis Kanavos | |
504 | aba9e6d9 | Panagiotis Kanavos | var permissions=objectInfo.GetPermissionString(); |
505 | aba9e6d9 | Panagiotis Kanavos | client.SetNonEmptyHeaderValue("X-Object-Sharing",permissions); |
506 | aba9e6d9 | Panagiotis Kanavos | |
507 | aba9e6d9 | Panagiotis Kanavos | client.SetNonEmptyHeaderValue("Content-Disposition",objectInfo.ContendDisposition); |
508 | aba9e6d9 | Panagiotis Kanavos | client.SetNonEmptyHeaderValue("Content-Encoding",objectInfo.ContentEncoding); |
509 | aba9e6d9 | Panagiotis Kanavos | client.SetNonEmptyHeaderValue("X-Object-Manifest",objectInfo.Manifest); |
510 | f0947233 | Panagiotis Kanavos | var isPublic = objectInfo.IsPublic.ToString().ToLower(); |
511 | f0947233 | Panagiotis Kanavos | client.Headers.Add("X-Object-Public", isPublic); |
512 | aba9e6d9 | Panagiotis Kanavos | |
513 | aba9e6d9 | Panagiotis Kanavos | |
514 | bb7717f5 | pkanavos | /*var uriBuilder = client.GetAddressBuilder(objectInfo.Container, objectInfo.Name); |
515 | bb7717f5 | pkanavos | uriBuilder.Query = "update="; |
516 | bb7717f5 | pkanavos | var uri = uriBuilder.Uri.MakeRelativeUri(this.RootAddressUri);*/ |
517 | bb7717f5 | pkanavos | var address = String.Format("{0}/{1}?update=",objectInfo.Container, objectInfo.Name); |
518 | bb7717f5 | pkanavos | client.PostWithRetry(address,"application/xml"); |
519 | bb7717f5 | pkanavos | |
520 | bb7717f5 | pkanavos | //client.UploadValues(uri,new NameValueCollection()); |
521 | aba9e6d9 | Panagiotis Kanavos | |
522 | aba9e6d9 | Panagiotis Kanavos | |
523 | aba9e6d9 | Panagiotis Kanavos | client.AssertStatusOK("UpdateMetadata failed"); |
524 | aba9e6d9 | Panagiotis Kanavos | //If the status is NOT ACCEPTED or OK we have a problem |
525 | aba9e6d9 | Panagiotis Kanavos | if (!(client.StatusCode == HttpStatusCode.Accepted || client.StatusCode == HttpStatusCode.OK)) |
526 | aba9e6d9 | Panagiotis Kanavos | { |
527 | aba9e6d9 | Panagiotis Kanavos | Log.Error("Failed to update metadata"); |
528 | aba9e6d9 | Panagiotis Kanavos | throw new Exception("Failed to update metadata"); |
529 | aba9e6d9 | Panagiotis Kanavos | } |
530 | aba9e6d9 | Panagiotis Kanavos | |
531 | aba9e6d9 | Panagiotis Kanavos | if (Log.IsDebugEnabled) Log.DebugFormat("END"); |
532 | aba9e6d9 | Panagiotis Kanavos | } |
533 | aba9e6d9 | Panagiotis Kanavos | } |
534 | aba9e6d9 | Panagiotis Kanavos | |
535 | aba9e6d9 | Panagiotis Kanavos | } |
536 | aba9e6d9 | Panagiotis Kanavos | |
537 | c92e02f3 | Panagiotis Kanavos | public void UpdateMetadata(ContainerInfo containerInfo) |
538 | c92e02f3 | Panagiotis Kanavos | { |
539 | c92e02f3 | Panagiotis Kanavos | if (containerInfo == null) |
540 | c92e02f3 | Panagiotis Kanavos | throw new ArgumentNullException("containerInfo"); |
541 | c92e02f3 | Panagiotis Kanavos | Contract.EndContractBlock(); |
542 | c92e02f3 | Panagiotis Kanavos | |
543 | 4f6d51d4 | Panagiotis Kanavos | using (ThreadContext.Stacks["Containers"].Push("UpdateMetadata")) |
544 | c92e02f3 | Panagiotis Kanavos | { |
545 | c92e02f3 | Panagiotis Kanavos | if (Log.IsDebugEnabled) Log.DebugFormat("START"); |
546 | c92e02f3 | Panagiotis Kanavos | |
547 | c92e02f3 | Panagiotis Kanavos | |
548 | c92e02f3 | Panagiotis Kanavos | using(var client=new RestClient(_baseClient)) |
549 | c92e02f3 | Panagiotis Kanavos | { |
550 | c92e02f3 | Panagiotis Kanavos | |
551 | c92e02f3 | Panagiotis Kanavos | client.BaseAddress = GetAccountUrl(containerInfo.Account); |
552 | c92e02f3 | Panagiotis Kanavos | |
553 | c92e02f3 | Panagiotis Kanavos | client.Parameters.Clear(); |
554 | c92e02f3 | Panagiotis Kanavos | |
555 | c92e02f3 | Panagiotis Kanavos | |
556 | c92e02f3 | Panagiotis Kanavos | //Set Tags |
557 | c92e02f3 | Panagiotis Kanavos | foreach (var tag in containerInfo.Tags) |
558 | c92e02f3 | Panagiotis Kanavos | { |
559 | c92e02f3 | Panagiotis Kanavos | var headerTag = String.Format("X-Container-Meta-{0}", tag.Key); |
560 | c92e02f3 | Panagiotis Kanavos | client.Headers.Add(headerTag, tag.Value); |
561 | c92e02f3 | Panagiotis Kanavos | } |
562 | c92e02f3 | Panagiotis Kanavos | |
563 | c92e02f3 | Panagiotis Kanavos | |
564 | c92e02f3 | Panagiotis Kanavos | //Set Policies |
565 | c92e02f3 | Panagiotis Kanavos | foreach (var policy in containerInfo.Policies) |
566 | c92e02f3 | Panagiotis Kanavos | { |
567 | c92e02f3 | Panagiotis Kanavos | var headerPolicy = String.Format("X-Container-Policy-{0}", policy.Key); |
568 | c92e02f3 | Panagiotis Kanavos | client.Headers.Add(headerPolicy, policy.Value); |
569 | c92e02f3 | Panagiotis Kanavos | } |
570 | c92e02f3 | Panagiotis Kanavos | |
571 | c92e02f3 | Panagiotis Kanavos | |
572 | c92e02f3 | Panagiotis Kanavos | var uriBuilder = client.GetAddressBuilder(containerInfo.Name,""); |
573 | c92e02f3 | Panagiotis Kanavos | var uri = uriBuilder.Uri; |
574 | c92e02f3 | Panagiotis Kanavos | |
575 | 4f6d51d4 | Panagiotis Kanavos | client.UploadValues(uri,new NameValueCollection()); |
576 | c92e02f3 | Panagiotis Kanavos | |
577 | c92e02f3 | Panagiotis Kanavos | |
578 | c92e02f3 | Panagiotis Kanavos | client.AssertStatusOK("UpdateMetadata failed"); |
579 | c92e02f3 | Panagiotis Kanavos | //If the status is NOT ACCEPTED or OK we have a problem |
580 | c92e02f3 | Panagiotis Kanavos | if (!(client.StatusCode == HttpStatusCode.Accepted || client.StatusCode == HttpStatusCode.OK)) |
581 | c92e02f3 | Panagiotis Kanavos | { |
582 | c92e02f3 | Panagiotis Kanavos | Log.Error("Failed to update metadata"); |
583 | c92e02f3 | Panagiotis Kanavos | throw new Exception("Failed to update metadata"); |
584 | c92e02f3 | Panagiotis Kanavos | } |
585 | c92e02f3 | Panagiotis Kanavos | |
586 | c92e02f3 | Panagiotis Kanavos | if (Log.IsDebugEnabled) Log.DebugFormat("END"); |
587 | c92e02f3 | Panagiotis Kanavos | } |
588 | c92e02f3 | Panagiotis Kanavos | } |
589 | c92e02f3 | Panagiotis Kanavos | |
590 | c92e02f3 | Panagiotis Kanavos | } |
591 | c92e02f3 | Panagiotis Kanavos | |
592 | cfed7823 | Panagiotis Kanavos | |
593 | cfed7823 | Panagiotis Kanavos | public IList<ObjectInfo> ListObjects(string account, string container, DateTime? since = null) |
594 | d78cbf09 | Panagiotis Kanavos | { |
595 | d78cbf09 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(container)) |
596 | 9c4346c9 | Panagiotis Kanavos | throw new ArgumentNullException("container"); |
597 | 9c4346c9 | Panagiotis Kanavos | Contract.EndContractBlock(); |
598 | d78cbf09 | Panagiotis Kanavos | |
599 | 4f6d51d4 | Panagiotis Kanavos | using (ThreadContext.Stacks["Objects"].Push("List")) |
600 | 9c4346c9 | Panagiotis Kanavos | { |
601 | 5120f3cb | Panagiotis Kanavos | if (Log.IsDebugEnabled) Log.DebugFormat("START"); |
602 | cfed7823 | Panagiotis Kanavos | |
603 | 5120f3cb | Panagiotis Kanavos | using (var client = new RestClient(_baseClient)) |
604 | 5120f3cb | Panagiotis Kanavos | { |
605 | 5120f3cb | Panagiotis Kanavos | if (!String.IsNullOrWhiteSpace(account)) |
606 | 5120f3cb | Panagiotis Kanavos | client.BaseAddress = GetAccountUrl(account); |
607 | 4d301e8e | Panagiotis Kanavos | |
608 | 5120f3cb | Panagiotis Kanavos | client.Parameters.Clear(); |
609 | 5120f3cb | Panagiotis Kanavos | client.Parameters.Add("format", "json"); |
610 | 5120f3cb | Panagiotis Kanavos | client.IfModifiedSince = since; |
611 | 5120f3cb | Panagiotis Kanavos | var content = client.DownloadStringWithRetry(container, 3); |
612 | 4d301e8e | Panagiotis Kanavos | |
613 | 5120f3cb | Panagiotis Kanavos | client.AssertStatusOK("ListObjects failed"); |
614 | d78cbf09 | Panagiotis Kanavos | |
615 | 99e6329f | Panagiotis Kanavos | if (client.StatusCode==HttpStatusCode.NotModified) |
616 | 99e6329f | Panagiotis Kanavos | return new[]{new NoModificationInfo(account,container)}; |
617 | 5120f3cb | Panagiotis Kanavos | //If the result is empty, return an empty list, |
618 | 5120f3cb | Panagiotis Kanavos | var infos = String.IsNullOrWhiteSpace(content) |
619 | 5120f3cb | Panagiotis Kanavos | ? new List<ObjectInfo>() |
620 | 5120f3cb | Panagiotis Kanavos | //Otherwise deserialize the object list into a list of ObjectInfos |
621 | 5120f3cb | Panagiotis Kanavos | : JsonConvert.DeserializeObject<IList<ObjectInfo>>(content); |
622 | 5120f3cb | Panagiotis Kanavos | |
623 | 5120f3cb | Panagiotis Kanavos | foreach (var info in infos) |
624 | 5120f3cb | Panagiotis Kanavos | { |
625 | 5120f3cb | Panagiotis Kanavos | info.Container = container; |
626 | 5120f3cb | Panagiotis Kanavos | info.Account = account; |
627 | 759bd3c4 | Panagiotis Kanavos | info.StorageUri = this.StorageUrl; |
628 | 5120f3cb | Panagiotis Kanavos | } |
629 | 126f90b3 | Panagiotis Kanavos | if (Log.IsDebugEnabled) Log.DebugFormat("END"); |
630 | 5120f3cb | Panagiotis Kanavos | return infos; |
631 | cfed7823 | Panagiotis Kanavos | } |
632 | 9c4346c9 | Panagiotis Kanavos | } |
633 | d78cbf09 | Panagiotis Kanavos | } |
634 | d78cbf09 | Panagiotis Kanavos | |
635 | cfed7823 | Panagiotis Kanavos | public IList<ObjectInfo> ListObjects(string account, string container, string folder, DateTime? since = null) |
636 | 637bc368 | Panagiotis Kanavos | { |
637 | 637bc368 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(container)) |
638 | 9c4346c9 | Panagiotis Kanavos | throw new ArgumentNullException("container"); |
639 | 93dc3a84 | Panagiotis Kanavos | /* |
640 | 9c4346c9 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(folder)) |
641 | 9c4346c9 | Panagiotis Kanavos | throw new ArgumentNullException("folder"); |
642 | 93dc3a84 | Panagiotis Kanavos | */ |
643 | 9c4346c9 | Panagiotis Kanavos | Contract.EndContractBlock(); |
644 | 637bc368 | Panagiotis Kanavos | |
645 | 4f6d51d4 | Panagiotis Kanavos | using (ThreadContext.Stacks["Objects"].Push("List")) |
646 | 9c4346c9 | Panagiotis Kanavos | { |
647 | 5120f3cb | Panagiotis Kanavos | if (Log.IsDebugEnabled) Log.DebugFormat("START"); |
648 | cfed7823 | Panagiotis Kanavos | |
649 | 5120f3cb | Panagiotis Kanavos | using (var client = new RestClient(_baseClient)) |
650 | 5120f3cb | Panagiotis Kanavos | { |
651 | 5120f3cb | Panagiotis Kanavos | if (!String.IsNullOrWhiteSpace(account)) |
652 | 5120f3cb | Panagiotis Kanavos | client.BaseAddress = GetAccountUrl(account); |
653 | 4d301e8e | Panagiotis Kanavos | |
654 | 5120f3cb | Panagiotis Kanavos | client.Parameters.Clear(); |
655 | 5120f3cb | Panagiotis Kanavos | client.Parameters.Add("format", "json"); |
656 | 5120f3cb | Panagiotis Kanavos | client.Parameters.Add("path", folder); |
657 | 5120f3cb | Panagiotis Kanavos | client.IfModifiedSince = since; |
658 | 5120f3cb | Panagiotis Kanavos | var content = client.DownloadStringWithRetry(container, 3); |
659 | 5120f3cb | Panagiotis Kanavos | client.AssertStatusOK("ListObjects failed"); |
660 | 5bcf6d70 | Panagiotis Kanavos | |
661 | 99e6329f | Panagiotis Kanavos | if (client.StatusCode==HttpStatusCode.NotModified) |
662 | 99e6329f | Panagiotis Kanavos | return new[]{new NoModificationInfo(account,container,folder)}; |
663 | 99e6329f | Panagiotis Kanavos | |
664 | 5120f3cb | Panagiotis Kanavos | var infos = JsonConvert.DeserializeObject<IList<ObjectInfo>>(content); |
665 | 93dc3a84 | Panagiotis Kanavos | foreach (var info in infos) |
666 | 93dc3a84 | Panagiotis Kanavos | { |
667 | 93dc3a84 | Panagiotis Kanavos | info.Account = account; |
668 | 759bd3c4 | Panagiotis Kanavos | if (info.Container == null) |
669 | 759bd3c4 | Panagiotis Kanavos | info.Container = container; |
670 | 759bd3c4 | Panagiotis Kanavos | info.StorageUri = this.StorageUrl; |
671 | 93dc3a84 | Panagiotis Kanavos | } |
672 | 5120f3cb | Panagiotis Kanavos | if (Log.IsDebugEnabled) Log.DebugFormat("END"); |
673 | 5120f3cb | Panagiotis Kanavos | return infos; |
674 | 5120f3cb | Panagiotis Kanavos | } |
675 | 9c4346c9 | Panagiotis Kanavos | } |
676 | 5bcf6d70 | Panagiotis Kanavos | } |
677 | 5bcf6d70 | Panagiotis Kanavos | |
678 | d15e99b4 | Panagiotis Kanavos | |
679 | cfed7823 | Panagiotis Kanavos | public bool ContainerExists(string account, string container) |
680 | d78cbf09 | Panagiotis Kanavos | { |
681 | d78cbf09 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(container)) |
682 | d78cbf09 | Panagiotis Kanavos | throw new ArgumentNullException("container", "The container property can't be empty"); |
683 | cfed7823 | Panagiotis Kanavos | Contract.EndContractBlock(); |
684 | cfed7823 | Panagiotis Kanavos | |
685 | 4f6d51d4 | Panagiotis Kanavos | using (ThreadContext.Stacks["Containters"].Push("Exists")) |
686 | d78cbf09 | Panagiotis Kanavos | { |
687 | 5120f3cb | Panagiotis Kanavos | if (Log.IsDebugEnabled) Log.DebugFormat("START"); |
688 | cfed7823 | Panagiotis Kanavos | |
689 | 5120f3cb | Panagiotis Kanavos | using (var client = new RestClient(_baseClient)) |
690 | 9c4346c9 | Panagiotis Kanavos | { |
691 | 5120f3cb | Panagiotis Kanavos | if (!String.IsNullOrWhiteSpace(account)) |
692 | 5120f3cb | Panagiotis Kanavos | client.BaseAddress = GetAccountUrl(account); |
693 | 5120f3cb | Panagiotis Kanavos | |
694 | 5120f3cb | Panagiotis Kanavos | client.Parameters.Clear(); |
695 | 5120f3cb | Panagiotis Kanavos | client.Head(container, 3); |
696 | 5120f3cb | Panagiotis Kanavos | |
697 | 5120f3cb | Panagiotis Kanavos | bool result; |
698 | 5120f3cb | Panagiotis Kanavos | switch (client.StatusCode) |
699 | 5120f3cb | Panagiotis Kanavos | { |
700 | 5120f3cb | Panagiotis Kanavos | case HttpStatusCode.OK: |
701 | 5120f3cb | Panagiotis Kanavos | case HttpStatusCode.NoContent: |
702 | 5120f3cb | Panagiotis Kanavos | result=true; |
703 | 5120f3cb | Panagiotis Kanavos | break; |
704 | 5120f3cb | Panagiotis Kanavos | case HttpStatusCode.NotFound: |
705 | 5120f3cb | Panagiotis Kanavos | result=false; |
706 | 5120f3cb | Panagiotis Kanavos | break; |
707 | 5120f3cb | Panagiotis Kanavos | default: |
708 | 5120f3cb | Panagiotis Kanavos | throw CreateWebException("ContainerExists", client.StatusCode); |
709 | 5120f3cb | Panagiotis Kanavos | } |
710 | 5120f3cb | Panagiotis Kanavos | if (Log.IsDebugEnabled) Log.DebugFormat("END"); |
711 | 5120f3cb | Panagiotis Kanavos | |
712 | 5120f3cb | Panagiotis Kanavos | return result; |
713 | 9c4346c9 | Panagiotis Kanavos | } |
714 | 5120f3cb | Panagiotis Kanavos | |
715 | d78cbf09 | Panagiotis Kanavos | } |
716 | d78cbf09 | Panagiotis Kanavos | } |
717 | d78cbf09 | Panagiotis Kanavos | |
718 | cfed7823 | Panagiotis Kanavos | public bool ObjectExists(string account, string container, string objectName) |
719 | d78cbf09 | Panagiotis Kanavos | { |
720 | d78cbf09 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(container)) |
721 | d78cbf09 | Panagiotis Kanavos | throw new ArgumentNullException("container", "The container property can't be empty"); |
722 | d78cbf09 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(objectName)) |
723 | d78cbf09 | Panagiotis Kanavos | throw new ArgumentNullException("objectName", "The objectName property can't be empty"); |
724 | cfed7823 | Panagiotis Kanavos | Contract.EndContractBlock(); |
725 | cfed7823 | Panagiotis Kanavos | |
726 | 9c4346c9 | Panagiotis Kanavos | using (var client = new RestClient(_baseClient)) |
727 | d78cbf09 | Panagiotis Kanavos | { |
728 | cfed7823 | Panagiotis Kanavos | if (!String.IsNullOrWhiteSpace(account)) |
729 | cfed7823 | Panagiotis Kanavos | client.BaseAddress = GetAccountUrl(account); |
730 | cfed7823 | Panagiotis Kanavos | |
731 | 9c4346c9 | Panagiotis Kanavos | client.Parameters.Clear(); |
732 | 9c4346c9 | Panagiotis Kanavos | client.Head(container + "/" + objectName, 3); |
733 | 9c4346c9 | Panagiotis Kanavos | |
734 | 9c4346c9 | Panagiotis Kanavos | switch (client.StatusCode) |
735 | 9c4346c9 | Panagiotis Kanavos | { |
736 | 9c4346c9 | Panagiotis Kanavos | case HttpStatusCode.OK: |
737 | 9c4346c9 | Panagiotis Kanavos | case HttpStatusCode.NoContent: |
738 | 9c4346c9 | Panagiotis Kanavos | return true; |
739 | 9c4346c9 | Panagiotis Kanavos | case HttpStatusCode.NotFound: |
740 | 9c4346c9 | Panagiotis Kanavos | return false; |
741 | 9c4346c9 | Panagiotis Kanavos | default: |
742 | 9c4346c9 | Panagiotis Kanavos | throw CreateWebException("ObjectExists", client.StatusCode); |
743 | 9c4346c9 | Panagiotis Kanavos | } |
744 | d78cbf09 | Panagiotis Kanavos | } |
745 | 9c4346c9 | Panagiotis Kanavos | |
746 | d78cbf09 | Panagiotis Kanavos | } |
747 | d78cbf09 | Panagiotis Kanavos | |
748 | cfed7823 | Panagiotis Kanavos | public ObjectInfo GetObjectInfo(string account, string container, string objectName) |
749 | d78cbf09 | Panagiotis Kanavos | { |
750 | d78cbf09 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(container)) |
751 | d78cbf09 | Panagiotis Kanavos | throw new ArgumentNullException("container", "The container property can't be empty"); |
752 | d78cbf09 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(objectName)) |
753 | d78cbf09 | Panagiotis Kanavos | throw new ArgumentNullException("objectName", "The objectName property can't be empty"); |
754 | cfed7823 | Panagiotis Kanavos | Contract.EndContractBlock(); |
755 | d78cbf09 | Panagiotis Kanavos | |
756 | 4f6d51d4 | Panagiotis Kanavos | using (ThreadContext.Stacks["Objects"].Push("GetObjectInfo")) |
757 | 5120f3cb | Panagiotis Kanavos | { |
758 | 5120f3cb | Panagiotis Kanavos | |
759 | 5120f3cb | Panagiotis Kanavos | using (var client = new RestClient(_baseClient)) |
760 | 9c4346c9 | Panagiotis Kanavos | { |
761 | 5120f3cb | Panagiotis Kanavos | if (!String.IsNullOrWhiteSpace(account)) |
762 | 5120f3cb | Panagiotis Kanavos | client.BaseAddress = GetAccountUrl(account); |
763 | 5120f3cb | Panagiotis Kanavos | try |
764 | 5120f3cb | Panagiotis Kanavos | { |
765 | 5120f3cb | Panagiotis Kanavos | client.Parameters.Clear(); |
766 | d78cbf09 | Panagiotis Kanavos | |
767 | 5120f3cb | Panagiotis Kanavos | client.Head(container + "/" + objectName, 3); |
768 | d78cbf09 | Panagiotis Kanavos | |
769 | 5120f3cb | Panagiotis Kanavos | if (client.TimedOut) |
770 | 5120f3cb | Panagiotis Kanavos | return ObjectInfo.Empty; |
771 | 9c4346c9 | Panagiotis Kanavos | |
772 | 5120f3cb | Panagiotis Kanavos | switch (client.StatusCode) |
773 | 5120f3cb | Panagiotis Kanavos | { |
774 | 5120f3cb | Panagiotis Kanavos | case HttpStatusCode.OK: |
775 | 5120f3cb | Panagiotis Kanavos | case HttpStatusCode.NoContent: |
776 | 5120f3cb | Panagiotis Kanavos | var keys = client.ResponseHeaders.AllKeys.AsQueryable(); |
777 | c92e02f3 | Panagiotis Kanavos | var tags = client.GetMeta("X-Object-Meta-"); |
778 | 5120f3cb | Panagiotis Kanavos | var extensions = (from key in keys |
779 | 5120f3cb | Panagiotis Kanavos | where key.StartsWith("X-Object-") && !key.StartsWith("X-Object-Meta-") |
780 | 5120f3cb | Panagiotis Kanavos | select new {Name = key, Value = client.ResponseHeaders[key]}) |
781 | 5120f3cb | Panagiotis Kanavos | .ToDictionary(t => t.Name, t => t.Value); |
782 | f0947233 | Panagiotis Kanavos | |
783 | c92e02f3 | Panagiotis Kanavos | var permissions=client.GetHeaderValue("X-Object-Sharing", true); |
784 | aba9e6d9 | Panagiotis Kanavos | |
785 | aba9e6d9 | Panagiotis Kanavos | |
786 | 5120f3cb | Panagiotis Kanavos | var info = new ObjectInfo |
787 | 5120f3cb | Panagiotis Kanavos | { |
788 | 7b0a5fec | Panagiotis Kanavos | Account = account, |
789 | 7b0a5fec | Panagiotis Kanavos | Container = container, |
790 | 5120f3cb | Panagiotis Kanavos | Name = objectName, |
791 | 43dd02a8 | pkanavos | ETag = client.GetHeaderValue("ETag"), |
792 | 43dd02a8 | pkanavos | X_Object_Hash = client.GetHeaderValue("X-Object-Hash"), |
793 | 5120f3cb | Panagiotis Kanavos | Content_Type = client.GetHeaderValue("Content-Type"), |
794 | 52e8e7d9 | Panagiotis Kanavos | Bytes = Convert.ToInt64(client.GetHeaderValue("Content-Length",true)), |
795 | 5120f3cb | Panagiotis Kanavos | Tags = tags, |
796 | 5120f3cb | Panagiotis Kanavos | Last_Modified = client.LastModified, |
797 | aba9e6d9 | Panagiotis Kanavos | Extensions = extensions, |
798 | aba9e6d9 | Panagiotis Kanavos | ContentEncoding=client.GetHeaderValue("Content-Encoding",true), |
799 | aba9e6d9 | Panagiotis Kanavos | ContendDisposition = client.GetHeaderValue("Content-Disposition",true), |
800 | aba9e6d9 | Panagiotis Kanavos | Manifest=client.GetHeaderValue("X-Object-Manifest",true), |
801 | bb7717f5 | pkanavos | PublicUrl=client.GetHeaderValue("X-Object-Public",true), |
802 | bb7717f5 | pkanavos | StorageUri=this.StorageUrl, |
803 | 5120f3cb | Panagiotis Kanavos | }; |
804 | f0947233 | Panagiotis Kanavos | info.SetPermissions(permissions); |
805 | 5120f3cb | Panagiotis Kanavos | return info; |
806 | 5120f3cb | Panagiotis Kanavos | case HttpStatusCode.NotFound: |
807 | 5120f3cb | Panagiotis Kanavos | return ObjectInfo.Empty; |
808 | 5120f3cb | Panagiotis Kanavos | default: |
809 | 5120f3cb | Panagiotis Kanavos | throw new WebException( |
810 | 5120f3cb | Panagiotis Kanavos | String.Format("[FAIL] GetObjectInfo for {0} failed with unexpected status code {1}", |
811 | 5120f3cb | Panagiotis Kanavos | objectName, client.StatusCode)); |
812 | 5120f3cb | Panagiotis Kanavos | } |
813 | 5120f3cb | Panagiotis Kanavos | |
814 | 5120f3cb | Panagiotis Kanavos | } |
815 | 5120f3cb | Panagiotis Kanavos | catch (RetryException) |
816 | 9c4346c9 | Panagiotis Kanavos | { |
817 | 4f6d51d4 | Panagiotis Kanavos | Log.WarnFormat("[RETRY FAIL] GetObjectInfo for {0} failed.",objectName); |
818 | 5120f3cb | Panagiotis Kanavos | return ObjectInfo.Empty; |
819 | 9c4346c9 | Panagiotis Kanavos | } |
820 | 5120f3cb | Panagiotis Kanavos | catch (WebException e) |
821 | 5120f3cb | Panagiotis Kanavos | { |
822 | 5120f3cb | Panagiotis Kanavos | Log.Error( |
823 | 5120f3cb | Panagiotis Kanavos | String.Format("[FAIL] GetObjectInfo for {0} failed with unexpected status code {1}", |
824 | 5120f3cb | Panagiotis Kanavos | objectName, client.StatusCode), e); |
825 | 5120f3cb | Panagiotis Kanavos | throw; |
826 | 5120f3cb | Panagiotis Kanavos | } |
827 | 5120f3cb | Panagiotis Kanavos | } |
828 | d78cbf09 | Panagiotis Kanavos | } |
829 | 9c4346c9 | Panagiotis Kanavos | |
830 | d78cbf09 | Panagiotis Kanavos | } |
831 | d78cbf09 | Panagiotis Kanavos | |
832 | cfed7823 | Panagiotis Kanavos | public void CreateFolder(string account, string container, string folder) |
833 | 10523ad9 | Panagiotis Kanavos | { |
834 | 10523ad9 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(container)) |
835 | 10523ad9 | Panagiotis Kanavos | throw new ArgumentNullException("container", "The container property can't be empty"); |
836 | 10523ad9 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(folder)) |
837 | 10523ad9 | Panagiotis Kanavos | throw new ArgumentNullException("folder", "The folder property can't be empty"); |
838 | cfed7823 | Panagiotis Kanavos | Contract.EndContractBlock(); |
839 | 10523ad9 | Panagiotis Kanavos | |
840 | 10523ad9 | Panagiotis Kanavos | var folderUrl=String.Format("{0}/{1}",container,folder); |
841 | 9c4346c9 | Panagiotis Kanavos | using (var client = new RestClient(_baseClient)) |
842 | 9c4346c9 | Panagiotis Kanavos | { |
843 | cfed7823 | Panagiotis Kanavos | if (!String.IsNullOrWhiteSpace(account)) |
844 | cfed7823 | Panagiotis Kanavos | client.BaseAddress = GetAccountUrl(account); |
845 | cfed7823 | Panagiotis Kanavos | |
846 | 9c4346c9 | Panagiotis Kanavos | client.Parameters.Clear(); |
847 | 9c4346c9 | Panagiotis Kanavos | client.Headers.Add("Content-Type", @"application/directory"); |
848 | 9c4346c9 | Panagiotis Kanavos | client.Headers.Add("Content-Length", "0"); |
849 | 9c4346c9 | Panagiotis Kanavos | client.PutWithRetry(folderUrl, 3); |
850 | 10523ad9 | Panagiotis Kanavos | |
851 | 9c4346c9 | Panagiotis Kanavos | if (client.StatusCode != HttpStatusCode.Created && client.StatusCode != HttpStatusCode.Accepted) |
852 | 9c4346c9 | Panagiotis Kanavos | throw CreateWebException("CreateFolder", client.StatusCode); |
853 | 9c4346c9 | Panagiotis Kanavos | } |
854 | 10523ad9 | Panagiotis Kanavos | } |
855 | 10523ad9 | Panagiotis Kanavos | |
856 | c92e02f3 | Panagiotis Kanavos | |
857 | c92e02f3 | Panagiotis Kanavos | |
858 | cfed7823 | Panagiotis Kanavos | public ContainerInfo GetContainerInfo(string account, string container) |
859 | d78cbf09 | Panagiotis Kanavos | { |
860 | d78cbf09 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(container)) |
861 | d78cbf09 | Panagiotis Kanavos | throw new ArgumentNullException("container", "The container property can't be empty"); |
862 | cfed7823 | Panagiotis Kanavos | Contract.EndContractBlock(); |
863 | cfed7823 | Panagiotis Kanavos | |
864 | 9c4346c9 | Panagiotis Kanavos | using (var client = new RestClient(_baseClient)) |
865 | d78cbf09 | Panagiotis Kanavos | { |
866 | cfed7823 | Panagiotis Kanavos | if (!String.IsNullOrWhiteSpace(account)) |
867 | cfed7823 | Panagiotis Kanavos | client.BaseAddress = GetAccountUrl(account); |
868 | cfed7823 | Panagiotis Kanavos | |
869 | 9c4346c9 | Panagiotis Kanavos | client.Head(container); |
870 | 9c4346c9 | Panagiotis Kanavos | switch (client.StatusCode) |
871 | 9c4346c9 | Panagiotis Kanavos | { |
872 | 5ce54458 | Panagiotis Kanavos | case HttpStatusCode.OK: |
873 | 9c4346c9 | Panagiotis Kanavos | case HttpStatusCode.NoContent: |
874 | c92e02f3 | Panagiotis Kanavos | var tags = client.GetMeta("X-Container-Meta-"); |
875 | c92e02f3 | Panagiotis Kanavos | var policies = client.GetMeta("X-Container-Policy-"); |
876 | 27361404 | Panagiotis Kanavos | |
877 | 9c4346c9 | Panagiotis Kanavos | var containerInfo = new ContainerInfo |
878 | 9c4346c9 | Panagiotis Kanavos | { |
879 | 42800be8 | Panagiotis Kanavos | Account=account, |
880 | 9c4346c9 | Panagiotis Kanavos | Name = container, |
881 | ebc37b0d | pkanavos | StorageUrl=this.StorageUrl.ToString(), |
882 | 9c4346c9 | Panagiotis Kanavos | Count = |
883 | 9c4346c9 | Panagiotis Kanavos | long.Parse(client.GetHeaderValue("X-Container-Object-Count")), |
884 | 5ce54458 | Panagiotis Kanavos | Bytes = long.Parse(client.GetHeaderValue("X-Container-Bytes-Used")), |
885 | 5ce54458 | Panagiotis Kanavos | BlockHash = client.GetHeaderValue("X-Container-Block-Hash"), |
886 | 42800be8 | Panagiotis Kanavos | BlockSize=int.Parse(client.GetHeaderValue("X-Container-Block-Size")), |
887 | 27361404 | Panagiotis Kanavos | Last_Modified=client.LastModified, |
888 | 27361404 | Panagiotis Kanavos | Tags=tags, |
889 | 27361404 | Panagiotis Kanavos | Policies=policies |
890 | 9c4346c9 | Panagiotis Kanavos | }; |
891 | 27361404 | Panagiotis Kanavos | |
892 | 27361404 | Panagiotis Kanavos | |
893 | 9c4346c9 | Panagiotis Kanavos | return containerInfo; |
894 | 9c4346c9 | Panagiotis Kanavos | case HttpStatusCode.NotFound: |
895 | 9c4346c9 | Panagiotis Kanavos | return ContainerInfo.Empty; |
896 | 9c4346c9 | Panagiotis Kanavos | default: |
897 | 9c4346c9 | Panagiotis Kanavos | throw CreateWebException("GetContainerInfo", client.StatusCode); |
898 | 9c4346c9 | Panagiotis Kanavos | } |
899 | d78cbf09 | Panagiotis Kanavos | } |
900 | d78cbf09 | Panagiotis Kanavos | } |
901 | d78cbf09 | Panagiotis Kanavos | |
902 | cfed7823 | Panagiotis Kanavos | public void CreateContainer(string account, string container) |
903 | b12f73e8 | Panagiotis Kanavos | { |
904 | b12f73e8 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(account)) |
905 | b12f73e8 | Panagiotis Kanavos | throw new ArgumentNullException("account"); |
906 | d78cbf09 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(container)) |
907 | b12f73e8 | Panagiotis Kanavos | throw new ArgumentNullException("container"); |
908 | cfed7823 | Panagiotis Kanavos | Contract.EndContractBlock(); |
909 | cfed7823 | Panagiotis Kanavos | |
910 | 9c4346c9 | Panagiotis Kanavos | using (var client = new RestClient(_baseClient)) |
911 | 9c4346c9 | Panagiotis Kanavos | { |
912 | cfed7823 | Panagiotis Kanavos | if (!String.IsNullOrWhiteSpace(account)) |
913 | cfed7823 | Panagiotis Kanavos | client.BaseAddress = GetAccountUrl(account); |
914 | cfed7823 | Panagiotis Kanavos | |
915 | 9c4346c9 | Panagiotis Kanavos | client.PutWithRetry(container, 3); |
916 | 9c4346c9 | Panagiotis Kanavos | var expectedCodes = new[] {HttpStatusCode.Created, HttpStatusCode.Accepted, HttpStatusCode.OK}; |
917 | 9c4346c9 | Panagiotis Kanavos | if (!expectedCodes.Contains(client.StatusCode)) |
918 | 9c4346c9 | Panagiotis Kanavos | throw CreateWebException("CreateContainer", client.StatusCode); |
919 | 9c4346c9 | Panagiotis Kanavos | } |
920 | d78cbf09 | Panagiotis Kanavos | } |
921 | d78cbf09 | Panagiotis Kanavos | |
922 | cfed7823 | Panagiotis Kanavos | public void DeleteContainer(string account, string container) |
923 | 2c053915 | Panagiotis Kanavos | { |
924 | 2c053915 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(container)) |
925 | 2c053915 | Panagiotis Kanavos | throw new ArgumentNullException("container", "The container property can't be empty"); |
926 | cfed7823 | Panagiotis Kanavos | Contract.EndContractBlock(); |
927 | cfed7823 | Panagiotis Kanavos | |
928 | 9c4346c9 | Panagiotis Kanavos | using (var client = new RestClient(_baseClient)) |
929 | 9c4346c9 | Panagiotis Kanavos | { |
930 | cfed7823 | Panagiotis Kanavos | if (!String.IsNullOrWhiteSpace(account)) |
931 | cfed7823 | Panagiotis Kanavos | client.BaseAddress = GetAccountUrl(account); |
932 | cfed7823 | Panagiotis Kanavos | |
933 | 9c4346c9 | Panagiotis Kanavos | client.DeleteWithRetry(container, 3); |
934 | 9c4346c9 | Panagiotis Kanavos | var expectedCodes = new[] {HttpStatusCode.NotFound, HttpStatusCode.NoContent}; |
935 | 9c4346c9 | Panagiotis Kanavos | if (!expectedCodes.Contains(client.StatusCode)) |
936 | 9c4346c9 | Panagiotis Kanavos | throw CreateWebException("DeleteContainer", client.StatusCode); |
937 | 9c4346c9 | Panagiotis Kanavos | } |
938 | 2c053915 | Panagiotis Kanavos | |
939 | 2c053915 | Panagiotis Kanavos | } |
940 | 2c053915 | Panagiotis Kanavos | |
941 | 5bcf6d70 | Panagiotis Kanavos | /// <summary> |
942 | 5bcf6d70 | Panagiotis Kanavos | /// |
943 | 5bcf6d70 | Panagiotis Kanavos | /// </summary> |
944 | cfed7823 | Panagiotis Kanavos | /// <param name="account"></param> |
945 | 5bcf6d70 | Panagiotis Kanavos | /// <param name="container"></param> |
946 | 5bcf6d70 | Panagiotis Kanavos | /// <param name="objectName"></param> |
947 | 283809f3 | Panagiotis Kanavos | /// <param name="fileName"></param> |
948 | 5bcf6d70 | Panagiotis Kanavos | /// <returns></returns> |
949 | 5ce54458 | Panagiotis Kanavos | /// <remarks>This method should have no timeout or a very long one</remarks> |
950 | 5ce54458 | Panagiotis Kanavos | //Asynchronously download the object specified by *objectName* in a specific *container* to |
951 | 5ce54458 | Panagiotis Kanavos | // a local file |
952 | 2341c603 | pkanavos | public async Task GetObject(string account, string container, string objectName, string fileName,CancellationToken cancellationToken) |
953 | d78cbf09 | Panagiotis Kanavos | { |
954 | d78cbf09 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(container)) |
955 | d78cbf09 | Panagiotis Kanavos | throw new ArgumentNullException("container", "The container property can't be empty"); |
956 | d78cbf09 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(objectName)) |
957 | 5ce54458 | Panagiotis Kanavos | throw new ArgumentNullException("objectName", "The objectName property can't be empty"); |
958 | 5ce54458 | Panagiotis Kanavos | Contract.EndContractBlock(); |
959 | 5ce54458 | Panagiotis Kanavos | |
960 | 283809f3 | Panagiotis Kanavos | try |
961 | 283809f3 | Panagiotis Kanavos | { |
962 | 5ce54458 | Panagiotis Kanavos | //WebClient, and by extension RestClient, are not thread-safe. Create a new RestClient |
963 | 5ce54458 | Panagiotis Kanavos | //object to avoid concurrency errors. |
964 | 5ce54458 | Panagiotis Kanavos | // |
965 | 5ce54458 | Panagiotis Kanavos | //Download operations take a long time therefore they have no timeout. |
966 | 2341c603 | pkanavos | using(var client = new RestClient(_baseClient) { Timeout = 0 }) |
967 | 2341c603 | pkanavos | { |
968 | 2341c603 | pkanavos | if (!String.IsNullOrWhiteSpace(account)) |
969 | 2341c603 | pkanavos | client.BaseAddress = GetAccountUrl(account); |
970 | cfed7823 | Panagiotis Kanavos | |
971 | 2341c603 | pkanavos | //The container and objectName are relative names. They are joined with the client's |
972 | 2341c603 | pkanavos | //BaseAddress to create the object's absolute address |
973 | 2341c603 | pkanavos | var builder = client.GetAddressBuilder(container, objectName); |
974 | 2341c603 | pkanavos | var uri = builder.Uri; |
975 | cfed7823 | Panagiotis Kanavos | |
976 | 2341c603 | pkanavos | //Download progress is reported to the Trace log |
977 | 2341c603 | pkanavos | Log.InfoFormat("[GET] START {0}", objectName); |
978 | 2341c603 | pkanavos | client.DownloadProgressChanged += (sender, args) => |
979 | 2341c603 | pkanavos | Log.InfoFormat("[GET PROGRESS] {0} {1}% {2} of {3}", |
980 | 2341c603 | pkanavos | fileName, args.ProgressPercentage, |
981 | 2341c603 | pkanavos | args.BytesReceived, |
982 | 2341c603 | pkanavos | args.TotalBytesToReceive); |
983 | 5ce54458 | Panagiotis Kanavos | |
984 | 2341c603 | pkanavos | |
985 | 2341c603 | pkanavos | //Start downloading the object asynchronously |
986 | 2341c603 | pkanavos | await client.DownloadFileTaskAsync(uri, fileName,cancellationToken); |
987 | 5ce54458 | Panagiotis Kanavos | |
988 | 2341c603 | pkanavos | //Once the download completes |
989 | 2341c603 | pkanavos | //Delete the local client object |
990 | 2341c603 | pkanavos | } |
991 | 2341c603 | pkanavos | //And report failure or completion |
992 | 283809f3 | Panagiotis Kanavos | } |
993 | 283809f3 | Panagiotis Kanavos | catch (Exception exc) |
994 | d78cbf09 | Panagiotis Kanavos | { |
995 | 2341c603 | pkanavos | Log.ErrorFormat("[GET] FAIL {0} with {1}", objectName, exc); |
996 | 283809f3 | Panagiotis Kanavos | throw; |
997 | d78cbf09 | Panagiotis Kanavos | } |
998 | 283809f3 | Panagiotis Kanavos | |
999 | 2341c603 | pkanavos | Log.InfoFormat("[GET] END {0}", objectName); |
1000 | 283809f3 | Panagiotis Kanavos | |
1001 | 283809f3 | Panagiotis Kanavos | |
1002 | d78cbf09 | Panagiotis Kanavos | } |
1003 | d78cbf09 | Panagiotis Kanavos | |
1004 | cfed7823 | Panagiotis Kanavos | public Task<IList<string>> PutHashMap(string account, string container, string objectName, TreeHash hash) |
1005 | 5ce54458 | Panagiotis Kanavos | { |
1006 | 5ce54458 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(container)) |
1007 | 5ce54458 | Panagiotis Kanavos | throw new ArgumentNullException("container"); |
1008 | 5ce54458 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(objectName)) |
1009 | 5ce54458 | Panagiotis Kanavos | throw new ArgumentNullException("objectName"); |
1010 | 5ce54458 | Panagiotis Kanavos | if (hash==null) |
1011 | 5ce54458 | Panagiotis Kanavos | throw new ArgumentNullException("hash"); |
1012 | 5ce54458 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(Token)) |
1013 | 5ce54458 | Panagiotis Kanavos | throw new InvalidOperationException("Invalid Token"); |
1014 | 5ce54458 | Panagiotis Kanavos | if (StorageUrl == null) |
1015 | 5ce54458 | Panagiotis Kanavos | throw new InvalidOperationException("Invalid Storage Url"); |
1016 | 5ce54458 | Panagiotis Kanavos | Contract.EndContractBlock(); |
1017 | cfed7823 | Panagiotis Kanavos | |
1018 | cfed7823 | Panagiotis Kanavos | |
1019 | cfed7823 | Panagiotis Kanavos | //Don't use a timeout because putting the hashmap may be a long process |
1020 | 692ec33b | Panagiotis Kanavos | var client = new RestClient(_baseClient) { Timeout = 0 }; |
1021 | cfed7823 | Panagiotis Kanavos | if (!String.IsNullOrWhiteSpace(account)) |
1022 | cfed7823 | Panagiotis Kanavos | client.BaseAddress = GetAccountUrl(account); |
1023 | cfed7823 | Panagiotis Kanavos | |
1024 | 5ce54458 | Panagiotis Kanavos | //The container and objectName are relative names. They are joined with the client's |
1025 | 5ce54458 | Panagiotis Kanavos | //BaseAddress to create the object's absolute address |
1026 | cfed7823 | Panagiotis Kanavos | var builder = client.GetAddressBuilder(container, objectName); |
1027 | 5ce54458 | Panagiotis Kanavos | builder.Query = "format=json&hashmap"; |
1028 | 5ce54458 | Panagiotis Kanavos | var uri = builder.Uri; |
1029 | 5ce54458 | Panagiotis Kanavos | |
1030 | 5ce54458 | Panagiotis Kanavos | |
1031 | 5ce54458 | Panagiotis Kanavos | //Send the tree hash as Json to the server |
1032 | 5ce54458 | Panagiotis Kanavos | client.Headers[HttpRequestHeader.ContentType] = "application/octet-stream"; |
1033 | 692ec33b | Panagiotis Kanavos | var jsonHash = hash.ToJson(); |
1034 | c945b450 | pkanavos | |
1035 | c945b450 | pkanavos | client.Headers.Add("ETag",hash.MD5); |
1036 | 692ec33b | Panagiotis Kanavos | var uploadTask=client.UploadStringTask(uri, "PUT", jsonHash); |
1037 | 72174cd5 | pkanavos | if (Log.IsDebugEnabled) |
1038 | 72174cd5 | pkanavos | Log.DebugFormat("Hashes:\r\n{0}", jsonHash); |
1039 | 5ce54458 | Panagiotis Kanavos | return uploadTask.ContinueWith(t => |
1040 | 5ce54458 | Panagiotis Kanavos | { |
1041 | a27aa447 | Panagiotis Kanavos | |
1042 | a27aa447 | Panagiotis Kanavos | var empty = (IList<string>)new List<string>(); |
1043 | 5ce54458 | Panagiotis Kanavos | |
1044 | 5ce54458 | Panagiotis Kanavos | |
1045 | 5ce54458 | Panagiotis Kanavos | //The server will respond either with 201-created if all blocks were already on the server |
1046 | a27aa447 | Panagiotis Kanavos | if (client.StatusCode == HttpStatusCode.Created) |
1047 | a27aa447 | Panagiotis Kanavos | { |
1048 | 5ce54458 | Panagiotis Kanavos | //in which case we return an empty hash list |
1049 | a27aa447 | Panagiotis Kanavos | return empty; |
1050 | a27aa447 | Panagiotis Kanavos | } |
1051 | 5ce54458 | Panagiotis Kanavos | //or with a 409-conflict and return the list of missing parts |
1052 | 5ce54458 | Panagiotis Kanavos | //A 409 will cause an exception so we need to check t.IsFaulted to avoid propagating the exception |
1053 | 5ce54458 | Panagiotis Kanavos | if (t.IsFaulted) |
1054 | 5ce54458 | Panagiotis Kanavos | { |
1055 | 5ce54458 | Panagiotis Kanavos | var ex = t.Exception.InnerException; |
1056 | 5ce54458 | Panagiotis Kanavos | var we = ex as WebException; |
1057 | 5ce54458 | Panagiotis Kanavos | var response = we.Response as HttpWebResponse; |
1058 | 5ce54458 | Panagiotis Kanavos | if (response!=null && response.StatusCode==HttpStatusCode.Conflict) |
1059 | 5ce54458 | Panagiotis Kanavos | { |
1060 | 5ce54458 | Panagiotis Kanavos | //In case of 409 the missing parts will be in the response content |
1061 | 5ce54458 | Panagiotis Kanavos | using (var stream = response.GetResponseStream()) |
1062 | ebc37b0d | pkanavos | using(var reader=stream.GetLoggedReader(Log)) |
1063 | 5ce54458 | Panagiotis Kanavos | { |
1064 | d9b1cbeb | Panagiotis Kanavos | //We used to have to cleanup the content before returning it because it contains |
1065 | a27aa447 | Panagiotis Kanavos | //error content after the list of hashes |
1066 | d9b1cbeb | Panagiotis Kanavos | // |
1067 | d9b1cbeb | Panagiotis Kanavos | //As of 30/1/2012, the result is a proper Json array so we don't need to read the content |
1068 | d9b1cbeb | Panagiotis Kanavos | //line by line |
1069 | d9b1cbeb | Panagiotis Kanavos | |
1070 | d9b1cbeb | Panagiotis Kanavos | var serializer = new JsonSerializer(); |
1071 | 739664d2 | pkanavos | serializer.Error += (sender, args) => Log.ErrorFormat("Deserialization error at [{0}] [{1}]", args.ErrorContext.Error, args.ErrorContext.Member); |
1072 | 72174cd5 | pkanavos | var hashes = (List<string>)serializer.Deserialize(reader, typeof(List<string>)); |
1073 | 72174cd5 | pkanavos | return hashes; |
1074 | 5ce54458 | Panagiotis Kanavos | } |
1075 | 4f6d51d4 | Panagiotis Kanavos | } |
1076 | 4f6d51d4 | Panagiotis Kanavos | //Any other status code is unexpected and the exception should be rethrown |
1077 | 72174cd5 | pkanavos | Log.LogError(response); |
1078 | 4f6d51d4 | Panagiotis Kanavos | throw ex; |
1079 | 5ce54458 | Panagiotis Kanavos | |
1080 | 5ce54458 | Panagiotis Kanavos | } |
1081 | d78d765c | pkanavos | |
1082 | 5ce54458 | Panagiotis Kanavos | //Any other status code is unexpected but there was no exception. We can probably continue processing |
1083 | 4f6d51d4 | Panagiotis Kanavos | Log.WarnFormat("Unexcpected status code when putting map: {0} - {1}",client.StatusCode,client.StatusDescription); |
1084 | 4f6d51d4 | Panagiotis Kanavos | |
1085 | a27aa447 | Panagiotis Kanavos | return empty; |
1086 | 5ce54458 | Panagiotis Kanavos | }); |
1087 | 5ce54458 | Panagiotis Kanavos | |
1088 | 5ce54458 | Panagiotis Kanavos | } |
1089 | 5ce54458 | Panagiotis Kanavos | |
1090 | 2341c603 | pkanavos | |
1091 | 2341c603 | pkanavos | public async Task<byte[]> GetBlock(string account, string container, Uri relativeUrl, long start, long? end, CancellationToken cancellationToken) |
1092 | a27aa447 | Panagiotis Kanavos | { |
1093 | a27aa447 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(Token)) |
1094 | a27aa447 | Panagiotis Kanavos | throw new InvalidOperationException("Invalid Token"); |
1095 | a27aa447 | Panagiotis Kanavos | if (StorageUrl == null) |
1096 | a27aa447 | Panagiotis Kanavos | throw new InvalidOperationException("Invalid Storage Url"); |
1097 | a27aa447 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(container)) |
1098 | a27aa447 | Panagiotis Kanavos | throw new ArgumentNullException("container"); |
1099 | 2341c603 | pkanavos | if (relativeUrl == null) |
1100 | a27aa447 | Panagiotis Kanavos | throw new ArgumentNullException("relativeUrl"); |
1101 | 2341c603 | pkanavos | if (end.HasValue && end < 0) |
1102 | a27aa447 | Panagiotis Kanavos | throw new ArgumentOutOfRangeException("end"); |
1103 | 2341c603 | pkanavos | if (start < 0) |
1104 | a27aa447 | Panagiotis Kanavos | throw new ArgumentOutOfRangeException("start"); |
1105 | a27aa447 | Panagiotis Kanavos | Contract.EndContractBlock(); |
1106 | a27aa447 | Panagiotis Kanavos | |
1107 | a27aa447 | Panagiotis Kanavos | //Don't use a timeout because putting the hashmap may be a long process |
1108 | 2341c603 | pkanavos | using (var client = new RestClient(_baseClient) {Timeout = 0, RangeFrom = start, RangeTo = end}) |
1109 | 2341c603 | pkanavos | { |
1110 | 2341c603 | pkanavos | if (!String.IsNullOrWhiteSpace(account)) |
1111 | 2341c603 | pkanavos | client.BaseAddress = GetAccountUrl(account); |
1112 | cfed7823 | Panagiotis Kanavos | |
1113 | 2341c603 | pkanavos | var builder = client.GetAddressBuilder(container, relativeUrl.ToString()); |
1114 | 2341c603 | pkanavos | var uri = builder.Uri; |
1115 | 97edb52f | pkanavos | |
1116 | 97edb52f | pkanavos | client.DownloadProgressChanged += (sender, args) => |
1117 | 97edb52f | pkanavos | Log.DebugFormat("[GET PROGRESS] {0} {1}% {2} of {3}", |
1118 | 97edb52f | pkanavos | uri.Segments.Last(), args.ProgressPercentage, |
1119 | 97edb52f | pkanavos | args.BytesReceived, |
1120 | 97edb52f | pkanavos | args.TotalBytesToReceive); |
1121 | 97edb52f | pkanavos | |
1122 | cfed7823 | Panagiotis Kanavos | |
1123 | 2341c603 | pkanavos | var result = await client.DownloadDataTaskAsync(uri, cancellationToken); |
1124 | 2341c603 | pkanavos | return result; |
1125 | 2341c603 | pkanavos | } |
1126 | a27aa447 | Panagiotis Kanavos | } |
1127 | a27aa447 | Panagiotis Kanavos | |
1128 | a27aa447 | Panagiotis Kanavos | |
1129 | fbe71a05 | pkanavos | public async Task PostBlock(string account, string container, byte[] block, int offset, int count,CancellationToken token) |
1130 | a27aa447 | Panagiotis Kanavos | { |
1131 | a27aa447 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(container)) |
1132 | a27aa447 | Panagiotis Kanavos | throw new ArgumentNullException("container"); |
1133 | a27aa447 | Panagiotis Kanavos | if (block == null) |
1134 | a27aa447 | Panagiotis Kanavos | throw new ArgumentNullException("block"); |
1135 | 0af3141d | Panagiotis Kanavos | if (offset < 0 || offset >= block.Length) |
1136 | 0af3141d | Panagiotis Kanavos | throw new ArgumentOutOfRangeException("offset"); |
1137 | 0af3141d | Panagiotis Kanavos | if (count < 0 || count > block.Length) |
1138 | 0af3141d | Panagiotis Kanavos | throw new ArgumentOutOfRangeException("count"); |
1139 | a27aa447 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(Token)) |
1140 | a27aa447 | Panagiotis Kanavos | throw new InvalidOperationException("Invalid Token"); |
1141 | a27aa447 | Panagiotis Kanavos | if (StorageUrl == null) |
1142 | 0af3141d | Panagiotis Kanavos | throw new InvalidOperationException("Invalid Storage Url"); |
1143 | a27aa447 | Panagiotis Kanavos | Contract.EndContractBlock(); |
1144 | a27aa447 | Panagiotis Kanavos | |
1145 | cfed7823 | Panagiotis Kanavos | |
1146 | 4f6d51d4 | Panagiotis Kanavos | try |
1147 | 4f6d51d4 | Panagiotis Kanavos | { |
1148 | cfed7823 | Panagiotis Kanavos | |
1149 | fbe71a05 | pkanavos | //Don't use a timeout because putting the hashmap may be a long process |
1150 | 4f6d51d4 | Panagiotis Kanavos | using (var client = new RestClient(_baseClient) { Timeout = 0 }) |
1151 | fbe71a05 | pkanavos | { |
1152 | 4f6d51d4 | Panagiotis Kanavos | if (!String.IsNullOrWhiteSpace(account)) |
1153 | 4f6d51d4 | Panagiotis Kanavos | client.BaseAddress = GetAccountUrl(account); |
1154 | 4f6d51d4 | Panagiotis Kanavos | |
1155 | fbe71a05 | pkanavos | token.Register(client.CancelAsync); |
1156 | fbe71a05 | pkanavos | |
1157 | 4f6d51d4 | Panagiotis Kanavos | var builder = client.GetAddressBuilder(container, ""); |
1158 | 4f6d51d4 | Panagiotis Kanavos | //We are doing an update |
1159 | 4f6d51d4 | Panagiotis Kanavos | builder.Query = "update"; |
1160 | 4f6d51d4 | Panagiotis Kanavos | var uri = builder.Uri; |
1161 | a27aa447 | Panagiotis Kanavos | |
1162 | 4f6d51d4 | Panagiotis Kanavos | client.Headers[HttpRequestHeader.ContentType] = "application/octet-stream"; |
1163 | a27aa447 | Panagiotis Kanavos | |
1164 | 4f6d51d4 | Panagiotis Kanavos | Log.InfoFormat("[BLOCK POST] START"); |
1165 | a27aa447 | Panagiotis Kanavos | |
1166 | 4f6d51d4 | Panagiotis Kanavos | client.UploadProgressChanged += (sender, args) => |
1167 | 4f6d51d4 | Panagiotis Kanavos | Log.InfoFormat("[BLOCK POST PROGRESS] {0}% {1} of {2}", |
1168 | 4f6d51d4 | Panagiotis Kanavos | args.ProgressPercentage, args.BytesSent, |
1169 | 4f6d51d4 | Panagiotis Kanavos | args.TotalBytesToSend); |
1170 | 4f6d51d4 | Panagiotis Kanavos | client.UploadFileCompleted += (sender, args) => |
1171 | 4f6d51d4 | Panagiotis Kanavos | Log.InfoFormat("[BLOCK POST PROGRESS] Completed "); |
1172 | a27aa447 | Panagiotis Kanavos | |
1173 | 4f6d51d4 | Panagiotis Kanavos | var buffer = new byte[count]; |
1174 | 4f6d51d4 | Panagiotis Kanavos | Buffer.BlockCopy(block, offset, buffer, 0, count); |
1175 | 4f6d51d4 | Panagiotis Kanavos | //Send the block |
1176 | fbe71a05 | pkanavos | await client.UploadDataTaskAsync(uri, "POST", buffer); |
1177 | 4f6d51d4 | Panagiotis Kanavos | Log.InfoFormat("[BLOCK POST] END"); |
1178 | a64c87c8 | Panagiotis Kanavos | } |
1179 | 4f6d51d4 | Panagiotis Kanavos | } |
1180 | fbe71a05 | pkanavos | catch (TaskCanceledException ) |
1181 | fbe71a05 | pkanavos | { |
1182 | fbe71a05 | pkanavos | Log.Info("Aborting block"); |
1183 | fbe71a05 | pkanavos | throw; |
1184 | fbe71a05 | pkanavos | } |
1185 | 4f6d51d4 | Panagiotis Kanavos | catch (Exception exc) |
1186 | 4f6d51d4 | Panagiotis Kanavos | { |
1187 | fbe71a05 | pkanavos | Log.ErrorFormat("[BLOCK POST] FAIL with \r{0}", exc); |
1188 | 4f6d51d4 | Panagiotis Kanavos | throw; |
1189 | 4f6d51d4 | Panagiotis Kanavos | } |
1190 | a27aa447 | Panagiotis Kanavos | } |
1191 | a27aa447 | Panagiotis Kanavos | |
1192 | 5ce54458 | Panagiotis Kanavos | |
1193 | a0dcfcc9 | Panagiotis Kanavos | public async Task<TreeHash> GetHashMap(string account, string container, string objectName) |
1194 | 5ce54458 | Panagiotis Kanavos | { |
1195 | 5ce54458 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(container)) |
1196 | 5ce54458 | Panagiotis Kanavos | throw new ArgumentNullException("container"); |
1197 | 5ce54458 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(objectName)) |
1198 | 5ce54458 | Panagiotis Kanavos | throw new ArgumentNullException("objectName"); |
1199 | 5ce54458 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(Token)) |
1200 | 5ce54458 | Panagiotis Kanavos | throw new InvalidOperationException("Invalid Token"); |
1201 | 5ce54458 | Panagiotis Kanavos | if (StorageUrl == null) |
1202 | 5ce54458 | Panagiotis Kanavos | throw new InvalidOperationException("Invalid Storage Url"); |
1203 | 5ce54458 | Panagiotis Kanavos | Contract.EndContractBlock(); |
1204 | 5ce54458 | Panagiotis Kanavos | |
1205 | 5ce54458 | Panagiotis Kanavos | try |
1206 | 5ce54458 | Panagiotis Kanavos | { |
1207 | 5ce54458 | Panagiotis Kanavos | //WebClient, and by extension RestClient, are not thread-safe. Create a new RestClient |
1208 | 5ce54458 | Panagiotis Kanavos | //object to avoid concurrency errors. |
1209 | 5ce54458 | Panagiotis Kanavos | // |
1210 | 5ce54458 | Panagiotis Kanavos | //Download operations take a long time therefore they have no timeout. |
1211 | a0dcfcc9 | Panagiotis Kanavos | //TODO: Do they really? this is a hashmap operation, not a download |
1212 | cfed7823 | Panagiotis Kanavos | |
1213 | 5ce54458 | Panagiotis Kanavos | //Start downloading the object asynchronously |
1214 | a0dcfcc9 | Panagiotis Kanavos | using (var client = new RestClient(_baseClient) { Timeout = 0 }) |
1215 | 5ce54458 | Panagiotis Kanavos | { |
1216 | a0dcfcc9 | Panagiotis Kanavos | if (!String.IsNullOrWhiteSpace(account)) |
1217 | a0dcfcc9 | Panagiotis Kanavos | client.BaseAddress = GetAccountUrl(account); |
1218 | a0dcfcc9 | Panagiotis Kanavos | |
1219 | a0dcfcc9 | Panagiotis Kanavos | //The container and objectName are relative names. They are joined with the client's |
1220 | a0dcfcc9 | Panagiotis Kanavos | //BaseAddress to create the object's absolute address |
1221 | a0dcfcc9 | Panagiotis Kanavos | var builder = client.GetAddressBuilder(container, objectName); |
1222 | a0dcfcc9 | Panagiotis Kanavos | builder.Query = "format=json&hashmap"; |
1223 | a0dcfcc9 | Panagiotis Kanavos | var uri = builder.Uri; |
1224 | a0dcfcc9 | Panagiotis Kanavos | |
1225 | a0dcfcc9 | Panagiotis Kanavos | |
1226 | a0dcfcc9 | Panagiotis Kanavos | var json = await client.DownloadStringTaskAsync(uri); |
1227 | 5ce54458 | Panagiotis Kanavos | var treeHash = TreeHash.Parse(json); |
1228 | a0dcfcc9 | Panagiotis Kanavos | Log.InfoFormat("[GET HASH] END {0}", objectName); |
1229 | 5ce54458 | Panagiotis Kanavos | return treeHash; |
1230 | a0dcfcc9 | Panagiotis Kanavos | } |
1231 | 5ce54458 | Panagiotis Kanavos | } |
1232 | 5ce54458 | Panagiotis Kanavos | catch (Exception exc) |
1233 | 5ce54458 | Panagiotis Kanavos | { |
1234 | 5120f3cb | Panagiotis Kanavos | Log.ErrorFormat("[GET HASH] END {0} with {1}", objectName, exc); |
1235 | 5ce54458 | Panagiotis Kanavos | throw; |
1236 | 5ce54458 | Panagiotis Kanavos | } |
1237 | 5ce54458 | Panagiotis Kanavos | |
1238 | 5ce54458 | Panagiotis Kanavos | } |
1239 | 5ce54458 | Panagiotis Kanavos | |
1240 | 5ce54458 | Panagiotis Kanavos | |
1241 | 5bcf6d70 | Panagiotis Kanavos | /// <summary> |
1242 | 5bcf6d70 | Panagiotis Kanavos | /// |
1243 | 5bcf6d70 | Panagiotis Kanavos | /// </summary> |
1244 | cfed7823 | Panagiotis Kanavos | /// <param name="account"></param> |
1245 | 5bcf6d70 | Panagiotis Kanavos | /// <param name="container"></param> |
1246 | 5bcf6d70 | Panagiotis Kanavos | /// <param name="objectName"></param> |
1247 | 5bcf6d70 | Panagiotis Kanavos | /// <param name="fileName"></param> |
1248 | b5061ac8 | Panagiotis Kanavos | /// <param name="hash">Optional hash value for the file. If no hash is provided, the method calculates a new hash</param> |
1249 | 5bcf6d70 | Panagiotis Kanavos | /// <remarks>>This method should have no timeout or a very long one</remarks> |
1250 | 4f6d51d4 | Panagiotis Kanavos | public async Task PutObject(string account, string container, string objectName, string fileName, string hash = null, string contentType = "application/octet-stream") |
1251 | d78cbf09 | Panagiotis Kanavos | { |
1252 | d78cbf09 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(container)) |
1253 | d78cbf09 | Panagiotis Kanavos | throw new ArgumentNullException("container", "The container property can't be empty"); |
1254 | d78cbf09 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(objectName)) |
1255 | d78cbf09 | Panagiotis Kanavos | throw new ArgumentNullException("objectName", "The objectName property can't be empty"); |
1256 | b6c72f62 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(fileName)) |
1257 | b6c72f62 | Panagiotis Kanavos | throw new ArgumentNullException("fileName", "The fileName property can't be empty"); |
1258 | 4f6d51d4 | Panagiotis Kanavos | /* |
1259 | 4f6d51d4 | Panagiotis Kanavos | if (!File.Exists(fileName) && !Directory.Exists(fileName)) |
1260 | 4f6d51d4 | Panagiotis Kanavos | throw new FileNotFoundException("The file or directory does not exist",fileName); |
1261 | 4f6d51d4 | Panagiotis Kanavos | */ |
1262 | b6c72f62 | Panagiotis Kanavos | |
1263 | b5061ac8 | Panagiotis Kanavos | try |
1264 | b5061ac8 | Panagiotis Kanavos | { |
1265 | cfed7823 | Panagiotis Kanavos | |
1266 | 4f6d51d4 | Panagiotis Kanavos | using (var client = new RestClient(_baseClient) { Timeout = 0 }) |
1267 | 0eea575a | Panagiotis Kanavos | { |
1268 | 4f6d51d4 | Panagiotis Kanavos | if (!String.IsNullOrWhiteSpace(account)) |
1269 | 4f6d51d4 | Panagiotis Kanavos | client.BaseAddress = GetAccountUrl(account); |
1270 | bfc13ed8 | Panagiotis Kanavos | |
1271 | 4f6d51d4 | Panagiotis Kanavos | var builder = client.GetAddressBuilder(container, objectName); |
1272 | 4f6d51d4 | Panagiotis Kanavos | var uri = builder.Uri; |
1273 | 0eea575a | Panagiotis Kanavos | |
1274 | 4f6d51d4 | Panagiotis Kanavos | string etag = hash ?? CalculateHash(fileName); |
1275 | 4f6d51d4 | Panagiotis Kanavos | |
1276 | 4f6d51d4 | Panagiotis Kanavos | client.Headers.Add("Content-Type", contentType); |
1277 | 4f6d51d4 | Panagiotis Kanavos | client.Headers.Add("ETag", etag); |
1278 | 4f6d51d4 | Panagiotis Kanavos | |
1279 | 4f6d51d4 | Panagiotis Kanavos | |
1280 | 4f6d51d4 | Panagiotis Kanavos | Log.InfoFormat("[PUT] START {0}", objectName); |
1281 | 4f6d51d4 | Panagiotis Kanavos | client.UploadProgressChanged += (sender, args) => |
1282 | 4f6d51d4 | Panagiotis Kanavos | { |
1283 | 4f6d51d4 | Panagiotis Kanavos | using (ThreadContext.Stacks["PUT"].Push("Progress")) |
1284 | 4f6d51d4 | Panagiotis Kanavos | { |
1285 | 4f6d51d4 | Panagiotis Kanavos | Log.InfoFormat("{0} {1}% {2} of {3}", fileName, |
1286 | 4f6d51d4 | Panagiotis Kanavos | args.ProgressPercentage, |
1287 | 4f6d51d4 | Panagiotis Kanavos | args.BytesSent, args.TotalBytesToSend); |
1288 | 4f6d51d4 | Panagiotis Kanavos | } |
1289 | 4f6d51d4 | Panagiotis Kanavos | }; |
1290 | 4f6d51d4 | Panagiotis Kanavos | |
1291 | 4f6d51d4 | Panagiotis Kanavos | client.UploadFileCompleted += (sender, args) => |
1292 | 4f6d51d4 | Panagiotis Kanavos | { |
1293 | 4f6d51d4 | Panagiotis Kanavos | using (ThreadContext.Stacks["PUT"].Push("Progress")) |
1294 | 4f6d51d4 | Panagiotis Kanavos | { |
1295 | 4f6d51d4 | Panagiotis Kanavos | Log.InfoFormat("Completed {0}", fileName); |
1296 | 4f6d51d4 | Panagiotis Kanavos | } |
1297 | 2341c603 | pkanavos | }; |
1298 | 4f6d51d4 | Panagiotis Kanavos | if (contentType=="application/directory") |
1299 | 4f6d51d4 | Panagiotis Kanavos | await client.UploadDataTaskAsync(uri, "PUT", new byte[0]); |
1300 | 4f6d51d4 | Panagiotis Kanavos | else |
1301 | 4f6d51d4 | Panagiotis Kanavos | await client.UploadFileTaskAsync(uri, "PUT", fileName); |
1302 | 4f6d51d4 | Panagiotis Kanavos | } |
1303 | 4f6d51d4 | Panagiotis Kanavos | |
1304 | 4f6d51d4 | Panagiotis Kanavos | Log.InfoFormat("[PUT] END {0}", objectName); |
1305 | b5061ac8 | Panagiotis Kanavos | } |
1306 | b5061ac8 | Panagiotis Kanavos | catch (Exception exc) |
1307 | b5061ac8 | Panagiotis Kanavos | { |
1308 | 5120f3cb | Panagiotis Kanavos | Log.ErrorFormat("[PUT] END {0} with {1}", objectName, exc); |
1309 | b5061ac8 | Panagiotis Kanavos | throw; |
1310 | b5061ac8 | Panagiotis Kanavos | } |
1311 | b5061ac8 | Panagiotis Kanavos | |
1312 | 0eea575a | Panagiotis Kanavos | } |
1313 | 0050438e | Panagiotis Kanavos | |
1314 | 4d301e8e | Panagiotis Kanavos | |
1315 | b6c72f62 | Panagiotis Kanavos | private static string CalculateHash(string fileName) |
1316 | d78cbf09 | Panagiotis Kanavos | { |
1317 | 0bd56b7c | Panagiotis Kanavos | Contract.Requires(!String.IsNullOrWhiteSpace(fileName)); |
1318 | 0bd56b7c | Panagiotis Kanavos | Contract.EndContractBlock(); |
1319 | 0bd56b7c | Panagiotis Kanavos | |
1320 | d78cbf09 | Panagiotis Kanavos | string hash; |
1321 | d78cbf09 | Panagiotis Kanavos | using (var hasher = MD5.Create()) |
1322 | b6c72f62 | Panagiotis Kanavos | using(var stream=File.OpenRead(fileName)) |
1323 | d78cbf09 | Panagiotis Kanavos | { |
1324 | d78cbf09 | Panagiotis Kanavos | var hashBuilder=new StringBuilder(); |
1325 | b6c72f62 | Panagiotis Kanavos | foreach (byte b in hasher.ComputeHash(stream)) |
1326 | d78cbf09 | Panagiotis Kanavos | hashBuilder.Append(b.ToString("x2").ToLower()); |
1327 | d78cbf09 | Panagiotis Kanavos | hash = hashBuilder.ToString(); |
1328 | d78cbf09 | Panagiotis Kanavos | } |
1329 | d78cbf09 | Panagiotis Kanavos | return hash; |
1330 | d78cbf09 | Panagiotis Kanavos | } |
1331 | 0bd56b7c | Panagiotis Kanavos | |
1332 | cfed7823 | Panagiotis Kanavos | public void MoveObject(string account, string sourceContainer, string oldObjectName, string targetContainer, string newObjectName) |
1333 | d78cbf09 | Panagiotis Kanavos | { |
1334 | 3c43ec9b | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(sourceContainer)) |
1335 | 3c43ec9b | Panagiotis Kanavos | throw new ArgumentNullException("sourceContainer", "The container property can't be empty"); |
1336 | d78cbf09 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(oldObjectName)) |
1337 | d78cbf09 | Panagiotis Kanavos | throw new ArgumentNullException("oldObjectName", "The oldObjectName property can't be empty"); |
1338 | 3c43ec9b | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(targetContainer)) |
1339 | 3c43ec9b | Panagiotis Kanavos | throw new ArgumentNullException("targetContainer", "The container property can't be empty"); |
1340 | d78cbf09 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(newObjectName)) |
1341 | d78cbf09 | Panagiotis Kanavos | throw new ArgumentNullException("newObjectName", "The newObjectName property can't be empty"); |
1342 | cfed7823 | Panagiotis Kanavos | Contract.EndContractBlock(); |
1343 | d78cbf09 | Panagiotis Kanavos | |
1344 | 3c43ec9b | Panagiotis Kanavos | var targetUrl = targetContainer + "/" + newObjectName; |
1345 | 3c43ec9b | Panagiotis Kanavos | var sourceUrl = String.Format("/{0}/{1}", sourceContainer, oldObjectName); |
1346 | 3c43ec9b | Panagiotis Kanavos | |
1347 | 9c4346c9 | Panagiotis Kanavos | using (var client = new RestClient(_baseClient)) |
1348 | d78cbf09 | Panagiotis Kanavos | { |
1349 | cfed7823 | Panagiotis Kanavos | if (!String.IsNullOrWhiteSpace(account)) |
1350 | cfed7823 | Panagiotis Kanavos | client.BaseAddress = GetAccountUrl(account); |
1351 | cfed7823 | Panagiotis Kanavos | |
1352 | 0af3141d | Panagiotis Kanavos | client.Headers.Add("X-Move-From", sourceUrl); |
1353 | 9c4346c9 | Panagiotis Kanavos | client.PutWithRetry(targetUrl, 3); |
1354 | 9c4346c9 | Panagiotis Kanavos | |
1355 | 9c4346c9 | Panagiotis Kanavos | var expectedCodes = new[] {HttpStatusCode.OK, HttpStatusCode.NoContent, HttpStatusCode.Created}; |
1356 | 0af3141d | Panagiotis Kanavos | if (!expectedCodes.Contains(client.StatusCode)) |
1357 | 9c4346c9 | Panagiotis Kanavos | throw CreateWebException("MoveObject", client.StatusCode); |
1358 | 9c4346c9 | Panagiotis Kanavos | } |
1359 | d78cbf09 | Panagiotis Kanavos | } |
1360 | d78cbf09 | Panagiotis Kanavos | |
1361 | c53aa229 | Panagiotis Kanavos | public void DeleteObject(string account, string sourceContainer, string objectName) |
1362 | 0af3141d | Panagiotis Kanavos | { |
1363 | 0af3141d | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(sourceContainer)) |
1364 | 0af3141d | Panagiotis Kanavos | throw new ArgumentNullException("sourceContainer", "The container property can't be empty"); |
1365 | 0af3141d | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(objectName)) |
1366 | 0af3141d | Panagiotis Kanavos | throw new ArgumentNullException("objectName", "The oldObjectName property can't be empty"); |
1367 | cfed7823 | Panagiotis Kanavos | Contract.EndContractBlock(); |
1368 | 0af3141d | Panagiotis Kanavos | |
1369 | c53aa229 | Panagiotis Kanavos | var targetUrl = FolderConstants.TrashContainer + "/" + objectName; |
1370 | 0af3141d | Panagiotis Kanavos | var sourceUrl = String.Format("/{0}/{1}", sourceContainer, objectName); |
1371 | 0af3141d | Panagiotis Kanavos | |
1372 | 0af3141d | Panagiotis Kanavos | using (var client = new RestClient(_baseClient)) |
1373 | 0af3141d | Panagiotis Kanavos | { |
1374 | cfed7823 | Panagiotis Kanavos | if (!String.IsNullOrWhiteSpace(account)) |
1375 | cfed7823 | Panagiotis Kanavos | client.BaseAddress = GetAccountUrl(account); |
1376 | cfed7823 | Panagiotis Kanavos | |
1377 | 0af3141d | Panagiotis Kanavos | client.Headers.Add("X-Move-From", sourceUrl); |
1378 | c53aa229 | Panagiotis Kanavos | client.AllowedStatusCodes.Add(HttpStatusCode.NotFound); |
1379 | 6f03d6e1 | Panagiotis Kanavos | Log.InfoFormat("[TRASH] [{0}] to [{1}]",sourceUrl,targetUrl); |
1380 | 0af3141d | Panagiotis Kanavos | client.PutWithRetry(targetUrl, 3); |
1381 | 0af3141d | Panagiotis Kanavos | |
1382 | 0af3141d | Panagiotis Kanavos | var expectedCodes = new[] {HttpStatusCode.OK, HttpStatusCode.NoContent, HttpStatusCode.Created,HttpStatusCode.NotFound}; |
1383 | 0af3141d | Panagiotis Kanavos | if (!expectedCodes.Contains(client.StatusCode)) |
1384 | 0af3141d | Panagiotis Kanavos | throw CreateWebException("DeleteObject", client.StatusCode); |
1385 | 0af3141d | Panagiotis Kanavos | } |
1386 | 0af3141d | Panagiotis Kanavos | } |
1387 | 0af3141d | Panagiotis Kanavos | |
1388 | 4d301e8e | Panagiotis Kanavos | |
1389 | 3c43ec9b | Panagiotis Kanavos | private static WebException CreateWebException(string operation, HttpStatusCode statusCode) |
1390 | 3c43ec9b | Panagiotis Kanavos | { |
1391 | 3c43ec9b | Panagiotis Kanavos | return new WebException(String.Format("{0} failed with unexpected status code {1}", operation, statusCode)); |
1392 | 3c43ec9b | Panagiotis Kanavos | } |
1393 | 3c43ec9b | Panagiotis Kanavos | |
1394 | 93dc3a84 | Panagiotis Kanavos | |
1395 | 93dc3a84 | Panagiotis Kanavos | /* |
1396 | 93dc3a84 | Panagiotis Kanavos | public IEnumerable<ObjectInfo> ListDirectories(ContainerInfo container) |
1397 | 93dc3a84 | Panagiotis Kanavos | { |
1398 | 93dc3a84 | Panagiotis Kanavos | var directories=this.ListObjects(container.Account, container.Name, "/"); |
1399 | 93dc3a84 | Panagiotis Kanavos | } |
1400 | 93dc3a84 | Panagiotis Kanavos | */ |
1401 | 8f918cb0 | pkanavos | |
1402 | 8f918cb0 | pkanavos | public bool CanUpload(string account, ObjectInfo cloudFile) |
1403 | 8f918cb0 | pkanavos | { |
1404 | 8f918cb0 | pkanavos | Contract.Requires(!String.IsNullOrWhiteSpace(account)); |
1405 | 8f918cb0 | pkanavos | Contract.Requires(cloudFile!=null); |
1406 | 8f918cb0 | pkanavos | |
1407 | 8f918cb0 | pkanavos | using (var client = new RestClient(_baseClient)) |
1408 | 8f918cb0 | pkanavos | { |
1409 | 8f918cb0 | pkanavos | if (!String.IsNullOrWhiteSpace(account)) |
1410 | 8f918cb0 | pkanavos | client.BaseAddress = GetAccountUrl(account); |
1411 | 8f918cb0 | pkanavos | |
1412 | 8f918cb0 | pkanavos | |
1413 | 8f918cb0 | pkanavos | var parts = cloudFile.Name.Split('/'); |
1414 | 8f918cb0 | pkanavos | var folder = String.Join("/", parts,0,parts.Length-1); |
1415 | 8f918cb0 | pkanavos | |
1416 | 8f918cb0 | pkanavos | var fileUrl=String.Format("{0}/{1}/{2}.pithos.ignore",cloudFile.Container,folder,Guid.NewGuid()); |
1417 | 8f918cb0 | pkanavos | |
1418 | 8f918cb0 | pkanavos | client.Parameters.Clear(); |
1419 | 8f918cb0 | pkanavos | try |
1420 | 8f918cb0 | pkanavos | { |
1421 | 8f918cb0 | pkanavos | client.PutWithRetry(fileUrl, 3, @"application/octet-stream"); |
1422 | 8f918cb0 | pkanavos | |
1423 | 8f918cb0 | pkanavos | var expectedCodes = new[] { HttpStatusCode.OK, HttpStatusCode.NoContent, HttpStatusCode.Created}; |
1424 | 69588a95 | pkanavos | var result=(expectedCodes.Contains(client.StatusCode)); |
1425 | 69588a95 | pkanavos | DeleteObject(account, cloudFile.Container, fileUrl); |
1426 | 69588a95 | pkanavos | return result; |
1427 | 8f918cb0 | pkanavos | } |
1428 | 8f918cb0 | pkanavos | catch |
1429 | 8f918cb0 | pkanavos | { |
1430 | 8f918cb0 | pkanavos | return false; |
1431 | 8f918cb0 | pkanavos | } |
1432 | 8f918cb0 | pkanavos | } |
1433 | 8f918cb0 | pkanavos | } |
1434 | d78cbf09 | Panagiotis Kanavos | } |
1435 | cfed7823 | Panagiotis Kanavos | |
1436 | cfed7823 | Panagiotis Kanavos | public class ShareAccountInfo |
1437 | cfed7823 | Panagiotis Kanavos | { |
1438 | cfed7823 | Panagiotis Kanavos | public DateTime? last_modified { get; set; } |
1439 | cfed7823 | Panagiotis Kanavos | public string name { get; set; } |
1440 | cfed7823 | Panagiotis Kanavos | } |
1441 | d78cbf09 | Panagiotis Kanavos | } |