-
Notifications
You must be signed in to change notification settings - Fork 434
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
GEOMESA-3370,GEOMESA-3368 Kafka - Java-friendly at-least-once consumer (
- Loading branch information
1 parent
80e283e
commit 6e2056a
Showing
7 changed files
with
244 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
70 changes: 70 additions & 0 deletions
70
...store/src/main/java/org/locationtech/geomesa/kafka/utils/interop/GeoMessageProcessor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/*********************************************************************** | ||
* Copyright (c) 2013-2024 Commonwealth Computer Research, Inc. | ||
* All rights reserved. This program and the accompanying materials | ||
* are made available under the terms of the Apache License, Version 2.0 | ||
* which accompanies this distribution and is available at | ||
* http://www.opensource.org/licenses/apache2.0.php. | ||
***********************************************************************/ | ||
|
||
package org.locationtech.geomesa.kafka.utils.interop; | ||
|
||
import org.locationtech.geomesa.kafka.consumer.BatchConsumer; | ||
import org.locationtech.geomesa.kafka.utils.GeoMessage; | ||
import scala.Enumeration; | ||
|
||
import java.util.List; | ||
|
||
/** | ||
* Message processor class. Guarantees 'at-least-once' processing. | ||
*/ | ||
public interface GeoMessageProcessor extends org.locationtech.geomesa.kafka.utils.GeoMessageProcessor { | ||
|
||
/** | ||
* Consume a batch of records. | ||
* <p> | ||
* The response from this method will determine the continued processing of messages. If `Commit` | ||
* is returned, the batch is considered complete and won't be presented again. If `Continue` is | ||
* returned, the batch will be presented again in the future, and more messages will be read off the topic | ||
* in the meantime. If `Pause` is returned, the batch will be presented again in the future, but | ||
* no more messages will be read off the topic in the meantime. | ||
* <p> | ||
* This method should return in a reasonable amount of time. If too much time is spent processing | ||
* messages, consumers may be considered inactive and be dropped from processing. See | ||
* <a href="https://kafka.apache.org/26/javadoc/org/apache/kafka/clients/consumer/KafkaConsumer.html">https://kafka.apache.org/26/javadoc/org/apache/kafka/clients/consumer/KafkaConsumer.html</a> | ||
* <p> | ||
* Note: if there is an error committing the batch or something else goes wrong, some messages may | ||
* be repeated in a subsequent call, regardless of the response from this method | ||
* | ||
* @param records records | ||
* @return indication to continue, pause, or commit | ||
*/ | ||
BatchResult consume(List<GeoMessage> records); | ||
|
||
// scala 2.12 - note, can't @Override these due to scala version differences | ||
default Enumeration.Value consume(scala.collection.Seq<GeoMessage> records) { | ||
List<GeoMessage> list = scala.collection.JavaConverters.seqAsJavaListConverter(records).asJava(); | ||
BatchResult result = consume(list); | ||
switch(result) { | ||
case COMMIT: return BatchConsumer.BatchResult$.MODULE$.Commit(); | ||
case CONTINUE: return BatchConsumer.BatchResult$.MODULE$.Continue(); | ||
case PAUSE: return BatchConsumer.BatchResult$.MODULE$.Pause(); | ||
} | ||
return null; | ||
} | ||
|
||
// scala 2.13 - note, can't @Override these due to scala version differences | ||
default Enumeration.Value consume(scala.collection.immutable.Seq<GeoMessage> records) { | ||
List<GeoMessage> list = scala.collection.JavaConverters.seqAsJavaListConverter(records).asJava(); | ||
BatchResult result = consume(list); | ||
switch(result) { | ||
case COMMIT: return BatchConsumer.BatchResult$.MODULE$.Commit(); | ||
case CONTINUE: return BatchConsumer.BatchResult$.MODULE$.Continue(); | ||
case PAUSE: return BatchConsumer.BatchResult$.MODULE$.Pause(); | ||
} | ||
return null; | ||
} | ||
|
||
enum BatchResult { | ||
COMMIT, CONTINUE, PAUSE | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
49 changes: 49 additions & 0 deletions
49
...tastore/src/test/java/org/locationtech/geomesa/kafka/data/GeoMessageProcessorApiTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/*********************************************************************** | ||
* Copyright (c) 2013-2024 Commonwealth Computer Research, Inc. | ||
* All rights reserved. This program and the accompanying materials | ||
* are made available under the terms of the Apache License, Version 2.0 | ||
* which accompanies this distribution and is available at | ||
* http://www.opensource.org/licenses/apache2.0.php. | ||
***********************************************************************/ | ||
|
||
package org.locationtech.geomesa.kafka.data; | ||
|
||
import org.junit.Test; | ||
import org.locationtech.geomesa.kafka.utils.GeoMessage; | ||
import org.locationtech.geomesa.kafka.utils.interop.GeoMessageProcessor; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
import static org.mockito.Mockito.mock; | ||
|
||
public class GeoMessageProcessorApiTest { | ||
|
||
public static class TestProcessor implements GeoMessageProcessor { | ||
public List<GeoMessage.Change> added = new ArrayList<>(); | ||
public List<GeoMessage.Delete> removed = new ArrayList<>(); | ||
public int cleared = 0; | ||
@Override | ||
public BatchResult consume(List<GeoMessage> records) { | ||
records.forEach((r) -> { | ||
if (r instanceof GeoMessage.Change) { | ||
added.add((GeoMessage.Change) r); | ||
} else if (r instanceof GeoMessage.Delete) { | ||
removed.add(((GeoMessage.Delete) r)); | ||
} else if (r instanceof GeoMessage.Clear) { | ||
cleared++; | ||
} | ||
}); | ||
return BatchResult.COMMIT; | ||
} | ||
} | ||
|
||
@Test | ||
public void testJavaApi() { | ||
GeoMessageProcessor processor = new TestProcessor(); | ||
KafkaDataStore kds = mock(); | ||
// verify that things compile from java | ||
// noinspection resource | ||
kds.createConsumer("type-name", "group-id", processor); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
...ore/src/test/scala/org/locationtech/geomesa/kafka/utils/GeoMessageProcessorJavaTest.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/*********************************************************************** | ||
* Copyright (c) 2013-2024 Commonwealth Computer Research, Inc. | ||
* All rights reserved. This program and the accompanying materials | ||
* are made available under the terms of the Apache License, Version 2.0 | ||
* which accompanies this distribution and is available at | ||
* http://www.opensource.org/licenses/apache2.0.php. | ||
***********************************************************************/ | ||
|
||
package org.locationtech.geomesa.kafka.utils | ||
|
||
import org.junit.runner.RunWith | ||
import org.locationtech.geomesa.features.ScalaSimpleFeature | ||
import org.locationtech.geomesa.kafka.consumer.BatchConsumer.BatchResult | ||
import org.locationtech.geomesa.kafka.data.GeoMessageProcessorApiTest | ||
import org.locationtech.geomesa.utils.geotools.SimpleFeatureTypes | ||
import org.specs2.mutable.Specification | ||
import org.specs2.runner.JUnitRunner | ||
|
||
@RunWith(classOf[JUnitRunner]) | ||
class GeoMessageProcessorJavaTest extends Specification { | ||
|
||
import scala.collection.JavaConverters._ | ||
|
||
lazy val sft = SimpleFeatureTypes.createType("KafkaGeoMessageTest", "name:String,*geom:Point:srid=4326") | ||
lazy val feature = ScalaSimpleFeature.create(sft, "test_id", "foo", "POINT(1 -1)") | ||
|
||
"GeoMessageProcessor" should { | ||
"work through the java api" in { | ||
val change = GeoMessage.change(feature) | ||
val del = GeoMessage.delete(feature.getID) | ||
val clear = GeoMessage.clear() | ||
|
||
val processor = new GeoMessageProcessorApiTest.TestProcessor() | ||
processor.consume(Seq(change, del, clear)) mustEqual BatchResult.Commit | ||
processor.added.asScala mustEqual Seq(change) | ||
processor.removed.asScala mustEqual Seq(del) | ||
processor.cleared mustEqual 1 | ||
} | ||
} | ||
} |