package io.kafka101.clickstream.rest.proxy.client;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import io.kafka101.clickstream.rest.proxy.client.dto.ConsumerData;
import io.kafka101.clickstream.rest.proxy.client.dto.ConsumerRecord;
import io.kafka101.clickstream.rest.proxy.client.dto.ConsumerResponse;
import io.kafka101.clickstream.rest.proxy.client.util.HttpCallback;
import io.kafka101.clickstream.rest.proxy.client.util.KafkaContentType;
import org.apache.http.HttpHeaders;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicHeader;
import org.apache.http.nio.client.HttpAsyncClient;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class Consumer extends AbstractClient {
private static final String CONSUME_URI_TEMPLATE = "%s/instances/%s/topics/%s/";
private static final String DELETE_URI_TEMPLATE = "%s/instances/%s/";
public Consumer(String consumers, HttpAsyncClient httpClient) throws URISyntaxException {
super(consumers, httpClient);
}
public Consumer(URI consumers, HttpAsyncClient httpClient) {
super(consumers, httpClient);
}
public CompletableFuture<ConsumerResponse> create(String group, ConsumerData data)
throws JsonProcessingException, UnsupportedEncodingException {
HttpPost post = new HttpPost(baseUri.resolve(group));
post.addHeader(new BasicHeader(HttpHeaders.CONTENT_TYPE, KafkaContentType.avro()));
post.setEntity(new StringEntity(mapper.writeValueAsString(data), ContentType.APPLICATION_JSON));
HttpCallback<ConsumerResponse> callback = new HttpCallback<>(ConsumerResponse.class);
httpClient.execute(post, callback);
return callback;
}
public CompletableFuture<ConsumerResponse> create(String group, String id, ConsumerData.Format format,
ConsumerData.OffsetReset autoOffsetReset, boolean autoCommitEnable)
throws JsonProcessingException, UnsupportedEncodingException {
ConsumerData data = new ConsumerData(id, format, autoOffsetReset, autoCommitEnable);
return create(group, data);
}
public <K, V> CompletableFuture<List<ConsumerRecord<K, V>>> consume(String group, String id, String topic,
Class<K> keyClass, Class<V> valueClazz) {
HttpGet get = new HttpGet(baseUri.resolve(String.format(CONSUME_URI_TEMPLATE, group, id, topic)));
get.addHeader(new BasicHeader(HttpHeaders.ACCEPT, KafkaContentType.avro()));
HttpCallback<List<ConsumerRecord<K, V>>> callback = new HttpCallback<>(constructType(keyClass, valueClazz));
httpClient.execute(get, callback);
return callback;
}
public void destroy(String group, String id) throws ExecutionException, InterruptedException {
HttpDelete delete = new HttpDelete(baseUri.resolve(String.format(DELETE_URI_TEMPLATE, group, id)));
delete.addHeader(new BasicHeader(HttpHeaders.ACCEPT, KafkaContentType.allTypes()));
httpClient.execute(delete, null).get();
}
private JavaType constructType(Class keyClass, Class valueClazz) {
JavaType type = mapper.getTypeFactory().constructParametrizedType(ConsumerRecord.class, ConsumerRecord.class,
keyClass, valueClazz);
return mapper.getTypeFactory().constructCollectionType(List.class, type);
}
}