You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Jetty Environment
Embedded, manually constructed via code.
Java version/vendor(use: java -version)
openjdk version "21.0.4" 2024-07-16 LTS
OpenJDK Runtime Environment Zulu21.36+17-CA (build 21.0.4+7-LTS)
OpenJDK 64-Bit Server VM Zulu21.36+17-CA (build 21.0.4+7-LTS, mixed mode, sharing
OS type/version
Ubuntu 24.04.1 LTS
Description
The MongoSessionDataStore creates a text index for the id field called id_1, which will prevent upserts if the SessionIdManagerworkerName contains one of the tokenization delimiters, like a hyphen.
The error (MongoError: E11000 duplicate key) might not be helping to find the underlying issue, as the id is unique in the field, but thanks to tokenization not in the index.
So anyone using it must realize what's happening behind-the-scenes of text indexes in MongoDB.
I didn't find any documentation mentioning this restriction, and there's no internal check to ensure a valid workerName.
However, I haven't looked deep into the code, if it would be even easily possible to go through the different layers and let the SessionDataStore contribute to a decision of the SessionIdManager has a valid workerName for the setup.
How to reproduce?
We use embedded Jetty via Code, so there's a little bit of setup required. If necessary I could try to create a test repo.
Essentially, the relevant part is the SessionIdManager configuration.
This is how we build our SessionHandler:
// This comes from a system-propertyvarworkerName = "ben-office-desktop";
varsessionIdManager = newDefaultSessionIdManager(server);
sessionIdManager.setWorkerName(workerName);
sessionIdManager.setServer(server);
varsessionHandler = newSessionHandler();
sessionHandler.setSessionIdManager(sessionIdManager);
sessionHandler.setSameSite(SameSite.NONE);
sessionHandler.setSecureRequestOnly(true);
SessionCachesessionCache = newDefaultSessionCache(sessionHandler);
sessionCache.setRemoveUnloadableSessions(true);
// We have our own MongoService that's already configured// so we override how the DBCollection is loadedvarmongodb = registry.getService(MongoService.class);
varsessionDataStoreFactory = newMongoSessionDataStoreFactory() {
@OverridepublicSessionDataStoregetSessionDataStore(SessionManagersessionManager) throwsException {
MongoSessionDataStorestore = newMongoSessionDataStore();
store.setGracePeriodSec(getGracePeriodSec());
store.setSavePeriodSec(getSavePeriodSec());
store.setDBCollection(mongodb.getCollection("sessions12", true));
returnstore;
}
};
SessionDataStorestore = sessionDataStoreFactory.getSessionDataStore(sessionHandler);
sessionCache.setSessionDataStore(store);
sessionHandler.setSessionCache(sessionCache);
server.setHandler(sessionHandler);
That code will trigger the following Exception on trying to upsert a second session:
Stacktrace
2025-01-14T17:38:11,925 WARN [org.eclipse.jetty.session.AbstractSessionManager]: Unable to release Session ManagedSession@653f9078{id=ben-office-desktopu15uon1wu06317vc8mzddober0,x=ben-office-desktopu15uon1wu06317vc8mzddober0.ben-office-desktop,req=0,res=true}
com.mongodb.MongoWriteException: Write operation error on server mongo:27017. Write error: WriteError{code=11000, message='E11000 duplicate key error collection: tenandone-dev.sessions12 index: id_1 dup key: { _fts: "ben", _ftsx: 0.6666666666666666 }', details={}}.
at com.mongodb.client.internal.MongoCollectionImpl.executeSingleWriteRequest(MongoCollectionImpl.java:1123) ~[mongodb-driver-sync-5.2.1.jar:?]
at com.mongodb.client.internal.MongoCollectionImpl.executeUpdate(MongoCollectionImpl.java:1099) ~[mongodb-driver-sync-5.2.1.jar:?]
at com.mongodb.client.internal.MongoCollectionImpl.updateOne(MongoCollectionImpl.java:608) ~[mongodb-driver-sync-5.2.1.jar:?]
at org.eclipse.jetty.nosql.mongodb.MongoSessionDataStore.doStore(MongoSessionDataStore.java:499) ~[jetty-nosql-12.0.16.jar:12.0.16]
at org.eclipse.jetty.session.AbstractSessionDataStore.lambda$store$2(AbstractSessionDataStore.java:196) ~[jetty-session-12.0.16.jar:12.0.16]
at org.eclipse.jetty.server.handler.ContextHandler$ScopedContext.run(ContextHandler.java:1507) ~[jetty-server-12.0.16.jar:12.0.16]
at org.eclipse.jetty.server.handler.ContextHandler$ScopedContext.run(ContextHandler.java:1500) ~[jetty-server-12.0.16.jar:12.0.16]
at org.eclipse.jetty.session.SessionContext.run(SessionContext.java:92) ~[jetty-session-12.0.16.jar:12.0.16]
at org.eclipse.jetty.session.AbstractSessionDataStore.store(AbstractSessionDataStore.java:207) ~[jetty-session-12.0.16.jar:12.0.16]
at org.eclipse.jetty.session.AbstractSessionCache.release(AbstractSessionCache.java:538) ~[jetty-session-12.0.16.jar:12.0.16]
at org.eclipse.jetty.session.AbstractSessionManager.complete(AbstractSessionManager.java:229) ~[jetty-session-12.0.16.jar:12.0.16]
at org.eclipse.jetty.session.AbstractSessionManager$SessionStreamWrapper.doComplete(AbstractSessionManager.java:1491) ~[jetty-session-12.0.16.jar:12.0.16]
at org.eclipse.jetty.server.handler.ContextHandler$ScopedContext.run(ContextHandler.java:1513) ~[jetty-server-12.0.16.jar:12.0.16]
at org.eclipse.jetty.session.AbstractSessionManager$SessionStreamWrapper.succeeded(AbstractSessionManager.java:1480) ~[jetty-session-12.0.16.jar:12.0.16]
at org.eclipse.jetty.server.internal.HttpChannelState$HandlerInvoker.completeStream(HttpChannelState.java:771) ~[jetty-server-12.0.16.jar:12.0.16]
at org.eclipse.jetty.server.internal.HttpChannelState$HandlerInvoker.run(HttpChannelState.java:697) ~[jetty-server-12.0.16.jar:12.0.16]
at org.eclipse.jetty.server.internal.HttpConnection.onFillable(HttpConnection.java:418) ~[jetty-server-12.0.16.jar:12.0.16]
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:322) ~[jetty-io-12.0.16.jar:12.0.16]
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:99) ~[jetty-io-12.0.16.jar:12.0.16]
at org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53) ~[jetty-io-12.0.16.jar:12.0.16]
at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.runTask(AdaptiveExecutionStrategy.java:480) ~[jetty-util-12.0.16.jar:12.0.16]
at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask(AdaptiveExecutionStrategy.java:443) ~[jetty-util-12.0.16.jar:12.0.16]
at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce(AdaptiveExecutionStrategy.java:293) ~[jetty-util-12.0.16.jar:12.0.16]
at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.run(AdaptiveExecutionStrategy.java:201) ~[jetty-util-12.0.16.jar:12.0.16]
at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:311) ~[jetty-util-12.0.16.jar:12.0.16]
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:979) ~[jetty-util-12.0.16.jar:12.0.16]
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.doRunJob(QueuedThreadPool.java:1209) ~[jetty-util-12.0.16.jar:12.0.16]
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1164) ~[jetty-util-12.0.16.jar:12.0.16]
at java.base/java.lang.Thread.run(Thread.java:1583) [?:?]
Quickfix
We use workerName.replaceAll("\\W", "_") to restrict it to only allowed characters.
The text was updated successfully, but these errors were encountered:
Jetty version(s)
jetty-ee10-plus-12.0.16
jetty-ee10-servlet-12.0.16
jetty-nosql-12.0.16
Jetty Environment
Embedded, manually constructed via code.
Java version/vendor
(use: java -version)
openjdk version "21.0.4" 2024-07-16 LTS
OpenJDK Runtime Environment Zulu21.36+17-CA (build 21.0.4+7-LTS)
OpenJDK 64-Bit Server VM Zulu21.36+17-CA (build 21.0.4+7-LTS, mixed mode, sharing
OS type/version
Ubuntu 24.04.1 LTS
Description
The MongoSessionDataStore creates a text index for the
id
field calledid_1
, which will prevent upserts if theSessionIdManager
workerName
contains one of the tokenization delimiters, like a hyphen.The error (
MongoError: E11000 duplicate key
) might not be helping to find the underlying issue, as the id is unique in the field, but thanks to tokenization not in the index.So anyone using it must realize what's happening behind-the-scenes of text indexes in MongoDB.
I didn't find any documentation mentioning this restriction, and there's no internal check to ensure a valid
workerName
.However, I haven't looked deep into the code, if it would be even easily possible to go through the different layers and let the
SessionDataStore
contribute to a decision of theSessionIdManager
has a validworkerName
for the setup.ensureIndexes()
method:jetty.project/jetty-integrations/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionDataStore.java
Line 504 in 73e6058
How to reproduce?
We use embedded Jetty via Code, so there's a little bit of setup required. If necessary I could try to create a test repo.
Essentially, the relevant part is the
SessionIdManager
configuration.This is how we build our
SessionHandler
:That code will trigger the following Exception on trying to upsert a second session:
Stacktrace
Quickfix
We use
workerName.replaceAll("\\W", "_")
to restrict it to only allowed characters.The text was updated successfully, but these errors were encountered: