[[server_config]]
== Configuration
Since the server is based on the WildFly codebase, refer to the WildFly documentation, apart from the JGroups, {brandname} and Endpoint subsytems.

[[server_config_jgroups]]
=== JGroups subsystem configuration
The JGroups subsystem configures the network transport and is only required when clustering multiple {brandname} Server nodes together.

The subsystem declaration is enclosed in the following XML element:

include::topics/jgroups/jgroups_subsystem.adoc[]

Within the subsystem, you need to declare the stacks that you wish to use and name them.
The default-stack attribute in the subsystem declaration must point to one of the declared stacks.
You can switch stacks from the command-line using the jboss.default.jgroups.stack property:

 bin/standalone.sh -c clustered.xml -Djboss.default.jgroups.stack=tcp

A stack declaration is composed of a transport, `UDP` or `TCP`, followed by a list of protocols. You can tune protocols by adding properties as child elements with this format:

`<property name="prop_name">prop_value</property>`

Default stacks for {brandname} are as follows:

include::topics/jgroups/jgroups_default_stack.adoc[]

[NOTE]
====
For some properties, {brandname} uses values other than the JGroups defaults to tune performance. You should examine the following files to review the JGroups configuration for {brandname}:

* Remote Client/Server Mode:
  - `jgroups-defaults.xml`
  - `infinispan-jgroups.xml`
* Library Mode:
  - `default-jgroups-tcp.xml`
  - `default-jgroups-udp.xml`

ifdef::productized[]
These JGroups files are available in the {brandname} source distribution from the Red Hat customer portal.
endif::productized[]

See link:http://www.jgroups.org/manual/html/protlist.html[JGroups Protocol] documentation for more information about available properties and default values.
====

The default TCP stack uses the MPING protocol for discovery, which uses UDP multicast.
If you need to use a different protocol, look at the
link:http://www.jgroups.org/manual/html/protlist.html#DiscoveryProtocols[JGroups Discovery Protocols] .
The following example stack configures the TCPPING discovery protocol with two initial hosts:

include::topics/jgroups/tcp_ping.adoc[]

The default configurations come with a variety of pre-configured stacks for different enviroments.
For example, the +tcpgossip+ stack uses Gossip discovery:

include::topics/jgroups/tcp_gossip.adoc[]

Use the +s3+ stack when running in Amazon AWS:

include::topics/jgroups/s3_ping.adoc[]

Similarly, when using Google's Cloud Platform, use the +google+ stack:

include::topics/jgroups/google_ping.adoc[]

Use the +dns-ping+ stack to run {brandname} on Kubernetes environments such as OKD or OpenShift:

include::topics/jgroups/dns_ping.adoc[]

The value of the `dns_query` property is the DNS query that returns the cluster members. See link:https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/[DNS for Services and Pods] for information about Kubernetes DNS naming.

==== Cluster authentication and authorization

The JGroups subsystem can be configured so that nodes need to authenticate each other when joining / merging. The authentication uses SASL and integrates with the security realms.

include::topics/jgroups/jgroups_sasl_auth.adoc[]

In the above example the nodes will use the +DIGEST-MD5+ mech to authenticate against the +ClusterRealm+. In order to join, nodes need to have the +cluster+ role. If the +cluster-role+ attribute is not specified it defaults to the name of the {brandname} +cache-container+, as described below.
Each node identifies itself using the +client_name+ property. If none is explicitly specified, the hostname on which the server is running will be used. This name can also be overridden by specifying the +jboss.node.name+ system property.
The +client_password+ property contains the password of the node. It is recommended that this password be stored in the Vault. Refer to link:https://community.jboss.org/wiki/AS7UtilisingMaskedPasswordsViaTheVault[AS7: Utilising masked passwords via the vault] for instructions on how to do so.
When using the GSSAPI mech, +client_name+ will be used as the name of a Kerberos-enabled login module defined within the security domain subsystem:

include::topics/jgroups/jgroups_kerberos_login.adoc[]

