How to enable Wildfly 10 InMemorySessionManager? - wildfly

I'm using Widlfy 10, but do not want to use the DistributableSessions that are used by Wildfly out of the box (I am having some session handling issues and need to debug things at a basic level). I see that Undertow has an InMemorySessionManager which I would rather use instead. But I haven't been able to figure out how to specify a different SessionManager.
I've tried to configure my Wildfly cache as a local cache:
<subsystem xmlns="urn:jboss:domain:infinispan:4.0">
<cache-container name="server" aliases="singleton cluster" default-cache="default" module="org.wildfly.clustering.server">
<transport lock-timeout="60000"/>
<replicated-cache name="default" mode="SYNC">
<transaction mode="BATCH"/>
</replicated-cache>
</cache-container>
<cache-container name="web" default-cache="passivation" module="org.wildfly.clustering.web.infinispan">
<local-cache name="passivation">
<locking isolation="REPEATABLE_READ"/>
<transaction mode="BATCH"/>
<file-store passivation="true" purge="false"/>
</local-cache>
<local-cache name="persistent">
<locking isolation="REPEATABLE_READ"/>
<transaction mode="BATCH"/>
<file-store passivation="false" purge="false"/>
</local-cache>
</cache-container>
...
...
However, in debugging my application, I still see that Wildfly is using the DistributableSessionManager and DistributableSessions instead.
Is there anyway to enable the Undertwo's InMemorySessionManager instead? Do I have to go through the effort of creating my own ServletExtension and Factory and configuring it in the META-INF/services/io.undertow.servlet.ServletExtension or is there an out-of-the-box way of enable functionality that already exists via the config file? Or do the required classes already exist as part of the Undertow/Wildfly packaging?

There are only conditions that result in the use of the distributed session manager:
in web.xml
Using shared sessions across web application within an ear, via shared-session-config.xml
Given that you've already stated that #1 is not the case, I'll assume #2. To disable the use of the distributed session manager for shared sessions, remove the org.wildfly.clustering.web.undertow module from your distribution.

Related

When does keycloak delete expired sessions?

I noticed that sessions that pass the SSO session idle and SSO session max aren't immediately deleted. They seem to be invalidated and therefor useless, but they are not getting immediately removed. I can view them in the sessions tab of the admin console.
Since I can't find an explanation for this, or how this mechanism works internally (didn't look into the code), I was wondering, if anyone could elaborate on what is going on? Is everything working as it should?
Keycloak relies heavily on Infinispan for caching. Many types of entities have dedicated caches configured directly to them, and sessions are not excluded.
When starting Keycloak, you specifiy a configuration file/operation mode ( via the -c parameter). For example, when I run my keycloak via docker I get the following command line:
java -D[Standalone] -server -Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true --add-exports=java.base/sun.nio.ch=ALL-UNNAMED --add-exports=jdk.unsupported/sun.misc=ALL-UNNAMED --add-exports=jdk.unsupported/sun.reflect=ALL-UNNAMED -Dorg.jboss.boot.log.file=/opt/jboss/keycloak/standalone/log/server.log -Dlogging.configuration=file:/opt/jboss/keycloak/standalone/configuration/logging.properties -jar /opt/jboss/keycloak/jboss-modules.jar -mp /opt/jboss/keycloak/modules org.jboss.as.standalone -Djboss.home.dir=/opt/jboss/keycloak -Djboss.server.base.dir=/opt/jboss/keycloak/standalone -Djboss.bind.address=172.19.0.3 -Djboss.bind.address.private=172.19.0.3 -c=standalone-ha.xml -Dkeycloak.profile.feature.token_exchange=enabled -Dkeycloak.profile.feature.admin_fine_grained_authz=enabled
you can see -D[Standalone] (for the operation mode) and -c=standalone-ha.xml, which points to the configuration XML file.
In it, you can see a section in the likes of:
<subsystem xmlns="urn:jboss:domain:infinispan:11.0">
<cache-container name="keycloak" module="org.keycloak.keycloak-model-infinispan">
<local-cache name="realms">
<heap-memory size="10000"/>
</local-cache>
<local-cache name="users">
<heap-memory size="10000"/>
</local-cache>
<local-cache name="sessions"/>
<local-cache name="authenticationSessions"/>
<local-cache name="offlineSessions"/>
<local-cache name="clientSessions"/>
<local-cache name="offlineClientSessions"/>
<local-cache name="loginFailures"/>
<local-cache name="work"/>
<local-cache name="authorization">
<heap-memory size="10000"/>
</local-cache>
<local-cache name="keys">
<heap-memory size="1000"/>
<expiration max-idle="3600000"/>
</local-cache>
<local-cache name="actionTokens">
<heap-memory size="-1"/>
<expiration interval="300000" max-idle="-1"/>
</local-cache>
</cache-container>
...
...
...
</subsystem>
You can try and tweak the various session caches expiration/lifespan attributes.
Have a look at Cache-Configuration section of the manual, and also on the xmlns infinispan-config specification

