Upgrade to mongodb driver async 5.x --------- Signed-off-by: Olivier Lamy <olamy@apache.org>
This commit is contained in:
parent
1bf074894a
commit
edbd21bdf0
|
@ -23,10 +23,21 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongo-java-driver</artifactId>
|
||||
<artifactId>bson</artifactId>
|
||||
<version>${mongodb.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongodb-driver-core</artifactId>
|
||||
<version>${mongodb.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongodb-driver-sync</artifactId>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
|
|
|
@ -14,11 +14,15 @@ sessions
|
|||
sessions/mongo/${connection-type}
|
||||
|
||||
[files]
|
||||
maven://org.mongodb/mongo-java-driver/${mongodb.version}|lib/nosql/mongo-java-driver-${mongodb.version}.jar
|
||||
maven://org.mongodb/mongodb-driver-sync/${mongodb.version}|lib/nosql/mongodb-driver-sync-${mongodb.version}.jar
|
||||
maven://org.mongodb/mongodb-driver-core/${mongodb.version}|lib/nosql/mongodb-driver-core-${mongodb.version}.jar
|
||||
maven://org.mongodb/bson/${mongodb.version}|lib/nosql/bson-${mongodb.version}.jar
|
||||
|
||||
[lib]
|
||||
lib/jetty-nosql-${jetty.version}.jar
|
||||
lib/nosql/mongo-java-driver-${mongodb.version}.jar
|
||||
lib/nosql/mongodb-driver-sync-${mongodb.version}.jar
|
||||
lib/nosql/mongodb-driver-core-${mongodb.version}.jar
|
||||
lib/nosql/bson-${mongodb.version}.jar
|
||||
|
||||
[license]
|
||||
The java driver for the MongoDB document-based database system is hosted on GitHub and released under the Apache 2.0 license.
|
||||
|
|
|
@ -13,7 +13,9 @@
|
|||
|
||||
module org.eclipse.jetty.nosql
|
||||
{
|
||||
requires transitive mongo.java.driver;
|
||||
requires transitive org.mongodb.driver.core;
|
||||
requires transitive org.mongodb.driver.sync.client;
|
||||
requires transitive org.mongodb.bson;
|
||||
requires transitive org.eclipse.jetty.session;
|
||||
|
||||
exports org.eclipse.jetty.nosql;
|
||||
|
|
|
@ -62,7 +62,7 @@ public abstract class NoSqlSessionDataStore extends ObjectStreamSessionDataStore
|
|||
|
||||
public Set<String> getAllAttributeNames()
|
||||
{
|
||||
return new HashSet<String>(_attributes.keySet());
|
||||
return new HashSet<>(_attributes.keySet());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,22 +15,29 @@ package org.eclipse.jetty.nosql.mongodb;
|
|||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import com.mongodb.BasicDBList;
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.BasicDBObjectBuilder;
|
||||
import com.mongodb.DBCollection;
|
||||
import com.mongodb.DBCursor;
|
||||
import com.mongodb.DBObject;
|
||||
import com.mongodb.MongoException;
|
||||
import com.mongodb.WriteConcern;
|
||||
import com.mongodb.WriteResult;
|
||||
import com.mongodb.client.FindIterable;
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.model.Filters;
|
||||
import com.mongodb.client.model.IndexModel;
|
||||
import com.mongodb.client.model.IndexOptions;
|
||||
import com.mongodb.client.model.Indexes;
|
||||
import com.mongodb.client.model.Projections;
|
||||
import com.mongodb.client.model.UpdateOptions;
|
||||
import com.mongodb.client.result.UpdateResult;
|
||||
import org.bson.Document;
|
||||
import org.bson.conversions.Bson;
|
||||
import org.bson.types.Binary;
|
||||
import org.eclipse.jetty.nosql.NoSqlSessionDataStore;
|
||||
import org.eclipse.jetty.session.SessionContext;
|
||||
import org.eclipse.jetty.session.SessionData;
|
||||
|
@ -155,15 +162,15 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
|
|||
/**
|
||||
* Access to MongoDB
|
||||
*/
|
||||
private DBCollection _dbSessions;
|
||||
private MongoCollection<Document> _dbSessions;
|
||||
|
||||
public void setDBCollection(DBCollection collection)
|
||||
public void setDBCollection(MongoCollection<Document> collection)
|
||||
{
|
||||
_dbSessions = collection;
|
||||
}
|
||||
|
||||
@ManagedAttribute(value = "DBCollection", readonly = true)
|
||||
public DBCollection getDBCollection()
|
||||
public MongoCollection<Document> getDBCollection()
|
||||
{
|
||||
return _dbSessions;
|
||||
}
|
||||
|
@ -171,7 +178,7 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
|
|||
@Override
|
||||
public SessionData doLoad(String id) throws Exception
|
||||
{
|
||||
DBObject sessionDocument = _dbSessions.findOne(new BasicDBObject(__ID, id));
|
||||
Document sessionDocument = _dbSessions.find(Filters.eq(__ID, id)).first();
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -191,7 +198,8 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
|
|||
Object version = MongoUtils.getNestedValue(sessionDocument, getContextSubfield(__VERSION));
|
||||
Long lastSaved = (Long)MongoUtils.getNestedValue(sessionDocument, getContextSubfield(__LASTSAVED));
|
||||
String lastNode = (String)MongoUtils.getNestedValue(sessionDocument, getContextSubfield(__LASTNODE));
|
||||
byte[] attributes = (byte[])MongoUtils.getNestedValue(sessionDocument, getContextSubfield(__ATTRIBUTES));
|
||||
Binary binary = ((Binary)MongoUtils.getNestedValue(sessionDocument, getContextSubfield(__ATTRIBUTES)));
|
||||
byte[] attributes = binary == null ? null : binary.getData();
|
||||
|
||||
Long created = (Long)sessionDocument.get(__CREATED);
|
||||
Long accessed = (Long)sessionDocument.get(__ACCESSED);
|
||||
|
@ -202,7 +210,7 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
|
|||
NoSqlSessionData data = null;
|
||||
|
||||
// get the session for the context
|
||||
DBObject sessionSubDocumentForContext = (DBObject)MongoUtils.getNestedValue(sessionDocument, getContextField());
|
||||
Document sessionSubDocumentForContext = (Document)MongoUtils.getNestedValue(sessionDocument, getContextField());
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("attrs {}", sessionSubDocumentForContext);
|
||||
|
@ -239,9 +247,9 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
|
|||
else
|
||||
{
|
||||
//attributes have special serialized format
|
||||
try (ByteArrayInputStream bais = new ByteArrayInputStream(attributes);)
|
||||
try (ByteArrayInputStream bais = new ByteArrayInputStream(attributes))
|
||||
{
|
||||
deserializeAttributes(data, bais);
|
||||
deserializeAttributes(data, bais);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -269,17 +277,17 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
|
|||
* Check if the session exists and if it does remove the context
|
||||
* associated with this session
|
||||
*/
|
||||
BasicDBObject mongoKey = new BasicDBObject(__ID, id);
|
||||
Bson filterId = Filters.eq(__ID, id);
|
||||
|
||||
DBObject sessionDocument = _dbSessions.findOne(new BasicDBObject(__ID, id));
|
||||
Document sessionDocument = _dbSessions.find(filterId).first();
|
||||
|
||||
if (sessionDocument != null)
|
||||
{
|
||||
DBObject c = (DBObject)MongoUtils.getNestedValue(sessionDocument, __CONTEXT);
|
||||
Document c = (Document)MongoUtils.getNestedValue(sessionDocument, __CONTEXT);
|
||||
if (c == null)
|
||||
{
|
||||
//delete whole doc
|
||||
_dbSessions.remove(mongoKey, WriteConcern.SAFE);
|
||||
_dbSessions.deleteOne(filterId);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -287,14 +295,14 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
|
|||
if (contexts.isEmpty())
|
||||
{
|
||||
//delete whole doc
|
||||
_dbSessions.remove(mongoKey, WriteConcern.SAFE);
|
||||
_dbSessions.deleteOne(filterId);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (contexts.size() == 1 && contexts.iterator().next().equals(getCanonicalContextId()))
|
||||
{
|
||||
//delete whole doc
|
||||
_dbSessions.remove(new BasicDBObject(__ID, id), WriteConcern.SAFE);
|
||||
_dbSessions.deleteOne(filterId);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -303,7 +311,7 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
|
|||
BasicDBObject unsets = new BasicDBObject();
|
||||
unsets.put(getContextField(), 1);
|
||||
remove.put("$unset", unsets);
|
||||
_dbSessions.update(mongoKey, remove, false, false, WriteConcern.SAFE);
|
||||
_dbSessions.updateOne(filterId, remove);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
@ -315,12 +323,9 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
|
|||
@Override
|
||||
public boolean doExists(String id) throws Exception
|
||||
{
|
||||
DBObject fields = new BasicDBObject();
|
||||
fields.put(__EXPIRY, 1);
|
||||
fields.put(__VALID, 1);
|
||||
fields.put(getContextSubfield(__VERSION), 1);
|
||||
|
||||
DBObject sessionDocument = _dbSessions.findOne(new BasicDBObject(__ID, id), fields);
|
||||
Bson projection = Projections.fields(Projections.include(__ID, __VALID, __EXPIRY, __VERSION, getContextField()), Projections.excludeId());
|
||||
Bson filterId = Filters.eq(__ID, id);
|
||||
Document sessionDocument = _dbSessions.find(filterId).projection(projection).first();
|
||||
|
||||
if (sessionDocument == null)
|
||||
return false; //doesn't exist
|
||||
|
@ -332,48 +337,33 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
|
|||
Long expiry = (Long)sessionDocument.get(__EXPIRY);
|
||||
|
||||
//expired?
|
||||
if (expiry.longValue() > 0 && expiry.longValue() < System.currentTimeMillis())
|
||||
if (expiry != null && expiry > 0 && expiry < System.currentTimeMillis())
|
||||
return false; //it's expired
|
||||
|
||||
//does it exist for this context?
|
||||
Object version = MongoUtils.getNestedValue(sessionDocument, getContextSubfield(__VERSION));
|
||||
if (version == null)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return version != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> doCheckExpired(Set<String> candidates, long time)
|
||||
{
|
||||
Set<String> expiredSessions = new HashSet<>();
|
||||
|
||||
//firstly ask mongo to verify if these candidate ids have expired - all of
|
||||
//these candidates will be for our node
|
||||
BasicDBObject query = new BasicDBObject();
|
||||
query.append(__ID, new BasicDBObject("$in", candidates));
|
||||
query.append(__EXPIRY, new BasicDBObject("$gt", 0).append("$lte", time));
|
||||
|
||||
DBCursor verifiedExpiredSessions = null;
|
||||
try
|
||||
{
|
||||
verifiedExpiredSessions = _dbSessions.find(query, new BasicDBObject(__ID, 1));
|
||||
for (DBObject session : verifiedExpiredSessions)
|
||||
{
|
||||
String id = (String)session.get(__ID);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("{} Mongo confirmed expired session {}", _context, id);
|
||||
expiredSessions.add(id);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (verifiedExpiredSessions != null)
|
||||
verifiedExpiredSessions.close();
|
||||
}
|
||||
|
||||
Bson query = Filters.and(
|
||||
Filters.in(__ID, candidates),
|
||||
Filters.gt(__EXPIRY, 0),
|
||||
Filters.lte(__EXPIRY, time));
|
||||
|
||||
//check through sessions that were candidates, but not found as expired.
|
||||
|
||||
FindIterable<Document> verifiedExpiredSessions = _dbSessions.find(query); // , new BasicDBObject(__ID, 1)
|
||||
Set<String> expiredSessions =
|
||||
StreamSupport.stream(verifiedExpiredSessions.spliterator(), false)
|
||||
.map(document -> document.getString(__ID))
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
//check through sessions that were candidates, but not found as expired.
|
||||
//they may no longer be persisted, in which case they are treated as expired.
|
||||
for (String c:candidates)
|
||||
{
|
||||
|
@ -398,37 +388,17 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
|
|||
{
|
||||
// now ask mongo to find sessions for this context, last managed by any
|
||||
// node, that expired before timeLimit
|
||||
Set<String> expiredSessions = new HashSet<>();
|
||||
Bson query = Filters.and(
|
||||
Filters.gt(__EXPIRY, 0),
|
||||
Filters.lte(__EXPIRY, timeLimit)
|
||||
);
|
||||
|
||||
BasicDBObject query = new BasicDBObject();
|
||||
BasicDBObject gt = new BasicDBObject(__EXPIRY, new BasicDBObject("$gt", 0));
|
||||
BasicDBObject lt = new BasicDBObject(__EXPIRY, new BasicDBObject("$lte", timeLimit));
|
||||
BasicDBList list = new BasicDBList();
|
||||
list.add(gt);
|
||||
list.add(lt);
|
||||
query.append("$and", list);
|
||||
|
||||
DBCursor oldExpiredSessions = null;
|
||||
try
|
||||
{
|
||||
BasicDBObject bo = new BasicDBObject(__ID, 1);
|
||||
bo.append(__EXPIRY, 1);
|
||||
|
||||
oldExpiredSessions = _dbSessions.find(query, bo);
|
||||
for (DBObject session : oldExpiredSessions)
|
||||
{
|
||||
String id = (String)session.get(__ID);
|
||||
|
||||
//TODO we should verify if there is a session for my context, not any context
|
||||
expiredSessions.add(id);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (oldExpiredSessions != null)
|
||||
oldExpiredSessions.close();
|
||||
}
|
||||
//TODO we should verify if there is a session for my context, not any context
|
||||
|
||||
FindIterable<Document> documents = _dbSessions.find(query);
|
||||
Set<String> expiredSessions = StreamSupport.stream(documents.spliterator(), false)
|
||||
.map(document -> document.getString(__ID))
|
||||
.collect(Collectors.toSet());
|
||||
return expiredSessions;
|
||||
}
|
||||
|
||||
|
@ -438,9 +408,11 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
|
|||
//Delete all session documents where the expiry time (which is always the most
|
||||
//up-to-date expiry of all contexts sharing that session id) has already past as
|
||||
//at the timeLimit.
|
||||
BasicDBObject query = new BasicDBObject();
|
||||
query.append(__EXPIRY, new BasicDBObject("$gt", 0).append("$lte", timeLimit));
|
||||
_dbSessions.remove(query, WriteConcern.SAFE);
|
||||
Bson query = Filters.and(
|
||||
Filters.gt(__EXPIRY, 0),
|
||||
Filters.lte(__EXPIRY, timeLimit)
|
||||
);
|
||||
_dbSessions.deleteMany(query);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -458,8 +430,7 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
|
|||
public void doStore(String id, SessionData data, long lastSaveTime) throws Exception
|
||||
{
|
||||
// Form query for upsert
|
||||
final BasicDBObject key = new BasicDBObject(__ID, id);
|
||||
|
||||
Bson key = Filters.eq(__ID, id);;
|
||||
// Form updates
|
||||
BasicDBObject update = new BasicDBObject();
|
||||
boolean upsert = false;
|
||||
|
@ -487,12 +458,13 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
|
|||
sets.put(getContextSubfield(__LASTNODE), data.getLastNode());
|
||||
version = ((Number)version).longValue() + 1L;
|
||||
((NoSqlSessionData)data).setVersion(version);
|
||||
update.put("$inc", _version1);
|
||||
// what is this?? this field is used no where...
|
||||
//sets.put("$inc", _version1);
|
||||
//if max idle time and/or expiry is smaller for this context, then choose that for the whole session doc
|
||||
BasicDBObject fields = new BasicDBObject();
|
||||
fields.append(__MAX_IDLE, true);
|
||||
fields.append(__EXPIRY, true);
|
||||
DBObject o = _dbSessions.findOne(new BasicDBObject("id", id), fields);
|
||||
Document o = _dbSessions.find(key).first();
|
||||
if (o != null)
|
||||
{
|
||||
Long tmpLong = (Long)o.get(__MAX_IDLE);
|
||||
|
@ -516,37 +488,39 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
|
|||
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();)
|
||||
{
|
||||
serializeAttributes(data, baos);
|
||||
sets.put(getContextSubfield(__ATTRIBUTES), baos.toByteArray());
|
||||
Binary binary = new Binary(baos.toByteArray());
|
||||
sets.put(getContextSubfield(__ATTRIBUTES), binary);
|
||||
}
|
||||
|
||||
// Do the upsert
|
||||
if (!sets.isEmpty())
|
||||
update.put("$set", sets);
|
||||
|
||||
WriteResult res = _dbSessions.update(key, update, upsert, false, WriteConcern.SAFE);
|
||||
UpdateResult res = _dbSessions.updateOne(key, update, new UpdateOptions().upsert(upsert));
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Save:db.sessions.update( {}, {},{} )", key, update, res);
|
||||
}
|
||||
|
||||
protected void ensureIndexes() throws MongoException
|
||||
{
|
||||
_version1 = new BasicDBObject(getContextSubfield(__VERSION), 1);
|
||||
DBObject idKey = BasicDBObjectBuilder.start().add("id", 1).get();
|
||||
_dbSessions.createIndex(idKey,
|
||||
BasicDBObjectBuilder.start()
|
||||
.add("name", "id_1")
|
||||
.add("ns", _dbSessions.getFullName())
|
||||
.add("sparse", false)
|
||||
.add("unique", true)
|
||||
.get());
|
||||
|
||||
DBObject versionKey = BasicDBObjectBuilder.start().add("id", 1).add("version", 1).get();
|
||||
_dbSessions.createIndex(versionKey, BasicDBObjectBuilder.start()
|
||||
.add("name", "id_1_version_1")
|
||||
.add("ns", _dbSessions.getFullName())
|
||||
.add("sparse", false)
|
||||
.add("unique", true)
|
||||
.get());
|
||||
var indexes =
|
||||
StreamSupport.stream(_dbSessions.listIndexes().spliterator(), false)
|
||||
.toList();
|
||||
var indexesNames = indexes.stream().map(document -> document.getString("name")).toList();
|
||||
if (!indexesNames.contains("id_1"))
|
||||
{
|
||||
String createResult = _dbSessions.createIndex(Indexes.text("id"),
|
||||
new IndexOptions().unique(true).name("id_1").sparse(false));
|
||||
LOG.info("create index {}, result: {}", "id_1", createResult);
|
||||
}
|
||||
if (!indexesNames.contains("id_1_version_1"))
|
||||
{
|
||||
// Command failed with error 67 (CannotCreateIndex): 'only one text index per collection allowed, found existing text index "id_1"'
|
||||
String createResult = _dbSessions.createIndex(
|
||||
Indexes.compoundIndex(Indexes.descending("id"), Indexes.descending("version")),
|
||||
new IndexOptions().unique(false).name("id_1_version_1").sparse(false));
|
||||
LOG.info("create index {}, result: {}", "id_1_version_1", createResult);
|
||||
}
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Done ensure Mongodb indexes existing");
|
||||
//TODO perhaps index on expiry time?
|
||||
|
@ -587,4 +561,4 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
|
|||
{
|
||||
return String.format("%s[collection=%s]", super.toString(), getDBCollection());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,8 +15,8 @@ package org.eclipse.jetty.nosql.mongodb;
|
|||
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import com.mongodb.MongoClient;
|
||||
import com.mongodb.MongoClientURI;
|
||||
import com.mongodb.client.MongoClient;
|
||||
import com.mongodb.client.MongoClients;
|
||||
import org.eclipse.jetty.session.AbstractSessionDataStoreFactory;
|
||||
import org.eclipse.jetty.session.SessionDataStore;
|
||||
import org.eclipse.jetty.session.SessionManager;
|
||||
|
@ -136,14 +136,14 @@ public class MongoSessionDataStoreFactory extends AbstractSessionDataStoreFactor
|
|||
MongoClient mongo;
|
||||
|
||||
if (!StringUtil.isBlank(getConnectionString()))
|
||||
mongo = new MongoClient(new MongoClientURI(getConnectionString()));
|
||||
mongo = MongoClients.create(getConnectionString());
|
||||
else if (!StringUtil.isBlank(getHost()) && getPort() != -1)
|
||||
mongo = new MongoClient(getHost(), getPort());
|
||||
mongo = MongoClients.create("mongodb://" + getHost() + ":" + getPort());
|
||||
else if (!StringUtil.isBlank(getHost()))
|
||||
mongo = new MongoClient(getHost());
|
||||
mongo = MongoClients.create("mongodb://" + getHost());
|
||||
else
|
||||
mongo = new MongoClient();
|
||||
store.setDBCollection(mongo.getDB(getDbName()).getCollection(getCollectionName()));
|
||||
mongo = MongoClients.create();
|
||||
store.setDBCollection(mongo.getDatabase(getDbName()).getCollection(getCollectionName()));
|
||||
return store;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,8 @@ import java.util.HashMap;
|
|||
import java.util.Map;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import org.bson.Document;
|
||||
import org.bson.types.Binary;
|
||||
import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
|
||||
|
@ -40,6 +41,13 @@ public class MongoUtils
|
|||
{
|
||||
return valueToDecode;
|
||||
}
|
||||
else if (valueToDecode instanceof Binary)
|
||||
{
|
||||
final byte[] decodeObject = ((Binary)valueToDecode).getData();
|
||||
final ByteArrayInputStream bais = new ByteArrayInputStream(decodeObject);
|
||||
final ClassLoadingObjectInputStream objectInputStream = new ClassLoadingObjectInputStream(bais);
|
||||
return objectInputStream.readUnshared();
|
||||
}
|
||||
else if (valueToDecode instanceof byte[])
|
||||
{
|
||||
final byte[] decodeObject = (byte[])valueToDecode;
|
||||
|
@ -47,13 +55,13 @@ public class MongoUtils
|
|||
final ClassLoadingObjectInputStream objectInputStream = new ClassLoadingObjectInputStream(bais);
|
||||
return objectInputStream.readUnshared();
|
||||
}
|
||||
else if (valueToDecode instanceof DBObject)
|
||||
else if (valueToDecode instanceof Document)
|
||||
{
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
for (String name : ((DBObject)valueToDecode).keySet())
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
for (String name : ((Document)valueToDecode).keySet())
|
||||
{
|
||||
String attr = decodeName(name);
|
||||
map.put(attr, decodeValue(((DBObject)valueToDecode).get(name)));
|
||||
map.put(attr, decodeValue(((Document)valueToDecode).get(name)));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
@ -107,19 +115,19 @@ public class MongoUtils
|
|||
/**
|
||||
* Dig through a given dbObject for the nested value
|
||||
*
|
||||
* @param dbObject the mongo object to search
|
||||
* @param sessionDocument the mongo document to search
|
||||
* @param nestedKey the field key to find
|
||||
* @return the value of the field key
|
||||
*/
|
||||
public static Object getNestedValue(DBObject dbObject, String nestedKey)
|
||||
public static Object getNestedValue(Document sessionDocument, String nestedKey)
|
||||
{
|
||||
String[] keyChain = nestedKey.split("\\.");
|
||||
|
||||
DBObject temp = dbObject;
|
||||
Document temp = sessionDocument;
|
||||
|
||||
for (int i = 0; i < keyChain.length - 1; ++i)
|
||||
{
|
||||
temp = (DBObject)temp.get(keyChain[i]);
|
||||
temp = (Document)temp.get(keyChain[i]);
|
||||
|
||||
if (temp == null)
|
||||
{
|
||||
|
|
9
pom.xml
9
pom.xml
|
@ -277,8 +277,8 @@
|
|||
<maven.version>3.9.0</maven.version>
|
||||
<maven.war.plugin.version>3.4.0</maven.war.plugin.version>
|
||||
<mina.core.version>2.2.3</mina.core.version>
|
||||
<mongo.docker.version>3.2.20</mongo.docker.version>
|
||||
<mongodb.version>3.12.14</mongodb.version>
|
||||
<mongo.docker.version>5.0.26</mongo.docker.version>
|
||||
<mongodb.version>5.1.3</mongodb.version>
|
||||
<netty.version>4.1.109.Final</netty.version>
|
||||
<openpojo.version>0.9.1</openpojo.version>
|
||||
<org.osgi.annotation.version>8.1.0</org.osgi.annotation.version>
|
||||
|
@ -1074,6 +1074,11 @@
|
|||
<artifactId>mariadb-java-client</artifactId>
|
||||
<version>${mariadb.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongodb-driver-sync</artifactId>
|
||||
<version>${mongodb.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mortbay.jetty.quiche</groupId>
|
||||
<artifactId>jetty-quiche-native</artifactId>
|
||||
|
|
|
@ -101,7 +101,7 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongo-java-driver</artifactId>
|
||||
<artifactId>mongodb-driver-sync</artifactId>
|
||||
<version>${mongodb.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
|
|
@ -18,13 +18,20 @@ import java.io.ByteArrayOutputStream;
|
|||
import java.io.ObjectOutputStream;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Map;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBCollection;
|
||||
import com.mongodb.DBObject;
|
||||
import com.mongodb.MongoClient;
|
||||
import com.mongodb.MongoException;
|
||||
import com.mongodb.WriteConcern;
|
||||
import com.mongodb.client.MongoClient;
|
||||
import com.mongodb.client.MongoClients;
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.model.CreateCollectionOptions;
|
||||
import com.mongodb.client.model.Filters;
|
||||
import com.mongodb.client.model.UpdateOptions;
|
||||
import org.bson.Document;
|
||||
import org.bson.types.Binary;
|
||||
import org.eclipse.jetty.nosql.mongodb.MongoSessionDataStore;
|
||||
import org.eclipse.jetty.nosql.mongodb.MongoSessionDataStoreFactory;
|
||||
import org.eclipse.jetty.nosql.mongodb.MongoUtils;
|
||||
|
@ -57,7 +64,7 @@ public class MongoTestHelper
|
|||
|
||||
static
|
||||
{
|
||||
mongo = new MongoDBContainer(DockerImageName.parse("mongo:" + System.getProperty("mongo.docker.version", "3.2.20")))
|
||||
mongo = new MongoDBContainer(DockerImageName.parse("mongo:" + System.getProperty("mongo.docker.version", "5.0.26")))
|
||||
.withLogConsumer(new Slf4jLogConsumer(MONGO_LOG));
|
||||
long start = System.currentTimeMillis();
|
||||
mongo.start();
|
||||
|
@ -65,21 +72,21 @@ public class MongoTestHelper
|
|||
mongoPort = mongo.getMappedPort(MONGO_PORT);
|
||||
LOG.info("Mongo container started for {}:{} - {}ms", mongoHost, mongoPort,
|
||||
System.currentTimeMillis() - start);
|
||||
mongoClient = new MongoClient(mongoHost, mongoPort);
|
||||
mongoClient = MongoClients.create(mongo.getConnectionString());
|
||||
}
|
||||
|
||||
public static MongoClient getMongoClient() throws UnknownHostException
|
||||
{
|
||||
if (mongoClient == null)
|
||||
{
|
||||
mongoClient = new MongoClient(mongoHost, mongoPort);
|
||||
mongoClient = MongoClients.create(mongo.getConnectionString());
|
||||
}
|
||||
return mongoClient;
|
||||
}
|
||||
|
||||
public static void dropCollection(String dbName, String collectionName) throws Exception
|
||||
{
|
||||
getMongoClient().getDB(dbName).getCollection(collectionName).drop();
|
||||
getMongoClient().getDatabase(dbName).getCollection(collectionName).withWriteConcern(WriteConcern.JOURNALED).drop();
|
||||
}
|
||||
|
||||
public static void shutdown() throws Exception
|
||||
|
@ -89,12 +96,14 @@ public class MongoTestHelper
|
|||
|
||||
public static void createCollection(String dbName, String collectionName) throws UnknownHostException, MongoException
|
||||
{
|
||||
getMongoClient().getDB(dbName).createCollection(collectionName, null);
|
||||
if (StreamSupport.stream(getMongoClient().getDatabase(dbName).listCollectionNames().spliterator(), false)
|
||||
.filter(collectionName::equals).findAny().isEmpty())
|
||||
getMongoClient().getDatabase(dbName).withWriteConcern(WriteConcern.JOURNALED).createCollection(collectionName, new CreateCollectionOptions());
|
||||
}
|
||||
|
||||
public static DBCollection getCollection(String dbName, String collectionName) throws UnknownHostException, MongoException
|
||||
public static MongoCollection<Document> getCollection(String dbName, String collectionName) throws UnknownHostException, MongoException
|
||||
{
|
||||
return getMongoClient().getDB(dbName).getCollection(collectionName);
|
||||
return getMongoClient().getDatabase(dbName).getCollection(collectionName);
|
||||
}
|
||||
|
||||
public static MongoSessionDataStoreFactory newSessionDataStoreFactory(String dbName, String collectionName)
|
||||
|
@ -108,15 +117,15 @@ public class MongoTestHelper
|
|||
}
|
||||
|
||||
public static boolean checkSessionExists(String id, String dbName, String collectionName)
|
||||
throws Exception
|
||||
throws Exception
|
||||
{
|
||||
DBCollection collection = getMongoClient().getDB(dbName).getCollection(collectionName);
|
||||
MongoCollection<Document> collection = getMongoClient().getDatabase(dbName).getCollection(collectionName);
|
||||
|
||||
DBObject fields = new BasicDBObject();
|
||||
fields.put(MongoSessionDataStore.__EXPIRY, 1);
|
||||
fields.put(MongoSessionDataStore.__VALID, 1);
|
||||
|
||||
DBObject sessionDocument = collection.findOne(new BasicDBObject(MongoSessionDataStore.__ID, id), fields);
|
||||
Document sessionDocument = collection.find(Filters.eq(MongoSessionDataStore.__ID, id)).first();
|
||||
|
||||
if (sessionDocument == null)
|
||||
return false; //doesn't exist
|
||||
|
@ -125,21 +134,21 @@ public class MongoTestHelper
|
|||
}
|
||||
|
||||
public static boolean checkSessionPersisted(SessionData data, String dbName, String collectionName)
|
||||
throws Exception
|
||||
throws Exception
|
||||
{
|
||||
DBCollection collection = getMongoClient().getDB(dbName).getCollection(collectionName);
|
||||
MongoCollection<Document> collection = getMongoClient().getDatabase(dbName).getCollection(collectionName);
|
||||
|
||||
DBObject fields = new BasicDBObject();
|
||||
|
||||
DBObject sessionDocument = collection.findOne(new BasicDBObject(MongoSessionDataStore.__ID, data.getId()), fields);
|
||||
Document sessionDocument = collection.find(Filters.eq(MongoSessionDataStore.__ID, data.getId())).first();
|
||||
if (sessionDocument == null)
|
||||
return false; //doesn't exist
|
||||
|
||||
LOG.debug("{}", sessionDocument);
|
||||
|
||||
Boolean valid = (Boolean)sessionDocument.get(MongoSessionDataStore.__VALID);
|
||||
boolean valid = (Boolean)sessionDocument.get(MongoSessionDataStore.__VALID);
|
||||
|
||||
if (valid == null || !valid)
|
||||
if (!valid)
|
||||
return false;
|
||||
|
||||
Long created = (Long)sessionDocument.get(MongoSessionDataStore.__CREATED);
|
||||
|
@ -149,13 +158,13 @@ public class MongoTestHelper
|
|||
Long expiry = (Long)sessionDocument.get(MongoSessionDataStore.__EXPIRY);
|
||||
|
||||
Object version = MongoUtils.getNestedValue(sessionDocument,
|
||||
MongoSessionDataStore.__CONTEXT + "." + data.getVhost().replace('.', '_') + ":" + data.getContextPath() + "." + MongoSessionDataStore.__VERSION);
|
||||
MongoSessionDataStore.__CONTEXT + "." + data.getVhost().replace('.', '_') + ":" + data.getContextPath() + "." + MongoSessionDataStore.__VERSION);
|
||||
Long lastSaved = (Long)MongoUtils.getNestedValue(sessionDocument,
|
||||
MongoSessionDataStore.__CONTEXT + "." + data.getVhost().replace('.', '_') + ":" + data.getContextPath() + "." + MongoSessionDataStore.__LASTSAVED);
|
||||
MongoSessionDataStore.__CONTEXT + "." + data.getVhost().replace('.', '_') + ":" + data.getContextPath() + "." + MongoSessionDataStore.__LASTSAVED);
|
||||
String lastNode = (String)MongoUtils.getNestedValue(sessionDocument,
|
||||
MongoSessionDataStore.__CONTEXT + "." + data.getVhost().replace('.', '_') + ":" + data.getContextPath() + "." + MongoSessionDataStore.__LASTNODE);
|
||||
byte[] attributes = (byte[])MongoUtils.getNestedValue(sessionDocument,
|
||||
MongoSessionDataStore.__CONTEXT + "." + data.getVhost().replace('.', '_') + ":" + data.getContextPath() + "." + MongoSessionDataStore.__ATTRIBUTES);
|
||||
MongoSessionDataStore.__CONTEXT + "." + data.getVhost().replace('.', '_') + ":" + data.getContextPath() + "." + MongoSessionDataStore.__LASTNODE);
|
||||
byte[] attributes = ((Binary)MongoUtils.getNestedValue(sessionDocument,
|
||||
MongoSessionDataStore.__CONTEXT + "." + data.getVhost().replace('.', '_') + ":" + data.getContextPath() + "." + MongoSessionDataStore.__ATTRIBUTES)).getData();
|
||||
|
||||
assertEquals(data.getCreated(), created.longValue());
|
||||
assertEquals(data.getAccessed(), accessed.longValue());
|
||||
|
@ -167,9 +176,9 @@ public class MongoTestHelper
|
|||
assertNotNull(lastSaved);
|
||||
|
||||
// get the session for the context
|
||||
DBObject sessionSubDocumentForContext =
|
||||
(DBObject)MongoUtils.getNestedValue(sessionDocument,
|
||||
MongoSessionDataStore.__CONTEXT + "." + data.getVhost().replace('.', '_') + ":" + data.getContextPath());
|
||||
Document sessionSubDocumentForContext =
|
||||
(Document)MongoUtils.getNestedValue(sessionDocument,
|
||||
MongoSessionDataStore.__CONTEXT + "." + data.getVhost().replace('.', '_') + ":" + data.getContextPath());
|
||||
|
||||
assertNotNull(sessionSubDocumentForContext);
|
||||
|
||||
|
@ -200,12 +209,9 @@ public class MongoTestHelper
|
|||
long lastAccessed, long maxIdle, long expiry,
|
||||
Map<String, Object> attributes, String dbName,
|
||||
String collectionName)
|
||||
throws Exception
|
||||
throws Exception
|
||||
{
|
||||
DBCollection collection = getMongoClient().getDB(dbName).getCollection(collectionName);
|
||||
|
||||
// Form query for upsert
|
||||
BasicDBObject key = new BasicDBObject(MongoSessionDataStore.__ID, id);
|
||||
MongoCollection<Document> collection = getMongoClient().getDatabase(dbName).getCollection(collectionName);
|
||||
|
||||
// Form updates
|
||||
BasicDBObject update = new BasicDBObject();
|
||||
|
@ -236,12 +242,12 @@ public class MongoTestHelper
|
|||
ObjectOutputStream oos = new ObjectOutputStream(baos))
|
||||
{
|
||||
SessionData.serializeAttributes(tmp, oos);
|
||||
sets.put(MongoSessionDataStore.__CONTEXT + "." + vhost.replace('.', '_') + ":" + contextPath + "." + MongoSessionDataStore.__ATTRIBUTES, baos.toByteArray());
|
||||
sets.put(MongoSessionDataStore.__CONTEXT + "." + vhost.replace('.', '_') + ":" + contextPath + "." + MongoSessionDataStore.__ATTRIBUTES, new Binary(baos.toByteArray()));
|
||||
}
|
||||
}
|
||||
|
||||
update.put("$set", sets);
|
||||
collection.update(key, update, upsert, false, WriteConcern.SAFE);
|
||||
collection.updateOne(Filters.eq(MongoSessionDataStore.__ID, id), update, new UpdateOptions().upsert(true));
|
||||
}
|
||||
|
||||
public static void createSession(String id, String contextPath, String vhost,
|
||||
|
@ -249,10 +255,10 @@ public class MongoTestHelper
|
|||
long lastAccessed, long maxIdle, long expiry,
|
||||
Map<String, Object> attributes, String dbName,
|
||||
String collectionName)
|
||||
throws Exception
|
||||
throws Exception
|
||||
{
|
||||
|
||||
DBCollection collection = getMongoClient().getDB(dbName).getCollection(collectionName);
|
||||
MongoCollection<Document> collection = getMongoClient().getDatabase(dbName).getCollection(collectionName);
|
||||
|
||||
// Form query for upsert
|
||||
BasicDBObject key = new BasicDBObject(MongoSessionDataStore.__ID, id);
|
||||
|
@ -283,12 +289,12 @@ public class MongoTestHelper
|
|||
ObjectOutputStream oos = new ObjectOutputStream(baos))
|
||||
{
|
||||
SessionData.serializeAttributes(tmp, oos);
|
||||
sets.put(MongoSessionDataStore.__CONTEXT + "." + vhost.replace('.', '_') + ":" + contextPath + "." + MongoSessionDataStore.__ATTRIBUTES, baos.toByteArray());
|
||||
sets.put(MongoSessionDataStore.__CONTEXT + "." + vhost.replace('.', '_') + ":" + contextPath + "." + MongoSessionDataStore.__ATTRIBUTES, new Binary(baos.toByteArray()));
|
||||
}
|
||||
}
|
||||
|
||||
update.put("$set", sets);
|
||||
collection.update(key, update, upsert, false, WriteConcern.SAFE);
|
||||
collection.updateOne(key, update, new UpdateOptions().upsert(true));
|
||||
}
|
||||
|
||||
public static void createLegacySession(String id, String contextPath, String vhost,
|
||||
|
@ -296,10 +302,10 @@ public class MongoTestHelper
|
|||
long lastAccessed, long maxIdle, long expiry,
|
||||
Map<String, Object> attributes, String dbName,
|
||||
String collectionName)
|
||||
throws Exception
|
||||
throws Exception
|
||||
{
|
||||
//make old-style session to test if we can retrieve it
|
||||
DBCollection collection = getMongoClient().getDB(dbName).getCollection(collectionName);
|
||||
MongoCollection<Document> collection = getMongoClient().getDatabase(dbName).getCollection(collectionName);
|
||||
|
||||
// Form query for upsert
|
||||
BasicDBObject key = new BasicDBObject(MongoSessionDataStore.__ID, id);
|
||||
|
@ -329,10 +335,10 @@ public class MongoTestHelper
|
|||
{
|
||||
Object value = attributes.get(name);
|
||||
sets.put(MongoSessionDataStore.__CONTEXT + "." + vhost.replace('.', '_') + ":" + contextPath + "." + MongoUtils.encodeName(name),
|
||||
MongoUtils.encodeName(value));
|
||||
MongoUtils.encodeName(value));
|
||||
}
|
||||
}
|
||||
update.put("$set", sets);
|
||||
collection.update(key, update, upsert, false, WriteConcern.SAFE);
|
||||
collection.updateOne(key, update, new UpdateOptions().upsert(true));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -35,7 +35,7 @@ public class MongodbSessionDistributionTests extends AbstractSessionDistribution
|
|||
|
||||
private static final int MONGO_PORT = 27017;
|
||||
|
||||
final String imageName = "mongo:" + System.getProperty("mongo.docker.version", "3.2.20");
|
||||
final String imageName = "mongo:" + System.getProperty("mongo.docker.version", "5.0.26");
|
||||
|
||||
final MongoDBContainer mongoDBContainer =
|
||||
new MongoDBContainer(DockerImageName.parse(imageName))
|
||||
|
|
Loading…
Reference in New Issue