1.3. The AdvancedCache Interface

Red Hat JBoss Data Grid offers an AdvancedCache interface, geared towards extending JBoss Data Grid, in addition to its simple Cache Interface. The AdvancedCache Interface can:
  • Inject custom interceptors
  • Access certain internal components
  • Apply flags to alter the behavior of certain cache methods
The following code snippet presents an example of how to obtain an AdvancedCache:
AdvancedCache advancedCache = cache.getAdvancedCache();

1.3.1. Flag Usage with the AdvancedCache Interface

Flags, when applied to certain cache methods in Red Hat JBoss Data Grid, alter the behavior of the target method. Use AdvancedCache.withFlags() to apply any number of flags to a cache invocation.

Example 1.4. Applying Flags to a Cache Invocation

advancedCache.withFlags(Flag.CACHE_MODE_LOCAL, Flag.SKIP_LOCKING)
   .withFlags(Flag.FORCE_SYNCHRONOUS)
   .put("hello", "world");

1.3.2. Custom Interceptors and the AdvancedCache Interface

The AdvancedCache Interface provides a mechanism that allows advanced developers to attach custom interceptors. Custom interceptors can alter the behavior of the Cache API methods and the AdvacedCache Interface can be used to attach such interceptors programmatically at run time.

1.3.3. Custom Interceptors

Custom interceptors can be added to Red Hat JBoss Data Grid declaratively or programmatically. Custom interceptors extend JBoss Data Grid by allowing it to influence or respond to cache modifications. Examples of such cache modifications are the addition, removal or updating of elements or transactions.

1.3.3.1. Custom Interceptor Design

To design a custom interceptor in Red Hat JBoss Data Grid, adhere to the following guidelines:
  • A custom interceptor must extend the CommandInterceptor.
  • A custom interceptor must declare a public, empty constructor to allow for instantiation.
  • A custom interceptor must have JavaBean style setters defined for any property that is defined through the property element.

1.3.3.2. Adding Custom Interceptors Declaratively

Each named cache in Red Hat JBoss Data Grid has its own interceptor stack. As a result, custom interceptors can be added on a per named cache basis.
A custom interceptor can be added using XML. Use the following procedure to add custom interceptors.

Procedure 1.1. Adding Custom Interceptors

  1. Define Custom Interceptors

    All custom interceptors must extend org.jboss.cache.interceptors.base.CommandInterceptor. Use the customInterceptors method to add custom interceptors to the cache:
    <namedCache name="cacheWithCustomInterceptors">
       <customInterceptors>
  2. Define the Position of the New Custom Interceptor

    Interceptors must have a defined position. Valid options are:
    • FIRST - Specifies that the new interceptor is placed first in the chain.
    • LAST - Specifies that the new interceptor is placed last in the chain.
    • OTHER_THAN_FIRST_OR_LAST - Specifies that the new interceptor can be placed anywhere except first or last in the chain.
    <namedCache name="cacheWithCustomInterceptors">
       <customInterceptors>
          <interceptor position="FIRST" class="com.mycompany.CustomInterceptor1">
    • Define Interceptor Properties

      Define specific interceptor properties.
      <namedCache name="cacheWithCustomInterceptors">
         <customInterceptors>
            <interceptor position="FIRST" class="com.mycompany.CustomInterceptor1">
               <properties>
                  <property name="attributeOne" value="value1" />
                  <property name="attributeTwo" value="value2" />
               </properties>
            </interceptor>
  3. Apply Other Custom Interceptors

    In this example, the next custom interceptor is called CustomInterceptor2.
    <namedCache name="cacheWithCustomInterceptors">
       <customInterceptors>
          <interceptor position="FIRST" class="com.mycompany.CustomInterceptor1">
             <properties>
                <property name="attributeOne" value="value1" />
                <property name="attributeTwo" value="value2" />
             </properties>
          </interceptor>
          <interceptor position="LAST" class="com.mycompany.CustomInterceptor2"/>
  4. Define the index, before, and after Attributes.

    • The index identifies the position of this interceptor in the chain, with 0 being the first position. This attribute is mutually exclusive with position, before, and after.
    • The after method places the new interceptor directly after the instance of the named interceptor specified via its fully qualified class name. This attribute is mutually exclusive with position, before, and index.
    • The before method places the new interceptor directly before the instance of the named interceptor specified via its fully qualified class name. This attribute is mutually exclusive with position, after, and index.
    <namedCache name="cacheWithCustomInterceptors">
       <customInterceptors>
          <interceptor position="FIRST" class="com.mycompany.CustomInterceptor1">
             <properties>
                <property name="attributeOne" value="value1" />
                <property name="attributeTwo" value="value2" />
             </properties>
          </interceptor>
          <interceptor position="LAST" class="com.mycompany.CustomInterceptor2"/>
          <interceptor index="3" class="com.mycompany.CustomInterceptor1"/>
          <interceptor before="org.infinispan.interceptors.CallInterceptor" class="com.mycompany.CustomInterceptor2"/>
          <interceptor after="org.infinispan.interceptors.CallInterceptor" class="com.mycompany.CustomInterceptor1"/>
       </customInterceptors>
    </namedCache>
    

