Java:Kafka AdminClient没有建立连接(或者似乎是这样)

时间:2018-04-18 20:04:02

标签: java intellij-idea apache-kafka

大家。 这是我在这里的第一篇文章,所以,请原谅我写的堆栈溢出问题的精湛技巧。

我在使用org.apache.kafka.clients.admin.AdminClient的AdminClient时遇到问题。

手头的问题是这样的: 我使用SASL SSL启动与代理服务器(运行kafka 1.0.0)的安全连接。

当我使用相同的安全设置运行针对同一代理的使用者时,它工作得很好。然而,当我在做AdminClient的时候,它似乎已经工作了,但是我看到没有任何流量从我的机器出来到wireshark中的代理服务器,而我试图做的事情不会发生在代理方面。

这是我的代码:

public class AclProvisioner {
//set up variables
private static Properties props = new Properties();
private static ClassLoader classloader = Thread.currentThread().getContextClassLoader();
static String mid = null;
static String topic = null;

public static void main(String... args) {
    props.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, "kafkabroker.mydomain.com:9094");
    props.put("security.protocol","SASL_SSL");
    props.put("ssl.truststore.location", "C:\\Temp\\mydomain.root.jks" );
    props.put("ssl.truststore.password","my_truststore_password");
    props.put("sasl.mechanism","GSSAPI");
    props.put("sasl.kerberos.service.name","kafka_admin_username");

    AdminClient adminClient = AdminClient.create(props);

    // generate ACLs
    AclBinding newTopicReadAcl = new AclBinding( new Resource(ResourceType.TOPIC, "TestTopic"),
            new AccessControlEntry("MY_TESTID", "*", AclOperation.READ, AclPermissionType.ALLOW) );
    AclBinding newTopicDescribeAcl = new AclBinding( new Resource(ResourceType.TOPIC, "TestTopic"),
            new AccessControlEntry("MY_TESTID", "*", AclOperation.DESCRIBE, AclPermissionType.ALLOW) );
    AclBinding newGroupReadAcl = new AclBinding( new Resource(ResourceType.GROUP, "TestGroup"),
            new AccessControlEntry("MY_TESTID", "*", AclOperation.READ, AclPermissionType.ALLOW) );
    Collection<AclBinding> aclList = Arrays.asList(newTopicReadAcl, newTopicDescribeAcl, newGroupReadAcl);
    adminClient.createAcls(aclList);


    // create topic 
    int numPartitions = 6;
    short replicasFactor = 2;
    NewTopic newTopic = new NewTopic("Demo.JavaAdminClientTest", numPartitions, replicasFactor);
    Map<String, String> configMap = new HashMap<>();
    configMap.put(TopicConfig.CLEANUP_POLICY_CONFIG, TopicConfig.CLEANUP_POLICY_COMPACT);
    configMap.put(TopicConfig.COMPRESSION_TYPE_CONFIG, "gzip");
    newTopic.configs(configMap);
    List<NewTopic> topics = Arrays.asList(newTopic);
    adminClient.createTopics( topics );

}

如果我ssh到服务器本身并导出我的keytab和kinit,我可以使用CLI方法生成ACL。我也能够使用相同的属性运行消费者(就安全性而言)。

我发现的另一件事是,如果我将服务器放在不存在或无法访问的位置,程序会失败,告诉我它无法解析BOOTSTRAP_SERVER_NAME。

如果不是ACL而是尝试创建主题,则会发生相同的确切行为。再一次,这在CLI中运行得很好。

我感谢任何指示!

干杯

1 个答案:

答案 0 :(得分:0)

所有AdminClient方法都是异步的,只返回Future对象。

因此,如果您没有明确等待期货完成,那么您的程序会在AdminClient有时间通过​​网络发送任何内容之前终止。

您可以使用all() [0]和values() [1]上的CreateAclsResultCreateTopicsResults来检索KafkaFuture [2]个对象。然后在它们上使用get()等待例如。

[0] http://kafka.apache.org/11/javadoc/org/apache/kafka/clients/admin/CreateAclsResult.html

[1] http://kafka.apache.org/11/javadoc/org/apache/kafka/clients/admin/CreateTopicsResult.html

[2] http://kafka.apache.org/11/javadoc/org/apache/kafka/common/KafkaFuture.html