Jekyll2024-03-13T09:56:09+01:00https://infinispan.org/feed.xmlInfinispanInfinispan is a distributed in-memory key/value data store with optional schema, available under the Apache License 2.0.Infinispan 15.0.0.Final2024-03-13T01:00:00+01:002024-03-13T01:00:00+01:00https://infinispan.org/blog/2024/03/13/infinispan-15.0.0.Final<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>Don’t you know I’m still standin' better than I ever did?
Lookin' like a true survivor, feelin' like a little kid</p>
</div>
<div class="paragraph">
<p>Those lyrics certainly apply to our newest, and best, release: Infinispan 15, which continues to improve on its mature foundation, and yet packs fun new features, just like a little kid.
And in our grand tradition of codenames based on beers, this one <a href="https://untappd.com/b/delphic-brewing-company-i-m-still-standing/3572608">is no exception</a>.</p>
</div>
<div class="imageblock">
<div class="content">
<img src="/assets/images/blog/im-still-standing.jpg" alt="I’m Still Standing" width="1000" height="891">
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="jdk-requirements">JDK requirements</h2>
<div class="sectionbody">
<div class="paragraph">
<p>You will need at least JDK 17 in order to use Infinispan 15. Infinispan also supports JDK 21 and the soon-to-be-released JDK 22.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="jakarta-ee">Jakarta EE</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Since we’ve completely embraced JDK 17, we now only ship <a href="https://jakarta.ee">Jakarta EE</a>-compatible modules. If you want to keep on using Java EE, you will have to stay
on Infinispan 14, which is still supported.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="redis-protocol">Redis protocol</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Infinispan Server now comes with a Redis protocol (RESP) connector. We implement over 90 commands from Redis OSS, including most data types (strings, sets, sorted sets, lists, hashes, pubsub). Why would you want to use Infinispan instead of Redis ? Just some things:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>multi-threaded: take advantage of multiple cores without resorting to clustering</p>
</li>
<li>
<p>P2P clustering: all members of a cluster are of the same kind. You don’t need to worry about writing to masters, reading from replicas: it’s all the same! Elastically add/remove nodes at runtime to increase/decrease capacity as required by your workload: Infinispan will rebalance the data to ensure that your redundancy settings are respected.</p>
</li>
<li>
<p>multiple caches with dedicated configuration: divide your data in different namespaces, possibly with different expiration, eviction, persistence rules. And it also works in a cluster, unlike Redis Cluster.</p>
</li>
<li>
<p>cross-site replication: work with 2 or more sites</p>
</li>
<li>
<p>multiple persistence options: store your data on disk, in a database or in another external store. You can even write your own to implement true inline caching instead of side-caching to reduce your overall latency.</p>
</li>
<li>
<p>integration with external identity providers: authenticate/authorize with OAuth2, LDAP, Kerberos, client certificates.</p>
</li>
<li>
<p>full pipeline inbound process handling allows for even greater batched throughput</p>
</li>
<li>
<p>a mature, open-source Kubernetes Operator which supports provisioning, scaling, persistence, and integration with enterprise security.</p>
</li>
<li>
<p>lots more!</p>
</li>
<li>
<p>and everything is available under the ASL 2.0, so you don’t have to worry about features being locked behind restrictive licenses.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The Redis connector is exposed via our single-port: we automatically detect RESP clients on connection!</p>
</div>
<div class="paragraph">
<p>We even made a <a href="https://www.youtube.com/watch?v=Xi9gTA0jfD0">video</a> highlighting some cool things!</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="vector-indexes">Vector indexes</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Infinispan now supports distributed vector indexes and KNN queries.
They are expressed in Ickle (SQL-like) syntax using the special operator <code><→</code>. For instance:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">Query<Item> query = cache.query("from Item i where i.byteVector <-> [7,6,7]~3");</code></pre>
</div>
</div>
<div class="paragraph">
<p>Vector parameters can be passed in different ways.
As an entire entity:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">query = cache.query("from model.Item i where i.byteVector <-> [:a]~:b");
query.setParameter("a", new byte[]{7, 6, 7});
query.setParameter("b", 3);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Or using a placeholder for each cell:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">query = cache.query("from model.Item i where i.floatVector <-> [:a,:b,:c]~:d");
query.setParameter("a", 1);
query.setParameter("b", 4.3);
query.setParameter("c", 3.3);
query.setParameter("d", 4);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Both float vectors and byte vectors are supported.</p>
</div>
<div class="paragraph">
<p>Infinispan can be easily integrated into a Python Langchain application as a vector store for semantic search or even in a chain: the picture below shows a QA chain in action.</p>
</div>
<div class="imageblock">
<div class="content">
<img src="/assets/images/blog/vector-search-relnotes.gif" alt="Infinispan VectorStore" width="640" height="480">
</div>
</div>
<div class="paragraph">
<p>See <a href="https://python.langchain.com/docs/integrations/vectorstores/infinispanvs">Infinispan VectorStore</a> and <a href="https://github.com/infinispan-demos/infinispan-langchain-demo">Infinispan Langchain demo</a> for more examples.</p>
</div>
<div class="paragraph">
<p>Infinispan is also part of <a href="https://github.com/langchain4j/langchain4j">Langchain4j</a>, thus the <a href="https://docs.quarkiverse.io/quarkus-langchain4j/dev/infinispan-store.html">Quarkus Langchain4j</a> quarkiverse extension.
It can be used as an <a href="https://docs.langchain4j.dev/integrations/embedding-stores/infinispan">embedding store</a> thanks to the support added to vector search.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="query">Query</h2>
<div class="sectionbody">
<div class="paragraph">
<p>We finally made it easy to execute queries directly from the cache API, instead of having to go through the Search/QueryFactory combination:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">Query<Image> query = cache.query("from play.image where moment between :from and :to order by moment desc");
query.setParameter("from", fromDate);
query.setParameter("to", toDate);</code></pre>
</div>
</div>
<div class="paragraph">
<p>The query result object evolved to provide accurate information about the hit count.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">QueryResult<Game> result = query.execute();
HitCount hitCount = result.count();
hitCount.value() // returns the value
hitCount.isExact() // returns the accuracy</code></pre>
</div>
</div>
<div class="paragraph">
<p>Moreover, hit count accuracy can be configured both globally and for each query execution to improve the performance of the queries.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>the efficiency of the #list query method has been improved.</p>
</li>
<li>
<p>High-performance indexed count aggregation queries are now supported.</p>
</li>
<li>
<p>More projections kinds have been added:</p>
<div class="ulist">
<ul>
<li>
<p>Score</p>
</li>
<li>
<p>Version</p>
</li>
<li>
<p>Star/Identity</p>
<div class="paragraph">
<p>and they are now available also using the REST query APIs.</p>
</div>
</li>
</ul>
</div>
</li>
<li>
<p>BigDecimal and BigInteger types are now supported on the ickle queries.</p>
</li>
<li>
<p>index sharding is now configurable.</p>
</li>
<li>
<p>indexing can be now configured in manual mode.</p>
</li>
<li>
<p>index statistics now also contain the faults.</p>
</li>
<li>
<p>the index engine is now called in a non-blocking fashion.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="tracing">Tracing</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The tracing subsystem configuration was greatly improved. Tracing can be configured both globally:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><cache-container name="default">
<tracing collector-endpoint="${infinispan.tracing.collector-endpoint}" security=”true” />
</cache-container></code></pre>
</div>
</div>
<div class="paragraph">
<p>and per-cache:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">tracing:
enabled: true
categories:
- "container"
- "cluster"
- "persistence"
- “x-site”</code></pre>
</div>
</div>
<div class="paragraph">
<p>Moreover, many more things can be traced:
* cluster calls
* cross-site calls
* persistence operations
* security audit operations</p>
</div>
<div class="paragraph">
<p>All of the aboive, with the only exception of the security tracing, can be enabled / disabled at runtime.</p>
</div>
<div class="paragraph">
<p>The following is a trace going from client application to the server via Hot Rod, involving a call to a persistent store;.</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="/assets/images/blog/tracing15-1.png"><img src="/assets/images/blog/thumb-tracing15-1.png" alt="Tracing #1" width="550" height="107"></a>
</div>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="/assets/images/blog/tracing15-2.png"><img src="/assets/images/blog/thumb-tracing15-2.png" alt="Tracing #2" width="550" height="101"></a>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="console">Console</h2>
<div class="sectionbody">
<div class="paragraph">
<p>List the connected clients from the console.</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="/assets/images/blog/console15-1.png"><img src="/assets/images/blog/thumb-console15-1.png" alt="Console #1" width="550" height="291"></a>
</div>
</div>
<div class="paragraph">
<p>Manage roles, users and access control for Principal Role Mappers from the console.</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="/assets/images/blog/console15-2.png"><img src="/assets/images/blog/thumb-console15-2.png" alt="Console #1" width="550" height="302"></a>
</div>
</div>
<div class="paragraph">
<p>Infinispan Server web console can be switched to dark mode.</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="/assets/images/blog/console15-3.png"><img src="/assets/images/blog/thumb-console15-3.png" alt="Console #3" width="550" height="286"></a>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="core">Core</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Many of the core optimizations have been around optimizing intra-cluster communications, especially around previous values that were identified being returned when they are not needed. This ensures Infinispan only sends the cache value around only in the case of put operations, reducing those payloads substantially.</p>
</div>
<div class="sect2">
<h3 id="remove-operations-behavior-change">Remove Operations behavior change</h3>
<div class="paragraph">
<p>Remove operations on a non tx cache will no longer generate intra-cluster traffic if no value is present. Cross sit removes are still always replicated due to not knowing if the other site has the key or not. Stores may load the key to see if it is present to invoke a remove or not, depending on the cache configuration.
This also may prevent some listeners from receiving remove notifications, since the operation is not replicated.</p>
</div>
</div>
<div class="sect2">
<h3 id="writes-on-backup-nodes-do-not-retrieve-previous-value">Writes on Backup Nodes do not retrieve previous value</h3>
<div class="paragraph">
<p>Internally write operations would be performed on backup nodes returning the previous value to the primary owner. There is no need for this and as such we have optimized intra cluster communication to no longer return this value.</p>
</div>
</div>
<div class="sect2">
<h3 id="converter-listener-can-ignore-old-value">Converter Listener can ignore old value</h3>
<div class="paragraph">
<p>Listener converters can override a new method includeOldValue. This allows for a converter to not send an old value along in a change event, reducing payload size of such events. This is useful for events where they only utilize the new value. Link to the source.</p>
</div>
<div class="paragraph">
<p>An example of a converter that just appends the new value and lifespan as the value for the listener.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java"> @ProtoName("StringAppender")
public static class StringAppender implements CacheEventConverter<Object, String, String> {
@Override
public String convert(Object key, String oldValue, Metadata oldMetadata, String newValue, Metadata newMetadata, EventType eventType) {
return oldValue + (oldMetadata != null ? oldMetadata.lifespan() : "null") + newValue + (newMetadata != null ? newMetadata.lifespan() : "null");
}
/**
* Whether the old value should be returned in the event with the converted value.
*/
@Override
public boolean includeOldValue() {
return false;
}
}</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="marshalling">Marshalling</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Our ProtoStream library, which handles annotation-based generation of Protocol Buffers marshallers, has been updated to finally support the proto3 syntax, including the <code>map</code> type. ProtoStream can now generate marshallers for Java <code>records</code>, as well as introducing a new annotation <code>@Proto</code> which makes life much simpler:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Proto
@Indexed
public record Book(
@Text String title,
@Keyword(projectable = true, sortable = true, normalizer = "lowercase", indexNullAs = "unnamed", norms = false) String description,
int publicationYear,
Set<Author> authors,
Type bookType,
BigDecimal price
) { }</code></pre>
</div>
</div>
<div class="paragraph">
<p>ProtoStream’s programmatic API has also received some love: you can now generate schemas from your code, and you can easily implement hand-written marshallers in case the annotation-based magic doesn’t work for you.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">Schema schema = new Schema.Builder("magazine.proto")
.packageName("magazine_sample")
.addMessage("Magazine")
.addField(Type.Scalar.STRING, "name", 1)
.addField(Type.Scalar.INT32, "publicationYear", 2)
.addField(Type.Scalar.INT32, "publicationMonth", 3)
.addRepeatedField(Type.Scalar.STRING, "stories", 4)
.build();
FileDescriptorSource file = FileDescriptorSource.fromString("magazine.proto", schema.toString());</code></pre>
</div>
</div>
<div class="paragraph">
<p>By popular demand, we have also undeprecated the use of JBoss Marshalling, although we still highly recommend ProtoBuf for interoperability and performance.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="memcached-protocol">Memcached protocol</h2>
<div class="sectionbody">
<div class="paragraph">
<p>We upgraded our memcached connector to support the binary protocol as well as supporting authentication and encryption for both the text and binary variants. Because of this, the connector is also exposed via our single-port, with protocol auto-detection! While we do not yet support the Memcached meta commands, text-based authentication can be performed by sending a fake <code>set`</code> command with any key:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">set <key> <flags> <exptime> <bytes>\r\n
username password\r\n</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="server">Server</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Server security has been expanded with the new <code>aggregate-realm</code> type, which allows you to combine different realm types for authentication and authorization. For example, you could use client certificates for authentication and an LDAP server to perform authorization:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><server xmlns="urn:infinispan:server:15.0">
<security>
<security-realms>
<security-realm name="default" default-realm="aggregate">
<server-identities>
<ssl>
<keystore path="server.pfx" password="secret" alias="server"/>
<truststore path="trust.pfx" password="secret"/>
</ssl>
</server-identities>
<properties-realm groups-attribute="Roles">
<user-properties path="users.properties" relative-to="infinispan.server.config.path"/>
<group-properties path="groups.properties" relative-to="infinispan.server.config.path"/>
</properties-realm>
<truststore-realm/>
<aggregate-realm authentication-realm="trust" authorization-realms="properties">
<name-rewriter>
<common-name-principal-transformer/>
</name-rewriter>
</aggregate-realm>
</security-realm>
</security-realms>
</security>
</server></code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="persistence">Persistence</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Along with the sub changes below we also have optimized persistent entries that do not have expiration or other custom metadata, reducing marshalled byte size by approximately 40 bytes per entry.</p>
</div>
<div class="sect2">
<h3 id="soft-index-file-store">Soft-Index File Store</h3>
<div class="paragraph">
<p>The underlying index for the Soft Index File Store has been completely revamped to no longer utilize a different set of “segments” for its index. Instead it splits its index into a number equal to the caches configured segments (ie. cache → clustering → hash → number of segments). The “index segments” configuration is now deprecated and ignored.</p>
</div>
<div class="paragraph">
<p>This change allows for more efficient segment based operations.
Iteration within a subset of segments now only needs to read a single file instead of multiple.
Cache rebalance with DIST is now orders of magnitude faster as it just drops a single index
Key lookup is also now slightly faster (on average 4 less hash comparisons)</p>
</div>
<div class="paragraph">
<p>Index files now also utilize a portion of the open files limit to prevent possibility of file descriptor exhaustion. By default the index will use up to 10% of the file limit to keep files open, closing as needed.</p>
</div>
</div>
<div class="sect2">
<h3 id="passivation">Passivation</h3>
<div class="paragraph">
<p>Passivation has been changed to be less chatty. Originally passivation required contents to only be in memory or in the store. This has been found to generate too many write operations to the underlying store. Instead now it is permitted that a value be stale in the store when it is present in memory. This prevents many remove operations from being generated. Upon shutdown or if the entry is evicted from memory only then will the store be updated with the proper value.</p>
</div>
<div class="paragraph">
<p>With a clean shutdown there will be no data inconsistency with a restart. It should be noted that if the node crashes without proper shutdown the cache may have a stale value (new behavior) instead of no value (previous behavior) for values that were in memory.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="operator">Operator</h2>
<div class="sectionbody">
<div class="ulist">
<ul>
<li>
<p>Configure Readiness, Liveness and Startup probe values</p>
</li>
<li>
<p>Expose JMX endpoint</p>
</li>
<li>
<p>Configuration of StatefulSet PriorityClass</p>
</li>
<li>
<p>Allow users to define credential-store entries</p>
</li>
<li>
<p>ConfigListener configure CPU and Memory resources</p>
</li>
<li>
<p>Make cross-site failure detection configurable</p>
</li>
<li>
<p>Use TLSv1.3 as default for Xsite</p>
</li>
<li>
<p>Xsite GossipRouter improvements</p>
</li>
<li>
<p>Allow setting the CPU and Memory resources</p>
</li>
<li>
<p>Added and enabled heartbeats by default</p>
</li>
<li>
<p>Disabled suspect events by default</p>
</li>
<li>
<p>TLS client authentication by default</p>
</li>
<li>
<p>Increase the probe timeout</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="helm-charts">Helm charts</h2>
<div class="sectionbody">
<div class="ulist">
<ul>
<li>
<p>Add ability to define custom environment variables</p>
</li>
<li>
<p>Add ability to set tolerations</p>
</li>
<li>
<p>Add support for node affinity and node selectors</p>
</li>
<li>
<p>Allow the user to specify container securityContext</p>
</li>
<li>
<p>Allow TLS configuration on endpoints</p>
</li>
<li>
<p>Allow TLS configuration on JGroups transport</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="graalvm">GraalVM</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In addition to our various Quarkus integrations, Infinispan now provides the <code>infinispan-client-hotrod-graalvm</code> and <code>infinispan-core-graalvm</code> modules. These modules enable you to build native Hot Rod clients and Embedded Infinispan applications natively with GraalVM, allowing integration with other frameworks such as Spring Broot.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="security-manager">Security Manager</h2>
<div class="sectionbody">
<div class="paragraph">
<p>We have completely removed support for the Java Security Manager, since it has been deprecated for removal in the JDK. It was designed mostly for sandboxing Java applets, but it was somehow (wrongly) co-opted as a way to implement similar functionality for normal Java applications. It was slow and cumbersome, and we’re glad to see it go. The removal of SecurityManager support from Infinispan does not affect its authentication and authorization capabilities.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="integrations">Integrations</h2>
<div class="sectionbody">
<div class="ulist">
<ul>
<li>
<p>Our second-level cache component now supports Hibernate ORM 6.4</p>
</li>
<li>
<p>We have dropped CDI support from our JCache provider since the specification has not been updated for Jakarta EE</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="removals">Removals</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Sadly, a couple of items have been removed, as we did not see much use in the wild: scattered caches and the cloud-events integration module. May they rest in peace.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="documentation">Documentation</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Many improvements, updates and fixes.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="release-notes">Release notes</h2>
<div class="sectionbody">
<div class="paragraph">
<p>You can look at the <a href="https://issues.redhat.com/secure/ReleaseNote.jspa?projectId=12310799&version=12377084">release notes</a> to see what has changed since our latest CR.</p>
</div>
<div class="paragraph">
<p>Get them from our <a href="https://infinispan.org/download/">download page</a>.</p>
</div>
</div>
</div>Tristan TarrantDon’t you know I’m still standin' better than I ever did? Lookin' like a true survivor, feelin' like a little kidUsing Infinispan Server for your Redis clients2024-02-02T01:00:00+01:002024-02-02T01:00:00+01:00https://infinispan.org/blog/2024/02/02/infinispan-server-redis-clients<div class="paragraph">
<p>Dear Infinispan community,</p>
</div>
<div class="paragraph">
<p>we’ve put together a video that shows how you can seamlessly connect your Redis clients to Infinispan Server, and take advantage of our advanced capabilities.</p>
</div>
<div class="videoblock">
<div class="content">
<iframe width="640" height="380" src="https://www.youtube.com/embed/Xi9gTA0jfD0?rel=0" frameborder="0" allowfullscreen></iframe>
</div>
</div>Tristan TarrantDear Infinispan community,Infinispan RESP in action: Resque use case2024-01-19T01:00:00+01:002024-01-19T01:00:00+01:00https://infinispan.org/blog/2024/01/19/infinispan-resp-resque-use-case<div class="paragraph">
<p>As you may know Infinispan 15 extended its RESP compatibility implementing most of the command related to the principal data types (set, list, hashes, sorted set…​).</p>
</div>
<div class="paragraph">
<p>In this post we want to present a demo case of integration between a real application (<a href="https://github.com/resque/resque">Resque</a>) and Infinispan used as a Redis-compatible cache backend.<br>
Aim of this is to show how it’s easy to switch between Redis and Infinispan making available to your application all the advanced features of our clustered cache server.</p>
</div>
<div class="paragraph">
<p>Resque is a job scheduler that creates jobs and send them to execution queues, it uses Redis as default backend and provides a testsuite and a demo application.<br>
Try yourself how Infinispan can seamlessly replace the default backend: just clone
<a href="https://github.com/rigazilla/resque/tree/ispn-testsuite">this Resque fork</a> and follow the <a href="https://github.com/rigazilla/resque/blob/ispn-testsuite/README.ispn.md">Infinispan README</a> to run both the test suite and the demo application.</p>
</div>
<div class="paragraph">
<p>Everything worked as a charm? Nice! Now check the diff with the original project, we only added code to turn on/off Infinispan instead of Redis. Nothing more than that! (*)</p>
</div>
<div class="paragraph">
<p>Hope you ejoyed this post!</p>
</div>
<div class="paragraph">
<p>Cheers,<br>
The Infinispan Team</p>
</div>
<div class="paragraph">
<p>(*) What? You also noticed we changed the expected result for a test. Surely you can easily guess why…​ if not just ask us on <a href="https://infinispan.zulipchat.com/#">Zulip</a>!</p>
</div>Vittorio RigamontiAs you may know Infinispan 15 extended its RESP compatibility implementing most of the command related to the principal data types (set, list, hashes, sorted set…​).Infinispan Insights: Securing Infinispan with Keycloak2024-01-09T01:00:00+01:002024-01-09T01:00:00+01:00https://infinispan.org/blog/2024/01/09/infinispan-security-keycloak<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>This tutorial shows you how to secure your Infinispan cluster using Keycloak.
To understand the basics of Infinispan Security, check
<a href="https://infinispan.org/blog/2023/12/19/infinispan-secured-caches">this blog post</a> before.</p>
</div>
<div class="paragraph">
<p><strong>Key Points:</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p>Learn how to create a security realm in Keycloak.</p>
</li>
<li>
<p>Override the default security realm in Infinispan.</p>
</li>
<li>
<p>Authentication and authorization in Infinispan with Keycloak.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="infinispan-and-keycloak-in-a-nutshell">Infinispan and Keycloak in a nutshell</h2>
<div class="sectionbody">
<div class="sect3">
<h4 id="about-infinispan">About Infinispan</h4>
<div class="paragraph">
<p>Infinispan is an open-source, in-memory distributed key/value data store. It is designed to provide fast
and scalable access to frequently accessed data by storing it in memory. In addition to caching,
Infinispan offers features for data distribution, replication, and partitioning, making it suitable
for use in distributed and clustered environments.</p>
</div>
<div class="paragraph">
<p>Infinispan is often used in scenarios where low-latency access to data is critical, such as caching
frequently accessed database queries, session data in web applications, or other
use cases where quick access to data can improve overall system performance</p>
</div>
</div>
<div class="sect3">
<h4 id="about-keycloak">About Keycloak</h4>
<div class="paragraph">
<p><a href="https://www.keycloak.org/">Keycloak</a> is an open-source identity and access management solution developed by Red Hat.
It provides functionalities for identity and access management, including features like single sign-on (SSO),
user authentication, authorization, and user federation. Keycloak is designed to simplify the implementation
of security protocols and standards such as OAuth 2.0, OpenID Connect, and SAML.
Some key features include Single Sign-On (SSO), Identity Brokering, User Authentication,
User Federation, RBAC and more.</p>
</div>
</div>
<div class="sect3">
<h4 id="infinispan-and-keycloak">Infinispan and Keycloak</h4>
<div class="paragraph">
<p>Keycloak uses Infinispan as its underlying data store for caching and storage purposes.
Infinispan provides scalable and efficient caching of authentication and authorization-related data.
This helps improve performance and responsiveness, especially in scenarios where quick access to user
session information and other identity-related data is crucial.</p>
</div>
<div class="paragraph">
<p>Some ways <strong>Keycloak leverages Infinispan</strong> include Caching User Sessions, storing Authorization policies,
providing distributed caching, improving performance, <a href="https://www.keycloak.org/2023/12/recover-site-failures">failover recovering</a>
and more.</p>
</div>
</div>
<div class="sect3">
<h4 id="what-about-infinispan-leveraging-keycloak">What about Infinispan leveraging Keycloak ?</h4>
<div class="paragraph">
<p>Infinispan provides several ways to handle authentication and user management.
By default, the security realm is properties based. However, token based authentication is supported
and Keycloak can be used for that purpose.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="creating-a-security-realm-in-keycloak">Creating a Security Realm in Keycloak</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="run-keycloak-in-dev-mode">Run Keycloak in dev mode</h3>
<div class="paragraph">
<p>The easiest way to use Keycloak on your laptop is in a container using the development mode.
Because we’re going to run Keycloak in one container and Infinispan in another, let’s set up
a network to connect them.</p>
</div>
<div class="paragraph">
<p>For Linux users, there’s an option called <strong>network_mode: host</strong> that might be available
to you instead of using a network bridge. However, since this option doesn’t work for
Mac or Windows currently, we’ll focus on the method that suits all operating systems.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-bash hljs" data-lang="bash">docker network create -d bridge mynetwork
docker run -p 8080:8080 --network=mynetwork --name=keycloak -e KEYCLOAK_ADMIN=keycloak -e KEYCLOAK_ADMIN_PASSWORD=keycloak quay.io/keycloak/keycloak:latest start-dev</code></pre>
</div>
</div>
<div class="paragraph">
<p>Keycloak Image will create an administrator user by defining the KEYCLOAK_ADMIN and KEYCLOAK_ADMIN_PASSWORD
environment variables.</p>
</div>
<div class="paragraph">
<p>After getting the container up and running, go to <a href="http://localhost:8080">http://localhost:8080</a>
Click on the Administration Console link, and log in using the credentials <strong>"keycloak/keycloak"</strong>.</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="/assets/images/blog/2024-01-09-infinispan-secured-keycloak/adminKeycloak.png"><img src="/assets/images/blog/2024-01-09-infinispan-secured-keycloak/adminKeycloak.png" alt="Admin Keycloak" width="800" height="316"></a>
</div>
</div>
</div>
<div class="sect2">
<h3 id="create-a-realm">Create a realm</h3>
<div class="paragraph">
<p>Keycloak realms are a fundamental concept in Keycloak. Realms in Keycloak serve as a way to
isolate and manage different sets of users, applications, and their associated configurations.</p>
</div>
<div class="paragraph">
<p>Using the web administration tool, create a new realm called <strong>"Infinispan"</strong>.
This realm is what the Infinispan Server will use in the later steps of this tutorial.</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="/assets/images/blog/2024-01-09-infinispan-secured-keycloak/createRealmKeycloak.png"><img src="/assets/images/blog/2024-01-09-infinispan-secured-keycloak/createRealmKeycloak.png" alt="Keycloak create realm" width="200" height="192"></a>
</div>
</div>
<div class="paragraph">
<p>Name your realm <strong>“infinispan”</strong>.</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="/assets/images/blog/2024-01-09-infinispan-secured-keycloak/infinispanRealmKeycloak.png"><img src="/assets/images/blog/2024-01-09-infinispan-secured-keycloak/infinispanRealmKeycloak.png" alt="Keycloak: realm name is infinispan" width="800" height="569"></a>
</div>
</div>
</div>
<div class="sect2">
<h3 id="create-the-infinispan-clients">Create the Infinispan clients</h3>
<div class="paragraph">
<p>Clients are entities that can request authentication of a user. Clients come in two forms.
The first type of client is an application that wants to participate in single-sign-on.
These clients just want Keycloak to provide security for them. The other type of client is one that
is requesting an access token so that it can invoke other services on behalf of the authenticated user.</p>
</div>
<div class="paragraph">
<p>For the Infinispan Server and testing the Console security, we’ll require two clients set up
in Keycloak: one named <strong>"infinispan-console"</strong> and the other <strong>"infinispan-server"</strong>.</p>
</div>
<div class="sect3">
<h4 id="infinispan-console-client">Infinispan Console Client</h4>
<div class="paragraph">
<p>Create a Keycloak client named <strong>“infinispan-console”</strong>. The Infinispan Web Console uses this client
to authenticate console users with Keycloak in order to obtain an authentication token. This token is
then used to authenticate all requests by the console to the Infinispan server.</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="/assets/images/blog/2024-01-09-infinispan-secured-keycloak/infinispan-client-stepOne.png"><img src="/assets/images/blog/2024-01-09-infinispan-secured-keycloak/infinispan-client-stepOne.png" alt="Keycloak: infinispan-console client step 1" width="800" height="377"></a>
</div>
</div>
<div class="paragraph">
<p>Configure the valid redirect URIs with Infinispan’s console URI: <strong><a href="http://localhost:11222" class="bare">http://localhost:11222</a></strong></p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="/assets/images/blog/2024-01-09-infinispan-secured-keycloak/infinispan-client-stepTwo.png"><img src="/assets/images/blog/2024-01-09-infinispan-secured-keycloak/infinispan-client-stepTwo.png" alt="Keycloak: infinispan-console client step 2" width="800" height="503"></a>
</div>
</div>
<div class="paragraph">
<p>This step is completed.</p>
</div>
</div>
<div class="sect3">
<h4 id="infinispan-server-client">Infinispan Server Client</h4>
<div class="paragraph">
<p>Create a second client called <strong>"infinispan-server"</strong>. Set <strong>"client authentication"</strong> to <strong>"ON"</strong>.
This defines the type of the OIDC client. When it’s ON, the OIDC type is set to confidential
access type. When it’s OFF, it is set to public access type ("infinispan-console" client type).</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="/assets/images/blog/2024-01-09-infinispan-secured-keycloak/infinispan-server-client-stepTwo.png"><img src="/assets/images/blog/2024-01-09-infinispan-secured-keycloak/infinispan-server-client-stepTwo.png" alt="Keycloak: infinispan-server client step 2" width="800" height="368"></a>
</div>
</div>
<div class="paragraph">
<p>This step is completed.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="create-a-user">Create a user</h3>
<div class="paragraph">
<p>Once we have the two clients created, we need to create an admin user for Infinispan.</p>
</div>
<div class="paragraph">
<p>Click on the <strong>"users"</strong> menu, and create a user named <strong>"admin"</strong>.</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="/assets/images/blog/2024-01-09-infinispan-secured-keycloak/createAdminUser.png"><img src="/assets/images/blog/2024-01-09-infinispan-secured-keycloak/createAdminUser.png" alt="Keycloak: create admin" width="800" height="448"></a>
</div>
</div>
<div class="paragraph">
<p>Once the user admin is created, navigate to the user detail page.</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="/assets/images/blog/2024-01-09-infinispan-secured-keycloak/adminDetailKeycloak.png"><img src="/assets/images/blog/2024-01-09-infinispan-secured-keycloak/adminDetailKeycloak.png" alt="Keycloak: admin detail" width="800" height="575"></a>
</div>
</div>
<div class="paragraph">
<p>In the credentials tab, create a password for the user, for example, <strong>"adminPassword"</strong>.</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="/assets/images/blog/2024-01-09-infinispan-secured-keycloak/adminSetAPasswordKeycloak.png"><img src="/assets/images/blog/2024-01-09-infinispan-secured-keycloak/adminSetAPasswordKeycloak.png" alt="Keycloak: admin set password" width="500" height="273"></a>
</div>
</div>
<div class="paragraph">
<p>We are now ready to run Infinispan.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="running-infinispan-secured-with-a-keycloak-realm">Running Infinispan secured with a Keycloak realm</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="create-the-infinispan-security-realm-configuration">Create the Infinispan security realm configuration</h3>
<div class="paragraph">
<p>You can configure this in XML, JSON, or YAML. In the example provided below, the configuration
is in YAML format.</p>
</div>
<div class="paragraph">
<p>Create a file named <strong>infinispan-token-realm.yaml</strong> with the following content.</p>
</div>
<div class="paragraph">
<p><strong>infinispan-token-realm.yaml</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre>server:
security:
securityRealms:
- name: default
tokenRealm:
name: infinispan
authServerUrl: 'http://keycloak:8080'
client-id: infinispan-console
oauth2Introspection:
clientId: infinispan-server
clientSecret: 'COPY AND PASTE THE SECRET FROM KEYCLOAK'
introspectionUrl: 'http://keycloak:8080/realms/infinispan/protocol/openid-connect/token/introspect'</pre>
</div>
</div>
<div class="paragraph">
<p>We are not done yet!!</p>
</div>
<div class="paragraph">
<p>Read the following sections to understand and <strong>change the placeholders</strong> in the file.</p>
</div>
<div class="sect3">
<h4 id="default-security-realm-name">Default Security Realm name</h4>
<div class="paragraph">
<p>The security realm is named <strong>"default"</strong>. This file is designed to replace the default security realm
in Infinispan, which is originally based on properties, with the configuration for this
token-based realm.</p>
</div>
</div>
<div class="sect3">
<h4 id="client-secret">Client Secret</h4>
<div class="paragraph">
<p>Retrieve the secret for the <strong>"infinispan-server"</strong> client from the Keycloak Administration,
and then paste the secret value into the file replacing <strong>'COPY AND PASTE THE SECRET FROM KEYCLOAK'</strong>.</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="/assets/images/blog/2024-01-09-infinispan-secured-keycloak/grabSecretFromInfinispanServerClient.png"><img src="/assets/images/blog/2024-01-09-infinispan-secured-keycloak/grabSecretFromInfinispanServerClient.png" alt="Keycloak: grab secret" width="800" height="465"></a>
</div>
</div>
</div>
<div class="sect3">
<h4 id="authentication-server-url-authserverurl">Authentication Server URL - <strong>authServerUrl</strong></h4>
<div class="paragraph">
<p>The authentication server is Keycloak, and it’s running at <strong>localhost:8080</strong>. However, in the YAML
configuration above, we used <strong>"keycloak"</strong> instead of "localhost" (the container name).
This adjustment is needed when running containers in a Docker network. The Infinispan Server
will be reaching out to the Keycloak Server inside the Docker environment. As mentioned earlier,
Linux users can use "localhost" with the <strong>network_mode: host</strong> configuration.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="run-the-infinispan-server-overriding-the-default-security-realm">Run the Infinispan Server overriding the default security realm</h3>
<div class="paragraph">
<p>Lets run Infinispan in a container providing the created security realm configuration.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-bash hljs" data-lang="bash">docker run -it -p 11222:11222 -v $(pwd):/user-config
--network=mynetwork
--name=infinispan quay.io/infinispan/server:15.0
-c infinispan.xml
-c /user-config/infinispan-token-realm.yaml</code></pre>
</div>
</div>
<div class="paragraph">
<p>The command:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>Creates a volume "user-config"</strong> in the current directory where we created the file <code>infinispan-token-realm.yaml</code></p>
</li>
<li>
<p><strong>Attaches the container to the network "mynetwork"</strong> so Infinispan and Keycloak can connect</p>
</li>
<li>
<p><strong>Uses <code>-c</code></strong>, which means the container is using the default configuration file, <code>infinispan.xml</code>.
Yet, specifying another <code>-c</code> file, it adds the content of <code>infinispan-token-realm.yaml</code> to <code>infinispan.xml</code>.
Since this file configures the default security realm, the original Infinispan default properties realm
will be replaced with the token-based realm.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="verify-the-changes">Verify the changes</h3>
<div class="paragraph">
<p>Accessing the following URL provides the information used by the Infinispan Web console
to handle authentication.</p>
</div>
<div class="paragraph">
<p><a href="http://localhost:11222/rest/v2/login?action=config" class="bare">http://localhost:11222/rest/v2/login?action=config</a></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-json hljs" data-lang="json">{
"mode": "OIDC",
"clientId": "infinispan-console",
"ready": "true",
"realm": "infinispan",
"url": "http://keycloak:8080"
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The Infinispan Console will use the information above, and making use of the
<a href="https://www.keycloak.org/docs/latest/securing_apps/index.html#_javascript_adapter">Keycloak Javascript Adapter</a>,
the interface will redirect to Keycloak for user authentication.</p>
</div>
</div>
<div class="sect2">
<h3 id="connect-to-the-console-with-the-admin-user">Connect to the console with the admin user</h3>
<div class="paragraph">
<p>Go the console web URL: <a href="http://localhost:11222" class="bare">http://localhost:11222</a></p>
</div>
<div class="sect3">
<h4 id="this-site-cant-be-reached">This site can’t be reached</h4>
<div class="paragraph">
<p>The console needs to access Keycloak from outside the container.
However, the realm configuration uses <code>keycloak</code> host.</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="/assets/images/blog/2024-01-09-infinispan-secured-keycloak/siteNotReached.png"><img src="/assets/images/blog/2024-01-09-infinispan-secured-keycloak/siteNotReached.png" alt="Site not reached" width="400" height="263"></a>
</div>
</div>
<div class="paragraph">
<p>To avoid this issue, the workaround is simple: add to the following line to the <code>/etc/hosts</code> file:</p>
</div>
<div class="listingblock">
<div class="content">
<pre> 127.0.0.1 keycloak</pre>
</div>
</div>
<div class="paragraph">
<p>As mentioned before, If you are using linux you can avoid this by using localhost and running
both containers with network_mode: host.</p>
</div>
</div>
<div class="sect3">
<h4 id="authenticate-using-keycloak">Authenticate using Keycloak</h4>
<div class="paragraph">
<p>When opening the Infinispan Console, Infinispan will attempt to make a call to a REST API
that requires authentication. You’ll be redirected to the Keycloak authentication, where you
should use the credentials <strong>admin/adminPassword</strong>. When you initially connect as admin,
you’ll be prompted to change the password. For this example, you can stick with "adminPassword".</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="/assets/images/blog/2024-01-09-infinispan-secured-keycloak/authenticateUsingKeycloak.png"><img src="/assets/images/blog/2024-01-09-infinispan-secured-keycloak/authenticateUsingKeycloak.png" alt="Infinispan: authenticate with Keycloak" width="400" height="258"></a>
</div>
</div>
<div class="paragraph">
<p>After Keycloak redirects back to the Infinispan Console, you can verify that admin is authenticated.
However, you will encounter Unauthorized errors in the console interface, since the connected
user’s roles are not known by Infinispan.</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="/assets/images/blog/2024-01-09-infinispan-secured-keycloak/adminIsNotAnAdmin.png"><img src="/assets/images/blog/2024-01-09-infinispan-secured-keycloak/adminIsNotAnAdmin.png" alt="Admin has not admin role" width="800" height="264"></a>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="create-and-assign-infinispan-admin-role">Create and assign Infinispan ADMIN role</h3>
<div class="paragraph">
<p>To grant complete access to the admin user, it’s necessary to create a role named <strong>"admin"</strong>
and assign that role to the user in Keycloak.</p>
</div>
<div class="sect3">
<h4 id="create-the-admin-role-in-keycloak">Create the ADMIN role in Keycloak</h4>
<div class="paragraph">
<p>Open the Keycloak administration interface, click on "Roles", and then create a role with the name
"admin".</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="/assets/images/blog/2024-01-09-infinispan-secured-keycloak/createRoleAdminKeycloak.png"><img src="/assets/images/blog/2024-01-09-infinispan-secured-keycloak/createRoleAdminKeycloak.png" alt="Keycloak: create admin role" width="800" height="285"></a>
</div>
</div>
</div>
<div class="sect3">
<h4 id="assign-the-admin-role-in-keycloak">Assign the ADMIN role in Keycloak</h4>
<div class="paragraph">
<p>In the admin user detail page, go to the Role Mapping tab and assign the previously created
"admin" role there.</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="/assets/images/blog/2024-01-09-infinispan-secured-keycloak/asignAdminRoleToAdminUser.png"><img src="/assets/images/blog/2024-01-09-infinispan-secured-keycloak/asignAdminRoleToAdminUser.png" alt="Keycloak: assign admin role to admin user" width="800" height="361"></a>
</div>
</div>
<div class="paragraph">
<p>Return to the Infinispan Console, and you’ll notice that the admin user is now granted the
admin role in Infinispan as well.</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="/assets/images/blog/2024-01-09-infinispan-secured-keycloak/adminIsGranted.png"><img src="/assets/images/blog/2024-01-09-infinispan-secured-keycloak/adminIsGranted.png" alt="Infinispan: admin is granted" width="800" height="440"></a>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="to-go-further">To go further</h3>
<div class="paragraph">
<p>In the <a href="https://infinispan.org/tutorials/simple/simple_tutorials.html#secured_with_token_keycloak_remote-cache-tutorials">Infinispan Simple tutorials</a>
repository you will find an example with docker-compose, for Linux and non linux users.
There are many other advanced features in Keycloak, this is just the most simple use case.</p>
</div>
<div class="paragraph">
<p>Learn more about it in the Keycloak and Infinispan documentation.</p>
</div>
</div>
</div>
</div>Katia ArestiThis tutorial shows you how to secure your Infinispan cluster using Keycloak. To understand the basics of Infinispan Security, check this blog post before.Infinispan Insights: Security basics and secured caches2023-12-20T01:00:00+01:002023-12-20T01:00:00+01:00https://infinispan.org/blog/2023/12/20/infinispan-secured-caches<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>This article shows you how to secure your Infinispan cluster, protecting both cluster management and data
access in various Infinispan caches</p>
</div>
<div class="paragraph">
<p><strong>Key Points:</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p>Learn how default authentication works in Infinispan</p>
</li>
<li>
<p>Explore how authorization works in Infinispan.</p>
</li>
<li>
<p>Understand the basics of creating secure caches in a straightforward way with Infinispan.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="security-in-a-nutshell">Security in a nutshell</h2>
<div class="sectionbody">
<div class="paragraph">
<p>When we talk about security, there are two main things to consider: proving who you are (authentication) and deciding
what you’re allowed to do (authorization). These tasks are managed by one or more security realms.</p>
</div>
<div class="sect3">
<h4 id="authentication">Authentication</h4>
<div class="paragraph">
<p>Authentication is the process of verifying the identity of an entity, such as a user, system, or device, to ensure
that it is who or what it claims to be. It can be done through different methods such as password based authentication,
token based authentication, certificate based… and more.</p>
</div>
</div>
<div class="sect3">
<h4 id="authorization">Authorization</h4>
<div class="paragraph">
<p>Authorization is the process of granting or denying access permissions to authenticated users or entities.
It defines what actions or resources users are allowed to access based on their verified identity.
Authorization works alongside authentication to ensure that only authorized users can perform specific actions within a
system. Infinispan uses Role-Based Access Control (RBAC) for authorization.</p>
</div>
</div>
<div class="sect3">
<h4 id="security-realms">Security Realms</h4>
<div class="paragraph">
<p>A security realm is a set of policies and authentication methods governing access to a system or resource.
It establishes rules for user authentication and authorization, such as using usernames/passwords or advanced methods
like OAuth. Security realms integrate Infinispan Server deployments with the network protocols and infrastructure
in your environment that control access and verify user identities.
Infinispan integrates with Kerberos, LDAP, Trust stores… and token based authentication such as <a href="https://openid.net/">OpenID Connect</a>
providers such as <a href="https://www.keycloak.org/">Keycloak</a>.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="infinispan-server-security">Infinispan Server Security</h2>
<div class="sectionbody">
<div class="paragraph">
<p>To truly grasp the basics, the best method is hands-on experience.
Infinispan 15.0 simplifies understanding authentication and authorization through a visual interface.</p>
</div>
<div class="sect3">
<h4 id="running-the-infinispan-server-with-a-single-user">Running the Infinispan Server with a single user</h4>
<div class="paragraph">
<p>Start by running the Infinispan Server with a Docker or Podman container.
Make sure you have the latest version of the Infinispan Server 15.0 image by pulling it locally.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-bash hljs" data-lang="bash"># Podman
podman run -it -p 11222:11222 -e USER="admin" -e PASS="password" --net=host quay.io/infinispan/server:15.0
# Docker
docker run -it -p 11222:11222 -e USER="admin" -e PASS="password" quay.io/infinispan/server:15.0</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="infinispan-defaults">Infinispan defaults</h4>
<div class="paragraph">
<p>In Infinispan, the default security realm relies on properties.
Users are established in a local properties file on the active server.
By running the container and providing "USER" and "PASS" environment variables, the
server generates a user capable of authenticating to Infinispan and is automatically granted
the "admin" implicit role.</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="/assets/images/blog/2023-12-19-secured-caches/browser-DIGEST.png"><img src="/assets/images/blog/2023-12-19-secured-caches/browser-DIGEST.png" alt="Browser authentication" width="800" height="547"></a>
</div>
</div>
<div class="paragraph">
<p>Infinispan doesn’t maintain user authentication through a session management system in the server for
its REST API. The REST API operates in a stateless manner, and authentication, as well as role-based
access control (RBAC), is facilitated through the AUTHENTICATION header when interacting
with the REST API. The console is built using the REST API. DIGEST mechanism is part
of the supported mechanism, so the browser will ask for user/password using the native browser
authentication mechanism. For security reasons, BASIC authentication is not enabled by default
unless TLS is also configured.</p>
</div>
</div>
<div class="sect3">
<h4 id="implicit-rbac">Implicit RBAC</h4>
<div class="paragraph">
<p>Infinispan safeguards operations by specifying various permissions to operations such as creating caches,
resetting statistics, uploading data schemas, and more. A role is a set of 1 or more permissions.
Implicit authorization is enabled by default, providing predefined roles to which users can be assigned,
granting them the ability to execute specific actions.</p>
</div>
<div class="paragraph">
<p>Starting from Infinispan 15, a new feature in the console allows users to view these roles, their
corresponding permissions, and descriptions. It is now also possible to create custom roles with
specific permissions directly from the web console (previously, this capability was limited to the
Command Line Tool). However, for the purpose of this article, we will focus on utilizing the pre-existing
implicit roles.</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="/assets/images/blog/2023-12-19-secured-caches/implicit-ROLES.png"><img src="/assets/images/blog/2023-12-19-secured-caches/implicit-ROLES.png" alt="Implicit roles" width="800" height="394"></a>
</div>
</div>
</div>
<div class="sect3">
<h4 id="running-the-server-with-multiple-users">Running the server with multiple users</h4>
<div class="paragraph">
<p>To start Infinispan locally with multiple users and distinct roles, we can employ a
identities batch that is passed to the container during startup.</p>
</div>
<div class="paragraph">
<p>1) Create a file called <strong>identities.batch</strong> with the following content.
To simplify matters, we have established a straightforward one-to-one mapping between user
names and roles.</p>
</div>
<div class="paragraph">
<p><strong>identities.batch</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre>user create "admin" -p "password" -g admin
user create "observer" -p "password" -g observer
user create "monitor" -p "password" -g monitor
user create "deployer" -p "password" -g deployer
user create "application" -p "password" -g application</pre>
</div>
</div>
<div class="paragraph">
<p>2) Provide the file on run, by creating the user-config volume and passing the IDENTITIES_BATCH env variable.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-bash hljs" data-lang="bash"># Podman
podman run -it -p 11222:11222 -v $(pwd):/user-config -e IDENTITIES_BATCH="/user-config/identities.batch" --net=host quay.io/infinispan/server:15.0
# Docker
docker run -it -p 11222:11222 -v $(pwd):/user-config -e IDENTITIES_BATCH="/user-config/identities.batch" quay.io/infinispan/server:15.0</code></pre>
</div>
</div>
<div class="paragraph">
<p>Those users are now available and listed in the Infinispan Web Console.</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="/assets/images/blog/2023-12-19-secured-caches/users-BATCH.png"><img src="/assets/images/blog/2023-12-19-secured-caches/users-BATCH.png" alt="Implicit roles" width="724" height="453"></a>
</div>
</div>
<div class="paragraph">
<p>When connecting with the "observer" user, which possesses the "observer" role,
it becomes apparent that this user is unable to access certain actions in the console that
necessitate "admin" role’s permissions. Examples include creating a cache, viewing connected clients,
or accessing the access management functionalities.</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="/assets/images/blog/2023-12-19-secured-caches/connect-OBSERVER.png"><img src="/assets/images/blog/2023-12-19-secured-caches/connect-OBSERVER.png" alt="connect observer" width="800" height="271"></a>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="secured-caches-in-infinispan">Secured Caches in Infinispan</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In Infinispan, it’s possible to create caches with data manipulation permissions restricted
to specific roles.</p>
</div>
<div class="sect3">
<h4 id="creating-a-secured-cache">Creating a secured cache</h4>
<div class="paragraph">
<p>For testing purposes, connect using the credentials admin/password and click on the
“Create a cache” button in the Data Container page. In the cache creation wizard, after opting
for all the default settings, select the "Authorization" capability, and the "admin" and "monitor"
roles.</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="/assets/images/blog/2023-12-19-secured-caches/create-CACHE.png"><img src="/assets/images/blog/2023-12-19-secured-caches/create-CACHE.png" alt="Create Secured Cache" width="800" height="408"></a>
</div>
</div>
<div class="paragraph">
<p>The final cache configuration will look like this:</p>
</div>
<div class="paragraph">
<p><strong>config.yaml</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre>distributedCache:
owners: "2"
mode: "SYNC"
statistics: "true"
encoding:
mediaType: "application/x-protostream"
security:
authorization:
enabled: "true"
roles:
- "admin"
- "monitor"</pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="accessing-the-secured-cache">Accessing the Secured Cache</h4>
<div class="paragraph">
<p>When using the "admin" user, the cache will have unrestricted access because the admin role has all the permissions. On the other hand, connecting with the "monitor" user, which is assigned the monitor role, the cache is visible. However, as the monitor role is designed solely for monitoring and not data creation, only data associated with the cache metrics will be accessible.</p>
</div>
<div class="paragraph">
<p>For users lacking the admin or monitor role, accessing the cache from the console is not possible.</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="/assets/images/blog/2023-12-19-secured-caches/secured-cache-MONITOR.png"><img src="/assets/images/blog/2023-12-19-secured-caches/secured-cache-MONITOR.png" alt="Console: monitor connects" width="800" height="310"></a>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="going-further">Going further</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In this article, you’ve explored the interplay of permissions, roles, Infinispan Security,
and the fundamentals of secured caches. Beyond these, Infinispan Security management offers a
range of additional capabilities. These include features like
<a href="https://infinispan.org/docs/stable/titles/security/security.html#configuring-encryption">data encryption</a>
and advanced security, such as providing access to an entire group of users managed by systems like LDAP.
This is achieved through a Principal Role Mapper, which establishes a connection between all these
users and a specific role.
Infinispan supports many authentication mechanisms, such as token based authentication,
which can be handled with Keycloak. Run the
<a href="https://infinispan.org/tutorials/simple/simple_tutorials.html#secured_with_token_keycloak_remote-cache-tutorials">simple tutorial</a>
to test it.</p>
</div>
</div>
</div>Katia ArestiThis article shows you how to secure your Infinispan cluster, protecting both cluster management and data access in various Infinispan cachesInfinispan 15.0.0.Dev062023-12-14T01:00:00+01:002023-12-14T01:00:00+01:00https://infinispan.org/blog/2023/12/14/infinispan-15.0.0.Dev06<div class="sect1">
<h2 id="redis-endpoint">Redis endpoint</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The Redis endpoint now implements most of the core Redis commands and data structures (strings, sets, lists, hashes and sorted sets), as well as implementing
clustering and CRC16 slots.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="knn-vector-search">kNN Vector search</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Infinispan can now perform indexed kNN vector searches. See our recent <a href="https://infinispan.org/blog/2023/12/13/infinispan-vector-search">blog post</a> for more information.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="infinispan-web-console">Infinispan Web Console</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The console has gained an access management section that lets you create, update, and delete roles, as well as assign access to principal mappers.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="graalvm-feature">GraalVM feature</h2>
<div class="sectionbody">
<div class="paragraph">
<p>A GraalVM native-image <a href="https://www.graalvm.org/sdk/javadoc/org/graalvm/nativeimage/hosted/Feature.html">Feature</a> is now available via the dedicated
modules <code>infinispan-hotrod-graalvm</code> and <code>infinispan-embedded-graalvm</code>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="hibernate-orm-6-3-2lc">Hibernate ORM 6.3 2LC</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Our second-level cache provider now supports Hibernate ORM 6.3.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="jcache-is-back">JCache is back!</h2>
<div class="sectionbody">
<div class="paragraph">
<p>While working on the Jakarta migration, we temporarily removed the JCache provider because of its optional dependency on CDI conflicting with the migration to Jakarta EE.
As of 15.0.0.Dev06, the JCache component is back, albeit without the CDI integration.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="when-is-the-final-release-coming">When is the Final release coming?</h2>
<div class="sectionbody">
<div class="paragraph">
<p>We hope to have the final release of Infinispan 15 ready for consumption by the end of the year and we will be making regular development releases.</p>
</div>
<div class="paragraph">
<p>Get them from our <a href="https://infinispan.org/download/">download page</a>.]</p>
</div>
</div>
</div>Tristan TarrantRedis endpointInfinispan kNN Vector Search2023-12-13T20:37:00+01:002023-12-13T20:37:00+01:00https://infinispan.org/blog/2023/12/13/infinispan-vector-search<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>With Infinispan 15.0.0.Dev06, we have started to expose vector search capabilities using Infinispan’s indexed queries.
Using the newly introduced kNN predicate, it is possible to find and order results by the k nearest neighbors of a given vector.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="mapping-the-embeddings">Mapping the embeddings</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The new <code>@Vector</code> indexing annotation is used to mark a field as an embedding. Embeddings are vector representations of data, according to a defined model.</p>
</div>
<div class="paragraph">
<p>The vector dimension is mandatory and should be defined at mapping time.
Other options that can be specified during mapping are:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>the similarity (distance) function</p>
</li>
<li>
<p>the beam width</p>
</li>
<li>
<p>the maximum number of connections.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Bear in mind that these values affect the performance of the approximation algorithm that is used to compute the kNN search.</p>
</div>
<div class="paragraph">
<p>We support <code>byte[]</code> embeddings. Here is an example of mapping:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Vector(dimension = 3)
@ProtoField(2)
public byte[] getByteVector() {
return byteVector;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>That corresponds to the Proto schema:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-proto hljs" data-lang="proto">/**
* @Vector(dimension=3)
*/
optional bytes byteVector = 2;</code></pre>
</div>
</div>
<div class="paragraph">
<p>We also support <code>float[]</code> embeddings. Here is an example of mapping:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Vector(dimension = 3)
@ProtoField(3)
public float[] getFloatVector() {
return floatVector;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>That corresponds to the Proto schema:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-proto hljs" data-lang="proto">/**
* @Vector(dimension=3)
*/
repeated float floatVector = 3;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="searching-the-embeddings">Searching the embeddings</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The following query shows how to perform a kNN search using a supplied vector and a specific distance</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-sql hljs" data-lang="sql">from Item i where i.byteVector <-> [7,7,7]~3</code></pre>
</div>
</div>
<div class="paragraph">
<p>The query can be parameterized in several ways:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">query = cache.query("from org.infinispan.query.model.Item i where i.byteVector <-> [:a,:b,:c]~3");
query.setParameter("a", 0);
query.setParameter("b", 2);
query.setParameter("c", 3);
hits = query.list();
assertThat(hits).extracting("code").containsExactly("c2", "c1", "c3"); // the order matters</code></pre>
</div>
</div>
<div class="paragraph">
<p>Or you can pass the entire vector as a single parameter:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">query = cache.query("from org.infinispan.query.model.Item i where i.floatVector <-> [:a]~:b");
query.setParameter("a", new float[]{7.1f, 7.0f, 3.1f});
query.setParameter("b", 3);
hits = query.list();
assertThat(hits).extracting("code").containsExactly("c5", "c6", "c4");</code></pre>
</div>
</div>
<div class="paragraph">
<p>If the cache is distributed, the query will be a broadcast query, and it will aggregate all the results from all the nodes that contain shards of the indexes that are related to the search.
When we get the result as usual we get all the metadata from the corresponding entities, so that the returning items can easily relate to the application domain.</p>
</div>
</div>
</div>Fabio Massimo ErcoliWith Infinispan 15.0.0.Dev06, we have started to expose vector search capabilities using Infinispan’s indexed queries. Using the newly introduced kNN predicate, it is possible to find and order results by the k nearest neighbors of a given vector.Reviving MongoDB cache store2023-05-04T02:00:00+02:002023-05-04T02:00:00+02:00https://infinispan.org/blog/2023/05/04/reviving-mongodb-cachestore<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>After a long period of inactivity, the MongoDB store is now back to life.
It has been upgraded to work with Infinispan 15.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="reactive-mongodb-driver">Reactive MongoDB driver</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Since the Infinispan cache store API is now fully reactive, the store has also been modified to use the reactive MongoDB driver.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="database-formats">Database formats</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The older MongoDB cache store worked by persisting keys and values as binary blobs.
This should be the most efficient way, but it makes it harder to inspect the documents stored in Mongo.
Therefore, the new implementation allows choosing between two formats:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>binary</code>: the binary format similar to that used with the previous MongoDB store:</p>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-json hljs" data-lang="json">[
{
"_id": {"$binary": {"base64": "mAEBigERCg9KDTAtNjc5LTc3NTQzLTk=", "subType": "00"}},
"value": {"$binary": {"base64": "mAELigFLCkmCARBib29rX3NhbXBsZS5Cb29rigEzChpUaGUgV2luZC1VcCBCaXJkIENocm9uaWNsZRjNDyISCgZIYXJ1a2kSCE11cmFrYW1p", "subType": "00"}}
...
}
]</code></pre>
</div>
</div>
</li>
<li>
<p><code>structured</code>: a structured BSON representation of the objects:</p>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-json hljs" data-lang="json">[
{
"_id": {
"_type": "string",
"_value": "0-679-77543-9"
},
"value": {
"_type": "book_sample.Book",
"title": "The Wind-Up Bird Chronicle",
"publicationYear": 1997,
"authors": [
{
"name": "Haruki",
"surname": "Murakami"
}
]
},
...
}
]</code></pre>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="expiration">Expiration</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The MongoDB store supports expiration. However, in order to ensure correctness the expired entries are removed from the database one by one, instead of using a bulk operation. Therefore, make sure this does not have a negative impact on MongoDB instances.</p>
</div>
</div>
</div>Antonio MacrìAfter a long period of inactivity, the MongoDB store is now back to life. It has been upgraded to work with Infinispan 15.Infinispan 15.0.0.Dev012023-04-24T02:00:00+02:002023-04-24T02:00:00+02:00https://infinispan.org/blog/2023/04/24/infinispan-15.0.0.Dev01<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>Infinispan 15.0.0.Dev01 marks the beginning of a new development cycle, and there are a number of
notable changes that we are making that deserve a detailed post.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="bye-bye-java-ee-hello-jakarta-ee">Bye bye, Java EE, Hello Jakarta EE</h2>
<div class="sectionbody">
<div class="paragraph">
<p>We’ve made the decision to drop Java EE support completely and focus solely on <a href="https://jakarta.ee">Jakarta EE</a>.
For 14.0 we provided artifacts for both, but we believe the time has come to move on. All of the leading
application servers (like <a href="https://wildfly.org">WildFly</a> and <a href="https://openliberty.io">OpenLiberty</a>) as well as the most
important stacks (like <a href="https://quarkus.io">Quarkus</a> and <a href="https://spring.io">Spring</a>) have adopted Jakarta EE, so we’ve decided it was time for us to make the move too.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="jcache-changes">JCache changes</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The choice to drop Java EE directly impacts our JCache provider implementation.
The JCache API (aka JSR 107) is essentially in maintenance mode: it was never adopted by Java EE and there are a number
of obstacles (mostly legal) that prevent it from moving to Jakarta EE. We understand the need to have an implementation
agnostic caching API, so we are going to continue supporting our JCache provider, but we will drop those parts which require Java EE,
most notably the <code>javax.cache.annotation</code> package. Hopefully a modern caching API will emerge as part of Jakarta EE.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="dropping-spring-5-spring-boot-2-support">Dropping Spring 5 / Spring Boot 2 support</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Dropping Java EE also means having to drop Spring 5 and Spring Boot 2 support.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="quarkus">Quarkus</h2>
<div class="sectionbody">
<div class="paragraph">
<p>We’ve merged our Quarkus components (embedded, CLI and server) into the main repository and have upgraded them to Quarkus 3.0.
Our <a href="https://quarkus.io/extensions/io.quarkus/quarkus-infinispan-client">client extension</a> continues to be part of the Quarkus ecosystem.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="security-manager">Security Manager</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The Java Security Manager has been <a href="https://openjdk.org/jeps/411">deprecated for removal</a>.
It was designed mostly for sandboxing Java applets, but it was somehow (wrongly) co-opted as a way to implement similar functionality for normal
Java applications. It was slow and cumbersome, and we’re glad to see it go. Luckily, the removal of SecurityManager support from Infinispan does
not affect its authentication and authorization capabilities.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="java-17-and-21">Java 17 and 21</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Starting with Infinispan 15, we will baseline on JDK 17 and also offer support for JDK 21, including virtual threads.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="but-what-if-i-rely-on-javaee-spring-5-spring-boot-2-and-jcache-annotations">But what if I rely on JavaEE, Spring 5, Spring Boot 2 and JCache annotations ?</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Don’t worry, we have you covered for quite some time, as we will continue to support Infinispan 14.0 for quite a while, with security patches, bug fixes and
improvements that we can backport.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="other-features-and-tentative-release-date">Other features and tentative release date</h2>
<div class="sectionbody">
<div class="paragraph">
<p>What you can expect to see in Infinispan 15:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>many improvements to our Redis-compatible <a href="https://redis.io/docs/reference/protocol-spec/">RESP</a> endpoint, including many more commands</p>
</li>
<li>
<p>a completely overhauled <a href="https://memcached.org/">Memcached</a> endpoint with support for authentication and the binary protocol</p>
</li>
<li>
<p>improved performance across the board, with particular focus on the remote endpoints and clustering</p>
</li>
<li>
<p>CDC integration, courtesy of our friends over at <a href="https://debezium.io/">Debezium</a></p>
</li>
<li>
<p>Much more!</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>We hope to have the final release of Infinispan 15 ready for consumption by the end of the year and we will be making regular development releases.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="release-notes">Release notes</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="sub-task">Sub-task</h3>
<div class="literalblock">
<div class="content">
<pre>https://issues.redhat.com/browse/ISPN-12152[ISPN-12152] - Remove the Kryo and Protostuff Marshallers
https://issues.redhat.com/browse/ISPN-13985[ISPN-13985] - Test AsyncCache new API.
https://issues.redhat.com/browse/ISPN-13994[ISPN-13994] - Pass added SerialAllowList to configuration
https://issues.redhat.com/browse/ISPN-14016[ISPN-14016] - Implement HotRodMutinyCaches methods</pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="feature-request">Feature Request</h3>
<div class="literalblock">
<div class="content">
<pre>https://issues.redhat.com/browse/ISPN-12081[ISPN-12081] - Weak counter creation
https://issues.redhat.com/browse/ISPN-13424[ISPN-13424] - Spring 6 integration
https://issues.redhat.com/browse/ISPN-13946[ISPN-13946] - Expose indexes metamodel
https://issues.redhat.com/browse/ISPN-14085[ISPN-14085] - Allow to pass new list of indexed entities in update schema API
https://issues.redhat.com/browse/ISPN-14233[ISPN-14233] - REST API makes it possible to download any server report
https://issues.redhat.com/browse/ISPN-14298[ISPN-14298] - Delete a counter
https://issues.redhat.com/browse/ISPN-14300[ISPN-14300] - Add a delta in a value
https://issues.redhat.com/browse/ISPN-14303[ISPN-14303] - Reset counter
https://issues.redhat.com/browse/ISPN-14309[ISPN-14309] - Improve Counters Table Filtering
https://issues.redhat.com/browse/ISPN-14344[ISPN-14344] - StoreMigrator support reading segmented SingleFileStores
https://issues.redhat.com/browse/ISPN-14361[ISPN-14361] - Create Hibernate 2LC implementation for Hibernate 6.2.x.
https://issues.redhat.com/browse/ISPN-14577[ISPN-14577] - Running tests with alternate JDK
https://issues.redhat.com/browse/ISPN-14731[ISPN-14731] - Hot Rod client should support alternate resolution strategies
https://issues.redhat.com/browse/ISPN-14758[ISPN-14758] - Add cli command alternative to /rest/v2/caches/{cacheName}/{cacheKey}?extended endpoint</pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="bug">Bug</h3>
<div class="literalblock">
<div class="content">
<pre>https://issues.redhat.com/browse/ISPN-12224[ISPN-12224] - Cluster in a confusing state after restarted from graceful shutdown - no hint for waiting on complete restarted
https://issues.redhat.com/browse/ISPN-13877[ISPN-13877] - NullPointerException in MetricsCollector.java
https://issues.redhat.com/browse/ISPN-14090[ISPN-14090] - Counters client 14 are incompatible with Server 13
https://issues.redhat.com/browse/ISPN-14112[ISPN-14112] - REST/CLI command will add a schema definition with 'upload' if the given file does not exists
https://issues.redhat.com/browse/ISPN-14119[ISPN-14119] - Cache details page: Queries give error in case of running after entries expiration
https://issues.redhat.com/browse/ISPN-14210[ISPN-14210] - Stores that do not return the EXPIRATION Characteristic should not allow expiration
https://issues.redhat.com/browse/ISPN-14238[ISPN-14238] - Memcached server: corrupted response
https://issues.redhat.com/browse/ISPN-14240[ISPN-14240] - Client certificate authentication doesn't work with HTTP/2
https://issues.redhat.com/browse/ISPN-14256[ISPN-14256] - CLI expands `-` filename breaking stdin batch
https://issues.redhat.com/browse/ISPN-14264[ISPN-14264] - [Console] Counters page - double click on Strong/Weak select loads all counters
https://issues.redhat.com/browse/ISPN-14271[ISPN-14271] - Cache wizard back button not working
https://issues.redhat.com/browse/ISPN-14278[ISPN-14278] - [Doc] sql-store examples should be updated
https://issues.redhat.com/browse/ISPN-14279[ISPN-14279] - "Divide by 0"-Exception on Cache.getStats()
https://issues.redhat.com/browse/ISPN-14280[ISPN-14280] - JSON parser doesn't report error locations correctly
https://issues.redhat.com/browse/ISPN-14282[ISPN-14282] - Spring Boot actuator embedded metrics use deprecated code
https://issues.redhat.com/browse/ISPN-14290[ISPN-14290] - [Docs] YAML Configuration example with typos
https://issues.redhat.com/browse/ISPN-14313[ISPN-14313] - Set different properties and port for cross-site testdriver
https://issues.redhat.com/browse/ISPN-14315[ISPN-14315] - Not possible to get server config over REST
https://issues.redhat.com/browse/ISPN-14316[ISPN-14316] - '/rest/v2/server/report' throws exception if there are 1+ instances on the host
https://issues.redhat.com/browse/ISPN-14317[ISPN-14317] - Not possible to create cluster backup over REST
https://issues.redhat.com/browse/ISPN-14319[ISPN-14319] - Use InetSocketAddress.getHostString() instead of getHostName()
https://issues.redhat.com/browse/ISPN-14323[ISPN-14323] - Get command blocks in text/plain caches
https://issues.redhat.com/browse/ISPN-14329[ISPN-14329] - Availability of caches should be prevented until a cluster is complete after "shutdown cluster"
https://issues.redhat.com/browse/ISPN-14348[ISPN-14348] - BytesObjectOutput.writeUTF performance improvements
https://issues.redhat.com/browse/ISPN-14356[ISPN-14356] - NPE if not configuring datasource connection pool maxSize
https://issues.redhat.com/browse/ISPN-14362[ISPN-14362] - Json escape should use two equality checks instead of HashMap lookup
https://issues.redhat.com/browse/ISPN-14364[ISPN-14364] - Yaml parser mishandles lists
https://issues.redhat.com/browse/ISPN-14368[ISPN-14368] - CacheInputEntryStream escapes the value for every byte in the value
https://issues.redhat.com/browse/ISPN-14376[ISPN-14376] - Web console crashes when cache name has a dot
https://issues.redhat.com/browse/ISPN-14377[ISPN-14377] - Stats command inaccurate results
https://issues.redhat.com/browse/ISPN-14390[ISPN-14390] - When reading entries from read only store apply expiration
https://issues.redhat.com/browse/ISPN-14399[ISPN-14399] - Do not allow read only and passivation to be configured together
https://issues.redhat.com/browse/ISPN-14406[ISPN-14406] - Stage returned from reindexing on explicit keys completes earlier than expected
https://issues.redhat.com/browse/ISPN-14416[ISPN-14416] - Data Distribution chart size issue
https://issues.redhat.com/browse/ISPN-14417[ISPN-14417] - The metrics for misses and retrievals are updated after page reload
https://issues.redhat.com/browse/ISPN-14421[ISPN-14421] - CVE-2022-41881 codec-haproxy: HAProxyMessageDecoder Stack Exhaustion DoS [jdg-8]
https://issues.redhat.com/browse/ISPN-14435[ISPN-14435] - Backwards compatibility broken with InvalidMagicIdException
https://issues.redhat.com/browse/ISPN-14440[ISPN-14440] - calling AsyncCache#keys or MutinyCache#keys throws an exception because the ToEmptyBytesKeyValueFilterConverter cannot be found.
https://issues.redhat.com/browse/ISPN-14453[ISPN-14453] - Ickl Queries should support BigInteger and BigDecimal
https://issues.redhat.com/browse/ISPN-14461[ISPN-14461] - Add missing licence: MPL-1.1
https://issues.redhat.com/browse/ISPN-14466[ISPN-14466] - Cache configuration update failure cause not returned in http body
https://issues.redhat.com/browse/ISPN-14468[ISPN-14468] - REST: return error if failed to create counter
https://issues.redhat.com/browse/ISPN-14470[ISPN-14470] - REST cache configuration comparison returns 204 for different caches
https://issues.redhat.com/browse/ISPN-14477[ISPN-14477] - Concurrent Spring session access results in lost session attributes
https://issues.redhat.com/browse/ISPN-14479[ISPN-14479] - SQL Cache store initiation fails on Sql type CHAR
https://issues.redhat.com/browse/ISPN-14491[ISPN-14491] - Adding entries with putAll does not add metadata version - following replaceWithVersion will end with a timout
https://issues.redhat.com/browse/ISPN-14510[ISPN-14510] - org.infinispan.server.cli.CliIT.testCliInteractive failure
https://issues.redhat.com/browse/ISPN-14511[ISPN-14511] - RestOperations.testCounter[HTTP_20] failure
https://issues.redhat.com/browse/ISPN-14512[ISPN-14512] - Fix *-jakarta modules
https://issues.redhat.com/browse/ISPN-14516[ISPN-14516] - Wrong versions in spring-boot-3-tests module
https://issues.redhat.com/browse/ISPN-14527[ISPN-14527] - Meta model may not reflect some schema changes
https://issues.redhat.com/browse/ISPN-14535[ISPN-14535] - GetCounterNameOperation can fail replay
https://issues.redhat.com/browse/ISPN-14540[ISPN-14540] - [Docs]Fix JSON example for Off-heap storage
https://issues.redhat.com/browse/ISPN-14542[ISPN-14542] - AsyncStore needs to use SecurityAction when retrieving ComponentRegistry
https://issues.redhat.com/browse/ISPN-14543[ISPN-14543] - Build resource filtering corrupts binary files
https://issues.redhat.com/browse/ISPN-14544[ISPN-14544] - RESP endpoint cache shouldn't require no expiration configured
https://issues.redhat.com/browse/ISPN-14545[ISPN-14545] - SIFS Compactor does not properly shut down but the index thinks it is okay
https://issues.redhat.com/browse/ISPN-14569[ISPN-14569] - Protocol parser throws a NPE if all branches of a switch statement or if/else contain a throw clause
https://issues.redhat.com/browse/ISPN-14573[ISPN-14573] - AbstractAuthorization.testRestServerNodeReport is failing
https://issues.redhat.com/browse/ISPN-14574[ISPN-14574] - [CLI] ClassCastException with get clusters -s option
https://issues.redhat.com/browse/ISPN-14578[ISPN-14578] - We should never be using CompletableFuture.completionStage
https://issues.redhat.com/browse/ISPN-14579[ISPN-14579] - Various RESP commands are requesting wrong size for buffer
https://issues.redhat.com/browse/ISPN-14580[ISPN-14580] - We should use voidPromise for all context writes that don't use a future
https://issues.redhat.com/browse/ISPN-14583[ISPN-14583] - RESP endpoint should bundle flush calls to allow pipelining
https://issues.redhat.com/browse/ISPN-14589[ISPN-14589] - JdbcStringBasedCacheStorePassivation.testFailoverWithPassivation failures
https://issues.redhat.com/browse/ISPN-14683[ISPN-14683] - NPE in configuration reader if resolver is null
https://issues.redhat.com/browse/ISPN-14685[ISPN-14685] - EncodingConfiguration matching is too strict
https://issues.redhat.com/browse/ISPN-14687[ISPN-14687] - Detect circular references on marshalling
https://issues.redhat.com/browse/ISPN-14691[ISPN-14691] - Fix Authorization error in Actuator Metrics Binding
https://issues.redhat.com/browse/ISPN-14730[ISPN-14730] - Exclude completely the non jakarta commons dependency
https://issues.redhat.com/browse/ISPN-14732[ISPN-14732] - ClasspathURLStreamHandlerProvider should throw FileNotFoundException if it cannot find a resource
https://issues.redhat.com/browse/ISPN-14733[ISPN-14733] - Make quarkus modules inherit from Infinispan parent
https://issues.redhat.com/browse/ISPN-14737[ISPN-14737] - SoftIndexFileStore Index can become corrupted
https://issues.redhat.com/browse/ISPN-14738[ISPN-14738] - RESP endpoint commands don't require previous value
https://issues.redhat.com/browse/ISPN-14739[ISPN-14739] - OffHeapConcurrentMap shouldn't require reading previous value on put
https://issues.redhat.com/browse/ISPN-14744[ISPN-14744] - RemoteCacheManagerAdmin docs should mention supported config formats
https://issues.redhat.com/browse/ISPN-14753[ISPN-14753] - Prevent SoftIndexFileStore Compactor from running multiple times
https://issues.redhat.com/browse/ISPN-14755[ISPN-14755] - Empty authorization roles serialized as JSON cannot be parsed
https://issues.redhat.com/browse/ISPN-14759[ISPN-14759] - SoftIndexFileStore Index can lag behind LogAppender under heavy load
https://issues.redhat.com/browse/ISPN-14763[ISPN-14763] - Users unable to configure StoreMigrator marshaller allow-list via properties
https://issues.redhat.com/browse/ISPN-14767[ISPN-14767] - CLI table printer breaks when values have line breaks</pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="task">Task</h3>
<div class="literalblock">
<div class="content">
<pre>https://issues.redhat.com/browse/ISPN-11701[ISPN-11701] - Add store migration capabilities to the CLI
https://issues.redhat.com/browse/ISPN-14263[ISPN-14263] - Restrict most JGroupsTransport INFO logging when using a ForkChannel.
https://issues.redhat.com/browse/ISPN-14287[ISPN-14287] - Remove extended-statistics module
https://issues.redhat.com/browse/ISPN-14288[ISPN-14288] - Remove kryo and protostuff marshallers
https://issues.redhat.com/browse/ISPN-14375[ISPN-14375] - Remove all uses of SecurityManager/AccessControlContext
https://issues.redhat.com/browse/ISPN-14414[ISPN-14414] - REST API retrieve caches in initializing state
https://issues.redhat.com/browse/ISPN-14424[ISPN-14424] - [Docs] Fix errors in the REST guide
https://issues.redhat.com/browse/ISPN-14426[ISPN-14426] - Disable tracing propagation on HotRod client using a system property
https://issues.redhat.com/browse/ISPN-14492[ISPN-14492] - Build Infinispan with JDK 17
https://issues.redhat.com/browse/ISPN-14541[ISPN-14541] - [Docs] Use Java serialization or JBoss Marshalling with cyclic objects
https://issues.redhat.com/browse/ISPN-14575[ISPN-14575] - Remove properties attribute from indexing configuration
https://issues.redhat.com/browse/ISPN-14591[ISPN-14591] - Add exception to the BlockHound for the registering of a proto file
https://issues.redhat.com/browse/ISPN-14705[ISPN-14705] - Expose indexing failures statistics using Infinispan indexing failure handler
https://issues.redhat.com/browse/ISPN-14713[ISPN-14713] - Include new api dependency in Spring Boot 3 modules
https://issues.redhat.com/browse/ISPN-14742[ISPN-14742] - Remove GeronimoTransactionManager
https://issues.redhat.com/browse/ISPN-14756[ISPN-14756] - Remove JCache support
https://issues.redhat.com/browse/ISPN-14769[ISPN-14769] - Replace completedExceptionFuture with failedFuture
https://issues.redhat.com/browse/ISPN-14771[ISPN-14771] - Change PrivateMetadata in OffHeap to use a flag for presence instead of 4 bytes for length
https://issues.redhat.com/browse/ISPN-14786[ISPN-14786] - Remove Wildfly modules
https://issues.redhat.com/browse/ISPN-14787[ISPN-14787] - Remove Spring5 and Spring Boot 2 support
https://issues.redhat.com/browse/ISPN-14789[ISPN-14789] - Fix port number in exam,ples of property files in SB starter docs
https://issues.redhat.com/browse/ISPN-14792[ISPN-14792] - Remove Security Integration tests with WildFly</pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="component-upgrade">Component Upgrade</h3>
<div class="literalblock">
<div class="content">
<pre>https://issues.redhat.com/browse/ISPN-14270[ISPN-14270] - Update to Spring Boot 3
https://issues.redhat.com/browse/ISPN-14320[ISPN-14320] - Update Patternfly to 2022.14 Release
https://issues.redhat.com/browse/ISPN-14342[ISPN-14342] - Apache SSHD 2.9.2
https://issues.redhat.com/browse/ISPN-14343[ISPN-14343] - Jackson 2.14.1
https://issues.redhat.com/browse/ISPN-14346[ISPN-14346] - Upgrade JGroups to 5.2.10.Final
https://issues.redhat.com/browse/ISPN-14365[ISPN-14365] - JBoss Marshalling 2.1.1
https://issues.redhat.com/browse/ISPN-14372[ISPN-14372] - Update Patternfly to 2022.15 Release
https://issues.redhat.com/browse/ISPN-14401[ISPN-14401] - Protostream 4.6.0.Final
https://issues.redhat.com/browse/ISPN-14437[ISPN-14437] - Update XStream to 1.4.20 to fix CVEs
https://issues.redhat.com/browse/ISPN-14442[ISPN-14442] - Update to 2.19.0 log4j
https://issues.redhat.com/browse/ISPN-14444[ISPN-14444] - Update Patternfly to 2022.16 Release
https://issues.redhat.com/browse/ISPN-14448[ISPN-14448] - Surefire 3.0.0-M8
https://issues.redhat.com/browse/ISPN-14462[ISPN-14462] - Upgrade assertj-core to 3.24.1
https://issues.redhat.com/browse/ISPN-14476[ISPN-14476] - Bump JGroups to 5.2.12.Final
https://issues.redhat.com/browse/ISPN-14513[ISPN-14513] - Upgrade Narayana to 5.13.1.Final
https://issues.redhat.com/browse/ISPN-14523[ISPN-14523] - Log4j 2.20.0
https://issues.redhat.com/browse/ISPN-14525[ISPN-14525] - Elytron 2.1.0.Final
https://issues.redhat.com/browse/ISPN-14550[ISPN-14550] - Upgrade Patternfly Dependencies to Release 2023.01 (2023-02-02)
https://issues.redhat.com/browse/ISPN-14553[ISPN-14553] - Spring and Spring Boot dependencies
https://issues.redhat.com/browse/ISPN-14681[ISPN-14681] - Surefire 3.0.0
https://issues.redhat.com/browse/ISPN-14694[ISPN-14694] - Upgrade Patternfly Dependencies to Release 2023.02 (2023-03-24)
https://issues.redhat.com/browse/ISPN-14711[ISPN-14711] - Updates latests SB 3 and 2
https://issues.redhat.com/browse/ISPN-14734[ISPN-14734] - Quarkus 3.0.0.CR2
https://issues.redhat.com/browse/ISPN-14745[ISPN-14745] - Narayana 6.0.0.Final
https://issues.redhat.com/browse/ISPN-14746[ISPN-14746] - Fabric8 kubernetes-client 6.5.1
https://issues.redhat.com/browse/ISPN-14747[ISPN-14747] - jboss-threads 3.5.0.Final
https://issues.redhat.com/browse/ISPN-14764[ISPN-14764] - Upgrade to plexus-utils 3.5.1</pre>
</div>
</div>
<div class="paragraph">
<p>Enhancement</p>
</div>
<div class="literalblock">
<div class="content">
<pre>https://issues.redhat.com/browse/ISPN-12106[ISPN-12106] - Add a refresh button in the cache detail
https://issues.redhat.com/browse/ISPN-12223[ISPN-12223] - Confusing behaviour in case of joining nodes if a partition is DEGRADED
https://issues.redhat.com/browse/ISPN-12484[ISPN-12484] - Explicit Locks should throw AvailabilityException during ClusterPartition instead of Timeouts
https://issues.redhat.com/browse/ISPN-14092[ISPN-14092] - Cache Configuration Wizard Direct Link
https://issues.redhat.com/browse/ISPN-14142[ISPN-14142] - Transport: add option to skip flow control
https://issues.redhat.com/browse/ISPN-14204[ISPN-14204] - Standardize NYC and LON for XSite tests
https://issues.redhat.com/browse/ISPN-14205[ISPN-14205] - InfinispanGenericContainer::getNetworkIpAddress fail fast if container is not running
https://issues.redhat.com/browse/ISPN-14213[ISPN-14213] - [Docs]: Add a statement why we provide no performance numbers
https://issues.redhat.com/browse/ISPN-14223[ISPN-14223] - Create Redis cache on first access
https://issues.redhat.com/browse/ISPN-14244[ISPN-14244] - Don't pretty print XML/JSON by default
https://issues.redhat.com/browse/ISPN-14246[ISPN-14246] - Query Statistics Tooltip
https://issues.redhat.com/browse/ISPN-14247[ISPN-14247] - Drop snakeyaml dependency
https://issues.redhat.com/browse/ISPN-14259[ISPN-14259] - Support benchmark CLI as a batch command
https://issues.redhat.com/browse/ISPN-14322[ISPN-14322] - Number of owners is 2 by default
https://issues.redhat.com/browse/ISPN-14327[ISPN-14327] - Overlays should be able to replace endpoint configuration
https://issues.redhat.com/browse/ISPN-14341[ISPN-14341] - Allow injecting a MeterRegistry instance into Infinispan
https://issues.redhat.com/browse/ISPN-14374[ISPN-14374] - Env variable for max_site_masters
https://issues.redhat.com/browse/ISPN-14394[ISPN-14394] - Cache Configuration Wizard indexing startup mode
https://issues.redhat.com/browse/ISPN-14415[ISPN-14415] - Expose REST endpoint to compare two cache configurations
https://issues.redhat.com/browse/ISPN-14423[ISPN-14423] - Improve configuration parser error reporting
https://issues.redhat.com/browse/ISPN-14451[ISPN-14451] - Set Hot Rod protocol version to AUTO via properties
https://issues.redhat.com/browse/ISPN-14456[ISPN-14456] - Validation for delta (counter)
https://issues.redhat.com/browse/ISPN-14467[ISPN-14467] - Suppressed exceptions should be sent over the wire
https://issues.redhat.com/browse/ISPN-14472[ISPN-14472] - Maven Shade 3.4.1
https://issues.redhat.com/browse/ISPN-14473[ISPN-14473] - Improve REST API error reporting
https://issues.redhat.com/browse/ISPN-14474[ISPN-14474] - Add a transcoder for 'application/x-www-form-urlencoded'
https://issues.redhat.com/browse/ISPN-14482[ISPN-14482] - Provide a single executor for all caches to execute indexing commands
https://issues.redhat.com/browse/ISPN-14490[ISPN-14490] - Add blocking scheduled tasks to BlockingManager
https://issues.redhat.com/browse/ISPN-14507[ISPN-14507] - [docs] REST updates
https://issues.redhat.com/browse/ISPN-14517[ISPN-14517] - Generate test certificates from code
https://issues.redhat.com/browse/ISPN-14528[ISPN-14528] - Configuration conversion should support templates
https://issues.redhat.com/browse/ISPN-14552[ISPN-14552] - Statistics reset REST API
https://issues.redhat.com/browse/ISPN-14570[ISPN-14570] - Protocol Parser should allow for code to be provided before the decode is invoked
https://issues.redhat.com/browse/ISPN-14585[ISPN-14585] - Convert RESP endpoint to use parser generator
https://issues.redhat.com/browse/ISPN-14680[ISPN-14680] - Reuse image in Server testsuite
https://issues.redhat.com/browse/ISPN-14689[ISPN-14689] - Handle RESP SET optional arguments
https://issues.redhat.com/browse/ISPN-14690[ISPN-14690] - Rework virtual thread detection and make it optional
https://issues.redhat.com/browse/ISPN-14720[ISPN-14720] - RESP endpoint should be able to parse commands as enum
https://issues.redhat.com/browse/ISPN-14722[ISPN-14722] - Expose auto/manual indexing mode
https://issues.redhat.com/browse/ISPN-14723[ISPN-14723] - Allow to configure index sharding
https://issues.redhat.com/browse/ISPN-14724[ISPN-14724] - Create a simple DSL to build Protocol Buffers schema
https://issues.redhat.com/browse/ISPN-14735[ISPN-14735] - Move to JakartaEE packages
https://issues.redhat.com/browse/ISPN-14761[ISPN-14761] - Add marshalling info in the entries tab for not protostream
https://issues.redhat.com/browse/ISPN-14765[ISPN-14765] - Java serialization to JSON transcoder
https://issues.redhat.com/browse/ISPN-14784[ISPN-14784] - Build with JDK 21</pre>
</div>
</div>
<div class="paragraph">
<p>Get them from our <a href="https://infinispan.org/download/">download page</a>.]</p>
</div>
</div>
</div>
</div>Tristan TarrantInfinispan 15.0.0.Dev01 marks the beginning of a new development cycle, and there are a number of notable changes that we are making that deserve a detailed post.Infinispan 14.0.7.Final2023-03-13T01:00:00+01:002023-03-13T01:00:00+01:00https://infinispan.org/blog/2023/03/13/infinispan-14.0.7.Final<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>We rarely do announcements for micro-releases, but 14.0.7.Final is a bit special, because it finally adds support for Spring 6 and Spring Boot 3.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="spring-framework-6-and-spring-boot-3">Spring Framework 6 and Spring Boot 3</h2>
<div class="sectionbody">
<div class="paragraph">
<p>We now ship components to support Spring Framework 6 and Spring Boot 3:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-spring-boot3-starter-embedded</artifactId>
<version>14.0.7.Final</version>
</dependency></code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-spring-boot3-starter-remote</artifactId>
<version>14.0.7.Final</version>
</dependency></code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="important-sifs-fixes">Important SIFS fixes</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This release also includes very important fixes to the Soft-Index File Store (SIFS), which is our default file-store implementation:
if you use it for your persistent caches you should really upgrade !</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="release-notes">Release Notes</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="feature-request">Feature Request</h3>
<div class="ulist">
<ul>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-13424">ISPN-13424 - Spring 6 integration</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14447">ISPN-14447 - Handle RBAC on counters</a></p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="bug">Bug</h3>
<div class="ulist">
<ul>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-13877">ISPN-13877 - NullPointerException in MetricsCollector.java</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14280">ISPN-14280 - JSON parser doesn't report error locations correctly</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14453">ISPN-14453 - Ickle Queries should support BigInteger and BigDecimal</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14470">ISPN-14470 - REST cache configuration comparison returns 204 for different caches</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14477">ISPN-14477 - Concurrent Spring session access results in lost session attributes</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14479">ISPN-14479 - SQL Cache store initiation fails on Sql type CHAR</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14491">ISPN-14491 - Adding entries with putAll does not add metadata version - following replaceWithVersion will end with a timeout</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14495">ISPN-14495 - RESP endpoint cannot parse request larger than packet size</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14496">ISPN-14496 - Implement CONFIG command for RESP endpoint</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14497">ISPN-14497 - RESP endpoint needs to release ByteBuf objects it creates</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14500">ISPN-14500 - REST API blocking when retrieving keys and entries</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14509">ISPN-14509 - JdbcStringBasedStore bulk operations don't work when more than 128 segments worth of values are provided</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14510">ISPN-14510 - org.infinispan.server.cli.CliIT.testCliInteractive failure</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14511">ISPN-14511 - RestOperations.testCounter HTTP_20 failure</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14512">ISPN-14512 - Fix *-jakarta modules</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14516">ISPN-14516 - Wrong versions in spring-boot-3-tests module</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14532">ISPN-14532 - Multimap failing with huge value</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14535">ISPN-14535 - GetCounterNameOperation can fail replay</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14536">ISPN-14536 - Fix HotRod client commands failing on replay</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14540">ISPN-14540 - DocsFix JSON example for Off-heap storage</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14542">ISPN-14542 - AsyncStore needs to use SecurityAction when retrieving ComponentRegistry</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14543">ISPN-14543 - Build resource filtering corrupts binary files</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14544">ISPN-14544 - RESP endpoint cache shouldn't require no expiration configured</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14545">ISPN-14545 - SIFS Compactor does not properly shut down but the index thinks it is okay</a></p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="task">Task</h3>
<div class="ulist">
<ul>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14083">ISPN-14083 - Infinispan cache configuration cheat sheet</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14492">ISPN-14492 - Build Infinispan with JDK 17</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14541">ISPN-14541 - Use Java serialization or JBoss Marshalling with cyclic objects</a></p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="component-upgrade">Component Upgrade</h3>
<div class="ulist">
<ul>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14270">ISPN-14270 - Update to Spring Boot 3</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14444">ISPN-14444 - Update Patternfly to 2022.16 Release</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14462">ISPN-14462 - Upgrade assertj-core to 3.24.1</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14476">ISPN-14476 - Bump JGroups to 5.2.12.Final</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14513">ISPN-14513 - Upgrade Narayana to 5.13.1.Final</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14520">ISPN-14520 - Upgrade Protostream to 4.6.1.Final</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14553">ISPN-14553 - Spring and Spring Boot dependencies</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14565">ISPN-14565 - Update Console to 14.0.7.Final</a></p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="enhancement">Enhancement</h3>
<div class="ulist">
<ul>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14244">ISPN-14244 - Don’t pretty print XML/JSON by default</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14423">ISPN-14423 - Improve configuration parser error reporting</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14472">ISPN-14472 - Maven Shade 3.4.1</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14473">ISPN-14473 - Improve REST API error reporting</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14507">ISPN-14507 - REST updates</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14522">ISPN-14522 - Migration of segmented cache stores</a></p>
</li>
<li>
<p><a href="https://issues.redhat.com/browse/ISPN-14528">ISPN-14528 - Configuration conversion should support templates</a></p>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="release-notes-2">Release notes</h2>
<div class="sectionbody">
<div class="paragraph">
<p>You can look at the <a href="https://issues.redhat.com/secure/ReleaseNote.jspa?projectId=12310799&version=12352858">release notes</a> to see what has changed since our latest CR.]</p>
</div>
<div class="paragraph">
<p>Get them from our <a href="https://infinispan.org/download/">download page</a>.]</p>
</div>
</div>
</div>Tristan TarrantWe rarely do announcements for micro-releases, but 14.0.7.Final is a bit special, because it finally adds support for Spring 6 and Spring Boot 3.