=== {brandname} subsystem configuration
The {brandname} subsystem configures the cache containers and caches.

The subsystem declaration is enclosed in the following XML element:

include::topics/configuration/ispn_subsystem.adoc[]

==== Containers
The {brandname} subsystem can declare multiple containers. A container is declared as follows:

include::topics/configuration/ispn_subsystem_containers.adoc[]

Note that in server mode is the lack of an implicit default cache, but the ability to specify a named cache as the default.

If you need to declare clustered caches (distributed, replicated, invalidation), you also need to specify the `<transport/>` element which references an existing JGroups transport. This is not needed if you only intend to have local caches only.

include::topics/configuration/ispn_jgroups_transport.adoc[]

==== Caches
Now you can declare your caches. Please be aware that only the caches declared in the configuration will be available to the endpoints and that attempting to access an undefined cache is an illegal operation. Contrast this with the default {brandname} library behaviour where obtaining an undefined cache will implicitly create one using the default settings. The following are example declarations for all four available types of caches:

include::topics/configuration/ispn_cache_declarations.adoc[]

==== Expiration
To define a default expiration for entries in a cache, add the `<expiration/>` element as follows:

include::topics/configuration/expiration.adoc[]

The possible attributes for the expiration element are:


*  _lifespan_ maximum lifespan of a cache entry, after which the entry is expired cluster-wide, in milliseconds. -1 means the entries never expire.
*  _max-idle_ maximum idle time a cache entry will be maintained in the cache, in milliseconds. If the idle time is exceeded, the entry will be expired cluster-wide. -1 means the entries never expire.
*  _interval_ interval (in milliseconds) between subsequent runs to purge expired entries from memory and any cache stores. If you wish to disable the periodic eviction process altogether, set interval to -1.

==== Eviction
To define an eviction strategy for a cache, add the `<eviction/>` element as follows:

include::topics/configuration/eviction.adoc[]

The possible attributes for the eviction element are:


*  _strategy_ sets the cache eviction strategy. Available options are 'UNORDERED', 'FIFO', 'LRU', 'LIRS' and 'NONE' (to disable eviction).
*  _max-entries_ maximum number of entries in a cache instance. If selected value is not a power of two the actual value will default to the least power of two larger than selected value. -1 means no limit.

==== Locking
To define the locking configuration for a cache, add the `<locking/>` element as follows:

include::topics/configuration/locking.adoc[]

The possible attributes for the locking element are:

*  _isolation_ sets the cache locking isolation level. Can be NONE, READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE. Defaults to REPEATABLE_READ
*  _striping_ if true, a pool of shared locks is maintained for all entries that need to be locked. Otherwise, a lock is created per entry in the cache. Lock striping helps control memory footprint but may reduce concurrency in the system.
*  _acquire-timeout_ maximum time to attempt a particular lock acquisition.
*  _concurrency-level_ concurrency level for lock containers. Adjust this value according to the number of concurrent threads interacting with {brandname}.
*  _concurrent-updates_ for non-transactional caches only: if set to true(default value) the cache keeps data consistent in the case of concurrent updates. For clustered caches this comes at the cost of an additional RPC, so if you don't expect your application to write data concurrently, disabling this flag increases performance.

==== Transactional Operations with Hot Rod

Hot Rod clients can take advantage of transactional capabilities when performing cache operations. No other protocols that {brandname} supports offer transactional capabilities.

==== Loaders and Stores
Loaders and stores can be defined in server mode in almost the same way as in embedded mode.
ifndef::productized[]
See link:../user_guide/user_guide.html#persistence[Persistence] in the User Guide.
endif::productized[]

However, in server mode it is no longer necessary to define the `<persistence>...</persistence>` tag. Instead, a store's attributes are
now defined on the store type element. For example, to configure the H2 database with a distributed cache in domain mode
we define the "default" cache as follows in our domain.xml configuration:

include::topics/configuration/ispn_datasource.adoc[]

Another important thing to note in this example, is that we use the "ExampleDS" datasource which is defined in the datasources
subsystem in our domain.xml configuration as follows:

