ZooKeeperBuilder.java
/*
* 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.zookeeper.client;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.time.Duration;
import java.util.Collection;
import java.util.Objects;
import java.util.function.Function;
import org.apache.yetus.audience.InterfaceAudience;
import org.apache.yetus.audience.InterfaceStability;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.admin.ZooKeeperAdmin;
/**
* Builder to construct {@link ZooKeeper} and {@link ZooKeeperAdmin}.
*/
@InterfaceAudience.Public
@InterfaceStability.Evolving
public class ZooKeeperBuilder {
private final String connectString;
private final Duration sessionTimeout;
private Function<Collection<InetSocketAddress>, HostProvider> hostProvider;
private Watcher defaultWatcher;
private boolean canBeReadOnly = false;
private long sessionId = 0;
private byte[] sessionPasswd;
private ZKClientConfig clientConfig;
/**
* Creates a builder with given connect string and session timeout.
*
* @param connectString
* comma separated host:port pairs, each corresponding to a zk
* server. e.g. "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002"
* If the optional chroot suffix is used the example would look
* like: "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002/app/a"
* where the client would be rooted at "/app/a" and all paths
* would be relative to this root - ie getting/setting/etc...
* "/foo/bar" would result in operations being run on
* "/app/a/foo/bar" (from the server perspective).
* @param sessionTimeout
* session timeout
*/
public ZooKeeperBuilder(String connectString, Duration sessionTimeout) {
this.connectString = connectString;
this.sessionTimeout = Objects.requireNonNull(sessionTimeout, "session timeout must not be null");
}
/**
* Specified watcher to receive state changes, and node events if attached later.
*
* @param watcher
* a watcher object which will be notified of state changes, may
* also be notified for node events
* @return this
*/
public ZooKeeperBuilder withDefaultWatcher(Watcher watcher) {
this.defaultWatcher = watcher;
return this;
}
/**
* Specifies a function to construct a {@link HostProvider} with initial server addresses from connect string.
*
* @param hostProvider
* use this as HostProvider to enable custom behaviour.
* @return this
*/
public ZooKeeperBuilder withHostProvider(Function<Collection<InetSocketAddress>, HostProvider> hostProvider) {
this.hostProvider = hostProvider;
return this;
}
/**
* Specifies whether the created client is allowed to go to read-only mode in case of partitioning.
*
* @param canBeReadOnly
* whether the created client is allowed to go to
* read-only mode in case of partitioning. Read-only mode
* basically means that if the client can't find any majority
* servers but there's partitioned server it could reach, it
* connects to one in read-only mode, i.e. read requests are
* allowed while write requests are not. It continues seeking for
* majority in the background.
* @return this
* @since 3.4
*/
public ZooKeeperBuilder withCanBeReadOnly(boolean canBeReadOnly) {
this.canBeReadOnly = canBeReadOnly;
return this;
}
/**
* Specifies session id and password in session reestablishment.
*
* @param sessionId
* session id to use if reconnecting, otherwise 0 to open new session
* @param sessionPasswd
* password for this session
* @return this
* @see ZooKeeper#getSessionId()
* @see ZooKeeper#getSessionPasswd()
*/
@SuppressFBWarnings({"EI_EXPOSE_REP", "EI_EXPOSE_REP2"})
public ZooKeeperBuilder withSession(long sessionId, byte[] sessionPasswd) {
this.sessionId = sessionId;
this.sessionPasswd = sessionPasswd;
return this;
}
/**
* Specifies the client config used to construct ZooKeeper instances.
*
* @param clientConfig
* passing this conf object gives each client the flexibility of
* configuring properties differently compared to other instances
* @return this
* @since 3.5.2
*/
public ZooKeeperBuilder withClientConfig(ZKClientConfig clientConfig) {
this.clientConfig = clientConfig;
return this;
}
/**
* Creates a {@link ZooKeeperOptions} with configured options.
*
* @apiNote helper to delegate existing constructors to {@link ZooKeeper#ZooKeeper(ZooKeeperOptions)}
*/
@InterfaceAudience.Private
public ZooKeeperOptions toOptions() {
return new ZooKeeperOptions(
connectString,
sessionTimeout,
defaultWatcher,
hostProvider,
canBeReadOnly,
sessionId,
sessionPasswd,
clientConfig
);
}
/**
* Constructs an instance of {@link ZooKeeper}.
*
* @return an instance of {@link ZooKeeper}
* @throws IOException from constructor of {@link ZooKeeper}
*/
public ZooKeeper build() throws IOException {
return new ZooKeeper(toOptions());
}
/**
* Constructs an instance of {@link ZooKeeperAdmin}.
*
* @return an instance of {@link ZooKeeperAdmin}
* @throws IOException from constructor of {@link ZooKeeperAdmin}
*/
public ZooKeeperAdmin buildAdmin() throws IOException {
return new ZooKeeperAdmin(toOptions());
}
}