Note

This configuration is only valid for JBoss Data Grid's Library Mode.

1.3.3.3. Adding Custom Interceptors Programmatically

To add a custom interceptor programmatically in Red Hat JBoss Data Grid, first obtain a reference to the AdvancedCache.

Example 1.5. Obtain a Reference to the AdvancedCache

CacheManager cm = getCacheManager();
Cache aCache = cm.getCache("aName");
AdvancedCache advCache = aCache.getAdvancedCache();
Then use an addInterceptor() method to add the interceptor.

Example 1.6. Add the Interceptor

advCache.addInterceptor(new MyInterceptor(), 0);

1.3.4. Other Management Tools and Operations

Managing Red Hat JBoss Data Grid instances requires exposing significant amounts of relevant statistical information. This information allows administrators to get a clear view of each JBoss Data Grid node's state. A single installation can comprise of tens or hundreds of JBoss Data Grid nodes and it is important to provide this information in a clear and concise manner. JBoss Operations Network is one example of a tool that provides runtime visibility. Other tools, such as JConsole can be used where JMX is enabled.

1.3.4.1. Accessing Data via URLs

Caches that have been configured with a REST interface have access to Red Hat JBoss Data Grid using RESTful HTTP access.
The RESTful service only requires a HTTP client library, eliminating the need for tightly coupled client libraries and bindings.
HTTP put() and post() methods place data in the cache, and the URL used determines the cache name and key(s) used. The data is the value placed into the cache, and is placed in the body of the request.
A Content-Type header must be set for these methods. GET and HEAD methods are used for data retrieval while other headers control cache settings and behavior.

Note

It is not possible to have conflicting server modules interact with the data grid. Caches must be configured with a compatible interface in order to have access to JBoss Data Grid.

1.3.4.2. Limitations of Map Methods

Specific Map methods, such as size(), values(), keySet() and entrySet(), can be used with certain limitations with Red Hat JBoss Data Grid as they are unreliable. These methods do not acquire locks (global or local) and concurrent modification, additions and removals are excluded from consideration in these calls. Furthermore, the listed methods are only operational on the local cache and do not provide a global view of state.
If the listed methods acted globally, it would result in a significant impact on performance and would produce a scalability bottleneck. As a result, it is recommended that these methods are used for informational and debugging purposes only.
Performance Concerns

From Red Hat JBoss Data Grid 6.3 onwards, the map methods size(), values(), keySet(), and entrySet() include entries in the cache loader by default whereas previously these methods only included the local data container. The underlying cache loader directly affects the performance of these commands. As an example, when using a database, these methods run a complete scan of the table where data is stored which can result in slower processing. Use Cache.getAdvancedCache().withFlags(Flag.SKIP_CACHE_LOAD).values() to maintain the old behavior and not loading from the cache loader which would avoid the slower performance.