clientServerConfigs.README.html Maven / Gradle / Ivy
vFabric™ GemFire®
clientServerConfigs
Java Caching API Programming Example
The clientServerConfigs example uses the cacheRunner example to demonstrate the common recommended cache server and client configurations for client/server caching. The example configurations are located under the GemFire installation in examples/dist/clientServerConfigs
. For information on client/server
caching, see the GemFire User's Guide and
the online Java API documentation.
In client/server caching, it is vital that the server
and client tiers access different sets of data. If the servers and clients access the same
distributed region in the same distributed system, the client/server caching model will fail. The servers
should be in one distributed system accessing one distributed region. The
clients should either all be in a second distributed system or they should be
run as standalone applications.
Cache Configuration
The examples/dist/clientServerConfigs
directory contains the XML cache configuration files for the cache server and client. There is one server file, server.xml
, and one client file, client.xml
.
In these files:
-
The client and server create the same region,
/root/cs_region
. The client
creates the region with local scope, which ensures region isolation. The
server creates it with distributed-ack
scope and replicate
data policy so multiple server instances have identical data. The server also creates a
very simple loader on the region.
-
The server's file declares a cache server for the cache. This process listens
on port 40404 for client data requests for all server cache regions.
-
The client's file configures a pool and sets the pool name attribute on the region.
The pool is configured to access the server locator process running
on the local host on port 41111.
The client and server are now configured to talk to each other.
You may need to change the cache server communication port to avoid conflicting with processes already running on your system. If you do, just make sure to change to
the same setting for cache-server
port
in the server.xml
file.
You may also need to change the locator communication port to avoid conflicting with processes already running on your system. If you do, just make sure to change 41111 to your new port number in the following files: server/gemfire.properties
, and client.xml
.
Distributed System Configuration
The clientServerConfigs
directory also contains subdirectories with gemfire.properties
files in them. These provide the distributed system configurations for the various client/server
caching models. They specify the server and client mcast-port
settings that
define the distributed systems the VMs belong to. For the standalone client, they specify that the VM does not belong to any distributed system.
You may need to change the mcast-port
settings to
avoid conflicting with ports that are already in use on your system. If you do, make sure
the setting in client_separate_dist_sys/gemfire.properties
is still different from the setting in server/gemfire.properties
.
Do not change any of the settings in client_standalone/gemfire.properties
.
Environment Setup
You will need at least two terminal sessions: one to run a cache server VM and one to run
a client VM. These examples show one server and one client running at
a time, but you can increase the number of either. However many you run,
you need a separate terminal session for each.
- Start two terminal sessions and then cd to the GemFire product directory in both of them. For each session, set the environment according to the instructions in examples/EnvSetup.html. If you intend to run the security authentication and authorization part of this example, be sure to include the environment settings specific to that part.
- Change directory in both sessions to
examples/dist/clientServerConfigs
.
The rest of the example instructions are relative to this directory.
Starting a Locator and the Cache Server
In one session, follow these steps to start a locator, start the cache server, and add some entries to the server's cache.
- Change directory to the
server
directory.
- Start a locator with port number 41111:
gemfire start-locator -port=41111
- Run the server with the
server.xml
file:
java cacheRunner.CacheRunner ../server.xml
This starts the cacheRunner
program with the server's XML file and the current working directory's gemfire.properties
file settings. The XML file defines a region named /root/cs_region
and gives it a loader and a listener.
When the server starts you see this prompt:
/root
- Enter the commands listed here in bold (most of the output is included in this listing). You
define a value,
value1
, for the first entry, entry1
, and you cause a loader
invocation by getting an entry, entry2
, that doesn't exist in the cache.
The loader is programmed to return a value that is the string equivalent of the key. The listener reports on all entry creations, and specifies whether the value came from a load operation.
/root> chrgn cs_region
/root/cs_region> put entry1 value1
CacheListener.afterCreate EntryEvent on region /root/cs_region
[distributed, not expiration, local origin]
[not load]
Key: entry1
Old value: null
New value: value1
/root/cs_region> get entry2
CacheListener.afterCreate EntryEvent on region /root/cs_region
[distributed, not expiration, local origin]
[local load]
Key: entry2
Old value: null
New value: entry2
entry2 -> String: "entry2"
/root/cs_region> ls
Region Entries:
entry1 -> byte[]: "value1"
entry2 -> String: "entry2"
Subregions:
/root/cs_region>
Leave this running. The listener will report
when there are modifications to the server's cs_region.
Running the Client
In the other session, follow these instructions for either of the client subdirectories
to see the client/server cache working.
- Choose the client directory whose
configuration you wish to try. Change to either the
client_standalone
or the client_separate_dist_sys
directory and run the following:
java cacheRunner.CacheRunner ../client.xml true
- Once the client is started, enter the commands below.
/root> chrgn cs_region
/root/cs_region> registerInterest entry1
Interest registered in entry1
/root/cs_region> get entry1
entry1 -> byte[]: "value1"
/root/cs_region> get entry2
entry2 -> String: "entry2"
/root/cs_region> des entry2
/root/cs_region> get entry3
entry3 -> String: "entry3"
/root/cs_region> put entry1 valueFromClient
/root/cs_region>
As you run the commands, note the output in the server VM.
When you ask for an entry that exists on the server, like entry1
, it is passed directly
from the server cache. When you ask for an entry that the
server does not have, like entry3
, it invokes its loader, updates the server cache,
and returns the result. When you put
an entry on the client side, the new value is passed up to the server.
- Run
ls
on both the server and client to verify the cache contents. Both sides should report the same thing:
/root/cs_region> ls
Region Entries:
entry1 -> byte[]: "valueFromClient"
entry3 -> String: "entry3"
The server automatically sends entry update notification, with values, for the entries the client has registered interest in. For entries that are not registered, the client can get values explicitly, but receives no updates for server-side update operations.
- Update
entry1
and entry2
in the server session.
/root/cs_region> put entry1 serverValue1
...
/root/cs_region> put entry2 serverValue2
...
Final Client Cache
The client side entry1
has the new server value. This is because the client registered interest in entry1
at the beginning of this session. The other entry, entry3
, is not changed, so at this point it does not match the server cache. Since the client did not register interest in entry3
, the server does not propagate any information on the server-side modification.
To see the results, run ls
on the client side.
/root/cs_region> ls
entry1 -> byte[]: "serverValue1"
entry3 -> String: "entry3"
Stopping the Server and Client
In both sessions, enter quit
to exit the program and return to the command line. You will use both sessions for the next example showing authentication and authorization.
Running the Server and Client with Authentication/Authorization Enabled
GemFire can be configured so that a client attempting to connect to a server must first submit credentials to the server for authentication. Credentials are typically submitted as a username and a password. Client operations on the server can be authorized or denied based on the client's credentials.
Authentication and authorization in this example is configured in the gemfire.properties
files for the server and client. Descriptions of the configuration properties are listed below.
Do not enter these values. These are descriptions of security properties for the server.
# The sample implementation of LDAP server-based authentication.
security-client-authenticator=templates.security.LdapUserAuthenticator.create
# Point to a valid LDAP server.
security-ldap-server=ldap
# The baseDN details (top level directory tree) of the LDAP server mentioned above.
security-ldap-basedn=ou=ldapTesting,dc=pune,dc=gemstone,dc=com
# The sample implementation of Xml-based authorization.
security-client-accessor=templates.security.XmlAuthorization.create
# The xml configuration file for XmlAuthorization accessor mentioned above.
# Modify the usernames in the provided XML to match those recognized by the
# LDAP server mentioned above.
security-authz-xml-uri=authz-ldap.xml
Do not enter these values. These are descriptions of security properties for the client.
# The username/password-based sample implementation of AuthInitialize.
security-client-auth-init=templates.security.UserPasswordAuthInit.create
# The authentication credentials, such as a username and password.
# These should be valid combinations recognized by the LDAP server mentioned
# on the server side.
security-username=gemfire
security-password=gemfire
Running the Server with Authentication and Authorization
This uses the first session from the first example, above, and assumes you still have the locator running. See Starting a Locator and the Cache Server.
Follow these steps to configure the cache server for authentication and authorization, then start the server.
- Make a copy of the
gemfire.properties
file so the file can be restored to its original, unedited state.
- Set the following security properties in the
gemfire.properties
file.
security-ldap-server=ldap
security-ldap-basedn=ou=ldapTesting,dc=pune,dc=gemstone,dc=com
security-client-authenticator=templates.security.LdapUserAuthenticator.create
security-client-accessor=templates.security.XmlAuthorization.create
security-authz-xml-uri=authz-ldap.xml
Refer to the Sample GemFire Security Implementations section for other options for configuring and launching the server with cacheRunner
.
- Start the server with the
server.xml
file:
java cacheRunner.CacheRunner ../server.xml
This starts the cacheRunner
program with the server's XML file and the current working directory's gemfire.properties
file settings. The xml
file defines a region named /root/cs_region
and gives it a loader and a listener.
Once the server has started, this prompt appears:
/root>
- Enter the commands listed here in bold (most of the output is included in this listing).
/root> chrgn cs_region
/root/cs_region> put entry1 value1
CacheListener.afterCreate EntryEvent on region /root/cs_region
[distributed, not expiration, local origin]
[not load]
Key: entry1
Old value: null
New value: value1
/root/cs_region> ls
Region Entries:
entry1 -> byte[]: "value1"
Subregions:
/root/cs_region
Leave this running. The listener will report when there are modifications to the server's cs_region.
Running the Client with Authentication and Authorization
To see the client/server cache working with authentication and authorization, you will modify the configuration in the client_standalone
subdirectory. Make a copy of the gemfire.properties
file in that directory so the file can be restored to its original, unedited state.
With Valid Credentials:
- In the other open session, change directory to the
client_standalone
directory if it's not already in that directory.
- Set the following security properties in the client's
gemfire.properties
file (be sure to remove #
from the security-
properties):
security-client-auth-init=templates.security.UserPasswordAuthInit.create
security-username=gemfire3
security-password=gemfire3
- Run the client with the following command:
java cacheRunner.CacheRunner ../client.xml
- Once the client is started, enter the commands below.
/root> chrgn cs_region
/root/cs_region> ls
Region Entries:
Subregions:
/root/cs_region> get entry1
entry1 -> byte[]: "value1"
/root/cs_region> ls
Region Entries:
entry1 -> byte[]: "value1"
Subregions:
/root/cs_region> put key2 value2
The put
operation results in this error message:
com.gemstone.gemfire.cache.client.ServerOperationException: com.gemstone.gemfire
.security.NotAuthorizedException: Not authorized to perform PUT operation on region
[/root/cs_region]
The error message reports that the put
operation is not authorized.
Note that authorization is granted for the get
operation. Review the roles and privileges table in LDAP Authentication to see that the gemfire3
credentials authorize the client to perform reader
operations, which includes get
, but not writer
operations, which includes put
.
With Invalid Credentials:
- Enter
quit
in the client session to stop the running client.
- Change the
security-username
and security-password
properties in gemfire.properties
to start the client with invalid credentials:
security-username=invalidUsr
security-password=invalidUsr
- Start the client. An
AuthenticationFailedException
occurs:
java cacheRunner.CacheRunner ../client.xml
Exception in thread "main" com.gemstone.gemfire.security.AuthenticationFailedException:
LdapUserAuthenticator: Failure with provided username, password combination for user name: invalidUsr
With No Credentials:
- Remove the
security-client-auth-init
, security-username
and security-password
properties from gemfire.properties
to start the client without any credentials.
- Start the client. An
AuthenticationRequiredException
exception occurs.
java cacheRunner.CacheRunner ../client.xml
Exception in thread "main" com.gemstone.gemfire.security.AuthenticationRequiredException:
No security-* properties are provided
Stopping the Locator and Closing the Server and Client Sessions
- In the server session, enter
quit
to stop the running server.
- In the server session, stop the locator by entering:
gemfire stop-locator -port=41111
exit
to close the server session.
exit
to close the session.
Sample GemFire Security Implementations
There are two aspects to GemFire security:
- Authentication: Handles the authentication of nodes in a peer-to-peer network, as well as clients that connect to the servers.
- Authorization : Evaluates the permission for GemFire operations by the clients.
Authentication can be either Dummy, LDAP server-based, or PKCS-based, whereas authorization is XML-based only. For different authentication schemes, the corresponding authorization XML configuration file should be provided to the Sample Authorization module.
Dummy Authentication
This authentication scheme is based on a simple username and password. The server side authenticator is in package templates.security.DummyAuthenticator.create
. The client side initializer for it is in templates.security.UserPasswordAuthInit.create
.
Authentication User Name | Authorization Roles | Permission to the Roles | |||
---|---|---|---|---|---|
root, admin, administrator | reader, writer, cacheOps |
|
|||
reader0, reader1, reader2 | reader |
|
|||
writer0, writer1, writer2 | writer |
|
|||
reader3, reader4 | queryRegions |
|
LDAP Authentication
This scheme is based on the usernames and password configured in a LDAP server. Refer to the Security chapter in the GemFire User's Guide for more details. The server side authenticator is in package templates.security.LdapUserAuthenticator.create
The client side initializer for it is in templates.security.UserPasswordAuthInit.create
.
Authentication User Name | Authorization Roles | Permission to the Roles | |||
---|---|---|---|---|---|
gemfire1, gemfire2 | reader, writer, cacheOps |
|
|||
gemfire3, gemfire4, gemfire5 | reader |
|
|||
gemfire6, gemfire7, gemfire8 | writer |
|
|||
gemfire9, gemfire10 | queryRegions |
|
PKCS Authentication
This scheme is based on public/private key-based encryption and decryption. Refer to the Security chapter in the GemFire User's Guide for keystore configurations. The server-side authenticator is in package templates.security.PKCSAuthenticator.create
. The client-side initializer is in templates.security.PKCSAuthInit.create
.
PKCS configuration details:
- Create a keystore for aliases from gemfire1 to gemfire10, as described in the Security chapter for the GemFire User's Guide.
- Provide the following properties in
gemfire.properties
for client-side configuration.
Note: All of these properties are user-provided information to keytool-like utilities during public/private key generation and self-signing.% security-keystorepath=<absolute filepath to keystore where keys are generated>
% security-alias=<alias name given while generating Public & Private key pair for the Client>
% security-keystorepass=<password entered while generating Private key while Self-signing> - Provide the following properties in
gemfire.properties
for server side configuration.
Note: All of these properties are user-provided information to keytool-like utilities during TrustStore generation.% security-publickey-filepath=<absolute filepath to keystore where public keys are generated>
% security-publickey-pass=<password entered while generating key to TrustStore>
Authentication KeyStore Aliases | Authorization Roles | Permission to the Roles | |||
---|---|---|---|---|---|
gemfire1, gemfire2 | reader, writer, cacheOps |
|
|||
gemfire3, gemfire4, gemfire5 | reader |
|
|||
gemfire6, gemfire7, gemfire8 | writer |
|
|||
gemfire9, gemfire10 | queryRegions |
|
XML-Based Authorization
This authorization scheme is based on the prior mapping of authentication credentials to roles and privileges. Permissions in XML files are supplied corresponding to the authentication scheme. Refer to the Security chapter in the GemFire User's Guide for more information. The server-side security-accessor
is in package templates.security.XmlAuthorization.create
, and security-authz-xml-uri
should point to either authz-dummy.xml or authz-ldap.xml, depending on the security-authenticator
provided.
Additional Example Scenarios
There are a number of scenarios you can explore with this basic setup. You might add
other clients and see the effect on client peers when a client updates an entry. You could see how the behavior changes when subscriptions are disabled
(in the client's XML configuration file, change the true
value
to false
for the "subscription-enabled"
attribute).