Upgrade from Wildfly 10 to Wildfly 14 Infinispan issue

We have migrated from Widlfly 10 to Wildfly 14. We have an issue with our configuration for the Infinispan(7.0) web cache-container . In previous versions its was possible to set a mode to ASYNC. This is no longer possible and the documenation states:
Deprecated Since 6.0.0 Deprecated. This attribute will be ignored. All
cache modes will be treated as SYNC. To perform asynchronous cache
operations, use Infinispan's asynchronous cache API.
https://wildscribe.github.io/WildFly/14.0/subsystem/infinispan/cache-container/distributed-cache/index.html
We do not want to have the mode SYNC that now is default so how can we by configuring standalone-ha.xml use Infinispan's asynchronous cache API?
Wildfly 10 config
<cache-container name="web" default-cache="dist" module="org.wildfly.clustering.web.infinispan">
<transport lock-timeout="60000"/>
<distributed-cache name="dist" mode="ASYNC" l1-lifespan="0" owners="2">
<locking isolation="REPEATABLE_READ"/>
<transaction mode="BATCH"/>
<file-store/>
</distributed-cache>
<distributed-cache name="concurrent" mode="SYNC" l1-lifespan="0" owners="2">
<file-store/>
</distributed-cache>
</cache-container>
Wildfly 14 config
<cache-container name="web" default-cache="dist" module="org.wildfly.clustering.web.infinispan">
<transport lock-timeout="60000"/>
<distributed-cache name="dist">
<locking isolation="REPEATABLE_READ"/>
<transaction mode="BATCH"/>
<file-store/>
</distributed-cache>
</cache-container>
In WF 14, modifications to the session cache are committed after the response is flushed - so all cache access is effectively asynchronous from the perspective of the user.
Additionally, ASYNC cache mode is not the same as Infinispan's async cache API.
The async cache API is only relevant to SYNC cache modes.
Same question was asked in the WildFly forum. See https://developer.jboss.org/thread/279453

Keycloak and invalidation mode for ISPN cache

