Skip to content

Commit b8678c5

Browse files
authored
Scala3 support (#974)
- Add scala3 to all project cross versions, but mongodb. - Mongodb does will not support scala3 due to its extensive use of macros. It won't be supported until the scala-mongodb-driver and bson libraries are released for scala3. - Mockito is used for unit testing in a few monix connectors, so we have kept them in a separate package for scala-2.x.x. - Pureconfig major update, which drops macros usage by manual config reader implementation. - Add Scala3 to github-ci matrix.
1 parent b05513e commit b8678c5

File tree

132 files changed

+1099
-3193
lines changed

Some content is hidden

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

132 files changed

+1099
-3193
lines changed

.github/scripts/release.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
#!/usr/bin/env bash
22

33
set -e
4-
sbt ++2.13.8 ci-release
4+
sbt ++3.1.2 ci-release

.github/workflows/build.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,14 @@ jobs:
1616
fail-fast: false
1717
matrix:
1818
java: [8, 11]
19-
scala: [2.12.11, 2.13.1]
19+
scala: [2.12.17, 2.13.8, 3.1.2]
2020
exclude:
2121
- java: 8
2222
scala: 2.13.1
23+
- java: 8
24+
scala: 3.1.2
2325
- java: 11
24-
scala: 2.12.11
26+
scala: 2.12.17
2527
steps:
2628
- uses: actions/checkout@v2
2729
- uses: olafurpg/setup-scala@v10
@@ -50,7 +52,7 @@ jobs:
5052
run: sh start-dependencies.sh
5153

5254
- name: Run Functional Tests for Java ${{ matrix.java }}, Scala ${{ matrix.scala }}
53-
run: sbt it:test
55+
run: sbt ++${{ matrix.scala }} it:test
5456

5557
- name: Run Unit Tests for Java ${{ matrix.java }}, Scala ${{ matrix.scala }}
5658
run: sbt test

aws-auth/src/main/resources/reference.conf

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ monix_aws: {
6969

7070
// Pascal case fallback
7171
MonixAws: {
72-
credentials {
73-
provider: "default"
72+
Credentials {
73+
Provider: "default"
7474
}
75-
region: "eu-west-1"
75+
Region: "eu-west-1"
7676
}

aws-auth/src/main/scala/monix/connect.aws.auth/MonixAwsConf.scala

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,16 @@
1717

1818
package monix.connect.aws.auth
1919

20+
import monix.connect.aws.auth.configreader.{
21+
CamelCaseConfigReader,
22+
KebabConfigReader,
23+
PascalConfigReader,
24+
SnakeCaseConfigReader
25+
}
2026
import monix.eval.Task
2127
import software.amazon.awssdk.regions.Region
22-
import pureconfig._
23-
import pureconfig.error.{ConfigReaderException, ConfigReaderFailures}
24-
import pureconfig.generic.ProductHint
25-
import pureconfig.generic.auto._
28+
import pureconfig.{NamingConvention, _}
29+
import pureconfig.error.ConfigReaderFailures
2630
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider
2731

2832
import java.io.File
@@ -72,13 +76,16 @@ object MonixAwsConf {
7276

7377
private[auth] final case class AppConf(monixAws: MonixAwsConf)
7478

75-
implicit val credentialsProviderReader: ConfigReader[AwsCredentialsProvider] =
76-
ConfigReader[AwsCredentialsConf].map(_.credentialsProvider)
77-
implicit val providerReader: ConfigReader[Providers.Provider] = ConfigReader[String].map(Providers.fromString)
78-
implicit val regionReader: ConfigReader[Region] = ConfigReader[String].map(Region.of)
79-
implicit val uriReader: ConfigReader[URI] = ConfigReader[String].map(URI.create)
80-
val customHint: NamingConvention => ProductHint[AppConf] = namingConvention =>
81-
ProductHint(ConfigFieldMapping(CamelCase, namingConvention), useDefaultArgs = false, allowUnknownKeys = true)
79+
private def withConfigReader[A](namingConvention: NamingConvention)(f: ConfigReader[AppConf] => Task[A]): Task[A] = {
80+
val derivedConfigReaderTask = namingConvention match {
81+
case CamelCase => Task.pure(CamelCaseConfigReader.appConfConfigReader)
82+
case SnakeCase => Task.pure(SnakeCaseConfigReader.appConfConfigReader)
83+
case PascalCase => Task.pure(PascalConfigReader.appConfConfigReader)
84+
case KebabCase => Task.pure(KebabConfigReader.appConfConfigReader)
85+
case _ => Task.raiseError(new IllegalArgumentException(s"Naming convention $namingConvention not supported."))
86+
}
87+
derivedConfigReaderTask.flatMap(f)
88+
}
8289

8390
/**
8491
* Loads the aws auth configuration from the config file with the specified naming
@@ -91,10 +98,13 @@ object MonixAwsConf {
9198
*
9299
*/
93100
def load(namingConvention: NamingConvention = KebabCase): Task[MonixAwsConf] = {
94-
implicit val hint: ProductHint[AppConf] = customHint(namingConvention)
95-
Task
96-
.fromEither[ConfigReaderFailures, AppConf] { ConfigReaderException(_) }(ConfigSource.default.load[AppConf])
97-
.map(_.monixAws)
101+
withConfigReader(namingConvention) { configReader =>
102+
Task
103+
.fromEither[ConfigReaderFailures, AppConf] { ex =>
104+
new IllegalArgumentException(s"Cannot convert configuration to class, failures are: ${ex.prettyPrint(1)}")
105+
}(ConfigSource.default.load[AppConf](configReader))
106+
.map(_.monixAws)
107+
}
98108
}
99109

100110
/**
@@ -108,10 +118,13 @@ object MonixAwsConf {
108118
*
109119
*/
110120
def file(file: File, namingConvention: NamingConvention = KebabCase): Task[MonixAwsConf] = {
111-
implicit val hint: ProductHint[AppConf] = customHint(namingConvention)
112-
Task
113-
.fromEither[ConfigReaderFailures, AppConf] { ConfigReaderException(_) }(ConfigSource.file(file).load[AppConf])
114-
.map(_.monixAws)
121+
withConfigReader(namingConvention) { configReader =>
122+
Task
123+
.fromEither[ConfigReaderFailures, AppConf] { ex =>
124+
new IllegalArgumentException(s"Cannot convert configuration to class, failures are: ${ex.prettyPrint(1)}")
125+
}(ConfigSource.file(file).load[AppConf](configReader))
126+
.map(_.monixAws)
127+
}
115128
}
116129

117130
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright (c) 2020-2021 by The Monix Connect Project Developers.
3+
* See the project homepage at: https://connect.monix.io
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package monix.connect.aws.auth.configreader
19+
20+
import monix.connect.aws.auth.MonixAwsConf.AppConf
21+
import monix.connect.aws.auth.{AwsCredentialsConf, HttpClientConf, MonixAwsConf, StaticCredentialsConf}
22+
import pureconfig.ConfigReader
23+
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider
24+
25+
private[auth] trait BaseConfigReader {
26+
27+
def cased(sequence: String*): String
28+
private[auth] implicit val staticCreedsConfConfigReader: ConfigReader[StaticCredentialsConf] =
29+
ConfigReader.forProduct3(cased("access", "key", "id"), cased("secret", "access", "key"), cased("session", "token"))(
30+
StaticCredentialsConf(_, _, _))
31+
private[auth] implicit val awsCredentialsConfConfigReader: ConfigReader[AwsCredentialsConf] =
32+
ConfigReader.forProduct3(cased("provider"), cased("profile", "name"), cased("static"))(AwsCredentialsConf(_, _, _))
33+
private[auth] implicit val credentialsProviderReader: ConfigReader[AwsCredentialsProvider] =
34+
ConfigReader[AwsCredentialsConf].map(_.credentialsProvider)
35+
private[auth] implicit val httpClientConfConfigReader: ConfigReader[HttpClientConf] = ConfigReader.forProduct8(
36+
cased("max", "concurrency"),
37+
cased("max", "pending", "connection", "acquires"),
38+
cased("connection", "acquisition", "timeout"),
39+
cased("connection", "max", "idle", "time"),
40+
cased("connection", "time", "to", "live"),
41+
cased("use", "idle", "connection", "reaper"),
42+
cased("read", "timeout"),
43+
cased("write", "timeout")
44+
)(HttpClientConf(_, _, _, _, _, _, _, _))
45+
private[auth] implicit val monixAwsConfConfigReader: ConfigReader[MonixAwsConf] =
46+
ConfigReader.forProduct4(cased("region"), cased("credentials"), cased("endpoint"), cased("http", "client"))(
47+
MonixAwsConf(_, _, _, _))
48+
private[auth] implicit val appConfConfigReader: ConfigReader[AppConf] =
49+
ConfigReader.forProduct1(cased("monix", "aws"))(AppConf(_))
50+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright (c) 2020-2021 by The Monix Connect Project Developers.
3+
* See the project homepage at: https://connect.monix.io
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package monix.connect.aws.auth.configreader
19+
20+
import pureconfig.CamelCase
21+
22+
private[auth] object CamelCaseConfigReader extends BaseConfigReader {
23+
override def cased(sequence: String*): String = CamelCase.fromTokens(sequence)
24+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright (c) 2020-2021 by The Monix Connect Project Developers.
3+
* See the project homepage at: https://connect.monix.io
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package monix.connect.aws.auth.configreader
19+
20+
import pureconfig.KebabCase
21+
22+
private[auth] object KebabConfigReader extends BaseConfigReader {
23+
override def cased(sequence: String*): String = KebabCase.fromTokens(sequence)
24+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright (c) 2020-2021 by The Monix Connect Project Developers.
3+
* See the project homepage at: https://connect.monix.io
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package monix.connect.aws.auth.configreader
19+
20+
import pureconfig.PascalCase
21+
22+
private[auth] object PascalConfigReader extends BaseConfigReader {
23+
override def cased(sequence: String*): String = PascalCase.fromTokens(sequence)
24+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright (c) 2020-2021 by The Monix Connect Project Developers.
3+
* See the project homepage at: https://connect.monix.io
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package monix.connect.aws.auth.configreader
19+
20+
import pureconfig.SnakeCase
21+
22+
private[auth] object SnakeCaseConfigReader extends BaseConfigReader {
23+
override def cased(sequence: String*): String = SnakeCase.fromTokens(sequence)
24+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright (c) 2020-2021 by The Monix Connect Project Developers.
3+
* See the project homepage at: https://connect.monix.io
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package monix.connect.aws.auth
19+
20+
import pureconfig.ConfigReader
21+
import software.amazon.awssdk.regions.Region
22+
23+
import java.net.URI
24+
25+
package object configreader {
26+
27+
private[configreader] implicit val providerReader: ConfigReader[Providers.Provider] =
28+
ConfigReader[String].map(Providers.fromString)
29+
private[configreader] implicit val regionReader: ConfigReader[Region] = ConfigReader[String].map(Region.of)
30+
private[configreader] implicit val uriReader: ConfigReader[URI] = ConfigReader[String].map(URI.create)
31+
32+
}

0 commit comments

Comments
 (0)