Skip to content

Commit f8f1c8d

Browse files
committed
Initial import
1 parent 1c2fabd commit f8f1c8d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+4243
-3
lines changed

.gitignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
target/
2+
.idea/
3+
# vim
4+
*.sw?
5+
6+
# Ignore [ce]tags files
7+
tags
8+
9+
.bloop
10+
.metals

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# changelog

CODE_OF_CONDUCT.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Code of Conduct
2+
3+
We are committed to providing a friendly, safe and welcoming environment for all, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, nationality, or other such characteristics.
4+
5+
Everyone is expected to follow the [Scala Code of Conduct] when discussing the project on the available communication channels. If you are being harassed, please contact us immediately so that we can support you.
6+
7+
## Moderation
8+
9+
Any questions, concerns, or moderation requests please contact a member of the project.
10+
11+
- [Zach Cox](mailto:[email protected])
12+
- [Andrew Mohrland](mailto:[email protected])
13+
14+
[Scala Code of Conduct]: https://www.scala-lang.org/conduct/

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,4 +198,4 @@
198198
distributed under the License is distributed on an "AS IS" BASIS,
199199
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200200
See the License for the specific language governing permissions and
201-
limitations under the License.
201+
limitations under the License.

NOTICE

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
kafka4s
2+
Copyright 2019 Jack Henry & Associates, Inc.®
3+
Licensed under Apache License 2.0 (see LICENSE)

README.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,14 @@
1-
# kafka4s
2-
Functional programming with Kafka and Scala.
1+
# kafka4s - Functional programming with Kafka and Scala [![Build Status](https://travis-ci.com/banno/kafka4s.svg?branch=master)](https://travis-ci.com/banno/kafka4s) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.banno/kafka4s_2.12/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.banno/kafka4s_2.12) ![Code of Conduct](https://img.shields.io/badge/Code%20of%20Conduct-Scala-blue.svg)
2+
3+
## [Head on over to the microsite](https://banno.github.io/kafka4s)
4+
5+
## Quick Start
6+
7+
To use kafka4s in an existing SBT project with Scala 2.12 or a later version, add the following dependencies to your
8+
`build.sbt` depending on your needs:
9+
10+
```scala
11+
libraryDependencies ++= Seq(
12+
"com.banno" %% "kafka4s" % "<version>"
13+
)
14+
```

