Skip to content

Commit af17114

Browse files
aozarovmziccard
authored andcommitted
initial work on functional blob/bucket
1 parent 3739a1a commit af17114

6 files changed

Lines changed: 539 additions & 134 deletions

File tree

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
/*
2+
*
3+
* * Copyright 2015 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version
4+
* 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may
5+
* obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless
6+
* required by applicable law or agreed to in writing, software * distributed under the License is
7+
* distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
8+
* or implied. * See the License for the specific language governing permissions and * limitations
9+
* under the License.
10+
*/
11+
12+
package com.google.gcloud.storage;
13+
14+
import static com.google.common.base.Preconditions.checkArgument;
15+
import static com.google.common.base.Preconditions.checkNotNull;
16+
import static com.google.gcloud.storage.Blob.BlobSourceOption.convert;
17+
18+
import com.google.common.collect.ImmutableList;
19+
import com.google.common.collect.Iterables;
20+
import com.google.gcloud.spi.StorageRpc;
21+
import com.google.gcloud.storage.Storage.BlobTargetOption;
22+
import com.google.gcloud.storage.Storage.CopyRequest;
23+
import com.google.gcloud.storage.Storage.SignUrlOption;
24+
25+
import java.net.URL;
26+
import java.util.Objects;
27+
28+
29+
/**
30+
* A Google cloud storage object.
31+
*/
32+
public final class Blob {
33+
34+
private final Storage storage;
35+
private BlobInfo info;
36+
37+
public static class BlobSourceOption extends Option {
38+
39+
private static final long serialVersionUID = 214616862061934846L;
40+
41+
private BlobSourceOption(StorageRpc.Option rpcOption) {
42+
super(rpcOption, null);
43+
}
44+
45+
private Storage.BlobSourceOption convert(BlobInfo blobInfo) {
46+
switch (rpcOption()) {
47+
case IF_GENERATION_MATCH:
48+
return Storage.BlobSourceOption.generationMatch(blobInfo.generation());
49+
case IF_GENERATION_NOT_MATCH:
50+
return Storage.BlobSourceOption.generationNotMatch(blobInfo.generation());
51+
case IF_METAGENERATION_MATCH:
52+
return Storage.BlobSourceOption.metagenerationMatch(blobInfo.metageneration());
53+
case IF_METAGENERATION_NOT_MATCH:
54+
return Storage.BlobSourceOption.metagenerationNotMatch(blobInfo.metageneration());
55+
default:
56+
throw new AssertionError("Unexpected enum value");
57+
}
58+
}
59+
60+
public static BlobSourceOption generationMatch() {
61+
return new BlobSourceOption(StorageRpc.Option.IF_GENERATION_MATCH);
62+
}
63+
64+
public static BlobSourceOption generationNotMatch() {
65+
return new BlobSourceOption(StorageRpc.Option.IF_GENERATION_NOT_MATCH);
66+
}
67+
68+
public static BlobSourceOption metagenerationMatch() {
69+
return new BlobSourceOption(StorageRpc.Option.IF_METAGENERATION_MATCH);
70+
}
71+
72+
public static BlobSourceOption metagenerationNotMatch() {
73+
return new BlobSourceOption(StorageRpc.Option.IF_METAGENERATION_NOT_MATCH);
74+
}
75+
76+
static Storage.BlobSourceOption[] convert(BlobInfo blobInfo, BlobSourceOption... options) {
77+
Storage.BlobSourceOption[] convertedOptions = new Storage.BlobSourceOption[options.length];
78+
int index = 0;
79+
for (BlobSourceOption option : options) {
80+
convertedOptions[index++] = option.convert(blobInfo);
81+
}
82+
return convertedOptions;
83+
}
84+
}
85+
86+
public Blob(Storage storage, BlobInfo info) {
87+
this.storage = checkNotNull(storage);
88+
this.info = checkNotNull(info);
89+
}
90+
91+
public BlobInfo info() {
92+
return info;
93+
}
94+
95+
/**
96+
* Returns true if this blob exists.
97+
*
98+
* @throws StorageException upon failure
99+
*/
100+
public boolean exists() {
101+
return storage.get(info.bucket(), info.name()) != null;
102+
}
103+
104+
/**
105+
* Returns the blob's content.
106+
*
107+
* @throws StorageException upon failure
108+
*/
109+
public byte[] content(Storage.BlobSourceOption... options) {
110+
return storage.readAllBytes(info.bucket(), info.name(), options);
111+
}
112+
113+
/**
114+
* Updates the blob's information. Bucket or blob's name cannot be changed by this method. If you
115+
* want to rename the blob or move it to a different bucket use the {@link #copyTo} and
116+
* {@link #delete} operations.
117+
*
118+
* @throws StorageException upon failure
119+
*/
120+
public void update(BlobInfo blobInfo, BlobTargetOption... options) {
121+
checkArgument(Objects.equals(blobInfo.bucket(), info.bucket()), "Bucket name must match");
122+
checkArgument(Objects.equals(blobInfo.name(), info.name()), "Blob name must match");
123+
info = storage.update(blobInfo, options);
124+
}
125+
126+
/**
127+
* Deletes this blob.
128+
*
129+
* @return true if bucket was deleted
130+
* @throws StorageException upon failure
131+
*/
132+
public boolean delete(BlobSourceOption... options) {
133+
return storage.delete(info.bucket(), info.name(), convert(info, options));
134+
}
135+
136+
/**
137+
* Send a copy request.
138+
*
139+
* @return the copied blob.
140+
* @throws StorageException upon failure
141+
*/
142+
public Blob copyTo(BlobInfo target, BlobSourceOption... options) {
143+
return copyTo(target, ImmutableList.copyOf(options), ImmutableList.<BlobTargetOption>of());
144+
}
145+
146+
/**
147+
* Send a copy request.
148+
*
149+
* @return the copied blob.
150+
* @throws StorageException upon failure
151+
*/
152+
public Blob copyTo(BlobInfo target, Iterable<BlobSourceOption> sourceOptions,
153+
Iterable<BlobTargetOption> targetOptions) {
154+
CopyRequest copyRequest =
155+
CopyRequest.builder().source(info.bucket(), info.name())
156+
.sourceOptions(convert(info, Iterables.toArray(sourceOptions, BlobSourceOption.class)))
157+
.target(target).targetOptions(targetOptions).build();
158+
return new Blob(storage, storage.copy(copyRequest));
159+
}
160+
161+
/**
162+
* Returns a channel for reading this blob's content.
163+
*
164+
* @throws StorageException upon failure
165+
*/
166+
public BlobReadChannel reader(BlobSourceOption... options) {
167+
return storage.reader(info.bucket(), info.name(), convert(info, options));
168+
}
169+
170+
/**
171+
* Returns a channel for writing to this blob.
172+
*
173+
* @throws StorageException upon failure
174+
*/
175+
public BlobWriteChannel writer(BlobTargetOption... options) {
176+
return storage.writer(info, options);
177+
}
178+
179+
/**
180+
* Generates a signed URL for this blob. If you want to allow access to for a fixed amount of time
181+
* for this blob, you can use this method to generate a URL that is only valid within a certain
182+
* time period. This is particularly useful if you don't want publicly accessible blobs, but don't
183+
* want to require users to explicitly log in.
184+
*
185+
* @param expirationTimeInSeconds the signed URL expiration (using epoch time)
186+
* @see <a href="https://cloud.google.com/storage/docs/access-control#Signed-URLs">Signed-URLs</a>
187+
*/
188+
public URL signUrl(long expirationTimeInSeconds, SignUrlOption... options) {
189+
return storage.signUrl(info, expirationTimeInSeconds, options);
190+
}
191+
192+
public Storage storage() {
193+
return storage;
194+
}
195+
}

gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobInfo.java

Lines changed: 24 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
11
/*
2-
* Copyright 2015 Google Inc. All Rights Reserved.
32
*
4-
* Licensed under the Apache License, Version 2.0 (the "License");
5-
* you may not use this file except in compliance with the License.
6-
* You may obtain a copy of the License at
7-
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
9-
*
10-
* Unless required by applicable law or agreed to in writing, software
11-
* distributed under the License is distributed on an "AS IS" BASIS,
12-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
* See the License for the specific language governing permissions and
14-
* limitations under the License.
3+
* * Copyright 2015 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version
4+
* 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may
5+
* obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless
6+
* required by applicable law or agreed to in writing, software * distributed under the License is
7+
* distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
8+
* or implied. * See the License for the specific language governing permissions and * limitations
9+
* under the License.
1510
*/
1611

1712
package com.google.gcloud.storage;
@@ -37,30 +32,28 @@
3732
import java.util.Objects;
3833

3934
/**
40-
* A Google Storage object.
35+
* Google Storage object metadata.
4136
*
42-
* @see <a href="https://cloud.google.com/storage/docs/concepts-techniques#concepts">Concepts and Terminology</a>
37+
* @see <a href="https://cloud.google.com/storage/docs/concepts-techniques#concepts">Concepts and
38+
* Terminology</a>
4339
*/
4440
public final class BlobInfo implements Serializable {
4541

46-
private static final long serialVersionUID = 2228487739943277159L;
47-
4842
static final Function<StorageObject, BlobInfo> FROM_PB_FUNCTION =
4943
new Function<StorageObject, BlobInfo>() {
5044
@Override
5145
public BlobInfo apply(StorageObject pb) {
5246
return BlobInfo.fromPb(pb);
5347
}
5448
};
55-
5649
static final Function<BlobInfo, StorageObject> TO_PB_FUNCTION =
5750
new Function<BlobInfo, StorageObject>() {
5851
@Override
5952
public StorageObject apply(BlobInfo blobInfo) {
6053
return blobInfo.toPb();
6154
}
6255
};
63-
56+
private static final long serialVersionUID = 2228487739943277159L;
6457
private final String bucket;
6558
private final String id;
6659
private final String name;
@@ -378,29 +371,14 @@ public String toString() {
378371
.toString();
379372
}
380373

381-
public static BlobInfo of(String bucket, String name) {
382-
return builder(bucket, name).build();
383-
}
384-
385-
public static Builder builder(BucketInfo bucketInfo, String name) {
386-
return builder(bucketInfo.name(), name);
387-
}
388-
389-
public static Builder builder(String bucket, String name) {
390-
return new Builder().bucket(bucket).name(name);
391-
}
392-
393374
@Override
394375
public int hashCode() {
395376
return Objects.hash(bucket, name);
396377
}
397378

398379
@Override
399380
public boolean equals(Object obj) {
400-
if (!(obj instanceof BlobInfo)) {
401-
return false;
402-
}
403-
return Objects.equals(toPb(), ((BlobInfo) obj).toPb());
381+
return obj instanceof BlobInfo && Objects.equals(toPb(), ((BlobInfo) obj).toPb());
404382
}
405383

406384
StorageObject toPb() {
@@ -445,6 +423,18 @@ public ObjectAccessControl apply(Acl acl) {
445423
return storageObject;
446424
}
447425

426+
public static BlobInfo of(String bucket, String name) {
427+
return builder(bucket, name).build();
428+
}
429+
430+
public static Builder builder(BucketInfo bucketInfo, String name) {
431+
return builder(bucketInfo.name(), name);
432+
}
433+
434+
public static Builder builder(String bucket, String name) {
435+
return new Builder().bucket(bucket).name(name);
436+
}
437+
448438
static BlobInfo fromPb(StorageObject storageObject) {
449439
Builder builder = new Builder()
450440
.bucket(storageObject.getBucket())
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
*
3+
* * Copyright 2015 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version
4+
* 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may
5+
* obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless
6+
* required by applicable law or agreed to in writing, software * distributed under the License is
7+
* distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
8+
* or implied. * See the License for the specific language governing permissions and * limitations
9+
* under the License.
10+
*/
11+
12+
package com.google.gcloud.storage;
13+
14+
import static com.google.common.base.Preconditions.checkArgument;
15+
import static com.google.common.base.Preconditions.checkNotNull;
16+
17+
import com.google.gcloud.storage.Storage.BlobSourceOption;
18+
import com.google.gcloud.storage.Storage.BucketSourceOption;
19+
import com.google.gcloud.storage.Storage.BucketTargetOption;
20+
21+
import java.util.List;
22+
import java.util.Objects;
23+
24+
/**
25+
* A Google cloud storage bucket.
26+
*/
27+
public final class Bucket {
28+
29+
private final Storage storage;
30+
private BucketInfo info;
31+
32+
public Bucket(Storage storage, BucketInfo info) {
33+
this.storage = checkNotNull(storage);
34+
this.info = checkNotNull(info);
35+
}
36+
37+
/**
38+
* Returns true if this bucket exists.
39+
*
40+
* @throws StorageException upon failure
41+
*/
42+
public boolean exists() {
43+
return storage.get(info.name()) != null;
44+
}
45+
46+
/**
47+
* Update the bucket's information. Bucket's name cannot be changed.
48+
*
49+
* @throws StorageException upon failure
50+
*/
51+
public void update(BucketInfo bucketInfo, BucketTargetOption... options) {
52+
checkArgument(Objects.equals(bucketInfo.name(), info.name()), "Bucket name must match");
53+
info = storage.update(bucketInfo, options);
54+
}
55+
56+
/**
57+
* Delete this bucket.
58+
*
59+
* @return true if bucket was deleted
60+
* @throws StorageException upon failure
61+
*/
62+
public boolean delete(BucketSourceOption... options) {
63+
return storage.delete(info.name(), options);
64+
}
65+
66+
public ListResult<BlobInfo> list(Storage.BlobListOption... options) {
67+
return storage.list(info.name(), options);
68+
}
69+
70+
public BlobInfo get(String blob, BlobSourceOption... options) {
71+
return null;
72+
}
73+
74+
public List<Blob> get(String... blob) {
75+
// todo
76+
return null;
77+
}
78+
79+
/*
80+
* BlobInfo create(BlobInfo blobInfo, byte[] content, BlobTargetOption... options) {
81+
*
82+
* }
83+
*/
84+
85+
86+
public Storage storage() {
87+
return storage;
88+
}
89+
}

0 commit comments

Comments
 (0)