Skip to content

Commit e2034e9

Browse files
Adding Salesforce tests (#48)
Co-authored-by: Benjamin Gaidioz <[email protected]>
1 parent 0884d6b commit e2034e9

File tree

6 files changed

+284
-77
lines changed

6 files changed

+284
-77
lines changed

.github/workflows/ci.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,4 @@ jobs:
3333
options: --user 1001:1001
3434
steps:
3535
- uses: actions/checkout@v4
36-
- run: sbt clean test
36+
- run: sbt clean compile Test/compile

README.md

+10-9
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,16 @@
55

66
## Options
77

8-
| Name | Description | Default | Required |
9-
|-----------------------|-----------------------------------|---------|----------|
10-
| `api_version` | Salesforce API version | | Yes |
11-
| `username` | Salesforce username | | Yes |
12-
| `password` | Salesforce password | | Yes |
13-
| `security_token` | Salesforce security token | | Yes |
14-
| `client_id` | Salesforce client id | | Yes |
15-
| `url` | Salesforce URL | | Yes |
16-
| `add_dynamic_columns` | Add dynamic columns to the schema | `true` | No |
8+
| Name | Description | Default | Required |
9+
|-----------------------|----------------------------------------------|---------|----------|
10+
| `api_version` | Salesforce API version | | Yes |
11+
| `username` | Salesforce username | | Yes |
12+
| `password` | Salesforce password | | Yes |
13+
| `security_token` | Salesforce security token | | Yes |
14+
| `client_id` | Salesforce client id | | Yes |
15+
| `url` | Salesforce URL | | Yes |
16+
| `add_dynamic_columns` | Add dynamic columns to the schema | `true` | No |
17+
| `dynamic_objects` | List of dynamic objects to add to the schema | | No |
1718

1819
## How to use
1920

build.sbt

+32-60
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
import com.typesafe.sbt.packager.docker.{Cmd, LayeredMapping}
1+
import java.nio.file.Paths
2+
23
import sbt.*
34
import sbt.Keys.*
45

5-
import java.nio.file.Paths
6+
import com.typesafe.sbt.packager.docker.{Cmd, LayeredMapping}
67

78
ThisBuild / credentials += Credentials(
89
"GitHub Package Registry",
910
"maven.pkg.github.com",
1011
"raw-labs",
11-
sys.env.getOrElse("GITHUB_TOKEN", "")
12-
)
12+
sys.env.getOrElse("GITHUB_TOKEN", ""))
1313

1414
lazy val commonSettings = Seq(
1515
homepage := Some(url("https://www.raw-labs.com/")),
@@ -19,17 +19,11 @@ lazy val commonSettings = Seq(
1919
// Use cached resolution of dependencies
2020
// http://www.scala-sbt.org/0.13/docs/Cached-Resolution.html
2121
updateOptions := updateOptions.in(Global).value.withCachedResolution(true),
22-
resolvers += "RAW Labs GitHub Packages" at "https://maven.pkg.github.com/raw-labs/_"
23-
)
22+
resolvers += "RAW Labs GitHub Packages" at "https://maven.pkg.github.com/raw-labs/_")
2423

2524
lazy val buildSettings = Seq(
2625
scalaVersion := "2.13.15",
27-
javacOptions ++= Seq(
28-
"-source",
29-
"21",
30-
"-target",
31-
"21"
32-
),
26+
javacOptions ++= Seq("-source", "21", "-target", "21"),
3327
scalacOptions ++= Seq(
3428
"-feature",
3529
"-unchecked",
@@ -38,27 +32,23 @@ lazy val buildSettings = Seq(
3832
"-Ywarn-dead-code",
3933
"-Ywarn-macros:after", // Fix for false warning of unused implicit arguments in traits/interfaces.
4034
"-Ypatmat-exhaust-depth",
41-
"160"
42-
)
43-
)
35+
"160"))
4436

4537
lazy val compileSettings = Seq(
4638
Compile / doc / sources := Seq.empty,
4739
Compile / packageDoc / mappings := Seq(),
4840
Compile / packageSrc / publishArtifact := true,
4941
Compile / packageDoc / publishArtifact := false,
5042
Compile / packageBin / packageOptions += Package.ManifestAttributes(
51-
"Automatic-Module-Name" -> name.value.replace('-', '.')
52-
),
43+
"Automatic-Module-Name" -> name.value.replace('-', '.')),
5344
// Ensure Java annotations get compiled first, so that they are accessible from Scala.
54-
compileOrder := CompileOrder.JavaThenScala
55-
)
45+
compileOrder := CompileOrder.JavaThenScala)
5646

