com.gemstone.gemfire.distributed.DistributedSystem Maven / Gradle / Ivy
/*
* Copyright (c) 2010-2015 Pivotal Software, Inc. All rights reserved.
*
* Licensed 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. See accompanying
* LICENSE file.
*/
package com.gemstone.gemfire.distributed;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import com.gemstone.gemfire.CancelCriterion;
import com.gemstone.gemfire.LogWriter;
import com.gemstone.gemfire.StatisticsFactory;
import com.gemstone.gemfire.cache.Cache;
import com.gemstone.gemfire.cache.CacheFactory;
import com.gemstone.gemfire.cache.client.ClientCache;
import com.gemstone.gemfire.cache.client.ClientCacheFactory;
import com.gemstone.gemfire.distributed.internal.DistributionConfig;
import com.gemstone.gemfire.distributed.internal.DistributionManager;
import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
import com.gemstone.gemfire.i18n.LogWriterI18n;
import com.gemstone.gemfire.internal.Assert;
import com.gemstone.gemfire.internal.ClassPathLoader;
import com.gemstone.gemfire.internal.LogWriterImpl;
import com.gemstone.gemfire.internal.SecurityLogWriter;
import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
import com.gemstone.gemfire.memcached.GemFireMemcachedServer;
import com.gemstone.gemfire.internal.tcp.ConnectionTable;
import com.gemstone.gemfire.internal.util.IOUtils;
import com.gemstone.gemfire.security.GemFireSecurityException;
/**
* A "connection" to a GemFire distributed system. A
* DistributedSystem
is created by invoking the {@link
* #connect} method with a configuration as described below. A DistributedSystem
* is used when calling {@link
* com.gemstone.gemfire.cache.CacheFactory#create}. This class should
* not be confused with the {@link
* com.gemstone.gemfire.admin.AdminDistributedSystem
* AdminDistributedSystem} interface that is used for administering a
* distributed system.
*
*
*
* When a program connects to the distributed system, a "distribution
* manager" is started in this VM and the other members of the
* distributed system are located. This discovery can be performed
* using either IP multicast (default) or by contacting "locators"
* running on a given host and port. All connections that are
* configured to use the same multicast address/port and the same
* locators are part of the same distributed system.
*
*
*
* The current version of GemFire only supports creating one
* DistributedSystem
per virtual machine. Attempts to
* connect to multiple distributed systems (that is calling {@link
* #connect} multiple times with different configuration
* Properties
) will result in an {@link
* IllegalStateException} being thrown (if connect
is
* invoked multiple times with equivalent Properties
,
* then the same instance of DistributedSystem
will be
* returned). A common practice is to connect to the distributed
* system and store a reference to the DistributedSystem
* object in a well-known location such as a static
* variable. This practice provides access to the
* DistributedSystem
slightly faster than invoking
* connect
multiple times. Note that it is always
* advisable to {@link #disconnect()} from the distributed system when a
* program will no longer access it. Disconnecting frees up certain
* resources and allows your application to connect to a different
* distributed system, if desirable.
*
*
*
*
* Configuration
*
*
*
*
* There are a number of configuration properties that can be set when
* a program {@linkplain #connect connects} to a distributed system.
*
*
*
* Distribution Configuration Properties
*
*
* - groups
* - Description: Defines the list of groups this member belongs to.
* Use commas to separate group names.
* Note that anything defined by the roles gemfire property will also be considered a group.
*
- Default: ""
* - Since: 7.0
*
*
* - name
* - Description: Uniquely identifies a member in its distributed system.
* If two members with the same name try to join the same distributed system
* then the second join will fail.
* - Default: ""
*
*
* - distributed-system-id
*- A number that uniquely identifies this distributed system, when
* using the WAN gateway to share data between multiple distributed systems. This
* setting is only required when using the WAN gateway in conjunction with
* the Portable Data eXchange (PDX) serialization format.
*
* If set, this setting must be the same for every member in this distributed
* system. It must be different than the number in other distributed systems
* that this one will connect to using the WAN.
*
* -1 means no setting.
*
* - Range-1..255
* - Default: "-1"
*
*
*
* - mcast-port
* - Description: The port used for multicast networking.
* If zero, then multicast will be disabled and locators must be used to find the other members
* of the distributed system.
* If "mcast-port" is zero and "locators" is ""
* then this distributed system will be isolated from all other GemFire
* processes.
*
* - Default: "0" if locators is ""; otherwise "10334"
*
*
*
* - mcast-address
* - Description: The IP address used for multicast
* networking. If mcast-port is zero, then mcast-address is
* ignored.
*
* - Default: "239.192.81.1"
*
*
* - mcast-ttl
* - Description: Determines how far through your network
* the multicast packets used by GemFire will propagate.
*
- Default: "32"
* - Allowed values: 0..255
* - Since: 4.1
*
*
* - mcast-send-buffer-size
* - Description: Sets the size of the socket buffer used for
* outgoing multicast transmissions.
*
- Default: "65535"
* - Allowed values: 2048..Operating System maximum
* - Since: 5.0
*
*
* - mcast-recv-buffer-size
* - Description: Sets the size of the socket buffer used for
* incoming multicast transmissions. You should set this high if there will be
* high volumes of messages.
*
- Default: "1048576"
* - Allowed values: 2048..Operating System maximum
* - Since: 5.0
*
*
* - mcast-flow-control
* - Description: Configures the flow-of-control protocol for
* multicast messaging. There are three settings that are separated
* by commas: byteAllowance (integer), rechargeThreshold (float) and
* rechargeBlockMs (integer). The byteAllowance determines how many bytes
* can be sent without a recharge from other processes. The rechargeThreshold
* tells receivers how low the sender's initial to remaining allowance
* ratio should be before sending a recharge. The rechargeBlockMs
* tells the sender how long to wait for a recharge before explicitly
* requesting one.
* - Default: "1048576,0.25,5000"
* - Allowed values: 100000-maxInt, 0.1-0.5, 500-60000
* - Since: 5.0
*
*
*
* - udp-send-buffer-size
* - Description: Sets the size of the socket buffer used for
* outgoing udp point-to-point transmissions.
*
- Default: "65535"
* - Allowed values: 2048..Operating System maximum
* - Since: 5.0
*
*
* - udp-recv-buffer-size
* - Description: Sets the size of the socket buffer used for
* incoming udp point-to-point transmissions. Note: if multicast is not
* enabled and disable-tcp is not enabled, a reduced default size of
* 65535 is used.
*
- Default: "1048576 if multicast is enabled or disable-tcp is true, 131071 if not"
* - Allowed values: 2048..Operating System maximum
* - Since: 5.0
*
*
* - udp-fragment-size
* - Description: When messages are sent over datagram sockets,
* GemFire breaks large messages down into fragments for transmission.
* This property sets the maximum fragment size for transmission.
*
- Default: "60000"
* - Allowed values: 1000..60000
* - Since: 5.0
*
*
* - disable-tcp
* - Description: Turns off use of tcp/ip sockets, forcing the
* cache to use datagram sockets for all communication. This is useful
* if you have a large number of processes in the distributed cache since
* it eliminates the per-connection reader-thread that is otherwise required.
* However, udp communications are somewhat slower than tcp/ip communications
* due to the extra work required in Java to break messages down to
* transmittable sizes, and the extra work required to guarantee
* message delivery.
*
* - Default: "false"
* - Allowed values: true or false
* - Since: 5.0
*
*
* - tcp-port
* - Description: A 16-bit integer that determines the tcp/ip port number to listen on
* for cache communications. If zero, the operating system will select
* an available port to listen on. Each process on a machine must have
* its own tcp-port. Note that some operating systems restrict the range
* of ports usable by non-privileged users, and using restricted port
* numbers can cause runtime errors in GemFire startup.
*
* - Default: "0"
* - Allowed values: 0..65535
* - Since: 5.0
*
*
* - member-timeout
* - Description: Sets the timeout interval, in milliseconds, used
* to determine whether another process is alive or not. When another process
* appears to be gone, GemFire sends it an ARE-YOU-DEAD message and waits
* for the member-timeout period for it to respond and declare it is not dead.
*
* - Default: "5000"
* - Allowed values: 1000-600000
* - Since: 5.0
*
*
* - bind-address
* - Description: The IP address that this distributed system's
* server sockets will listen on.
* If set to an empty string then the local machine's
* default address will be listened on.
*
* - Default: ""
*
*
*
* - membership-port-range
* - Description: The allowed range of ports for use in forming an
* unique membership identifier (UDP), for failure detection purposes (TCP) and
* to listen on for peer connections (TCP). This range is given as two numbers
* separated by a minus sign. Minimum 3 values in range are required to
* successfully startup.
*
* - Default: 1024-65535
*
*
*
* - locators
* - Description: A list of locators (host and port) that
* are used to find other member of the distributed system. This
* attribute's value is a possibly empty comma separated list. Each
* element must be of the form "hostName[portNum]" and may be of the
* form "host:bindAddress[port]" if a specific bind address is to be
* used on the locator machine. The square
* brackets around the portNum are literal character and must be
* specified.
* Since IPv6 bind addresses may contain colons, you may use an at symbol
* instead of a colon to separate the host name and bind address.
* For example, "server1@fdf0:76cf:a0ed:9449::5[12233]" specifies a locator
* running on "server1" and bound to fdf0:76cf:a0ed:9449::5 on port 12233.
* If "mcast-port" is zero and "locators" is ""
* then this distributed system will be isolated from all other GemFire
* processes.
*
* - Default: ""
*
*
*
* - start-locator
* - Description: A host name or bind-address and port
* ("host[port],peer=
,server=")
* that are used to start a locator in the same process as the DistributedSystem.
* The locator is started when the DistributedSystem connects,
* and is stopped when the DistributedSystem disconnects. To start a
* locator that is not tied to the DistributedSystem's lifecycle, see
* the {@link Locator} class in this same package.
*
* The peer and server parameters are optional. They specify whether
* the locator can be used for peers to discover each other, or for clients
* to discover peers. By default both are true.
*
* - Default: "" (doesn't start a locator)
*
*
*
* - ssl-enabled
* - Description: If true, all gemfire socket communication is
* configured to use SSL through JSSE.
*
* - Default: "false"
*
*
*
* - ssl-protocols
* - Description: A space seperated list of the SSL protocols to enable.
* Those listed must be supported by the available providers.
*
* - Default: "any"
*
*
*
* - ssl-ciphers
* - Description: A space seperated list of the SSL cipher suites to enable.
* Those listed must be supported by the available providers.
*
* - Default: "any"
*
*
*
* - ssl-require-authentication
* - Description: If false, allow ciphers that do not require the client
* side of the connection to be authenticated.
*
* - Default: "true"
*
*
*
* - ack-wait-threshold
* - Description: The number of seconds the distributed
* system will wait for a message to be acknowledged before it sends
* a warning level alert to signal that something might be wrong with the system
* node that is unresponsive. After sending this alert the waiter
* continues to wait. The alerts are logged in the log as warnings
* and will cause an alert notification in the Admin API and GemFire
* JMX Agent.
* - Default: "15"
* - Allowed values: 1..2147483647
*
*
*
* - ack-severe-alert-threshold
* - Description:
* The number of seconds the distributed
* system will wait after the ack-wait-threshold for a message to be
* acknowledged before it issues an alert at severe level. The
* default value is zero, which turns off this feature.
* when ack-severe-alert-threshold is used, GemFire will also initiate
* additional checks to see if the process is alive. These checks will
* begin when the ack-wait-threshold is reached and will continue until
* GemFire has been able to communicate with the process and ascertain its
* status.
*
- Default: "0"
* - Allowed values: 0..2147483647
*
*
*
* - conserve-sockets
* - Description: If "true" then a minimal number of sockets
* will be used when connecting to the distributed system. This conserves
* resource usage but can cause performance to suffer.
* If "false" then every application thread that sends
* distribution messages to other members of the distributed system
* will own its own sockets and have exclusive access to them.
* The length of time a thread can have exclusive access to a socket
* can be configured with "socket-lease-time".
*
- Default: "true"
* - Allowed values: true|false
* - Since: 4.1
*
*
* - socket-lease-time
* - Description: The number of milliseconds a thread
* can keep exclusive access to a socket that it is not actively using.
* Once a thread loses its lease to a socket it will need to re-acquire
* a socket the next time it sends a message.
* A value of zero causes socket leases to never expire.
* This property is ignored if "conserve-sockets" is true.
*
- Default: "15000"
* - Allowed values: 0..600000
* - Since: 4.1
*
*
* - socket-buffer-size
* - Description: The size of each socket buffer, in bytes.
* Smaller buffers conserve memory. Larger buffers can improve performance;
* in particular if large messages are being sent.
*
- Default: "32768"
* - Allowed values: 128..16777215
* - Since: 4.1
*
*
* - conflate-events
* - Description: This is a client-side property that is passed to
* the server. Allowable values are "server", "true", and "false". With the
* "server" setting, this client's servers use their own client queue
* conflation settings. With a "true" setting, the servers disregard their
* own configuration and enable conflation of events for all regions for the
* client. A "false" setting causes the client's servers to disable
* conflation for all regions for the client.
*
- Default: "server"
* - Since: 5.7
*
*
* - durable-client-id
* - Description: The id to be used by this durable client. When a
* durable client connects to a server, this id is used by the server to
* identify it. The server will accumulate updates for a durable client
* while it is disconnected and deliver these events to the client when it
* reconnects.
*
- Default: ""
* - Since: 5.5
*
*
* - durable-client-timeout
* - Description: The number of seconds a disconnected durable
* client is kept alive and updates are accumulated for it by the server
* before it is terminated.
*
- Default: "300"
* - Since: 5.5
*
*
* - security-
* - Description: Mechanism to define client credentials.
* All tags with "security-" prefix is packaged together as security properties
* and passed as an argument to getCredentials of Authentication module.
* These tags cannot have null values.
*
* - Default: Optional
* - Allowed values: any string
*
* *
* - security-client-auth-init
* - Description: Authentication module name for Clients that requires to act
* upon credentials read from the gemfire.properties file.
* Module must implement AuthInitialize interface.
*
* - Default: "gemfire.jar:authInit"
* - Allowed values: jar file:class name
*
*
*
*
* - delta-propagation
*
* - Description: "true" indicates that server propagates delta
* generated from {@link com.gemstone.gemfire.Delta} type of objects. If "false"
* then server propagates full object but not delta.
* - Default: "true"
* - Allowed values: true|false
*
*
* Network Partitioning Detection
*
*
* - enable-network-partition-detection
* - Description: Turns on network partitioning detection algorithms, which
* detect loss of quorum and shuts down losing partitions.
*
* - Default: "false"
*
*
*
* - disable-auto-reconnect
* - Description: By default GemFire will attempt to reconnect and
* reinitialize the cache when it has been forced out of the distributed system
* by a network-partition event or has otherwise been shunned by other members.
* This setting will turn off this behavior.
* - Default: "false"
*
*
*
* - departure-correlation-window
* - Description: deprecated. This was used in GemFire's previous network
* partition detection algorithm.
*
* - Default: "120"
*
*
* Redundancy Management
*
*
* - enforce-unique-host
* - Description: Whether or not partitioned regions will
* put redundant copies of the same data in different JVMs running on the same physical host.
*
* By default, partitioned regions will try to put redundancy copies on different physical hosts, but it may
* put them on the same physical host if no other hosts are available. Setting this property to true
* will prevent partitions regions from ever putting redundant copies of data on the same physical host.
*
* - Default: "false"
*
*
*
* - redundancy-zone
* - Description: Defines the redundancy zone from this member. If this property is set, partitioned
* regions will not put two redundant copies of data in two members with the same redundancy zone setting.
*
* - Default: ""
*
*
* Logging Configuration Properties
*
*
* - log-file
* - Description: Name of the file to write logging
* messages to. If the file name if "" (default) then messages are
* written to standard out.
*
* - Default: ""
*
*
*
* - log-level
* - Description:The type of log messages that will
* actually write to the log file.
*
* - Default: "config"
* - Allowed values: all|finest|finer|fine|config|info|warning|severe|none
*
*
*
* - statistic-sampling-enabled
* - Description: "true" causes the statistics to be
* sampled periodically and operating system statistics to be
* fetched each time a sample is taken. "false" disables sampling
* which also disables operating system statistic collection. Non
* OS statistics will still be recorded in memory and can be viewed
* by administration tools. However, charts will show no activity
* and no statistics will be archived while sampling is
* disabled.
* Starting in 7.0 the default value has been changed to true.
* If statistic sampling is disabled it will also cause various
* metrics seen in gfsh and pulse to always be zero.
*
* - Default: "true"
* - Allowed values: true|false
*
*
*
* - statistic-sample-rate
* - Description:The rate, in milliseconds, at which samples
* of the statistics will be taken.
* If set to a value less than 1000 the rate will be set to 1000 because
* the VSD tool does not support sub-second sampling.
*
* - Default: "1000"
* - Allowed values: 100..60000
*
*
*
* - statistic-archive-file
* - Description: The file that statistic samples are
* written to. An empty string (default) disables statistic
* archival.
*
* - Default: ""
*
*
*
* - enable-time-statistics
* - Description: "true" causes additional time-based statistics to be
* gathered for gemfire operations. This can aid in discovering
* where time is going in cache operations, albeit at the expense of
* extra clock probes on every operation. "false" disables the additional
* time-based statistics.
*
* - Default: "false"
* - Allowed values: true or false
* - Since: 5.0
*
*
*
* - log-file-size-limit
* - Description: Limits, in megabytes, how large the current log
* file can grow before it is closed and logging rolls on to a new file.
* Set to zero to disable log rolling.
*
* - Default: "0"
* - Allowed values: 0..1000000
*
*
* - log-disk-space-limit
* - Description: Limits, in megabytes, how much disk space can be
* consumed by old inactive log files. When the limit is
* exceeded the oldest inactive log file is deleted.
* Set to zero to disable automatic log file deletion.
*
* - Default: "0"
* - Allowed values: 0..1000000
*
*
*
* - archive-file-size-limit
* - Description: Limits, in megabytes, how large the current statistic archive
* file can grow before it is closed and archival rolls on to a new file.
* Set to zero to disable archive rolling.
*
* - Default: "0"
* - Allowed values: 0..1000000
*
*
* - archive-disk-space-limit
* - Description: Limits, in megabytes, how much disk space can be
* consumed by old inactive statistic archive files. When the limit is
* exceeded the oldest inactive archive is deleted.
* Set to zero to disable automatic archive deletion.
*
* - Default: "0"
* - Allowed values: 0..1000000
*
*
*
* - roles
* - Description: Specifies the application roles that this member
* performs in the distributed system. This is a comma delimited list of
* user-defined strings. Any number of members can be configured to perform
* the same role, and a member can be configured to perform any number of
* roles.
* Note that anything defined by the groups gemfire property will also be considered a role.
*
* - Default: ""
* - Since: 5.0
* - Deprecated: as of 7.0 use
groups
instead.
*
*
*
* - max-wait-time-reconnect
* - Description: Specifies the maximum number of milliseconds
* to wait for the distributed system to reconnect in case of required role
* loss. The system will attempt to reconnect
* more than once, and this timeout period applies to each reconnection attempt.
*
* - Default: "60000"
* - Since: 5.0
*
*
*
* - max-num-reconnect-tries
* - Description: Specifies the maximum number or times to attempt
* to reconnect to the distributed system when required roles are missing.
*
* - Default: "3"
* - Since: 5.0
*
*
* Cache Configuration Properties
*
*
* - cache-xml-file
* - Description: Specifies the name of the XML file or resource
* to initialize the cache with when it is
* {@linkplain com.gemstone.gemfire.cache.CacheFactory#create created}.
* Create will first look for a file that matches the value of this property.
* If a file is not found then it will be searched for using
* {@link java.lang.ClassLoader#getResource}. If the value of this
* property is the empty string (
""
), then the cache
* will not be declaratively initialized.
* - Default: "cache.xml"
*
*
*
* - memcached-port
* - Description: Specifies the port used by {@link GemFireMemcachedServer}
* which enables memcached clients to connect and store data in GemFire distributed system.
* see {@link GemFireMemcachedServer} for other configuration options.
* - Default: "0" disables GemFireMemcachedServer
* - Allowed values: 0..65535
*
*
*
* - memcached-protocol
* - Description: Specifies the protocol used by {@link GemFireMemcachedServer}
* - Default: "ASCII"
* - Allowed values: "ASCII" "BINARY"
*
*
* Asynchronous Message Properties
*
*
* - async-distribution-timeout
* - Description: The number of milliseconds before a
* publishing process should attempt to distribute a cache operation
* before switching over to asynchronous messaging for this process.
* To enable asynchronous messaging, the value must be set above
* zero. If a thread that is publishing to the cache exceeds this value
* when attempting to distribute to this process, it will switch to
* asynchronous messaging until this process catches up, departs, or
* some specified limit is reached, such as
* async-queue-timeout or
* async-max-queue-size.
*
* - Default: "0"
* - Allowed values: 0..60000
*
*
* - async-queue-timeout
* - Description: The number of milliseconds a queuing
* publisher may enqueue asynchronous messages without any distribution
* to this process before that publisher requests this process to
* depart. If a queuing publisher has not been able to send this process
* any cache operations prior to the timeout, this process will attempt
* to close its cache and disconnect from the distributed system.
*
* - Default: "60000"
* - Allowed values: 0..86400000
*
*
* - async-max-queue-size
* - Description: The maximum size in megabytes that a
* publishing process should be allowed to asynchronously enqueue
* for this process before asking this process to depart from the
* distributed system.
*
* - Default: "8"
* - Allowed values: 0..1024
*
*
* JMX Management
*
*
* - jmx-manager
* - Description: If true then this member is willing to be a jmx-manager.
* All the other jmx-manager properties will be used when it does become a manager.
* If this property is false then all other jmx-manager properties are ignored.
*
* - Default: "false except on locators"
*
*
*
* - jmx-manager-start
* - Description: If true then this member will start a jmx manager when
* it creates a cache. Management tools like gfsh can be configured to connect
* to the jmx-manager. In most cases you should not set this because a jmx manager will
* automatically be started when needed on a member that sets "jmx-manager" to true.
* Ignored if jmx-manager is false.
*
* - Default: "false"
*
*
*
* - jmx-manager-port
* - Description: The port this jmx manager will listen to for client connections.
* If this property is set to zero then GemFire will not allow remote client connections
* but you can alternatively use the standard system properties supported by the JVM
* for configuring access from remote JMX clients.
* Ignored if jmx-manager is false.
*
* - Default: "1099"
*
*
*
* - jmx-manager-ssl
* - Description: If true and jmx-manager-port is not zero then the jmx-manager
* will only accept ssl connections. Note that the ssl-enabled property does not apply to the jmx-manager
* but the other ssl properties do. This allows ssl to be configured for just the jmx-manager
* without needing to configure it for the other GemFire connections.
* Ignored if jmx-manager is false.
*
* - Default: "false"
*
*
*
* - jmx-manager-bind-address
* - Description: By default the jmx-manager when configured with a port will listen
* on all the local host's addresses. You can use this property to configure what ip address
* or host name the jmx-manager will listen on. In addition, if the embedded http server is
* started, it will also bind to this address if it is set.
* Ignored if jmx-manager is false or jmx-manager-port is zero.
*
* - Default: ""
*
*
*
* - jmx-manager-hostname-for-clients
* - Description: Lets you control what hostname will be given to clients that ask
* the locator for the location of a jmx manager. By default the ip address that the jmx-manager
* reports is used. But for clients on a different network this property allows you to configure
* a different hostname that will be given to clients.
* Ignored if jmx-manager is false or jmx-manager-port is zero.
*
* - Default: ""
*
*
*
* - jmx-manager-password-file
* - Description: By default the jmx-manager will allow clients without credentials to connect.
* If this property is set to the name of a file then only clients that connect with credentials that
* match an entry in this file will be allowed.
* Most JVMs require that the file is only readable by the owner.
* For more information about the format of this file see Oracle's documentation of the
* com.sun.management.jmxremote.password.file system property.
* Ignored if jmx-manager is false or if jmx-manager-port is zero.
*
* - Default: ""
*
*
*
* - jmx-manager-access-file
* - Description: By default the jmx-manager will allow full access to all mbeans by any client.
* If this property is set to the name of a file then it can restrict clients to only being able to read
* mbeans; they will not be able to modify mbeans. The access level can be configured differently in this
* file for each user name defined in the password file.
* For more information about the format of this file see Oracle's documentation of the
* com.sun.management.jmxremote.access.file system property.
* Ignored if jmx-manager is false or if jmx-manager-port is zero.
*
* - Default: ""
*
*
*
* - jmx-manager-http-port
* - Description: If non-zero then when the jmx manager is started, an embedded
* web server will also be started and will listen on this port.
* The web server is used to host the GemFire Pulse application.
* If you are hosting the Pulse web app in your own web server, then disable
* this embedded server by setting this property to zero.
* Ignored if jmx-manager is false.
*
* - Default: "8080"
*
*
*
* - jmx-manager-update-rate
* - Description: The rate, in milliseconds, at which this member will push updates
* to any jmx managers. Currently this value should be greater than or equal to the
* statistic-sample-rate. Setting this value too high will cause stale values to be
* seen by gfsh and pulse.
*
* - Default: "2000"
*
*
* Off-Heap Memory
*
*
* - off-heap-memory-size
* - Description: The total size of off-heap memory specified as
* off-heap-memory-size=
[g|m]. is the size. [g|m] indicates
* whether the size should be interpreted as gigabytes or megabytes.
*
* - Default:
""
* - Since: 7.5
*
*
*
* - lock-memory
* - Description: Include this option to lock GemFire XD heap and off-heap memory pages into RAM.
* This prevents the operating system from swapping the pages out to disk, which can cause sever
* performance degradation. When you use this command, also configure the operating system limits for
* locked memory.
*
* - Default:
"false"
* - Since: 7.5
*
*
* Miscellaneous
*
*
* - deploy-working-dir
* - Description: Specifies the working directory which this
* distributed member will use to persist deployed JAR files. This directory
* should be unchanged when restarting the member so that it can read what
* was previously persisted. The default is the current working directory
* as determined by
System.getProperty("user.dir")
.
*
* - Default:
System.getProperty("user.dir")
* - Since: 7.0
*
*
*
* - user-command-packages
* - Description: A comma separated list of Java packages that
* contain classes implementing the
CommandMarker
interface.
* Matching classes will be loaded when the VM starts and will be available
* in the GFSH command-line utility.
*
* - Default:
""
* - Since: 7.5
*
*
* @author Darrel Schneider
* @author Bruce Schuchardt
*
* @since 3.0
*/
public abstract class DistributedSystem implements StatisticsFactory {
/**
* The instances of DistributedSystem
created in this
* VM. Presently only one connect to a distributed system is allowed in a VM.
* This set is never modified in place (it is always read only) but
* the reference can be updated by holders of {@link #existingSystemsLock}.
*/
protected static volatile List existingSystems = Collections.EMPTY_LIST;
/**
* This lock must be changed to add or remove a system.
* It is notified when a system is removed.
*
* @see #existingSystems
*/
protected static final Object existingSystemsLock = new Object();
//public static Properties props = new Properties();
/**
* Used to indicate a reconnect is tried in case of required role
* loss.
* */
// public static boolean reconnect = false;
//////////////////////// Static Methods ////////////////////////
/**
* Connects to a GemFire distributed system with a configuration
* supplemented by the given properties.
* The actual configuration attribute values used to connect comes
* from the following sources:
*
* - System properties. If a system property named
* "
gemfire.
propertyName" is defined
* and its value is not an empty string
* then its value will be used for the named configuration attribute.
*
* - Code properties. Otherwise if a property is defined in the
config
* parameter object and its value is not an empty string
* then its value will be used for that configuration attribute.
* - File properties. Otherwise if a property is defined in a configuration property
* file found by this application and its value is not an empty string
* then its value will be used for that configuration attribute.
* A configuration property file may not exist.
* See the following section for how configuration property files are found.
*
- Defaults. Otherwise a default value is used.
*
*
* The name of the property file can be
* specified using the "gemfirePropertyFile" system property.
* If the system property is set to a relative file name then it
* is searched for in following locations.
* If the system property is set to an absolute file name then that
* file is used as the property file.
* If the system property is not set, then the name of the property
* file defaults to "gemfire.properties". The configuration file is
* searched for in the following locations:
*
*
* - Current directory (directory in which the VM was
* launched)
* - User's home directory
* - Class path (loaded as a {@linkplain
* ClassLoader#getResource(String) system resource})
*
*
* If the configuration file cannot be located, then the property
* will have its default value as described above.
*
* @param config
* The configuration properties
* used when connecting to the distributed system
*
* @throws IllegalArgumentException
* If config
contains an unknown configuration
* property or a configuration property does not have an
* allowed value. Note that the values of boolean
* properties are parsed using {@link Boolean#valueOf(java.lang.String)}.
* Therefore all values other than "true" values will be
* considered false
-- an exception will not be
* thrown.
* @throws IllegalStateException
* If a DistributedSystem
with a different
* configuration has already been created in this VM or if
* this VM is {@link
* com.gemstone.gemfire.admin.AdminDistributedSystem
* administering} a distributed system.
* @throws com.gemstone.gemfire.GemFireIOException
* Problems while reading configuration properties file or
* while opening the log file.
* @throws com.gemstone.gemfire.GemFireConfigException
* The distribution transport is not configured correctly
*
* @deprecated as of 6.5 use {@link CacheFactory#create} or {@link ClientCacheFactory#create} instead.
*
* */
@Deprecated
public static DistributedSystem connect(Properties config) {
if (config == null) {
// fix for bug 33992
config = new Properties();
}
// {
// LogWriterI18n logger =
// new LocalLogWriter(LocalLogWriter.ALL_LEVEL, System.out);
// logger.info("DistributedSystem: Connecting with " + config,
// new Exception("Stack trace"));
// }
synchronized (existingSystemsLock) {
if (DistributionManager.isDedicatedAdminVM) {
// For a dedicated admin VM, check to see if there is already
// a connect that will suit our purposes.
DistributedSystem existingSystem = getConnection(config);
if (existingSystem != null) {
return existingSystem;
}
} else {
if (!existingSystems.isEmpty()) {
Assert.assertTrue(existingSystems.size() == 1);
InternalDistributedSystem existingSystem =
(InternalDistributedSystem) existingSystems.get(0);
if (existingSystem.isDisconnecting()) {
while (existingSystem.isConnected()) {
boolean interrupted = Thread.interrupted();
try {
existingSystemsLock.wait(500);
}
catch (InterruptedException ex) {
interrupted = true;
}
finally {
if (interrupted) {
Thread.currentThread().interrupt();
}
}
}
}
if (existingSystem.isConnected()) {
existingSystem.validateSameProperties(config);
return existingSystem;
}
}
}
// Make a new connection to the distributed system
try {
InternalDistributedSystem newSystem =
InternalDistributedSystem.newInstance(config);
addSystem(newSystem);
return newSystem;
}
catch (GemFireSecurityException ex) {
ex.fillInStackTrace(); // Make it harder to figure out where jgroups code lives.
throw ex;
}
}
}
protected static void addSystem(InternalDistributedSystem newSystem) {
synchronized (existingSystemsLock) {
int size = existingSystems.size();
if (size == 0) {
existingSystems = Collections.singletonList(newSystem);
}
else {
ArrayList l = new ArrayList(size+1);
l.addAll(existingSystems);
l.add(0, newSystem);
existingSystems = Collections.unmodifiableList(l);
}
}
}
protected static boolean removeSystem(InternalDistributedSystem oldSystem) {
synchronized (existingSystemsLock) {
ArrayList l = new ArrayList(existingSystems);
boolean result = l.remove(oldSystem);
if (result) {
int size = l.size();
if (size == 0) {
existingSystems = Collections.EMPTY_LIST;
}
else if (size == 1) {
existingSystems = Collections.singletonList(l.get(0));
}
else {
existingSystems = Collections.unmodifiableList(l);
}
}
return result;
}
}
/**
* Sets the calling thread's socket policy.
* This value will override that default set by the
* conserve-sockets
configuration property.
* @param conserveSockets If true
then calling thread will share
* socket connections with other threads.
* If false
then calling thread will have its own sockets.
* @since 4.1
*/
public static void setThreadsSocketPolicy(boolean conserveSockets) {
if (conserveSockets) {
ConnectionTable.threadWantsSharedResources();
} else {
ConnectionTable.threadWantsOwnResources();
}
}
/**
* Frees up any socket resources owned by the calling thread.
* @since 4.1
*/
public static void releaseThreadsSockets() {
ConnectionTable.releaseThreadsSockets();
}
/**
* Returns an existing connection to the distributed system
* described by the given properties.
*
* @since 4.0
*/
private static DistributedSystem getConnection(Properties config) {
// In an admin VM you can have a connection to more than one
// distributed system. If we are already connected to the desired
// distributed system, return that connection.
List l = existingSystems;
for (Iterator iter = l.iterator(); iter.hasNext(); ) {
InternalDistributedSystem existingSystem =
(InternalDistributedSystem) iter.next();
if (existingSystem.sameSystemAs(config)) {
Assert.assertTrue(existingSystem.isConnected());
return existingSystem;
}
}
return null;
}
/**
* Returns a connection to the distributed system that is
* appropriate for administration. This method is for internal use
* only by the admin API.
*
* @since 4.0
*/
protected static DistributedSystem connectForAdmin(Properties props,
LogWriterI18n logger) {
DistributedSystem existing = getConnection(props);
if (existing != null) {
return existing;
} else {
//logger.info("creating new distributed system for admin");
//for (java.util.Enumeration en=props.propertyNames(); en.hasMoreElements(); ) {
// String prop=(String)en.nextElement();
// logger.info(prop + "=" + props.getProperty(prop));
//}
props.setProperty(DistributionConfig.CONSERVE_SOCKETS_NAME, "true");
props.put(DistributionConfig.LOG_WRITER_NAME, logger);
if (logger instanceof LogWriterImpl) {
LogWriterImpl loggerImpl = (LogWriterImpl)logger;
props.put(DistributionConfig.SECURITY_LOG_WRITER_NAME,
new SecurityLogWriter(loggerImpl.getLevel(), loggerImpl));
}
return connect(props);
}
}
/**
* see {@link com.gemstone.gemfire.admin.AdminDistributedSystemFactory}
* @since 5.7
*/
protected static void setEnableAdministrationOnly(boolean adminOnly) {
synchronized (existingSystemsLock) {
if( existingSystems != null && !existingSystems.isEmpty()) {
throw new IllegalStateException(
LocalizedStrings.DistributedSystem_THIS_VM_ALREADY_HAS_ONE_OR_MORE_DISTRIBUTED_SYSTEM_CONNECTIONS_0
.toLocalizedString(existingSystems));
}
DistributionManager.isDedicatedAdminVM = adminOnly;
}
}
// /**
// * Connects to a GemFire distributed system with a configuration
// * supplemented by the given properties.
// *
// * @param config
// * The configuration properties
// * used when connecting to the distributed system
// * @param callback
// * A user-specified object that is delivered with the {@link
// * com.gemstone.gemfire.admin.SystemMembershipEvent}
// * triggered by connecting.
// *
// * @see #connect(Properties)
// * @see com.gemstone.gemfire.admin.SystemMembershipListener#memberJoined
// *
// * @since 4.0
// */
// public static DistributedSystem connect(Properties config,
// Object callback) {
// throw new UnsupportedOperationException("Not implemented yet");
// }
////////////////////// Constructors //////////////////////
/**
* Creates a new instance of DistributedSystem
. This
* constructor is protected so that it may only be invoked by
* subclasses.
*/
protected DistributedSystem() {
}
//////////////////// Instance Methods ////////////////////
/**
* Returns the LogWriter
used for logging information.
* See logFile.
*
* @throws IllegalStateException
* This VM has {@linkplain #disconnect() disconnected} from the
* distributed system.
*/
public abstract LogWriter getLogWriter();
/**
* Returns the LogWriter
used for logging security related
* information. See logFile.
*
* @throws IllegalStateException
* This VM has {@linkplain #disconnect() disconnected} from
* the distributed system.
* @since 5.5
*/
public abstract LogWriter getSecurityLogWriter();
/**
* Returns the configuration properties.
* @return the configuration Properties
*/
public abstract Properties getProperties();
/**
* Returns the security specific configuration properties.
* @return the configuration Properties
* @since 5.5
*/
public abstract Properties getSecurityProperties();
/**
*
* @return the cancel criterion for this system
*/
public abstract CancelCriterion getCancelCriterion();
/**
* Disconnects from this distributed system. This operation will
* close the distribution manager and render the {@link
* com.gemstone.gemfire.cache.Cache Cache} and all distributed
* collections obtained from this distributed system inoperable.
* After a disconnect has completed, a VM may connect to another
* distributed system.
*
*
*
* Attempts to access a distributed system after a VM has
* disconnected from it will result in an {@link
* IllegalStateException} being thrown.
* @deprecated as of 6.5 use {@link Cache#close} or {@link ClientCache#close} instead.
*/
@Deprecated
public abstract void disconnect();
/**
* Returns whether or not this DistributedSystem
is
* connected to the distributed system.
*
* @see #disconnect()
*/
public abstract boolean isConnected();
/**
* Returns the id of this connection to the distributed system.
*
* @deprecated {@link #getDistributedMember} provides an identity for
* this connection that is unique across the entire
* distributed system.
*/
@Deprecated
public abstract long getId();
/**
* Returns a string that uniquely identifies this connection to the
* distributed system.
*
* @see com.gemstone.gemfire.admin.SystemMembershipEvent#getMemberId
*
* @since 4.0
* @deprecated as of GemFire 5.0, use {@link #getDistributedMember} instead
*/
@Deprecated
public abstract String getMemberId();
/**
* Returns the {@link DistributedMember} that identifies this connection to
* the distributed system.
* @return the member that represents this distributed system connection.
* @since 5.0
*/
public abstract DistributedMember getDistributedMember();
/**
* Returns a set of all the other members in this distributed system.
* @return returns a set of all the other members in this distributed system.
* @since 7.0
*/
public abstract Set getAllOtherMembers();
/**
* Returns a set of all the members in the given group.
* Members join a group be setting the "groups" gemfire property.
* @return returns a set of all the member in a group.
* @since 7.0
*/
public abstract Set getGroupMembers(String group);
/**
* Returns the name of this connection to the
* distributed system.
*/
public abstract String getName();
// /**
// * Fires an "informational" SystemMembershipEvent
that
// * is delivered to all {@link
// * com.gemstone.gemfire.admin.SystemMembershipListener}s.
// *
// * @param callback
// * A user-specified object that is delivered with the {@link
// * com.gemstone.gemfire.admin.SystemMembershipEvent}
// * triggered by invoking this method.
// *
// * @see com.gemstone.gemfire.admin.SystemMembershipListener#memberInfo
// *
// * @since 4.0
// */
// public abstract void fireInfoEvent(Object callback);
/**
* The PROPERTY_FILE
is the name of the
* property file that the connect method will check for when
* it looks for a property file.
* The file will be searched for, in order, in the following directories:
*
* - the current directory
*
- the home directory
*
- the class path
*
* Only the first file found will be used.
*
* The default value of PROPERTY_FILE is
* "gemfire.properties"
. However if the
* "gemfirePropertyFile" system property is set then its value is
* the value of PROPERTY_FILE. If this value is a relative file
* system path then the above search is done. If it is an absolute
* file system path then that file must exist; no search for it is
* done.
* @since 5.0
*/
public static String PROPERTY_FILE = System.getProperty(
"gemfirePropertyFile", "gemfire.properties");
/**
* The SECURITY_PROPERTY_FILE
is the name of the
* property file that the connect method will check for when
* it looks for a security property file.
* The file will be searched for, in order, in the following directories:
*
* - the current directory
*
- the home directory
*
- the class path
*
* Only the first file found will be used.
*
* The default value of SECURITY_PROPERTY_FILE is
* "gfsecurity.properties"
. However if the
* "gemfireSecurityPropertyFile" system property is set then its value is
* the value of SECURITY_PROPERTY_FILE. If this value is a relative file
* system path then the above search is done. If it is an absolute
* file system path then that file must exist; no search for it is
* done.
* @since 6.6.2
*/
public static String SECURITY_PROPERTY_FILE = System.getProperty(
"gemfireSecurityPropertyFile", "gfsecurity.properties");
/**
* Gets an URL
for the property file, if one can be found,
* that the connect method will use as its property file.
*
* See {@link #PROPERTY_FILE} for information on the name of
* the property file and what locations it will be looked for in.
* @return a URL
that names the GemFire property file.
* Null is returned if no property file was found.
* @since 5.0
*/
public static URL getPropertyFileURL() {
return getFileURL(PROPERTY_FILE);
}
/**
* Gets an URL
for the security property file, if one can be found,
* that the connect method will use as its property file.
*
* See {@link #SECURITY_PROPERTY_FILE} for information on the name of
* the property file and what locations it will be looked for in.
* @return a URL
that names the GemFire security property file.
* Null is returned if no property file was found.
* @since 6.6.2
*/
public static URL getSecurityPropertiesFileURL() {
return getFileURL(SECURITY_PROPERTY_FILE);
}
private static URL getFileURL(String fileName) {
File file = new File(fileName);
if (file.exists()) {
try {
return IOUtils.tryGetCanonicalFileElseGetAbsoluteFile(file).toURI().toURL();
} catch (MalformedURLException ignore) {
}
}
file = new File(System.getProperty("user.home"), fileName);
if (file.exists()) {
try {
return IOUtils.tryGetCanonicalFileElseGetAbsoluteFile(file).toURI().toURL();
} catch (MalformedURLException ignore) {
}
}
return ClassPathLoader.getLatest().getResource(DistributedSystem.class, fileName);
}
/**
* Test to see whether the DistributedSystem is in the process of reconnecting
* and recreating the cache after it has been removed from the system
* by other members or has shut down due to missing Roles and is reconnecting.
* This will also return true if the DistributedSystem has finished reconnecting.
* When reconnect has completed you can use {@link DistributedSystem#getReconnectedSystem} to
* retrieve the new distributed system.
*
* @return true if the DistributedSystem is attempting to reconnect or has finished reconnecting
*/
abstract public boolean isReconnecting();
/**
* Wait for the DistributedSystem to finish reconnecting to the system
* and recreate the cache.
*
* @param time amount of time to wait, or -1 to wait forever
* @param units
* @return true if the system was reconnected
* @throws InterruptedException if the thread is interrupted while waiting
*/
abstract public boolean waitUntilReconnected(long time, TimeUnit units) throws InterruptedException;
/**
* Force the DistributedSystem to stop reconnecting. If the DistributedSystem
* is currently connected this will disconnect it and close the cache.
*
*/
abstract public void stopReconnecting();
/**
* Returns the new DistributedSystem if there was an auto-reconnect
*/
abstract public DistributedSystem getReconnectedSystem();
}