-
Notifications
You must be signed in to change notification settings - Fork 83
Introducing support for Kafka streams #39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
92e615f to
30bc5ea
Compare
|
Hi @adamosloizou and thanks for your PR! I'll go through it in the next days - however I think your changes are incompatible with Scala 2.10 (there's a transitive dependency missing in Travis build for 2.10). I'm not sure whether we need to keep cross versions compatibility, but if you have an easy way to fix that it would be appreciated. Will keep you posted on the rest of the PR (I haven't used Kafka Streams myself). |
|
Hey @manub! Yes, it was Typesafe's As for Kafka Streams, interesting concept but its API is still young. You can definitely spot commonalities between that and Spark and Akka Streams API for functional-style transformations (maps, flatmaps etc). It's a nice way forward it seems. Let me know what you think! |
|
Try to merge |
30bc5ea to
4116932
Compare
|
@manub I think I fixed it. There was a clash with the two sub-modules' tests using the same ports for their Kafka/Zookeeper servers. |
|
This is really weird, it works fine locally on my machine. I am running with JVM 8 instead of 7 as the build. Could that have something to do? |
|
I will have a look at it - had a failure with my Mac and I'm in the middle of reinstalling all the software. Sorry for the delay! |
1cf6fe3 to
fae64c5
Compare
|
I have managed to replicate the issue on my machine by using a VM with limited resources. It was a race-condition that exposed the fact that the Stream consumers could start consuming after the 1st set of published messages. However, now I am seeing a failure on the embedded-kafka side. Any ideas? |
|
Rerunning your build passes it - it's quite unstable on CI and I'm aware of that. Will look at the code as soon as I have an opportunity. As I mentioned before my personal laptop failed and I'm still in the process of restoring it. Thanks for your patience! |
manub
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @adamosloizou - thanks for the PR! It looks overall good although there are some coding style things that I'd like to get fixed before merging. Also - would it be possible for you to extend the README.md?
| */ | ||
| def consumeLazily(topic: String): Stream[(K, V)] = { | ||
| val attempts = 1 to MaximumAttempts | ||
| attempts.toStream.flatMap(attempt => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could this be rewritten as .flatMap { attempt => ... }?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in badc3b2
| * | ||
| * @return the unique ID | ||
| */ | ||
| def newUuid(): String = UUID.randomUUID().toString |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather have this method still returning a UUID and let the user convert it to string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in badc3b2
| def withConsumer[K: Deserializer, V: Deserializer, T](block: KafkaConsumer[K, V] => T) | ||
| (implicit config: EmbeddedKafkaConfig): T = { | ||
| val consumer = newConsumer[K, V]() | ||
| val result = block(consumer) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can block() ever throw an exception? as probably we don't know in advance it would be better to wrap block(consumer) into a try / finally block in order to close the consumer regardless of what happens.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch!
Fixed in badc3b2
| @@ -1,7 +1,8 @@ | |||
| log4j.rootLogger=info, stdout | |||
| log4j.rootLogger=off | |||
| #log4j.rootLogger=info, stdout | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this line can be removed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 2cace27
| (block: => Any) | ||
| (implicit config: EmbeddedKafkaConfig): Any = | ||
| withRunningKafka { | ||
| topicsToCreate.foreach(topic => createCustomTopic(topic)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in my opinion it would be more idiomatic .foreach(createCustomTopic)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. I tried that originally but unfortunately it does not work:
Error:(45, 30) type mismatch;
found : (String, Map[String,String], Int, Int) => Unit
required: String => ?
topicsToCreate.foreach(createCustomTopic)
An alternative is foreach(createCustomTopic(_)). In my opinion that's not particularly pretty and I prefer being explicit as per above. I think it reads better.
What do you think?
| (implicit config: EmbeddedKafkaConfig): Any = | ||
| withRunningKafka { | ||
| topicsToCreate.foreach(topic => createCustomTopic(topic)) | ||
| val streamId: String = UUIDs.newUuid() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this type annotation it's redundand
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in badc3b2
| @@ -0,0 +1,9 @@ | |||
| log4j.rootLogger=off | |||
| #log4j.logger.net.manub.embeddedkafka=debug, stdout | |||
| #log4j.logger.org.apache.kafka.streams=debug, stdout | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
those 2 lines can be removed as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 2cace27
| import org.apache.kafka.streams.kstream.{KStream, KStreamBuilder} | ||
| import org.scalatest.{FlatSpec, Matchers} | ||
|
|
||
| class ExampleKafkaStreamsSpec extends FlatSpec with Matchers with EmbeddedKafkaStreamsAllInOne { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be possible to use WordSpec here for consistency reasons?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Of course!
Fixed in badc3b2
fae64c5 to
2cace27
Compare
|
README updated 😄! |
…ggregation project in preparation for introducing kafka-streams subproject.
…ded Kafka. Introduced EmbeddedKafkaStreams and EmbeddedKafkaStreamsAllInOne traits for easy testing. Introduced Consumers trait for easy creation and consumption of test messages.
2cace27 to
e661bdc
Compare
|
@manub Please re-run the build. I think the failures are the unstable part that you mentioned. |
|
Thanks @adamosloizou ! |
Description
Hello,
I have been using your library recently and I really like it 😃!
I am currently working with Kafka's new library, Kafka Streams and I couldn't find an easy abstraction for testing.
This PR introduces a ScalaTest-based trait that should make testing Kafka Streams testing easier.
Features/Changes
embedded-kafkaand introducedkafka-streamssubmodule. This allows for people to not have to depend on Kafka Streams for using the original code base.EmbeddedKafkaStreamsandEmbeddedKafkaStreamsAllInOnetraits. They use and expand on theEmbeddedKafkatrait.ConsumersandConsumerExtensionsfor easily consuming arbitrary messages as Scala Streams.Testing
kafka-streamspassembedded-kafkaget[Address already in use errors]which I also see in master. Is that expected?Notes
I have not changed the
README.mdas I would like to see how you like it before discussing what the user manual should look like.Thanks!
Adamos