include::topics/configuration/ispn_h2_ds.adoc[]

NOTE: For additional examples of store configurations, please view the configuration templates in the default "domain.xml" file
provided with in the server distribution at `./domain/configuration/domain.xml`.

==== State Transfer
To define the state transfer configuration for a distributed or replicated cache, add the `<state-transfer/>` element as follows:

include::topics/configuration/state_transfer.adoc[]

The possible attributes for the state-transfer element are:

*  _enabled_ if true, this will cause the cache to ask neighboring caches for state when it starts up, so the cache starts 'warm', although it will impact startup time. Defaults to true.
*  _timeout_ the maximum amount of time (ms) to wait for state from neighboring caches, before throwing an exception and aborting startup. Defaults to 240000 (4 minutes).
*  _chunk-size_ the number of cache entries to batch in each transfer. Defaults to 512.
*  _await-initial-transfer_ if true, this will cause the cache to wait for initial state transfer to complete before responding to requests. Defaults to true.

=== Endpoint subsystem configuration

The endpoint subsystem exposes a whole container (or in the case of Memcached, a single cache) over a specific connector protocol. You can define as many connector as you need, provided they bind on different interfaces/ports.

The subsystem declaration is enclosed in the following XML element:

include::topics/configuration/ispn_subsystem_endpoint.adoc[]

==== Hot Rod
The following connector declaration enables a HotRod server using the _hotrod_ socket binding (declared within a `<socket-binding-group />` element) and exposing the caches declared in the _local_ container, using defaults for all other settings.

include::topics/configuration/hotrod_connector.adoc[]

The connector will create a supporting topology cache with default settings. If you wish to tune these settings add the `<topology-state-transfer />` child element to the connector as follows:

include::topics/configuration/hotrod_topology_state_transfer.adoc[]

The Hot Rod connector can be further tuned with additional settings such as concurrency and buffering. See the protocol connector settings paragraph for additional details

Furthermore the HotRod connector can be secured using SSL. First you need to declare an SSL server identity within a security realm in the management section of the configuration file. The SSL server identity should specify the path to a keystore and its secret. Refer to the AS link:{wildflydocroot}/Security%20Realms[documentation] on this. Next add the `<security />` element to the HotRod connector as follows:

include::topics/configuration/hotrod_security.adoc[]

==== Memcached
The following connector declaration enables a Memcached server using the _memcached_ socket binding (declared within a `<socket-binding-group />` element) and exposing the _memcachedCache_ cache declared in the _local_ container, using defaults for all other settings. Because of limitations in the Memcached protocol, only one cache can be exposed by a connector. If you wish to expose more than one cache, declare additional memcached-connectors on different socket-bindings.

include::topics/configuration/memcached_connector.adoc[]

==== WebSocket

include::topics/configuration/websocket_connector.adoc[]

==== REST

include::topics/configuration/rest_connector.adoc[]

==== Common Protocol Connector Settings

The HotRod, Memcached and WebSocket protocol connectors support a number of tuning attributes in their declaration:

*  _worker-threads_ Sets the number of worker threads. Defaults to 160.
*  _idle-timeout_ Specifies the maximum time in seconds that connections from client will be kept open without activity. Defaults to -1 (connections will never timeout)
*  _tcp-nodelay_ Affects TCP NODELAY on the TCP stack. Defaults to enabled.
*  _send-buffer-size_ Sets the size of the send buffer.
*  _receive-buffer-size_ Sets the size of the receive buffer.

[[protocol_interoperability]]
==== Protocol Interoperability
Clients exchange data with {brandname} through endpoints such as REST or Hot Rod.

Each endpoint uses a different protocol so that clients can read and write data in a suitable format. Because {brandname} can interoperate with multiple clients at the same time, it must convert data between client formats and the storage formats.

ifndef::productized[]
For more information, see link:../user_guide/user_guide.html#endpoint_interop[Protocol Interoperability] in the User Guide.
endif::productized[]

