Skip to content

Commit 1018f4c

Browse files
committed
Feat: Searching keys through prefix in GetBucket API.
Add keyStartWith specification in ResourceSpecificationFactory to support this feature in this commit. Signed-off-by: RichardLea <chigix@zoho.com>
1 parent c6e53f6 commit 1018f4c

File tree

5 files changed

+146
-23
lines changed

5 files changed

+146
-23
lines changed

src/main/java/com/chigix/resserver/domain/model/resource/ResourceRepository.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,8 @@ public interface ResourceRepository {
2727
* @param specification
2828
* @param limit
2929
* @return
30-
* @throws NoSuchBucket
3130
*/
32-
Iterator<Resource> fetchResources(Specification<Resource> specification, int limit) throws NoSuchBucket;
31+
Iterator<Resource> fetchResources(Specification<Resource> specification, int limit);
3332

3433
void removeResource(Resource resource) throws NoSuchKey, NoSuchBucket;
3534

src/main/java/com/chigix/resserver/domain/model/resource/SpecificationFactory.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,6 @@ public interface SpecificationFactory {
3232
SubresourceSpecification subresourceInfo(AmassedResource parent,
3333
BigInteger range_start, BigInteger range_end,
3434
String index_in_parent);
35+
36+
<T extends Specification<Resource>> T keyStartWith(String prefix);
3537
}

src/main/java/com/chigix/resserver/endpoint/GetBucket/ResourceListHandler.java

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package com.chigix.resserver.endpoint.GetBucket;
22

33
import com.chigix.resserver.config.ApplicationContext;
4+
import com.chigix.resserver.domain.Specification;
45
import com.chigix.resserver.domain.error.InvalidArgument;
56
import com.chigix.resserver.domain.model.bucket.Bucket;
67
import com.chigix.resserver.domain.model.resource.Resource;
7-
import com.chigix.resserver.domain.error.NoSuchBucket;
88
import com.chigix.resserver.domain.model.resource.SpecificationFactory;
99
import com.chigix.resserver.interfaces.handling.http.HttpHeaderNames;
1010
import com.chigix.resserver.interfaces.handling.http.HttpHeaderUtil;
@@ -62,7 +62,6 @@ public ResourceListHandler() {
6262
/**
6363
* Response bucket objects list.
6464
*
65-
* @TODO Support searching key under a specified bucket.
6665
* @TODO ONLY SUPPORT standard storage class.
6766
*
6867
* @param ctx
@@ -121,26 +120,19 @@ public int read() throws IOException {
121120
throw e;
122121
}
123122
}
124-
final Iterator<Resource> resources;
125-
try {
126-
if (listCtx.continuationToken == null) {
127-
resources = application.getEntityManager()
128-
.getResourceRepository()
129-
.fetchResources(
130-
resourceSpecifications.bucketIs(route_ctx.getTargetBucket()),
131-
listCtx.maxKeys + 1);
132-
} else {
133-
resources = application.getEntityManager()
134-
.getResourceRepository()
135-
.fetchResources(
136-
resourceSpecifications.bucketIs(route_ctx.getTargetBucket())
137-
.and(resourceSpecifications.continuateFrom(listCtx.nextContinuationToken)),
138-
listCtx.maxKeys + 1);
139-
}
140-
} catch (NoSuchBucket ex) {
141-
setStream(new ClosedInputStream());
142-
return super.read();
123+
Specification<Resource> resourceSpecs = resourceSpecifications
124+
.bucketIs(route_ctx.getTargetBucket())
125+
.and(resourceSpecifications.keyStartWith(listCtx.prefix));
126+
if (listCtx.continuationToken != null) {
127+
resourceSpecs.and(resourceSpecifications
128+
.continuateFrom(listCtx.nextContinuationToken));
143129
}
130+
final Iterator<Resource> resources;
131+
resources = application.getEntityManager()
132+
.getResourceRepository()
133+
.fetchResources(
134+
resourceSpecs,
135+
listCtx.maxKeys + 1);
144136
setStream(new IteratorInputStream<Resource>(resources) {
145137
@Override
146138
protected InputStream inputStreamProvider(Resource item) throws NoSuchElementException {

src/main/java/com/chigix/resserver/mybatis/specification/ResourceSpecification.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,20 @@ public SubresourceSpecification subresourceInfo(AmassedResource parent, BigInteg
8484
return spec;
8585
}
8686

87+
@Override
88+
public QueryCriteriaSpecification<Resource, ResourceExample.Criteria>
89+
keyStartWith(final String prefix) {
90+
return new QueryCriteriaSpecification<Resource, ResourceExample.Criteria>() {
91+
@Override
92+
public ResourceExample.Criteria appendCriteria(ResourceExample.Criteria criteria) {
93+
if (prefix == null || prefix.length() < 1) {
94+
return criteria;
95+
}
96+
return criteria.andKeyLike(prefix + "%");
97+
}
98+
};
99+
}
100+
87101
public static class byParentResource implements IndexOfParentOffset {
88102

89103
private final AmassedResource parentResource;
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
> GET /?fetch-owner=true&list-type=2&max-keys=1000 HTTP/1.1
2+
> Host: oos-for-learning.s3-ap-northeast-1.amazonaws.com
3+
> Authorization: AWS4-HMAC-SHA256 ####
4+
> X-Amz-Content-Sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
5+
> X-Amz-Date: 20180102T153955Z
6+
> User-Agent: Minio (windows; amd64) minio-go/2.0.2 mc/2016-12-09T18:23:19Z
7+
> Expect: 100-continue
8+
> Accept: */*
9+
10+
< HTTP/1.1 200 OK
11+
< x-amz-id-2: 2B0xtwp0RYp6PzSf032XyBu6gePSRw5SYnsD2175jlCZkCKvQ0irbPwjC/feGCc+numIyxoJUGE=
12+
< x-amz-request-id: D95325A5704281A2
13+
< Date: Tue, 02 Jan 2018 15:40:10 GMT
14+
< x-amz-bucket-region: ap-northeast-1
15+
< Content-Type: application/xml
16+
< Transfer-Encoding: chunked
17+
< Connection: close
18+
< Server: AmazonS3
19+
20+
<?xml version="1.0" encoding="UTF-8"?>
21+
<ListBucketResult
22+
xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
23+
<Name>oos-for-learning</Name>
24+
<Prefix></Prefix>
25+
<KeyCount>8</KeyCount>
26+
<MaxKeys>1000</MaxKeys>
27+
<IsTruncated>false</IsTruncated>
28+
<Contents>
29+
<Key>Gatebox - Virtual Home Robot [PV]_english.mp4</Key>
30+
<LastModified>2017-12-04T12:10:48.000Z</LastModified>
31+
<ETag>&quot;f4b9861d73b47f3d81bb7ca73892adf6&quot;</ETag>
32+
<Size>6157050</Size>
33+
<Owner>
34+
<ID>####</ID>
35+
<DisplayName>chigix</DisplayName>
36+
</Owner>
37+
<StorageClass>STANDARD</StorageClass>
38+
</Contents>
39+
<Contents>
40+
<Key>bankai/</Key>
41+
<LastModified>2017-01-01T14:23:32.000Z</LastModified>
42+
<ETag>&quot;d41d8cd98f00b204e9800998ecf8427e&quot;</ETag>
43+
<Size>0</Size>
44+
<Owner>
45+
<ID>####</ID>
46+
<DisplayName>chigix</DisplayName>
47+
</Owner>
48+
<StorageClass>STANDARD</StorageClass>
49+
</Contents>
50+
<Contents>
51+
<Key>bankai/Gatebox - Virtual Home Robot [PV]_english.mp4</Key>
52+
<LastModified>2018-01-02T15:39:38.000Z</LastModified>
53+
<ETag>&quot;f4b9861d73b47f3d81bb7ca73892adf6&quot;</ETag>
54+
<Size>6157050</Size>
55+
<Owner>
56+
<ID>e0455b7089090a533ff84adf12e4d26b1bec51a6e1b203301749b1e640895b59</ID>
57+
<DisplayName>chigix</DisplayName>
58+
</Owner>
59+
<StorageClass>STANDARD</StorageClass>
60+
</Contents>
61+
<Contents>
62+
<Key>build.log</Key>
63+
<LastModified>2017-01-12T09:25:14.000Z</LastModified>
64+
<ETag>&quot;bee9cd71554a137502ad2054d90c5e13&quot;</ETag>
65+
<Size>62312</Size>
66+
<Owner>
67+
<ID>####</ID>
68+
<DisplayName>chigix</DisplayName>
69+
</Owner>
70+
<StorageClass>STANDARD</StorageClass>
71+
</Contents>
72+
<Contents>
73+
<Key>new-empty.log</Key>
74+
<LastModified>2017-08-18T15:59:56.000Z</LastModified>
75+
<ETag>&quot;d41d8cd98f00b204e9800998ecf8427e&quot;</ETag>
76+
<Size>0</Size>
77+
<Owner>
78+
<ID>####</ID>
79+
<DisplayName>chigix</DisplayName>
80+
</Owner>
81+
<StorageClass>STANDARD</StorageClass>
82+
</Contents>
83+
<Contents>
84+
<Key>new-folder/</Key>
85+
<LastModified>2017-08-18T16:04:18.000Z</LastModified>
86+
<ETag>&quot;d41d8cd98f00b204e9800998ecf8427e&quot;</ETag>
87+
<Size>0</Size>
88+
<Owner>
89+
<ID>####</ID>
90+
<DisplayName>chigix</DisplayName>
91+
</Owner>
92+
<StorageClass>STANDARD</StorageClass>
93+
</Contents>
94+
<Contents>
95+
<Key>p086-090.pdf</Key>
96+
<LastModified>2016-12-20T16:44:41.000Z</LastModified>
97+
<ETag>&quot;994f096f47480a2fd8e3d066536951f8&quot;</ETag>
98+
<Size>6583194</Size>
99+
<Owner>
100+
<ID>####</ID>
101+
<DisplayName>chigix</DisplayName>
102+
</Owner>
103+
<StorageClass>STANDARD</StorageClass>
104+
</Contents>
105+
<Contents>
106+
<Key>video.mp4</Key>
107+
<LastModified>2017-02-11T14:58:01.000Z</LastModified>
108+
<ETag>&quot;92a4a34286e2cec4091bdbcbb7a5c2c4&quot;</ETag>
109+
<Size>3885299</Size>
110+
<Owner>
111+
<ID>####</ID>
112+
<DisplayName>chigix</DisplayName>
113+
</Owner>
114+
<StorageClass>STANDARD</StorageClass>
115+
</Contents>
116+
</ListBucketResult>

0 commit comments

Comments
 (0)