build.sbt

Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
lazy val kafka4s = project.in(file("."))
2+
.settings(commonSettings, releaseSettings, skipOnPublishSettings)
3+
.aggregate(core, docs)
4+
5+
lazy val core = project
6+
.settings(commonSettings, releaseSettings, mimaSettings)
7+
.settings(
8+
name := "kafka4s"
9+
)
10+
11+
lazy val docs = project
12+
.settings(commonSettings, skipOnPublishSettings, micrositeSettings)
13+
.dependsOn(core)
14+
.enablePlugins(MicrositesPlugin)
15+
.enablePlugins(TutPlugin)
16+
17+
lazy val contributors = Seq(
18+
"amohrland" -> "Andrew Mohrland",
19+
"zcox" -> "Zach Cox",
20+
)
21+
22+
lazy val V = new {
23+
val scala_2_12 = "2.12.8"
24+
val cats = "1.6.1"
25+
val fs2 = "1.0.5"
26+
val kafka = "2.2.1"
27+
val confluent = "5.2.2"
28+
val avro4s = "1.8.4"
29+
val log4cats = "0.3.0"
30+
}
31+
32+
lazy val commonSettings = Seq(
33+
organization := "com.banno",
34+
scalaVersion := V.scala_2_12,
35+
crossScalaVersions := Seq(V.scala_2_12),
36+
37+
publishArtifact in ThisBuild := true,
38+
39+
cancelable in Global := true,
40+
41+
scalacOptions ++= Seq(
42+
"-language:postfixOps",
43+
"-Xlog-free-terms",
44+
"-Xlog-free-types",
45+
),
46+
47+
organizationName := "Jack Henry & Associates, Inc.®",
48+
startYear := Some(2019),
49+
licenses += ("Apache-2.0", new URL("https://www.apache.org/licenses/LICENSE-2.0.txt")),
50+
51+
resolvers += "confluent" at "http://packages.confluent.io/maven/",
52+
53+
addCompilerPlugin("org.typelevel" %% "kind-projector" % "0.10.3"),
54+
addCompilerPlugin("com.olegpy" %% "better-monadic-for" % "0.3.0"),
55+
libraryDependencies ++= Seq(
56+
"co.fs2" %% "fs2-core" % V.fs2,
57+
//TODO may no longer need logging excludes for kafka-clients, need to verify
58+
"org.apache.kafka" % "kafka-clients" % V.kafka exclude("org.slf4j", "slf4j-log4j12") exclude("log4j", "log4j"),
59+
"javax.ws.rs" % "javax.ws.rs-api" % "2.1.1" artifacts Artifact("javax.ws.rs-api", "jar", "jar"), // This explicit dependency is needed for confluent (see https://github.com/sbt/sbt/issues/3618#issuecomment-413257502)
60+
"io.confluent" % "kafka-avro-serializer" % V.confluent exclude("org.slf4j", "slf4j-log4j12") exclude("log4j", "log4j") exclude("org.apache.zookeeper", "zookeeper"),
61+
"com.sksamuel.avro4s" %% "avro4s-core" % V.avro4s,
62+
"io.prometheus" % "simpleclient" % "0.6.0",
63+
"io.chrisdavenport" %% "log4cats-slf4j" % V.log4cats,
64+
"org.apache.curator" % "curator-test" % "4.2.0" % "test",
65+
"org.apache.kafka" %% "kafka" % V.kafka % "test" exclude("org.slf4j", "slf4j-log4j12") exclude("log4j", "log4j"),
66+
"org.apache.kafka" %% "kafka" % V.kafka % "test" classifier "test" exclude("org.slf4j", "slf4j-log4j12") exclude("log4j", "log4j"),
67+
"org.apache.kafka" % "kafka-clients" % V.kafka % "test" classifier "test" exclude("org.slf4j", "slf4j-log4j12") exclude("log4j", "log4j"),
68+
"io.confluent" % "kafka-schema-registry" % V.confluent % "test" exclude("org.slf4j", "slf4j-log4j12") exclude("log4j", "log4j"),
69+
"io.confluent" % "kafka-schema-registry" % V.confluent % "test" classifier "tests" exclude("org.slf4j", "slf4j-log4j12") exclude("log4j", "log4j"),
70+
"junit" % "junit" % "4.12" % "test",
71+
"ch.qos.logback" % "logback-classic" % "1.2.3" % "test",
72+
"org.slf4j" % "log4j-over-slf4j" % "1.7.26" % "test",
73+
"org.scalacheck" %% "scalacheck" % "1.14.0" % "test",
74+
"org.scalatest" %% "scalatest" % "3.0.8" % "test",
75+
"com.github.alexarchambault" %% "scalacheck-shapeless_1.14" % "1.2.3" % "test",
76+
"org.typelevel" %% "cats-laws" % V.cats % "test",
77+
"org.typelevel" %% "discipline" % "0.11.1" % "test"
78+
),
79+
sourceGenerators in Test += (avroScalaGenerate in Test).taskValue,
80+
watchSources ++= ((avroSourceDirectory in Test).value ** "*.avdl").get,
81+
testOptions in Test += Tests.Argument(TestFrameworks.ScalaTest, "-oS"),
82+
)
83+
84+
lazy val releaseSettings = {
85+
import ReleaseTransformations._
86+
Seq(
87+
releaseCrossBuild := true,
88+
releaseProcess := Seq[ReleaseStep](
89+
checkSnapshotDependencies,
90+
inquireVersions,
91+
runClean,
92+
runTest,
93+
setReleaseVersion,
94+
commitReleaseVersion,
95+
tagRelease,
96+
releaseStepCommandAndRemaining("+publishSigned"),
97+
setNextVersion,
98+
commitNextVersion,
99+
releaseStepCommand("sonatypeReleaseAll"),
100+
pushChanges
101+
),
102+
publishTo := {
103+
val nexus = "https://oss.sonatype.org/"
104+
if (isSnapshot.value)
105+
Some("snapshots" at nexus + "content/repositories/snapshots")
106+
else
107+
Some("releases" at nexus + "service/local/staging/deploy/maven2")
108+
},
109+
credentials ++= (
110+
for {
111+
username <- Option(System.getenv().get("SONATYPE_USERNAME"))
112+
password <- Option(System.getenv().get("SONATYPE_PASSWORD"))
113+
} yield
114+
Credentials(
115+
"Sonatype Nexus Repository Manager",
116+
"oss.sonatype.org",
117+
username,
118+
password
119+
)
120+
).toSeq,
121+
publishArtifact in Test := false,
122+
releasePublishArtifactsAction := PgpKeys.publishSigned.value,
123+
scmInfo := Some(
124+
ScmInfo(
125+
url("https://github.com/banno/kafka4s"),
126+
"[email protected]:banno/kafka4s.git"
127+
)
128+
),
129+
homepage := Some(url("https://github.com/banno/kafka4s")),
130+
publishMavenStyle := true,
131+
pomIncludeRepository := { _ =>
132+
false
133+
},
134+
pomExtra := {
135+
<developers>
136+
{for ((username, name) <- contributors) yield
137+
<developer>
138+
<id>{username}</id>
139+
<name>{name}</name>
140+
<url>http://github.com/{username}</url>
141+
</developer>
142+
}
143+
</developers>
144+
}
145+
)
146+
}
147+
148+
lazy val mimaSettings = {
149+
import sbtrelease.Version
150+
151+
def semverBinCompatVersions(major: Int, minor: Int, patch: Int): Set[(Int, Int, Int)] = {
152+
val majorVersions: List[Int] =
153+
if (major == 0 && minor == 0) List.empty[Int] // If 0.0.x do not check MiMa
154+
else List(major)
155+
val minorVersions : List[Int] =
156+
if (major >= 1) Range(0, minor).inclusive.toList
157+
else List(minor)
158+
def patchVersions(currentMinVersion: Int): List[Int] =
159+
if (minor == 0 && patch == 0) List.empty[Int]
160+
else if (currentMinVersion != minor) List(0)
161+
else Range(0, patch - 1).inclusive.toList
162+
163+
val versions = for {
164+
maj <- majorVersions
165+
min <- minorVersions
166+
pat <- patchVersions(min)
167+
} yield (maj, min, pat)
168+
versions.toSet
169+
}
170+
171+
def mimaVersions(version: String): Set[String] = {
172+
Version(version) match {
173+
case Some(Version(major, Seq(minor, patch), _)) =>
174+
semverBinCompatVersions(major.toInt, minor.toInt, patch.toInt)
175+
.map{case (maj, min, pat) => maj.toString + "." + min.toString + "." + pat.toString}
176+
case _ =>
177+
Set.empty[String]
178+
}
179+
}
180+
// Safety Net For Exclusions
181+
lazy val excludedVersions: Set[String] = Set()
182+
183+
// Safety Net for Inclusions
184+
lazy val extraVersions: Set[String] = Set()
185+
186+
Seq(
187+
mimaFailOnProblem := mimaVersions(version.value).toList.headOption.isDefined,
188+
mimaPreviousArtifacts := (mimaVersions(version.value) ++ extraVersions)
189+
.filterNot(excludedVersions.contains(_))
190+
.map{v =>
191+
val moduleN = moduleName.value + "_" + scalaBinaryVersion.value.toString
192+
organization.value % moduleN % v
193+
},
194+
mimaBinaryIssueFilters ++= {
195+
import com.typesafe.tools.mima.core._
196+
import com.typesafe.tools.mima.core.ProblemFilters._
197+
Seq()
198+
}
199+
)
200+
}
201+
202+
lazy val micrositeSettings = {
203+
import microsites._
204+
Seq(
205+
micrositeName := "kafka4s",
206+
micrositeDescription := "Functional programming with Kafka and Scala",
207+
micrositeAuthor := "Jack Henry & Associates, Inc.®",
208+
micrositeGithubOwner := "Banno",
209+
micrositeGithubRepo := "kafka4s",
210+
micrositeBaseUrl := "/kafka4s",
211+
micrositeDocumentationUrl := "/kafka4s/docs",
212+
micrositeFooterText := None,
213+
micrositeHighlightTheme := "atom-one-light",
214+
micrositePalette := Map(
215+
"brand-primary" -> "#3e5b95",
216+
"brand-secondary" -> "#294066",
217+
"brand-tertiary" -> "#2d5799",
218+
"gray-dark" -> "#49494B",
219+
"gray" -> "#7B7B7E",
220+
"gray-light" -> "#E5E5E6",
221+
"gray-lighter" -> "#F4F3F4",
222+
"white-color" -> "#FFFFFF"
223+
),
224+
fork in tut := true,
225+
scalacOptions in Tut --= Seq(
226+
"-Xfatal-warnings",
227+
"-Ywarn-unused-import",
228+
"-Ywarn-numeric-widen",
229+
"-Ywarn-dead-code",
230+
"-Ywarn-unused:imports",
231+
"-Xlint:-missing-interpolator,_"
232+
),
233+
libraryDependencies += "com.47deg" %% "github4s" % "0.20.1",
234+
micrositePushSiteWith := GitHub4s,
235+
micrositeGithubToken := sys.env.get("GITHUB_TOKEN"),
236+
micrositeExtraMdFiles := Map(
237+
file("CHANGELOG.md") -> ExtraMdFileConfig("changelog.md", "page", Map("title" -> "changelog", "section" -> "changelog", "position" -> "100")),
238+
file("CODE_OF_CONDUCT.md") -> ExtraMdFileConfig("code-of-conduct.md", "page", Map("title" -> "code of conduct", "section" -> "code of conduct", "position" -> "101")),
239+
file("LICENSE") -> ExtraMdFileConfig("license.md", "page", Map("title" -> "license", "section" -> "license", "position" -> "102"))
240+
)
241+
)
242+
}
243+
244+
lazy val skipOnPublishSettings = Seq(
245+
skip in publish := true,
246+
publish := (()),
247+
publishLocal := (()),
248+
publishArtifact := false,
249+
publishTo := None
250+
)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright 2019 Jack Henry & Associates, Inc.®
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.banno.kafka
18+
19+
import org.apache.kafka.common.TopicPartition
20+
import org.apache.kafka.clients.consumer.OffsetAndMetadata
21+
22+
case class TopicPartitionOffset(topic: String, partition: Int, offset: Long)
23+
object TopicPartitionOffset {
24+
implicit def toMap(o: TopicPartitionOffset): Map[TopicPartition, OffsetAndMetadata] =
25+
Map(new TopicPartition(o.topic, o.partition) -> new OffsetAndMetadata(o.offset))
26+
}

0 commit comments

Comments
 (0)