/*
* Copyright 2016 LINE Corporation
*
* LINE Corporation 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 com.linecorp.armeria.server.logging.structured.kafka;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.internal.verification.VerificationModeFactory.times;
import org.apache.kafka.clients.producer.Callback;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import com.linecorp.armeria.common.http.HttpRequest;
import com.linecorp.armeria.common.http.HttpResponse;
import com.linecorp.armeria.server.Service;
public class KafkaStructuredLoggingServiceTest {
@Rule
public final MockitoRule mockitoRule = MockitoJUnit.rule();
private static final String TOPIC_NAME = "topic-test";
private static final class SimpleStructuredLog {
private final String name;
private SimpleStructuredLog(String name) {
this.name = name;
}
}
private static class KafkaStructuredLoggingServiceExposed
extends KafkaStructuredLoggingService<HttpRequest, HttpResponse, SimpleStructuredLog> {
KafkaStructuredLoggingServiceExposed(
Producer<byte[], SimpleStructuredLog> producer,
KeySelector<SimpleStructuredLog> keySelector,
boolean needToCloseProducer) {
super(mock(Service.class), log -> null, producer, TOPIC_NAME, keySelector, needToCloseProducer);
}
}
@Mock
private Producer<byte[], SimpleStructuredLog> producer;
@Captor
private ArgumentCaptor<ProducerRecord<byte[], SimpleStructuredLog>> captor;
@Test
public void testServiceWithoutKeySelector() {
KafkaStructuredLoggingServiceExposed service =
new KafkaStructuredLoggingServiceExposed(producer, null, false);
SimpleStructuredLog log = new SimpleStructuredLog("kawamuray");
service.writeLog(null, log);
verify(producer, times(1)).send(captor.capture(), any(Callback.class));
ProducerRecord<byte[], SimpleStructuredLog> record = captor.getValue();
assertThat(record.key()).isNull();
assertThat(record.value()).isEqualTo(log);
}
@Test
public void testWithKeySelector() {
KafkaStructuredLoggingServiceExposed service = new KafkaStructuredLoggingServiceExposed(
producer, (res, log) -> log.name.getBytes(), false);
SimpleStructuredLog log = new SimpleStructuredLog("kawamuray");
service.writeLog(null, log);
verify(producer, times(1)).send(captor.capture(), any(Callback.class));
ProducerRecord<byte[], SimpleStructuredLog> record = captor.getValue();
assertThat(record.key()).isNotNull();
assertThat(new String(record.key())).isEqualTo(log.name);
assertThat(record.value()).isEqualTo(log);
}
@Test
public void testCloseProducerWhenRequested() {
KafkaStructuredLoggingServiceExposed service =
new KafkaStructuredLoggingServiceExposed(producer, null, true);
service.close();
verify(producer, times(1)).close();
}
@Test
public void testDoNotCloseProducerWhenNotRequested() {
KafkaStructuredLoggingServiceExposed service =
new KafkaStructuredLoggingServiceExposed(producer, null, false);
service.close();
verify(producer, times(0)).close();
}
}