This is an automated email from the ASF dual-hosted git repository. ibessonov pushed a commit to branch revert-63-implement_spring_sessions in repository https://gitbox.apache.org/repos/asf/ignite-extensions.git
commit 04fb55ea0d71efd7a85889f73420064db4066f96 Author: ibessonov <[email protected]> AuthorDate: Wed Jun 23 15:21:30 2021 +0300 Revert "IGNITE-14920: Implement Spring Sessions Using Ignite As Backing Store" --- modules/spring-session-ext/pom.xml | 127 ----- .../spring/sessions/EnableIgniteHttpSession.java | 98 ---- .../sessions/IgniteHttpSessionConfiguration.java | 164 ------ .../sessions/IgniteIndexedSessionRepository.java | 555 --------------------- .../spring/sessions/SpringSessionIgnite.java | 39 -- .../src/main/java/package-info.java | 5 - ...bstractIgniteIndexedSessionRepositoryITest.java | 242 --------- ...mbeddedIgniteIndexedSessionRepositoryITest.java | 65 --- .../IgniteHttpSessionConfigurationTest.java | 495 ------------------ .../ignite/spring/sessions/IgniteITestUtils.java | 37 -- .../IgniteIndexedSessionRepositoryTest.java | 483 ------------------ .../testsuites/IgniteSpringSessionTestSuite.java | 19 - pom.xml | 1 - 13 files changed, 2330 deletions(-) diff --git a/modules/spring-session-ext/pom.xml b/modules/spring-session-ext/pom.xml deleted file mode 100644 index 1077de8..0000000 --- a/modules/spring-session-ext/pom.xml +++ /dev/null @@ -1,127 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <parent> - <artifactId>apache-ignite-extensions</artifactId> - <groupId>org.apache.ignite</groupId> - <version>1.0.0-SNAPSHOT</version> - <relativePath>../../pom.xml</relativePath> - </parent> - <modelVersion>4.0.0</modelVersion> - - <artifactId>spring-session-ext</artifactId> - - <properties> - <ignite.version>2.10.0</ignite.version> - <spring.version>5.3.8</spring.version> - <spring.session.version>2.5.0</spring.session.version> - <spring.security.version>5.5.0</spring.security.version> - <javax.annotation.version>1.3.2</javax.annotation.version> - <assertj.version>3.20.0</assertj.version> - <junit.jupiter.version>5.7.2</junit.jupiter.version> - <javax.servlet.version>3.0.1</javax.servlet.version> - <mockito.version>2.22.0</mockito.version> - </properties> - - <dependencies> - <dependency> - <groupId>org.apache.ignite</groupId> - <artifactId>ignite-core</artifactId> - <version>${ignite.version}</version> - <scope>provided</scope> - </dependency> - - <dependency> - <groupId>org.springframework</groupId> - <artifactId>spring-core</artifactId> - <version>${spring.version}</version> - </dependency> - - <dependency> - <groupId>org.springframework</groupId> - <artifactId>spring-expression</artifactId> - <version>${spring.version}</version> - </dependency> - - <!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-core --> - <dependency> - <groupId>org.springframework.security</groupId> - <artifactId>spring-security-core</artifactId> - <version>${spring.security.version}</version> - </dependency> - - <!-- https://mvnrepository.com/artifact/org.springframework.session/spring-session-core --> - <dependency> - <groupId>org.springframework.session</groupId> - <artifactId>spring-session-core</artifactId> - <version>${spring.session.version}</version> - </dependency> - - <!-- https://mvnrepository.com/artifact/org.springframework/spring-context --> - <dependency> - <groupId>org.springframework</groupId> - <artifactId>spring-context</artifactId> - <version>${spring.version}</version> - </dependency> - - <dependency> - <groupId>javax.annotation</groupId> - <artifactId>javax.annotation-api</artifactId> - <version>${javax.annotation.version}</version> - </dependency> - - <!-- https://mvnrepository.com/artifact/org.assertj/assertj-core --> - <dependency> - <groupId>org.assertj</groupId> - <artifactId>assertj-core</artifactId> - <version>${assertj.version}</version> - <scope>test</scope> - </dependency> - - <!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api --> - <dependency> - <groupId>org.junit.jupiter</groupId> - <artifactId>junit-jupiter-api</artifactId> - <version>${junit.jupiter.version}</version> - <scope>test</scope> - </dependency> - - <!-- https://mvnrepository.com/artifact/org.springframework/spring-test --> - <dependency> - <groupId>org.springframework</groupId> - <artifactId>spring-test</artifactId> - <version>${spring.version}</version> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>javax.servlet</groupId> - <artifactId>javax.servlet-api</artifactId> - <version>${javax.servlet.version}</version> - <scope>provided</scope> - </dependency> - - <!-- https://mvnrepository.com/artifact/org.springframework/spring-web --> - <dependency> - <groupId>org.springframework</groupId> - <artifactId>spring-web</artifactId> - <version>${spring.version}</version> - </dependency> - - <!-- https://mvnrepository.com/artifact/org.apache.ignite/ignite-indexing --> - <dependency> - <groupId>org.apache.ignite</groupId> - <artifactId>ignite-indexing</artifactId> - <version>${ignite.version}</version> - </dependency> - - <!-- https://mvnrepository.com/artifact/org.mockito/mockito-core --> - <dependency> - <groupId>org.mockito</groupId> - <artifactId>mockito-core</artifactId> - <version>${mockito.version}</version> - <scope>test</scope> - </dependency> - </dependencies> -</project> diff --git a/modules/spring-session-ext/src/main/java/org/apache/ignite/spring/sessions/EnableIgniteHttpSession.java b/modules/spring-session-ext/src/main/java/org/apache/ignite/spring/sessions/EnableIgniteHttpSession.java deleted file mode 100644 index 787496f..0000000 --- a/modules/spring-session-ext/src/main/java/org/apache/ignite/spring/sessions/EnableIgniteHttpSession.java +++ /dev/null @@ -1,98 +0,0 @@ -package org.apache.ignite.spring.sessions; - -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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. - */ - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.apache.ignite.Ignite; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.session.FlushMode; -import org.springframework.session.MapSession; -import org.springframework.session.SaveMode; -import org.springframework.session.Session; -import org.springframework.session.SessionRepository; -import org.springframework.session.web.http.SessionRepositoryFilter; - -/** - * Add this annotation to an {@code @Configuration} class to expose the - * {@link SessionRepositoryFilter} as a bean named {@code springSessionRepositoryFilter} - * and backed by Ignite. In order to leverage the annotation, a single {@link Ignite} must - * be provided. For example: - * - * <pre class="code"> - * @Configuration - * @EnableIgniteHttpSession - * public class IgniteHttpSessionConfig { - * - * @Bean - * public Ignite embeddedIgnite() { - * return IgniteEx.start(); - * } - * - * } - * </pre> - * - * More advanced configurations can extend {@link IgniteHttpSessionConfiguration} instead. - * - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -@Documented -@Import(IgniteHttpSessionConfiguration.class) -@Configuration(proxyBeanMethods = false) -public @interface EnableIgniteHttpSession { - /** - * The session timeout in seconds. By default, it is set to 1800 seconds (30 minutes). - * This should be a non-negative integer. - * @return the seconds a session can be inactive before expiring - */ - int maxInactiveIntervalInSeconds() default MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS; - - /** - * This is the name of the Map that will be used in Ignite to store the session data. - * Default is "spring:session:sessions". - * @return the name of the Map to store the sessions in Ignite - */ - String sessionMapName() default "spring:session:sessions"; - - /** - * Flush mode for the Ignite sessions. The default is {@code ON_SAVE} which only - * updates the backing Ignite when {@link SessionRepository#save(Session)} is invoked. - * In a web environment this happens just before the HTTP response is committed. - * <p> - * Setting the value to {@code IMMEDIATE} will ensure that the any updates to the - * Session are immediately written to the Ignite instance. - * @return the {@link FlushMode} to use - * @since 2.2.0 - */ - FlushMode flushMode() default FlushMode.ON_SAVE; - - /** - * Save mode for the session. The default is {@link SaveMode#ON_SET_ATTRIBUTE}, which - * only saves changes made to session. - * @return the save mode - * @since 2.2.0 - */ - SaveMode saveMode() default SaveMode.ON_SET_ATTRIBUTE; - -} diff --git a/modules/spring-session-ext/src/main/java/org/apache/ignite/spring/sessions/IgniteHttpSessionConfiguration.java b/modules/spring-session-ext/src/main/java/org/apache/ignite/spring/sessions/IgniteHttpSessionConfiguration.java deleted file mode 100644 index 36aa7e3..0000000 --- a/modules/spring-session-ext/src/main/java/org/apache/ignite/spring/sessions/IgniteHttpSessionConfiguration.java +++ /dev/null @@ -1,164 +0,0 @@ -package org.apache.ignite.spring.sessions; - -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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. - */ - -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import org.apache.ignite.Ignite; -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.ImportAware; -import org.springframework.core.annotation.AnnotationAttributes; -import org.springframework.core.type.AnnotationMetadata; -import org.springframework.session.FlushMode; -import org.springframework.session.IndexResolver; -import org.springframework.session.MapSession; -import org.springframework.session.SaveMode; -import org.springframework.session.Session; -import org.springframework.session.SessionRepository; -import org.springframework.session.config.SessionRepositoryCustomizer; -import org.springframework.session.config.annotation.web.http.SpringHttpSessionConfiguration; -import org.springframework.session.web.http.SessionRepositoryFilter; -import org.springframework.util.StringUtils; - -/** - * Exposes the {@link SessionRepositoryFilter} as a bean named - * {@code springSessionRepositoryFilter}. In order to use this a single {@link Ignite} - * must be exposed as a Bean. - */ -@Configuration(proxyBeanMethods = false) -public class IgniteHttpSessionConfiguration extends SpringHttpSessionConfiguration implements ImportAware { - /** */ - private Integer maxInactiveIntervalInSeconds = MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS; - - /** */ - private String sessionMapName = IgniteIndexedSessionRepository.DEFAULT_SESSION_MAP_NAME; - - /** */ - private FlushMode flushMode = FlushMode.ON_SAVE; - - /** */ - private SaveMode saveMode = SaveMode.ON_SET_ATTRIBUTE; - - /** */ - private Ignite ignite; - - /** */ - private ApplicationEventPublisher applicationEventPublisher; - - /** */ - private IndexResolver<Session> indexResolver; - - /** */ - private List<SessionRepositoryCustomizer<IgniteIndexedSessionRepository>> sessionRepositoryCustomizers; - - /** */ - @Bean - public SessionRepository<?> sessionRepository() { - return createIgniteIndexedSessionRepository(); - } - - /** */ - public void setMaxInactiveIntervalInSeconds(int maxInactiveIntervalInSeconds) { - this.maxInactiveIntervalInSeconds = maxInactiveIntervalInSeconds; - } - - /** */ - public void setSessionMapName(String sessionMapName) { - this.sessionMapName = sessionMapName; - } - - /** - * - */ - public void setFlushMode(FlushMode flushMode) { - this.flushMode = flushMode; - } - - /** */ - public void setSaveMode(SaveMode saveMode) { - this.saveMode = saveMode; - } - - /** */ - @Autowired - public void setIgnite(@SpringSessionIgnite ObjectProvider<Ignite> springSessionIgnite, - ObjectProvider<Ignite> ignite) { - Ignite igniteToUse = springSessionIgnite.getIfAvailable(); - if (igniteToUse == null) - igniteToUse = ignite.getObject(); - - this.ignite = igniteToUse; - } - - /** */ - @Autowired - public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { - this.applicationEventPublisher = applicationEventPublisher; - } - - /** */ - @Autowired(required = false) - public void setIndexResolver(IndexResolver<Session> indexResolver) { - this.indexResolver = indexResolver; - } - - /** */ - @Autowired(required = false) - public void setSessionRepositoryCustomizer( - ObjectProvider<SessionRepositoryCustomizer<IgniteIndexedSessionRepository>> sessionRepositoryCustomizers) { - this.sessionRepositoryCustomizers = sessionRepositoryCustomizers.orderedStream().collect(Collectors.toList()); - } - - /** */ - @Override @SuppressWarnings("deprecation") public void setImportMetadata(AnnotationMetadata importMetadata) { - Map<String, Object> attributeMap = importMetadata - .getAnnotationAttributes(EnableIgniteHttpSession.class.getName()); - AnnotationAttributes attributes = AnnotationAttributes.fromMap(attributeMap); - this.maxInactiveIntervalInSeconds = attributes.getNumber("maxInactiveIntervalInSeconds"); - String sessionMapNameValue = attributes.getString("sessionMapName"); - if (StringUtils.hasText(sessionMapNameValue)) - this.sessionMapName = sessionMapNameValue; - - this.flushMode = attributes.getEnum("flushMode"); - this.saveMode = attributes.getEnum("saveMode"); - } - - /** */ - private IgniteIndexedSessionRepository createIgniteIndexedSessionRepository() { - IgniteIndexedSessionRepository sessionRepository = new IgniteIndexedSessionRepository(this.ignite); - sessionRepository.setApplicationEventPublisher(this.applicationEventPublisher); - if (this.indexResolver != null) - sessionRepository.setIndexResolver(this.indexResolver); - - if (StringUtils.hasText(this.sessionMapName)) - sessionRepository.setSessionMapName(this.sessionMapName); - - sessionRepository.setDefaultMaxInactiveInterval(this.maxInactiveIntervalInSeconds); - sessionRepository.setFlushMode(this.flushMode); - sessionRepository.setSaveMode(this.saveMode); - this.sessionRepositoryCustomizers - .forEach((sessionRepositoryCustomizer) -> sessionRepositoryCustomizer.customize(sessionRepository)); - return sessionRepository; - } -} diff --git a/modules/spring-session-ext/src/main/java/org/apache/ignite/spring/sessions/IgniteIndexedSessionRepository.java b/modules/spring-session-ext/src/main/java/org/apache/ignite/spring/sessions/IgniteIndexedSessionRepository.java deleted file mode 100644 index 8fe5ff0..0000000 --- a/modules/spring-session-ext/src/main/java/org/apache/ignite/spring/sessions/IgniteIndexedSessionRepository.java +++ /dev/null @@ -1,555 +0,0 @@ -package org.apache.ignite.spring.sessions; - -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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. - */ - -import java.time.Duration; -import java.time.Instant; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.TimeUnit; - -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; -import javax.cache.configuration.CacheEntryListenerConfiguration; -import javax.cache.configuration.Factory; -import javax.cache.event.CacheEntryCreatedListener; -import javax.cache.event.CacheEntryEvent; -import javax.cache.event.CacheEntryEventFilter; -import javax.cache.event.CacheEntryExpiredListener; -import javax.cache.event.CacheEntryListener; -import javax.cache.event.CacheEntryListenerException; -import javax.cache.event.CacheEntryRemovedListener; -import javax.cache.expiry.TouchedExpiryPolicy; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.ignite.Ignite; -import org.apache.ignite.IgniteCache; -import org.apache.ignite.cache.query.FieldsQueryCursor; -import org.apache.ignite.cache.query.SqlFieldsQuery; -import org.apache.ignite.cache.query.annotations.QuerySqlField; -import org.apache.ignite.configuration.CacheConfiguration; -import org.apache.ignite.internal.GridDirectTransient; - -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.session.DelegatingIndexResolver; -import org.springframework.session.FindByIndexNameSessionRepository; -import org.springframework.session.FlushMode; -import org.springframework.session.IndexResolver; -import org.springframework.session.MapSession; -import org.springframework.session.PrincipalNameIndexResolver; -import org.springframework.session.SaveMode; -import org.springframework.session.Session; -import org.springframework.session.events.AbstractSessionEvent; -import org.springframework.session.events.SessionCreatedEvent; -import org.springframework.session.events.SessionDeletedEvent; -import org.springframework.session.events.SessionExpiredEvent; -import org.springframework.util.Assert; - -/** - * A {@link org.springframework.session.SessionRepository} implementation that stores - * sessions in Apache Ignite distributed {@link IgniteCache}. - * - * <p> - * An example of how to create a new instance can be seen below: - * - * <pre class="code"> - * IgniteConfiguration config = new IgniteConfiguration(); - * - * // ... configure Ignite ... - * - * Ignite ignite = IgnitionEx.start(config); - * - * IgniteIndexedSessionRepository sessionRepository = - * new IgniteIndexedSessionRepository(ignite); - * </pre> - * - * In order to support finding sessions by principal name using - * {@link #findByIndexNameAndIndexValue(String, String)} method, custom configuration of - * {@link IgniteCache} supplied to this implementation is required. - * - * This implementation listens for events on the Ignite-backed SessionRepository and - * translates those events into the corresponding Spring Session events. Publish the - * Spring Session events with the given {@link ApplicationEventPublisher}. - * - * <ul> - * <li>entryAdded - {@link SessionCreatedEvent}</li> - * <li>entryEvicted - {@link SessionExpiredEvent}</li> - * <li>entryRemoved - {@link SessionDeletedEvent}</li> - * </ul> - * - */ -public class IgniteIndexedSessionRepository - implements FindByIndexNameSessionRepository<IgniteIndexedSessionRepository.IgniteSession>, - CacheEntryCreatedListener<String, IgniteIndexedSessionRepository.IgniteSession>, - CacheEntryRemovedListener<String, IgniteIndexedSessionRepository.IgniteSession>, - CacheEntryExpiredListener<String, IgniteIndexedSessionRepository.IgniteSession> { - /** - * The default name of map used by Spring Session to store sessions. - */ - public static final String DEFAULT_SESSION_MAP_NAME = "spring:session:sessions"; - - /** */ - private static final String SPRING_SECURITY_CONTEXT = "SPRING_SECURITY_CONTEXT"; - - /** */ - private static final Log logger = LogFactory.getLog(IgniteIndexedSessionRepository.class); - - /** */ - private final Ignite ignite; - - /** */ - private ApplicationEventPublisher eventPublisher = (event) -> { - }; - - /** - * If non-null, this value is used to override - * {@link MapSession#setMaxInactiveInterval(Duration)}. - */ - private Integer defaultMaxInactiveInterval; - - /** */ - private IndexResolver<Session> indexResolver = new DelegatingIndexResolver<>(new PrincipalNameIndexResolver<>()); - - /** */ - private String sessionMapName = DEFAULT_SESSION_MAP_NAME; - - /** */ - private FlushMode flushMode = FlushMode.ON_SAVE; - - /** */ - private SaveMode saveMode = SaveMode.ON_SET_ATTRIBUTE; - - /** */ - private IgniteCache<String, IgniteSession> sessions; - - /** */ - private CacheEntryListenerConfiguration<String, IgniteSession> listenerConfiguration; - - /** - * Create a new {@link IgniteIndexedSessionRepository} instance. - * @param ignite the {@link Ignite} instance to use for managing sessions - */ - public IgniteIndexedSessionRepository(Ignite ignite) { - Assert.notNull(ignite, "Ignite must not be null"); - this.ignite = ignite; - } - - /** */ - @PostConstruct - public void init() { - final CacheConfiguration<String, IgniteSession> configuration = new CacheConfiguration<String, IgniteSession>( - this.sessionMapName).setIndexedTypes(String.class, IgniteSession.class); - - if (this.defaultMaxInactiveInterval != null) - configuration.setExpiryPolicyFactory(TouchedExpiryPolicy - .factoryOf(new javax.cache.expiry.Duration(TimeUnit.SECONDS, this.defaultMaxInactiveInterval))); - - this.sessions = this.ignite.getOrCreateCache(configuration); - - this.listenerConfiguration = new CacheEntryListenerConfiguration<String, IgniteSession>() { - @Override public Factory<CacheEntryListener<? super String, ? super IgniteSession>> getCacheEntryListenerFactory() { - return (Factory<CacheEntryListener<? super String, ? super IgniteSession>>) () -> IgniteIndexedSessionRepository.this; - } - - @Override public boolean isOldValueRequired() { - return true; - } - - @Override public Factory<CacheEntryEventFilter<? super String, ? super IgniteSession>> getCacheEntryEventFilterFactory() { - return null; - } - - @Override public boolean isSynchronous() { - return false; - } - }; - this.sessions.registerCacheEntryListener(this.listenerConfiguration); - } - - /** */ - @PreDestroy - public void close() { - this.sessions.deregisterCacheEntryListener(this.listenerConfiguration); - } - - /** - * Sets the {@link ApplicationEventPublisher} that is used to publish - * {@link AbstractSessionEvent session events}. The default is to not publish session - * events. - * @param applicationEventPublisher the {@link ApplicationEventPublisher} that is used - * to publish session events. Cannot be null. - */ - public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { - Assert.notNull(applicationEventPublisher, "ApplicationEventPublisher cannot be null"); - this.eventPublisher = applicationEventPublisher; - } - - /** - * Set the maximum inactive interval in seconds between requests before newly created - * sessions will be invalidated. A negative time indicates that the session will never - * timeout. The default is 1800 (30 minutes). - * @param defaultMaxInactiveInterval the maximum inactive interval in seconds - */ - public void setDefaultMaxInactiveInterval(Integer defaultMaxInactiveInterval) { - this.defaultMaxInactiveInterval = defaultMaxInactiveInterval; - } - - /** - * Set the {@link IndexResolver} to use. - * @param indexResolver the index resolver - */ - public void setIndexResolver(IndexResolver<Session> indexResolver) { - Assert.notNull(indexResolver, "indexResolver cannot be null"); - this.indexResolver = indexResolver; - } - - /** - * Set the name of map used to store sessions. - * @param sessionMapName the session map name - */ - public void setSessionMapName(String sessionMapName) { - Assert.hasText(sessionMapName, "Map name must not be empty"); - this.sessionMapName = sessionMapName; - } - - /** - * Sets the flush mode. Default flush mode is {@link FlushMode#ON_SAVE}. - * @param flushMode the new flush mode - */ - public void setFlushMode(FlushMode flushMode) { - Assert.notNull(flushMode, "flushMode cannot be null"); - this.flushMode = flushMode; - } - - /** - * Set the save mode. - * @param saveMode the save mode - */ - public void setSaveMode(SaveMode saveMode) { - Assert.notNull(saveMode, "saveMode must not be null"); - this.saveMode = saveMode; - } - - /** */ - @Override public IgniteSession createSession() { - MapSession cached = new MapSession(); - if (this.defaultMaxInactiveInterval != null) - cached.setMaxInactiveInterval(Duration.ofSeconds(this.defaultMaxInactiveInterval)); - - IgniteSession session = new IgniteSession(cached, true); - session.flushImmediateIfNecessary(); - return session; - } - - /** */ - @Override public void save(IgniteSession session) { - if (session.isNew) - ttlSessions(session.getMaxInactiveInterval()).put(session.getId(), session); - - else if (session.sessionIdChanged) { - this.sessions.remove(session.originalId); - session.originalId = session.getId(); - ttlSessions(session.getMaxInactiveInterval()).put(session.getId(), session); - } - else if (session.hasChanges()) { - if (session.maxInactiveIntervalChanged) { - ttlSessions(session.getMaxInactiveInterval()).replace(session.getId(), session); - } - else { - this.sessions.replace(session.getId(), session); - } - } - session.clearChangeFlags(); - } - - /** */ - @Override public IgniteSession findById(String id) { - IgniteSession saved = this.sessions.get(id); - if (saved == null) - return null; - - if (saved.isExpired()) { - deleteById(saved.getId()); - return null; - } - saved.isNew = false; - return saved; - } - - /** */ - @Override public void deleteById(String id) { - this.sessions.remove(id); - } - - /** */ - @Override public Map<String, IgniteSession> findByIndexNameAndIndexValue(String indexName, String indexValue) { - if (!PRINCIPAL_NAME_INDEX_NAME.equals(indexName)) - return Collections.emptyMap(); - - final FieldsQueryCursor<List<?>> cursor = this.sessions - .query(new SqlFieldsQuery("SELECT * FROM IgniteSession WHERE principal='" + indexValue + "'")); - - if (cursor == null) - return Collections.emptyMap(); - - final List<List<?>> sessions = cursor.getAll(); - - Map<String, IgniteSession> sessionMap = new HashMap<>(sessions.size()); - sessions.forEach((List<?> res) -> { - final MapSession session = (MapSession) res.get(0); - final IgniteSession value = new IgniteSession(session, false); - value.principal = (String) res.get(1); - sessionMap.put(session.getId(), value); - }); - - return sessionMap; - } - - /** */ - @Override public void onCreated(Iterable<CacheEntryEvent<? extends String, ? extends IgniteSession>> events) - throws CacheEntryListenerException { - events.forEach((event) -> { - IgniteSession session = event.getValue(); - if (session.getId().equals(session.getDelegate().getOriginalId())) { - if (logger.isDebugEnabled()) - logger.debug("Session created with id: " + session.getId()); - - this.eventPublisher.publishEvent(new SessionCreatedEvent(this, session)); - } - }); - } - - /** */ - @Override - public void onExpired(Iterable<CacheEntryEvent<? extends String, ? extends IgniteSession>> events) - throws CacheEntryListenerException { - events.forEach((event) -> { - if (logger.isDebugEnabled()) - logger.debug("Session expired with id: " + event.getOldValue().getId()); - - this.eventPublisher.publishEvent(new SessionExpiredEvent(this, event.getOldValue())); - }); - } - - /** */ - @Override public void onRemoved(Iterable<CacheEntryEvent<? extends String, ? extends IgniteSession>> events) - throws CacheEntryListenerException { - events.forEach((event) -> { - IgniteSession session = event.getOldValue(); - if (session != null) { - if (logger.isDebugEnabled()) - logger.debug("Session deleted with id: " + session.getId()); - - this.eventPublisher.publishEvent(new SessionDeletedEvent(this, session)); - } - }); - } - - /** - * Get cache view with custom duration expiry policy. - * @param duration expiry duration for IgniteSession. - * @return cache with custom duration expiry policy. - */ - private IgniteCache<String, IgniteSession> ttlSessions(Duration duration) { - return this.sessions.withExpiryPolicy(createPolicy(duration)); - } - - /** - * Create expiry policy from {@link Duration}. - * @param duration expiry duration. - * @return expiry policy. - */ - private static TouchedExpiryPolicy createPolicy(Duration duration) { - return new TouchedExpiryPolicy(new javax.cache.expiry.Duration(TimeUnit.SECONDS, duration.getSeconds())); - } - - /** - * A custom implementation of {@link Session} that uses a {@link MapSession} as the - * basis for its mapping. It keeps track if changes have been made since last save. - */ - final class IgniteSession implements Session { - - /** */ - @QuerySqlField - private final MapSession delegate; - - /** */ - @GridDirectTransient - private boolean isNew; - - /** */ - @GridDirectTransient - private boolean sessionIdChanged; - - /** */ - @GridDirectTransient - private boolean lastAccessedTimeChanged; - - /** */ - @GridDirectTransient - private boolean maxInactiveIntervalChanged; - - /** */ - @GridDirectTransient - private String originalId; - - /** */ - @GridDirectTransient - private Map<String, Object> delta = new HashMap<>(); - - /** */ - @QuerySqlField(index = true) - private String principal; - - IgniteSession(MapSession cached, boolean isNew) { - this.delegate = cached; - this.isNew = isNew; - this.originalId = cached.getId(); - if (this.isNew || (IgniteIndexedSessionRepository.this.saveMode == SaveMode.ALWAYS)) - getAttributeNames() - .forEach((attributeName) -> this.delta.put(attributeName, cached.getAttribute(attributeName))); - - } - - /** */ - @Override public void setLastAccessedTime(Instant lastAccessedTime) { - this.delegate.setLastAccessedTime(lastAccessedTime); - this.lastAccessedTimeChanged = true; - flushImmediateIfNecessary(); - } - - /** */ - @Override public boolean isExpired() { - return this.delegate.isExpired(); - } - - /** */ - @Override public Instant getCreationTime() { - return this.delegate.getCreationTime(); - } - - /** */ - @Override public String getId() { - return this.delegate.getId(); - } - - /** */ - @Override public String changeSessionId() { - String newSessionId = this.delegate.changeSessionId(); - this.sessionIdChanged = true; - return newSessionId; - } - - /** */ - @Override public Instant getLastAccessedTime() { - return this.delegate.getLastAccessedTime(); - } - - /** */ - @Override public void setMaxInactiveInterval(Duration interval) { - this.delegate.setMaxInactiveInterval(interval); - this.maxInactiveIntervalChanged = true; - flushImmediateIfNecessary(); - } - - /** */ - @Override public Duration getMaxInactiveInterval() { - return this.delegate.getMaxInactiveInterval(); - } - - /** */ - @Override public <T> T getAttribute(String attributeName) { - T attributeValue = this.delegate.getAttribute(attributeName); - if (attributeValue != null - && IgniteIndexedSessionRepository.this.saveMode.equals(SaveMode.ON_GET_ATTRIBUTE)) - this.delta.put(attributeName, attributeValue); - - return attributeValue; - } - - /** */ - @Override public Set<String> getAttributeNames() { - return this.delegate.getAttributeNames(); - } - - /** */ - @Override public void setAttribute(String attributeName, Object attributeValue) { - this.delegate.setAttribute(attributeName, attributeValue); - this.delta.put(attributeName, attributeValue); - if (SPRING_SECURITY_CONTEXT.equals(attributeName)) { - Map<String, String> indexes = IgniteIndexedSessionRepository.this.indexResolver.resolveIndexesFor(this); - String principal = (attributeValue != null) ? indexes.get(PRINCIPAL_NAME_INDEX_NAME) : null; - this.delegate.setAttribute(PRINCIPAL_NAME_INDEX_NAME, principal); - this.principal = principal; - } - flushImmediateIfNecessary(); - } - - /** */ - @Override public void removeAttribute(String attributeName) { - setAttribute(attributeName, null); - } - - /** */ - MapSession getDelegate() { - return this.delegate; - } - - /** */ - boolean hasChanges() { - return (this.lastAccessedTimeChanged || this.maxInactiveIntervalChanged || !this.delta.isEmpty()); - } - - /** */ - void clearChangeFlags() { - this.isNew = false; - this.lastAccessedTimeChanged = false; - this.sessionIdChanged = false; - this.maxInactiveIntervalChanged = false; - this.delta.clear(); - } - - /** */ - private void flushImmediateIfNecessary() { - if (IgniteIndexedSessionRepository.this.flushMode == FlushMode.IMMEDIATE) - IgniteIndexedSessionRepository.this.save(this); - } - - /** */ - @Override public boolean equals(Object o) { - if (this == o) - return true; - - if (o == null || getClass() != o.getClass()) - return false; - - IgniteSession session = (IgniteSession) o; - return this.delegate.equals(session.delegate); - } - - /** */ - @Override public int hashCode() { - return Objects.hash(this.delegate); - } - } -} diff --git a/modules/spring-session-ext/src/main/java/org/apache/ignite/spring/sessions/SpringSessionIgnite.java b/modules/spring-session-ext/src/main/java/org/apache/ignite/spring/sessions/SpringSessionIgnite.java deleted file mode 100644 index 82b51a4..0000000 --- a/modules/spring-session-ext/src/main/java/org/apache/ignite/spring/sessions/SpringSessionIgnite.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.apache.ignite.spring.sessions; - -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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. - */ - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.apache.ignite.Ignite; -import org.springframework.beans.factory.annotation.Qualifier; - -/** - * Qualifier annotation for a {@link Ignite} to be injected in - * {@link IgniteIndexedSessionRepository}. - * - */ -@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE }) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Qualifier -public @interface SpringSessionIgnite { -} diff --git a/modules/spring-session-ext/src/main/java/package-info.java b/modules/spring-session-ext/src/main/java/package-info.java deleted file mode 100644 index 8c21795..0000000 --- a/modules/spring-session-ext/src/main/java/package-info.java +++ /dev/null @@ -1,5 +0,0 @@ -/** - * <!-- Package description. --> - * Contains classes that allow using Ignite as backing store for storing Spring sessions. - */ -package org.apache.ignite.spring.sessions; diff --git a/modules/spring-session-ext/src/test/java/org/apache/ignite/spring/sessions/AbstractIgniteIndexedSessionRepositoryITest.java b/modules/spring-session-ext/src/test/java/org/apache/ignite/spring/sessions/AbstractIgniteIndexedSessionRepositoryITest.java deleted file mode 100644 index 7a6036a..0000000 --- a/modules/spring-session-ext/src/test/java/org/apache/ignite/spring/sessions/AbstractIgniteIndexedSessionRepositoryITest.java +++ /dev/null @@ -1,242 +0,0 @@ -package org.apache.ignite.spring.sessions; - -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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. - */ - -import java.time.Duration; - -import org.apache.ignite.Ignite; -import org.apache.ignite.IgniteCache; -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.authority.AuthorityUtils; -import org.springframework.security.core.context.SecurityContext; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.session.FindByIndexNameSessionRepository; - -import org.apache.ignite.spring.sessions.IgniteIndexedSessionRepository.IgniteSession; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Base class for {@link IgniteIndexedSessionRepository} integration tests. - */ -abstract class AbstractIgniteIndexedSessionRepositoryITest { - /** */ - private static final String SPRING_SECURITY_CONTEXT = "SPRING_SECURITY_CONTEXT"; - - /** */ - @Autowired - private Ignite ignite; - - /** */ - @Autowired - private IgniteIndexedSessionRepository repository; - - /** */ - @Test - void createAndDestroySession() { - IgniteIndexedSessionRepository.IgniteSession sessionToSave = this.repository.createSession(); - String sessionId = sessionToSave.getId(); - - IgniteCache<String, IgniteIndexedSessionRepository.IgniteSession> cache = this.ignite - .getOrCreateCache(IgniteIndexedSessionRepository.DEFAULT_SESSION_MAP_NAME); - - assertThat(cache.size()).isEqualTo(0); - - this.repository.save(sessionToSave); - - assertThat(cache.size()).isEqualTo(1); - assertThat(cache.get(sessionId)).isEqualTo(sessionToSave); - - this.repository.deleteById(sessionId); - - assertThat(cache.size()).isEqualTo(0); - } - - /** */ - @Test - void changeSessionIdWhenOnlyChangeId() { - String attrName = "changeSessionId"; - String attrValue = "changeSessionId-value"; - IgniteSession toSave = this.repository.createSession(); - toSave.setAttribute(attrName, attrValue); - - this.repository.save(toSave); - - IgniteSession findById = this.repository.findById(toSave.getId()); - - assertThat(findById.<String>getAttribute(attrName)).isEqualTo(attrValue); - - String originalFindById = findById.getId(); - String changeSessionId = findById.changeSessionId(); - - this.repository.save(findById); - - assertThat(this.repository.findById(originalFindById)).isNull(); - - IgniteSession findByChangeSessionId = this.repository.findById(changeSessionId); - - assertThat(findByChangeSessionId.<String>getAttribute(attrName)).isEqualTo(attrValue); - - this.repository.deleteById(changeSessionId); - } - - /** */ - @Test - void changeSessionIdWhenChangeTwice() { - IgniteSession toSave = this.repository.createSession(); - - this.repository.save(toSave); - - String originalId = toSave.getId(); - String changeId1 = toSave.changeSessionId(); - String changeId2 = toSave.changeSessionId(); - - this.repository.save(toSave); - - assertThat(this.repository.findById(originalId)).isNull(); - assertThat(this.repository.findById(changeId1)).isNull(); - assertThat(this.repository.findById(changeId2)).isNotNull(); - - this.repository.deleteById(changeId2); - } - - /** */ - @Test - void changeSessionIdWhenSetAttributeOnChangedSession() { - String attrName = "changeSessionId"; - String attrValue = "changeSessionId-value"; - - IgniteSession toSave = this.repository.createSession(); - - this.repository.save(toSave); - - IgniteSession findById = this.repository.findById(toSave.getId()); - - findById.setAttribute(attrName, attrValue); - - String originalFindById = findById.getId(); - String changeSessionId = findById.changeSessionId(); - - this.repository.save(findById); - - assertThat(this.repository.findById(originalFindById)).isNull(); - - IgniteSession findByChangeSessionId = this.repository.findById(changeSessionId); - - assertThat(findByChangeSessionId.<String>getAttribute(attrName)).isEqualTo(attrValue); - - this.repository.deleteById(changeSessionId); - } - - /** */ - @Test - void changeSessionIdWhenHasNotSaved() { - IgniteSession toSave = this.repository.createSession(); - String originalId = toSave.getId(); - toSave.changeSessionId(); - - this.repository.save(toSave); - - assertThat(this.repository.findById(toSave.getId())).isNotNull(); - assertThat(this.repository.findById(originalId)).isNull(); - - this.repository.deleteById(toSave.getId()); - } - - @Test - void attemptToUpdateSessionAfterDelete() { - IgniteSession session = this.repository.createSession(); - String sessionId = session.getId(); - this.repository.save(session); - session = this.repository.findById(sessionId); - session.setAttribute("attributeName", "attributeValue"); - this.repository.deleteById(sessionId); - this.repository.save(session); - - assertThat(this.repository.findById(sessionId)).isNull(); - } - - /** */ - @Test - void expireSession() { - IgniteSession session = this.repository.createSession(); - String sessionId = session.getId(); - - session.setMaxInactiveInterval(Duration.ofNanos(0)); - - this.repository.save(session); - assertThat(this.repository.findById(sessionId)).isNull(); - } - - /** */ - @Test - void createAndUpdateSession() { - IgniteSession session = this.repository.createSession(); - String sessionId = session.getId(); - - this.repository.save(session); - - session = this.repository.findById(sessionId); - session.setAttribute("attributeName", "attributeValue"); - - this.repository.save(session); - - assertThat(this.repository.findById(sessionId)).isNotNull(); - } - - /** */ - @Test - void createSessionWithSecurityContextAndFindById() { - IgniteSession session = this.repository.createSession(); - String sessionId = session.getId(); - - Authentication authentication = new UsernamePasswordAuthenticationToken("saves-" + System.currentTimeMillis(), - "password", AuthorityUtils.createAuthorityList("ROLE_USER")); - SecurityContext securityContext = SecurityContextHolder.createEmptyContext(); - securityContext.setAuthentication(authentication); - session.setAttribute(SPRING_SECURITY_CONTEXT, securityContext); - - this.repository.save(session); - - assertThat(this.repository.findById(sessionId)).isNotNull(); - } - - /** */ - @Test - void createSessionWithSecurityContextAndFindByPrincipal() { - IgniteSession session = this.repository.createSession(); - - String username = "saves-" + System.currentTimeMillis(); - Authentication authentication = new UsernamePasswordAuthenticationToken(username, "password", - AuthorityUtils.createAuthorityList("ROLE_USER")); - SecurityContext securityContext = SecurityContextHolder.createEmptyContext(); - securityContext.setAuthentication(authentication); - session.setAttribute(SPRING_SECURITY_CONTEXT, securityContext); - - this.repository.save(session); - - assertThat(this.repository - .findByIndexNameAndIndexValue(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, username)) - .hasSize(1); - } - -} diff --git a/modules/spring-session-ext/src/test/java/org/apache/ignite/spring/sessions/EmbeddedIgniteIndexedSessionRepositoryITest.java b/modules/spring-session-ext/src/test/java/org/apache/ignite/spring/sessions/EmbeddedIgniteIndexedSessionRepositoryITest.java deleted file mode 100644 index e40fc72..0000000 --- a/modules/spring-session-ext/src/test/java/org/apache/ignite/spring/sessions/EmbeddedIgniteIndexedSessionRepositoryITest.java +++ /dev/null @@ -1,65 +0,0 @@ -package org.apache.ignite.spring.sessions; - -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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. - */ - -import org.apache.ignite.Ignite; -import org.apache.ignite.Ignition; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit.jupiter.SpringExtension; -import org.springframework.test.context.web.WebAppConfiguration; - -/** - * Integration tests for {@link IgniteIndexedSessionRepository} using embedded topology. - */ -@ExtendWith(SpringExtension.class) -@ContextConfiguration -@WebAppConfiguration -public -class EmbeddedIgniteIndexedSessionRepositoryITest extends AbstractIgniteIndexedSessionRepositoryITest { - /** */ - @BeforeAll - static void setUpClass() { - Ignition.stopAll(true); - } - - /** */ - @AfterAll - static void tearDownClass() { - Ignition.stopAll(true); - } - - /** */ - @EnableIgniteHttpSession - @Configuration - static class IgniteSessionConfig { - - /** */ - @Bean - Ignite ignite() { - return IgniteITestUtils.embeddedIgniteServer(); - } - - } - -} diff --git a/modules/spring-session-ext/src/test/java/org/apache/ignite/spring/sessions/IgniteHttpSessionConfigurationTest.java b/modules/spring-session-ext/src/test/java/org/apache/ignite/spring/sessions/IgniteHttpSessionConfigurationTest.java deleted file mode 100644 index 0e69f4f..0000000 --- a/modules/spring-session-ext/src/test/java/org/apache/ignite/spring/sessions/IgniteHttpSessionConfigurationTest.java +++ /dev/null @@ -1,495 +0,0 @@ -package org.apache.ignite.spring.sessions; - -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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. - */ - -import org.apache.ignite.Ignite; -import org.apache.ignite.IgniteCache; -import org.apache.ignite.configuration.CacheConfiguration; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; -import org.mockito.ArgumentMatchers; - -import org.springframework.beans.factory.BeanCreationException; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; -import org.springframework.core.annotation.Order; -import org.springframework.session.FlushMode; -import org.springframework.session.IndexResolver; -import org.springframework.session.SaveMode; -import org.springframework.session.Session; -import org.springframework.session.config.SessionRepositoryCustomizer; -import org.springframework.test.util.ReflectionTestUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link IgniteHttpSessionConfiguration}. - */ -public class IgniteHttpSessionConfigurationTest { - /** */ - private static final String MAP_NAME = "spring:test:sessions"; - - /** */ - private static final int MAX_INACTIVE_INTERVAL_IN_SECONDS = 600; - - /** */ - private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); - - /** */ - @AfterEach - void closeContext() { - if (this.context != null) - this.context.close(); - } - - /** */ - @Test - void noIgniteConfiguration() { - assertThatExceptionOfType(BeanCreationException.class) - .isThrownBy(() -> registerAndRefresh(NoIgniteConfiguration.class)).withMessageContaining("Ignite"); - } - - /** */ - @Test - void defaultConfiguration() { - registerAndRefresh(DefaultConfiguration.class); - - assertThat(this.context.getBean(IgniteIndexedSessionRepository.class)).isNotNull(); - } - - /** */ - @Test - void customTableName() { - registerAndRefresh(CustomSessionMapNameConfiguration.class); - - IgniteIndexedSessionRepository repository = this.context.getBean(IgniteIndexedSessionRepository.class); - IgniteHttpSessionConfiguration configuration = this.context.getBean(IgniteHttpSessionConfiguration.class); - assertThat(repository).isNotNull(); - assertThat(ReflectionTestUtils.getField(configuration, "sessionMapName")).isEqualTo(MAP_NAME); - } - - /** */ - @Test - void setCustomSessionMapName() { - registerAndRefresh(BaseConfiguration.class, CustomSessionMapNameSetConfiguration.class); - - IgniteIndexedSessionRepository repository = this.context.getBean(IgniteIndexedSessionRepository.class); - IgniteHttpSessionConfiguration configuration = this.context.getBean(IgniteHttpSessionConfiguration.class); - assertThat(repository).isNotNull(); - assertThat(ReflectionTestUtils.getField(configuration, "sessionMapName")).isEqualTo(MAP_NAME); - } - - /** */ - @Test - void setCustomMaxInactiveIntervalInSeconds() { - registerAndRefresh(BaseConfiguration.class, CustomMaxInactiveIntervalInSecondsSetConfiguration.class); - - IgniteIndexedSessionRepository repository = this.context.getBean(IgniteIndexedSessionRepository.class); - assertThat(repository).isNotNull(); - assertThat(ReflectionTestUtils.getField(repository, "defaultMaxInactiveInterval")) - .isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS); - } - - /** */ - @Test - void customMaxInactiveIntervalInSeconds() { - registerAndRefresh(CustomMaxInactiveIntervalInSecondsConfiguration.class); - - IgniteIndexedSessionRepository repository = this.context.getBean(IgniteIndexedSessionRepository.class); - assertThat(repository).isNotNull(); - assertThat(ReflectionTestUtils.getField(repository, "defaultMaxInactiveInterval")) - .isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS); - } - - /** */ - @Test - void customFlushImmediately() { - registerAndRefresh(CustomFlushImmediatelyConfiguration.class); - - IgniteIndexedSessionRepository repository = this.context.getBean(IgniteIndexedSessionRepository.class); - assertThat(repository).isNotNull(); - assertThat(ReflectionTestUtils.getField(repository, "flushMode")).isEqualTo(FlushMode.IMMEDIATE); - } - - /** */ - @Test - void setCustomFlushImmediately() { - registerAndRefresh(BaseConfiguration.class, CustomFlushImmediatelySetConfiguration.class); - - IgniteIndexedSessionRepository repository = this.context.getBean(IgniteIndexedSessionRepository.class); - assertThat(repository).isNotNull(); - assertThat(ReflectionTestUtils.getField(repository, "flushMode")).isEqualTo(FlushMode.IMMEDIATE); - } - - /** */ - @Test - void customSaveModeAnnotation() { - registerAndRefresh(BaseConfiguration.class, CustomSaveModeExpressionAnnotationConfiguration.class); - assertThat(this.context.getBean(IgniteIndexedSessionRepository.class)).hasFieldOrPropertyWithValue("saveMode", - SaveMode.ALWAYS); - } - - /** */ - @Test - void customSaveModeSetter() { - registerAndRefresh(BaseConfiguration.class, CustomSaveModeExpressionSetterConfiguration.class); - assertThat(this.context.getBean(IgniteIndexedSessionRepository.class)).hasFieldOrPropertyWithValue("saveMode", - SaveMode.ALWAYS); - } - - /** */ - @Test - void qualifiedIgniteConfiguration() { - registerAndRefresh(QualifiedIgniteConfiguration.class); - - IgniteIndexedSessionRepository repository = this.context.getBean(IgniteIndexedSessionRepository.class); - Ignite ignite = this.context.getBean("qualifiedIgnite", Ignite.class); - assertThat(repository).isNotNull(); - assertThat(ignite).isNotNull(); - assertThat(ReflectionTestUtils.getField(repository, "sessions")) - .isEqualTo(QualifiedIgniteConfiguration.qualifiedIgniteSessions); - } - - /** */ - @Test - void primaryIgniteConfiguration() { - registerAndRefresh(PrimaryIgniteConfiguration.class); - - IgniteIndexedSessionRepository repository = this.context.getBean(IgniteIndexedSessionRepository.class); - Ignite ignite = this.context.getBean("primaryIgnite", Ignite.class); - assertThat(repository).isNotNull(); - assertThat(ignite).isNotNull(); - assertThat(ReflectionTestUtils.getField(repository, "sessions")) - .isEqualTo(PrimaryIgniteConfiguration.primaryIgniteSessions); - } - - /** */ - @Test - void qualifiedAndPrimaryIgniteConfiguration() { - registerAndRefresh(QualifiedAndPrimaryIgniteConfiguration.class); - - IgniteIndexedSessionRepository repository = this.context.getBean(IgniteIndexedSessionRepository.class); - Ignite ignite = this.context.getBean("qualifiedIgnite", Ignite.class); - assertThat(repository).isNotNull(); - assertThat(ignite).isNotNull(); - assertThat(ReflectionTestUtils.getField(repository, "sessions")) - .isEqualTo(QualifiedAndPrimaryIgniteConfiguration.qualifiedIgniteSessions); - } - - /** */ - @Test - void namedIgniteConfiguration() { - registerAndRefresh(NamedIgniteConfiguration.class); - - IgniteIndexedSessionRepository repository = this.context.getBean(IgniteIndexedSessionRepository.class); - Ignite ignite = this.context.getBean("ignite", Ignite.class); - assertThat(repository).isNotNull(); - assertThat(ignite).isNotNull(); - assertThat(ReflectionTestUtils.getField(repository, "sessions")) - .isEqualTo(NamedIgniteConfiguration.igniteSessions); - } - - /** */ - @Test - void multipleIgniteConfiguration() { - assertThatExceptionOfType(BeanCreationException.class) - .isThrownBy(() -> registerAndRefresh(MultipleIgniteConfiguration.class)) - .withMessageContaining("expected single matching bean but found 2"); - } - - /** */ - @Test - void customIndexResolverConfiguration() { - registerAndRefresh(CustomIndexResolverConfiguration.class); - IgniteIndexedSessionRepository repository = this.context.getBean(IgniteIndexedSessionRepository.class); - @SuppressWarnings("unchecked") - IndexResolver<Session> indexResolver = this.context.getBean(IndexResolver.class); - assertThat(repository).isNotNull(); - assertThat(indexResolver).isNotNull(); - assertThat(repository).hasFieldOrPropertyWithValue("indexResolver", indexResolver); - } - - /** */ - @Test - void sessionRepositoryCustomizer() { - registerAndRefresh(SessionRepositoryCustomizerConfiguration.class); - IgniteIndexedSessionRepository sessionRepository = this.context.getBean(IgniteIndexedSessionRepository.class); - assertThat(sessionRepository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", - MAX_INACTIVE_INTERVAL_IN_SECONDS); - } - - /** */ - private void registerAndRefresh(Class<?>... annotatedClasses) { - this.context.register(annotatedClasses); - this.context.refresh(); - } - - /** */ - @Configuration - @EnableIgniteHttpSession - static class NoIgniteConfiguration { - - } - - /** */ - static class BaseConfiguration { - - /** */ - @SuppressWarnings("unchecked") - static IgniteCache<Object, Object> defaultIgniteSessions = mock(IgniteCache.class); - - /** */ - @Bean - Ignite defaultIgnite() { - Ignite ignite = mock(Ignite.class); - given(ignite.getOrCreateCache(ArgumentMatchers.<CacheConfiguration<Object, Object>>any())) - .willReturn(defaultIgniteSessions); - return ignite; - } - - } - - /** */ - @Configuration - @EnableIgniteHttpSession - static class DefaultConfiguration extends BaseConfiguration { - - } - - /** */ - @Configuration - @EnableIgniteHttpSession(sessionMapName = MAP_NAME) - static class CustomSessionMapNameConfiguration extends BaseConfiguration { - - } - - /** */ - @Configuration - static class CustomSessionMapNameSetConfiguration extends IgniteHttpSessionConfiguration { - - CustomSessionMapNameSetConfiguration() { - setSessionMapName(MAP_NAME); - } - - } - - /** */ - @Configuration - static class CustomMaxInactiveIntervalInSecondsSetConfiguration extends IgniteHttpSessionConfiguration { - - CustomMaxInactiveIntervalInSecondsSetConfiguration() { - setMaxInactiveIntervalInSeconds(MAX_INACTIVE_INTERVAL_IN_SECONDS); - } - - } - - /** */ - @Configuration - @EnableIgniteHttpSession(maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS) - static class CustomMaxInactiveIntervalInSecondsConfiguration extends BaseConfiguration { - - } - - /** */ - @Configuration - static class CustomFlushImmediatelySetConfiguration extends IgniteHttpSessionConfiguration { - - CustomFlushImmediatelySetConfiguration() { - setFlushMode(FlushMode.IMMEDIATE); - } - - } - - /** */ - @EnableIgniteHttpSession(saveMode = SaveMode.ALWAYS) - static class CustomSaveModeExpressionAnnotationConfiguration { - - } - - /** */ - @Configuration - static class CustomSaveModeExpressionSetterConfiguration extends IgniteHttpSessionConfiguration { - - CustomSaveModeExpressionSetterConfiguration() { - setSaveMode(SaveMode.ALWAYS); - } - - } - - /** */ - @Configuration - @EnableIgniteHttpSession(flushMode = FlushMode.IMMEDIATE) - static class CustomFlushImmediatelyConfiguration extends BaseConfiguration { - - } - - /** */ - @Configuration - @EnableIgniteHttpSession - static class QualifiedIgniteConfiguration extends BaseConfiguration { - - /** */ - @SuppressWarnings("unchecked") - static IgniteCache<Object, Object> qualifiedIgniteSessions = mock(IgniteCache.class); - - /** */ - @Bean - @SpringSessionIgnite - Ignite qualifiedIgnite() { - Ignite ignite = mock(Ignite.class); - given(ignite.getOrCreateCache(ArgumentMatchers.<CacheConfiguration<Object, Object>>any())) - .willReturn(qualifiedIgniteSessions); - return ignite; - } - - } - - /** */ - @Configuration - @EnableIgniteHttpSession - static class PrimaryIgniteConfiguration extends BaseConfiguration { - - /** */ - @SuppressWarnings("unchecked") - static IgniteCache<Object, Object> primaryIgniteSessions = mock(IgniteCache.class); - - /** */ - @Bean - @Primary - Ignite primaryIgnite() { - Ignite ignite = mock(Ignite.class); - given(ignite.getOrCreateCache(ArgumentMatchers.<CacheConfiguration<Object, Object>>any())) - .willReturn(primaryIgniteSessions); - return ignite; - } - - } - - /** */ - @Configuration - @EnableIgniteHttpSession - static class QualifiedAndPrimaryIgniteConfiguration extends BaseConfiguration { - - /** */ - @SuppressWarnings("unchecked") - static IgniteCache<Object, Object> qualifiedIgniteSessions = mock(IgniteCache.class); - - /** */ - @SuppressWarnings("unchecked") - static IgniteCache<Object, Object> primaryIgniteSessions = mock(IgniteCache.class); - - /** */ - @Bean - @SpringSessionIgnite - Ignite qualifiedIgnite() { - Ignite ignite = mock(Ignite.class); - given(ignite.getOrCreateCache(ArgumentMatchers.<CacheConfiguration<Object, Object>>any())) - .willReturn(qualifiedIgniteSessions); - return ignite; - } - - /** */ - @Bean - @Primary - Ignite primaryIgnite() { - Ignite ignite = mock(Ignite.class); - given(ignite.getOrCreateCache(ArgumentMatchers.<CacheConfiguration<Object, Object>>any())) - .willReturn(primaryIgniteSessions); - return ignite; - } - - } - - /** */ - @Configuration - @EnableIgniteHttpSession - static class NamedIgniteConfiguration extends BaseConfiguration { - - /** */ - @SuppressWarnings("unchecked") - static IgniteCache<Object, Object> igniteSessions = mock(IgniteCache.class); - - /** */ - @Bean - Ignite ignite() { - Ignite ignite = mock(Ignite.class); - given(ignite.getOrCreateCache(ArgumentMatchers.<CacheConfiguration<Object, Object>>any())) - .willReturn(igniteSessions); - return ignite; - } - - } - - /** */ - @Configuration - @EnableIgniteHttpSession - static class MultipleIgniteConfiguration extends BaseConfiguration { - - /** */ - @SuppressWarnings("unchecked") - static IgniteCache<Object, Object> secondaryIgniteSessions = mock(IgniteCache.class); - - /** */ - @Bean - Ignite secondaryIgnite() { - Ignite ignite = mock(Ignite.class); - given(ignite.getOrCreateCache(ArgumentMatchers.<CacheConfiguration<Object, Object>>any())) - .willReturn(secondaryIgniteSessions); - return ignite; - } - - } - - /** */ - @EnableIgniteHttpSession - static class CustomIndexResolverConfiguration extends BaseConfiguration { - - /** */ - @Bean - @SuppressWarnings("unchecked") - IndexResolver<Session> indexResolver() { - return mock(IndexResolver.class); - } - - } - - /** */ - @EnableIgniteHttpSession - static class SessionRepositoryCustomizerConfiguration extends BaseConfiguration { - - /** */ - @Bean - @Order(0) - SessionRepositoryCustomizer<IgniteIndexedSessionRepository> sessionRepositoryCustomizerOne() { - return (sessionRepository) -> sessionRepository.setDefaultMaxInactiveInterval(0); - } - - /** */ - @Bean - @Order(1) - SessionRepositoryCustomizer<IgniteIndexedSessionRepository> sessionRepositoryCustomizerTwo() { - return (sessionRepository) -> sessionRepository - .setDefaultMaxInactiveInterval(MAX_INACTIVE_INTERVAL_IN_SECONDS); - } - } -} diff --git a/modules/spring-session-ext/src/test/java/org/apache/ignite/spring/sessions/IgniteITestUtils.java b/modules/spring-session-ext/src/test/java/org/apache/ignite/spring/sessions/IgniteITestUtils.java deleted file mode 100644 index f0b2a94..0000000 --- a/modules/spring-session-ext/src/test/java/org/apache/ignite/spring/sessions/IgniteITestUtils.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.apache.ignite.spring.sessions; - -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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. - */ - -import org.apache.ignite.Ignite; -import org.apache.ignite.Ignition; - -/** - * Utility class for Ignite integration tests. - */ -final class IgniteITestUtils { - private IgniteITestUtils() { - } - - /** - * Creates {@link Ignite} for use in integration tests. - * @return the Ignite instance - */ - static Ignite embeddedIgniteServer() { - return Ignition.start(); - } -} diff --git a/modules/spring-session-ext/src/test/java/org/apache/ignite/spring/sessions/IgniteIndexedSessionRepositoryTest.java b/modules/spring-session-ext/src/test/java/org/apache/ignite/spring/sessions/IgniteIndexedSessionRepositoryTest.java deleted file mode 100644 index 61f4eb8..0000000 --- a/modules/spring-session-ext/src/test/java/org/apache/ignite/spring/sessions/IgniteIndexedSessionRepositoryTest.java +++ /dev/null @@ -1,483 +0,0 @@ -package org.apache.ignite.spring.sessions; - -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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. - */ - -import java.time.Duration; -import java.time.Instant; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -import javax.cache.expiry.TouchedExpiryPolicy; - -import org.apache.ignite.Ignite; -import org.apache.ignite.IgniteCache; -import org.apache.ignite.cache.query.FieldsQueryCursor; -import org.apache.ignite.configuration.CacheConfiguration; -import org.jetbrains.annotations.NotNull; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.ArgumentMatchers; - -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.authority.AuthorityUtils; -import org.springframework.session.FindByIndexNameSessionRepository; -import org.springframework.session.FlushMode; -import org.springframework.session.MapSession; -import org.apache.ignite.spring.sessions.IgniteIndexedSessionRepository.IgniteSession; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; - -/** - * Tests for {@link IgniteIndexedSessionRepository}. - */ -public class IgniteIndexedSessionRepositoryTest { - /** */ - private static final String SPRING_SECURITY_CONTEXT = "SPRING_SECURITY_CONTEXT"; - - /** */ - private final Ignite ignite = mock(Ignite.class); - - /** */ - @SuppressWarnings("unchecked") - private final IgniteCache<String, IgniteSession> sessions = mock(IgniteCache.class); - - /** */ - private IgniteIndexedSessionRepository repository; - - /** */ - @BeforeEach - void setUp() { - given(this.ignite.<String, IgniteSession>getOrCreateCache( - ArgumentMatchers.<CacheConfiguration<String, IgniteSession>>any())).willReturn(this.sessions); - given(this.sessions.withExpiryPolicy(ArgumentMatchers.any())).willReturn(this.sessions); - this.repository = new IgniteIndexedSessionRepository(this.ignite); - this.repository.init(); - } - - /** */ - @Test - void constructorNullIgnite() { - assertThatIllegalArgumentException().isThrownBy(() -> new IgniteIndexedSessionRepository(null)) - .withMessage("Ignite must not be null"); - } - - /** */ - @Test - void setSaveModeNull() { - assertThatIllegalArgumentException().isThrownBy(() -> this.repository.setSaveMode(null)) - .withMessage("saveMode must not be null"); - } - - /** */ - @Test - void createSessionDefaultMaxInactiveInterval() { - verify(this.sessions, times(1)).registerCacheEntryListener(ArgumentMatchers.any()); - - IgniteSession session = this.repository.createSession(); - - assertThat(session.getMaxInactiveInterval()).isEqualTo(new MapSession().getMaxInactiveInterval()); - verifyNoMoreInteractions(this.sessions); - } - - /** */ - @Test - void createSessionCustomMaxInactiveInterval() { - verify(this.sessions, times(1)).registerCacheEntryListener(ArgumentMatchers.any()); - - int interval = 1; - this.repository.setDefaultMaxInactiveInterval(interval); - - IgniteSession session = this.repository.createSession(); - - assertThat(session.getMaxInactiveInterval()).isEqualTo(Duration.ofSeconds(interval)); - verifyNoMoreInteractions(this.sessions); - } - - /** */ - @Test - void saveNewFlushModeOnSave() { - verify(this.sessions, times(1)).registerCacheEntryListener(ArgumentMatchers.any()); - - IgniteSession session = this.repository.createSession(); - verifyNoMoreInteractions(this.sessions); - - this.repository.save(session); - verify(this.sessions, times(1)).put(eq(session.getId()), eq(session)); - verify(this.sessions, times(1)).withExpiryPolicy(eq(createExpiryPolicy(session))); - verifyNoMoreInteractions(this.sessions); - } - - /** */ - @Test - void saveNewFlushModeImmediate() { - verify(this.sessions, times(1)).registerCacheEntryListener(ArgumentMatchers.any()); - - this.repository.setFlushMode(FlushMode.IMMEDIATE); - - IgniteSession session = this.repository.createSession(); - verify(this.sessions, times(1)).put(eq(session.getId()), eq(session)); - verify(this.sessions, times(1)).withExpiryPolicy(eq(createExpiryPolicy(session))); - verifyNoMoreInteractions(this.sessions); - } - - /** */ - @Test - void saveUpdatedAttributeFlushModeOnSave() { - verify(this.sessions, times(1)).registerCacheEntryListener(ArgumentMatchers.any()); - - IgniteSession session = this.repository.createSession(); - session.setAttribute("testName", "testValue"); - verifyNoMoreInteractions(this.sessions); - - this.repository.save(session); - verify(this.sessions, times(1)).put(eq(session.getId()), eq(session)); - verify(this.sessions, times(1)).withExpiryPolicy(eq(createExpiryPolicy(session))); - verifyNoMoreInteractions(this.sessions); - } - - @Test - void saveUpdatedAttributeFlushModeImmediate() { - verify(this.sessions, times(1)).registerCacheEntryListener(ArgumentMatchers.any()); - - this.repository.setFlushMode(FlushMode.IMMEDIATE); - - IgniteSession session = this.repository.createSession(); - session.setAttribute("testName", "testValue"); - verify(this.sessions, times(1)).withExpiryPolicy(eq(createExpiryPolicy(session))); - verify(this.sessions, times(1)).put(eq(session.getId()), eq(session)); - verify(this.sessions, times(1)).replace(eq(session.getId()), eq(session)); - - this.repository.save(session); - verifyNoMoreInteractions(this.sessions); - } - - /** */ - @Test - void removeAttributeFlushModeOnSave() { - verify(this.sessions, times(1)).registerCacheEntryListener(ArgumentMatchers.any()); - - IgniteSession session = this.repository.createSession(); - session.removeAttribute("testName"); - verifyNoMoreInteractions(this.sessions); - - this.repository.save(session); - verify(this.sessions, times(1)).put(eq(session.getId()), eq(session)); - verify(this.sessions, times(1)).withExpiryPolicy(eq(createExpiryPolicy(session))); - verifyNoMoreInteractions(this.sessions); - } - - /** */ - @Test - void removeAttributeFlushModeImmediate() { - verify(this.sessions, times(1)).registerCacheEntryListener(ArgumentMatchers.any()); - - this.repository.setFlushMode(FlushMode.IMMEDIATE); - - IgniteSession session = this.repository.createSession(); - session.removeAttribute("testName"); - verify(this.sessions, times(1)).put(eq(session.getId()), eq(session)); - verify(this.sessions, times(1)).replace(eq(session.getId()), eq(session)); - verify(this.sessions, times(1)).withExpiryPolicy(eq(createExpiryPolicy(session))); - - this.repository.save(session); - verifyNoMoreInteractions(this.sessions); - } - - /** */ - @Test - void saveUpdatedLastAccessedTimeFlushModeOnSave() { - verify(this.sessions, times(1)).registerCacheEntryListener(ArgumentMatchers.any()); - - IgniteSession session = this.repository.createSession(); - session.setLastAccessedTime(Instant.now()); - verifyNoMoreInteractions(this.sessions); - - this.repository.save(session); - verify(this.sessions, times(1)).put(eq(session.getId()), eq(session)); - verify(this.sessions, times(1)).withExpiryPolicy(eq(createExpiryPolicy(session))); - verifyNoMoreInteractions(this.sessions); - } - - /** */ - @Test - void saveUpdatedLastAccessedTimeFlushModeImmediate() { - verify(this.sessions, times(1)).registerCacheEntryListener(ArgumentMatchers.any()); - - this.repository.setFlushMode(FlushMode.IMMEDIATE); - - IgniteSession session = this.repository.createSession(); - session.setLastAccessedTime(Instant.now()); - verify(this.sessions, times(1)).put(eq(session.getId()), eq(session)); - verify(this.sessions, times(1)).replace(eq(session.getId()), eq(session)); - verify(this.sessions, times(1)).withExpiryPolicy(eq(createExpiryPolicy(session))); - - this.repository.save(session); - verifyNoMoreInteractions(this.sessions); - } - - /** */ - @Test - void saveUpdatedMaxInactiveIntervalInSecondsFlushModeOnSave() { - verify(this.sessions, times(1)).registerCacheEntryListener(ArgumentMatchers.any()); - - IgniteSession session = this.repository.createSession(); - session.setMaxInactiveInterval(Duration.ofSeconds(1)); - verifyNoMoreInteractions(this.sessions); - - this.repository.save(session); - verify(this.sessions, times(1)).put(eq(session.getId()), eq(session)); - verify(this.sessions, times(1)).withExpiryPolicy(eq(createExpiryPolicy(session))); - verifyNoMoreInteractions(this.sessions); - } - - /** */ - @Test - void saveUpdatedMaxInactiveIntervalInSecondsFlushModeImmediate() { - verify(this.sessions, times(1)).registerCacheEntryListener(ArgumentMatchers.any()); - - this.repository.setFlushMode(FlushMode.IMMEDIATE); - - IgniteSession session = this.repository.createSession(); - verify(this.sessions, times(1)).withExpiryPolicy(eq(createExpiryPolicy(session))); - String sessionId = session.getId(); - session.setMaxInactiveInterval(Duration.ofSeconds(1)); - verify(this.sessions, times(1)).put(eq(sessionId), eq(session)); - verify(this.sessions, times(1)).replace(eq(sessionId), eq(session)); - verify(this.sessions, times(1)).withExpiryPolicy(eq(createExpiryPolicy(session))); - - this.repository.save(session); - verifyNoMoreInteractions(this.sessions); - } - - /** */ - @Test - void saveUnchangedFlushModeOnSave() { - verify(this.sessions, times(1)).registerCacheEntryListener(ArgumentMatchers.any()); - - IgniteSession session = this.repository.createSession(); - this.repository.save(session); - verify(this.sessions, times(1)).put(eq(session.getId()), eq(session)); - verify(this.sessions, times(1)).withExpiryPolicy(eq(createExpiryPolicy(session))); - - this.repository.save(session); - verifyNoMoreInteractions(this.sessions); - } - - /** */ - @Test - void saveUnchangedFlushModeImmediate() { - verify(this.sessions, times(1)).registerCacheEntryListener(ArgumentMatchers.any()); - - this.repository.setFlushMode(FlushMode.IMMEDIATE); - - IgniteSession session = this.repository.createSession(); - verify(this.sessions, times(1)).put(eq(session.getId()), eq(session)); - verify(this.sessions, times(1)).withExpiryPolicy(eq(createExpiryPolicy(session))); - - this.repository.save(session); - verifyNoMoreInteractions(this.sessions); - } - - /** */ - @Test - void getSessionNotFound() { - verify(this.sessions, times(1)).registerCacheEntryListener(ArgumentMatchers.any()); - - String sessionId = "testSessionId"; - - IgniteSession session = this.repository.findById(sessionId); - - assertThat(session).isNull(); - verify(this.sessions, times(1)).get(eq(sessionId)); - verifyNoMoreInteractions(this.sessions); - } - - /** */ - @Test - void getSessionExpired() { - verify(this.sessions, times(1)).registerCacheEntryListener(ArgumentMatchers.any()); - - IgniteSession expired = this.repository.new IgniteSession(new MapSession(), true); - - expired.setLastAccessedTime(Instant.now().minusSeconds(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS + 1)); - given(this.sessions.get(eq(expired.getId()))).willReturn(expired); - - IgniteSession session = this.repository.findById(expired.getId()); - - assertThat(session).isNull(); - verify(this.sessions, times(1)).get(eq(expired.getId())); - verify(this.sessions, times(1)).remove(eq(expired.getId())); - verifyNoMoreInteractions(this.sessions); - } - - /** */ - @Test - void getSessionFound() { - verify(this.sessions, times(1)).registerCacheEntryListener(ArgumentMatchers.any()); - - IgniteSession saved = this.repository.new IgniteSession(new MapSession(), true); - saved.setAttribute("savedName", "savedValue"); - given(this.sessions.get(eq(saved.getId()))).willReturn(saved); - - IgniteSession session = this.repository.findById(saved.getId()); - - assertThat(session.getId()).isEqualTo(saved.getId()); - assertThat(session.<String>getAttribute("savedName")).isEqualTo("savedValue"); - verify(this.sessions, times(1)).get(eq(saved.getId())); - verifyNoMoreInteractions(this.sessions); - } - - /** */ - @Test - void delete() { - verify(this.sessions, times(1)).registerCacheEntryListener(ArgumentMatchers.any()); - - String sessionId = "testSessionId"; - - this.repository.deleteById(sessionId); - - verify(this.sessions, times(1)).remove(eq(sessionId)); - verifyNoMoreInteractions(this.sessions); - } - - /** */ - @Test - void findByIndexNameAndIndexValueUnknownIndexName() { - verify(this.sessions, times(1)).registerCacheEntryListener(ArgumentMatchers.any()); - - String indexValue = "testIndexValue"; - - Map<String, IgniteSession> sessions = this.repository.findByIndexNameAndIndexValue("testIndexName", indexValue); - - assertThat(sessions).isEmpty(); - verifyNoMoreInteractions(this.sessions); - } - - /** */ - @Test - void findByIndexNameAndIndexValuePrincipalIndexNameNotFound() { - verify(this.sessions, times(1)).registerCacheEntryListener(ArgumentMatchers.any()); - - String principal = "username"; - - Map<String, IgniteSession> sessions = this.repository - .findByIndexNameAndIndexValue(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, principal); - - verify(this.sessions, times(1)).query(ArgumentMatchers - .argThat((argument) -> ("SELECT * FROM IgniteSession WHERE principal='" + principal + "'") - .equals(argument.getSql()))); - - assertThat(sessions).isEmpty(); - verifyNoMoreInteractions(this.sessions); - } - - /** */ - @Test - void findByIndexNameAndIndexValuePrincipalIndexNameFound() { - verify(this.sessions, times(1)).registerCacheEntryListener(ArgumentMatchers.any()); - - String principal = "username"; - Authentication authentication = new UsernamePasswordAuthenticationToken(principal, "notused", - AuthorityUtils.createAuthorityList("ROLE_USER")); - - List<Object> saved = new ArrayList<>(2); - - final MapSession ses1 = new MapSession(); - ses1.setAttribute(SPRING_SECURITY_CONTEXT, authentication); - IgniteSession saved1 = this.repository.new IgniteSession(ses1, true); - saved.add(Arrays.asList(ses1, authentication.getPrincipal())); - final MapSession ses2 = new MapSession(); - ses2.setAttribute(SPRING_SECURITY_CONTEXT, authentication); - IgniteSession saved2 = this.repository.new IgniteSession(ses2, true); - saved.add(Arrays.asList(ses2, authentication.getPrincipal())); - - given(this.sessions.query(ArgumentMatchers.any())).willReturn(new FieldsQueryCursor<List<?>>() { - /** */ - @Override - public String getFieldName(int idx) { - return null; - } - - /** */ - @Override - public int getColumnsCount() { - return 2; - } - - /** */ - @Override - public List<List<?>> getAll() { - return (List) saved; - } - - /** */ - @Override - public void close() { - - } - - /** */ - @NotNull - @Override - public Iterator<List<?>> iterator() { - return (Iterator) saved.iterator(); - } - }); - - Map<String, IgniteSession> sessions = this.repository - .findByIndexNameAndIndexValue(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, principal); - - assertThat(sessions).hasSize(2); - verify(this.sessions, times(1)).query(any()); - verifyNoMoreInteractions(this.sessions); - } - - /** */ - @Test - void getAttributeNamesAndRemove() { - IgniteSession session = this.repository.createSession(); - session.setAttribute("attribute1", "value1"); - session.setAttribute("attribute2", "value2"); - - for (String attributeName : session.getAttributeNames()) { - session.removeAttribute(attributeName); - } - - assertThat(session.getAttributeNames()).isEmpty(); - } - - /** */ - private static TouchedExpiryPolicy createExpiryPolicy(IgniteSession session) { - return new TouchedExpiryPolicy( - new javax.cache.expiry.Duration(TimeUnit.SECONDS, session.getMaxInactiveInterval().getSeconds())); - } - -} diff --git a/modules/spring-session-ext/src/test/java/org/apache/ignite/testsuites/IgniteSpringSessionTestSuite.java b/modules/spring-session-ext/src/test/java/org/apache/ignite/testsuites/IgniteSpringSessionTestSuite.java deleted file mode 100644 index 880119e..0000000 --- a/modules/spring-session-ext/src/test/java/org/apache/ignite/testsuites/IgniteSpringSessionTestSuite.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.apache.ignite.testsuites; - -import org.apache.ignite.spring.sessions.EmbeddedIgniteIndexedSessionRepositoryITest; -import org.apache.ignite.spring.sessions.IgniteHttpSessionConfigurationTest; -import org.apache.ignite.spring.sessions.IgniteIndexedSessionRepositoryTest; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Ignite Spring Session Test Suite - */ -@RunWith(Suite.class) [email protected]({ - EmbeddedIgniteIndexedSessionRepositoryITest.class, - IgniteHttpSessionConfigurationTest.class, - IgniteIndexedSessionRepositoryTest.class -}) -public class IgniteSpringSessionTestSuite { -} diff --git a/pom.xml b/pom.xml index 27249de..8682549 100644 --- a/pom.xml +++ b/pom.xml @@ -62,7 +62,6 @@ <module>modules/performance-statistics-ext</module> <module>modules/spring-tx-ext</module> <module>modules/spring-cache-ext</module> - <module>modules/spring-session-ext</module> </modules> <profiles>