I'd like to configure Keycloak with embedded ISPN cache in invalidation mode for user sessions.
According to the doc, invalidation mode means each node gets its own cache and only invalidation is propagated to other nodes (the cache is only useful for read operations). I am aware that performances are non optimal but the JDBC store became a single source of truth which looks interesting to me. Moreover, as I need to store 1 million user sessions a week, the ISPN cache is filled very quickly (6GB instances) and sessions would probably be writen/read from database at a high frequency rate using the passivation/activation mechanism.
http://infinispan.org/docs/stable/user_guide/user_guide.html#replicated_mode
But I can't manage to get it work, no error, but the behavior is not the expected one: the database is still empty after several login operations.
<subsystem xmlns="urn:jboss:domain:infinispan:6.0">
<cache-container name="keycloak" module="org.keycloak.keycloak-model-infinispan">
<transport lock-timeout="60000"/>
<local-cache name="realms">
<object-memory size="10000"/>
</local-cache>
<local-cache name="users">
<object-memory size="10000"/>
</local-cache>
<invalidation-cache name="sessions" statistics-enabled="true">
<binary-memory eviction-type="COUNT" size="1000"/>
<expiration lifespan="180000"/>
<jdbc-store data-source="InfinispanDS"
dialect="POSTGRES"
fetch-state="false"
passivation="false"
preload="false"
purge="false"
shared="true"
singleton="false">
<table prefix="ISPN">
<id-column name="ID_COLUMN" type="VARCHAR(255)"/>
<data-column name="DATA_COLUMN" type="BYTEA"/>
<timestamp-column name="TIMESTAMP_COLUMN" type="BIGINT"/>
</table>
</jdbc-store>
</invalidation-cache>
</cache-container>
</subsystem>
<xa-datasource jndi-name="java:jboss/datasources/InfinispanDS" pool-name="InfinispanDS" enabled="true" use-java-context="true" spy="true">
<driver>postgresql</driver>
<xa-datasource-property name="URL">jdbc:postgresql://localhost:5432/keycloak_ispn</xa-datasource-property>
<security>
<user-name>postgres</user-name>
<password>***</password>
</security>
<validation>
<use-fast-fail>true</use-fast-fail>
<validate-on-match>false</validate-on-match>
<background-validation>true</background-validation>
<background-validation-millis>60000</background-validation-millis>
<valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.postgres.PostgreSQLValidConnectionChecker"/>
<exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.postgres.PostgreSQLExceptionSorter"/>
</validation>
</xa-datasource>
Could someone confirm to me that this is supposed to work?
(The other option would be to use a distributed cache with eviction-type="COUNT" and size="1" which actually works, but not more cache at all I guess).
Thanks
UPDATE 15:09
Actually, there are traces:
15:01:07,748 DEBUG [org.keycloak.models.sessions.infinispan.InfinispanAuthenticationSessionProviderFactory] (default task-1) [node11] Registered cluster listeners
15:01:12,147 DEBUG [org.keycloak.models.sessions.infinispan.InfinispanUserSessionProvider] (default task-1) getUserSessionWithPredicate(2cd1a484-1ba6-4f69-8aec-e85f56029bef): found in local cache
15:01:12,149 DEBUG [org.keycloak.models.sessions.infinispan.InfinispanCodeToTokenStoreProviderFactory] (default task-1) Not having remote stores. Using normal cache 'actionTokens' for single-use cache of code
15:01:12,220 DEBUG [org.keycloak.models.sessions.infinispan.changes.InfinispanChangelogBasedTransaction] (default task-1) Replace failed for entity: bd8fe447-b350-45a7-b785-4a4a0c40cb83, old version 9f465b0f-a2ac-407c-a9a1-5f97dca0e337, new version f8b2cf82-c84b-4e57-a058-5e44dba58324. Will try again
--nick

Application Fails to Load after enabling jdbc based session persistence

I am doing a POC with JBoss EAP 7.1 release wherein I have enabled db based session persistence, I have tested with the default cache manager persistence and it works well but somehow it doesn't stores any session data in the database schema, however the table gets created at the start of the server which I could see, for this I am starting with the sample counter.war which is present in the Redhat knowledge base. I am using Oracle 12cR1 database.
One more thing is , I am also not able to see the application from the console, same thing when I run the CLI command to read the resource. When I try to see the deployment under Deployments, it simly complains
Unable to load deployments
Unexpected HTTP response: 500 Request { "operation" => "read-children-resources", "address" => undefined, "child-type" => "deployment", "include-runtime" => true, "recursive" => true } Response Internal Server Error { "outcome" => "failed", "rolled-back" => true }
My server configuration in the standalone-ha.xml for the jdbc store is as below:
<cache-container name="server" aliases="singleton cluster" default-cache="default" module="org.wildfly.clustering.server">
<transport lock-timeout="60000"/>
<replicated-cache name="default">
<transaction mode="BATCH"/>
</replicated-cache>
</cache-container>
<cache-container name="web" default-cache="jdbc" module="org.wildfly.clustering.web.infinispan">
<transport channel="ee" lock-timeout="60000"/>
<local-cache name="concurrent">
<file-store passivation="true" purge="false"/>
</local-cache>
<invalidation-cache name="jdbc">
<binary-keyed-jdbc-store data-source="Session" dialect="ORACLE" fetch-state="false" passivation="false" preload="false" purge="false" shared="true" singleton="false">
<!-- <transaction mode="BATCH"/>-->
<property name="database-Type">
oracle
</property>
<binary-keyed-table prefix="sess">
<id-column name="ID" type="VARCHAR2(500)"/>
<data-column name="DATUM" type="BINARY"/>
<timestamp-column name="MAXINACTIVE" type="NUMBER"/>
<timestamp-column name="LASTACCESS" type="NUMBER"/>
<timestamp-column name="VERSION" type="NUMBER"/>
</binary-keyed-table>
</binary-keyed-jdbc-store>
</invalidation-cache>
</cache-container>
<cache-container name="ejb" aliases="sfsb" default-cache="dist" module="org.wildfly.clustering.ejb.infinispan">
<transport lock-timeout="60000"/>
<distributed-cache name="dist">
<locking isolation="REPEATABLE_READ"/>
<transaction mode="BATCH"/>
<file-store/>
</distributed-cache>
The table that gets created is also as below:
TNAME
TABTYPE CLUSTERID
BIN$cLKr2H7+eQ3gU1J2QgonwQ==$0
TABLE
SESS_counter_war
TABLE
sess_counter_war
TABLE
FYI, just for my satisfaction I tried by changing the prefix in the standalone-ha.xml so that's why two tables you could see.
Please guide me if I am doing something wrong.
This is quite a late reply almost a year after but as it is being said "Better Late than Never" :)
I managed to bring up the application successfully after some days of facing the error initially. I realized that there was some major issue in my configuration. Basically, I had the below problems:
Using distributed cache instead of invalidated cache.
Using binary store instead of string based store.
Invalid column and datatypes.
Refer the original post and answer here- https://developer.jboss.org/thread/278374
In EAP 7.1, you should configure session persistence using string-keyed-jdbc-store instead of using binary-keyed-jdbc-store which is deprecated in this version.

