diff --git a/testing-modules/load-testing-comparison/pom.xml b/testing-modules/load-testing-comparison/pom.xml
new file mode 100644
index 0000000000..869eda1bb5
--- /dev/null
+++ b/testing-modules/load-testing-comparison/pom.xml
@@ -0,0 +1,148 @@
+
+
+
+ parent-modules
+ com.baeldung
+ 1.0.0-SNAPSHOT
+ ../../pom.xml
+
+ 4.0.0
+
+ load-testing-bakeoff
+
+
+ 1.8
+ 1.8
+ UTF-8
+ 2.11.12
+ 2.2.5
+ 3.2.2
+ 2.2.1
+ 5.0
+ 3.11
+ 2.0.5.RELEASE
+
+
+
+
+ io.gatling
+ gatling-app
+ ${gatling.version}
+
+
+ io.gatling
+ gatling-recorder
+ ${gatling.version}
+
+
+ io.gatling.highcharts
+ gatling-charts-highcharts
+ ${gatling.version}
+
+
+ org.scala-lang
+ scala-library
+ ${scala.version}
+
+
+
+
+
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ 2.9.4
+
+
+ org.springframework.boot
+ spring-boot-starter
+ ${spring.boot.version}
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+ ${spring.boot.version}
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+ ${spring.boot.version}
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ ${spring.boot.version}
+ test
+
+
+ com.h2database
+ h2
+ 1.4.197
+
+
+ org.projectlombok
+ lombok
+ 1.18.2
+ compile
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ 2.0.5.RELEASE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/testing-modules/load-testing-comparison/src/main/java/com/baeldung/loadtesting/Application.java b/testing-modules/load-testing-comparison/src/main/java/com/baeldung/loadtesting/Application.java
new file mode 100644
index 0000000000..6647bcb640
--- /dev/null
+++ b/testing-modules/load-testing-comparison/src/main/java/com/baeldung/loadtesting/Application.java
@@ -0,0 +1,12 @@
+package com.baeldung.loadtesting;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class Application {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+}
diff --git a/testing-modules/load-testing-comparison/src/main/java/com/baeldung/loadtesting/RewardsController.java b/testing-modules/load-testing-comparison/src/main/java/com/baeldung/loadtesting/RewardsController.java
new file mode 100644
index 0000000000..50cc6fb7ab
--- /dev/null
+++ b/testing-modules/load-testing-comparison/src/main/java/com/baeldung/loadtesting/RewardsController.java
@@ -0,0 +1,51 @@
+package com.baeldung.loadtesting;
+
+import com.baeldung.loadtesting.model.CustomerRewardsAccount;
+import com.baeldung.loadtesting.model.Transaction;
+import com.baeldung.loadtesting.repository.CustomerRewardsRepository;
+import com.baeldung.loadtesting.repository.TransactionRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Calendar;
+import java.util.List;
+import java.util.Optional;
+
+@RestController
+public class RewardsController {
+
+ @Autowired
+ private CustomerRewardsRepository customerRewardsRepository;
+
+ @Autowired
+ private TransactionRepository transactionRepository;
+
+ @PostMapping(path="/transactions/add")
+ public @ResponseBody Transaction saveTransactions(@RequestBody Transaction trnsctn){
+ trnsctn.setTransactionDate(Calendar.getInstance().getTime());
+ Transaction result = transactionRepository.save(trnsctn);
+ return result;
+ }
+
+ @GetMapping(path="/transactions/findAll/{rewardId}")
+ public @ResponseBody Iterable getTransactions(@PathVariable Integer rewardId){
+ return transactionRepository.findByCustomerRewardsId(rewardId);
+ }
+
+ @PostMapping(path="/rewards/add")
+ public @ResponseBody CustomerRewardsAccount addRewardsAcount(@RequestBody CustomerRewardsAccount body) {
+ Optional acct = customerRewardsRepository.findByCustomerId(body.getCustomerId());
+ return !acct.isPresent() ? customerRewardsRepository.save(body) : acct.get();
+ }
+
+ @GetMapping(path="/rewards/find/{customerId}")
+ public @ResponseBody
+ Optional find(@PathVariable Integer customerId) {
+ return customerRewardsRepository.findByCustomerId(customerId);
+ }
+
+ @GetMapping(path="/rewards/all")
+ public @ResponseBody List findAll() {
+ return customerRewardsRepository.findAll();
+ }
+}
diff --git a/testing-modules/load-testing-comparison/src/main/java/com/baeldung/loadtesting/TransactionController.java b/testing-modules/load-testing-comparison/src/main/java/com/baeldung/loadtesting/TransactionController.java
new file mode 100644
index 0000000000..2ea2c06a41
--- /dev/null
+++ b/testing-modules/load-testing-comparison/src/main/java/com/baeldung/loadtesting/TransactionController.java
@@ -0,0 +1,26 @@
+package com.baeldung.loadtesting;
+
+import com.baeldung.loadtesting.model.Transaction;
+import com.baeldung.loadtesting.repository.TransactionRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@Deprecated
+public class TransactionController {
+
+ @Autowired
+ private TransactionRepository transactionRepository;
+
+ @PostMapping(path="/addTransaction")
+ public @ResponseBody
+ String saveTransactions(@RequestBody Transaction trnsctn){
+ transactionRepository.save(trnsctn);
+ return "Saved Transaction.";
+ }
+
+ @GetMapping(path="/findAll/{rewardId}")
+ public @ResponseBody Iterable getTransactions(@RequestParam Integer id){
+ return transactionRepository.findByCustomerRewardsId(id);
+ }
+}
diff --git a/testing-modules/load-testing-comparison/src/main/java/com/baeldung/loadtesting/model/CustomerRewardsAccount.java b/testing-modules/load-testing-comparison/src/main/java/com/baeldung/loadtesting/model/CustomerRewardsAccount.java
new file mode 100644
index 0000000000..2c6742fbaf
--- /dev/null
+++ b/testing-modules/load-testing-comparison/src/main/java/com/baeldung/loadtesting/model/CustomerRewardsAccount.java
@@ -0,0 +1,22 @@
+package com.baeldung.loadtesting.model;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+
+import lombok.Data;
+
+@Entity
+@Data
+public class CustomerRewardsAccount {
+
+ @Id
+ @GeneratedValue(strategy= GenerationType.AUTO)
+ private Integer id;
+ private Integer customerId;
+
+ public Integer getCustomerId(){
+ return this.customerId;
+ }
+}
diff --git a/testing-modules/load-testing-comparison/src/main/java/com/baeldung/loadtesting/model/Transaction.java b/testing-modules/load-testing-comparison/src/main/java/com/baeldung/loadtesting/model/Transaction.java
new file mode 100644
index 0000000000..312f52f4ab
--- /dev/null
+++ b/testing-modules/load-testing-comparison/src/main/java/com/baeldung/loadtesting/model/Transaction.java
@@ -0,0 +1,30 @@
+package com.baeldung.loadtesting.model;
+
+import lombok.Data;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import java.util.Date;
+import java.util.Calendar;
+
+@Entity
+@Data
+public class Transaction {
+
+ @Id
+ @GeneratedValue(strategy= GenerationType.AUTO)
+ private Integer id;
+ private Integer customerRewardsId;
+ private Integer customerId;
+ private Date transactionDate;
+
+ public Transaction(){
+ transactionDate = Calendar.getInstance().getTime();
+ }
+
+ public void setTransactionDate(Date transactionDate){
+ this.transactionDate = transactionDate;
+ }
+}
diff --git a/testing-modules/load-testing-comparison/src/main/java/com/baeldung/loadtesting/repository/CustomerRewardsRepository.java b/testing-modules/load-testing-comparison/src/main/java/com/baeldung/loadtesting/repository/CustomerRewardsRepository.java
new file mode 100644
index 0000000000..f945359eb8
--- /dev/null
+++ b/testing-modules/load-testing-comparison/src/main/java/com/baeldung/loadtesting/repository/CustomerRewardsRepository.java
@@ -0,0 +1,11 @@
+package com.baeldung.loadtesting.repository;
+
+import com.baeldung.loadtesting.model.CustomerRewardsAccount;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.Optional;
+
+public interface CustomerRewardsRepository extends JpaRepository {
+
+ Optional findByCustomerId(Integer customerId);
+}
diff --git a/testing-modules/load-testing-comparison/src/main/java/com/baeldung/loadtesting/repository/TransactionRepository.java b/testing-modules/load-testing-comparison/src/main/java/com/baeldung/loadtesting/repository/TransactionRepository.java
new file mode 100644
index 0000000000..af0b343c10
--- /dev/null
+++ b/testing-modules/load-testing-comparison/src/main/java/com/baeldung/loadtesting/repository/TransactionRepository.java
@@ -0,0 +1,11 @@
+package com.baeldung.loadtesting.repository;
+
+import com.baeldung.loadtesting.model.Transaction;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+
+public interface TransactionRepository extends JpaRepository {
+
+ List findByCustomerRewardsId(Integer rewardsId);
+}
diff --git a/testing-modules/load-testing-comparison/src/main/resources/scripts/Gatling/GatlingScenario.scala b/testing-modules/load-testing-comparison/src/main/resources/scripts/Gatling/GatlingScenario.scala
new file mode 100644
index 0000000000..f9b3837759
--- /dev/null
+++ b/testing-modules/load-testing-comparison/src/main/resources/scripts/Gatling/GatlingScenario.scala
@@ -0,0 +1,52 @@
+package com.baeldung
+
+import scala.util._
+import io.gatling.core.Predef._
+import io.gatling.http.Predef._
+import scala.concurrent.duration._
+
+class RewardsScenario extends Simulation {
+
+ def randCustId() = Random.nextInt(99)
+
+ val httpProtocol = http.baseUrl("http://localhost:8080")
+ .acceptHeader("text/html,application/json;q=0.9,*/*;q=0.8")
+ .doNotTrackHeader("1")
+ .acceptLanguageHeader("en-US,en;q=0.5")
+ .acceptEncodingHeader("gzip, deflate")
+ .userAgentHeader("Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Firefox/31.0")
+
+ val scn = scenario("RewardsScenario")
+ .repeat(10){
+ exec(http("transactions_add")
+ .post("/transactions/add/")
+ .body(StringBody("""{ "customerRewardsId":null,"customerId":""""+ randCustId() + """","transactionDate":null }""")).asJson
+ .check(jsonPath("$.id").saveAs("txnId"))
+ .check(jsonPath("$.transactionDate").saveAs("txtDate"))
+ .check(jsonPath("$.customerId").saveAs("custId")))
+ .pause(1)
+
+ .exec(http("get_reward")
+ .get("/rewards/find/${custId}")
+ .check(jsonPath("$.id").saveAs("rwdId")))
+ .pause(1)
+
+ .doIf("${rwdId.isUndefined()}"){
+ exec(http("rewards_add")
+ .post("/rewards/add")
+ .body(StringBody("""{ "customerId": "${custId}" }""")).asJson
+ .check(jsonPath("$.id").saveAs("rwdId")))
+ }
+
+ .exec(http("transactions_add")
+ .post("/transactions/add/")
+ .body(StringBody("""{ "customerRewardsId":"${rwdId}","customerId":"${custId}","transactionDate":"${txtDate}" }""")).asJson)
+ .pause(1)
+
+ .exec(http("get_reward")
+ .get("/transactions/findAll/${rwdId}"))
+ }
+ setUp(
+ scn.inject(atOnceUsers(100))
+ ).protocols(httpProtocol)
+}
\ No newline at end of file
diff --git a/testing-modules/load-testing-comparison/src/main/resources/scripts/JMeter/Test Plan.jmx b/testing-modules/load-testing-comparison/src/main/resources/scripts/JMeter/Test Plan.jmx
new file mode 100644
index 0000000000..da32a13a22
--- /dev/null
+++ b/testing-modules/load-testing-comparison/src/main/resources/scripts/JMeter/Test Plan.jmx
@@ -0,0 +1,293 @@
+
+
+
+
+
+ false
+ true
+ false
+
+
+
+
+
+
+
+ continue
+
+ false
+ 10
+
+ 100
+ 0
+ false
+
+
+
+
+
+ true
+ 1
+
+
+
+
+
+ Content-Type
+ application/json
+
+
+
+
+
+ true
+
+
+
+ false
+ {"customerRewardsId":null,"customerId":${random},"transactionDate":null}
+ =
+
+
+
+ localhost
+ 8080
+ http
+
+ /transactions/add
+ POST
+ true
+ false
+ true
+ false
+
+
+
+
+
+
+ txnId
+ $.id
+ 1
+ all
+ foo
+
+
+
+ txnDate
+ $.transactionDate
+ 1
+ Never
+
+
+
+ custId
+ $.customerId
+ 1
+ all
+ bob
+
+
+
+
+
+
+
+ localhost
+ 8080
+
+
+ /rewards/find/${custId}
+ GET
+ true
+ false
+ true
+ false
+
+
+
+
+
+
+ rwdId
+ $.id
+ 1
+ 0
+ all
+
+
+
+
+ ${rwdId} == 0
+ true
+
+
+
+ true
+
+
+
+ false
+ {"customerId":${custId}}
+ =
+
+
+
+ localhost
+ 8080
+
+
+ /rewards/add
+ POST
+ true
+ false
+ true
+ false
+
+
+
+
+
+
+ rwdId
+ $.id
+ 1
+ bar
+ all
+
+
+
+
+
+ true
+
+
+
+ false
+ {"id":${txnId},"customerRewardsId":${rwdId},"customerId":${custId},"transactionDate":"${txnDate}"}
+ =
+
+
+
+ localhost
+ 8080
+
+
+ /transactions/add
+ POST
+ true
+ false
+ true
+ false
+
+
+
+
+
+
+
+
+
+ localhost
+ 8080
+
+
+ /transactions/findAll/${rwdId}
+ GET
+ true
+ false
+ true
+ false
+
+
+
+
+
+
+
+ 10000
+ 1
+
+ false
+ 67
+ random
+
+
+
+ false
+
+ saveConfig
+
+
+ true
+ true
+ true
+
+ true
+ true
+ true
+ true
+ false
+ true
+ true
+ false
+ false
+ false
+ true
+ false
+ false
+ false
+ true
+ 0
+ true
+ true
+ true
+ true
+ true
+ true
+
+
+
+
+
+
+ false
+
+ saveConfig
+
+
+ true
+ true
+ true
+
+ true
+ true
+ true
+ true
+ false
+ true
+ true
+ false
+ false
+ false
+ true
+ false
+ false
+ false
+ true
+ 0
+ true
+ true
+ true
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
diff --git a/testing-modules/load-testing-comparison/src/main/resources/scripts/The Grinder/grinder.properties b/testing-modules/load-testing-comparison/src/main/resources/scripts/The Grinder/grinder.properties
new file mode 100644
index 0000000000..68adf90856
--- /dev/null
+++ b/testing-modules/load-testing-comparison/src/main/resources/scripts/The Grinder/grinder.properties
@@ -0,0 +1,5 @@
+grinder.script = grinder.py
+grinder.threads = 100
+grinder.processes = 1
+grinder.runs = 10
+grinder.logDirectory = /logs
diff --git a/testing-modules/load-testing-comparison/src/main/resources/scripts/The Grinder/grinder.py b/testing-modules/load-testing-comparison/src/main/resources/scripts/The Grinder/grinder.py
new file mode 100644
index 0000000000..025f90d38b
--- /dev/null
+++ b/testing-modules/load-testing-comparison/src/main/resources/scripts/The Grinder/grinder.py
@@ -0,0 +1,40 @@
+import java.util.Random
+from net.grinder.script import Test
+from net.grinder.script.Grinder import grinder
+from net.grinder.plugin.http import HTTPRequest, HTTPPluginControl, HTTPUtilities
+from HTTPClient import NVPair
+
+def parseJsonString(json, element):
+ for x in json.split(","):
+ pc = x.replace('"','').split(":")
+ if pc[0].replace("{","") == element:
+ ele = pc[1].replace("}","")
+ return ele
+ else:
+ return ""
+
+test1 = Test(1, "Request resource")
+request1 = HTTPRequest()
+headers = \
+( NVPair('Content-Type', 'application/json'), )
+request1.setHeaders(headers)
+utilities = HTTPPluginControl.getHTTPUtilities()
+test1.record(request1)
+random=java.util.Random()
+
+class TestRunner:
+ def __call__(self):
+ customerId = str(random.nextInt());
+
+ result = request1.POST("http://localhost:8080/transactions/add", "{"'"customerRewardsId"'":null,"'"customerId"'":"+ customerId + ","'"transactionDate"'":null}")
+ txnId = parseJsonString(result.getText(), "id")
+
+ result = request1.GET("http://localhost:8080/rewards/find/"+ customerId)
+ rwdId = parseJsonString(result.getText(), "id")
+
+ if rwdId == "":
+ result = request1.POST("http://localhost:8080/rewards/add", "{"'"customerId"'":"+ customerId + "}")
+ rwdId = parseJsonString(result.getText(), "id")
+
+ result = request1.POST("http://localhost:8080/transactions/add", "{"'"id"'":" + txnId + ","'"customerRewardsId"'":" + rwdId + ","'"customerId"'":"+ customerId + ","'"transactionDate"'":null}")
+ result = request1.GET("http://localhost:8080/transactions/findAll/" + rwdId)
\ No newline at end of file