5747
lazy val testSettings = Seq(
5848
// Ensuring tests are run in a forked JVM for isolation.
5949
Test / fork := true,
6050
// Disabling parallel execution of tests.
61-
//Test / parallelExecution := false,
51+
// Test / parallelExecution := false,
6252
// Pass system properties starting with "raw." to the forked JVMs.
6353
Test / javaOptions ++= {
6454
import scala.collection.JavaConverters.*
@@ -73,10 +63,8 @@ lazy val testSettings = Seq(
7363
// Set up heap dump options for out-of-memory errors.
7464
Test / javaOptions ++= Seq(
7565
"-XX:+HeapDumpOnOutOfMemoryError",
76-
s"-XX:HeapDumpPath=${Paths.get(sys.env.getOrElse("SBT_FORK_OUTPUT_DIR", "target/test-results")).resolve("heap-dumps")}"
77-
),
78-
Test / publishArtifact := true
79-
)
66+
s"-XX:HeapDumpPath=${Paths.get(sys.env.getOrElse("SBT_FORK_OUTPUT_DIR", "target/test-results")).resolve("heap-dumps")}"),
67+
Test / publishArtifact := true)
8068

8169
val isCI = sys.env.getOrElse("CI", "false").toBoolean
8270

@@ -85,31 +73,28 @@ lazy val publishSettings = Seq(
8573
publish / skip := false,
8674
publishMavenStyle := true,
8775
publishTo := Some("GitHub raw-labs Apache Maven Packages" at "https://maven.pkg.github.com/raw-labs/das-salesforce"),
88-
publishConfiguration := publishConfiguration.value.withOverwrite(isCI)
89-
)
76+
publishConfiguration := publishConfiguration.value.withOverwrite(isCI))
9077

91-
lazy val strictBuildSettings = commonSettings ++ compileSettings ++ buildSettings ++ testSettings ++ Seq(
92-
scalacOptions ++= Seq(
93-
"-Xfatal-warnings"
94-
)
95-
)
78+
lazy val strictBuildSettings =
79+
commonSettings ++ compileSettings ++ buildSettings ++ testSettings ++ Seq(scalacOptions ++= Seq("-Xfatal-warnings"))
9680

9781
lazy val root = (project in file("."))
9882
.settings(
9983
name := "das-salesforce",
10084
strictBuildSettings,
10185
publishSettings,
10286
libraryDependencies ++= Seq(
87+
// DAS
10388
"com.raw-labs" %% "das-server-scala" % "0.4.1" % "compile->compile;test->test",
10489
"com.raw-labs" %% "protocol-das" % "1.0.0" % "compile->compile;test->test",
90+
// Salesforce client
10591
"com.frejo" % "force-rest-api" % "0.0.45",
92+
// Jackson
10693
"joda-time" % "joda-time" % "2.12.7",
10794
"com.fasterxml.jackson.datatype" % "jackson-datatype-jsr310" % "2.18.2",
10895
"com.fasterxml.jackson.datatype" % "jackson-datatype-jdk8" % "2.18.2",
10996
"com.fasterxml.jackson.datatype" % "jackson-datatype-joda" % "2.18.2",
110-
"com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.18.2"
111-
)
112-
)
97+
"com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.18.2"))
11398