ifdef::productized[]
For more information, see the _Protocol Interoperability_ topic in the User Guide.
endif::productized[]

==== Custom Marshaller Bridges
{brandname} provides two marshalling bridges for marshalling client/server requests using the Kryo and Protostuff libraries.
To utilise either of these marshallers, you simply place the dependency of the marshaller you require in your client
pom. Custom schemas for object marshalling must then be registered with the selected library using the library's api on
the client or by implementing a RegistryService for the given marshaller bridge. Examples of how to achieve this for both
libraries are presented below:

===== Protostuff

Add the protostuff marshaller dependency to your pom:

include::topics/dependencies/protostuff_marshaller.adoc[]

To register custom Protostuff schemas in your own code, you must register the custom schema with Protostuff before any
marshalling begins. This can be achieved by simply calling:

[source,java]
----
RuntimeSchema.register(ExampleObject.class, new ExampleObjectSchema());
----

Or, you can implement a service provider for the `SchemaRegistryService.java` interface, placing all Schema registrations
in the `register()` method.  Implementations of this interface are loaded via Java's ServiceLoader api, therefore the full path
of the implementing class(es) should be provided in a `META-INF/services/org/infinispan/marshaller/protostuff/SchemaRegistryService`
file within your deployment jar.

===== Kryo

Add the kryo marshaller dependency to your pom:

include::topics/dependencies/kyro_marshaller.adoc[]

To register custom Kryo serializer in your own code, you must register the custom serializer with Kryo before any
marshalling begins. This can be achieved by implementing a service provider for the `SerializerRegistryService.java` interface, placing all serializer registrations
in the `register(Kryo)` method; where serializers should be registered with the supplied `Kryo` object using the Kryo api.
e.g. `kryo.register(ExampleObject.class, new ExampleObjectSerializer())`.  Implementations of this interface are loaded
via Java's ServiceLoader api, therefore the full path of the implementing class(es) should be provided in a
`META-INF/services/org/infinispan/marshaller/kryo/SerializerRegistryService` file within your deployment jar.

===== Server Compatibility Mode
When using the Protostuff/Kryo bridges in compatibility mode, it is necessary for the class files of all custom objects to
be placed on the classpath of the server.  To achieve this, you should follow the steps outlined in the link:#protocol_interoperability[Protocol Interoperability]
section, to place a jar containing all of their custom classes on the server's classpath.

When utilising a custom marshaller in compatibility mode, it is also necessary for the marshaller and it's runtime dependencies
to be on the server's classpath.  To aid with this step we have created a "bundle" jar for each of the bridge implementations
which includes all of the runtime class files required by the bridge and underlying library. Therefore, it is only
necessary to include this single jar on the server's classpath.

Bundle jar downloads:

- link:http://central.maven.org/maven2/org/infinispan/infinispan-marshaller-kryo-bundle/{infinispanversion}/infinispan-marshaller-kryo-bundle-{infinispanversion}.jar[Kryo Bundle]
- link:http://central.maven.org/maven2/org/infinispan/infinispan-marshaller-protostuff-bundle/{infinispanversion}/infinispan-marshaller-protostuff-bundle-{infinispanversion}.jar[Protostuff Bundle]

NOTE: Jar files containing custom classes must be placed in the same module/directory as the custom marshaller bundle so
that the marshaller can load them. i.e. if you register the marshaller bundle in `modules/system/layers/base/org/infinispan/main/modules.xml`,
then you must also register your custom classes here.

====== Registering Custom Schemas/Serializers
Custom serializers/schemas for the Kryo/Protostuff marshallers must be
registered via their respective service interfaces in compatibility mode. To
achieve this, it is necessary for a *JAR* that contains the service provider to
be registered in the same directory or module as the marshaller bundle and
custom classes.

[NOTE]
====
It is not necessary for the service provider implementation to be provided in
the same *JAR* as the user's custom classes. However, the *JAR* that contains
the provider must be in the same directory/module as the marshaller and custom
class *JAR* files.
====

//-
