Skip to content

Commit

Permalink
Initial HodRod-based Tomcat session manager implementation.
Browse files Browse the repository at this point in the history
  • Loading branch information
pferraro committed Dec 2, 2016
1 parent 8030307 commit 9a3b911
Show file tree
Hide file tree
Showing 17 changed files with 1,807 additions and 12 deletions.
44 changes: 32 additions & 12 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,12 +1,32 @@
*.class

# Mobile Tools for Java (J2ME)
.mtj.tmp/

# Package Files #
*.jar
*.war
*.ear

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
# ignore Maven generated target folders
~
target
# ignore eclipse files
.project
.classpath
.settings
.metadata
.checkstyle
# ignore m2e annotation processing files
.factorypath
# ignore IDEA files
*.iml
*.ipr
*.iws
.idea
# ignore NetBeans files
nbactions.xml
nb-configuration.xml
catalog.xml
# vim files
*.swp
/.gitk-tmp.*
atlassian-ide-plugin.xml
# temp files
*~
# maven versions plugin
pom.xml.versionsBackup
# hprof dumps
/*.hprof
# ignore java crashes
hs_err_pid*.log
51 changes: 51 additions & 0 deletions hotrod/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ JBoss, Home of Professional Open Source.
~ Copyright 2010, Red Hat, Inc., and individual contributors
~ as indicated by the @author tags. See the copyright.txt file in the
~ distribution for a full listing of individual contributors.
~
~ This is free software; you can redistribute it and/or modify it
~ under the terms of the GNU Lesser General Public License as
~ published by the Free Software Foundation; either version 2.1 of
~ the License, or (at your option) any later version.
~
~ This software is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
~ Lesser General Public License for more details.
~
~ You should have received a copy of the GNU Lesser General Public
~ License along with this software; if not, write to the Free
~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-->

<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">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.wildfly.clustering</groupId>
<artifactId>wildfly-clustering-tomcat-parent</artifactId>
<version>1.0.0.Alpha1-SNAPSHOT</version>
</parent>

<artifactId>wildfly-clustering-tomcat-hotrod</artifactId>
<packaging>jar</packaging>

<name>WildFly: Tomcat integration with HotRod-based session manager</name>

<dependencies>
<dependency>
<groupId>org.wildfly.clustering</groupId>
<artifactId>wildfly-clustering-tomcat</artifactId>
</dependency>
<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-clustering-web-hotrod</artifactId>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2016, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.wildfly.clustering.tomcat.hotrod;

import java.io.Externalizable;
import java.io.IOException;
import java.io.Serializable;
import java.util.Properties;
import java.util.function.Function;

import javax.servlet.ServletContext;

import org.apache.catalina.Context;
import org.apache.catalina.Host;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.LifecycleState;
import org.apache.catalina.Session;
import org.apache.catalina.session.ManagerBase;
import org.infinispan.client.hotrod.RemoteCacheManager;
import org.infinispan.client.hotrod.configuration.Configuration;
import org.infinispan.client.hotrod.configuration.ConfigurationBuilder;
import org.infinispan.client.hotrod.configuration.NearCacheMode;
import org.infinispan.commons.marshall.jboss.DefaultContextClassResolver;
import org.jboss.marshalling.MarshallingConfiguration;
import org.wildfly.clustering.ee.Batch;
import org.wildfly.clustering.ee.Recordable;
import org.wildfly.clustering.marshalling.jboss.ExternalizerObjectTable;
import org.wildfly.clustering.marshalling.jboss.MarshallingContext;
import org.wildfly.clustering.marshalling.jboss.SimpleClassTable;
import org.wildfly.clustering.marshalling.jboss.SimpleMarshalledValueFactory;
import org.wildfly.clustering.marshalling.jboss.SimpleMarshallingConfigurationRepository;
import org.wildfly.clustering.marshalling.jboss.SimpleMarshallingContextFactory;
import org.wildfly.clustering.marshalling.spi.MarshalledValueFactory;
import org.wildfly.clustering.tomcat.IdentifierFactoryAdapter;
import org.wildfly.clustering.tomcat.session.DistributableManager;
import org.wildfly.clustering.tomcat.session.LocalSessionContext;
import org.wildfly.clustering.tomcat.session.LocalSessionContextFactory;
import org.wildfly.clustering.tomcat.session.TomcatManager;
import org.wildfly.clustering.tomcat.session.TomcatSessionExpirationListener;
import org.wildfly.clustering.web.IdentifierFactory;
import org.wildfly.clustering.web.LocalContextFactory;
import org.wildfly.clustering.web.hotrod.session.HotRodSessionManager;
import org.wildfly.clustering.web.hotrod.session.HotRodSessionManagerFactory;
import org.wildfly.clustering.web.hotrod.session.HotRodSessionManagerFactoryConfiguration;
import org.wildfly.clustering.web.session.ImmutableSession;
import org.wildfly.clustering.web.session.SessionExpirationListener;
import org.wildfly.clustering.web.session.SessionManager;
import org.wildfly.clustering.web.session.SessionManagerConfiguration;
import org.wildfly.clustering.web.session.SessionManagerFactory;
import org.wildfly.clustering.web.session.SessionManagerFactoryConfiguration;
import org.wildfly.clustering.web.session.SessionManagerFactoryConfiguration.SessionAttributePersistenceStrategy;

/**
* Distributed Manager implementation that configures a HotRod client.
* @author Paul Ferraro
*/
public class HotRodManager extends ManagerBase {

enum MarshallingVersion implements Function<ClassLoader, MarshallingConfiguration> {
VERSION_1() {
@Override
public MarshallingConfiguration apply(ClassLoader loader) {
MarshallingConfiguration config = new MarshallingConfiguration();
config.setClassResolver(new DefaultContextClassResolver(loader));
config.setClassTable(new SimpleClassTable(Serializable.class, Externalizable.class));
config.setObjectTable(new ExternalizerObjectTable(loader));
return config;
}
},
;
static final MarshallingVersion CURRENT = VERSION_1;
}

private final Properties properties = new Properties();

private volatile RemoteCacheManager container;
private volatile TomcatManager manager;
private volatile SessionAttributePersistenceStrategy persistenceStrategy = SessionAttributePersistenceStrategy.COARSE;

public String getProperty(String name) {
return this.properties.getProperty(name);
}

public void setProperty(String name, String value) {
this.properties.setProperty(name, value);
}

public void setPersistenceStrategy(SessionAttributePersistenceStrategy strategy) {
this.persistenceStrategy = strategy;
}

public void setPersistenceStrategy(String strategy) {
this.setPersistenceStrategy(SessionAttributePersistenceStrategy.valueOf(strategy));
}

@Override
protected void startInternal() throws LifecycleException {
super.startInternal();

Configuration configuration = new ConfigurationBuilder()
.withProperties(this.properties)
.nearCache().mode(NearCacheMode.INVALIDATED).maxEntries(this.getMaxActiveSessions())
.marshaller(new HotRodMarshaller(HotRodSessionManager.class.getClassLoader()))
.build();

RemoteCacheManager container = new RemoteCacheManager(configuration, false);
this.container = container;
this.container.start();

Context context = this.getContext();
ClassLoader loader = context.getLoader().getClassLoader();
Host host = (Host) context.getParent();
// Deployment name = host name + context path + version
String deploymentName = host.getName() + context.getName();
int maxActiveSessions = this.getMaxActiveSessions();
SessionAttributePersistenceStrategy strategy = this.persistenceStrategy;
MarshallingContext marshallingContext = new SimpleMarshallingContextFactory().createMarshallingContext(new SimpleMarshallingConfigurationRepository(MarshallingVersion.class, MarshallingVersion.CURRENT, loader), loader);
MarshalledValueFactory<MarshallingContext> marshallingFactory = new SimpleMarshalledValueFactory(marshallingContext);

SessionManagerFactoryConfiguration<MarshallingContext> sessionManagerFactoryConfig = new SessionManagerFactoryConfiguration<MarshallingContext>() {
@Override
public int getMaxActiveSessions() {
return maxActiveSessions;
}

@Override
public SessionAttributePersistenceStrategy getAttributePersistenceStrategy() {
return strategy;
}

@Override
public String getDeploymentName() {
return deploymentName;
}

@Override
public String getCacheName() {
return null;
}

@Override
public MarshalledValueFactory<MarshallingContext> getMarshalledValueFactory() {
return marshallingFactory;
}

@Override
public MarshallingContext getMarshallingContext() {
return marshallingContext;
}
};

HotRodSessionManagerFactoryConfiguration<MarshallingContext> hotrodSessionManagerFactoryConfig = new HotRodSessionManagerFactoryConfiguration<MarshallingContext>() {
@Override
public SessionManagerFactoryConfiguration<MarshallingContext> getSessionManagerFactoryConfiguration() {
return sessionManagerFactoryConfig;
}

@Override
public RemoteCacheManager getCacheContainer() {
return container;
}
};

SessionManagerFactory<Batch> sessionManagerFactory = new HotRodSessionManagerFactory<>(hotrodSessionManagerFactoryConfig);

ServletContext servletContext = context.getServletContext();
SessionExpirationListener expirationListener = new TomcatSessionExpirationListener(context);
LocalContextFactory<LocalSessionContext> contextFactory = new LocalSessionContextFactory();
IdentifierFactory<String> identifierFactory = new IdentifierFactoryAdapter(this.getSessionIdGenerator());

SessionManagerConfiguration<LocalSessionContext> sessionManagerConfiguration = new SessionManagerConfiguration<LocalSessionContext>() {
@Override
public ServletContext getServletContext() {
return servletContext;
}

@Override
public IdentifierFactory<String> getIdentifierFactory() {
return identifierFactory;
}

@Override
public SessionExpirationListener getExpirationListener() {
return expirationListener;
}

@Override
public LocalContextFactory<LocalSessionContext> getLocalContextFactory() {
return contextFactory;
}

@Override
public Recordable<ImmutableSession> getInactiveSessionRecorder() {
return null;
}
};
SessionManager<LocalSessionContext, Batch> sessionManager = sessionManagerFactory.createSessionManager(sessionManagerConfiguration);

this.manager = new DistributableManager(sessionManager, context, marshallingContext);
this.manager.start();

this.setState(LifecycleState.STARTING);
}

@Override
protected void stopInternal() throws LifecycleException {
this.setState(LifecycleState.STOPPING);

this.manager.stop();
this.container.stop();
}

@Override
public Session createSession(String sessionId) {
return this.manager.createSession(sessionId);
}

@Override
public Session findSession(String id) throws IOException {
return this.manager.findSession(id);
}

@Override
public void load() throws ClassNotFoundException, IOException {
// Do nothing
}

@Override
public void unload() throws IOException {
// Do nothing
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2016, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.wildfly.clustering.tomcat.hotrod;

import org.infinispan.commons.marshall.jboss.AbstractJBossMarshaller;
import org.infinispan.commons.marshall.jboss.DefaultContextClassResolver;
import org.wildfly.clustering.marshalling.jboss.DynamicClassTable;
import org.wildfly.clustering.marshalling.jboss.ExternalizerObjectTable;

/**
* @author Paul Ferraro
*/
public class HotRodMarshaller extends AbstractJBossMarshaller {

public HotRodMarshaller(ClassLoader loader) {
super();
super.baseCfg.setClassExternalizerFactory(null);
super.baseCfg.setClassResolver(new DefaultContextClassResolver(loader));
super.baseCfg.setClassTable(new DynamicClassTable(loader));
super.baseCfg.setObjectTable(new ExternalizerObjectTable(loader));
}
}
Loading

0 comments on commit 9a3b911

Please sign in to comment.