use of org.wildfly.clustering.web.infinispan.sso.InfinispanSSOManagerFactoryConfiguration in project wildfly-clustering-spring-session by wildfly-clustering.
the class InfinispanSessionRepository method afterPropertiesSet.
@Override
public void afterPropertiesSet() throws Exception {
ServletContext context = this.configuration.getServletContext();
// Deployment name = host name + context path + version
String deploymentName = context.getVirtualServerName() + context.getContextPath();
String resourceName = this.configuration.getConfigurationResource();
String templateName = this.configuration.getTemplateName();
Integer maxActiveSessions = this.configuration.getMaxActiveSessions();
SessionAttributePersistenceStrategy strategy = this.configuration.getPersistenceStrategy();
COUNTER.incrementAndGet();
this.stopTasks.add(() -> {
// Stop RxJava schedulers when no longer in use
if (COUNTER.decrementAndGet() == 0) {
Schedulers.shutdown();
}
});
ClassLoader containerLoader = WildFlySecurityManager.getClassLoaderPrivileged(InfinispanSessionManagerFactory.class);
URL url = context.getResource(resourceName);
if (url == null) {
throw new FileNotFoundException(resourceName);
}
ConfigurationBuilderHolder holder = new ParserRegistry().parse(url);
GlobalConfigurationBuilder global = holder.getGlobalConfigurationBuilder();
String containerName = global.cacheContainer().name();
TransportConfiguration transport = global.transport().create();
JGroupsChannelConfigurator configurator = (transport.transport() != null) ? new JChannelConfigurator(context, transport) : null;
JChannel channel = (configurator != null) ? configurator.createChannel(null) : null;
if (channel != null) {
channel.setName(transport.nodeName());
channel.setDiscardOwnMessages(true);
channel.connect(transport.clusterName());
this.stopTasks.add(channel::close);
GlobalJmxConfiguration jmx = global.jmx().create();
if (jmx.enabled()) {
ObjectName prefix = new ObjectName(jmx.domain(), "manager", ObjectName.quote(containerName));
JmxConfigurator.registerChannel(channel, ManagementFactory.getPlatformMBeanServer(), prefix, transport.clusterName(), true);
this.stopTasks.add(() -> {
try {
JmxConfigurator.unregisterChannel(channel, ManagementFactory.getPlatformMBeanServer(), prefix, transport.clusterName());
} catch (Exception e) {
context.log(e.getLocalizedMessage(), e);
}
});
}
Properties properties = new Properties();
properties.put(JGroupsTransport.CHANNEL_CONFIGURATOR, new ForkChannelConfigurator(channel, containerName));
global.transport().withProperties(properties);
}
Function<ClassLoader, ByteBufferMarshaller> marshallerFactory = this.configuration.getMarshallerFactory();
CommandDispatcherFactory dispatcherFactory = (channel != null) ? new ChannelCommandDispatcherFactory(new ChannelCommandDispatcherFactoryConfiguration() {
@Override
public JChannel getChannel() {
return channel;
}
@Override
public ByteBufferMarshaller getMarshaller() {
return SessionMarshallerFactory.PROTOSTREAM.apply(containerLoader);
}
@Override
public Duration getTimeout() {
return Duration.ofMillis(transport.initialClusterTimeout());
}
@Override
public Function<ClassLoader, ByteBufferMarshaller> getMarshallerFactory() {
return marshallerFactory;
}
@Override
public Predicate<ByteBuffer> getUnknownForkPredicate() {
return buffer -> buffer.remaining() == 0;
}
@Override
public Function<ClassLoader, Contextualizer> getContextualizerFactory() {
return loader -> new ContextReferenceExecutor<>(loader, ContextClassLoaderReference.INSTANCE);
}
}) : new LocalCommandDispatcherFactory(new LocalGroup(transport.nodeName()));
if (channel != null) {
ChannelCommandDispatcherFactory factory = (ChannelCommandDispatcherFactory) dispatcherFactory;
this.stopTasks.add(factory::close);
}
holder.getGlobalConfigurationBuilder().classLoader(containerLoader).blockingThreadPool().threadFactory(new DefaultThreadFactory(BlockingManager.class)).expirationThreadPool().threadFactory(new DefaultThreadFactory(ExpirationManager.class)).listenerThreadPool().threadFactory(new DefaultThreadFactory(ListenerInvocation.class)).nonBlockingThreadPool().threadFactory(new DefaultNonBlockingThreadFactory(NonBlockingManager.class)).serialization().marshaller(new InfinispanProtoStreamMarshaller(new SimpleClassLoaderMarshaller(containerLoader), builder -> builder.load(containerLoader))).addContextInitializer(new SerializationContextInitializer() {
@Deprecated
@Override
public String getProtoFile() {
return null;
}
@Deprecated
@Override
public String getProtoFileName() {
return null;
}
@Override
public void registerMarshallers(SerializationContext context) {
}
@Override
public void registerSchema(SerializationContext context) {
}
}).globalState().configurationStorage(ConfigurationStorage.IMMUTABLE).disable();
@SuppressWarnings("resource") EmbeddedCacheManager container = new DefaultCacheManager(holder, false);
Configuration template = (templateName != null) ? container.getCacheConfiguration(templateName) : container.getDefaultCacheConfiguration();
if (template == null) {
if (templateName == null) {
throw new IllegalArgumentException("Infinispan configuration does not define a default cache");
}
throw new IllegalArgumentException(String.format("No such configuration template: %s", templateName));
}
ConfigurationBuilder builder = new ConfigurationBuilder().read(template).template(false);
builder.encoding().mediaType(MediaType.APPLICATION_OBJECT_TYPE);
builder.clustering().hash().groups().enabled();
// Disable expiration, if necessary
ExpirationConfiguration expiration = builder.expiration().create();
if ((expiration.lifespan() >= 0) || (expiration.maxIdle() >= 0)) {
builder.expiration().lifespan(-1).maxIdle(-1);
}
EvictionStrategy eviction = (maxActiveSessions != null) ? EvictionStrategy.REMOVE : EvictionStrategy.MANUAL;
builder.memory().storage(StorageType.HEAP).whenFull(eviction).maxCount((maxActiveSessions != null) ? maxActiveSessions.longValue() : -1);
if (eviction.isEnabled()) {
// Only evict creation meta-data entries
// We will cascade eviction to the remaining entries for a given session
builder.addModule(DataContainerConfigurationBuilder.class).evictable(SessionCreationMetaDataKey.class::isInstance);
}
container.defineConfiguration(deploymentName, builder.build());
this.stopTasks.add(() -> container.undefineConfiguration(deploymentName));
container.start();
this.stopTasks.add(container::stop);
ByteBufferMarshaller marshaller = marshallerFactory.apply(context.getClassLoader());
MarshalledValueFactory<ByteBufferMarshaller> marshalledValueFactory = new ByteBufferMarshalledValueFactory(marshaller);
ServiceLoader<Immutability> loadedImmutability = ServiceLoader.load(Immutability.class, Immutability.class.getClassLoader());
Immutability immutability = new CompositeImmutability(new CompositeIterable<>(EnumSet.allOf(DefaultImmutability.class), EnumSet.allOf(SessionAttributeImmutability.class), EnumSet.allOf(SpringSecurityImmutability.class), loadedImmutability));
Supplier<String> identifierFactory = this.configuration.getIdentifierFactory();
KeyAffinityServiceFactory affinityFactory = new DefaultKeyAffinityServiceFactory();
Map<String, String> indexes = this.configuration.getIndexes();
Map<String, SSOManager<Void, String, String, Void, TransactionBatch>> managers = indexes.isEmpty() ? Collections.emptyMap() : new HashMap<>();
for (Map.Entry<String, String> entry : indexes.entrySet()) {
String cacheName = String.format("%s/%s", deploymentName, entry.getKey());
String indexName = entry.getValue();
container.defineConfiguration(cacheName, builder.build());
this.stopTasks.add(() -> container.undefineConfiguration(cacheName));
Cache<?, ?> cache = container.getCache(cacheName);
cache.start();
this.stopTasks.add(cache::stop);
SSOManagerFactory<Void, String, String, TransactionBatch> ssoManagerFactory = new InfinispanSSOManagerFactory<>(new InfinispanSSOManagerFactoryConfiguration() {
@Override
public <K, V> Cache<K, V> getCache() {
return container.getCache(cacheName);
}
@Override
public KeyAffinityServiceFactory getKeyAffinityServiceFactory() {
return affinityFactory;
}
});
SSOManager<Void, String, String, Void, TransactionBatch> ssoManager = ssoManagerFactory.createSSOManager(new SSOManagerConfiguration<ByteBufferMarshaller, Void>() {
@Override
public Supplier<String> getIdentifierFactory() {
return identifierFactory;
}
@Override
public MarshalledValueFactory<ByteBufferMarshaller> getMarshalledValueFactory() {
return marshalledValueFactory;
}
@Override
public LocalContextFactory<Void> getLocalContextFactory() {
return InfinispanSessionRepository.this;
}
});
managers.put(indexName, ssoManager);
}
IndexResolver<Session> resolver = this.configuration.getIndexResolver();
IndexingConfiguration<TransactionBatch> indexing = new IndexingConfiguration<TransactionBatch>() {
@Override
public Map<String, SSOManager<Void, String, String, Void, TransactionBatch>> getSSOManagers() {
return managers;
}
@Override
public IndexResolver<Session> getIndexResolver() {
return resolver;
}
};
Cache<?, ?> cache = container.getCache(deploymentName);
cache.start();
this.stopTasks.add(cache::stop);
NodeFactory<org.jgroups.Address> memberFactory = (channel != null) ? (ChannelCommandDispatcherFactory) dispatcherFactory : new LocalGroup(context.getVirtualServerName());
CacheGroup group = new CacheGroup(new CacheGroupConfiguration() {
@Override
public Cache<?, ?> getCache() {
return cache;
}
@Override
public NodeFactory<org.jgroups.Address> getMemberFactory() {
return memberFactory;
}
});
this.stopTasks.add(group::close);
SessionManagerFactory<ServletContext, Void, TransactionBatch> managerFactory = new InfinispanSessionManagerFactory<>(new InfinispanSessionManagerFactoryConfiguration<HttpSession, ServletContext, HttpSessionActivationListener, ByteBufferMarshaller, Void>() {
@Override
public Integer getMaxActiveSessions() {
return maxActiveSessions;
}
@Override
public SessionAttributePersistenceStrategy getAttributePersistenceStrategy() {
return strategy;
}
@Override
public String getDeploymentName() {
return deploymentName;
}
@Override
public MarshalledValueFactory<ByteBufferMarshaller> getMarshalledValueFactory() {
return marshalledValueFactory;
}
@Override
public String getServerName() {
return context.getVirtualServerName();
}
@Override
public LocalContextFactory<Void> getLocalContextFactory() {
return InfinispanSessionRepository.this;
}
@Override
public <K, V> Cache<K, V> getCache() {
return container.getCache(this.getDeploymentName());
}
@Override
public Immutability getImmutability() {
return immutability;
}
@Override
public SpecificationProvider<HttpSession, ServletContext, HttpSessionActivationListener> getSpecificationProvider() {
return SpringSpecificationProvider.INSTANCE;
}
@Override
public CommandDispatcherFactory getCommandDispatcherFactory() {
return dispatcherFactory;
}
@Override
public KeyAffinityServiceFactory getKeyAffinityServiceFactory() {
return affinityFactory;
}
@Override
public NodeFactory<Address> getMemberFactory() {
return group;
}
});
this.stopTasks.add(managerFactory::close);
ApplicationEventPublisher publisher = this.configuration.getEventPublisher();
BiConsumer<ImmutableSession, BiFunction<Object, Session, ApplicationEvent>> sessionDestroyAction = new ImmutableSessionDestroyAction<>(publisher, context, indexing);
SessionExpirationListener expirationListener = new ImmutableSessionExpirationListener(context, sessionDestroyAction);
SessionManager<Void, TransactionBatch> manager = managerFactory.createSessionManager(new SessionManagerConfiguration<ServletContext>() {
@Override
public ServletContext getServletContext() {
return context;
}
@Override
public Supplier<String> getIdentifierFactory() {
return identifierFactory;
}
@Override
public SessionExpirationListener getExpirationListener() {
return expirationListener;
}
@Override
public Recordable<ImmutableSessionMetaData> getInactiveSessionRecorder() {
// Spring session has no metrics capability
return null;
}
});
Optional<Duration> defaultTimeout = setDefaultMaxInactiveInterval(manager, Duration.ofMinutes(context.getSessionTimeout()));
manager.start();
this.stopTasks.add(manager::stop);
this.repository = new DistributableSessionRepository<>(new DistributableSessionRepositoryConfiguration<TransactionBatch>() {
@Override
public SessionManager<Void, TransactionBatch> getSessionManager() {
return manager;
}
@Override
public Optional<Duration> getDefaultTimeout() {
return defaultTimeout;
}
@Override
public ApplicationEventPublisher getEventPublisher() {
return publisher;
}
@Override
public ServletContext getServletContext() {
return context;
}
@Override
public BiConsumer<ImmutableSession, BiFunction<Object, Session, ApplicationEvent>> getSessionDestroyAction() {
return sessionDestroyAction;
}
@Override
public IndexingConfiguration<TransactionBatch> getIndexingConfiguration() {
return indexing;
}
});
}
Aggregations