org.apache.flume.api.RpcClientFactory Maven / Gradle / Ivy
/*
* 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.flume.api;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.Properties;
import org.apache.flume.FlumeException;
/**
* Factory class to construct Flume {@link RPCClient} implementations.
*/
public class RpcClientFactory {
/**
* Returns an instance of {@link RpcClient}, optionally with failover.
* To create a failover client, the properties object should have a
* property client.type which has the value "failover". The client
* connects to hosts specified by hosts property in given properties.
*
* @see org.apache.flume.api.FailoverRpcClient
*
* If no client.type is specified, a default client that connects to
* single host at a given port is created.(type can also simply be
* DEFAULT for the default client).
*
* @see org.apache.flume.api.NettyAvroClient
*
* @param properties The properties to instantiate the client with.
* @throws FlumeException
*/
@SuppressWarnings("unchecked")
public static RpcClient getInstance(Properties properties)
throws FlumeException {
String type = null;
type = properties.getProperty(
RpcClientConfigurationConstants.CONFIG_CLIENT_TYPE);
if (type == null || type.isEmpty()) {
type = ClientType.DEFAULT.getClientClassName();
}
Class extends AbstractRpcClient> clazz;
AbstractRpcClient client;
try {
String clientClassType = type;
ClientType clientType = null;
try{
clientType = ClientType.valueOf(type.toUpperCase());
} catch (IllegalArgumentException e){
clientType = ClientType.OTHER;
}
if (!clientType.equals(ClientType.OTHER)){
clientClassType = clientType.getClientClassName();
}
clazz =
(Class extends AbstractRpcClient>) Class.forName(clientClassType);
} catch (ClassNotFoundException e) {
throw new FlumeException("No such client!", e);
}
try {
client = clazz.newInstance();
} catch (InstantiationException e) {
throw new FlumeException("Cannot instantiate client. " +
"Exception follows:", e);
} catch (IllegalAccessException e) {
throw new FlumeException("Cannot instantiate client. " +
"Exception follows:", e);
}
client.configure(properties);
return client;
}
/**
* Delegates to {@link #getInstance(Properties props)}, given a File path
* to a {@link Properties} file.
* @param propertiesFile Valid properties file
* @return RpcClient configured according to the given Properties file.
* @throws FileNotFoundException If the file cannot be found
* @throws IOException If there is an IO error
*/
public static RpcClient getInstance(File propertiesFile)
throws FileNotFoundException, IOException {
Reader reader = new FileReader(propertiesFile);
Properties props = new Properties();
props.load(reader);
return getInstance(props);
}
/**
* Deprecated. Use
* {@link getDefaultInstance() getDefaultInstance(String, Integer)} instead.
* @throws FlumeException
* @deprecated
*/
@Deprecated
public static RpcClient getInstance(String hostname, Integer port)
throws FlumeException {
return getDefaultInstance(hostname, port);
}
/**
* Returns an instance of {@link RpcClient} connected to the specified
* {@code hostname} and {@code port}.
* @throws FlumeException
*/
public static RpcClient getDefaultInstance(String hostname, Integer port)
throws FlumeException {
return getDefaultInstance(hostname, port, 0);
}
/**
* Deprecated. Use
* {@link getDefaultInstance() getDefaultInstance(String, Integer, Integer)}
* instead.
* @throws FlumeException
* @deprecated
*/
@Deprecated
public static RpcClient getInstance(String hostname, Integer port,
Integer batchSize) throws FlumeException {
return getDefaultInstance(hostname, port, batchSize);
}
/**
* Returns an instance of {@link RpcClient} connected to the specified
* {@code hostname} and {@code port} with the specified {@code batchSize}.
* @throws FlumeException
*/
public static RpcClient getDefaultInstance(String hostname, Integer port,
Integer batchSize) throws FlumeException {
if (hostname == null) {
throw new NullPointerException("hostname must not be null");
}
if (port == null) {
throw new NullPointerException("port must not be null");
}
if (batchSize == null) {
throw new NullPointerException("batchSize must not be null");
}
Properties props = new Properties();
props.setProperty(RpcClientConfigurationConstants.CONFIG_HOSTS, "h1");
props.setProperty(RpcClientConfigurationConstants.CONFIG_HOSTS_PREFIX + "h1",
hostname + ":" + port.intValue());
props.setProperty(RpcClientConfigurationConstants.CONFIG_BATCH_SIZE, batchSize.toString());
NettyAvroRpcClient client = new NettyAvroRpcClient();
client.configure(props);
return client;
}
/**
* Return an {@linkplain RpcClient} that uses Thrift for communicating with
* the next hop. The next hop must have a ThriftSource listening on the
* specified port.
* @param hostname - The hostname of the next hop.
* @param port - The port on which the ThriftSource is listening
* @param batchSize - batch size of each transaction.
* @return an {@linkplain RpcClient} which uses thrift configured with the
* given parameters.
*/
public static RpcClient getThriftInstance(String hostname, Integer port,
Integer batchSize) {
if (hostname == null) {
throw new NullPointerException("hostname must not be null");
}
if (port == null) {
throw new NullPointerException("port must not be null");
}
if (batchSize == null) {
throw new NullPointerException("batchSize must not be null");
}
Properties props = new Properties();
props.setProperty(RpcClientConfigurationConstants.CONFIG_HOSTS, "h1");
props.setProperty(RpcClientConfigurationConstants.CONFIG_HOSTS_PREFIX + "h1",
hostname + ":" + port.intValue());
props.setProperty(RpcClientConfigurationConstants.CONFIG_BATCH_SIZE, batchSize.toString());
ThriftRpcClient client = new ThriftRpcClient();
client.configure(props);
return client;
}
/**
* Return an {@linkplain RpcClient} that uses Thrift for communicating with
* the next hop. The next hop must have a ThriftSource listening on the
* specified port. This will use the default batch size. See {@linkplain
* RpcClientConfigurationConstants}
* @param hostname - The hostname of the next hop.
* @param port - The port on which the ThriftSource is listening
* @return - An {@linkplain RpcClient} which uses thrift configured with the
* given parameters.
*/
public static RpcClient getThriftInstance(String hostname, Integer port) {
return getThriftInstance(hostname, port, RpcClientConfigurationConstants
.DEFAULT_BATCH_SIZE);
}
/**
* Return an {@linkplain RpcClient} that uses Thrift for communicating with
* the next hop.
* @param props
* @return - An {@linkplain RpcClient} which uses thrift configured with the
* given parameters.
*/
public static RpcClient getThriftInstance(Properties props) {
props.setProperty(RpcClientConfigurationConstants.CONFIG_CLIENT_TYPE,
ClientType.THRIFT.clientClassName);
return getInstance(props);
}
public static enum ClientType {
OTHER(null),
DEFAULT(NettyAvroRpcClient.class.getCanonicalName()),
DEFAULT_FAILOVER(FailoverRpcClient.class.getCanonicalName()),
DEFAULT_LOADBALANCE(LoadBalancingRpcClient.class.getCanonicalName()),
THRIFT(ThriftRpcClient.class.getCanonicalName());
private final String clientClassName;
private ClientType(String className) {
this.clientClassName = className;
}
protected String getClientClassName() {
return this.clientClassName;
}
}
}