Skip to content

Commit 2c2f9b8

Browse files
committed
Update Persistor to use new utils so that it supports mongo types
Signed-off-by: John Oliver <[email protected]>
1 parent a15017c commit 2c2f9b8

File tree

9 files changed

+342
-113
lines changed

9 files changed

+342
-113
lines changed

README.md

+5-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ The mongo-persistor module takes the following configuration:
2626
"db_name": <db_name>,
2727
"pool_size": <pool_size>,
2828
"use_ssl": <bool>,
29-
"read_preference": <e.g. "nearest" or "primary" etecetera>
29+
"read_preference": <e.g. "nearest" or "primary" etecetera>,
30+
"use_mongo_types": <bool>
3031
}
3132

3233
For example:
@@ -37,7 +38,8 @@ For example:
3738
"port": 27000,
3839
"pool_size": 20,
3940
"db_name": "my_db",
40-
"read_preference": "nearest"
41+
"read_preference": "nearest",
42+
"use_mongo_types": false
4143
}
4244

4345
Let's take a look at each field in turn:
@@ -49,6 +51,7 @@ Let's take a look at each field in turn:
4951
* `pool_size` The number of socket connections the module instance should maintain to the MongoDB server. Default is 10.
5052
* `use_ssl` enable SSL based connections. See http://docs.mongodb.org/manual/tutorial/configure-ssl/ for more details. Defaults to `false`.
5153
* `read_preference` is the read preferences, see http://docs.mongodb.org/manual/core/read-preference/. Default is "primary".
54+
* `use_mongo_types` enable the use of mongo types such as Date, byte array, array list. Note that if enabled this will incur a performance overhead to all queries. Default is `false`.
5255

5356
### Replsets or sharding
5457

gradle.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ mongoVersion=2.11.1
1515
# Set to true if you want module dependencies to be pulled in and nested inside the module itself
1616
pullInDeps=false
1717

18-
gradleVersion=1.5
18+
gradleVersion=1.10
1919
vertxVersion=2.0.0-final
2020
toolsVersion=2.0.0-final
2121
junitVersion=4.10

gradle/wrapper/gradle-wrapper.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
33
distributionPath=wrapper/dists
44
zipStoreBase=GRADLE_USER_HOME
55
zipStorePath=wrapper/dists
6-
distributionUrl=http\://services.gradle.org/distributions/gradle-1.5-bin.zip
6+
distributionUrl=http\://services.gradle.org/distributions/gradle-1.10-bin.zip

src/main/java/org/vertx/mods/MongoPersistor.java

+27-13
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package org.vertx.mods;
1818

1919
import com.mongodb.*;
20-
import com.mongodb.util.JSON;
2120
import org.vertx.java.busmods.BusModBase;
2221
import org.vertx.java.core.Handler;
2322
import org.vertx.java.core.eventbus.Message;
@@ -53,6 +52,7 @@ public class MongoPersistor extends BusModBase implements Handler<Message<JsonOb
5352

5453
protected Mongo mongo;
5554
protected DB db;
55+
private boolean useMongoTypes;
5656

