diff --git a/spring-session/src/integration-test/java/org/springframework/session/hazelcast/AbstractHazelcastRepositoryITests.java b/spring-session/src/integration-test/java/org/springframework/session/hazelcast/AbstractHazelcastRepositoryITests.java index a17845fa..6c9012ef 100644 --- a/spring-session/src/integration-test/java/org/springframework/session/hazelcast/AbstractHazelcastRepositoryITests.java +++ b/spring-session/src/integration-test/java/org/springframework/session/hazelcast/AbstractHazelcastRepositoryITests.java @@ -18,9 +18,17 @@ package org.springframework.session.hazelcast; import com.hazelcast.core.HazelcastInstance; import com.hazelcast.core.IMap; +import com.hazelcast.instance.HazelcastInstanceProxy; +import org.junit.Assume; import org.junit.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.springframework.session.MapSession; import org.springframework.session.hazelcast.HazelcastSessionRepository.HazelcastSession; @@ -34,8 +42,10 @@ import static org.assertj.core.api.Assertions.assertThat; */ public abstract class AbstractHazelcastRepositoryITests { + private static final String SPRING_SECURITY_CONTEXT = "SPRING_SECURITY_CONTEXT"; + @Autowired - private HazelcastInstance hazelcast; + private HazelcastInstance hazelcastInstance; @Autowired private HazelcastSessionRepository repository; @@ -45,8 +55,8 @@ public abstract class AbstractHazelcastRepositoryITests { HazelcastSession sessionToSave = this.repository.createSession(); String sessionId = sessionToSave.getId(); - IMap hazelcastMap = this.hazelcast.getMap( - "spring:session:sessions"); + IMap hazelcastMap = this.hazelcastInstance + .getMap("spring:session:sessions"); assertThat(hazelcastMap.size()).isEqualTo(0); @@ -73,4 +83,57 @@ public abstract class AbstractHazelcastRepositoryITests { assertThat(this.repository.getSession(sessionId)).isNull(); } + @Test + public void createAndUpdateSession() { + HazelcastSession session = this.repository.createSession(); + String sessionId = session.getId(); + + this.repository.save(session); + + session = this.repository.getSession(sessionId); + session.setAttribute("attributeName", "attributeValue"); + + this.repository.save(session); + + assertThat(this.repository.getSession(sessionId)).isNotNull(); + } + + @Test + public void createSessionWithSecurityContextAndFindById() { + HazelcastSession 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.getSession(sessionId)).isNotNull(); + } + + @Test + public void createSessionWithSecurityContextAndFindByPrincipal() { + Assume.assumeTrue("Hazelcast runs in embedded server topology", + this.hazelcastInstance instanceof HazelcastInstanceProxy); + + HazelcastSession 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)) + .isNotNull(); + } + } diff --git a/spring-session/src/integration-test/java/org/springframework/session/hazelcast/HazelcastClientRepositoryITests.java b/spring-session/src/integration-test/java/org/springframework/session/hazelcast/HazelcastClientRepositoryITests.java index 7dab0184..ec70e672 100644 --- a/spring-session/src/integration-test/java/org/springframework/session/hazelcast/HazelcastClientRepositoryITests.java +++ b/spring-session/src/integration-test/java/org/springframework/session/hazelcast/HazelcastClientRepositoryITests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-2018 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. @@ -49,12 +49,12 @@ public class HazelcastClientRepositoryITests extends AbstractHazelcastRepository private static HazelcastInstance hazelcastInstance; @BeforeClass - public static void setup() { + public static void setUpClass() { hazelcastInstance = HazelcastITestUtils.embeddedHazelcastServer(PORT); } @AfterClass - public static void teardown() { + public static void tearDownClass() { if (hazelcastInstance != null) { hazelcastInstance.shutdown(); } @@ -65,7 +65,7 @@ public class HazelcastClientRepositoryITests extends AbstractHazelcastRepository static class HazelcastSessionConfig { @Bean - public HazelcastInstance embeddedHazelcastClient() { + public HazelcastInstance hazelcastInstance() { ClientConfig clientConfig = new ClientConfig(); clientConfig.getNetworkConfig().addAddress("127.0.0.1:" + PORT); return HazelcastClient.newHazelcastClient(clientConfig); diff --git a/spring-session/src/integration-test/java/org/springframework/session/hazelcast/HazelcastServerRepositoryITests.java b/spring-session/src/integration-test/java/org/springframework/session/hazelcast/HazelcastServerRepositoryITests.java index 3749f89f..990b34b2 100644 --- a/spring-session/src/integration-test/java/org/springframework/session/hazelcast/HazelcastServerRepositoryITests.java +++ b/spring-session/src/integration-test/java/org/springframework/session/hazelcast/HazelcastServerRepositoryITests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-2018 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. @@ -43,7 +43,7 @@ public class HazelcastServerRepositoryITests extends AbstractHazelcastRepository static class HazelcastSessionConfig { @Bean - public HazelcastInstance embeddedHazelcastServer() { + public HazelcastInstance hazelcastInstance() { return HazelcastITestUtils.embeddedHazelcastServer(); } diff --git a/spring-session/src/main/java/org/springframework/session/hazelcast/HazelcastSessionRepository.java b/spring-session/src/main/java/org/springframework/session/hazelcast/HazelcastSessionRepository.java index f2d8d3ee..19c8e9ce 100644 --- a/spring-session/src/main/java/org/springframework/session/hazelcast/HazelcastSessionRepository.java +++ b/spring-session/src/main/java/org/springframework/session/hazelcast/HazelcastSessionRepository.java @@ -28,8 +28,6 @@ import javax.annotation.PreDestroy; import com.hazelcast.core.EntryEvent; import com.hazelcast.core.IMap; -import com.hazelcast.map.AbstractEntryProcessor; -import com.hazelcast.map.EntryProcessor; import com.hazelcast.map.listener.EntryAddedListener; import com.hazelcast.map.listener.EntryEvictedListener; import com.hazelcast.map.listener.EntryRemovedListener; @@ -392,58 +390,4 @@ public class HazelcastSessionRepository implements } - /** - * Hazelcast {@link EntryProcessor} responsible for handling updates to session. - * - * @since 1.3.2 - * @see #save(HazelcastSession) - */ - private static final class SessionUpdateEntryProcessor - extends AbstractEntryProcessor { - - private long lastAccessedTime; - - private int maxInactiveInterval; - - private Map delta; - - public Object process(Map.Entry entry) { - MapSession value = entry.getValue(); - if (value == null) { - return Boolean.FALSE; - } - if (this.lastAccessedTime > 0) { - value.setLastAccessedTime(this.lastAccessedTime); - } - if (this.maxInactiveInterval > 0) { - value.setMaxInactiveIntervalInSeconds(this.maxInactiveInterval); - } - if (this.delta != null) { - for (final Map.Entry attribute : this.delta.entrySet()) { - if (attribute.getValue() != null) { - value.setAttribute(attribute.getKey(), attribute.getValue()); - } - else { - value.removeAttribute(attribute.getKey()); - } - } - } - entry.setValue(value); - return Boolean.TRUE; - } - - public void setLastAccessedTime(long lastAccessedTime) { - this.lastAccessedTime = lastAccessedTime; - } - - public void setMaxInactiveInterval(int maxInactiveInterval) { - this.maxInactiveInterval = maxInactiveInterval; - } - - public void setDelta(Map delta) { - this.delta = delta; - } - - } - } diff --git a/spring-session/src/main/java/org/springframework/session/hazelcast/SessionUpdateEntryProcessor.java b/spring-session/src/main/java/org/springframework/session/hazelcast/SessionUpdateEntryProcessor.java new file mode 100644 index 00000000..c908e5ba --- /dev/null +++ b/spring-session/src/main/java/org/springframework/session/hazelcast/SessionUpdateEntryProcessor.java @@ -0,0 +1,78 @@ +/* + * Copyright 2014-2018 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 org.springframework.session.hazelcast; + +import java.util.Map; + +import com.hazelcast.map.AbstractEntryProcessor; +import com.hazelcast.map.EntryProcessor; + +import org.springframework.session.MapSession; + +/** + * Hazelcast {@link EntryProcessor} responsible for handling updates to session. + * + * @author Vedran Pavic + * @since 1.3.4 + * @see HazelcastSessionRepository#save(HazelcastSessionRepository.HazelcastSession) + */ +class SessionUpdateEntryProcessor extends AbstractEntryProcessor { + + private long lastAccessedTime; + + private int maxInactiveInterval; + + private Map delta; + + public Object process(Map.Entry entry) { + MapSession value = entry.getValue(); + if (value == null) { + return Boolean.FALSE; + } + if (this.lastAccessedTime > 0) { + value.setLastAccessedTime(this.lastAccessedTime); + } + if (this.maxInactiveInterval > 0) { + value.setMaxInactiveIntervalInSeconds(this.maxInactiveInterval); + } + if (this.delta != null) { + for (final Map.Entry attribute : this.delta.entrySet()) { + if (attribute.getValue() != null) { + value.setAttribute(attribute.getKey(), attribute.getValue()); + } + else { + value.removeAttribute(attribute.getKey()); + } + } + } + entry.setValue(value); + return Boolean.TRUE; + } + + void setLastAccessedTime(long lastAccessedTime) { + this.lastAccessedTime = lastAccessedTime; + } + + void setMaxInactiveInterval(int maxInactiveInterval) { + this.maxInactiveInterval = maxInactiveInterval; + } + + void setDelta(Map delta) { + this.delta = delta; + } + +}