Java tutorial
/* * Copyright 2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package ro.pippo.session.mongodb; import com.mongodb.MongoException; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; import static com.mongodb.client.model.Filters.eq; import com.mongodb.client.model.IndexOptions; import static com.mongodb.client.model.Projections.include; import com.mongodb.client.model.UpdateOptions; import static com.mongodb.client.model.Updates.combine; import static com.mongodb.client.model.Updates.set; import java.util.Date; import java.util.concurrent.TimeUnit; import org.bson.Document; import ro.pippo.session.SerializationSessionDataTranscoder; import ro.pippo.session.SessionData; import ro.pippo.session.SessionDataStorage; import ro.pippo.session.SessionDataTranscoder; /** * SessionDataStorage implementation with MongoDB. * * @author Herman Barrantes */ public class MongoDBSessionDataStorage implements SessionDataStorage { private static final String SESSION_NAME = "session"; private static final int IDLE_TIME = SessionData.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS; private static final String SESSION_ID = "_id"; private static final String SESSION_DATA = "session_data"; private static final String SESSION_TTL = "creation_time"; private static final String SESSION_INDEX_NAME = "session_ttl_index"; private final MongoCollection<Document> sessions; private final SessionDataTranscoder transcoder; /** * Manage session with MongoDB in the collection named "session" and 30 * minutes idle time. * * @param database MongoDB database object * @see #MongoDBSessionDataStorage(com.mongodb.client.MongoDatabase, * java.lang.String, long, ro.pippo.session.mongodb.SessionDataTranscoder) */ public MongoDBSessionDataStorage(MongoDatabase database) { this(database, SESSION_NAME, IDLE_TIME, new SerializationSessionDataTranscoder()); } /** * Manage session with MongoDB in the collection named "session" and idle * time indicated. * * @param database MongoDB database object * @param idleTime idle time of the session in seconds * @see #MongoDBSessionDataStorage(com.mongodb.client.MongoDatabase, * java.lang.String, long, ro.pippo.session.mongodb.SessionDataTranscoder) */ public MongoDBSessionDataStorage(MongoDatabase database, int idleTime) { this(database, SESSION_NAME, idleTime, new SerializationSessionDataTranscoder()); } /** * Manage session with MongoDB in the specified collection and 30 minutes * idle time. * * @param database MongoDB database object * @param collection name of collection to manage the session * @see #MongoDBSessionDataStorage(com.mongodb.client.MongoDatabase, * java.lang.String, long, ro.pippo.session.mongodb.SessionDataTranscoder) */ public MongoDBSessionDataStorage(MongoDatabase database, String collection) { this(database, collection, IDLE_TIME, new SerializationSessionDataTranscoder()); } /** * Manage session with MongoDB in the specified collection and idle time * indicated. * * @param database MongoDB database object * @param collection name of collection to manage the session * @param idleTime idle time of the session in seconds * @param transcoder trancoder */ public MongoDBSessionDataStorage(MongoDatabase database, String collection, long idleTime, SessionDataTranscoder transcoder) { this.transcoder = transcoder; this.sessions = database.getCollection(collection); createIndex(idleTime); } /** * Create TTL index * * @param idleTime idle time in seconds * @see https://docs.mongodb.com/manual/core/index-ttl/ */ private void createIndex(long idleTime) { try { this.sessions.createIndex(new Document(SESSION_TTL, 1), new IndexOptions().expireAfter(idleTime, TimeUnit.SECONDS).name(SESSION_INDEX_NAME)); } catch (MongoException ex) {//update idle time this.sessions.dropIndex(SESSION_INDEX_NAME); this.sessions.createIndex(new Document(SESSION_TTL, 1), new IndexOptions().expireAfter(idleTime, TimeUnit.SECONDS).name(SESSION_INDEX_NAME)); } } @Override public SessionData create() { return new SessionData(); } @Override public void save(SessionData sessionData) { String sessionId = sessionData.getId(); this.sessions .updateOne(eq(SESSION_ID, sessionId), combine(set(SESSION_ID, sessionId), set(SESSION_TTL, new Date()), set(SESSION_DATA, transcoder.encode(sessionData))), new UpdateOptions().upsert(true)); } @Override public SessionData get(String sessionId) { Document doc = this.sessions.find(eq(SESSION_ID, sessionId)).projection(include(SESSION_DATA)).first(); if (doc == null) { return null; } String sessionStored = doc.getString(SESSION_DATA); SessionData sessionData = transcoder.decode(sessionStored); return sessionData; } @Override public void delete(String sessionId) { this.sessions.deleteOne(eq(SESSION_ID, sessionId)); } }