Skip to content

Commit f489047

Browse files
authored
Merge pull request #232 from qiniu/features/support-object-lifecycle
support object lifecycle
2 parents 7bdebe4 + dc95957 commit f489047

File tree

2 files changed

+184
-1
lines changed

2 files changed

+184
-1
lines changed

src/Qiniu/Storage/BucketManager.cs

Lines changed: 114 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using Qiniu.Util;
55
using System.Collections.Generic;
66
using System.Collections.Specialized;
7+
using System.Linq;
78

89
namespace Qiniu.Storage
910
{
@@ -633,7 +634,7 @@ public ListResult ListFiles(string bucket, string prefix, string marker, int lim
633634
}
634635

635636
/// <summary>
636-
/// 更新文件生命周期
637+
/// 更新文件删除生命周期
637638
/// </summary>
638639
/// <param name="bucket">空间名称</param>
639640
/// <param name="key">文件key</param>
@@ -670,6 +671,81 @@ public HttpResult DeleteAfterDays(string bucket, string key, int deleteAfterDays
670671
return result;
671672
}
672673

674+
public HttpResult SetObjectLifecycle(
675+
string bucket,
676+
string key,
677+
int toIaAfterDays = 0,
678+
int toArchiveAfterDays = 0,
679+
int toDeepArchiveAfterDays = 0,
680+
int deleteAfterDays = 0
681+
)
682+
{
683+
return SetObjectLifecycle(
684+
bucket,
685+
key,
686+
null,
687+
toIaAfterDays,
688+
toArchiveAfterDays,
689+
toDeepArchiveAfterDays,
690+
deleteAfterDays
691+
);
692+
}
693+
694+
/// <summary>
695+
/// 更新文件生命周期
696+
/// </summary>
697+
/// <param name="bucket">空间名称</param>
698+
/// <param name="key">文件key</param>
699+
/// <param name="cond">匹配条件,只有条件匹配才会设置成功,目前支持:hash、mime、fsize、putTime</param>
700+
/// <param name="toIaAfterDays">多少天后将文件转为低频存储,设置为 -1 表示取消已设置的转低频存储的生命周期规则,0 表示不修改转低频生命周期规则。</param>
701+
/// <param name="toArchiveAfterDays">多少天后将文件转为归档存储,设置为 -1 表示取消已设置的转归档存储的生命周期规则,0 表示不修改转归档生命周期规则。</param>
702+
/// <param name="toDeepArchiveAfterDays">多少天后将文件转为深度归档存储,设置为 -1 表示取消已设置的转深度归档存储的生命周期规则,0 表示不修改转深度归档生命周期规则。</param>
703+
/// <param name="deleteAfterDays">多少天后将文件删除,设置为 -1 表示取消已设置的删除存储的生命周期规则,0 表示不修改删除存储的生命周期规则。</param>
704+
/// <returns>状态码为200时表示OK</returns>
705+
public HttpResult SetObjectLifecycle(
706+
string bucket,
707+
string key,
708+
Dictionary<string, string> cond = null,
709+
int toIaAfterDays = 0,
710+
int toArchiveAfterDays = 0,
711+
int toDeepArchiveAfterDays = 0,
712+
int deleteAfterDays = 0
713+
)
714+
{
715+
HttpResult result = new HttpResult();
716+
717+
try
718+
{
719+
string updateUrl = string.Format("{0}{1}", this.config.RsHost(this.mac.AccessKey, bucket),
720+
SetObjectLifecycleOp(bucket, key, cond, toIaAfterDays, toArchiveAfterDays, toDeepArchiveAfterDays, deleteAfterDays));
721+
StringDictionary headers = new StringDictionary
722+
{
723+
{"Content-Type", ContentType.WWW_FORM_URLENC}
724+
};
725+
string token = auth.CreateManageTokenV2("POST", updateUrl, headers);
726+
result = httpManager.Post(updateUrl, headers, token);
727+
}
728+
catch (QiniuException ex)
729+
{
730+
StringBuilder sb = new StringBuilder();
731+
sb.AppendFormat("[{0}] [setObjectLifecycle] Error: ", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff"));
732+
Exception e = ex;
733+
while (e != null)
734+
{
735+
sb.Append(e.Message + " ");
736+
e = e.InnerException;
737+
}
738+
sb.AppendLine();
739+
740+
result.Code = ex.HttpResult.Code;
741+
result.RefCode = ex.HttpResult.Code;
742+
result.Text = ex.HttpResult.Text;
743+
result.RefText += sb.ToString();
744+
}
745+
746+
return result;
747+
}
748+
673749
/// <summary>
674750
/// 生成stat操作字符串
675751
/// </summary>
@@ -835,5 +911,42 @@ public string DeleteAfterDaysOp(string bucket, string key, int deleteAfterDays)
835911
Base64.UrlSafeBase64Encode(bucket, key), deleteAfterDays);
836912
}
837913

914+
/// <summary>
915+
/// 生成 setObjectLifecycle 操作字符串
916+
/// </summary>
917+
/// <param name="bucket">空间名称</param>
918+
/// <param name="key">文件key</param>
919+
/// <param name="cond">匹配条件,只有条件匹配才会设置成功,目前支持:hash、mime、fsize、putTime</param>
920+
/// <param name="toIaAfterDays">多少天后将文件转为低频存储,设置为 -1 表示取消已设置的转低频存储的生命周期规则,0 表示不修改转低频生命周期规则。</param>
921+
/// <param name="toArchiveAfterDays">多少天后将文件转为归档存储,设置为 -1 表示取消已设置的转归档存储的生命周期规则,0 表示不修改转归档生命周期规则。</param>
922+
/// <param name="toDeepArchiveAfterDays">多少天后将文件转为深度归档存储,设置为 -1 表示取消已设置的转深度归档存储的生命周期规则,0 表示不修改转深度归档生命周期规则。</param>
923+
/// <param name="deleteAfterDays">多少天后将文件删除,设置为 -1 表示取消已设置的删除存储的生命周期规则,0 表示不修改删除存储的生命周期规则。</param>
924+
/// <returns>updateLifecycle操作字符串</returns>
925+
public string SetObjectLifecycleOp(
926+
string bucket,
927+
string key,
928+
Dictionary<string, string> cond = null,
929+
int toIaAfterDays = 0,
930+
int toArchiveAfterDays = 0,
931+
int toDeepArchiveAfterDays = 0,
932+
int deleteAfterDays = 0
933+
)
934+
{
935+
string entry = Base64.UrlSafeBase64Encode(bucket, key);
936+
string result = string.Format(
937+
"/lifecycle/{0}/toIAAfterDays/{1}/toArchiveAfterDays/{2}/toDeepArchiveAfterDays/{3}/deleteAfterDays/{4}",
938+
entry, toIaAfterDays, toArchiveAfterDays, toDeepArchiveAfterDays, deleteAfterDays);
939+
940+
if (cond != null)
941+
{
942+
string query = string.Join("&",
943+
cond.Keys.Select(k => k + "=" + cond[k]));
944+
945+
result += "/cond/" + Base64.UrlSafeBase64Encode(query);
946+
}
947+
Console.WriteLine(result);
948+
949+
return result;
950+
}
838951
}
839952
}

src/QiniuTests/Storage/BucketManagerTests.cs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,76 @@ public void DeleteAfterDaysTest()
195195
Console.WriteLine(expireRet.ToString());
196196
}
197197

198+
[Test]
199+
public void SetObjectLifecycleTest()
200+
{
201+
Config config = new Config();
202+
config.Zone = Zone.ZONE_CN_East;
203+
Mac mac = new Mac(AccessKey, SecretKey);
204+
BucketManager bucketManager = new BucketManager(mac, config);
205+
string newKey = "qiniu-to-set-object-lifecycle.png";
206+
HttpResult copyRet = bucketManager.Copy(Bucket, "qiniu.png", Bucket, newKey, true);
207+
if (copyRet.Code != (int)HttpCode.OK)
208+
{
209+
Assert.Fail("copy error: " + copyRet.ToString());
210+
}
211+
Console.WriteLine(copyRet.ToString());
212+
HttpResult ret = bucketManager.SetObjectLifecycle(
213+
Bucket,
214+
newKey,
215+
10,
216+
20,
217+
30,
218+
40);
219+
if (ret.Code != (int)HttpCode.OK)
220+
{
221+
Assert.Fail("deleteAfterDays error: " + ret.ToString());
222+
}
223+
Console.WriteLine(ret.ToString());
224+
}
225+
226+
[Test]
227+
public void SetObjectLifecycleCondTest()
228+
{
229+
Config config = new Config();
230+
config.Zone = Zone.ZONE_CN_East;
231+
Mac mac = new Mac(AccessKey, SecretKey);
232+
BucketManager bucketManager = new BucketManager(mac, config);
233+
string newKey = "qiniu-to-set-object-lifecycle-cond.png";
234+
235+
HttpResult copyRet = bucketManager.Copy(Bucket, "qiniu.png", Bucket, newKey, true);
236+
if (copyRet.Code != (int)HttpCode.OK)
237+
{
238+
Assert.Fail("copy error: " + copyRet.ToString());
239+
}
240+
Console.WriteLine(copyRet.ToString());
241+
242+
StatResult statRet = bucketManager.Stat(Bucket, newKey);
243+
if (statRet.Code != (int)HttpCode.OK)
244+
{
245+
Assert.Fail("copy error: " + statRet.ToString());
246+
}
247+
248+
249+
HttpResult ret = bucketManager.SetObjectLifecycle(
250+
Bucket,
251+
newKey,
252+
new Dictionary<string, string>
253+
{
254+
{ "hash", statRet.Result.Hash },
255+
{ "fsize", statRet.Result.Fsize.ToString() }
256+
},
257+
10,
258+
20,
259+
30,
260+
40);
261+
if (ret.Code != (int)HttpCode.OK)
262+
{
263+
Assert.Fail("deleteAfterDays error: " + ret.ToString());
264+
}
265+
Console.WriteLine(ret.ToString());
266+
}
267+
198268
[Test]
199269
public void PrefetchTest()
200270
{

0 commit comments

Comments
 (0)