11499
val amzn_jdk_version = "21.0.4.7-1"
115100
val amzn_corretto_bin = s"java-21-amazon-corretto-jdk_${amzn_jdk_version}_amd64.deb"
@@ -122,17 +107,16 @@ lazy val dockerSettings = strictBuildSettings ++ Seq(
122107
"vendor" -> "RAW Labs SA",
123108
"product" -> "das-salesforce-server",
124109
"image-type" -> "final",
125-
"org.opencontainers.image.source" -> "https://github.com/raw-labs/das-salesforce"
126-
),
110+
"org.opencontainers.image.source" -> "https://github.com/raw-labs/das-salesforce"),
127111
Docker / daemonUser := "raw",
128112
dockerExposedVolumes := Seq("/var/log/raw"),
129113
dockerExposedPorts := Seq(50051),
130114
dockerEnvVars := Map("PATH" -> s"${(Docker / defaultLinuxInstallLocation).value}/bin:$$PATH"),
131115
// We remove the automatic switch to USER 1001:0.
132116
// We we want to run as root to install the JDK, also later we will switch to a non-root user.
133117
dockerCommands := dockerCommands.value.filterNot {
134-
case Cmd("USER", args@_*) => args.contains("1001:0")
135-
case cmd => false
118+
case Cmd("USER", args @ _*) => args.contains("1001:0")
119+
case cmd => false
136120
},
137121
dockerCommands ++= Seq(
138122
Cmd(
@@ -145,13 +129,8 @@ lazy val dockerSettings = strictBuildSettings ++ Seq(
145129
&& dpkg --install $amzn_corretto_bin \\
146130
&& rm -f $amzn_corretto_bin \\
147131
&& apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \\
148-
wget gnupg software-properties-common"""
149-
),
150-
Cmd(
151-
"USER",
152-
"raw"
153-
)
154-
),
132+
wget gnupg software-properties-common"""),
133+
Cmd("USER", "raw")),
155134
dockerEnvVars += "LANG" -> "C.UTF-8",
156135
dockerEnvVars += "JAVA_HOME" -> "/usr/lib/jvm/java-21-amazon-corretto",
157136
Compile / doc / sources := Seq.empty, // Do not generate scaladocs
@@ -165,11 +144,11 @@ lazy val dockerSettings = strictBuildSettings ++ Seq(
165144
case ClasspathPattern(classpath) => s"""
166145
|declare -r app_classpath="$${app_home}/../conf:$classpath"
167146
|""".stripMargin
168-
case _@entry => entry
147+
case _ @entry => entry
169148
}
170149
},
171150
Docker / dockerLayerMappings := (Docker / dockerLayerMappings).value.map {
172-
case lm@LayeredMapping(Some(1), file, path) => {
151+
case lm @ LayeredMapping(Some(1), file, path) => {
173152
val fileName = java.nio.file.Paths.get(path).getFileName.toString
174153
if (!fileName.endsWith(".jar")) {
175154
// If it is not a jar, put it on the top layer. Configuration files and other small files.
@@ -182,7 +161,7 @@ lazy val dockerSettings = strictBuildSettings ++ Seq(
182161
lm
183162
}
184163
}
185-
case lm@_ => lm
164+
case lm @ _ => lm
186165
},
187166
Compile / mainClass := Some("com.rawlabs.das.server.DASServer"),
188167
Docker / dockerAutoremoveMultiStageIntermediateImages := false,
@@ -193,22 +172,15 @@ lazy val dockerSettings = strictBuildSettings ++ Seq(
193172
val baseAlias = dockerAlias.value.withRegistryHost(Some(devRegistry))
194173

195174
releaseRegistry match {
196-
case Some(releaseReg) => Seq(
197-
baseAlias,
198-
dockerAlias.value.withRegistryHost(Some(releaseReg))
199-
)
200-
case None => Seq(baseAlias)
175+
case Some(releaseReg) => Seq(baseAlias, dockerAlias.value.withRegistryHost(Some(releaseReg)))
176+
case None => Seq(baseAlias)
201177
}
202-
}
203-
)
178+
})
204179

205180
lazy val docker = (project in file("docker"))
206-
.dependsOn(
207-
root % "compile->compile;test->test"
208-
)
181+
.dependsOn(root % "compile->compile;test->test")
209182
.enablePlugins(JavaAppPackaging, DockerPlugin)
210183
.settings(
211184
strictBuildSettings,
212185
dockerSettings,
213-
libraryDependencies += "com.raw-labs" %% "das-server-scala" % "0.4.1" % "compile->compile;test->test"
214-
)
186+
libraryDependencies += "com.raw-labs" %% "das-server-scala" % "0.4.1" % "compile->compile;test->test")

project/plugins.sbt

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ libraryDependencies += "commons-io" % "commons-io" % "2.11.0"
88

99
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.0")
1010

11+
addSbtPlugin("nl.gn0s1s" % "sbt-dotenv" % "3.1.1")
12+
1113
addSbtPlugin("com.github.sbt" % "sbt-native-packager" % "1.10.4")
1214

1315
addSbtPlugin("de.heikoseeberger" % "sbt-header" % "5.10.0")

src/main/scala/com/rawlabs/das/salesforce/DASSalesforceConnector.scala

+20-7
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,26 @@ class DASSalesforceConnector(options: Map[String, String]) extends StrictLogging
3636
registerModule(DefaultScalaModule)
3737
}
3838

39-
private val apiConfig = new ApiConfig()
40-
.setApiVersionString(options("api_version"))
41-
.setUsername(options("username"))
42-
.setPassword(options("password") + options("security_token"))
43-
.setClientId(options("client_id"))
44-
.setForceURL(options("url"))
45-
.setObjectMapper(jsonMapper)
39+
private val apiVersion = {
40+
val v = options.getOrElse("api_version", throw new DASSdkInvalidArgumentException("api_version is required"))
41+
if (v.startsWith("v")) v else s"v$v"
42+
}
43+
44+
private val apiConfig = {
45+
val userName = options.getOrElse("username", throw new DASSdkInvalidArgumentException("username is required"))
46+
val password = options.getOrElse("password", throw new DASSdkInvalidArgumentException("password is required"))
47+
val securityToken =
48+
options.getOrElse("security_token", throw new DASSdkInvalidArgumentException("security_token is required"))
49+
val clientId = options.getOrElse("client_id", throw new DASSdkInvalidArgumentException("client_id is required"))
50+
val url = options.getOrElse("url", throw new DASSdkInvalidArgumentException("url is required"))
51+
new ApiConfig()
52+
.setApiVersionString(apiVersion)
53+
.setUsername(userName)
54+
.setPassword(password + securityToken)
55+
.setClientId(clientId)
56+
.setForceURL(url)
57+
.setObjectMapper(jsonMapper)
58+
}
4659

4760
private val forceApi: ForceApi =
4861
withSalesforceException {

0 commit comments

Comments
 (0)