Skip to content
This repository was archived by the owner on Mar 15, 2024. It is now read-only.

Commit 3053cb4

Browse files
committed
Support use of a standard MongoDB connection string; deprecate non-standard connection string format
1 parent 4f0f809 commit 3053cb4

File tree

4 files changed

+102
-38
lines changed

4 files changed

+102
-38
lines changed

README.md

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,30 @@ Maven:
2929
</dependency>
3030
```
3131

32-
Next, obtain an instance of the `BlobStore`.
32+
Next, obtain an instance of the `BlobStore` using a
33+
[standard MongoDB connection string](http://docs.mongodb.org/manual/reference/connection-string/):
3334

3435
```java
3536
Properties overrides = new Properties();
36-
overrides.setProperty(Constants.PROPERTY_ENDPOINT, "gridfs://my_mongo_server:27017");
37+
overrides.setProperty(Constants.PROPERTY_ENDPOINT, "mongodb://my_mongo_server:27017/?maxPoolSize=50");
3738
BlobStoreContext context = ContextBuilder.newBuilder("gridfs").overrides(overrides)
3839
.buildView(BlobStoreContext.class);
3940
BlobStore blobStore = context.getBlobStore();
4041
```
4142

43+
You can also use a non-standard connection string (deprecated):
44+
45+
```java
46+
overrides.setProperty(Constants.PROPERTY_ENDPOINT, "gridfs://my_mongo_server:27017");
47+
```
48+
49+
To use a replica set when using a non-standard connection string, specify additional members as a comma or
50+
semicolon-separated list, like this:
51+
52+
```java
53+
overrides.setProperty(Constants.PROPERTY_ENDPOINT, "gridfs://node1:27017;node2:27017;node3:27017");
54+
```
55+
4256
Then, use the blob store to put/get blobs. The container is in the format **DB**[/**BUCKET**], where **DB** is the
4357
name of the database and **BUCKET** is the optional name of the GridFS bucket (which defaults to `fs`).
4458

@@ -54,9 +68,3 @@ Finally, close the context to allow it to properly clean up.
5468
```java
5569
context.close();
5670
```
57-
58-
To use a replica set, specify additional members as a comma or semicolon-separated list, like this:
59-
60-
```java
61-
overrides.setProperty(Constants.PROPERTY_ENDPOINT, "gridfs://node1:27017;node2:27017;node3:27017");
62-
```
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
package com.commercehub.jclouds.gridfs.blobstore;
22

33
class Constants {
4+
5+
/**
6+
* @deprecated Use a <a href="http://docs.mongodb.org/manual/reference/connection-string/">standard MongoDB
7+
* connection string</a> instead.
8+
*/
9+
@Deprecated
410
static final String GRIDFS_URI_SCHEME = "gridfs";
11+
512
}

src/main/java/com/commercehub/jclouds/gridfs/blobstore/GridFSBlobStore.java

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
11
package com.commercehub.jclouds.gridfs.blobstore;
22

33
import com.google.common.base.Supplier;
4-
import com.mongodb.BasicDBObject;
5-
import com.mongodb.DBObject;
6-
import com.mongodb.MongoClient;
7-
import com.mongodb.MongoClientOptions;
8-
import com.mongodb.MongoCredential;
9-
import com.mongodb.ServerAddress;
4+
import com.mongodb.*;
105
import com.mongodb.gridfs.GridFS;
116
import com.mongodb.gridfs.GridFSDBFile;
127
import com.mongodb.gridfs.GridFSInputFile;
@@ -32,10 +27,10 @@
3227

3328
import javax.inject.Inject;
3429
import java.net.UnknownHostException;
35-
import java.util.ArrayList;
3630
import java.util.List;
3731
import java.util.Set;
3832

33+
import static com.commercehub.jclouds.gridfs.blobstore.Constants.GRIDFS_URI_SCHEME;
3934
import static com.commercehub.jclouds.gridfs.blobstore.Util.parseGridFSIdentifier;
4035
import static com.commercehub.jclouds.gridfs.blobstore.Util.parseServerAddresses;
4136
import static com.google.common.base.Preconditions.checkNotNull;
@@ -60,15 +55,18 @@ protected GridFSBlobStore(ProviderMetadata providerMetadata, BlobStoreContext co
6055
this.dbFileToBlobMetadata = dbFileToBlobMetadata;
6156
this.locations = checkNotNull(locations, "locations");
6257

63-
List<ServerAddress> addresses = parseServerAddresses(providerMetadata.getEndpoint());
64-
List<MongoCredential> credentials = new ArrayList<>(); // TODO support credentials
65-
MongoClientOptions options = MongoClientOptions.builder().build(); // TODO support options configuration
66-
if (addresses.size() > 1) {
67-
this.mongo = new MongoClient(addresses, credentials, options);
58+
String endpoint = providerMetadata.getEndpoint();
59+
if (endpoint.startsWith(GRIDFS_URI_SCHEME)) {
60+
List<ServerAddress> addresses = parseServerAddresses(providerMetadata.getEndpoint());
61+
if (addresses.size() > 1) {
62+
this.mongo = new MongoClient(addresses);
63+
} else {
64+
// If only one address, assume we want single-node mode.
65+
// You should always use multiple seeds with a replica set.
66+
this.mongo = new MongoClient(addresses.get(0));
67+
}
6868
} else {
69-
// If only one address, assume we want single-node mode.
70-
// You should always use multiple seeds with a replica set.
71-
this.mongo = new MongoClient(addresses.get(0), credentials, options);
69+
this.mongo = new MongoClient(new MongoClientURI(endpoint));
7270
}
7371
}
7472

src/test/groovy/com/commercehub/jclouds/gridfs/blobstore/GridFSBlobStoreSpec.groovy

Lines changed: 66 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ import spock.lang.Specification
1818
import static com.commercehub.jclouds.gridfs.blobstore.Constants.GRIDFS_URI_SCHEME
1919

2020
class GridFSBlobStoreSpec extends Specification {
21+
private static final HOST = "localhost"
22+
private static final PORT = 27017
23+
private static final GRIDFS_ENDPOINT = "${GRIDFS_URI_SCHEME}://${HOST}:${PORT}"
24+
private static final STANDARD_CONNECTION_STRING = "mongodb://${HOST}:${PORT}"
2125
private static final DB_NAME = this.simpleName
2226
private static final BUCKET = "bk1"
2327
private static final CONTAINER = "${DB_NAME}/${BUCKET}"
@@ -28,36 +32,53 @@ class GridFSBlobStoreSpec extends Specification {
2832

2933
@Shared
3034
private Mongo mongo
31-
@Shared
35+
3236
private BlobStoreContext context
33-
@Shared
3437
private BlobStore blobStore
3538

3639
def setupSpec() {
37-
String host = "localhost"
38-
int port = 27017
39-
mongo = new MongoClient(host, port)
40+
mongo = new MongoClient(HOST, PORT)
4041
mongo.getDB(DB_NAME).dropDatabase()
41-
// TODO: use embedded mongo
42-
def overrides = new Properties()
43-
overrides.setProperty(Constants.PROPERTY_ENDPOINT, "${GRIDFS_URI_SCHEME}://${host}:${port}");
44-
context = ContextBuilder.newBuilder("gridfs")
45-
.overrides(overrides)
46-
.buildView(BlobStoreContext)
47-
blobStore = context.getBlobStore()
4842
}
4943

5044
def cleanupSpec() {
51-
if (context) {
52-
context.close()
53-
}
5445
if (mongo) {
5546
mongo.getDB(DB_NAME).dropDatabase()
5647
mongo.close()
5748
}
5849
}
5950

51+
def cleanup() {
52+
if (context) {
53+
context.close()
54+
}
55+
}
56+
57+
private void initBlobStore(String endpoint) {
58+
// TODO: use embedded mongo
59+
def overrides = new Properties()
60+
overrides.setProperty(Constants.PROPERTY_ENDPOINT, endpoint);
61+
context = ContextBuilder.newBuilder("gridfs")
62+
.overrides(overrides)
63+
.buildView(BlobStoreContext)
64+
blobStore = context.getBlobStore()
65+
}
66+
67+
private void initBlobStore() {
68+
initBlobStore(STANDARD_CONNECTION_STRING)
69+
}
70+
71+
def "can create blobStore with 'gridfs://' endpoint"() {
72+
initBlobStore(GRIDFS_ENDPOINT)
73+
}
74+
75+
def "can create blobStore with standard connection string endpoint"() {
76+
initBlobStore(STANDARD_CONNECTION_STRING)
77+
}
78+
6079
def "can create and delete containers without create container options"() {
80+
initBlobStore()
81+
6182
assert !blobStore.containerExists(CONTAINER)
6283

6384
expect:
@@ -69,6 +90,8 @@ class GridFSBlobStoreSpec extends Specification {
6990
}
7091

7192
def "can create and delete containers with NONE create container options"() {
93+
initBlobStore()
94+
7295
assert !blobStore.containerExists(CONTAINER)
7396

7497
expect:
@@ -80,6 +103,8 @@ class GridFSBlobStoreSpec extends Specification {
80103
}
81104

82105
def "doesn't allow creating containers with public read"() {
106+
initBlobStore()
107+
83108
when:
84109
blobStore.createContainerInLocation(null, CONTAINER, CreateContainerOptions.Builder.publicRead())
85110

@@ -89,6 +114,8 @@ class GridFSBlobStoreSpec extends Specification {
89114
}
90115

91116
def "can create and delete blobs without put options"() {
117+
initBlobStore()
118+
92119
assert !blobStore.blobExists(CONTAINER, BLOB_NAME)
93120
// TODO: test put when container doesn't exist
94121
// TODO: test remove when container doesn't exist
@@ -108,6 +135,8 @@ class GridFSBlobStoreSpec extends Specification {
108135
}
109136

110137
def "can create and delete blobs with multipart put options"() {
138+
initBlobStore()
139+
111140
assert !blobStore.blobExists(CONTAINER, BLOB_NAME)
112141

113142
expect:
@@ -123,6 +152,8 @@ class GridFSBlobStoreSpec extends Specification {
123152
}
124153

125154
def "doesn't allow put with null payload"() {
155+
initBlobStore()
156+
126157
when:
127158
blobStore.putBlob(CONTAINER, blobStore.blobBuilder(BLOB_NAME).build())
128159

@@ -131,6 +162,8 @@ class GridFSBlobStoreSpec extends Specification {
131162
}
132163

133164
def "doesn't allow put with non-multipart"() {
165+
initBlobStore()
166+
134167
when:
135168
def payload = blobStore.blobBuilder(BLOB_NAME).payload(PAYLOAD).build()
136169
blobStore.putBlob(CONTAINER, payload, PutOptions.Builder.multipart(false))
@@ -141,6 +174,8 @@ class GridFSBlobStoreSpec extends Specification {
141174
}
142175

143176
def "get from non-existent container throws exception"() {
177+
initBlobStore()
178+
144179
when:
145180
blobStore.getBlob("containerDoesNotExist", "blobDoesNotExist")
146181

@@ -149,11 +184,15 @@ class GridFSBlobStoreSpec extends Specification {
149184
}
150185

151186
def "get non-existent blob returns null"() {
187+
initBlobStore()
188+
152189
expect:
153190
blobStore.getBlob(CONTAINER, "blobDoesNotExist") == null
154191
}
155192

156193
def "can retrieve blob without get options"() {
194+
initBlobStore()
195+
157196
when:
158197
def payload = blobStore.blobBuilder(BLOB_NAME).payload(PAYLOAD).contentType(CONTENT_TYPE)
159198
.userMetadata([user: "joe", type: "profilePicture"]).build()
@@ -200,6 +239,8 @@ class GridFSBlobStoreSpec extends Specification {
200239
}
201240

202241
def "get options not supported"() {
242+
initBlobStore()
243+
203244
when:
204245
blobStore.getBlob(CONTAINER, BLOB_NAME, GetOptions.Builder.ifETagDoesntMatch(PAYLOAD_MD5))
205246

@@ -232,6 +273,8 @@ class GridFSBlobStoreSpec extends Specification {
232273
}
233274

234275
def "list not supported"() {
276+
initBlobStore()
277+
235278
when:
236279
blobStore.list()
237280
then:
@@ -249,6 +292,8 @@ class GridFSBlobStoreSpec extends Specification {
249292
}
250293

251294
def "clearContainer not supported"() {
295+
initBlobStore()
296+
252297
when:
253298
blobStore.clearContainer(CONTAINER)
254299
then:
@@ -261,6 +306,8 @@ class GridFSBlobStoreSpec extends Specification {
261306
}
262307

263308
def "directory operations not supported"() {
309+
initBlobStore()
310+
264311
when:
265312
blobStore.createDirectory(CONTAINER, "myDirectory")
266313
then:
@@ -278,13 +325,17 @@ class GridFSBlobStoreSpec extends Specification {
278325
}
279326

280327
def "blobMetadata not supported"() {
328+
initBlobStore()
329+
281330
when:
282331
blobStore.blobMetadata(CONTAINER, BLOB_NAME)
283332
then:
284333
thrown(UnsupportedOperationException)
285334
}
286335

287336
def "countBlobs not supported"() {
337+
initBlobStore()
338+
288339
when:
289340
blobStore.countBlobs(CONTAINER)
290341
then:

0 commit comments

Comments
 (0)