Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MongoSessionDataStore can't upsert sessions if workerName contains token deliminators #12714

Open
benweidig opened this issue Jan 14, 2025 · 2 comments · May be fixed by #12715
Open

MongoSessionDataStore can't upsert sessions if workerName contains token deliminators #12714

benweidig opened this issue Jan 14, 2025 · 2 comments · May be fixed by #12715
Assignees
Labels
Bug For general bugs on Jetty side

Comments

@benweidig
Copy link

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 called id_1, which will prevent upserts if the SessionIdManager 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 the SessionIdManager has a valid workerName for the setup.

ensureIndexes() method:

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-property
var workerName = "ben-office-desktop";

var sessionIdManager = new DefaultSessionIdManager(server);
sessionIdManager.setWorkerName(workerName);
sessionIdManager.setServer(server);

var sessionHandler = new SessionHandler();
sessionHandler.setSessionIdManager(sessionIdManager);
sessionHandler.setSameSite(SameSite.NONE);
sessionHandler.setSecureRequestOnly(true);

SessionCache sessionCache = new DefaultSessionCache(sessionHandler);
sessionCache.setRemoveUnloadableSessions(true);

// We have our own MongoService that's already configured
// so we override how the DBCollection is loaded
var mongodb = registry.getService(MongoService.class);
var sessionDataStoreFactory = new MongoSessionDataStoreFactory() {

    @Override
    public SessionDataStore getSessionDataStore(SessionManager sessionManager) throws Exception {
        MongoSessionDataStore store = new MongoSessionDataStore();
        store.setGracePeriodSec(getGracePeriodSec());
        store.setSavePeriodSec(getSavePeriodSec());
        store.setDBCollection(mongodb.getCollection("sessions12", true));
        return store;
    }
};

SessionDataStore store = 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.

@benweidig benweidig added the Bug For general bugs on Jetty side label Jan 14, 2025
@janbartel janbartel self-assigned this Jan 14, 2025
@janbartel janbartel linked a pull request Jan 15, 2025 that will close this issue
@janbartel
Copy link
Contributor

@benweidig have a look at #12715, I think that fixes the problem?

@benweidig
Copy link
Author

Tried it in our code base, and the PR fixed the problem to make the underlying issue more obvious.

Thanks for the lightning-fast response time!

I've added two comments to the PR of things that might be could be further improved to allow more names and communicate what's wrong.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug For general bugs on Jetty side
Projects
Status: No status
Development

Successfully merging a pull request may close this issue.

2 participants