Skip to content
Permalink
Browse files
Initial Commit
  • Loading branch information
atris committed Jun 16, 2021
1 parent 83a4612 commit 0883c7fcadcb1237f626d7104bdf8b4ec5ffd59b
Showing 7 changed files with 966 additions and 0 deletions.
@@ -0,0 +1,64 @@
<?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-sessions</artifactId>

<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.session/spring-session-core -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-core</artifactId>
<version>2.5.0</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.8</version>
</dependency>

<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>

<dependency>
<groupId>org.apache.ignite</groupId>
<artifactId>ignite-core</artifactId>
<version>2.11.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>


</project>
@@ -0,0 +1,98 @@
package org.apache.ignite.spring.sessions;

/*
* Copyright 2014-2020 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
*
* https://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">
* &#064;Configuration
* &#064;EnableIgniteHttpSession
* public class IgniteHttpSessionConfig {
*
* &#064;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;

}
@@ -0,0 +1,146 @@
package org.apache.ignite.spring.sessions;

/*
* Copyright 2014-2020 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
*
* https://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;
}

}

0 comments on commit 0883c7f

Please sign in to comment.