5757
@Override
5858
public void start() {
@@ -70,6 +70,7 @@ public void start() {
7070
autoConnectRetry = getOptionalBooleanConfig("auto_connect_retry", true);
7171
socketTimeout = getOptionalIntConfig("socket_timeout", 60000);
7272
useSSL = getOptionalBooleanConfig("use_ssl", false);
73+
useMongoTypes = getOptionalBooleanConfig("use_mongo_types", false);
7374

7475
JsonArray seedsProperty = config.getArray("seeds");
7576

@@ -147,7 +148,7 @@ public void handle(Message<JsonObject> message) {
147148
case "findone":
148149
doFindOne(message);
149150
break;
150-
// no need for a backwards compatible "findAndModify" since this feature was added after
151+
// no need for a backwards compatible "findAndModify" since this feature was added after
151152
case "find_and_modify":
152153
doFindAndModify(message);
153154
break;
@@ -206,6 +207,7 @@ private void doSave(Message<JsonObject> message) {
206207
if (writeConcern == null) {
207208
writeConcern = db.getWriteConcern();
208209
}
210+
209211
WriteResult res = coll.save(obj, writeConcern);
210212
if (res.getError() == null) {
211213
if (genID != null) {
@@ -341,7 +343,7 @@ private void sendBatch(Message<JsonObject> message, final DBCursor cursor, final
341343
JsonArray results = new JsonArray();
342344
while (cursor.hasNext() && count < max) {
343345
DBObject obj = cursor.next();
344-
JsonObject m = new JsonObject(obj.toMap());
346+
JsonObject m = dbObjectToJsonObject(obj);
345347
results.add(m);
346348
count++;
347349
}
@@ -406,7 +408,7 @@ private void doFindOne(Message<JsonObject> message) {
406408
}
407409
sendOK(message, reply);
408410
}
409-
411+
410412
private void doFindAndModify(Message<JsonObject> message) {
411413
String collectionName = getMandatoryString("collection", message);
412414
if (collectionName == null) {
@@ -427,7 +429,7 @@ private void doFindAndModify(Message<JsonObject> message) {
427429

428430
JsonObject reply = new JsonObject();
429431
if (result != null) {
430-
JsonObject resultJson = new JsonObject(result.toMap());
432+
JsonObject resultJson = dbObjectToJsonObject(result);
431433
reply.putObject("result", resultJson);
432434
}
433435
sendOK(message, reply);
@@ -514,7 +516,7 @@ private void getCollectionStats(Message<JsonObject> message) {
514516
CommandResult stats = coll.getStats();
515517

516518
JsonObject reply = new JsonObject();
517-
reply.putObject("stats", new JsonObject(stats.toMap()));
519+
reply.putObject("stats", dbObjectToJsonObject(stats));
518520
sendOK(message, reply);
519521

520522
}
@@ -528,20 +530,32 @@ private void runCommand(Message<JsonObject> message) {
528530
return;
529531
}
530532

531-
DBObject commandObject = (DBObject) JSON.parse(command);
533+
DBObject commandObject = MongoUtil.convertJsonToBson(command);
532534
CommandResult result = db.command(commandObject);
533535

534536
reply.putObject("result", new JsonObject(result.toMap()));
535537
sendOK(message, reply);
536538
}
537-
538-
private static DBObject jsonToDBObject(JsonObject object) {
539+
540+
private JsonObject dbObjectToJsonObject(DBObject obj) {
541+
if (useMongoTypes) {
542+
return MongoUtil.convertBsonToJson(obj);
543+
} else {
544+
return new JsonObject(obj.toMap());
545+
}
546+
}
547+
548+
private DBObject jsonToDBObject(JsonObject object) {
549+
if (useMongoTypes) {
550+
return MongoUtil.convertJsonToBson(object);
551+
} else {
539552
return new BasicDBObject(object.toMap());
540-
}
541-
542-
private static DBObject jsonToDBObjectNullSafe(JsonObject object) {
553+
}
554+
}
555+
556+
private DBObject jsonToDBObjectNullSafe(JsonObject object) {
543557
if (object != null) {
544-
return new BasicDBObject(object.toMap());
558+
return jsonToDBObject(object);
545559
} else {
546560
return null;
547561
}

src/main/java/org/vertx/mods/MongoUtil.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public static DBObject convertJsonToBson(String json) {
4141
throw new IllegalArgumentException("Cannot convert empty string to DBObject");
4242
}
4343

44-
return (DBObject) JSON.parse(json.toString());
44+
return (DBObject) JSON.parse(json);
4545
}
4646

4747
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
package org.vertx.mods.mongo.test.integration.java;
2+
/*
3+
* Copyright 2013 Red Hat, Inc.
4+
*
5+
* Red Hat licenses this file to you under the Apache License, version 2.0
6+
* (the "License"); you may not use this file except in compliance with the
7+
* License. You may obtain a copy of the License at:
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14+
* License for the specific language governing permissions and limitations
15+
* under the License.
16+
*
17+
* @author <a href="http://tfox.org">Tim Fox</a>
18+
*/
19+
20+
import com.mongodb.BasicDBObject;
21+
import com.mongodb.DBObject;
22+
import org.bson.types.Binary;
23+
import org.junit.Test;
24+
import org.vertx.java.core.Handler;
25+
import org.vertx.java.core.eventbus.Message;
26+
import org.vertx.java.core.json.JsonArray;
27+
import org.vertx.java.core.json.JsonObject;
28+
import org.vertx.mods.MongoUtil;
29+
import org.vertx.testtools.VertxAssert;
30+
31+
import java.util.ArrayList;
32+
import java.util.Date;
33+
import java.util.List;
34+
35+
import static org.vertx.testtools.VertxAssert.assertEquals;
36+
import static org.vertx.testtools.VertxAssert.testComplete;
37+
38+
public class MongoTypesTest extends PersistorTestParent {
39+
40+
@Override
41+
protected JsonObject getConfig() {
42+
JsonObject config = super.getConfig();
43+
config.putBoolean("use_mongo_types", true);
44+
return config;
45+
}
46+
47+
@Test
48+
public void testCommand() throws Exception {
49+
JsonObject ping = new JsonObject()
50+
.putString("action", "command")
51+
.putString("command", "{ping:1}");
52+
53+
eb.send(ADDRESS, ping, new Handler<Message<JsonObject>>() {
54+
public void handle(Message<JsonObject> reply) {
55+
Number ok = reply.body()
56+
.getObject("result")
57+
.getNumber("ok");
58+
59+
assertEquals(1.0, ok);
60+
testComplete();
61+
}
62+
});
63+
}
64+
65+
66+
@Test
67+
public void testDate() throws Exception {
68+
Date date = new Date();
69+
insertTypedData(date);
70+
}
71+
72+
@Test
73+
public void testByteArray() throws Exception {
74+
byte[] data = new byte[]{1, 2, 3};
75+
insertTypedData(data);
76+
}
77+
78+
@Test
79+
public void testArrayList() throws Exception {
80+
List data = new ArrayList();
81+
data.add(1);
82+
data.add(2);
83+
data.add(new BasicDBObject("foo", "bar"));
84+
data.add(4);
85+
insertTypedData(data);
86+
}
87+
88+
@Test
89+
public void testEmbeddedDoc() throws Exception {
90+
BasicDBObject y = new BasicDBObject("y", 3);
91+
BasicDBObject data = new BasicDBObject("x", y);
92+
insertTypedData(data);
93+
}
94+
95+
private void insertTypedData(final Object data) {
96+
deleteAll(new Handler<Message<JsonObject>>() {
97+
public void handle(Message<JsonObject> reply) {
98+
final String testValue = "{\"testKey\" : \"testValue\"}";
99+
final DBObject obj = MongoUtil.convertJsonToBson(testValue);
100+
obj.put("data", data);
101+
102+
JsonObject docWithDate = MongoUtil.convertBsonToJson(obj);
103+
104+
JsonObject json = new JsonObject()
105+
.putString("collection", COLLECTION)
106+
.putString("action", "save").putObject("document", docWithDate);
107+
108+
eb.send(ADDRESS, json, new Handler<Message<JsonObject>>() {
109+
public void handle(Message<JsonObject> reply) {
110+
assertEquals(reply.body().toString(), "ok", reply.body().getString("status"));
111+
112+
assertStored(testValue, data, obj);
113+
}
114+
});
115+
}
116+
});
117+
118+
}
119+
120+
private void assertStored(String testValue, final Object data, final DBObject sentObject) {
121+
JsonObject matcher = new JsonObject(testValue);
122+
JsonObject query = new JsonObject()
123+
.putString("collection", COLLECTION)
124+
.putString("action", "find")
125+
.putObject("matcher", matcher);
126+
127+
eb.send(ADDRESS, query, new Handler<Message<JsonObject>>() {
128+
public void handle(Message<JsonObject> reply) {
129+
assertEquals(reply.body().toString(), "ok", reply.body().getString("status"));
130+
JsonArray results = reply.body().getArray("results");
131+
132+
if (results.size() > 0) {
133+
JsonObject result = results.get(0);
134+
DBObject dbObj = MongoUtil.convertJsonToBson(result);
135+
dbObj.removeField("_id");
136+
Object storedData = dbObj.get("data");
137+
if (storedData instanceof Binary) {
138+
VertxAssert.assertArrayEquals((byte[]) data, ((Binary) storedData).getData());
139+
} else {
140+
VertxAssert.assertEquals(sentObject, dbObj);
141+
}
142+
testComplete();
143+
} else {
144+
VertxAssert.fail("Stored object not found in DB");
145+
}
146+
}
147+
}
148+
149+
);
150+
}
151+
}
152+

0 commit comments

Comments
 (0)