blob: 058163418c58679db8c1fa6226b82904ceb2e37a [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional information regarding
* copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License. You may obtain a
* copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package org.apache.geode.cache.client;
import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
import java.util.Properties;
import org.apache.geode.cache.CacheClosedException;
import org.apache.geode.cache.CacheWriterException;
import org.apache.geode.cache.CacheXmlException;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.RegionExistsException;
import org.apache.geode.cache.TimeoutException;
import org.apache.geode.cache.client.internal.InternalClientCache;
import org.apache.geode.cache.server.CacheServer;
import org.apache.geode.distributed.DistributedSystem;
import org.apache.geode.distributed.internal.InternalDistributedSystem;
import org.apache.geode.internal.GemFireVersion;
import org.apache.geode.internal.cache.CacheConfig;
import org.apache.geode.internal.cache.GemFireCacheImpl;
import org.apache.geode.internal.cache.InternalCacheBuilder;
import org.apache.geode.pdx.PdxInstance;
import org.apache.geode.pdx.PdxSerializer;
import org.apache.geode.security.AuthenticationFailedException;
import org.apache.geode.security.AuthenticationRequiredException;
/**
* Factory class used to create the singleton {@link ClientCache client cache} and connect to one or
* more GemFire Cache Servers. If the application wants to connect to GemFire as a peer it should
* use {@link org.apache.geode.cache.CacheFactory} instead.
* <p>
* Once the factory has been configured using its set* methods you produce a {@link ClientCache} by
* calling the {@link #create} method. The
* {@link org.apache.geode.distributed.ConfigurationProperties#CACHE_XML_FILE} property can be used
* to specify a cache.xml file to initialize the cache with. The contents of this file must comply
* with the <code>"doc-files/cache8_0.dtd"</code> file and the top level element must be a
* <code>client-cache</code> element.
* <p>
* Client connections are managed through connection {@link Pool pools}. ClientCacheFactory creates
* a single pool to use by default on the cache it creates. ClientCacheFactory can also be used to
* configure the default connection pool using its <code>setPool*</code> and <code>addPool*</code>
* methods. In most cases, the defaults used by this implementation will suffice. For the default
* pool attributes see {@link PoolFactory}. If no pool is configured and a pool was not declared in
* cache.xml or created using {@link PoolManager} then a default one will be created that connects
* to a server on the default cache server port and local host. If multiple pools are declared in
* cache.xml or created by the PoolFactory then no default pool will exist and
* <code>ClientRegionFactory.setPoolName</code> will need to be called on each region created.
* <p>
* To get the existing unclosed singleton client cache instance call {@link #getAnyInstance}.
* <p>
* The following examples illustrate bootstrapping the client cache using region shortcuts:
* <p>
* Example 1: Connect to a CacheServer on the default host and port and access a region "customers"
*
* <PRE>
* ClientCache c = new ClientCacheFactory().create();
* Region r = c.createClientRegionFactory(PROXY).create("customers");
* // The PROXY shortcut tells GemFire to route all requests to the servers
* // . i.e. there is no local caching
* </PRE>
*
* Example 2: Connect using the GemFire locator and create a local LRU cache
*
* <PRE>
* ClientCache c = new ClientCacheFactory().addPoolLocator(host, port).create();
* Region r = c.createClientRegionFactory(CACHING_PROXY_HEAP_LRU).create("customers");
* // The local LRU "customers" data region will automatically start evicting, by default, at 80%
* // heap utilization threshold
* </PRE>
*
* Example 3: Access the query service
*
* <PRE>
* QueryService qs = new ClientCacheFactory().create().getQueryService();
* </PRE>
*
* Example 4: Construct the client cache region declaratively in cache.xml
*
* <PRE>
* &lt;!DOCTYPE client-cache PUBLIC
* "-//GemStone Systems, Inc.//GemFire Declarative Caching 6.5//EN"
* "http://www.gemstone.com/dtd/cache8_0.dtd">
* &lt;client-cache>
* &lt;pool name="myPool">
* &lt;locator host="hostName" port="10334"/>
* &lt;/pool>
* &lt;region name="myRegion" refid="PROXY"/>
* &lt;!-- you can override or add to the PROXY attributes by adding
* a region-attributes sub element here -->
* &lt;/client-cache>
* </PRE>
*
* Now, create the cache telling it to read your cache.xml file:
*
* <PRE>
* ClientCache c = new ClientCacheFactory().set("cache-xml-file", "myCache.xml").create();
* Region r = c.getRegion("myRegion");
* </PRE>
* <p>
* <p>
* For a complete list of all client region shortcuts see {@link ClientRegionShortcut}. Applications
* that need to explicitly control the individual region attributes can do this declaratively in XML
* or using API.
* <p>
* Example 5: Define custom region attributes for persistence in XML and create region using API.
* Define new region attributes with ID "MYAPP_CACHING_PROXY_MEM_LRU" that overrides the
* "CACHING_PROXY" shortcut
*
* <PRE>
* &lt;!DOCTYPE client-cache PUBLIC
* "-//GemStone Systems, Inc.//GemFire Declarative Caching 8.0//EN"
* "http://www.gemstone.com/dtd/cache8_0.dtd">
* &lt;client-cache>
* &lt;!-- now create a named region attributes that uses the CACHING_PROXY shortcut
* and adds a memory LRU limited to 900 megabytes -->
* &lt;region-attributes id="MYAPP_CACHING_PROXY_MEM_LRU" refid="CACHING_PROXY" >
* &lt;lru-memory-size maximum="900"/>
* &lt;/region-attributes>
* &lt;/client-cache>
* </PRE>
*
* Now, create the data region in the client cache using this new attributes ID.
*
* <PRE>
* ClientCache c = new ClientCacheFactory().set("cache-xml-file", "myCache.xml")
* .addPoolLocator(host, port).create();
* Region r = c.createClientRegionFactory("MYAPP_CACHING_PROXY_MEM_LRU").create("customers");
* </PRE>
*
* @since 6.5
*/
public class ClientCacheFactory {
private PoolFactory pf;
private final Properties dsProps;
private final CacheConfig cacheConfig = new CacheConfig();
/**
* Creates a new client cache factory.
*/
public ClientCacheFactory() {
dsProps = new Properties();
}
/**
* Create a new client cache factory given the initial gemfire properties.
*
* @param props The initial gemfire properties to be used. These properties can be overridden
* using the {@link #set} method For a full list of valid gemfire properties see
* {@link org.apache.geode.distributed.ConfigurationProperties}.
*/
public ClientCacheFactory(Properties props) {
if (props == null) {
props = new Properties();
}
dsProps = props;
}
/**
* Sets a gemfire property that will be used when creating the ClientCache. For a full list of
* valid gemfire properties see {@link org.apache.geode.distributed.ConfigurationProperties}.
*
* @param name the name of the gemfire property
* @param value the value of the gemfire property
* @return a reference to this ClientCacheFactory object
*/
public ClientCacheFactory set(String name, String value) {
dsProps.setProperty(name, value);
return this;
}
/**
* Create a singleton client cache. If a client cache already exists in this vm that is not
* compatible with this factory's configuration then create will fail.
* <p>
* While creating the cache instance any declarative cache configuration (cache.xml) is processed
* and used to initialize the created cache.
* <P>
* Note that the cache that is produced is a singleton. Before a different instance can be
* produced the old one must be {@link ClientCache#close closed}.
*
* @return the singleton client cache
* @throws CacheXmlException If a problem occurs while parsing the declarative caching XML file.
* @throws TimeoutException If a {@link Region#put(Object, Object)} times out while initializing
* the cache.
* @throws CacheWriterException If a <code>CacheWriterException</code> is thrown while
* initializing the cache.
* @throws RegionExistsException If the declarative caching XML file describes a region that
* already exists (including the root region).
* @throws IllegalStateException if a client cache already exists and it is not compatible with
* this factory's configuration.
* @throws IllegalStateException if mcast-port or locator is set on client cache.
* @throws AuthenticationFailedException if authentication fails.
* @throws AuthenticationRequiredException if server is in secure mode and client cache is not
* configured with security credentials.
*/
public ClientCache create() {
return basicCreate();
}
@SuppressWarnings("deprecation")
private static InternalClientCache getInternalClientCache() {
return GemFireCacheImpl.getInstance();
}
private ClientCache basicCreate() {
synchronized (ClientCacheFactory.class) {
InternalClientCache instance = getInternalClientCache();
{
String propValue = dsProps.getProperty(MCAST_PORT);
if (propValue != null) {
int mcastPort = Integer.parseInt(propValue);
if (mcastPort != 0) {
throw new IllegalStateException(
"On a client cache the mcast-port must be set to 0 or not set. It was set to "
+ mcastPort);
}
}
}
{
String propValue = dsProps.getProperty(LOCATORS);
if (propValue != null && !propValue.isEmpty()) {
throw new IllegalStateException(
"On a client cache the locators property must be set to an empty string or not set. It was set to \""
+ propValue + "\".");
}
}
dsProps.setProperty(MCAST_PORT, "0");
dsProps.setProperty(LOCATORS, "");
InternalDistributedSystem system = connectInternalDistributedSystem();
if (instance != null && !instance.isClosed()) {
// this is ok; just make sure it is a client cache
if (!instance.isClient()) {
throw new IllegalStateException(
"A client cache can not be created because a non-client cache already exists.");
}
// check if pool is compatible
instance.validatePoolFactory(pf);
// Check if cache configuration matches.
cacheConfig.validateCacheConfig(instance);
return instance;
} else {
return (InternalClientCache) new InternalCacheBuilder(cacheConfig)
.setIsClient(true)
.setPoolFactory(pf)
.create(system);
}
}
}
@SuppressWarnings("deprecation")
private InternalDistributedSystem connectInternalDistributedSystem() {
return (InternalDistributedSystem) DistributedSystem.connect(dsProps);
}
private PoolFactory getPoolFactory() {
if (pf == null) {
pf = PoolManager.createFactory();
}
return pf;
}
/**
* Sets the socket connect timeout for this pool. The number of milli seconds specified as socket
* timeout when the client connects to the servers/locators. A timeout of zero is interpreted as
* an infinite timeout. The connection will then block until established or an error occurs.
*
* @param socketConnectTimeout timeout in milliseconds when the client connects to the servers
* @return a reference to <code>this</code>
* @throws IllegalArgumentException if <code>socketConnectTimeout</code> is less than or equal to
* <code>-1</code>.
*/
public ClientCacheFactory setPoolSocketConnectTimeout(int socketConnectTimeout) {
getPoolFactory().setSocketConnectTimeout(socketConnectTimeout);
return this;
}
/**
* Sets the free connection timeout for this pool. If the pool has a max connections setting,
* operations will block if all of the connections are in use. The free connection timeout
* specifies how long those operations will block waiting for a free connection before receiving
* an {@link AllConnectionsInUseException}. If max connections is not set this setting has no
* effect.
*
* @param connectionTimeout the connection timeout in milliseconds
* @return a reference to <code>this</code>
* @throws IllegalArgumentException if <code>connectionTimeout</code> is less than or equal to
* <code>0</code>.
* @see #setPoolMaxConnections(int)
*/
public ClientCacheFactory setPoolFreeConnectionTimeout(int connectionTimeout) {
getPoolFactory().setFreeConnectionTimeout(connectionTimeout);
return this;
}
/**
* Sets the load conditioning interval for this pool. This interval controls how frequently the
* pool will check to see if a connection to a given server should be moved to a different server
* to improve the load balance.
* <p>
* A value of <code>-1</code> disables load conditioning
*
* @param loadConditioningInterval the connection lifetime in milliseconds
* @return a reference to <code>this</code>
* @throws IllegalArgumentException if <code>connectionLifetime</code> is less than
* <code>-1</code>.
*/
public ClientCacheFactory setPoolLoadConditioningInterval(int loadConditioningInterval) {
getPoolFactory().setLoadConditioningInterval(loadConditioningInterval);
return this;
}
/**
* Sets the socket buffer size for each connection made in this pool. Large messages can be
* received and sent faster when this buffer is larger. Larger buffers also optimize the rate at
* which servers can send events for client subscriptions.
*
* @param bufferSize the size of the socket buffers used for reading and writing on each
* connection in this pool.
* @return a reference to <code>this</code>
* @throws IllegalArgumentException if <code>bufferSize</code> is less than or equal to
* <code>0</code>.
*/
public ClientCacheFactory setPoolSocketBufferSize(int bufferSize) {
getPoolFactory().setSocketBufferSize(bufferSize);
return this;
}
/**
* Sets the thread local connections policy for this pool. If <code>true</code> then any time a
* thread goes to use a connection from this pool it will check a thread local cache and see if it
* already has a connection in it. If so it will use it. If not it will get one from this pool and
* cache it in the thread local. This gets rid of thread contention for the connections but
* increases the number of connections the servers see.
* <p>
* If <code>false</code> then connections are returned to the pool as soon as the operation being
* done with the connection completes. This allows connections to be shared amonst multiple
* threads keeping the number of connections down.
*
* @param threadLocalConnections if <code>true</code> then enable thread local connections.
* @return a reference to <code>this</code>
* @deprecated Since Geode 1.10.0. Thread local connections are ignored. Will be removed in future
* major release.
*/
@Deprecated
public ClientCacheFactory setPoolThreadLocalConnections(boolean threadLocalConnections) {
getPoolFactory().setThreadLocalConnections(threadLocalConnections);
return this;
}
/**
* Sets the number of milliseconds to wait for a response from a server before timing out the
* operation and trying another server (if any are available).
*
* @param timeout number of milliseconds to wait for a response from a server
* @return a reference to <code>this</code>
* @throws IllegalArgumentException if <code>timeout</code> is less than <code>0</code>.
*/
public ClientCacheFactory setPoolReadTimeout(int timeout) {
getPoolFactory().setReadTimeout(timeout);
return this;
}
/**
* Set the minimum number of connections to keep available at all times. When the pool is created,
* it will create this many connections. If <code>0</code> then connections will not be made until
* an actual operation is done that requires client-to-server communication.
*
* @param minConnections the initial number of connections this pool will create.
* @return a reference to <code>this</code>
* @throws IllegalArgumentException if <code>minConnections</code> is less than <code>0</code>.
*/
public ClientCacheFactory setPoolMinConnections(int minConnections) {
getPoolFactory().setMinConnections(minConnections);
return this;
}
/**
* Set the max number of client to server connections that the pool will create. If all of the
* connections are in use, an operation requiring a client to server connection will block until a
* connection is available.
*
* @param maxConnections the maximum number of connections in the pool. this pool will create. -1
* indicates that there is no maximum number of connections
* @return a reference to <code>this</code>
* @throws IllegalArgumentException if <code>maxConnections</code> is less than
* <code>minConnections</code>.
* @see #setPoolFreeConnectionTimeout(int)
*/
public ClientCacheFactory setPoolMaxConnections(int maxConnections) {
getPoolFactory().setMaxConnections(maxConnections);
return this;
}
/**
* Set the amount of time a connection can be idle before expiring the connection. If the pool
* size is greater than the minimum specified by {@link #setPoolMinConnections(int)}, connections
* which have been idle for longer than the idleTimeout will be closed.
*
* @param idleTimeout The amount of time in milliseconds that an idle connection should live
* before expiring. -1 indicates that connections should never expire.
* @return a reference to <code>this</code>
* @throws IllegalArgumentException if <code>idleTimout</code> is less than <code>-1</code>.
*/
public ClientCacheFactory setPoolIdleTimeout(long idleTimeout) {
getPoolFactory().setIdleTimeout(idleTimeout);
return this;
}
/**
* Set the number of times to retry a request after timeout/exception.
*
* @param retryAttempts The number of times to retry a request after timeout/exception. -1
* indicates that a request should be tried against every available server before failing
* @return a reference to <code>this</code>
* @throws IllegalArgumentException if <code>idleTimout</code> is less than <code>-1</code>.
*/
public ClientCacheFactory setPoolRetryAttempts(int retryAttempts) {
getPoolFactory().setRetryAttempts(retryAttempts);
return this;
}
/**
* How often to ping servers to verify that they are still alive. Each server will be sent a ping
* every pingInterval if there has not been any other communication with the server.
* <p>
* These pings are used by the server to monitor the health of the client. Make sure that the
* pingInterval is less than the maximum time between pings allowed by the cache server.
*
* @param pingInterval The amount of time in milliseconds between pings.
* @return a reference to <code>this</code>
* @throws IllegalArgumentException if <code>pingInterval</code> is less than or equal to
* <code>0</code>.
* @see CacheServer#setMaximumTimeBetweenPings(int)
*/
public ClientCacheFactory setPoolPingInterval(long pingInterval) {
getPoolFactory().setPingInterval(pingInterval);
return this;
}
/**
* How often to send client statistics to the server. Doing this allows <code>gfmon</code> to
* monitor clients.
* <p>
* A value of <code>-1</code> disables the sending of client statistics to the server.
*
* @param statisticInterval The amount of time in milliseconds between sends of client statistics
* to the server.
* @return a reference to <code>this</code>
* @throws IllegalArgumentException if <code>statisticInterval</code> is less than
* <code>-1</code>.
*/
public ClientCacheFactory setPoolStatisticInterval(int statisticInterval) {
getPoolFactory().setStatisticInterval(statisticInterval);
return this;
}
/**
* Configures the group that all servers this pool connects to must belong to.
*
* @param group the server group that this pool will connect to. If <code>null</code> or
* <code>""</code> then all servers will be connected to.
* @return a reference to <code>this</code>
*/
public ClientCacheFactory setPoolServerGroup(String group) {
getPoolFactory().setServerGroup(group);
return this;
}
/**
* Add a locator, given its host and port, to this factory. The locator must be a server locator
* and will be used to discover other running cache servers and locators. Note that if the host is
* unknown at the time of this call the locator will still be added. When the pool is used for an
* operation if the host is still unknown an exception will be thrown.
*
* @param host the host name or ip address that the locator is listening on.
* @param port the port that the locator is listening on
* @return a reference to <code>this</code>
* @throws IllegalArgumentException if port is outside the valid range of [0..65535] inclusive.
* @throws IllegalStateException if a server has already been {@link #addPoolServer added} to this
* factory.
*/
public ClientCacheFactory addPoolLocator(String host, int port) {
getPoolFactory().addLocator(host, port);
return this;
}
/**
* Add a server, given its host and port, to this factory. The server must be a cache server and
* this client will directly connect to without consulting a server locator. Note that if the host
* is unknown at the time of this call the server will still be added. When the pool is used for
* an operation if the host is still unknown an exception will be thrown.
*
* @param host the host name or ip address that the server is listening on.
* @param port the port that the server is listening on
* @return a reference to <code>this</code>
* @throws IllegalArgumentException if port is outside the valid range of [0..65535] inclusive.
* @throws IllegalStateException if a locator has already been {@link #addPoolLocator added} to
* this factory.
*/
public ClientCacheFactory addPoolServer(String host, int port) {
getPoolFactory().addServer(host, port);
return this;
}
/**
* If set to <code>true</code> then the created pool will have server-to-client subscriptions
* enabled. If set to <code>false</code> then all <code>Subscription*</code> attributes are
* ignored at create time.
*
* @return a reference to <code>this</code>
*/
public ClientCacheFactory setPoolSubscriptionEnabled(boolean enabled) {
getPoolFactory().setSubscriptionEnabled(enabled);
return this;
}
/**
* Sets the redundancy level for this pools server-to-client subscriptions. If <code>0</code> then
* no redundant copies will be kept on the servers. Otherwise an effort will be made to maintain
* the requested number of copies of the server-to-client subscriptions. At most one copy per
* server will be made up to the requested level.
*
* @param redundancy the number of redundant servers for this client's subscriptions.
* @return a reference to <code>this</code>
* @throws IllegalArgumentException if <code>redundancyLevel</code> is less than <code>-1</code>.
*/
public ClientCacheFactory setPoolSubscriptionRedundancy(int redundancy) {
getPoolFactory().setSubscriptionRedundancy(redundancy);
return this;
}
/**
* A server has an inactivity monitor that ensures a message is sent to a client at least once a
* minute (60,000 milliseconds). If a subscription timeout multipler is set in the client it
* enables timing out of the subscription feed with failover to another server.
* <p>
* The client will time out it's subscription connection after a number of seconds equal to this
* multiplier times the server's subscription-timeout.
* <p>
* Set this to 2 or more to make sure the client will receive pings from the server before the
* timeout.
* <p>
* A value of zero (the default) disables timeouts
* <p>
* The resulting timeout will be multiplied by 1.25 in order to avoid race conditions with the
* server sending its "ping" message.
*/
public ClientCacheFactory setPoolSubscriptionTimeoutMultiplier(int multiplier) {
getPoolFactory().setSubscriptionTimeoutMultiplier(multiplier);
return this;
}
/**
* Sets the messageTrackingTimeout attribute which is the time-to-live period, in milliseconds,
* for subscription events the client has received from the server. It's used to minimize
* duplicate events. Entries that have not been modified for this amount of time are expired from
* the list
*
* @param messageTrackingTimeout number of milliseconds to set the timeout to.
* @return a reference to <code>this</code>
* @throws IllegalArgumentException if <code>messageTrackingTimeout</code> is less than or equal
* to <code>0</code>.
*/
public ClientCacheFactory setPoolSubscriptionMessageTrackingTimeout(int messageTrackingTimeout) {
getPoolFactory().setSubscriptionMessageTrackingTimeout(messageTrackingTimeout);
return this;
}
/**
* Sets the interval in milliseconds to wait before sending acknowledgements to the cache server
* for events received from the server subscriptions.
*
* @param ackInterval number of milliseconds to wait before sending event acknowledgements.
* @return a reference to <code>this</code>
* @throws IllegalArgumentException if <code>ackInterval</code> is less than or equal to
* <code>0</code>.
*/
public ClientCacheFactory setPoolSubscriptionAckInterval(int ackInterval) {
getPoolFactory().setSubscriptionAckInterval(ackInterval);
return this;
}
/**
* By default setPRSingleHopEnabled is <code>true</code> in which case the client is aware of the
* location of partitions on servers hosting {@link Region regions} with
* {@link org.apache.geode.cache.DataPolicy#PARTITION}. Using this information, the client routes
* the client cache operations directly to the server which is hosting the required partition for
* the cache operation using a single network hop. This mode works best when
* {@link #setPoolMaxConnections(int)} is set to <code>-1</code> which is the default. This mode
* causes the client to have more connections to the servers.
* <p>
* If setPRSingleHopEnabled is <code>false</code> the client may need to do an extra network hop
* on servers to go to the required partition for that cache operation. The client will use fewer
* network connections to the servers.
* <p>
* Caution: for {@link org.apache.geode.cache.DataPolicy#PARTITION partition} regions with
* {@link org.apache.geode.cache.PartitionAttributesFactory#setLocalMaxMemory(int)
* local-max-memory} equal to zero, no cache operations mentioned above will be routed to those
* servers as they do not host any partitions.
*
* @return the newly created pool.
*/
public ClientCacheFactory setPoolPRSingleHopEnabled(boolean enabled) {
getPoolFactory().setPRSingleHopEnabled(enabled);
return this;
}
/**
* If set to <code>true</code> then the created pool can be used by multiple users. <br>
* <br>
* Note: If set to true, all the client side regions must be {@link ClientRegionShortcut#PROXY
* proxies}. No client side storage is allowed.
*
* @return a reference to <code>this</code>
*/
public ClientCacheFactory setPoolMultiuserAuthentication(boolean enabled) {
getPoolFactory().setMultiuserAuthentication(enabled);
return this;
}
/**
* Returns the version of the cache implementation.
*
* @return the version of the cache implementation as a <code>String</code>
*/
public static String getVersion() {
return GemFireVersion.getGemFireVersion();
}
/**
* Gets an arbitrary open instance of {@link ClientCache} produced by an earlier call to
* {@link #create}.
*
* @throws CacheClosedException if a cache has not been created or the only created one is
* {@link ClientCache#isClosed closed}
* @throws IllegalStateException if the cache was created by CacheFactory instead of
* ClientCacheFactory
*/
public static synchronized ClientCache getAnyInstance() {
InternalClientCache instance = getInternalClientCache();
if (instance == null) {
throw new CacheClosedException(
"A cache has not yet been created.");
} else {
if (!instance.isClient()) {
throw new IllegalStateException(
"The singleton cache was created by CacheFactory not ClientCacheFactory.");
}
instance.getCancelCriterion().checkCancelInProgress(null);
return instance;
}
}
/**
* Sets the object preference to PdxInstance type. When a cached object that was serialized as a
* PDX is read from the cache a {@link PdxInstance} will be returned instead of the actual domain
* class. The PdxInstance is an interface that provides run time access to the fields of a PDX
* without deserializing the entire PDX. The PdxInstance implementation is a light weight wrapper
* that simply refers to the raw bytes of the PDX that are kept in the cache. Using this method
* applications can choose to access PdxInstance instead of Java object.
* <p>
* Note that a PdxInstance is only returned if a serialized PDX is found in the cache. If the
* cache contains a deserialized PDX, then a domain class instance is returned instead of a
* PdxInstance.
*
* @param pdxReadSerialized true to prefer PdxInstance
* @return this ClientCacheFactory
* @since GemFire 6.6
* @see org.apache.geode.pdx.PdxInstance
*/
public ClientCacheFactory setPdxReadSerialized(boolean pdxReadSerialized) {
cacheConfig.setPdxReadSerialized(pdxReadSerialized);
return this;
}
/**
* Set the PDX serializer for the cache. If this serializer is set, it will be consulted to see if
* it can serialize any domain classes which are added to the cache in portable data exchange
* format.
*
* @param serializer the serializer to use
* @return this ClientCacheFactory
* @since GemFire 6.6
* @see PdxSerializer
*/
public ClientCacheFactory setPdxSerializer(PdxSerializer serializer) {
cacheConfig.setPdxSerializer(serializer);
return this;
}
/**
* Set the disk store that is used for PDX meta data. When serializing objects in the PDX format,
* the type definitions are persisted to disk. This setting controls which disk store is used for
* that persistence.
* <p>
* If not set, the metadata will go in the default disk store.
*
* @param diskStoreName the name of the disk store to use for the PDX metadata.
* @return this ClientCacheFactory
* @since GemFire 6.6
* @deprecated Pdx Persistence is not supported on client side. Even when set, it's internally
* ignored.
*/
@Deprecated
public ClientCacheFactory setPdxDiskStore(String diskStoreName) {
cacheConfig.setPdxDiskStore(diskStoreName);
return this;
}
/**
* Control whether the type metadata for PDX objects is persisted to disk. The default for this
* setting is false. If you are using persistent regions with PDX then you must set this to true.
* If you are using a WAN gateway with PDX then you should set this to true.
*
* @param isPersistent true if the metadata should be persistent
* @return this ClientCacheFactory
* @since GemFire 6.6
* @deprecated Pdx Persistence is not supported on client side. Even when set, it's internally
* ignored.
*/
@Deprecated
public ClientCacheFactory setPdxPersistent(boolean isPersistent) {
cacheConfig.setPdxPersistent(isPersistent);
return this;
}
/**
* Control whether pdx ignores fields that were unread during deserialization. The default is to
* preserve unread fields be including their data during serialization. But if you configure the
* cache to ignore unread fields then their data will be lost during serialization.
* <P>
* You should only set this attribute to <code>true</code> if you know this member will only be
* reading cache data. In this use case you do not need to pay the cost of preserving the unread
* fields since you will never be reserializing pdx data.
*
* @param ignore <code>true</code> if fields not read during pdx deserialization should be
* ignored; <code>false</code>, the default, if they should be preserved.
* @return this ClientCacheFactory
* @since GemFire 6.6
*/
public ClientCacheFactory setPdxIgnoreUnreadFields(boolean ignore) {
cacheConfig.setPdxIgnoreUnreadFields(ignore);
return this;
}
}