# Class DNSMembershipProvider

java.lang.Object
org.apache.catalina.tribes.membership.MembershipProviderBase
org.apache.catalina.tribes.membership.cloud.CloudMembershipProvider
org.apache.catalina.tribes.membership.cloud.DNSMembershipProvider

All Implemented Interfaces:
  `ChannelListener, Heartbeat, MembershipProvider`

public class DNSMembershipProvider extends CloudMembershipProvider
A `MembershipProvider` that uses DNS to retrieve the members of a cluster.

Relying solely on DNS to determine cluster membership requires that all DNS caching between the cluster nodes and the authoritative name server must honour the TTL set by the authoritative name server. Experience has shown that that is often not the case. Therefore, to ensure that new cluster members are not excluded from the cluster due to a stale DNS cache, this membership service accepts messages from any node regardless of whether it or not is listed as a cluster member in DNS and adds that node to the cluster. The DNS entry is, effectively, used by new nodes to identify the other nodes in the cluster to which cluster messages should be sent.

If more control is required over cluster membership, users are strongly encouraged to use `KubernetesMembershipProvider` instead. Alternatively, the `EncryptInterceptor` may be used to ensure that only nodes with knowledge of the shared key are able to participate in the cluster.

TODO: Make the "accept messages from any node and add that node to the cluster" behaviour optional.

Configuration example for Kubernetes

`server.xml`

    <Server ...

      <Service ...

        <Engine ...

          <Host ...

            <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster">
              <Channel className="org.apache.catalina.tribes.group.GroupChannel">
                <Membership className="org.apache.catalina.tribes.membership.cloud.CloudMembershipService"
                    membershipProviderClassName="org.apache.catalina.tribes.membership.cloud.DNSMembershipProvider"/>
              </Channel>
            </Cluster>
            ...

minimal example for the Service my-tomcat-app-membership, note the selector
`dns-membership-service.yml`

    apiVersion: v1
    kind: Service
    metadata:
      annotations:
        service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
        description: "The service for tomcat cluster membership."
      name: my-tomcat-app-membership
    spec:
      clusterIP: None
      selector:
        app: my-tomcat-app

First Tomcat pod minimal example, note the labels that must correspond to the selector in the service.
`tomcat1.yml`

    apiVersion: v1
    kind: Pod
    metadata:
      name: tomcat1
      labels:
        app: my-tomcat-app
    spec:
      containers:
      - name: tomcat
        image: tomcat
        ports:
        - containerPort: 8080

Environment variable configuration
`DNS_MEMBERSHIP_SERVICE_NAME=my-tomcat-app-membership`

- ## Field Summary

  ### Fields inherited from class CloudMembershipProvider

  `connectionTimeout, CUSTOM_ENV_PREFIX, expirationTime, headers, localIp, port, readTimeout, sm, startTime, streamProvider, url`

  ### Fields inherited from class MembershipProviderBase

  `executor, membership, membershipListener, service`

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `DNSMembershipProvider()`
  Construct a new DNSMembershipProvider.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `boolean`
  `accept(Serializable msg, Member sender)`
  Invoked by the channel to determine if the listener will process this message or not.
  `protected Member[]`
  `fetchMembers()`
  Fetch current cluster members from the cloud orchestration.
  `void`
  `start(int level)`
  Start the membership provider.
  `boolean`
  `stop(int level)`
  Stop the membership provider.

  ### Methods inherited from class CloudMembershipProvider

  `digest, getEnv, getNamespace, heartbeat, init, messageReceived, updateMember`

  ### Methods inherited from class MembershipProviderBase

  `getMember, getMembers, hasMembers, setMembershipListener, setMembershipService`

  ### Methods inherited from class Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- ## Constructor Details

  - ### DNSMembershipProvider

    public DNSMembershipProvider()
    Construct a new DNSMembershipProvider.

- ## Method Details

  - ### start

    public void start(int level) throws Exception
    Description copied from interface: `MembershipProvider`
    Start the membership provider.
    Specified by:
      `start` in interface `MembershipProvider`
    Overrides:
      `start` in class `CloudMembershipProvider`
    Parameters:
      `level` - the readiness level
      - Channel.DEFAULT - will start all services
      - Channel.MBR_RX_SEQ - starts the membership receiver
      - Channel.MBR_TX_SEQ - starts the membership broadcaster
    Throws:
      `Exception` - if an error occurs

  - ### stop

    public boolean stop(int level) throws Exception
    Description copied from interface: `MembershipProvider`
    Stop the membership provider.
    Specified by:
      `stop` in interface `MembershipProvider`
    Overrides:
      `stop` in class `CloudMembershipProvider`
    Parameters:
      `level` - the readiness level
      - Channel.DEFAULT - will stop all services
      - Channel.MBR_RX_SEQ - stops the membership receiver
      - Channel.MBR_TX_SEQ - stops the membership broadcaster
    Returns:
      `true` if successful
    Throws:
      `Exception` - if an error occurs

  - ### fetchMembers

    protected Member[] fetchMembers()
    Description copied from class: `CloudMembershipProvider`
    Fetch current cluster members from the cloud orchestration.
    Specified by:
      `fetchMembers` in class `CloudMembershipProvider`
    Returns:
      the member array

  - ### accept

    public boolean accept(Serializable msg, Member sender)
    Description copied from interface: `ChannelListener`
    Invoked by the channel to determine if the listener will process this message or not.
    Specified by:
      `accept` in interface `ChannelListener`
    Overrides:
      `accept` in class `CloudMembershipProvider`
    Parameters:
      `msg` - Serializable
      `sender` - Member
    Returns:
      boolean