Modeshape workspace creation

We are working with this platform:
JBoss 6.1.0.GA
Modeshape 3.6.0
I just need to create a new workspace and to put inside images,javascripts, and other files I need for a webapp we are developing.
I tried to connect via webdav to our modeshape repository and create a new test directory inside, but I always receive this exception:
2015-02-03 16:47 WARN [org.modeshape.web.jcr.webdav.ModeShapeWebdavStore] (http-/0.0.0.0:8021-1) Cannot obtain a session for the repository 'repository': The workspace test was not found
I looked on stackoverflow and on the official guide of modeshape, but I still cannot catch how to do this "easy" task.
It seems there's no documentation that explains how to manually create a new workspace in a repository.
I add the configurations from standalone.xml I'm using for cache:
<subsystem xmlns="urn:jboss:domain:infinispan:1.4">
<cache-container name="hibernate" default-cache="local-query" module="org.jboss.as.jpa.hibernate:4">
<local-cache name="entity">
<transaction mode="NON_XA"/>
<eviction strategy="LRU" max-entries="10000"/>
<expiration max-idle="100000"/>
</local-cache>
<local-cache name="local-query">
<transaction mode="NONE"/>
<eviction strategy="LRU" max-entries="10000"/>
<expiration max-idle="100000"/>
</local-cache>
<local-cache name="timestamps">
<transaction mode="NONE"/>
<eviction strategy="NONE"/>
</local-cache>
</cache-container>
<cache-container name="modeshape" default-cache="repository" module="org.modeshape">
<local-cache name="repository">
<transaction mode="NON_XA"/>
<string-keyed-jdbc-store datasource="java:/jdbc/blablablaDatasource" shared="true" passivation="false" purge="false">
<property name="databaseType">
oracle
</property>
<property name="createTableOnStart">
true
</property>
<string-keyed-table prefix="CONTENT_REPO_STRING">
<id-column name="id_column" type="VARCHAR2(255)"/>
<data-column name="data_column" type="BLOB"/>
<timestamp-column name="timestamp_column" type="NUMBER(20)"/>
</string-keyed-table>
</string-keyed-jdbc-store>
</local-cache>
</cache-container>
<cache-container name="binary_cache_container" default-cache="binary_fs">
<local-cache name="binary_fs">
<transaction mode="NON_XA"/>
<string-keyed-jdbc-store datasource="java:/jdbc/blablablaDatasource" shared="true" preload="false" passivation="false" purge="false">
<write-behind flush-lock-timeout="1" modification-queue-size="1024" shutdown-timeout="25000" thread-pool-size="1"/>
<property name="databaseType">
oracle
</property>
<string-keyed-table prefix="CONTENT_REPO">
<id-column name="id_column" type="VARCHAR(255)"/>
<data-column name="data_column" type="BLOB"/>
<timestamp-column name="timestamp_column" type="NUMBER(20)"/>
</string-keyed-table>
</string-keyed-jdbc-store>
</local-cache>
<local-cache name="binary_fs_meta">
<transaction mode="NON_XA"/>
<string-keyed-jdbc-store datasource="java:/jdbc/blablablaDatasource" shared="true" preload="false" passivation="false" purge="false">
<write-behind flush-lock-timeout="1" modification-queue-size="1024" shutdown-timeout="25000" thread-pool-size="1"/>
<property name="databaseType">
oracle
</property>
<string-keyed-table prefix="CONTENT_REPO">
<id-column name="id_column" type="VARCHAR(255)"/>
<data-column name="data_column" type="BLOB"/>
<timestamp-column name="timestamp_column" type="NUMBER(20)"/>
</string-keyed-table>
</string-keyed-jdbc-store>
</local-cache>
</cache-container>
</subsystem>
and also for the modeshape conf:
<subsystem xmlns="urn:jboss:domain:modeshape:1.0">
<repository name="repository" security-domain="modeshape-internal-security">
<workspaces default-workspace="default" allow-workspace-creation="true">
<workspace name="ops">
<initial-content>
initial-content-default.xml
</initial-content>
</workspace>
<workspace name="other"/>
<workspace name="extra">
<initial-content>
initial-content-default.xml
</initial-content>
</workspace>
<workspace name="default"/>
</workspaces>
<indexing rebuild-upon-startup="ALWAYS"/>
<cache-binary-storage data-cache-name="binary_fs" metadata-cache-name="binary_fs_meta" cache-container="binary_cache_container"/>
<sequencers>
<sequencer name="fixed-width-text-sequencer" classname="org.modeshape.sequencer.text.FixedWidthTextSequencer" module="org.modeshape.sequencer.text" commentMarker="#" path-expression="/files(//*.txt[*])/jcr:content[#jcr:data] => /derived/text/fixedWidth/$1"/>
<sequencer name="xml-sequencer" classname="xml" module="org.modeshape.sequencer.xml" path-expression="/files(//)*.xml[*]/jcr:content[#jcr:data] => /derived/xml/$1"/>
<sequencer name="image-sequencer" classname="image" module="org.modeshape.sequencer.image" path-expression="/files(//*.(png|jpg|gif)[*])/jcr:content[#jcr:data] => /derived/image/$1"/>
</sequencers>
<text-extractors>
<text-extractor name="tika-extractor" classname="tika" module="org.modeshape.extractor.tika"/>
</text-extractors>
</repository>
</subsystem>
You can create a new workspace programmatically using the standard JCR API (see this StackOverflow question, but you can also define workspaces in the ModeShape configuration file.
Since you're deploying ModeShape to JBoss EAP, you can configure new workspaces in the ModeShape subsystem configuration within the installation's standalone-modeshape.xml file. Here's an example (that actually is in that configuration file) to define 3 workspaces named default, other, and extra upon startup, defines some initial content for the workspace named default, and it enables the programmatic creation of workspaces.
<repository name="artifacts">
<!-- ... -->
<!-- Define 3 workspaces to exist upon startup -->
<workspaces default-workspace="default" allow-workspace-creation="false">
<workspace name="default">
<initial-content>initial-content-default.xml</initial-content>
</workspace>
<workspace name="other"/>
<workspace name="extra"/>
</workspaces>
<!-- ... -->
<repository name="artifacts">
The structure of this XML fragment is dictated by the modeshape_1_0.xsd file in your EAP installation (or the modeshape_2_0.xsd file in Wildfly installations).
For those not deploying ModeShape in JBoss EAP (or Wildfly for ModeShape 4.x), you can do the same thing in ModeShape's JSON configuration file. For example, this defines exactly the same workspaces described above:
"workspaces" : {
"predefined" : ["other", "extra"],
"default" : "default",
"allowCreation" : true,
"initialContent" : {
"default" : "initial-content-default.xml"
}
},
See ModeShape's JSON schema for more details and options.
Also, be sure that when you log into a Session that you correctly specify the workspace name.
I managed to get it work only changing the configuration to this one:
JBoss 6.3.0.GA
Modeshape 3.8.1