From 5252f0c1b9bb32146311240870286e8b5352a284 Mon Sep 17 00:00:00 2001 From: Barry Oglesby Date: Fri, 3 Jan 2020 16:40:17 -0800 Subject: [PATCH] initial commit --- .gitignore | 24 + README.md | 1409 +++++++++++++++++ build.gradle | 80 + client-cq/manifest.yml | 10 + .../java/io/pivotal/test/client/Client.java | 19 + .../test/client/cq/TradeProcessor.java | 18 + .../io/pivotal/test/client/domain/Trade.java | 35 + .../resources/application-local.properties | 10 + .../src/main/resources/application.properties | 12 + client/manifest.yml | 10 + .../java/io/pivotal/test/client/Client.java | 123 ++ .../io/pivotal/test/client/Constants.java | 58 + .../client/controller/AdminController.java | 57 + .../client/controller/TradeController.java | 137 ++ .../test/client/domain/CusipHelper.java | 21 + .../io/pivotal/test/client/domain/Trade.java | 34 + .../test/client/function/AdminFunctions.java | 16 + .../AdminFunctionsResultCollector.java | 68 + .../test/client/function/TradeFunctions.java | 15 + .../pivotal/test/client/metrics/Metrics.java | 20 + .../test/client/metrics/MetricsHelper.java | 68 + .../client/repository/TradeRepository.java | 11 + .../client/service/OperationResponse.java | 19 + .../pivotal/test/client/service/Status.java | 6 + .../test/client/service/TradeService.java | 366 +++++ .../resources/application-local.properties | 10 + .../src/main/resources/application.properties | 12 + gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 58702 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 183 +++ gradlew.bat | 100 ++ server/README.md | 785 +++++++++ server/bin/cleanup.sh | 8 + server/bin/configure.sh | 10 + server/bin/deployfunctions.sh | 5 + server/bin/exportlogs.sh | 4 + .../server/function/GetMetricsFunction.java | 30 + .../server/function/UpdateTradeFunction.java | 39 + .../test/server/metrics/MetricsHelper.java | 85 + settings.gradle | 2 + 40 files changed, 3925 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 build.gradle create mode 100644 client-cq/manifest.yml create mode 100644 client-cq/src/main/java/io/pivotal/test/client/Client.java create mode 100644 client-cq/src/main/java/io/pivotal/test/client/cq/TradeProcessor.java create mode 100644 client-cq/src/main/java/io/pivotal/test/client/domain/Trade.java create mode 100644 client-cq/src/main/resources/application-local.properties create mode 100644 client-cq/src/main/resources/application.properties create mode 100644 client/manifest.yml create mode 100644 client/src/main/java/io/pivotal/test/client/Client.java create mode 100644 client/src/main/java/io/pivotal/test/client/Constants.java create mode 100644 client/src/main/java/io/pivotal/test/client/controller/AdminController.java create mode 100644 client/src/main/java/io/pivotal/test/client/controller/TradeController.java create mode 100755 client/src/main/java/io/pivotal/test/client/domain/CusipHelper.java create mode 100644 client/src/main/java/io/pivotal/test/client/domain/Trade.java create mode 100644 client/src/main/java/io/pivotal/test/client/function/AdminFunctions.java create mode 100644 client/src/main/java/io/pivotal/test/client/function/AdminFunctionsResultCollector.java create mode 100644 client/src/main/java/io/pivotal/test/client/function/TradeFunctions.java create mode 100644 client/src/main/java/io/pivotal/test/client/metrics/Metrics.java create mode 100644 client/src/main/java/io/pivotal/test/client/metrics/MetricsHelper.java create mode 100644 client/src/main/java/io/pivotal/test/client/repository/TradeRepository.java create mode 100644 client/src/main/java/io/pivotal/test/client/service/OperationResponse.java create mode 100644 client/src/main/java/io/pivotal/test/client/service/Status.java create mode 100644 client/src/main/java/io/pivotal/test/client/service/TradeService.java create mode 100644 client/src/main/resources/application-local.properties create mode 100644 client/src/main/resources/application.properties create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 gradlew.bat create mode 100644 server/README.md create mode 100755 server/bin/cleanup.sh create mode 100755 server/bin/configure.sh create mode 100755 server/bin/deployfunctions.sh create mode 100755 server/bin/exportlogs.sh create mode 100644 server/src/main/java/io/pivotal/test/server/function/GetMetricsFunction.java create mode 100644 server/src/main/java/io/pivotal/test/server/function/UpdateTradeFunction.java create mode 100644 server/src/main/java/io/pivotal/test/server/metrics/MetricsHelper.java create mode 100644 settings.gradle diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3a45642 --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +build/ +.idea/ +.gradle/ +.classpath +.project +.settings/ +.idea/ +.java-version +build-eclipse/ +/tags +out/ +setenv.sh + +.DS_store +*.iml +*.ipr +*.iws +*.swp +*.log +*.patch +*.diff +*.dat +*.rej +*.orig diff --git a/README.md b/README.md new file mode 100644 index 0000000..5ee0d96 --- /dev/null +++ b/README.md @@ -0,0 +1,1409 @@ +# Spring Boot Data Geode Example + +## Description +This is an example of a Spring Boot Data Geode client. + +It uses: + +- SB 2.2.2.RELEASE +- SBDG 1.2.2.RELEASE +- GEODE 1.9.2 +- GemFire 9.8.4 + +## Deploy Application +### PCFOne +#### Build Application +Build the application jar using **gradlew** like: + +``` +./gradlew clean jar bootJar + +> Task :client:compileJava +Note: Some input files use unchecked or unsafe operations. +Note: Recompile with -Xlint:unchecked for details. + +> Task :server:compileJava +Note: Some input files use unchecked or unsafe operations. +Note: Recompile with -Xlint:unchecked for details. + +Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0. +Use '--warning-mode all' to show the individual deprecation warnings. +See https://docs.gradle.org/6.0.1/userguide/command_line_interface.html#sec:command_line_warnings + +BUILD SUCCESSFUL in 8s +13 actionable tasks: 13 executed +``` +#### Push Client Application +Push the client application using **cf push** like: + +``` +cf push -f client/manifest.yml +Pushing from manifest to org pivot-boglesby / space playground as boglesby@pivotal.io... +Using manifest file client/manifest.yml +Getting app info... +Updating app with these attributes... + name: sdgApp + path: /Users/boglesby/Dev/Tests/spring-boot/pcc-long-running-test/client/build/libs/client-0.0.1-SNAPSHOT.jar + buildpacks: + https://github.com/cloudfoundry/java-buildpack.git + command: JAVA_OPTS="-agentpath:$PWD/.java-buildpack/open_jdk_jre/bin/jvmkill-1.16.0_RELEASE=printHeapHistogram=1 -Djava.io.tmpdir=$TMPDIR -XX:ActiveProcessorCount=$(nproc) -Djava.ext.dirs=$PWD/.java-buildpack/container_security_provider:$PWD/.java-buildpack/open_jdk_jre/lib/ext -Djava.security.properties=$PWD/.java-buildpack/java_security/java.security $JAVA_OPTS" && CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_jre/bin/java-buildpack-memory-calculator-3.13.0_RELEASE -totMemory=$MEMORY_LIMIT -loadedClasses=23795 -poolType=metaspace -stackThreads=250 -vmOptions="$JAVA_OPTS") && echo JVM Memory Configuration: $CALCULATED_MEMORY && JAVA_OPTS="$JAVA_OPTS $CALCULATED_MEMORY" && MALLOC_ARENA_MAX=2 SERVER_PORT=$PORT eval exec $PWD/.java-buildpack/open_jdk_jre/bin/java $JAVA_OPTS -cp $PWD/. org.springframework.boot.loader.JarLauncher + disk quota: 1G + health check type: port + instances: 1 + memory: 768M + stack: cflinuxfs3 + services: + pccService + routes: + sdgapp.apps.pcfone.io + +Updating app sdgApp... +Mapping routes... +Comparing local files to remote cache... +Packaging files to upload... +Uploading files... + 793.77 KiB / 793.77 KiB [==========================================] 100.00% 2s + +Waiting for API to complete processing files... + +Stopping app... + +Staging app and tracing logs... + Cell c1dffb38-7389-46f7-9c3a-8a8fb57af8b4 creating container for instance 452c0370-e11f-47f1-a20b-5ce1903b196a + Cell c1dffb38-7389-46f7-9c3a-8a8fb57af8b4 successfully created container for instance 452c0370-e11f-47f1-a20b-5ce1903b196a + Downloading app package... + Downloading build artifacts cache... + Downloaded build artifacts cache (42M) + Downloaded app package (67.4M) + -----> Java Buildpack 6fea4d5 | https://github.com/cloudfoundry/java-buildpack.git#6fea4d5 + -----> Downloading Jvmkill Agent 1.16.0_RELEASE from https://java-buildpack.cloudfoundry.org/jvmkill/bionic/x86_64/jvmkill-1.16.0-RELEASE.so (found in cache) + -----> Downloading Open Jdk JRE 1.8.0_232 from https://java-buildpack.cloudfoundry.org/openjdk/bionic/x86_64/openjdk-jre-1.8.0_232-bionic.tar.gz (found in cache) + Expanding Open Jdk JRE to .java-buildpack/open_jdk_jre (1.1s) + JVM DNS caching disabled in lieu of BOSH DNS caching + -----> Downloading Open JDK Like Memory Calculator 3.13.0_RELEASE from https://java-buildpack.cloudfoundry.org/memory-calculator/bionic/x86_64/memory-calculator-3.13.0-RELEASE.tar.gz (found in cache) + Loaded Classes: 23014, Threads: 250 + -----> Downloading Client Certificate Mapper 1.11.0_RELEASE from https://java-buildpack.cloudfoundry.org/client-certificate-mapper/client-certificate-mapper-1.11.0-RELEASE.jar (found in cache) + -----> Downloading Container Security Provider 1.16.0_RELEASE from https://java-buildpack.cloudfoundry.org/container-security-provider/container-security-provider-1.16.0-RELEASE.jar (found in cache) + -----> Downloading Spring Auto Reconfiguration 2.11.0_RELEASE from https://java-buildpack.cloudfoundry.org/auto-reconfiguration/auto-reconfiguration-2.11.0-RELEASE.jar (found in cache) + Exit status 0 + Uploading droplet, build artifacts cache... + Uploading droplet... + Uploading build artifacts cache... + Uploaded build artifacts cache (42M) + Uploaded droplet (109.6M) + Uploading complete + Cell c1dffb38-7389-46f7-9c3a-8a8fb57af8b4 stopping instance 452c0370-e11f-47f1-a20b-5ce1903b196a + Cell c1dffb38-7389-46f7-9c3a-8a8fb57af8b4 destroying container for instance 452c0370-e11f-47f1-a20b-5ce1903b196a + Cell c1dffb38-7389-46f7-9c3a-8a8fb57af8b4 successfully destroyed container for instance 452c0370-e11f-47f1-a20b-5ce1903b196a + +Waiting for app to start... + +name: sdgApp +requested state: started +isolation segment: iso-01 +routes: sdgapp.apps.pcfone.io +last uploaded: Fri 03 Jan 16:02:05 PST 2020 +stack: cflinuxfs3 +buildpacks: https://github.com/cloudfoundry/java-buildpack.git + +type: web +instances: 1/1 +memory usage: 768M +start command: JAVA_OPTS="-agentpath:$PWD/.java-buildpack/open_jdk_jre/bin/jvmkill-1.16.0_RELEASE=printHeapHistogram=1 + -Djava.io.tmpdir=$TMPDIR -XX:ActiveProcessorCount=$(nproc) + -Djava.ext.dirs=$PWD/.java-buildpack/container_security_provider:$PWD/.java-buildpack/open_jdk_jre/lib/ext + -Djava.security.properties=$PWD/.java-buildpack/java_security/java.security + $JAVA_OPTS" && + CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_jre/bin/java-buildpack-memory-calculator-3.13.0_RELEASE + -totMemory=$MEMORY_LIMIT -loadedClasses=23795 + -poolType=metaspace -stackThreads=250 -vmOptions="$JAVA_OPTS") + && echo JVM Memory Configuration: $CALCULATED_MEMORY && + JAVA_OPTS="$JAVA_OPTS $CALCULATED_MEMORY" && MALLOC_ARENA_MAX=2 + SERVER_PORT=$PORT eval exec + $PWD/.java-buildpack/open_jdk_jre/bin/java $JAVA_OPTS -cp + $PWD/. org.springframework.boot.loader.JarLauncher + state since cpu memory disk details +#0 running 2020-01-04T00:02:26Z 0.0% 224M of 768M 183.8M of 1G +``` +#### Push CQ Client Application +Push the CQ client application using **cf push** like: + +``` +cf push -f client_cq/manifest.yml +Pushing from manifest to org pivot-boglesby / space playground as boglesby@pivotal.io... +Using manifest file client_cq/manifest.yml +Getting app info... +Updating app with these attributes... + name: clientCqApp + path: /Users/boglesby/Dev/Tests/spring-boot/pcc-long-running-test/client_cq/build/libs/client_cq-0.0.1-SNAPSHOT.jar + buildpacks: + https://github.com/cloudfoundry/java-buildpack.git + command: JAVA_OPTS="-agentpath:$PWD/.java-buildpack/open_jdk_jre/bin/jvmkill-1.16.0_RELEASE=printHeapHistogram=1 -Djava.io.tmpdir=$TMPDIR -XX:ActiveProcessorCount=$(nproc) -Djava.ext.dirs=$PWD/.java-buildpack/container_security_provider:$PWD/.java-buildpack/open_jdk_jre/lib/ext -Djava.security.properties=$PWD/.java-buildpack/java_security/java.security $JAVA_OPTS" && CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_jre/bin/java-buildpack-memory-calculator-3.13.0_RELEASE -totMemory=$MEMORY_LIMIT -loadedClasses=23790 -poolType=metaspace -stackThreads=250 -vmOptions="$JAVA_OPTS") && echo JVM Memory Configuration: $CALCULATED_MEMORY && JAVA_OPTS="$JAVA_OPTS $CALCULATED_MEMORY" && MALLOC_ARENA_MAX=2 SERVER_PORT=$PORT eval exec $PWD/.java-buildpack/open_jdk_jre/bin/java $JAVA_OPTS -cp $PWD/. org.springframework.boot.loader.JarLauncher + disk quota: 1G + health check type: port + instances: 1 + memory: 768M + stack: cflinuxfs3 + services: + pccService + routes: + clientcqapp.apps.pcfone.io + +Updating app clientCqApp... +Mapping routes... +Comparing local files to remote cache... +Packaging files to upload... +Uploading files... + 772.39 KiB / 772.39 KiB [==========================================] 100.00% 2s + +Waiting for API to complete processing files... + +Stopping app... + +Staging app and tracing logs... + Cell 8851f31c-1d22-48d4-b987-839b9a8db015 creating container for instance 4baa38e6-438c-4b3e-8fbd-68d19a0b2e18 + Cell 8851f31c-1d22-48d4-b987-839b9a8db015 successfully created container for instance 4baa38e6-438c-4b3e-8fbd-68d19a0b2e18 + Downloading app package... + Downloading build artifacts cache... + Downloaded build artifacts cache (42M) + Downloaded app package (67.4M) + -----> Java Buildpack 6fea4d5 | https://github.com/cloudfoundry/java-buildpack.git#6fea4d5 + -----> Downloading Jvmkill Agent 1.16.0_RELEASE from https://java-buildpack.cloudfoundry.org/jvmkill/bionic/x86_64/jvmkill-1.16.0-RELEASE.so (found in cache) + -----> Downloading Open Jdk JRE 1.8.0_232 from https://java-buildpack.cloudfoundry.org/openjdk/bionic/x86_64/openjdk-jre-1.8.0_232-bionic.tar.gz (found in cache) + Expanding Open Jdk JRE to .java-buildpack/open_jdk_jre (1.1s) + JVM DNS caching disabled in lieu of BOSH DNS caching + -----> Downloading Open JDK Like Memory Calculator 3.13.0_RELEASE from https://java-buildpack.cloudfoundry.org/memory-calculator/bionic/x86_64/memory-calculator-3.13.0-RELEASE.tar.gz (found in cache) + Loaded Classes: 23009, Threads: 250 + -----> Downloading Client Certificate Mapper 1.11.0_RELEASE from https://java-buildpack.cloudfoundry.org/client-certificate-mapper/client-certificate-mapper-1.11.0-RELEASE.jar (found in cache) + -----> Downloading Container Security Provider 1.16.0_RELEASE from https://java-buildpack.cloudfoundry.org/container-security-provider/container-security-provider-1.16.0-RELEASE.jar (found in cache) + -----> Downloading Spring Auto Reconfiguration 2.11.0_RELEASE from https://java-buildpack.cloudfoundry.org/auto-reconfiguration/auto-reconfiguration-2.11.0-RELEASE.jar (found in cache) + Exit status 0 + Uploading droplet, build artifacts cache... + Uploading droplet... + Uploading build artifacts cache... + Uploaded build artifacts cache (42M) + Uploaded droplet (109.6M) + Uploading complete + Cell 8851f31c-1d22-48d4-b987-839b9a8db015 stopping instance 4baa38e6-438c-4b3e-8fbd-68d19a0b2e18 + Cell 8851f31c-1d22-48d4-b987-839b9a8db015 destroying container for instance 4baa38e6-438c-4b3e-8fbd-68d19a0b2e18 + Cell 8851f31c-1d22-48d4-b987-839b9a8db015 successfully destroyed container for instance 4baa38e6-438c-4b3e-8fbd-68d19a0b2e18 + +Waiting for app to start... + +name: clientCqApp +requested state: started +isolation segment: iso-01 +routes: clientcqapp.apps.pcfone.io +last uploaded: Fri 03 Jan 16:05:13 PST 2020 +stack: cflinuxfs3 +buildpacks: https://github.com/cloudfoundry/java-buildpack.git + +type: web +instances: 1/1 +memory usage: 768M +start command: JAVA_OPTS="-agentpath:$PWD/.java-buildpack/open_jdk_jre/bin/jvmkill-1.16.0_RELEASE=printHeapHistogram=1 + -Djava.io.tmpdir=$TMPDIR -XX:ActiveProcessorCount=$(nproc) + -Djava.ext.dirs=$PWD/.java-buildpack/container_security_provider:$PWD/.java-buildpack/open_jdk_jre/lib/ext + -Djava.security.properties=$PWD/.java-buildpack/java_security/java.security + $JAVA_OPTS" && + CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_jre/bin/java-buildpack-memory-calculator-3.13.0_RELEASE + -totMemory=$MEMORY_LIMIT -loadedClasses=23790 + -poolType=metaspace -stackThreads=250 -vmOptions="$JAVA_OPTS") + && echo JVM Memory Configuration: $CALCULATED_MEMORY && + JAVA_OPTS="$JAVA_OPTS $CALCULATED_MEMORY" && MALLOC_ARENA_MAX=2 + SERVER_PORT=$PORT eval exec + $PWD/.java-buildpack/open_jdk_jre/bin/java $JAVA_OPTS -cp + $PWD/. org.springframework.boot.loader.JarLauncher + state since cpu memory disk details +#0 running 2020-01-04T00:05:35Z 0.0% 178.2M of 768M 183.6M of 1G +``` +#### Get Client Application Logs +##### Get latest Logs +Get the latest client application log messages using the **cf logs** command like: + +``` +cf logs sdgApp --recent +... + 2019-12-19T16:20:09.95-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:20:09.955 INFO 33 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' + 2019-12-19T16:20:09.96-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:20:09.960 INFO 33 --- [ main] io.pivotal.test.client.Client : Started Client in 7.316 seconds (JVM running for 8.365) + 2019-12-19T16:20:10.01-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:20:10.017 INFO 33 --- [ main] io.pivotal.test.client.Client : Client Command Line Arguments: [] + 2019-12-19T16:20:11.67-0800 [CELL/0] OUT Container became healthy +``` +##### Tail Logs +Tail the client application log messages using the **cf logs** command like: + +``` +cf logs sdgApp +Retrieving logs for app sdgApp in org pivot-boglesby / space playground as boglesby@pivotal.io... +``` +#### Get CQ Client Application Logs +##### Get latest Logs +Get the latest CQ client application log messages using the **cf logs** command like: + +``` +cf logs clientCqApp --recent +... + 2020-01-03T16:05:32.66-0800 [APP/PROC/WEB/0] OUT 2020-01-04 00:05:32.664 INFO 14 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' + 2020-01-03T16:05:32.66-0800 [APP/PROC/WEB/0] OUT 2020-01-04 00:05:32.669 INFO 14 --- [ main] io.pivotal.test.client.Client : Started Client in 7.769 seconds (JVM running for 8.694) + 2020-01-03T16:05:33.97-0800 [CELL/0] OUT Container became healthy +``` +##### Tail Logs +Tail the CQ client application log messages using the **cf logs** command like: + +``` +cf logs clientCqApp +Retrieving logs for app sdgApp in org pivot-boglesby / space playground as boglesby@pivotal.io... +``` +## Run Clients +### PCFOne +#### REST +##### Put Command +Run the put command using **curl** like: + +``` +curl -X POST https://sdgapp.apps.pcfone.io/trades/put/10/1024 +{"operation":"put","status":"SUCCESS","completionTime":191} +``` +The application will log messages like: + +``` + 2019-12-19T16:45:46.45-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:45:46.457 INFO 33 --- [nio-8080-exec-4] i.p.test.client.service.TradeService : Putting 10 trades of size 1024 bytes + 2019-12-19T16:45:46.51-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:45:46.517 INFO 33 --- [nio-8080-exec-4] i.p.test.client.service.TradeService : Saved Trade(id=0, cusip=HD, shares=55, price=371.99) + 2019-12-19T16:45:46.52-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:45:46.524 INFO 33 --- [nio-8080-exec-4] i.p.test.client.service.TradeService : Saved Trade(id=1, cusip=SAP, shares=98, price=544.99) + 2019-12-19T16:45:46.53-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:45:46.531 INFO 33 --- [nio-8080-exec-4] i.p.test.client.service.TradeService : Saved Trade(id=2, cusip=UPS, shares=39, price=114.47) + 2019-12-19T16:45:46.54-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:45:46.548 INFO 33 --- [nio-8080-exec-4] i.p.test.client.service.TradeService : Saved Trade(id=3, cusip=HD, shares=77, price=613.03) + 2019-12-19T16:45:46.56-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:45:46.560 INFO 33 --- [nio-8080-exec-4] i.p.test.client.service.TradeService : Saved Trade(id=4, cusip=MMM, shares=59, price=671.10) + 2019-12-19T16:45:46.57-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:45:46.570 INFO 33 --- [nio-8080-exec-4] i.p.test.client.service.TradeService : Saved Trade(id=5, cusip=BUD, shares=92, price=226.78) + 2019-12-19T16:45:46.59-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:45:46.589 INFO 33 --- [nio-8080-exec-4] i.p.test.client.service.TradeService : Saved Trade(id=6, cusip=AVGO, shares=6, price=321.33) + 2019-12-19T16:45:46.59-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:45:46.592 INFO 33 --- [nio-8080-exec-4] i.p.test.client.service.TradeService : Saved Trade(id=7, cusip=AMZN, shares=26, price=908.64) + 2019-12-19T16:45:46.64-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:45:46.645 INFO 33 --- [nio-8080-exec-4] i.p.test.client.service.TradeService : Saved Trade(id=8, cusip=AXP, shares=69, price=911.00) + 2019-12-19T16:45:46.64-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:45:46.648 INFO 33 --- [nio-8080-exec-4] i.p.test.client.service.TradeService : Saved Trade(id=9, cusip=TM, shares=72, price=975.52) + 2019-12-19T16:45:46.64-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:45:46.649 INFO 33 --- [nio-8080-exec-4] i.p.test.client.service.TradeService : Put 10 trades of size 1024 bytes in 191 ms +``` +###### Get Command +Run the get command using **curl** like: + +``` +curl https://sdgapp.apps.pcfone.io/trades/get/10 +{"operation":"get","status":"SUCCESS","completionTime":55} +``` +The application will log messages like: + +``` + 2019-12-19T16:47:42.28-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:47:42.286 INFO 33 --- [io-8080-exec-10] i.p.test.client.service.TradeService : Getting 10 trades + 2019-12-19T16:47:42.31-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:47:42.318 INFO 33 --- [io-8080-exec-10] i.p.test.client.service.TradeService : Got Trade(id=0, cusip=HD, shares=55, price=371.99) + 2019-12-19T16:47:42.32-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:47:42.326 INFO 33 --- [io-8080-exec-10] i.p.test.client.service.TradeService : Got Trade(id=1, cusip=SAP, shares=98, price=544.99) + 2019-12-19T16:47:42.32-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:47:42.327 INFO 33 --- [io-8080-exec-10] i.p.test.client.service.TradeService : Got Trade(id=2, cusip=UPS, shares=39, price=114.47) + 2019-12-19T16:47:42.32-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:47:42.329 INFO 33 --- [io-8080-exec-10] i.p.test.client.service.TradeService : Got Trade(id=3, cusip=HD, shares=77, price=613.03) + 2019-12-19T16:47:42.33-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:47:42.330 INFO 33 --- [io-8080-exec-10] i.p.test.client.service.TradeService : Got Trade(id=4, cusip=MMM, shares=59, price=671.10) + 2019-12-19T16:47:42.33-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:47:42.331 INFO 33 --- [io-8080-exec-10] i.p.test.client.service.TradeService : Got Trade(id=5, cusip=BUD, shares=92, price=226.78) + 2019-12-19T16:47:42.33-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:47:42.338 INFO 33 --- [io-8080-exec-10] i.p.test.client.service.TradeService : Got Trade(id=6, cusip=AVGO, shares=6, price=321.33) + 2019-12-19T16:47:42.33-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:47:42.339 INFO 33 --- [io-8080-exec-10] i.p.test.client.service.TradeService : Got Trade(id=7, cusip=AMZN, shares=26, price=908.64) + 2019-12-19T16:47:42.34-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:47:42.340 INFO 33 --- [io-8080-exec-10] i.p.test.client.service.TradeService : Got Trade(id=8, cusip=AXP, shares=69, price=911.00) + 2019-12-19T16:47:42.34-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:47:42.341 INFO 33 --- [io-8080-exec-10] i.p.test.client.service.TradeService : Got Trade(id=9, cusip=TM, shares=72, price=975.52) + 2019-12-19T16:47:42.34-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:47:42.341 INFO 33 --- [io-8080-exec-10] i.p.test.client.service.TradeService : Got 10 trades in 55 ms +``` +##### Destroy Command +Run the destroy command using **curl** like: + +``` +curl -X DELETE https://sdgapp.apps.pcfone.io/trades/destroy/10 +{"operation":"destroy","status":"SUCCESS","completionTime":63} +``` +The application will log messages like: + +``` + 2019-12-19T16:48:10.72-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:48:10.719 INFO 33 --- [nio-8080-exec-2] i.p.test.client.service.TradeService : Destroying 10 trades + 2019-12-19T16:48:10.73-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:48:10.735 INFO 33 --- [nio-8080-exec-2] i.p.test.client.service.TradeService : Destroyed key=0 + 2019-12-19T16:48:10.74-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:48:10.740 INFO 33 --- [nio-8080-exec-2] i.p.test.client.service.TradeService : Destroyed key=1 + 2019-12-19T16:48:10.75-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:48:10.750 INFO 33 --- [nio-8080-exec-2] i.p.test.client.service.TradeService : Destroyed key=2 + 2019-12-19T16:48:10.75-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:48:10.758 INFO 33 --- [nio-8080-exec-2] i.p.test.client.service.TradeService : Destroyed key=3 + 2019-12-19T16:48:10.76-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:48:10.761 INFO 33 --- [nio-8080-exec-2] i.p.test.client.service.TradeService : Destroyed key=4 + 2019-12-19T16:48:10.76-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:48:10.765 INFO 33 --- [nio-8080-exec-2] i.p.test.client.service.TradeService : Destroyed key=5 + 2019-12-19T16:48:10.76-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:48:10.768 INFO 33 --- [nio-8080-exec-2] i.p.test.client.service.TradeService : Destroyed key=6 + 2019-12-19T16:48:10.77-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:48:10.779 INFO 33 --- [nio-8080-exec-2] i.p.test.client.service.TradeService : Destroyed key=7 + 2019-12-19T16:48:10.78-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:48:10.781 INFO 33 --- [nio-8080-exec-2] i.p.test.client.service.TradeService : Destroyed key=8 + 2019-12-19T16:48:10.78-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:48:10.783 INFO 33 --- [nio-8080-exec-2] i.p.test.client.service.TradeService : Destroyed key=9 + 2019-12-19T16:48:10.78-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:48:10.783 INFO 33 --- [nio-8080-exec-2] i.p.test.client.service.TradeService : Destroyed 10 trades in 63 ms +``` +##### Query By Cusip Command +Run the query by cusip command using **curl** like: + +``` +curl https://sdgapp.apps.pcfone.io/trades/querybycusip/10 +``` +The application will log messages like: + +``` + 2019-12-19T16:49:04.52-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:49:04.529 INFO 33 --- [nio-8080-exec-5] i.p.test.client.service.TradeService : Executing 10 cusip queries + 2019-12-19T16:49:04.79-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:49:04.797 INFO 33 --- [nio-8080-exec-5] i.p.test.client.service.TradeService : Returned 1803 trades for cusip=FB + 2019-12-19T16:49:04.96-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:49:04.959 INFO 33 --- [nio-8080-exec-5] i.p.test.client.service.TradeService : Returned 1848 trades for cusip=AAPL + 2019-12-19T16:49:05.04-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:49:05.049 INFO 33 --- [nio-8080-exec-5] i.p.test.client.service.TradeService : Returned 1889 trades for cusip=ADBE + 2019-12-19T16:49:05.11-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:49:05.110 INFO 33 --- [nio-8080-exec-5] i.p.test.client.service.TradeService : Returned 1838 trades for cusip=AVGO + 2019-12-19T16:49:05.25-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:49:05.259 INFO 33 --- [nio-8080-exec-5] i.p.test.client.service.TradeService : Returned 1832 trades for cusip=CRM + 2019-12-19T16:49:05.41-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:49:05.414 INFO 33 --- [nio-8080-exec-5] i.p.test.client.service.TradeService : Returned 1801 trades for cusip=SAP + 2019-12-19T16:49:05.52-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:49:05.523 INFO 33 --- [nio-8080-exec-5] i.p.test.client.service.TradeService : Returned 1826 trades for cusip=XOM + 2019-12-19T16:49:05.58-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:49:05.580 INFO 33 --- [nio-8080-exec-5] i.p.test.client.service.TradeService : Returned 1886 trades for cusip=GE + 2019-12-19T16:49:05.64-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:49:05.642 INFO 33 --- [nio-8080-exec-5] i.p.test.client.service.TradeService : Returned 1879 trades for cusip=NKE + 2019-12-19T16:49:05.70-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:49:05.705 INFO 33 --- [nio-8080-exec-5] i.p.test.client.service.TradeService : Returned 1886 trades for cusip=GE + 2019-12-19T16:49:05.70-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:49:05.705 INFO 33 --- [nio-8080-exec-5] i.p.test.client.service.TradeService : Executed 10 cusip queries in 1176 ms +``` +##### Function Update Command +Run the function update command using **curl** like: + +``` +curl -X POST https://sdgapp.apps.pcfone.io/trades/functionupdate/10 +{"operation":"functionupdate","status":"SUCCESS","completionTime":65} +``` +The application will log messages like: + +``` + 2019-12-19T16:50:12.12-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:50:12.125 INFO 33 --- [io-8080-exec-10] i.p.test.client.service.TradeService : Updating 10 trades with function + 2019-12-19T16:50:12.14-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:50:12.149 INFO 33 --- [io-8080-exec-10] i.p.test.client.service.TradeService : Updated trade 0 result=[true] + 2019-12-19T16:50:12.16-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:50:12.164 INFO 33 --- [io-8080-exec-10] i.p.test.client.service.TradeService : Updated trade 1 result=[true] + 2019-12-19T16:50:12.16-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:50:12.167 INFO 33 --- [io-8080-exec-10] i.p.test.client.service.TradeService : Updated trade 2 result=[true] + 2019-12-19T16:50:12.17-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:50:12.174 INFO 33 --- [io-8080-exec-10] i.p.test.client.service.TradeService : Updated trade 3 result=[true] + 2019-12-19T16:50:12.17-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:50:12.176 INFO 33 --- [io-8080-exec-10] i.p.test.client.service.TradeService : Updated trade 4 result=[true] + 2019-12-19T16:50:12.17-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:50:12.179 INFO 33 --- [io-8080-exec-10] i.p.test.client.service.TradeService : Updated trade 5 result=[true] + 2019-12-19T16:50:12.18-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:50:12.181 INFO 33 --- [io-8080-exec-10] i.p.test.client.service.TradeService : Updated trade 6 result=[true] + 2019-12-19T16:50:12.18-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:50:12.186 INFO 33 --- [io-8080-exec-10] i.p.test.client.service.TradeService : Updated trade 7 result=[true] + 2019-12-19T16:50:12.18-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:50:12.188 INFO 33 --- [io-8080-exec-10] i.p.test.client.service.TradeService : Updated trade 8 result=[true] + 2019-12-19T16:50:12.19-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:50:12.190 INFO 33 --- [io-8080-exec-10] i.p.test.client.service.TradeService : Updated trade 9 result=[true] + 2019-12-19T16:50:12.19-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:50:12.190 INFO 33 --- [io-8080-exec-10] i.p.test.client.service.TradeService : Updated 10 trades with function in 65 ms +``` +##### Put Forever Command +Run the function update command using **curl** like: + +``` +curl -X POST https://sdgapp.apps.pcfone.io/trades/putforever/10/1024 +``` +The application will log messages like: + +``` +... +``` +##### Get Forever Command +Run the function update command using **curl** like: + +``` +curl https://sdgapp.apps.pcfone.io/trades/getforever/10 +``` +The application will log messages like: + +``` +... +``` +##### Destroy Forever Command +Run the function update command using **curl** like: + +``` +curl -X DELETE https://sdgapp.apps.pcfone.io/trades/destroyforever/10 +``` +The application will log messages like: + +``` +... +``` +##### Query by Cusip Forever Command +Run the function update command using **curl** like: + +``` +curl https://sdgapp.apps.pcfone.io/trades/querybycusipforever +``` +The application will log messages like: + +``` +... +``` +##### Function Update Forever Command +Run the function update command using **curl** like: + +``` +curl -X POST https://sdgapp.apps.pcfone.io/trades/functionupdateforever/10 +``` +The application will log messages like: + +``` +... +``` +##### Multi-threaded Put Forever Command +Run the multi-threaded put forever command using **curl** like: + +``` +curl -X POST https://sdgapp.apps.pcfone.io/trades/putforever/10/1024/5 +``` +The application will log messages like: + +``` +... +``` +##### Multi-threaded Get Forever Command +Run the multi-threaded get forever command using **curl** like: + +``` +curl https://sdgapp.apps.pcfone.io/trades/getforever/10/5 +``` +The application will log messages like: + +``` +... +``` +##### Multi-threaded Destroy Forever Command +Run the multi-threaded destroy forever command using **curl** like: + +``` +curl -X DELETE https://sdgapp.apps.pcfone.io/trades/destroyforever/10/5 +``` +The application will log messages like: + +``` +... +``` +##### Multi-threaded Query by Cusip Forever Command +Run the multi-threaded query by cusip forever command using **curl** like: + +``` +curl https://sdgapp.apps.pcfone.io/trades/querybycusipforever/5 +``` +The application will log messages like: + +``` +... +``` +##### Multi-threaded Function Update Forever Command +Run the multi-threaded function update command using **curl** like: + +``` +curl -X POST https://sdgapp.apps.pcfone.io/trades/functionupdateforever/10/5 +``` +The application will log messages like: + +``` +... +``` +##### Get One Command +Run the get one command using **curl** like: + +``` +curl https://sdgapp.apps.pcfone.io/trades/getone/0 +``` +The application will log messages like: + +``` +``` +##### Query One By Cusip Command +Run the query one by cusip command using **curl** like: + +``` +curl https://sdgapp.apps.pcfone.io/trades/queryonebycusip/AAPL +``` +The application will log messages like: + +``` +``` +##### Test Command +Run the test command using **curl** like: + +``` +curl -X POST https://sdgapp.apps.pcfone.io/trades/starttest/100000/1024 +[{"operation":"putforever","status":"SUCCESS","completionTime":0},{"operation":"getforever","status":"SUCCESS","completionTime":0},{"operation":"querybycusipforever","status":"SUCCESS","completionTime":0},{"operation":"functionupdateforever","status":"SUCCESS","completionTime":0}] +``` +The application will log messages like: + +``` + 2019-12-19T16:55:37.45-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:55:37.450 INFO 33 --- [ Thread-12] i.p.test.client.service.TradeService : Putting 10000 trades of size 1024 bytes forever + 2019-12-19T16:55:37.45-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:55:37.451 INFO 33 --- [ Thread-13] i.p.test.client.service.TradeService : Getting 100000 trades forever + 2019-12-19T16:55:37.45-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:55:37.452 INFO 33 --- [ Thread-14] i.p.test.client.service.TradeService : Executing cusip queries forever + 2019-12-19T16:55:37.45-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:55:37.458 INFO 33 --- [ Thread-15] i.p.test.client.service.TradeService : Updating 100000 trades with function forever + 2019-12-19T16:55:50.19-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:55:50.194 INFO 33 --- [ Thread-13] i.p.test.client.service.TradeService : Got 10000 trades in 12743 ms + 2019-12-19T16:55:55.83-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:55:55.830 INFO 33 --- [ Thread-12] i.p.test.client.service.TradeService : Put 10000 trades of size 1024 bytes in 18379 ms + 2019-12-19T16:55:56.82-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:55:56.822 INFO 33 --- [ Thread-15] i.p.test.client.service.TradeService : Updated 10000 trades with function in 19364 ms + 2019-12-19T16:55:59.66-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:55:59.662 INFO 33 --- [ Thread-13] i.p.test.client.service.TradeService : Got 20000 trades in 9468 ms + 2019-12-19T16:56:11.27-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:56:11.274 INFO 33 --- [ Thread-13] i.p.test.client.service.TradeService : Got 30000 trades in 11612 ms + 2019-12-19T16:56:11.96-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:56:11.960 INFO 33 --- [ Thread-12] i.p.test.client.service.TradeService : Put 20000 trades of size 1024 bytes in 16130 ms + 2019-12-19T16:56:13.96-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:56:13.966 INFO 33 --- [ Thread-15] i.p.test.client.service.TradeService : Updated 20000 trades with function in 17143 ms + 2019-12-19T16:56:25.74-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:56:25.742 INFO 33 --- [ Thread-12] i.p.test.client.service.TradeService : Put 30000 trades of size 1024 bytes in 13781 ms + 2019-12-19T16:56:29.08-0800 [APP/PROC/WEB/0] OUT 2019-12-20 00:56:29.085 INFO 33 --- [ Thread-15] i.p.test.client.service.TradeService : Updated 30000 trades with function in 15118 ms + 2019-12-19T17:03:56.82-0800 [APP/PROC/WEB/0] OUT 2019-12-20 01:03:56.829 INFO 33 --- [ Thread-14] i.p.test.client.service.TradeService : Executed 10000 cusip queries in 499377 ms + 2019-12-19T17:12:08.31-0800 [APP/PROC/WEB/0] OUT 2019-12-20 01:12:08.314 INFO 33 --- [ Thread-14] i.p.test.client.service.TradeService : Executed 20000 cusip queries in 491485 ms + 2019-12-19T17:20:22.31-0800 [APP/PROC/WEB/0] OUT 2019-12-20 01:20:22.310 INFO 33 --- [ Thread-14] i.p.test.client.service.TradeService : Executed 30000 cusip queries in 493995 ms +... +``` +##### Stop Operations Command +Run the stop operations command using **curl** like: + +``` +curl -X POST https://sdgapp.apps.pcfone.io/trades/stopoperations +``` +The application will log messages like: + +``` +``` +### Local +#### Java +##### Put Command +Run the put command using the **runclient.sh** script like: + +``` +./runclient.sh put 10 1024 +... +2019-12-18 15:55:16.285 INFO 95421 --- [ main] i.p.test.client.service.TradeService : Putting 10 trades of size 1024 bytes +2019-12-18 15:55:16.324 INFO 95421 --- [ main] i.p.test.client.service.TradeService : Saved Trade(id=0, cusip=BA, shares=66, price=217.50) +2019-12-18 15:55:16.330 INFO 95421 --- [ main] i.p.test.client.service.TradeService : Saved Trade(id=1, cusip=JPM, shares=87, price=182.33) +2019-12-18 15:55:16.337 INFO 95421 --- [ main] i.p.test.client.service.TradeService : Saved Trade(id=2, cusip=SAP, shares=87, price=415.07) +2019-12-18 15:55:16.344 INFO 95421 --- [ main] i.p.test.client.service.TradeService : Saved Trade(id=3, cusip=CMCSA, shares=70, price=972.59) +2019-12-18 15:55:16.347 INFO 95421 --- [ main] i.p.test.client.service.TradeService : Saved Trade(id=4, cusip=AAPL, shares=93, price=315.32) +2019-12-18 15:55:16.351 INFO 95421 --- [ main] i.p.test.client.service.TradeService : Saved Trade(id=5, cusip=JNJ, shares=90, price=404.47) +2019-12-18 15:55:16.356 INFO 95421 --- [ main] i.p.test.client.service.TradeService : Saved Trade(id=6, cusip=HSBC, shares=64, price=879.82) +2019-12-18 15:55:16.363 INFO 95421 --- [ main] i.p.test.client.service.TradeService : Saved Trade(id=7, cusip=COST, shares=48, price=378.87) +2019-12-18 15:55:16.367 INFO 95421 --- [ main] i.p.test.client.service.TradeService : Saved Trade(id=8, cusip=ORCL, shares=3, price=882.84) +2019-12-18 15:55:16.371 INFO 95421 --- [ main] i.p.test.client.service.TradeService : Saved Trade(id=9, cusip=SAP, shares=15, price=384.58) +2019-12-18 15:55:16.371 INFO 95421 --- [ main] i.p.test.client.service.TradeService : Put 10 trades of size 1024 bytes in 86 ms +``` +###### Get Command +Run the get command using the **runclient.sh** script like: + +``` +./runclient.sh get 10 +... +2019-12-18 16:16:11.679 INFO 96776 --- [ main] i.p.test.client.service.TradeService : Getting 10 trades +2019-12-18 16:16:11.720 INFO 96776 --- [ main] i.p.test.client.service.TradeService : Got Trade(id=0, cusip=BA, shares=66, price=217.50) +2019-12-18 16:16:11.721 INFO 96776 --- [ main] i.p.test.client.service.TradeService : Got Trade(id=1, cusip=JPM, shares=87, price=182.33) +2019-12-18 16:16:11.725 INFO 96776 --- [ main] i.p.test.client.service.TradeService : Got Trade(id=2, cusip=SAP, shares=87, price=415.07) +2019-12-18 16:16:11.730 INFO 96776 --- [ main] i.p.test.client.service.TradeService : Got Trade(id=3, cusip=CMCSA, shares=70, price=972.59) +2019-12-18 16:16:11.731 INFO 96776 --- [ main] i.p.test.client.service.TradeService : Got Trade(id=4, cusip=AAPL, shares=93, price=315.32) +2019-12-18 16:16:11.732 INFO 96776 --- [ main] i.p.test.client.service.TradeService : Got Trade(id=5, cusip=JNJ, shares=90, price=404.47) +2019-12-18 16:16:11.733 INFO 96776 --- [ main] i.p.test.client.service.TradeService : Got Trade(id=6, cusip=HSBC, shares=64, price=879.82) +2019-12-18 16:16:11.738 INFO 96776 --- [ main] i.p.test.client.service.TradeService : Got Trade(id=7, cusip=COST, shares=48, price=378.87) +2019-12-18 16:16:11.740 INFO 96776 --- [ main] i.p.test.client.service.TradeService : Got Trade(id=8, cusip=ORCL, shares=3, price=882.84) +2019-12-18 16:16:11.741 INFO 96776 --- [ main] i.p.test.client.service.TradeService : Got Trade(id=9, cusip=SAP, shares=15, price=384.58) +2019-12-18 16:16:11.741 INFO 96776 --- [ main] i.p.test.client.service.TradeService : Got 10 trades in 62 ms +``` +##### Destroy Command +Run the destroy command using the **runclient.sh** script like: + +``` +./runclient.sh destroy 10 +... +2019-12-18 16:19:30.910 INFO 97101 --- [ main] i.p.test.client.service.TradeService : Destroying 10 trades +2019-12-18 16:19:30.937 INFO 97101 --- [ main] i.p.test.client.service.TradeService : Destroyed key=0 +2019-12-18 16:19:30.950 INFO 97101 --- [ main] i.p.test.client.service.TradeService : Destroyed key=1 +2019-12-18 16:19:30.956 INFO 97101 --- [ main] i.p.test.client.service.TradeService : Destroyed key=2 +2019-12-18 16:19:30.962 INFO 97101 --- [ main] i.p.test.client.service.TradeService : Destroyed key=3 +2019-12-18 16:19:30.964 INFO 97101 --- [ main] i.p.test.client.service.TradeService : Destroyed key=4 +2019-12-18 16:19:30.968 INFO 97101 --- [ main] i.p.test.client.service.TradeService : Destroyed key=5 +2019-12-18 16:19:30.970 INFO 97101 --- [ main] i.p.test.client.service.TradeService : Destroyed key=6 +2019-12-18 16:19:30.976 INFO 97101 --- [ main] i.p.test.client.service.TradeService : Destroyed key=7 +2019-12-18 16:19:30.979 INFO 97101 --- [ main] i.p.test.client.service.TradeService : Destroyed key=8 +2019-12-18 16:19:30.982 INFO 97101 --- [ main] i.p.test.client.service.TradeService : Destroyed key=9 +2019-12-18 16:19:30.982 INFO 97101 --- [ main] i.p.test.client.service.TradeService : Destroyed 10 trades in 71 ms +``` +##### Query By Cusip Command +Run the query by cusip command using the **runclient.sh** script like: + +``` +./runclient.sh querybycusip 10 +... +2019-12-18 16:20:58.897 INFO 97261 --- [ main] i.p.test.client.service.TradeService : Executing 10 cusip queries +2019-12-18 16:20:59.000 INFO 97261 --- [ main] i.p.test.client.service.TradeService : Returned 2 trades for cusip=HON +2019-12-18 16:20:59.007 INFO 97261 --- [ main] i.p.test.client.service.TradeService : Returned 2 trades for cusip=PYPL +2019-12-18 16:20:59.016 INFO 97261 --- [ main] i.p.test.client.service.TradeService : Returned 4 trades for cusip=GE +2019-12-18 16:20:59.041 INFO 97261 --- [ main] i.p.test.client.service.TradeService : Returned 3 trades for cusip=ORCL +2019-12-18 16:20:59.048 INFO 97261 --- [ main] i.p.test.client.service.TradeService : Returned 1 trades for cusip=LMT +2019-12-18 16:20:59.055 INFO 97261 --- [ main] i.p.test.client.service.TradeService : Returned 3 trades for cusip=JPM +2019-12-18 16:20:59.063 INFO 97261 --- [ main] i.p.test.client.service.TradeService : Returned 4 trades for cusip=CSCO +2019-12-18 16:20:59.071 INFO 97261 --- [ main] i.p.test.client.service.TradeService : Returned 2 trades for cusip=BAC +2019-12-18 16:20:59.078 INFO 97261 --- [ main] i.p.test.client.service.TradeService : Returned 3 trades for cusip=JPM +2019-12-18 16:20:59.084 INFO 97261 --- [ main] i.p.test.client.service.TradeService : Returned 4 trades for cusip=GE +2019-12-18 16:20:59.084 INFO 97261 --- [ main] i.p.test.client.service.TradeService : Executed 10 cusip queries in 187 ms +``` +##### Function Update Command +Run the function update command using the **runclient.sh** script like: + +``` +./runclient.sh functionupdate 10 +... +2019-12-19 15:36:02.235 INFO 57857 --- [ main] i.p.test.client.service.TradeService : Updating 10 trades with function +2019-12-19 15:36:02.368 INFO 57857 --- [ main] i.p.test.client.service.TradeService : Updated trade 0 result=[true] +2019-12-19 15:36:02.484 INFO 57857 --- [ main] i.p.test.client.service.TradeService : Updated trade 1 result=[true] +2019-12-19 15:36:02.520 INFO 57857 --- [ main] i.p.test.client.service.TradeService : Updated trade 2 result=[true] +2019-12-19 15:36:02.556 INFO 57857 --- [ main] i.p.test.client.service.TradeService : Updated trade 3 result=[true] +2019-12-19 15:36:02.575 INFO 57857 --- [ main] i.p.test.client.service.TradeService : Updated trade 4 result=[true] +2019-12-19 15:36:02.596 INFO 57857 --- [ main] i.p.test.client.service.TradeService : Updated trade 5 result=[true] +2019-12-19 15:36:02.596 INFO 57857 --- [ main] i.p.test.client.service.TradeService : Updated trade 6 result=[true] +2019-12-19 15:36:02.636 INFO 57857 --- [ main] i.p.test.client.service.TradeService : Updated trade 7 result=[true] +2019-12-19 15:36:02.661 INFO 57857 --- [ main] i.p.test.client.service.TradeService : Updated trade 8 result=[true] +2019-12-19 15:36:02.683 INFO 57857 --- [ main] i.p.test.client.service.TradeService : Updated trade 9 result=[true] +2019-12-19 15:36:02.683 INFO 57857 --- [ main] i.p.test.client.service.TradeService : Updated 10 trades with function in 448 ms +``` +##### Put Forever Command +Run the put forever command using the **runclient.sh** script like: + +``` +./runclient.sh putforever 10 1024 +... +2019-12-18 16:25:13.375 INFO 97527 --- [ main] i.p.test.client.service.TradeService : Putting trades forever of size 1024 bytes +2019-12-18 16:25:26.151 INFO 97527 --- [ main] i.p.test.client.service.TradeService : Put 10000 trades of size 1024 bytes in 12776 ms +2019-12-18 16:25:33.715 INFO 97527 --- [ main] i.p.test.client.service.TradeService : Put 20000 trades of size 1024 bytes in 7564 ms +2019-12-18 16:25:39.731 INFO 97527 --- [ main] i.p.test.client.service.TradeService : Put 30000 trades of size 1024 bytes in 6016 ms +2019-12-18 16:25:45.077 INFO 97527 --- [ main] i.p.test.client.service.TradeService : Put 40000 trades of size 1024 bytes in 5346 ms +2019-12-18 16:25:50.076 INFO 97527 --- [ main] i.p.test.client.service.TradeService : Put 50000 trades of size 1024 bytes in 4999 ms +2019-12-18 16:25:55.212 INFO 97527 --- [ main] i.p.test.client.service.TradeService : Put 60000 trades of size 1024 bytes in 5135 ms +2019-12-18 16:26:00.291 INFO 97527 --- [ main] i.p.test.client.service.TradeService : Put 70000 trades of size 1024 bytes in 5078 ms +2019-12-18 16:26:05.810 INFO 97527 --- [ main] i.p.test.client.service.TradeService : Put 80000 trades of size 1024 bytes in 5519 ms +2019-12-18 16:26:10.709 INFO 97527 --- [ main] i.p.test.client.service.TradeService : Put 90000 trades of size 1024 bytes in 4899 ms +2019-12-18 16:26:15.723 INFO 97527 --- [ main] i.p.test.client.service.TradeService : Put 100000 trades of size 1024 bytes in 5014 ms +... +``` +##### Get Forever Command +Run the get forever command using the **runclient.sh** script like: + +``` +./runclient.sh getforever 10 +... +2019-12-18 16:28:41.760 INFO 97736 --- [ main] i.p.test.client.service.TradeService : Getting entries forever +2019-12-18 16:28:43.031 INFO 97736 --- [ main] i.p.test.client.service.TradeService : Got 10000 trades in 1271 ms +2019-12-18 16:28:43.892 INFO 97736 --- [ main] i.p.test.client.service.TradeService : Got 20000 trades in 861 ms +2019-12-18 16:28:44.760 INFO 97736 --- [ main] i.p.test.client.service.TradeService : Got 30000 trades in 868 ms +2019-12-18 16:28:45.509 INFO 97736 --- [ main] i.p.test.client.service.TradeService : Got 40000 trades in 749 ms +2019-12-18 16:28:46.274 INFO 97736 --- [ main] i.p.test.client.service.TradeService : Got 50000 trades in 765 ms +2019-12-18 16:28:47.087 INFO 97736 --- [ main] i.p.test.client.service.TradeService : Got 60000 trades in 812 ms +2019-12-18 16:28:47.808 INFO 97736 --- [ main] i.p.test.client.service.TradeService : Got 70000 trades in 721 ms +2019-12-18 16:28:48.550 INFO 97736 --- [ main] i.p.test.client.service.TradeService : Got 80000 trades in 742 ms +2019-12-18 16:28:49.301 INFO 97736 --- [ main] i.p.test.client.service.TradeService : Got 90000 trades in 750 ms +2019-12-18 16:28:50.037 INFO 97736 --- [ main] i.p.test.client.service.TradeService : Got 100000 trades in 736 ms +... +``` +##### Destroy Forever Command +Run the destroy forever command using the **runclient.sh** script like: + +``` +./runclient.sh destroyforever 10 +... +2019-12-18 16:31:22.751 INFO 97971 --- [ main] i.p.test.client.service.TradeService : Destroying trades forever +2019-12-18 16:31:23.175 INFO 97971 --- [Timer-DEFAULT-3] o.a.g.internal.admin.ClientStatsManager : ClientStatsManager, intializing the statistics... +2019-12-18 16:31:23.630 INFO 97971 --- [ main] i.p.test.client.service.TradeService : Destroyed 10000 trades in 879 ms +2019-12-18 16:31:24.325 INFO 97971 --- [ main] i.p.test.client.service.TradeService : Destroyed 20000 trades in 695 ms +2019-12-18 16:31:25.111 INFO 97971 --- [ main] i.p.test.client.service.TradeService : Destroyed 30000 trades in 786 ms +2019-12-18 16:31:25.807 INFO 97971 --- [ main] i.p.test.client.service.TradeService : Destroyed 40000 trades in 696 ms +2019-12-18 16:31:26.446 INFO 97971 --- [ main] i.p.test.client.service.TradeService : Destroyed 50000 trades in 639 ms +2019-12-18 16:31:27.089 INFO 97971 --- [ main] i.p.test.client.service.TradeService : Destroyed 60000 trades in 643 ms +2019-12-18 16:31:27.842 INFO 97971 --- [ main] i.p.test.client.service.TradeService : Destroyed 70000 trades in 753 ms +2019-12-18 16:31:28.495 INFO 97971 --- [ main] i.p.test.client.service.TradeService : Destroyed 80000 trades in 653 ms +2019-12-18 16:31:29.127 INFO 97971 --- [ main] i.p.test.client.service.TradeService : Destroyed 90000 trades in 632 ms +2019-12-18 16:31:29.807 INFO 97971 --- [ main] i.p.test.client.service.TradeService : Destroyed 100000 trades in 680 ms +... +``` +##### Query by Cusip Forever Command +Run the query-by-cusip forever command using the **runclient.sh** script like: + +``` +./runclient.sh querybycusipforever +... +2019-12-18 16:35:55.360 INFO 98398 --- [ main] i.p.test.client.service.TradeService : Executing cusip queries forever +2019-12-18 16:36:18.278 INFO 98398 --- [ main] i.p.test.client.service.TradeService : Executed 10000 cusip queries in 22918 ms +2019-12-18 16:36:38.614 INFO 98398 --- [ main] i.p.test.client.service.TradeService : Executed 20000 cusip queries in 20336 ms +2019-12-18 16:36:58.543 INFO 98398 --- [ main] i.p.test.client.service.TradeService : Executed 30000 cusip queries in 19929 ms +2019-12-18 16:37:18.054 INFO 98398 --- [ main] i.p.test.client.service.TradeService : Executed 40000 cusip queries in 19511 ms +2019-12-18 16:37:38.098 INFO 98398 --- [ main] i.p.test.client.service.TradeService : Executed 50000 cusip queries in 20044 ms +2019-12-18 16:37:58.478 INFO 98398 --- [ main] i.p.test.client.service.TradeService : Executed 60000 cusip queries in 20380 ms +2019-12-18 16:38:18.119 INFO 98398 --- [ main] i.p.test.client.service.TradeService : Executed 70000 cusip queries in 19641 ms +2019-12-18 16:38:36.396 INFO 98398 --- [ main] i.p.test.client.service.TradeService : Executed 80000 cusip queries in 18277 ms +2019-12-18 16:38:55.145 INFO 98398 --- [ main] i.p.test.client.service.TradeService : Executed 90000 cusip queries in 18749 ms +2019-12-18 16:39:14.346 INFO 98398 --- [ main] i.p.test.client.service.TradeService : Executed 100000 cusip queries in 19201 ms +... +``` +##### Function Update Forever Command +Run the function update forever command using the **runclient.sh** script like: + +``` +./runclient.sh functionupdateforever 10 +... +2019-12-19 15:39:07.259 INFO 57950 --- [ Thread-6] i.p.test.client.service.TradeService : Updating 10 trades with function forever +2019-12-19 15:39:14.541 INFO 57950 --- [ Thread-6] i.p.test.client.service.TradeService : Updated 10000 trades with function in 7282 ms +2019-12-19 15:39:18.485 INFO 57950 --- [ Thread-6] i.p.test.client.service.TradeService : Updated 20000 trades with function in 3944 ms +2019-12-19 15:39:21.483 INFO 57950 --- [ Thread-6] i.p.test.client.service.TradeService : Updated 30000 trades with function in 2998 ms +2019-12-19 15:39:24.141 INFO 57950 --- [ Thread-6] i.p.test.client.service.TradeService : Updated 40000 trades with function in 2658 ms +2019-12-19 15:39:26.307 INFO 57950 --- [ Thread-6] i.p.test.client.service.TradeService : Updated 50000 trades with function in 2166 ms +2019-12-19 15:39:28.426 INFO 57950 --- [ Thread-6] i.p.test.client.service.TradeService : Updated 60000 trades with function in 2119 ms +2019-12-19 15:39:30.504 INFO 57950 --- [ Thread-6] i.p.test.client.service.TradeService : Updated 70000 trades with function in 2077 ms +2019-12-19 15:39:32.625 INFO 57950 --- [ Thread-6] i.p.test.client.service.TradeService : Updated 80000 trades with function in 2121 ms +2019-12-19 15:39:34.810 INFO 57950 --- [ Thread-6] i.p.test.client.service.TradeService : Updated 90000 trades with function in 2185 ms +2019-12-19 15:39:36.904 INFO 57950 --- [ Thread-6] i.p.test.client.service.TradeService : Updated 100000 trades with function in 2094 ms +... +``` +##### Multi-threaded Put Forever Command +Run the multi-threaded put forever command using the **runclient.sh** script like: + +``` +./runclient.sh putforever 10 1024 5 +... +2019-12-18 16:46:12.424 INFO 99172 --- [ Thread-6] i.p.test.client.service.TradeService : Putting trades forever of size 1024 bytes +2019-12-18 16:46:12.424 INFO 99172 --- [ Thread-7] i.p.test.client.service.TradeService : Putting trades forever of size 1024 bytes +2019-12-18 16:46:12.424 INFO 99172 --- [ Thread-8] i.p.test.client.service.TradeService : Putting trades forever of size 1024 bytes +2019-12-18 16:46:12.424 INFO 99172 --- [ Thread-9] i.p.test.client.service.TradeService : Putting trades forever of size 1024 bytes +2019-12-18 16:46:12.424 INFO 99172 --- [ Thread-10] i.p.test.client.service.TradeService : Putting trades forever of size 1024 bytes +2019-12-18 16:46:22.227 INFO 99172 --- [ Thread-9] i.p.test.client.service.TradeService : Put 10000 trades of size 1024 bytes in 9802 ms +2019-12-18 16:46:22.255 INFO 99172 --- [ Thread-8] i.p.test.client.service.TradeService : Put 10000 trades of size 1024 bytes in 9831 ms +2019-12-18 16:46:22.255 INFO 99172 --- [ Thread-7] i.p.test.client.service.TradeService : Put 10000 trades of size 1024 bytes in 9831 ms +2019-12-18 16:46:22.263 INFO 99172 --- [ Thread-6] i.p.test.client.service.TradeService : Put 10000 trades of size 1024 bytes in 9839 ms +2019-12-18 16:46:22.277 INFO 99172 --- [ Thread-10] i.p.test.client.service.TradeService : Put 10000 trades of size 1024 bytes in 9853 ms +2019-12-18 16:46:30.672 INFO 99172 --- [ Thread-10] i.p.test.client.service.TradeService : Put 20000 trades of size 1024 bytes in 8395 ms +2019-12-18 16:46:30.676 INFO 99172 --- [ Thread-9] i.p.test.client.service.TradeService : Put 20000 trades of size 1024 bytes in 8448 ms +2019-12-18 16:46:30.692 INFO 99172 --- [ Thread-7] i.p.test.client.service.TradeService : Put 20000 trades of size 1024 bytes in 8437 ms +2019-12-18 16:46:30.696 INFO 99172 --- [ Thread-8] i.p.test.client.service.TradeService : Put 20000 trades of size 1024 bytes in 8441 ms +2019-12-18 16:46:30.711 INFO 99172 --- [ Thread-6] i.p.test.client.service.TradeService : Put 20000 trades of size 1024 bytes in 8448 ms +2019-12-18 16:46:38.654 INFO 99172 --- [ Thread-10] i.p.test.client.service.TradeService : Put 30000 trades of size 1024 bytes in 7982 ms +2019-12-18 16:46:38.702 INFO 99172 --- [ Thread-9] i.p.test.client.service.TradeService : Put 30000 trades of size 1024 bytes in 8026 ms +2019-12-18 16:46:38.730 INFO 99172 --- [ Thread-8] i.p.test.client.service.TradeService : Put 30000 trades of size 1024 bytes in 8034 ms +2019-12-18 16:46:38.730 INFO 99172 --- [ Thread-6] i.p.test.client.service.TradeService : Put 30000 trades of size 1024 bytes in 8018 ms +2019-12-18 16:46:38.736 INFO 99172 --- [ Thread-7] i.p.test.client.service.TradeService : Put 30000 trades of size 1024 bytes in 8044 ms +... +``` +##### Multi-threaded Get Forever Command +Run the multi-threaded get forever command using the **runclient.sh** script like: + +``` +./runclient.sh getforever 10 5 +... +2019-12-18 16:49:08.951 INFO 99345 --- [ Thread-6] i.p.test.client.service.TradeService : Getting entries forever +2019-12-18 16:49:08.951 INFO 99345 --- [ Thread-7] i.p.test.client.service.TradeService : Getting entries forever +2019-12-18 16:49:08.951 INFO 99345 --- [ Thread-8] i.p.test.client.service.TradeService : Getting entries forever +2019-12-18 16:49:08.951 INFO 99345 --- [ Thread-9] i.p.test.client.service.TradeService : Getting entries forever +2019-12-18 16:49:08.951 INFO 99345 --- [ Thread-10] i.p.test.client.service.TradeService : Getting entries forever +2019-12-18 16:49:10.288 INFO 99345 --- [ Thread-10] i.p.test.client.service.TradeService : Got 10000 trades in 1337 ms +2019-12-18 16:49:10.292 INFO 99345 --- [ Thread-6] i.p.test.client.service.TradeService : Got 10000 trades in 1341 ms +2019-12-18 16:49:10.294 INFO 99345 --- [ Thread-9] i.p.test.client.service.TradeService : Got 10000 trades in 1343 ms +2019-12-18 16:49:10.295 INFO 99345 --- [ Thread-7] i.p.test.client.service.TradeService : Got 10000 trades in 1344 ms +2019-12-18 16:49:10.297 INFO 99345 --- [ Thread-8] i.p.test.client.service.TradeService : Got 10000 trades in 1346 ms +2019-12-18 16:49:11.192 INFO 99345 --- [ Thread-10] i.p.test.client.service.TradeService : Got 20000 trades in 904 ms +2019-12-18 16:49:11.195 INFO 99345 --- [ Thread-6] i.p.test.client.service.TradeService : Got 20000 trades in 901 ms +2019-12-18 16:49:11.200 INFO 99345 --- [ Thread-7] i.p.test.client.service.TradeService : Got 20000 trades in 905 ms +2019-12-18 16:49:11.201 INFO 99345 --- [ Thread-8] i.p.test.client.service.TradeService : Got 20000 trades in 904 ms +2019-12-18 16:49:11.204 INFO 99345 --- [ Thread-9] i.p.test.client.service.TradeService : Got 20000 trades in 910 ms +2019-12-18 16:49:12.059 INFO 99345 --- [ Thread-10] i.p.test.client.service.TradeService : Got 30000 trades in 867 ms +2019-12-18 16:49:12.065 INFO 99345 --- [ Thread-6] i.p.test.client.service.TradeService : Got 30000 trades in 870 ms +2019-12-18 16:49:12.068 INFO 99345 --- [ Thread-8] i.p.test.client.service.TradeService : Got 30000 trades in 867 ms +2019-12-18 16:49:12.070 INFO 99345 --- [ Thread-7] i.p.test.client.service.TradeService : Got 30000 trades in 870 ms +2019-12-18 16:49:12.075 INFO 99345 --- [ Thread-9] i.p.test.client.service.TradeService : Got 30000 trades in 871 ms +... +``` +##### Multi-threaded Destroy Forever Command +Run the multi-threaded destroy forever threads command using the **runclient.sh** script like: + +``` +./runclient.sh destroyforever 10 5 +... +2019-12-18 16:52:34.692 INFO 99731 --- [ Thread-6] i.p.test.client.service.TradeService : Destroying trades forever +2019-12-18 16:52:34.692 INFO 99731 --- [ Thread-7] i.p.test.client.service.TradeService : Destroying trades forever +2019-12-18 16:52:34.692 INFO 99731 --- [ Thread-8] i.p.test.client.service.TradeService : Destroying trades forever +2019-12-18 16:52:34.692 INFO 99731 --- [ Thread-9] i.p.test.client.service.TradeService : Destroying trades forever +2019-12-18 16:52:34.693 INFO 99731 --- [ Thread-10] i.p.test.client.service.TradeService : Destroying trades forever +2019-12-18 16:52:35.831 INFO 99731 --- [ Thread-6] i.p.test.client.service.TradeService : Destroyed 10000 trades in 1139 ms +2019-12-18 16:52:35.835 INFO 99731 --- [ Thread-8] i.p.test.client.service.TradeService : Destroyed 10000 trades in 1143 ms +2019-12-18 16:52:35.835 INFO 99731 --- [ Thread-10] i.p.test.client.service.TradeService : Destroyed 10000 trades in 1142 ms +2019-12-18 16:52:35.837 INFO 99731 --- [ Thread-7] i.p.test.client.service.TradeService : Destroyed 10000 trades in 1145 ms +2019-12-18 16:52:35.840 INFO 99731 --- [ Thread-9] i.p.test.client.service.TradeService : Destroyed 10000 trades in 1147 ms +2019-12-18 16:52:36.920 INFO 99731 --- [ Thread-6] i.p.test.client.service.TradeService : Destroyed 20000 trades in 1088 ms +2019-12-18 16:52:36.923 INFO 99731 --- [ Thread-7] i.p.test.client.service.TradeService : Destroyed 20000 trades in 1086 ms +2019-12-18 16:52:36.923 INFO 99731 --- [ Thread-10] i.p.test.client.service.TradeService : Destroyed 20000 trades in 1088 ms +2019-12-18 16:52:36.925 INFO 99731 --- [ Thread-8] i.p.test.client.service.TradeService : Destroyed 20000 trades in 1090 ms +2019-12-18 16:52:36.927 INFO 99731 --- [ Thread-9] i.p.test.client.service.TradeService : Destroyed 20000 trades in 1087 ms +2019-12-18 16:52:37.864 INFO 99731 --- [ Thread-6] i.p.test.client.service.TradeService : Destroyed 30000 trades in 944 ms +2019-12-18 16:52:37.867 INFO 99731 --- [ Thread-10] i.p.test.client.service.TradeService : Destroyed 30000 trades in 943 ms +2019-12-18 16:52:37.867 INFO 99731 --- [ Thread-8] i.p.test.client.service.TradeService : Destroyed 30000 trades in 942 ms +2019-12-18 16:52:37.868 INFO 99731 --- [ Thread-9] i.p.test.client.service.TradeService : Destroyed 30000 trades in 941 ms +2019-12-18 16:52:37.869 INFO 99731 --- [ Thread-7] i.p.test.client.service.TradeService : Destroyed 30000 trades in 946 ms +... +``` +##### Multi-threaded Query by Cusip Forever Command +Run the multi-threaded query-by-cusip forever command using the **runclient.sh** script like: + +``` +./runclient.sh querybycusipforever 5 +... +2019-12-18 16:54:15.296 INFO 99865 --- [ Thread-6] i.p.test.client.service.TradeService : Executing cusip queries forever +2019-12-18 16:54:15.297 INFO 99865 --- [ Thread-8] i.p.test.client.service.TradeService : Executing cusip queries forever +2019-12-18 16:54:15.297 INFO 99865 --- [ Thread-7] i.p.test.client.service.TradeService : Executing cusip queries forever +2019-12-18 16:54:15.297 INFO 99865 --- [ Thread-9] i.p.test.client.service.TradeService : Executing cusip queries forever +2019-12-18 16:54:15.297 INFO 99865 --- [ Thread-10] i.p.test.client.service.TradeService : Executing cusip queries forever +2019-12-18 16:55:12.166 INFO 99865 --- [ Thread-6] i.p.test.client.service.TradeService : Executed 10000 cusip queries in 56869 ms +2019-12-18 16:55:12.226 INFO 99865 --- [ Thread-10] i.p.test.client.service.TradeService : Executed 10000 cusip queries in 56929 ms +2019-12-18 16:55:12.426 INFO 99865 --- [ Thread-8] i.p.test.client.service.TradeService : Executed 10000 cusip queries in 57129 ms +2019-12-18 16:55:12.654 INFO 99865 --- [ Thread-9] i.p.test.client.service.TradeService : Executed 10000 cusip queries in 57357 ms +2019-12-18 16:55:12.763 INFO 99865 --- [ Thread-7] i.p.test.client.service.TradeService : Executed 10000 cusip queries in 57466 ms +2019-12-18 16:56:09.829 INFO 99865 --- [ Thread-6] i.p.test.client.service.TradeService : Executed 20000 cusip queries in 57663 ms +2019-12-18 16:56:09.831 INFO 99865 --- [ Thread-10] i.p.test.client.service.TradeService : Executed 20000 cusip queries in 57605 ms +2019-12-18 16:56:10.236 INFO 99865 --- [ Thread-8] i.p.test.client.service.TradeService : Executed 20000 cusip queries in 57810 ms +2019-12-18 16:56:10.355 INFO 99865 --- [ Thread-7] i.p.test.client.service.TradeService : Executed 20000 cusip queries in 57592 ms +2019-12-18 16:56:10.390 INFO 99865 --- [ Thread-9] i.p.test.client.service.TradeService : Executed 20000 cusip queries in 57735 ms +2019-12-18 16:57:13.819 INFO 99865 --- [ Thread-10] i.p.test.client.service.TradeService : Executed 30000 cusip queries in 63988 ms +2019-12-18 16:57:14.317 INFO 99865 --- [ Thread-6] i.p.test.client.service.TradeService : Executed 30000 cusip queries in 64487 ms +2019-12-18 16:57:14.716 INFO 99865 --- [ Thread-7] i.p.test.client.service.TradeService : Executed 30000 cusip queries in 64361 ms +2019-12-18 16:57:14.923 INFO 99865 --- [ Thread-8] i.p.test.client.service.TradeService : Executed 30000 cusip queries in 64687 ms +2019-12-18 16:57:15.151 INFO 99865 --- [ Thread-9] i.p.test.client.service.TradeService : Executed 30000 cusip queries in 64761 ms +... +``` +##### Multi-threaded Function Update Forever Command +Run the multi-threaded function update forever command using the **runclient.sh** script like: + +``` +./runclient.sh functionupdateforever 10 5 +... +2019-12-19 15:46:58.070 INFO 58292 --- [ Thread-7] i.p.test.client.service.TradeService : Updating 10 trades with function forever +2019-12-19 15:46:58.070 INFO 58292 --- [ Thread-6] i.p.test.client.service.TradeService : Updating 10 trades with function forever +2019-12-19 15:46:58.070 INFO 58292 --- [ Thread-8] i.p.test.client.service.TradeService : Updating 10 trades with function forever +2019-12-19 15:46:58.070 INFO 58292 --- [ Thread-9] i.p.test.client.service.TradeService : Updating 10 trades with function forever +2019-12-19 15:46:58.070 INFO 58292 --- [ Thread-10] i.p.test.client.service.TradeService : Updating 10 trades with function forever +2019-12-19 15:47:03.126 INFO 58292 --- [ Thread-6] i.p.test.client.service.TradeService : Updated 10000 trades with function in 5056 ms +2019-12-19 15:47:03.136 INFO 58292 --- [ Thread-8] i.p.test.client.service.TradeService : Updated 10000 trades with function in 5066 ms +2019-12-19 15:47:03.141 INFO 58292 --- [ Thread-10] i.p.test.client.service.TradeService : Updated 10000 trades with function in 5071 ms +2019-12-19 15:47:03.145 INFO 58292 --- [ Thread-7] i.p.test.client.service.TradeService : Updated 10000 trades with function in 5075 ms +2019-12-19 15:47:03.146 INFO 58292 --- [ Thread-9] i.p.test.client.service.TradeService : Updated 10000 trades with function in 5076 ms +2019-12-19 15:47:06.926 INFO 58292 --- [ Thread-10] i.p.test.client.service.TradeService : Updated 20000 trades with function in 3784 ms +2019-12-19 15:47:06.926 INFO 58292 --- [ Thread-7] i.p.test.client.service.TradeService : Updated 20000 trades with function in 3781 ms +2019-12-19 15:47:06.927 INFO 58292 --- [ Thread-8] i.p.test.client.service.TradeService : Updated 20000 trades with function in 3791 ms +2019-12-19 15:47:06.930 INFO 58292 --- [ Thread-6] i.p.test.client.service.TradeService : Updated 20000 trades with function in 3804 ms +2019-12-19 15:47:06.943 INFO 58292 --- [ Thread-9] i.p.test.client.service.TradeService : Updated 20000 trades with function in 3797 ms +2019-12-19 15:47:10.836 INFO 58292 --- [ Thread-10] i.p.test.client.service.TradeService : Updated 30000 trades with function in 3910 ms +2019-12-19 15:47:10.840 INFO 58292 --- [ Thread-7] i.p.test.client.service.TradeService : Updated 30000 trades with function in 3914 ms +2019-12-19 15:47:10.845 INFO 58292 --- [ Thread-8] i.p.test.client.service.TradeService : Updated 30000 trades with function in 3918 ms +2019-12-19 15:47:10.846 INFO 58292 --- [ Thread-6] i.p.test.client.service.TradeService : Updated 30000 trades with function in 3916 ms +2019-12-19 15:47:10.862 INFO 58292 --- [ Thread-9] i.p.test.client.service.TradeService : Updated 30000 trades with function in 3919 ms +... +``` +##### Get One Command +Run the get one command using the **runclient.sh** script like: + +``` +./runclient.sh getone 0 +... +2019-12-18 16:59:25.722 INFO 551 --- [ main] i.p.test.client.service.TradeService : Got Trade(id=0, cusip=GOOGL, shares=27, price=278.51) +``` +##### Query One By Cusip Command +Run the query one by cusip command using the **runclient.sh** script like: + +``` +./runclient.sh queryonebycusip AAPL +... +2019-12-18 17:00:23.615 INFO 636 --- [ main] i.p.test.client.service.TradeService : Executing query for cusip=AAPL +2019-12-18 17:00:23.689 INFO 636 --- [ main] i.p.test.client.service.TradeService : Returned 5 trades for cusip=AAPL in 74 ms: +2019-12-18 17:00:23.689 INFO 636 --- [ main] i.p.test.client.service.TradeService : Trade(id=98, cusip=AAPL, shares=24, price=305.78) +2019-12-18 17:00:23.689 INFO 636 --- [ main] i.p.test.client.service.TradeService : Trade(id=43, cusip=AAPL, shares=0, price=833.94) +2019-12-18 17:00:23.689 INFO 636 --- [ main] i.p.test.client.service.TradeService : Trade(id=68, cusip=AAPL, shares=64, price=383.67) +2019-12-18 17:00:23.689 INFO 636 --- [ main] i.p.test.client.service.TradeService : Trade(id=99, cusip=AAPL, shares=52, price=169.36) +2019-12-18 17:00:23.690 INFO 636 --- [ main] i.p.test.client.service.TradeService : Trade(id=75, cusip=AAPL, shares=45, price=273.66) +``` +##### Test Command +Run the test command using the **runclient.sh** script like: + +``` +./runclient.sh starttest 10 1024 1 +... +2019-12-18 17:02:27.921 INFO 855 --- [ Thread-6] i.p.test.client.service.TradeService : Putting trades forever of size 1024 bytes +2019-12-18 17:02:27.922 INFO 855 --- [ Thread-7] i.p.test.client.service.TradeService : Getting entries forever +2019-12-18 17:02:27.922 INFO 855 --- [ Thread-8] i.p.test.client.service.TradeService : Executing cusip queries forever +2019-12-18 17:02:29.679 INFO 855 --- [ Thread-7] i.p.test.client.service.TradeService : Got 10000 trades in 1757 ms +2019-12-18 17:02:31.141 INFO 855 --- [ Thread-7] i.p.test.client.service.TradeService : Got 20000 trades in 1462 ms +2019-12-18 17:02:32.653 INFO 855 --- [ Thread-7] i.p.test.client.service.TradeService : Got 30000 trades in 1512 ms +2019-12-18 17:02:36.009 INFO 855 --- [ Thread-6] i.p.test.client.service.TradeService : Put 10000 trades of size 1024 bytes in 8088 ms +2019-12-18 17:02:43.971 INFO 855 --- [ Thread-6] i.p.test.client.service.TradeService : Put 20000 trades of size 1024 bytes in 7962 ms +2019-12-18 17:02:50.814 INFO 855 --- [ Thread-8] i.p.test.client.service.TradeService : Executed 10000 cusip queries in 22892 ms +2019-12-18 17:02:51.744 INFO 855 --- [ Thread-6] i.p.test.client.service.TradeService : Put 30000 trades of size 1024 bytes in 7772 ms +2019-12-18 17:03:13.281 INFO 855 --- [ Thread-8] i.p.test.client.service.TradeService : Executed 20000 cusip queries in 22467 ms +2019-12-18 17:03:35.607 INFO 855 --- [ Thread-8] i.p.test.client.service.TradeService : Executed 30000 cusip queries in 22325 ms +... +``` +#### REST +##### Start Client Application +Start the client application using the **runclient.sh** script like: + +``` +./runclient.sh wait +2019-12-18 17:06:49.078 INFO 1239 --- [ main] io.pivotal.test.client.Client : Started Client in 2.917 seconds (JVM running for 3.252) +2019-12-18 17:06:49.106 INFO 1239 --- [ main] io.pivotal.test.client.Client : Client Command Line Arguments: [--spring.profiles.active=local, --operation=wait] +2019-12-18 17:06:49.106 INFO 1239 --- [ main] io.pivotal.test.client.Client : Client Option Argument: operation=[wait] +2019-12-18 17:06:49.106 INFO 1239 --- [ main] io.pivotal.test.client.Client : Client Option Argument: spring.profiles.active=[local] +``` +##### Put Command +Run the put command using **curl** like: + +``` +curl -X POST http://localhost:8080/trades/put/10/1024 +{"operation":"put","status":"SUCCESS","completionTime":55} +``` +The application will log messages like: + +``` +2019-12-18 17:09:00.073 INFO 1239 --- [nio-8080-exec-1] i.p.test.client.service.TradeService : Putting 10 trades of size 1024 bytes +2019-12-18 17:09:00.100 INFO 1239 --- [nio-8080-exec-1] i.p.test.client.service.TradeService : Saved Trade(id=0, cusip=JNJ, shares=43, price=176.49) +2019-12-18 17:09:00.103 INFO 1239 --- [nio-8080-exec-1] i.p.test.client.service.TradeService : Saved Trade(id=1, cusip=MA, shares=40, price=45.30) +2019-12-18 17:09:00.107 INFO 1239 --- [nio-8080-exec-1] i.p.test.client.service.TradeService : Saved Trade(id=2, cusip=SBUX, shares=36, price=329.88) +2019-12-18 17:09:00.111 INFO 1239 --- [nio-8080-exec-1] i.p.test.client.service.TradeService : Saved Trade(id=3, cusip=UNP, shares=91, price=944.36) +2019-12-18 17:09:00.113 INFO 1239 --- [nio-8080-exec-1] i.p.test.client.service.TradeService : Saved Trade(id=4, cusip=MMM, shares=14, price=295.43) +2019-12-18 17:09:00.118 INFO 1239 --- [nio-8080-exec-1] i.p.test.client.service.TradeService : Saved Trade(id=5, cusip=NFLX, shares=42, price=808.43) +2019-12-18 17:09:00.121 INFO 1239 --- [nio-8080-exec-1] i.p.test.client.service.TradeService : Saved Trade(id=6, cusip=BA, shares=46, price=431.10) +2019-12-18 17:09:00.125 INFO 1239 --- [nio-8080-exec-1] i.p.test.client.service.TradeService : Saved Trade(id=7, cusip=AAPL, shares=26, price=163.14) +2019-12-18 17:09:00.127 INFO 1239 --- [nio-8080-exec-1] i.p.test.client.service.TradeService : Saved Trade(id=8, cusip=QCOM, shares=14, price=5.41) +2019-12-18 17:09:00.128 INFO 1239 --- [nio-8080-exec-1] i.p.test.client.service.TradeService : Saved Trade(id=9, cusip=TXN, shares=13, price=149.88) +2019-12-18 17:09:00.128 INFO 1239 --- [nio-8080-exec-1] i.p.test.client.service.TradeService : Put 10 trades of size 1024 bytes in 55 ms +``` +###### Get Command +Run the get command using **curl** like: + +``` +curl http://localhost:8080/trades/get/10 +{"operation":"get","status":"SUCCESS","completionTime":41} +``` +The application will log messages like: + +``` +2019-12-18 17:14:33.635 INFO 1239 --- [nio-8080-exec-4] i.p.test.client.service.TradeService : Getting 10 trades +2019-12-18 17:14:33.648 INFO 1239 --- [nio-8080-exec-4] i.p.test.client.service.TradeService : Got Trade(id=0, cusip=JNJ, shares=43, price=176.49) +2019-12-18 17:14:33.649 INFO 1239 --- [nio-8080-exec-4] i.p.test.client.service.TradeService : Got Trade(id=1, cusip=MA, shares=40, price=45.30) +2019-12-18 17:14:33.671 INFO 1239 --- [nio-8080-exec-4] i.p.test.client.service.TradeService : Got Trade(id=2, cusip=SBUX, shares=36, price=329.88) +2019-12-18 17:14:33.674 INFO 1239 --- [nio-8080-exec-4] i.p.test.client.service.TradeService : Got Trade(id=3, cusip=UNP, shares=91, price=944.36) +2019-12-18 17:14:33.675 INFO 1239 --- [nio-8080-exec-4] i.p.test.client.service.TradeService : Got Trade(id=4, cusip=MMM, shares=14, price=295.43) +2019-12-18 17:14:33.675 INFO 1239 --- [nio-8080-exec-4] i.p.test.client.service.TradeService : Got Trade(id=5, cusip=NFLX, shares=42, price=808.43) +2019-12-18 17:14:33.676 INFO 1239 --- [nio-8080-exec-4] i.p.test.client.service.TradeService : Got Trade(id=6, cusip=BA, shares=46, price=431.10) +2019-12-18 17:14:33.676 INFO 1239 --- [nio-8080-exec-4] i.p.test.client.service.TradeService : Got Trade(id=7, cusip=AAPL, shares=26, price=163.14) +2019-12-18 17:14:33.677 INFO 1239 --- [nio-8080-exec-4] i.p.test.client.service.TradeService : Got Trade(id=8, cusip=QCOM, shares=14, price=5.41) +2019-12-18 17:14:33.677 INFO 1239 --- [nio-8080-exec-4] i.p.test.client.service.TradeService : Got Trade(id=9, cusip=TXN, shares=13, price=149.88) +2019-12-18 17:14:33.677 INFO 1239 --- [nio-8080-exec-4] i.p.test.client.service.TradeService : Got 10 trades in 41 ms +``` +##### Destroy Command +Run the destroy command using **curl** like: + +``` +curl -X DELETE http://localhost:8080/trades/destroy/10 +{"operation":"destroy","status":"SUCCESS","completionTime":35} +``` +The application will log messages like: + +``` +2019-12-18 17:17:34.514 INFO 1239 --- [nio-8080-exec-5] i.p.test.client.service.TradeService : Destroying 10 trades +2019-12-18 17:17:34.524 INFO 1239 --- [nio-8080-exec-5] i.p.test.client.service.TradeService : Destroyed key=0 +2019-12-18 17:17:34.527 INFO 1239 --- [nio-8080-exec-5] i.p.test.client.service.TradeService : Destroyed key=1 +2019-12-18 17:17:34.532 INFO 1239 --- [nio-8080-exec-5] i.p.test.client.service.TradeService : Destroyed key=2 +2019-12-18 17:17:34.537 INFO 1239 --- [nio-8080-exec-5] i.p.test.client.service.TradeService : Destroyed key=3 +2019-12-18 17:17:34.539 INFO 1239 --- [nio-8080-exec-5] i.p.test.client.service.TradeService : Destroyed key=4 +2019-12-18 17:17:34.541 INFO 1239 --- [nio-8080-exec-5] i.p.test.client.service.TradeService : Destroyed key=5 +2019-12-18 17:17:34.543 INFO 1239 --- [nio-8080-exec-5] i.p.test.client.service.TradeService : Destroyed key=6 +2019-12-18 17:17:34.545 INFO 1239 --- [nio-8080-exec-5] i.p.test.client.service.TradeService : Destroyed key=7 +2019-12-18 17:17:34.547 INFO 1239 --- [nio-8080-exec-5] i.p.test.client.service.TradeService : Destroyed key=8 +2019-12-18 17:17:34.549 INFO 1239 --- [nio-8080-exec-5] i.p.test.client.service.TradeService : Destroyed key=9 +2019-12-18 17:17:34.549 INFO 1239 --- [nio-8080-exec-5] i.p.test.client.service.TradeService : Destroyed 10 trades in 35 ms +``` +##### Query By Cusip Command +Run the query by cusip command using **curl** like: + +``` +curl http://localhost:8080/trades/querybycusip/10 +{"operation":"querybycusip","status":"SUCCESS","completionTime":71} +``` +The application will log messages like: + +``` +2019-12-18 17:18:54.977 INFO 1239 --- [nio-8080-exec-7] i.p.test.client.service.TradeService : Executing 10 cusip queries +2019-12-18 17:18:55.017 INFO 1239 --- [nio-8080-exec-7] i.p.test.client.service.TradeService : Returned 1 trades for cusip=JPM +2019-12-18 17:18:55.021 INFO 1239 --- [nio-8080-exec-7] i.p.test.client.service.TradeService : Returned 0 trades for cusip=KO +2019-12-18 17:18:55.024 INFO 1239 --- [nio-8080-exec-7] i.p.test.client.service.TradeService : Returned 0 trades for cusip=BUD +2019-12-18 17:18:55.028 INFO 1239 --- [nio-8080-exec-7] i.p.test.client.service.TradeService : Returned 1 trades for cusip=MRK +2019-12-18 17:18:55.031 INFO 1239 --- [nio-8080-exec-7] i.p.test.client.service.TradeService : Returned 1 trades for cusip=C +2019-12-18 17:18:55.035 INFO 1239 --- [nio-8080-exec-7] i.p.test.client.service.TradeService : Returned 3 trades for cusip=LMT +2019-12-18 17:18:55.038 INFO 1239 --- [nio-8080-exec-7] i.p.test.client.service.TradeService : Returned 0 trades for cusip=KO +2019-12-18 17:18:55.042 INFO 1239 --- [nio-8080-exec-7] i.p.test.client.service.TradeService : Returned 2 trades for cusip=WMT +2019-12-18 17:18:55.045 INFO 1239 --- [nio-8080-exec-7] i.p.test.client.service.TradeService : Returned 1 trades for cusip=MCD +2019-12-18 17:18:55.048 INFO 1239 --- [nio-8080-exec-7] i.p.test.client.service.TradeService : Returned 2 trades for cusip=NVS +2019-12-18 17:18:55.048 INFO 1239 --- [nio-8080-exec-7] i.p.test.client.service.TradeService : Executed 10 cusip queries in 71 ms +``` +##### Function Update Command +Run the function update command using **curl** like: + +``` +curl -X POST http://localhost:8080/trades/functionupdate/10 +{"operation":"functionupdate","status":"SUCCESS","completionTime":15} +``` +The application will log messages like: + +``` +2019-12-19 16:14:43.667 INFO 58371 --- [nio-8080-exec-1] i.p.test.client.service.TradeService : Updating 10 trades with function +2019-12-19 16:14:43.670 INFO 58371 --- [nio-8080-exec-1] i.p.test.client.service.TradeService : Updated trade 0 result=[true] +2019-12-19 16:14:43.674 INFO 58371 --- [nio-8080-exec-1] i.p.test.client.service.TradeService : Updated trade 1 result=[true] +2019-12-19 16:14:43.677 INFO 58371 --- [nio-8080-exec-1] i.p.test.client.service.TradeService : Updated trade 2 result=[true] +2019-12-19 16:14:43.678 INFO 58371 --- [nio-8080-exec-1] i.p.test.client.service.TradeService : Updated trade 3 result=[true] +2019-12-19 16:14:43.679 INFO 58371 --- [nio-8080-exec-1] i.p.test.client.service.TradeService : Updated trade 4 result=[true] +2019-12-19 16:14:43.680 INFO 58371 --- [nio-8080-exec-1] i.p.test.client.service.TradeService : Updated trade 5 result=[true] +2019-12-19 16:14:43.680 INFO 58371 --- [nio-8080-exec-1] i.p.test.client.service.TradeService : Updated trade 6 result=[true] +2019-12-19 16:14:43.681 INFO 58371 --- [nio-8080-exec-1] i.p.test.client.service.TradeService : Updated trade 7 result=[true] +2019-12-19 16:14:43.681 INFO 58371 --- [nio-8080-exec-1] i.p.test.client.service.TradeService : Updated trade 8 result=[true] +2019-12-19 16:14:43.682 INFO 58371 --- [nio-8080-exec-1] i.p.test.client.service.TradeService : Updated trade 9 result=[true] +2019-12-19 16:14:43.682 INFO 58371 --- [nio-8080-exec-1] i.p.test.client.service.TradeService : Updated 10 trades with function in 15 ms +``` +##### Put Forever Command +Run the function update command using **curl** like: + +``` +curl -X POST http://localhost:8080/trades/putforever/10/1024 +{"operation":"putforeverthreads","status":"SUCCESS","completionTime":0} +``` +The application will log messages like: + +``` +2019-12-18 17:21:49.050 INFO 1239 --- [ Thread-6] i.p.test.client.service.TradeService : Putting trades forever of size 1024 bytes +2019-12-18 17:21:56.581 INFO 1239 --- [ Thread-6] i.p.test.client.service.TradeService : Put 10000 trades of size 1024 bytes in 7531 ms +2019-12-18 17:22:05.740 INFO 1239 --- [ Thread-6] i.p.test.client.service.TradeService : Put 20000 trades of size 1024 bytes in 9159 ms +2019-12-18 17:22:11.330 INFO 1239 --- [ Thread-6] i.p.test.client.service.TradeService : Put 30000 trades of size 1024 bytes in 5590 ms +2019-12-18 17:22:16.271 INFO 1239 --- [ Thread-6] i.p.test.client.service.TradeService : Put 40000 trades of size 1024 bytes in 4941 ms +2019-12-18 17:22:21.705 INFO 1239 --- [ Thread-6] i.p.test.client.service.TradeService : Put 50000 trades of size 1024 bytes in 5434 ms +2019-12-18 17:22:27.906 INFO 1239 --- [ Thread-6] i.p.test.client.service.TradeService : Put 60000 trades of size 1024 bytes in 6201 ms +2019-12-18 17:22:33.774 INFO 1239 --- [ Thread-6] i.p.test.client.service.TradeService : Put 70000 trades of size 1024 bytes in 5868 ms +2019-12-18 17:22:39.254 INFO 1239 --- [ Thread-6] i.p.test.client.service.TradeService : Put 80000 trades of size 1024 bytes in 5480 ms +2019-12-18 17:22:44.481 INFO 1239 --- [ Thread-6] i.p.test.client.service.TradeService : Put 90000 trades of size 1024 bytes in 5226 ms +2019-12-18 17:22:49.693 INFO 1239 --- [ Thread-6] i.p.test.client.service.TradeService : Put 100000 trades of size 1024 bytes in 5210 ms +... +``` +##### Get Forever Command +Run the function update command using **curl** like: + +``` +curl http://localhost:8080/trades/getforever/10 +{"operation":"getforeverthreads","status":"SUCCESS","completionTime":0} +``` +The application will log messages like: + +``` +2019-12-18 17:23:47.516 INFO 1239 --- [ Thread-7] i.p.test.client.service.TradeService : Getting entries forever +2019-12-18 17:23:48.358 INFO 1239 --- [ Thread-7] i.p.test.client.service.TradeService : Got 10000 trades in 842 ms +2019-12-18 17:23:49.069 INFO 1239 --- [ Thread-7] i.p.test.client.service.TradeService : Got 20000 trades in 711 ms +2019-12-18 17:23:49.789 INFO 1239 --- [ Thread-7] i.p.test.client.service.TradeService : Got 30000 trades in 720 ms +2019-12-18 17:23:50.512 INFO 1239 --- [ Thread-7] i.p.test.client.service.TradeService : Got 40000 trades in 723 ms +2019-12-18 17:23:51.247 INFO 1239 --- [ Thread-7] i.p.test.client.service.TradeService : Got 50000 trades in 735 ms +2019-12-18 17:23:51.971 INFO 1239 --- [ Thread-7] i.p.test.client.service.TradeService : Got 60000 trades in 724 ms +2019-12-18 17:23:52.672 INFO 1239 --- [ Thread-7] i.p.test.client.service.TradeService : Got 70000 trades in 701 ms +2019-12-18 17:23:53.376 INFO 1239 --- [ Thread-7] i.p.test.client.service.TradeService : Got 80000 trades in 704 ms +2019-12-18 17:23:54.067 INFO 1239 --- [ Thread-7] i.p.test.client.service.TradeService : Got 90000 trades in 691 ms +2019-12-18 17:23:54.749 INFO 1239 --- [ Thread-7] i.p.test.client.service.TradeService : Got 100000 trades in 681 ms +... +``` +##### Destroy Forever Command +Run the function update command using **curl** like: + +``` +curl -X DELETE http://localhost:8080/trades/destroyforever/10 +{"operation":"destroyforeverthreads","status":"SUCCESS","completionTime":0} +``` +The application will log messages like: + +``` +2019-12-18 17:24:45.007 INFO 1239 --- [ Thread-8] i.p.test.client.service.TradeService : Destroying trades forever +2019-12-18 17:24:45.763 INFO 1239 --- [ Thread-8] i.p.test.client.service.TradeService : Destroyed 10000 trades in 756 ms +2019-12-18 17:24:46.471 INFO 1239 --- [ Thread-8] i.p.test.client.service.TradeService : Destroyed 20000 trades in 707 ms +2019-12-18 17:24:47.193 INFO 1239 --- [ Thread-8] i.p.test.client.service.TradeService : Destroyed 30000 trades in 722 ms +2019-12-18 17:24:47.892 INFO 1239 --- [ Thread-8] i.p.test.client.service.TradeService : Destroyed 40000 trades in 699 ms +2019-12-18 17:24:48.585 INFO 1239 --- [ Thread-8] i.p.test.client.service.TradeService : Destroyed 50000 trades in 693 ms +2019-12-18 17:24:49.280 INFO 1239 --- [ Thread-8] i.p.test.client.service.TradeService : Destroyed 60000 trades in 695 ms +2019-12-18 17:24:49.952 INFO 1239 --- [ Thread-8] i.p.test.client.service.TradeService : Destroyed 70000 trades in 672 ms +2019-12-18 17:24:50.604 INFO 1239 --- [ Thread-8] i.p.test.client.service.TradeService : Destroyed 80000 trades in 652 ms +2019-12-18 17:24:51.302 INFO 1239 --- [ Thread-8] i.p.test.client.service.TradeService : Destroyed 90000 trades in 698 ms +2019-12-18 17:24:52.037 INFO 1239 --- [ Thread-8] i.p.test.client.service.TradeService : Destroyed 100000 trades in 735 ms +2019-12-18 17:24:52.709 INFO 1239 --- [ Thread-8] i.p.test.client.service.TradeService : Destroyed 110000 trades in 672 ms +... +``` +##### Query by Cusip Forever Command +Run the function update command using **curl** like: + +``` +curl http://localhost:8080/trades/querybycusipforever +{"operation":"querybycusipforeverthreads","status":"SUCCESS","completionTime":0} +``` +The application will log messages like: + +``` +2019-12-18 17:25:41.177 INFO 1239 --- [ Thread-9] i.p.test.client.service.TradeService : Executing cusip queries forever +2019-12-18 17:26:01.775 INFO 1239 --- [ Thread-9] i.p.test.client.service.TradeService : Executed 10000 cusip queries in 20598 ms +2019-12-18 17:26:20.484 INFO 1239 --- [ Thread-9] i.p.test.client.service.TradeService : Executed 20000 cusip queries in 18709 ms +2019-12-18 17:26:39.543 INFO 1239 --- [ Thread-9] i.p.test.client.service.TradeService : Executed 30000 cusip queries in 19059 ms +2019-12-18 17:26:57.534 INFO 1239 --- [ Thread-9] i.p.test.client.service.TradeService : Executed 40000 cusip queries in 17991 ms +2019-12-18 17:27:15.314 INFO 1239 --- [ Thread-9] i.p.test.client.service.TradeService : Executed 50000 cusip queries in 17780 ms +2019-12-18 17:27:33.081 INFO 1239 --- [ Thread-9] i.p.test.client.service.TradeService : Executed 60000 cusip queries in 17767 ms +2019-12-18 17:27:50.804 INFO 1239 --- [ Thread-9] i.p.test.client.service.TradeService : Executed 70000 cusip queries in 17723 ms +2019-12-18 17:28:09.086 INFO 1239 --- [ Thread-9] i.p.test.client.service.TradeService : Executed 80000 cusip queries in 18281 ms +2019-12-18 17:28:27.066 INFO 1239 --- [ Thread-9] i.p.test.client.service.TradeService : Executed 90000 cusip queries in 17980 ms +2019-12-18 17:28:44.831 INFO 1239 --- [ Thread-9] i.p.test.client.service.TradeService : Executed 100000 cusip queries in 17765 ms +... +``` +##### Function Update Forever Command +Run the function update command using **curl** like: + +``` +curl -X POST http://localhost:8080/trades/functionupdateforever/10 +{"operation":"functionupdateforeverthreads","status":"SUCCESS","completionTime":0} +``` +The application will log messages like: + +``` +2019-12-19 15:56:31.876 INFO 58371 --- [ Thread-19] i.p.test.client.service.TradeService : Updating 10 trades with function forever +2019-12-19 15:56:34.579 INFO 58371 --- [ Thread-19] i.p.test.client.service.TradeService : Updated 10000 trades with function in 2703 ms +2019-12-19 15:56:37.002 INFO 58371 --- [ Thread-19] i.p.test.client.service.TradeService : Updated 20000 trades with function in 2423 ms +2019-12-19 15:56:39.491 INFO 58371 --- [ Thread-19] i.p.test.client.service.TradeService : Updated 30000 trades with function in 2488 ms +2019-12-19 15:56:41.914 INFO 58371 --- [ Thread-19] i.p.test.client.service.TradeService : Updated 40000 trades with function in 2423 ms +2019-12-19 15:56:44.281 INFO 58371 --- [ Thread-19] i.p.test.client.service.TradeService : Updated 50000 trades with function in 2366 ms +2019-12-19 15:56:46.519 INFO 58371 --- [ Thread-19] i.p.test.client.service.TradeService : Updated 60000 trades with function in 2238 ms +2019-12-19 15:56:48.857 INFO 58371 --- [ Thread-19] i.p.test.client.service.TradeService : Updated 70000 trades with function in 2338 ms +2019-12-19 15:56:51.229 INFO 58371 --- [ Thread-19] i.p.test.client.service.TradeService : Updated 80000 trades with function in 2372 ms +2019-12-19 15:56:53.563 INFO 58371 --- [ Thread-19] i.p.test.client.service.TradeService : Updated 90000 trades with function in 2334 ms +2019-12-19 15:56:56.014 INFO 58371 --- [ Thread-19] i.p.test.client.service.TradeService : Updated 100000 trades with function in 2451 ms +... +``` +##### Multi-threaded Put Forever Command +Run the multi-threaded put forever command using **curl** like: + +``` +curl -X POST http://localhost:8080/trades/putforever/10/1024/5 +{"operation":"putforever","status":"SUCCESS","completionTime":0} +``` +The application will log messages like: + +``` +2019-12-18 17:36:22.188 INFO 3437 --- [ Thread-7] i.p.test.client.service.TradeService : Putting trades forever of size 1024 bytes +2019-12-18 17:36:22.188 INFO 3437 --- [ Thread-8] i.p.test.client.service.TradeService : Putting trades forever of size 1024 bytes +2019-12-18 17:36:22.188 INFO 3437 --- [ Thread-9] i.p.test.client.service.TradeService : Putting trades forever of size 1024 bytes +2019-12-18 17:36:22.188 INFO 3437 --- [ Thread-10] i.p.test.client.service.TradeService : Putting trades forever of size 1024 bytes +2019-12-18 17:36:22.189 INFO 3437 --- [ Thread-11] i.p.test.client.service.TradeService : Putting trades forever of size 1024 bytes +2019-12-18 17:36:30.755 INFO 3437 --- [ Thread-8] i.p.test.client.service.TradeService : Put 10000 trades of size 1024 bytes in 8567 ms +2019-12-18 17:36:30.780 INFO 3437 --- [ Thread-9] i.p.test.client.service.TradeService : Put 10000 trades of size 1024 bytes in 8592 ms +2019-12-18 17:36:30.788 INFO 3437 --- [ Thread-11] i.p.test.client.service.TradeService : Put 10000 trades of size 1024 bytes in 8599 ms +2019-12-18 17:36:30.792 INFO 3437 --- [ Thread-7] i.p.test.client.service.TradeService : Put 10000 trades of size 1024 bytes in 8604 ms +2019-12-18 17:36:30.793 INFO 3437 --- [ Thread-10] i.p.test.client.service.TradeService : Put 10000 trades of size 1024 bytes in 8604 ms +2019-12-18 17:36:39.269 INFO 3437 --- [ Thread-11] i.p.test.client.service.TradeService : Put 20000 trades of size 1024 bytes in 8481 ms +2019-12-18 17:36:39.275 INFO 3437 --- [ Thread-9] i.p.test.client.service.TradeService : Put 20000 trades of size 1024 bytes in 8495 ms +2019-12-18 17:36:39.280 INFO 3437 --- [ Thread-10] i.p.test.client.service.TradeService : Put 20000 trades of size 1024 bytes in 8487 ms +2019-12-18 17:36:39.322 INFO 3437 --- [ Thread-7] i.p.test.client.service.TradeService : Put 20000 trades of size 1024 bytes in 8530 ms +2019-12-18 17:36:39.328 INFO 3437 --- [ Thread-8] i.p.test.client.service.TradeService : Put 20000 trades of size 1024 bytes in 8573 ms +2019-12-18 17:36:48.276 INFO 3437 --- [ Thread-9] i.p.test.client.service.TradeService : Put 30000 trades of size 1024 bytes in 9001 ms +2019-12-18 17:36:48.296 INFO 3437 --- [ Thread-10] i.p.test.client.service.TradeService : Put 30000 trades of size 1024 bytes in 9016 ms +2019-12-18 17:36:48.297 INFO 3437 --- [ Thread-7] i.p.test.client.service.TradeService : Put 30000 trades of size 1024 bytes in 8975 ms +2019-12-18 17:36:48.302 INFO 3437 --- [ Thread-8] i.p.test.client.service.TradeService : Put 30000 trades of size 1024 bytes in 8974 ms +2019-12-18 17:36:48.345 INFO 3437 --- [ Thread-11] i.p.test.client.service.TradeService : Put 30000 trades of size 1024 bytes in 9076 ms +... +``` +##### Multi-threaded Get Forever Command +Run the multi-threaded get forever command using **curl** like: + +``` +curl http://localhost:8080/trades/getforever/10/5 +{"operation":"getforever","status":"SUCCESS","completionTime":0} +``` +The application will log messages like: + +``` +2019-12-18 17:41:50.830 INFO 3437 --- [ Thread-12] i.p.test.client.service.TradeService : Getting entries forever +2019-12-18 17:41:50.830 INFO 3437 --- [ Thread-13] i.p.test.client.service.TradeService : Getting entries forever +2019-12-18 17:41:50.830 INFO 3437 --- [ Thread-14] i.p.test.client.service.TradeService : Getting entries forever +2019-12-18 17:41:50.830 INFO 3437 --- [ Thread-15] i.p.test.client.service.TradeService : Getting entries forever +2019-12-18 17:41:50.830 INFO 3437 --- [ Thread-16] i.p.test.client.service.TradeService : Getting entries forever +2019-12-18 17:41:51.745 INFO 3437 --- [ Thread-14] i.p.test.client.service.TradeService : Got 10000 trades in 915 ms +2019-12-18 17:41:51.747 INFO 3437 --- [ Thread-15] i.p.test.client.service.TradeService : Got 10000 trades in 917 ms +2019-12-18 17:41:51.750 INFO 3437 --- [ Thread-12] i.p.test.client.service.TradeService : Got 10000 trades in 920 ms +2019-12-18 17:41:51.750 INFO 3437 --- [ Thread-16] i.p.test.client.service.TradeService : Got 10000 trades in 920 ms +2019-12-18 17:41:51.753 INFO 3437 --- [ Thread-13] i.p.test.client.service.TradeService : Got 10000 trades in 923 ms +2019-12-18 17:41:52.577 INFO 3437 --- [ Thread-14] i.p.test.client.service.TradeService : Got 20000 trades in 831 ms +2019-12-18 17:41:52.581 INFO 3437 --- [ Thread-16] i.p.test.client.service.TradeService : Got 20000 trades in 831 ms +2019-12-18 17:41:52.582 INFO 3437 --- [ Thread-15] i.p.test.client.service.TradeService : Got 20000 trades in 835 ms +2019-12-18 17:41:52.583 INFO 3437 --- [ Thread-12] i.p.test.client.service.TradeService : Got 20000 trades in 833 ms +2019-12-18 17:41:52.590 INFO 3437 --- [ Thread-13] i.p.test.client.service.TradeService : Got 20000 trades in 836 ms +2019-12-18 17:41:53.440 INFO 3437 --- [ Thread-14] i.p.test.client.service.TradeService : Got 30000 trades in 863 ms +2019-12-18 17:41:53.442 INFO 3437 --- [ Thread-16] i.p.test.client.service.TradeService : Got 30000 trades in 861 ms +2019-12-18 17:41:53.444 INFO 3437 --- [ Thread-15] i.p.test.client.service.TradeService : Got 30000 trades in 862 ms +2019-12-18 17:41:53.445 INFO 3437 --- [ Thread-12] i.p.test.client.service.TradeService : Got 30000 trades in 862 ms +2019-12-18 17:41:53.454 INFO 3437 --- [ Thread-13] i.p.test.client.service.TradeService : Got 30000 trades in 864 ms +... +``` +##### Multi-threaded Destroy Forever Command +Run the multi-threaded destroy forever command using **curl** like: + +``` +curl -X DELETE http://localhost:8080/trades/destroyforever/10/5 +{"operation":"destroyforever","status":"SUCCESS","completionTime":0} +``` +The application will log messages like: + +``` +2019-12-18 17:45:40.359 INFO 3437 --- [ Thread-17] i.p.test.client.service.TradeService : Destroying trades forever +2019-12-18 17:45:40.359 INFO 3437 --- [ Thread-18] i.p.test.client.service.TradeService : Destroying trades forever +2019-12-18 17:45:40.359 INFO 3437 --- [ Thread-19] i.p.test.client.service.TradeService : Destroying trades forever +2019-12-18 17:45:40.359 INFO 3437 --- [ Thread-20] i.p.test.client.service.TradeService : Destroying trades forever +2019-12-18 17:45:40.360 INFO 3437 --- [ Thread-21] i.p.test.client.service.TradeService : Destroying trades forever +2019-12-18 17:45:41.412 INFO 3437 --- [ Thread-17] i.p.test.client.service.TradeService : Destroyed 10000 trades in 1053 ms +2019-12-18 17:45:41.413 INFO 3437 --- [ Thread-21] i.p.test.client.service.TradeService : Destroyed 10000 trades in 1053 ms +2019-12-18 17:45:41.414 INFO 3437 --- [ Thread-20] i.p.test.client.service.TradeService : Destroyed 10000 trades in 1055 ms +2019-12-18 17:45:41.416 INFO 3437 --- [ Thread-19] i.p.test.client.service.TradeService : Destroyed 10000 trades in 1056 ms +2019-12-18 17:45:41.417 INFO 3437 --- [ Thread-18] i.p.test.client.service.TradeService : Destroyed 10000 trades in 1058 ms +2019-12-18 17:45:42.449 INFO 3437 --- [ Thread-17] i.p.test.client.service.TradeService : Destroyed 20000 trades in 1037 ms +2019-12-18 17:45:42.450 INFO 3437 --- [ Thread-21] i.p.test.client.service.TradeService : Destroyed 20000 trades in 1037 ms +2019-12-18 17:45:42.452 INFO 3437 --- [ Thread-20] i.p.test.client.service.TradeService : Destroyed 20000 trades in 1038 ms +2019-12-18 17:45:42.455 INFO 3437 --- [ Thread-19] i.p.test.client.service.TradeService : Destroyed 20000 trades in 1039 ms +2019-12-18 17:45:42.457 INFO 3437 --- [ Thread-18] i.p.test.client.service.TradeService : Destroyed 20000 trades in 1040 ms +2019-12-18 17:45:43.633 INFO 3437 --- [ Thread-17] i.p.test.client.service.TradeService : Destroyed 30000 trades in 1184 ms +2019-12-18 17:45:43.634 INFO 3437 --- [ Thread-21] i.p.test.client.service.TradeService : Destroyed 30000 trades in 1184 ms +2019-12-18 17:45:43.635 INFO 3437 --- [ Thread-20] i.p.test.client.service.TradeService : Destroyed 30000 trades in 1183 ms +2019-12-18 17:45:43.637 INFO 3437 --- [ Thread-19] i.p.test.client.service.TradeService : Destroyed 30000 trades in 1182 ms +2019-12-18 17:45:43.642 INFO 3437 --- [ Thread-18] i.p.test.client.service.TradeService : Destroyed 30000 trades in 1185 ms +... +``` +##### Multi-threaded Query by Cusip Forever Command +Run the multi-threaded query by cusip forever command using **curl** like: + +``` +curl http://localhost:8080/trades/querybycusipforever/5 +{"operation":"querybycusipforever","status":"SUCCESS","completionTime":0} +``` +The application will log messages like: + +``` +2019-12-19 16:01:46.684 INFO 58371 --- [ Thread-35] i.p.test.client.service.TradeService : Executing cusip queries forever +2019-12-19 16:01:46.684 INFO 58371 --- [ Thread-36] i.p.test.client.service.TradeService : Executing cusip queries forever +2019-12-19 16:01:46.684 INFO 58371 --- [ Thread-37] i.p.test.client.service.TradeService : Executing cusip queries forever +2019-12-19 16:01:46.685 INFO 58371 --- [ Thread-38] i.p.test.client.service.TradeService : Executing cusip queries forever +2019-12-19 16:01:46.685 INFO 58371 --- [ Thread-39] i.p.test.client.service.TradeService : Executing cusip queries forever +2019-12-19 16:01:56.990 INFO 58371 --- [ Thread-37] i.p.test.client.service.TradeService : Executed 10000 cusip queries in 10306 ms +2019-12-19 16:01:57.003 INFO 58371 --- [ Thread-38] i.p.test.client.service.TradeService : Executed 10000 cusip queries in 10318 ms +2019-12-19 16:01:57.012 INFO 58371 --- [ Thread-35] i.p.test.client.service.TradeService : Executed 10000 cusip queries in 10328 ms +2019-12-19 16:01:57.013 INFO 58371 --- [ Thread-39] i.p.test.client.service.TradeService : Executed 10000 cusip queries in 10328 ms +2019-12-19 16:01:57.013 INFO 58371 --- [ Thread-36] i.p.test.client.service.TradeService : Executed 10000 cusip queries in 10329 ms +2019-12-19 16:02:06.849 INFO 58371 --- [ Thread-37] i.p.test.client.service.TradeService : Executed 20000 cusip queries in 9859 ms +2019-12-19 16:02:06.859 INFO 58371 --- [ Thread-38] i.p.test.client.service.TradeService : Executed 20000 cusip queries in 9856 ms +2019-12-19 16:02:06.879 INFO 58371 --- [ Thread-36] i.p.test.client.service.TradeService : Executed 20000 cusip queries in 9866 ms +2019-12-19 16:02:06.884 INFO 58371 --- [ Thread-39] i.p.test.client.service.TradeService : Executed 20000 cusip queries in 9871 ms +2019-12-19 16:02:06.889 INFO 58371 --- [ Thread-35] i.p.test.client.service.TradeService : Executed 20000 cusip queries in 9877 ms +2019-12-19 16:02:16.623 INFO 58371 --- [ Thread-37] i.p.test.client.service.TradeService : Executed 30000 cusip queries in 9774 ms +2019-12-19 16:02:16.648 INFO 58371 --- [ Thread-38] i.p.test.client.service.TradeService : Executed 30000 cusip queries in 9789 ms +2019-12-19 16:02:16.655 INFO 58371 --- [ Thread-36] i.p.test.client.service.TradeService : Executed 30000 cusip queries in 9775 ms +2019-12-19 16:02:16.666 INFO 58371 --- [ Thread-39] i.p.test.client.service.TradeService : Executed 30000 cusip queries in 9782 ms +2019-12-19 16:02:16.667 INFO 58371 --- [ Thread-35] i.p.test.client.service.TradeService : Executed 30000 cusip queries in 9778 ms +... +``` +##### Multi-threaded Function Update Forever Command +Run the multi-threaded function update command using **curl** like: + +``` +curl -X POST http://localhost:8080/trades/functionupdateforever/10/5 +{"operation":"functionupdateforever","status":"SUCCESS","completionTime":0} +``` +The application will log messages like: + +``` +2019-12-19 16:03:09.034 INFO 58371 --- [ Thread-41] i.p.test.client.service.TradeService : Updating 10 trades with function forever +2019-12-19 16:03:09.034 INFO 58371 --- [ Thread-42] i.p.test.client.service.TradeService : Updating 10 trades with function forever +2019-12-19 16:03:09.034 INFO 58371 --- [ Thread-40] i.p.test.client.service.TradeService : Updating 10 trades with function forever +2019-12-19 16:03:09.034 INFO 58371 --- [ Thread-43] i.p.test.client.service.TradeService : Updating 10 trades with function forever +2019-12-19 16:03:09.034 INFO 58371 --- [ Thread-44] i.p.test.client.service.TradeService : Updating 10 trades with function forever +2019-12-19 16:03:11.147 INFO 58371 --- [ Thread-43] i.p.test.client.service.TradeService : Updated 10000 trades with function in 2113 ms +2019-12-19 16:03:11.150 INFO 58371 --- [ Thread-44] i.p.test.client.service.TradeService : Updated 10000 trades with function in 2116 ms +2019-12-19 16:03:11.150 INFO 58371 --- [ Thread-42] i.p.test.client.service.TradeService : Updated 10000 trades with function in 2116 ms +2019-12-19 16:03:11.151 INFO 58371 --- [ Thread-40] i.p.test.client.service.TradeService : Updated 10000 trades with function in 2117 ms +2019-12-19 16:03:11.152 INFO 58371 --- [ Thread-41] i.p.test.client.service.TradeService : Updated 10000 trades with function in 2118 ms +2019-12-19 16:03:13.127 INFO 58371 --- [ Thread-42] i.p.test.client.service.TradeService : Updated 20000 trades with function in 1977 ms +2019-12-19 16:03:13.129 INFO 58371 --- [ Thread-43] i.p.test.client.service.TradeService : Updated 20000 trades with function in 1982 ms +2019-12-19 16:03:13.130 INFO 58371 --- [ Thread-41] i.p.test.client.service.TradeService : Updated 20000 trades with function in 1978 ms +2019-12-19 16:03:13.131 INFO 58371 --- [ Thread-44] i.p.test.client.service.TradeService : Updated 20000 trades with function in 1981 ms +2019-12-19 16:03:13.134 INFO 58371 --- [ Thread-40] i.p.test.client.service.TradeService : Updated 20000 trades with function in 1983 ms +2019-12-19 16:03:14.831 INFO 58371 --- [ Thread-44] i.p.test.client.service.TradeService : Updated 30000 trades with function in 1700 ms +2019-12-19 16:03:14.832 INFO 58371 --- [ Thread-42] i.p.test.client.service.TradeService : Updated 30000 trades with function in 1705 ms +2019-12-19 16:03:14.832 INFO 58371 --- [ Thread-41] i.p.test.client.service.TradeService : Updated 30000 trades with function in 1702 ms +2019-12-19 16:03:14.832 INFO 58371 --- [ Thread-43] i.p.test.client.service.TradeService : Updated 30000 trades with function in 1703 ms +2019-12-19 16:03:14.837 INFO 58371 --- [ Thread-40] i.p.test.client.service.TradeService : Updated 30000 trades with function in 1703 ms +... +``` +##### Get One Command +Run the get one command using **curl** like: + +``` +curl http://localhost:8080/trades/getone/0 +{"id":"0","cusip":"NKE","shares":46,"price":343.43,"payload":"..."} +``` +The application will log messages like: + +``` +2019-12-19 16:04:41.261 INFO 58371 --- [nio-8080-exec-5] i.p.test.client.service.TradeService : Got Trade(id=0, cusip=NKE, shares=46, price=343.43) +``` +##### Query One By Cusip Command +Run the query one by cusip command using **curl** like: + +``` +curl http://localhost:8080/trades/queryonebycusip/AAPL +[{"id":"42","cusip":"AAPL","shares":60,"price":720.05,"payload":"..."}] +``` +The application will log messages like: + +``` +2019-12-19 16:07:59.880 INFO 58371 --- [nio-8080-exec-1] i.p.test.client.service.TradeService : Executing query for cusip=AAPL +2019-12-19 16:07:59.881 INFO 58371 --- [nio-8080-exec-1] i.p.test.client.service.TradeService : Returned 1 trades for cusip=AAPL in 1 ms: +2019-12-19 16:07:59.881 INFO 58371 --- [nio-8080-exec-1] i.p.test.client.service.TradeService : Trade(id=42, cusip=AAPL, shares=60, price=720.05) +``` +##### Test Command +Run the test command using **curl** like: + +``` +curl -X POST http://localhost:8080/trades/starttest/100/1024/2 +[{"operation":"putforever","status":"SUCCESS","completionTime":0},{"operation":"getforever","status":"SUCCESS","completionTime":0},{"operation":"querybycusipforever","status":"SUCCESS","completionTime":0},{"operation":"functionupdateforever","status":"SUCCESS","completionTime":0}] +``` +The application will log messages like: + +``` +2019-12-19 16:10:19.415 INFO 58371 --- [ Thread-68] i.p.test.client.service.TradeService : Putting trades forever of size 1024 bytes +2019-12-19 16:10:19.415 INFO 58371 --- [ Thread-69] i.p.test.client.service.TradeService : Putting trades forever of size 1024 bytes +2019-12-19 16:10:19.416 INFO 58371 --- [ Thread-70] i.p.test.client.service.TradeService : Getting entries forever +2019-12-19 16:10:19.416 INFO 58371 --- [ Thread-71] i.p.test.client.service.TradeService : Getting entries forever +2019-12-19 16:10:19.416 INFO 58371 --- [ Thread-72] i.p.test.client.service.TradeService : Executing cusip queries forever +2019-12-19 16:10:19.416 INFO 58371 --- [ Thread-73] i.p.test.client.service.TradeService : Executing cusip queries forever +2019-12-19 16:10:19.417 INFO 58371 --- [ Thread-74] i.p.test.client.service.TradeService : Updating 100 trades with function forever +2019-12-19 16:10:19.417 INFO 58371 --- [ Thread-75] i.p.test.client.service.TradeService : Updating 100 trades with function forever +2019-12-19 16:10:21.578 INFO 58371 --- [ Thread-71] i.p.test.client.service.TradeService : Got 10000 trades in 2162 ms +2019-12-19 16:10:21.583 INFO 58371 --- [ Thread-70] i.p.test.client.service.TradeService : Got 10000 trades in 2167 ms +2019-12-19 16:10:23.766 INFO 58371 --- [ Thread-71] i.p.test.client.service.TradeService : Got 20000 trades in 2188 ms +2019-12-19 16:10:23.778 INFO 58371 --- [ Thread-70] i.p.test.client.service.TradeService : Got 20000 trades in 2195 ms +2019-12-19 16:10:24.341 INFO 58371 --- [ Thread-69] i.p.test.client.service.TradeService : Put 10000 trades of size 1024 bytes in 4926 ms +2019-12-19 16:10:24.355 INFO 58371 --- [ Thread-68] i.p.test.client.service.TradeService : Put 10000 trades of size 1024 bytes in 4940 ms +2019-12-19 16:10:25.151 INFO 58371 --- [ Thread-74] i.p.test.client.service.TradeService : Updated 10000 trades with function in 5734 ms +2019-12-19 16:10:25.153 INFO 58371 --- [ Thread-75] i.p.test.client.service.TradeService : Updated 10000 trades with function in 5736 ms +2019-12-19 16:10:25.858 INFO 58371 --- [ Thread-71] i.p.test.client.service.TradeService : Got 30000 trades in 2092 ms +2019-12-19 16:10:25.873 INFO 58371 --- [ Thread-70] i.p.test.client.service.TradeService : Got 30000 trades in 2095 ms +2019-12-19 16:10:29.129 INFO 58371 --- [ Thread-69] i.p.test.client.service.TradeService : Put 20000 trades of size 1024 bytes in 4787 ms +2019-12-19 16:10:29.139 INFO 58371 --- [ Thread-68] i.p.test.client.service.TradeService : Put 20000 trades of size 1024 bytes in 4784 ms +2019-12-19 16:10:30.753 INFO 58371 --- [ Thread-74] i.p.test.client.service.TradeService : Updated 20000 trades with function in 5602 ms +2019-12-19 16:10:30.770 INFO 58371 --- [ Thread-75] i.p.test.client.service.TradeService : Updated 20000 trades with function in 5617 ms +2019-12-19 16:10:32.609 INFO 58371 --- [ Thread-72] i.p.test.client.service.TradeService : Executed 10000 cusip queries in 13193 ms +2019-12-19 16:10:32.621 INFO 58371 --- [ Thread-73] i.p.test.client.service.TradeService : Executed 10000 cusip queries in 13204 ms +2019-12-19 16:10:33.853 INFO 58371 --- [ Thread-69] i.p.test.client.service.TradeService : Put 30000 trades of size 1024 bytes in 4723 ms +2019-12-19 16:10:33.859 INFO 58371 --- [ Thread-68] i.p.test.client.service.TradeService : Put 30000 trades of size 1024 bytes in 4720 ms +2019-12-19 16:10:36.184 INFO 58371 --- [ Thread-74] i.p.test.client.service.TradeService : Updated 30000 trades with function in 5431 ms +2019-12-19 16:10:36.217 INFO 58371 --- [ Thread-75] i.p.test.client.service.TradeService : Updated 30000 trades with function in 5447 ms +2019-12-19 16:10:45.901 INFO 58371 --- [ Thread-72] i.p.test.client.service.TradeService : Executed 20000 cusip queries in 13292 ms +2019-12-19 16:10:45.911 INFO 58371 --- [ Thread-73] i.p.test.client.service.TradeService : Executed 20000 cusip queries in 13290 ms +2019-12-19 16:10:59.129 INFO 58371 --- [ Thread-72] i.p.test.client.service.TradeService : Executed 30000 cusip queries in 13228 ms +2019-12-19 16:10:59.169 INFO 58371 --- [ Thread-73] i.p.test.client.service.TradeService : Executed 30000 cusip queries in 13258 ms +... +``` +##### Stop Operations Command +Run the stop operations command using **curl** like: + +``` +curl -X POST http://localhost:8080/trades/stopoperations +{"operation":"stopoperations","status":"SUCCESS","completionTime":0} +``` +The application will log messages like: + +``` +2019-12-19 15:51:19.022 INFO 58371 --- [nio-8080-exec-1] i.p.test.client.service.TradeService : Stopping operations +2019-12-19 15:51:19.022 INFO 58371 --- [ Thread-8] i.p.test.client.service.TradeService : Stopping after getting 168798 trades +2019-12-19 15:51:19.022 INFO 58371 --- [ Thread-9] i.p.test.client.service.TradeService : Stopping after getting 167932 trades +2019-12-19 15:51:19.022 INFO 58371 --- [ Thread-10] i.p.test.client.service.TradeService : Stopping after executing 32543 cusip queries +2019-12-19 15:51:19.022 INFO 58371 --- [ Thread-11] i.p.test.client.service.TradeService : Stopping after executing 32550 cusip queries +2019-12-19 15:51:19.022 INFO 58371 --- [ Thread-12] i.p.test.client.service.TradeService : Stopping after updating 63897 trades with function +2019-12-19 15:51:19.022 INFO 58371 --- [ Thread-7] i.p.test.client.service.TradeService : Stopping after putting 74388 trades of size 1024 bytes +2019-12-19 15:51:19.022 INFO 58371 --- [ Thread-13] i.p.test.client.service.TradeService : Stopping after updating 63754 trades with function +2019-12-19 15:51:19.022 INFO 58371 --- [ Thread-6] i.p.test.client.service.TradeService : Stopping after putting 74523 trades of size 1024 bytes +``` + \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..59d10bf --- /dev/null +++ b/build.gradle @@ -0,0 +1,80 @@ +buildscript { + ext { + springBootVersion = '2.2.2.RELEASE' + } + repositories { + mavenCentral() + maven { url "https://repo.spring.io/snapshot" } + maven { url "https://repo.spring.io/milestone" } + } + dependencies { + classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") + } +} + +plugins { + id 'io.franzbecker.gradle-lombok' version '1.11' +} + +allprojects { + repositories { + mavenCentral() + jcenter() + maven { url 'https://repo.spring.io/libs-release' } + maven { url 'https://repo.spring.io/libs-milestone' } + maven { url 'https://repo.spring.io/libs-snapshot' } + } +} + +subprojects { + apply plugin: 'java' + sourceCompatibility = 1.8 + + group = 'example.cloudcache' + version = '0.0.1-SNAPSHOT' + + configurations { + provided + compile.extendsFrom provided + } + + + task copyDependancies(type: Copy) { + into "$buildDir/dependancies" + from(configurations.compile - configurations.provided) + } + + jar { + dependsOn copyDependancies + } +} + +project(':client') { + apply plugin: 'org.springframework.boot' + apply plugin: 'io.spring.dependency-management' + dependencies { + compile 'org.projectlombok:lombok:1.18.8' + annotationProcessor 'org.projectlombok:lombok:1.18.10' + compile 'org.springframework.geode:spring-geode-starter:1.2.2.RELEASE' + compile 'org.springframework.geode:spring-geode-starter-actuator:1.2.2.RELEASE' + compile "org.springframework.boot:spring-boot-starter-web:2.2.2.RELEASE" + } +} + +project(':client-cq') { + apply plugin: 'org.springframework.boot' + apply plugin: 'io.spring.dependency-management' + dependencies { + compile 'org.projectlombok:lombok:1.18.8' + annotationProcessor 'org.projectlombok:lombok:1.18.10' + compile 'org.springframework.geode:spring-geode-starter:1.2.2.RELEASE' + compile 'org.springframework.geode:spring-geode-starter-actuator:1.2.2.RELEASE' + compile "org.springframework.boot:spring-boot-starter-web:2.2.2.RELEASE" + } +} + +project(':server') { + dependencies { + provided 'io.pivotal.gemfire:geode-core:9.8.3' + } +} \ No newline at end of file diff --git a/client-cq/manifest.yml b/client-cq/manifest.yml new file mode 100644 index 0000000..e8ed2f9 --- /dev/null +++ b/client-cq/manifest.yml @@ -0,0 +1,10 @@ +--- +applications: + - name: clientCqApp + memory: 768M + instances: 1 + path: build/libs/client_cq-0.0.1-SNAPSHOT.jar + services: + - pccService + buildpacks: + - https://github.com/cloudfoundry/java-buildpack.git \ No newline at end of file diff --git a/client-cq/src/main/java/io/pivotal/test/client/Client.java b/client-cq/src/main/java/io/pivotal/test/client/Client.java new file mode 100644 index 0000000..8bced86 --- /dev/null +++ b/client-cq/src/main/java/io/pivotal/test/client/Client.java @@ -0,0 +1,19 @@ +package io.pivotal.test.client; + +import io.pivotal.test.client.domain.Trade; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.data.gemfire.config.annotation.EnableEntityDefinedRegions; +import org.springframework.data.gemfire.config.annotation.EnableStatistics; + +@SpringBootApplication +@EnableEntityDefinedRegions(basePackageClasses = Trade.class) +@EnableStatistics +public class Client { + + public static void main(String[] args) { + new SpringApplicationBuilder(Client.class) + .build() + .run(args); + } +} diff --git a/client-cq/src/main/java/io/pivotal/test/client/cq/TradeProcessor.java b/client-cq/src/main/java/io/pivotal/test/client/cq/TradeProcessor.java new file mode 100644 index 0000000..b9d93f6 --- /dev/null +++ b/client-cq/src/main/java/io/pivotal/test/client/cq/TradeProcessor.java @@ -0,0 +1,18 @@ +package io.pivotal.test.client.cq; + +import org.apache.geode.cache.query.CqEvent; +import org.apache.geode.internal.logging.LogService; +import org.apache.logging.log4j.Logger; +import org.springframework.data.gemfire.listener.annotation.ContinuousQuery; +import org.springframework.stereotype.Component; + +@Component +public class TradeProcessor { + + private static final Logger logger = LogService.getLogger(); + + @ContinuousQuery(name = "TradeProcessor", query = "SELECT * FROM /Trades WHERE cusip = 'AAPL'") + public void processTrade(CqEvent event) { + logger.info("TradeProcessor.processTrade processing event=" + event); + } +} diff --git a/client-cq/src/main/java/io/pivotal/test/client/domain/Trade.java b/client-cq/src/main/java/io/pivotal/test/client/domain/Trade.java new file mode 100644 index 0000000..8fc06be --- /dev/null +++ b/client-cq/src/main/java/io/pivotal/test/client/domain/Trade.java @@ -0,0 +1,35 @@ +package io.pivotal.test.client.domain; + +import lombok.Data; +import lombok.Getter; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import lombok.ToString; +import org.springframework.data.annotation.Id; +import org.springframework.data.gemfire.mapping.annotation.Region; + +import java.io.Serializable; +import java.math.BigDecimal; + +@Data +@Getter +@ToString(exclude = "payload") +@Region("Trades") +@RequiredArgsConstructor +public class Trade { + + @Id + @NonNull + private final String id; + + @NonNull + private final String cusip; + + private final int shares; + + @NonNull + private final BigDecimal price; + + @NonNull + private final byte[] payload; +} diff --git a/client-cq/src/main/resources/application-local.properties b/client-cq/src/main/resources/application-local.properties new file mode 100644 index 0000000..0383090 --- /dev/null +++ b/client-cq/src/main/resources/application-local.properties @@ -0,0 +1,10 @@ +# GemFire properties +spring.data.gemfire.name=client +spring.data.gemfire.pool.locators=localhost[10334] +spring.data.gemfire.pool.statistic-interval=1000 +spring.data.gemfire.stats.archive-file=client_cq.gfs +spring.data.gemfire.logging.log-file=client_cq.log + +# Spring Actuator Properties +management.endpoint.health.show-details=always +management.endpoints.web.exposure.include=* diff --git a/client-cq/src/main/resources/application.properties b/client-cq/src/main/resources/application.properties new file mode 100644 index 0000000..46b75ae --- /dev/null +++ b/client-cq/src/main/resources/application.properties @@ -0,0 +1,12 @@ +# GemFire properties +# This property was causing this exception in pcfone: +# org.apache.geode.security.GemFireSecurityException: Instance could not be obtained from org.springframework.data.gemfire.config.annotation.support.AutoConfiguredAuthenticationInitializer.newAuthenticationInitializer +#spring.data.gemfire.pool.statistic-interval=1000 + +# Spring Actuator Properties +management.endpoint.health.show-details=always +management.endpoints.web.exposure.include=* + +# GemFire properties +spring.data.gemfire.stats.archive-file=client_cq.gfs +spring.data.gemfire.logging.log-file=client_cq.log diff --git a/client/manifest.yml b/client/manifest.yml new file mode 100644 index 0000000..621415e --- /dev/null +++ b/client/manifest.yml @@ -0,0 +1,10 @@ +--- +applications: + - name: sdgApp + memory: 768M + instances: 1 + path: build/libs/client-0.0.1-SNAPSHOT.jar + services: + - pccService + buildpacks: + - https://github.com/cloudfoundry/java-buildpack.git \ No newline at end of file diff --git a/client/src/main/java/io/pivotal/test/client/Client.java b/client/src/main/java/io/pivotal/test/client/Client.java new file mode 100644 index 0000000..327654d --- /dev/null +++ b/client/src/main/java/io/pivotal/test/client/Client.java @@ -0,0 +1,123 @@ +package io.pivotal.test.client; + +import io.pivotal.test.client.domain.Trade; +import io.pivotal.test.client.service.TradeService; +import org.apache.geode.internal.logging.LogService; +import org.apache.logging.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.data.gemfire.config.annotation.EnableEntityDefinedRegions; +import org.springframework.data.gemfire.config.annotation.EnableStatistics; +import org.springframework.geode.boot.autoconfigure.ContinuousQueryAutoConfiguration; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +import static io.pivotal.test.client.Constants.*; + +@SpringBootApplication(exclude = ContinuousQueryAutoConfiguration.class) // disable subscriptions +@EnableEntityDefinedRegions(basePackageClasses = Trade.class) +@EnableStatistics +public class Client { + + private static final Logger logger = LogService.getLogger(); + + @Autowired + private TradeService service; + + public static void main(String[] args) { + new SpringApplicationBuilder(Client.class) + .web(WebApplicationType.SERVLET) + .build() + .run(args); + } + + @Bean + ApplicationRunner runner() { + return args -> { + dumpArguments(args); + List operations = args.getOptionValues(OPERATION); + if (operations == null || operations.get(0).equals("wait")) { + waitForever(); + } else { + String operation = operations.get(0); + String parameter1 = (args.containsOption(PARAMETER_1)) ? args.getOptionValues(PARAMETER_1).get(0) : null; + String parameter2 = (args.containsOption(PARAMETER_2)) ? args.getOptionValues(PARAMETER_2).get(0) : null; + String parameter3 = (args.containsOption(PARAMETER_3)) ? args.getOptionValues(PARAMETER_3).get(0) : null; + switch (operation) { + case PUT: + this.service.put(Integer.parseInt(parameter1), Integer.parseInt(parameter2)); + break; + case GET: + this.service.get(Integer.parseInt(parameter1)); + break; + case DESTROY: + this.service.destroy(Integer.parseInt(parameter1)); + break; + case QUERY_BY_CUSIP: + this.service.queryByCusip(Integer.parseInt(parameter1)); + break; + case FUNCTION_UPDATE: + this.service.functionUpdate(Integer.parseInt(parameter1)); + break; + case PUT_FOREVER: + Optional putThreads = parameter3 == null ? Optional.empty() : Optional.of(Integer.parseInt(parameter3)); + this.service.putForever(Integer.parseInt(parameter1), Integer.parseInt(parameter2), putThreads); + break; + case GET_FOREVER: + Optional getThreads = parameter2 == null ? Optional.empty() : Optional.of(Integer.parseInt(parameter2)); + this.service.getForever(Integer.parseInt(parameter1), getThreads); + break; + case DESTROY_FOREVER: + Optional destroyThreads = parameter2 == null ? Optional.empty() : Optional.of(Integer.parseInt(parameter2)); + this.service.destroyForever(Integer.parseInt(parameter1), destroyThreads); + break; + case QUERY_BY_CUSIP_FOREVER: + Optional queryThreads = parameter1 == null ? Optional.empty() : Optional.of(Integer.parseInt(parameter1)); + this.service.queryByCusipForever(queryThreads); + break; + case FUNCTION_UPDATE_FOREVER: + Optional functionThreads = parameter2 == null ? Optional.empty() : Optional.of(Integer.parseInt(parameter2)); + this.service.functionUpdateForever(Integer.parseInt(parameter1), functionThreads); + break; + case GET_ONE: + this.service.getOne(Integer.parseInt(parameter1)); + break; + case QUERY_ONE_BY_CUSIP: + this.service.queryOneByCusip(parameter1); + break; + case START_TEST: + Optional testThreads = parameter3 == null ? Optional.empty() : Optional.of(Integer.parseInt(parameter3)); + this.service.startTest(Integer.parseInt(parameter1), Integer.parseInt(parameter2), testThreads); + break; + } + } + }; + } + +// @Bean +// MappingPdxSerializer myCustomMappingPdxSerializer() { +// logger.warn("XXX Client.myCustomMappingPdxSerializer ", new Exception()); +// return MappingPdxSerializer.newMappingPdxSerializer(); +// } + + private void dumpArguments(ApplicationArguments args) { + logger.info("Client Command Line Arguments: " + Arrays.toString(args.getSourceArgs())); + for (String name : args.getOptionNames()){ + logger.info("Client Option Argument: " + name + "=" + args.getOptionValues(name)); + } + } + + private void waitForever() throws InterruptedException { + Object obj = new Object(); + synchronized (obj) { + obj.wait(); + } + } +} diff --git a/client/src/main/java/io/pivotal/test/client/Constants.java b/client/src/main/java/io/pivotal/test/client/Constants.java new file mode 100644 index 0000000..4eb0267 --- /dev/null +++ b/client/src/main/java/io/pivotal/test/client/Constants.java @@ -0,0 +1,58 @@ +package io.pivotal.test.client; + +public interface Constants { + + String OPERATION = "operation"; + + String PARAMETER_1 = "parameter1"; + + String PARAMETER_2 = "parameter2"; + + String PARAMETER_3 = "parameter3"; + + String PUT = "put"; + + String GET = "get"; + + String DESTROY = "destroy"; + + String QUERY_BY_CUSIP = "querybycusip"; + + String FUNCTION_UPDATE = "functionupdate"; + + String PUT_FOREVER = "putforever"; + + String GET_FOREVER = "getforever"; + + String DESTROY_FOREVER = "destroyforever"; + + String QUERY_BY_CUSIP_FOREVER = "querybycusipforever"; + + String FUNCTION_UPDATE_FOREVER = "functionupdateforever"; + + String GET_ONE = "getone"; + + String QUERY_ONE_BY_CUSIP = "queryonebycusip"; + + String START_TEST = "starttest"; + + String STOP_OPERATIONS = "stopoperations"; + + String TRADES_PATH = "/trades/"; + + String KEY_PARAMETER = "/{key}"; + + String CUSIP_PARAMETER = "/{cusip}"; + + String ENTRIES_PARAMETER = "/{entries}"; + + String SIZE_PARAMETER = "/{size}"; + + String QUERIES_PARAMETER = "/{queries}"; + + String THREADS_PARAMETER = "/{threads}"; + + String METRICS_PATH = "/metrics"; + + String METRICS_TYPE_PARAMETER = "/{type}"; +} diff --git a/client/src/main/java/io/pivotal/test/client/controller/AdminController.java b/client/src/main/java/io/pivotal/test/client/controller/AdminController.java new file mode 100644 index 0000000..6ebf474 --- /dev/null +++ b/client/src/main/java/io/pivotal/test/client/controller/AdminController.java @@ -0,0 +1,57 @@ +package io.pivotal.test.client.controller; + +import io.pivotal.test.client.function.AdminFunctions; +import org.apache.geode.cache.client.Pool; +import org.apache.geode.cache.client.PoolManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Collection; +import java.util.Map; + +@RestController +public class AdminController { + +// @Autowired +// private AdminFunctions functions; + + @GetMapping("/pools") + @ResponseStatus(HttpStatus.OK) + public String getPools() { + StringBuilder builder = new StringBuilder(); + Collection pools = PoolManager.getAll().values(); + builder + .append("The client defines the following ") + .append(pools.size()) + .append(" pools:"); + for (Pool pool : pools) { + builder + .append("\n\tname=") + .append(pool.getName()) + .append("; locators=") + .append(pool.getLocators()); + } + return builder.toString(); + } + +// @GetMapping("/metrics/{type}") +// @ResponseStatus(HttpStatus.OK) +// public Object getMetrics(@PathVariable String type) { +// StringBuilder builder = new StringBuilder(); +// Map>> allServerMetrics = this.functions.getMetrics(type); +// for (Map.Entry>> serverMetrics : allServerMetrics.entrySet()) { +// builder.append("\n").append(serverMetrics.getKey()).append(":"); +// for (Map.Entry> serverMetricTypes : serverMetrics.getValue().entrySet()) { +// builder.append("\n\t").append(serverMetricTypes.getKey()).append(":"); +// for (Map.Entry serverMetric : serverMetricTypes.getValue().entrySet()) { +// builder.append("\n\t\t").append(serverMetric.getKey()).append("=").append(serverMetric.getValue()); +// } +// } +// } +// return builder.toString(); +// } +} diff --git a/client/src/main/java/io/pivotal/test/client/controller/TradeController.java b/client/src/main/java/io/pivotal/test/client/controller/TradeController.java new file mode 100644 index 0000000..0d3273c --- /dev/null +++ b/client/src/main/java/io/pivotal/test/client/controller/TradeController.java @@ -0,0 +1,137 @@ +package io.pivotal.test.client.controller; + +import io.pivotal.test.client.domain.Trade; +import io.pivotal.test.client.service.OperationResponse; +import io.pivotal.test.client.service.TradeService; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Collection; +import java.util.Optional; + +import static io.pivotal.test.client.Constants.*; + +@RestController +public class TradeController { + + private final TradeService service; + + public TradeController(TradeService service) { + this.service = service; + } + + @GetMapping("/") + @ResponseStatus(HttpStatus.OK) + public String index() { + return "Spring Data Geode Example"; + } + + @GetMapping(TRADES_PATH + QUERY_ONE_BY_CUSIP + CUSIP_PARAMETER) + @ResponseStatus(HttpStatus.OK) + public Collection queryOneByCusip(@PathVariable String cusip) { + return this.service.queryOneByCusip( + cusip); + } + + @GetMapping(TRADES_PATH + GET_ONE + KEY_PARAMETER) + @ResponseStatus(HttpStatus.OK) + public Trade getOne(@PathVariable int key) { + return this.service.getOne(key); + } + + @GetMapping(TRADES_PATH + GET + ENTRIES_PARAMETER) + @ResponseStatus(HttpStatus.OK) + public OperationResponse get(@PathVariable int entries) { + return this.service.get(entries); + } + + @PostMapping(TRADES_PATH + PUT + ENTRIES_PARAMETER + SIZE_PARAMETER) + @ResponseStatus(HttpStatus.OK) + public OperationResponse put(@PathVariable int entries, @PathVariable int size) { + return this.service.put(entries, size); + } + + @DeleteMapping(TRADES_PATH + DESTROY + ENTRIES_PARAMETER) + @ResponseStatus(HttpStatus.OK) + public OperationResponse destroy(@PathVariable int entries) { + return this.service.destroy(entries); + } + + @GetMapping(TRADES_PATH + QUERY_BY_CUSIP + QUERIES_PARAMETER) + @ResponseStatus(HttpStatus.OK) + public OperationResponse queryByCusip(@PathVariable int queries) { + return this.service.queryByCusip(queries); + } + + @PostMapping(TRADES_PATH + FUNCTION_UPDATE + ENTRIES_PARAMETER) + @ResponseStatus(HttpStatus.OK) + public OperationResponse functionUpdate(@PathVariable int entries) { + return this.service.functionUpdate(entries); + } + + @PostMapping(value = { + TRADES_PATH + PUT_FOREVER + ENTRIES_PARAMETER + SIZE_PARAMETER, + TRADES_PATH + PUT_FOREVER + ENTRIES_PARAMETER + SIZE_PARAMETER + THREADS_PARAMETER }) + @ResponseStatus(HttpStatus.OK) + public OperationResponse putForever(@PathVariable int entries, @PathVariable int size, @PathVariable Optional threads) { + return this.service.putForever(entries, size, threads); + } + + @GetMapping(value = { + TRADES_PATH + GET_FOREVER + ENTRIES_PARAMETER, + TRADES_PATH + GET_FOREVER + ENTRIES_PARAMETER + THREADS_PARAMETER }) + @ResponseStatus(HttpStatus.OK) + public OperationResponse getForever(@PathVariable int entries, @PathVariable Optional threads) { + return this.service.getForever(entries, threads); + } + + @DeleteMapping(value = { + TRADES_PATH + DESTROY_FOREVER + ENTRIES_PARAMETER, + TRADES_PATH + DESTROY_FOREVER + ENTRIES_PARAMETER + THREADS_PARAMETER }) + @ResponseStatus(HttpStatus.OK) + public OperationResponse destroyForever(@PathVariable int entries, @PathVariable Optional threads) { + return this.service.destroyForever(entries, threads); + } + + @GetMapping(value = { + TRADES_PATH + QUERY_BY_CUSIP_FOREVER, + TRADES_PATH + QUERY_BY_CUSIP_FOREVER + THREADS_PARAMETER}) + @ResponseStatus(HttpStatus.OK) + public OperationResponse queryByCusipForever(@PathVariable Optional threads) { + return this.service.queryByCusipForever(threads); + } + + @PostMapping(value = { + TRADES_PATH + FUNCTION_UPDATE_FOREVER + ENTRIES_PARAMETER, + TRADES_PATH + FUNCTION_UPDATE_FOREVER + ENTRIES_PARAMETER + THREADS_PARAMETER}) + @ResponseStatus(HttpStatus.OK) + public OperationResponse functionUpdateForever(@PathVariable int entries, @PathVariable Optional threads) { + return this.service.functionUpdateForever(entries, threads); + } + + @PostMapping(value = { + TRADES_PATH + START_TEST + ENTRIES_PARAMETER + SIZE_PARAMETER, + TRADES_PATH + START_TEST + ENTRIES_PARAMETER + SIZE_PARAMETER + THREADS_PARAMETER + }) + @ResponseStatus(HttpStatus.OK) + public OperationResponse[] startTest(@PathVariable int entries, @PathVariable int size, @PathVariable Optional threads) { + return this.service.startTest(entries, size, threads); + } + + @PostMapping(TRADES_PATH + STOP_OPERATIONS) + @ResponseStatus(HttpStatus.OK) + public OperationResponse stopOperations() { + return this.service.stopOperations(); + } + + @GetMapping(METRICS_PATH + METRICS_TYPE_PARAMETER) + @ResponseStatus(HttpStatus.OK) + public Object getMetrics(@PathVariable String type) { + return this.service.getMetrics(type); + } +} diff --git a/client/src/main/java/io/pivotal/test/client/domain/CusipHelper.java b/client/src/main/java/io/pivotal/test/client/domain/CusipHelper.java new file mode 100755 index 0000000..515c32a --- /dev/null +++ b/client/src/main/java/io/pivotal/test/client/domain/CusipHelper.java @@ -0,0 +1,21 @@ +package io.pivotal.test.client.domain; + +import java.util.Random; + +public class CusipHelper { + + private static final Random RANDOM = new Random(); + + private static final String[] CUSIPS = new String[] { + "AAPL", "MSFT", "AMZN", "GOOGL", "FB", "JPM", "V", "JNJ", "WMT", "PG", + "BAC", "XOM", "MA", "UNH", "VZ", "INTC", "HD", "KO", "MRK", "WFC", "PFE", + "NVS", "TM", "CMCSA", "BA", "PEP", "CSCO", "ORCL", "C", "SAP", "HSBC", + "ADBE", "MCD", "NKE", "NFLX", "COST", "BUD", "HON", "PYPL", "AVGO", "CRM", + "UNP", "IBM", "LLY", "TXN", "LMT", "SBUX", "UPS", "QCOM", "CVS", "AXP", + "MMM", "BMY", "GE" + }; + + public static String getCusip() { + return CUSIPS[RANDOM.nextInt(CUSIPS.length)]; + } +} diff --git a/client/src/main/java/io/pivotal/test/client/domain/Trade.java b/client/src/main/java/io/pivotal/test/client/domain/Trade.java new file mode 100644 index 0000000..79ebafb --- /dev/null +++ b/client/src/main/java/io/pivotal/test/client/domain/Trade.java @@ -0,0 +1,34 @@ +package io.pivotal.test.client.domain; + +import lombok.Data; +import lombok.Getter; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import lombok.ToString; +import org.springframework.data.annotation.Id; +import org.springframework.data.gemfire.mapping.annotation.Region; + +import java.math.BigDecimal; + +@Data +@Getter +@ToString(exclude = "payload") +@Region("Trades") +@RequiredArgsConstructor +public class Trade { + + @Id + @NonNull + private final String id; + + @NonNull + private final String cusip; + + private final int shares; + + @NonNull + private final BigDecimal price; + + @NonNull + private final byte[] payload; +} diff --git a/client/src/main/java/io/pivotal/test/client/function/AdminFunctions.java b/client/src/main/java/io/pivotal/test/client/function/AdminFunctions.java new file mode 100644 index 0000000..91dc8b2 --- /dev/null +++ b/client/src/main/java/io/pivotal/test/client/function/AdminFunctions.java @@ -0,0 +1,16 @@ +package io.pivotal.test.client.function; + +import org.springframework.data.gemfire.function.annotation.FunctionId; +import org.springframework.data.gemfire.function.annotation.OnRegion; +//import org.springframework.data.gemfire.function.annotation.OnServers; + +import java.util.Map; + +//@OnServers(resultCollector = "adminResultCollector") +@OnRegion(region = "Trades", resultCollector = "adminResultCollector") +public interface AdminFunctions { + + @FunctionId("GetMetricsFunction") + //Map>> getMetrics(String type); + Object getMetrics(); +} diff --git a/client/src/main/java/io/pivotal/test/client/function/AdminFunctionsResultCollector.java b/client/src/main/java/io/pivotal/test/client/function/AdminFunctionsResultCollector.java new file mode 100644 index 0000000..dbedd2f --- /dev/null +++ b/client/src/main/java/io/pivotal/test/client/function/AdminFunctionsResultCollector.java @@ -0,0 +1,68 @@ +package io.pivotal.test.client.function; + +import org.apache.geode.cache.execute.FunctionException; +import org.apache.geode.cache.execute.ResultCollector; +import org.apache.geode.distributed.DistributedMember; +import org.apache.geode.internal.logging.LogService; +import org.springframework.stereotype.Component; + +import java.util.Collections; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; + +@Component("adminResultCollector") +public class AdminFunctionsResultCollector implements ResultCollector { + + private Map results = new ConcurrentHashMap<>(); + + @Override + public Set getResult() throws FunctionException { + // SDG OnServers functions expect an iterable containing one element (the actual result). + // In this case the first element of the iterable is passed to the caller. + // java.lang.ClassCastException: java.util.concurrent.ConcurrentHashMap cannot be cast to java.lang.Iterable + // at org.springframework.data.gemfire.function.execution.AbstractFunctionExecution.execute(AbstractFunctionExecution.java:140) ~[spring-data-geode-2.2.1.RELEASE.jar:2.2.1.RELEASE] + // at org.springframework.data.gemfire.function.execution.AbstractFunctionExecution.execute(AbstractFunctionExecution.java:95) ~[spring-data-geode-2.2.1.RELEASE.jar:2.2.1.RELEASE] + // at org.springframework.data.gemfire.function.execution.AbstractFunctionExecution.executeAndExtract(AbstractFunctionExecution.java:158) ~[spring-data-geode-2.2.1.RELEASE.jar:2.2.1.RELEASE] + // at org.springframework.data.gemfire.function.execution.AbstractFunctionTemplate.executeAndExtract(AbstractFunctionTemplate.java:79) ~[spring-data-geode-2.2.1.RELEASE.jar:2.2.1.RELEASE] + // at org.springframework.data.gemfire.function.execution.AbstractFunctionTemplate.executeAndExtract(AbstractFunctionTemplate.java:57) ~[spring-data-geode-2.2.1.RELEASE.jar:2.2.1.RELEASE] + // at org.springframework.data.gemfire.function.execution.GemfireOnServersFunctionTemplate.executeAndExtract(GemfireOnServersFunctionTemplate.java:45) ~[spring-data-geode-2.2.1.RELEASE.jar:2.2.1.RELEASE] + // at org.springframework.data.gemfire.function.execution.GemfireFunctionProxyFactoryBean.invokeFunction(GemfireFunctionProxyFactoryBean.java:102) ~[spring-data-geode-2.2.1.RELEASE.jar:2.2.1.RELEASE] + // at org.springframework.data.gemfire.function.execution.GemfireFunctionProxyFactoryBean.invoke(GemfireFunctionProxyFactoryBean.java:96) ~[spring-data-geode-2.2.1.RELEASE.jar:2.2.1.RELEASE] + + // SDG OnRegions functions expect an iterable result. In this case, the iterable is passed to the caller. + // java.lang.ClassCastException: java.util.concurrent.ConcurrentHashMap cannot be cast to java.lang.Iterable + // at org.springframework.data.gemfire.function.execution.AbstractFunctionExecution.execute(AbstractFunctionExecution.java:140) ~[spring-data-geode-2.2.3.RELEASE.jar:2.2.3.RELEASE] + // at org.springframework.data.gemfire.function.execution.AbstractFunctionExecution.execute(AbstractFunctionExecution.java:95) ~[spring-data-geode-2.2.3.RELEASE.jar:2.2.3.RELEASE] + // at org.springframework.data.gemfire.function.execution.AbstractFunctionTemplate.execute(AbstractFunctionTemplate.java:71) ~[spring-data-geode-2.2.3.RELEASE.jar:2.2.3.RELEASE] + // at org.springframework.data.gemfire.function.execution.AbstractFunctionTemplate.execute(AbstractFunctionTemplate.java:52) ~[spring-data-geode-2.2.3.RELEASE.jar:2.2.3.RELEASE] + // at org.springframework.data.gemfire.function.execution.GemfireOnRegionFunctionTemplate.execute(GemfireOnRegionFunctionTemplate.java:26) ~[spring-data-geode-2.2.3.RELEASE.jar:2.2.3.RELEASE] + // at org.springframework.data.gemfire.function.execution.OnRegionFunctionProxyFactoryBean.invokeFunction(OnRegionFunctionProxyFactoryBean.java:65) ~[spring-data-geode-2.2.3.RELEASE.jar:2.2.3.RELEASE] + // at org.springframework.data.gemfire.function.execution.OnRegionFunctionProxyFactoryBean.invokeFunction(OnRegionFunctionProxyFactoryBean.java:28) ~[spring-data-geode-2.2.3.RELEASE.jar:2.2.3.RELEASE] + // at org.springframework.data.gemfire.function.execution.GemfireFunctionProxyFactoryBean.invoke(GemfireFunctionProxyFactoryBean.java:96) ~[spring-data-geode-2.2.3.RELEASE.jar:2.2.3.RELEASE] + + return Collections.singleton(this.results); + } + + @Override + public Set getResult(long timeout, TimeUnit unit) throws FunctionException, InterruptedException { + return getResult(); + } + + @Override + public void addResult(DistributedMember memberID, Map result) { + //LogService.getLogger().warn("XXX AdminFunctionsResultCollector.addResult memberID=" + memberID + "; result=" + result); + this.results.put(memberID.toString(), result); + } + + @Override + public void endResults() { + + } + + @Override + public void clearResults() { + this.results.clear(); + } +} diff --git a/client/src/main/java/io/pivotal/test/client/function/TradeFunctions.java b/client/src/main/java/io/pivotal/test/client/function/TradeFunctions.java new file mode 100644 index 0000000..573a73b --- /dev/null +++ b/client/src/main/java/io/pivotal/test/client/function/TradeFunctions.java @@ -0,0 +1,15 @@ +package io.pivotal.test.client.function; + +import org.springframework.data.gemfire.function.annotation.Filter; +import org.springframework.data.gemfire.function.annotation.FunctionId; +import org.springframework.data.gemfire.function.annotation.OnRegion; + +import java.math.BigDecimal; +import java.util.Set; + +@OnRegion(region = "Trades") +public interface TradeFunctions { + + @FunctionId("UpdateTradeFunction") + Object updateTrade(@Filter Set keys, int shares, BigDecimal price); +} \ No newline at end of file diff --git a/client/src/main/java/io/pivotal/test/client/metrics/Metrics.java b/client/src/main/java/io/pivotal/test/client/metrics/Metrics.java new file mode 100644 index 0000000..5b7db84 --- /dev/null +++ b/client/src/main/java/io/pivotal/test/client/metrics/Metrics.java @@ -0,0 +1,20 @@ +package io.pivotal.test.client.metrics; + +import lombok.Getter; +import lombok.ToString; + +import java.util.Map; + +@Getter +@ToString +public class Metrics { + + private Map clientMetrics; + + private Map serverMetrics; + + public Metrics(Map clientMetrics, Map serverMetrics) { + this.clientMetrics = clientMetrics; + this.serverMetrics = serverMetrics; + } +} diff --git a/client/src/main/java/io/pivotal/test/client/metrics/MetricsHelper.java b/client/src/main/java/io/pivotal/test/client/metrics/MetricsHelper.java new file mode 100644 index 0000000..7b14ddf --- /dev/null +++ b/client/src/main/java/io/pivotal/test/client/metrics/MetricsHelper.java @@ -0,0 +1,68 @@ +package io.pivotal.test.client.metrics; + +import org.apache.geode.StatisticDescriptor; +import org.apache.geode.Statistics; +import org.apache.geode.StatisticsType; +import org.apache.geode.cache.Cache; +import org.apache.geode.cache.CacheFactory; +import org.apache.geode.distributed.internal.InternalDistributedSystem; +import org.apache.geode.internal.statistics.platform.LinuxSystemStats; +import org.apache.geode.management.ManagementService; +import org.apache.geode.management.OSMetrics; +import org.apache.geode.management.internal.beans.MemberMBean; + +import java.lang.management.GarbageCollectorMXBean; +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryPoolMXBean; +import java.lang.management.MemoryUsage; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +public class MetricsHelper { + + public static void addOSMetrics(Map allMetrics) { + InternalDistributedSystem system = (InternalDistributedSystem) CacheFactory.getAnyInstance().getDistributedSystem(); + + Map osMetrics = new TreeMap(); + allMetrics.put("os", osMetrics); + + // If the linux system statistics exist, add them to the os metrics map. + // Otherwise add the available stats from the osmetrics. + Statistics[] systemStatisticsArr = system.findStatisticsByType(LinuxSystemStats.getType()); + if (systemStatisticsArr.length > 0) { + Statistics systemStatistics = systemStatisticsArr[0]; + StatisticsType type = systemStatistics.getType(); + for (StatisticDescriptor descriptor : type.getStatistics()) { + String statName = descriptor.getName(); + Number statValue = systemStatistics.get(statName); + osMetrics.put(statName, statValue); + } + } + } + + public static void addGCMetrics(Map allMetrics) { + Map gcMetrics = new TreeMap(); + allMetrics.put("gc", gcMetrics); + List gcBeans = ManagementFactory.getGarbageCollectorMXBeans(); + for (GarbageCollectorMXBean gcBean : gcBeans) { + gcMetrics.put(gcBean.getName() + "_collections", gcBean.getCollectionCount()); + gcMetrics.put(gcBean.getName() + "_collectionTime", gcBean.getCollectionTime()); + } + } + + public static void addMemoryMetrics(Map allMetrics) { + Map memoryMetrics = new TreeMap(); + allMetrics.put("memory", memoryMetrics); + List memoryBeans = ManagementFactory.getMemoryPoolMXBeans(); + for (MemoryPoolMXBean memoryBean : memoryBeans) { + if (memoryBean.getName().contains("Old") || memoryBean.getName().contains("Eden")) { + String memoryBeanName = memoryBean.getName().replaceAll(" ", "_"); + MemoryUsage usage = memoryBean.getUsage(); + memoryMetrics.put(memoryBeanName + "_init", usage.getInit()); + memoryMetrics.put(memoryBeanName + "_used", usage.getUsed()); + memoryMetrics.put(memoryBeanName + "_max", usage.getMax()); + } + } + } +} diff --git a/client/src/main/java/io/pivotal/test/client/repository/TradeRepository.java b/client/src/main/java/io/pivotal/test/client/repository/TradeRepository.java new file mode 100644 index 0000000..01c51aa --- /dev/null +++ b/client/src/main/java/io/pivotal/test/client/repository/TradeRepository.java @@ -0,0 +1,11 @@ +package io.pivotal.test.client.repository; + +import io.pivotal.test.client.domain.Trade; +import org.springframework.data.gemfire.repository.GemfireRepository; + +import java.util.Collection; + +public interface TradeRepository extends GemfireRepository { + + Collection findByCusip(String cusip); +} diff --git a/client/src/main/java/io/pivotal/test/client/service/OperationResponse.java b/client/src/main/java/io/pivotal/test/client/service/OperationResponse.java new file mode 100644 index 0000000..a33cfe5 --- /dev/null +++ b/client/src/main/java/io/pivotal/test/client/service/OperationResponse.java @@ -0,0 +1,19 @@ +package io.pivotal.test.client.service; + +import lombok.Getter; + +@Getter +public class OperationResponse { + + private String operation; + + private Status status; + + private long completionTime; + + public OperationResponse(String operation, Status status, long completionTime) { + this.operation = operation; + this.status = status; + this.completionTime = completionTime; + } +} diff --git a/client/src/main/java/io/pivotal/test/client/service/Status.java b/client/src/main/java/io/pivotal/test/client/service/Status.java new file mode 100644 index 0000000..a89eb85 --- /dev/null +++ b/client/src/main/java/io/pivotal/test/client/service/Status.java @@ -0,0 +1,6 @@ +package io.pivotal.test.client.service; + +public enum Status { + SUCCESS, + FAILURE +} diff --git a/client/src/main/java/io/pivotal/test/client/service/TradeService.java b/client/src/main/java/io/pivotal/test/client/service/TradeService.java new file mode 100644 index 0000000..37573ef --- /dev/null +++ b/client/src/main/java/io/pivotal/test/client/service/TradeService.java @@ -0,0 +1,366 @@ +package io.pivotal.test.client.service; + +import io.pivotal.test.client.domain.CusipHelper; +import io.pivotal.test.client.domain.Trade; +import io.pivotal.test.client.function.AdminFunctions; +import io.pivotal.test.client.function.TradeFunctions; +import io.pivotal.test.client.metrics.Metrics; +import io.pivotal.test.client.metrics.MetricsHelper; +import io.pivotal.test.client.repository.TradeRepository; +import org.apache.geode.internal.logging.LogService; +import org.apache.logging.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.Optional; +import java.util.Random; +import java.util.TreeMap; +import java.util.concurrent.atomic.AtomicInteger; + +import static io.pivotal.test.client.Constants.*; + +@Service +public class TradeService { + + @Autowired + private TradeRepository repository; + + @Autowired + private TradeFunctions tradeFunctions; + + @Autowired + private AdminFunctions adminFunctions; + + private final AtomicInteger putOperations = new AtomicInteger(); + + private final AtomicInteger getOperations = new AtomicInteger(); + + private final AtomicInteger destroyOperations = new AtomicInteger(); + + private final AtomicInteger queryByCusipOperations = new AtomicInteger(); + + private final AtomicInteger functionUpdateOperations = new AtomicInteger(); + + private volatile boolean continueOperations; + + private static final Logger logger = LogService.getLogger(); + + private static final Random RANDOM = new Random(); + + private static final int ENTRIES_TO_LOG = 10000; + + public Collection queryOneByCusip(String cusip) { + logger.info("Executing query for cusip=" + cusip); + long start, end; + start = System.currentTimeMillis(); + Collection results = executeFindByCusipQuery(cusip); + end = System.currentTimeMillis(); + logger.info("Returned " + results.size() + " trades for cusip=" + cusip + " in " + (end-start) + " ms:"); + for (Trade trade : results) { + logger.info("\t" + trade); + } + return results; + } + + public Trade getOne(int key) { + return get(key, true); + } + + public OperationResponse put(int numEntries, int entrySize) { + logger.info("Putting " + numEntries + " trades of size " + entrySize + " bytes"); + long start, end; + start = System.currentTimeMillis(); + for (int i=0; i results = executeFindByCusipQuery(cusip); + logger.info("Returned " + results.size() + " trades for cusip=" + cusip); + } + end = System.currentTimeMillis(); + logger.info("Executed " + numQueries + " cusip queries in " + (end-start) + " ms"); + return new OperationResponse(QUERY_BY_CUSIP, Status.SUCCESS, end-start); + } + + public OperationResponse functionUpdate(int numEntries) { + logger.info("Updating " + numEntries + " trades with function"); + long start, end; + start = System.currentTimeMillis(); + for (int i = 0; i < numEntries; i++) { + Object result = executUpdateFunction(i); + logger.info("Updated trade " + i + " result=" + result); + } + end = System.currentTimeMillis(); + logger.info("Updated " + numEntries + " trades with function in " + (end - start) + " ms"); + return new OperationResponse(FUNCTION_UPDATE, Status.SUCCESS, end - start); + } + + public void putForever(int numEntries, int entrySize) { + logger.info("Putting " + numEntries + " trades of size " + entrySize + " bytes forever"); + this.continueOperations = true; + this.putOperations.set(0); + int i=0; + long start=0, end=0; + start = System.currentTimeMillis(); + while (continueOperations()) { + put(RANDOM.nextInt(numEntries), entrySize, false); + if ((i+1) % ENTRIES_TO_LOG == 0) { + end = System.currentTimeMillis(); + logger.info("Put " + (i+1) + " trades of size " + entrySize + " bytes in " + (end-start) + " ms"); + start = System.currentTimeMillis(); + } + i++; + this.putOperations.incrementAndGet(); + } + logger.info("Stopping after putting " + i + " trades of size " + entrySize + " bytes"); + } + + public void getForever(int numEntries) { + logger.info("Getting " + numEntries + " trades forever"); + this.continueOperations = true; + this.getOperations.set(0); + int i=0; + long start=0, end=0; + start = System.currentTimeMillis(); + while (continueOperations()) { + get(RANDOM.nextInt(numEntries), false); + if ((i+1) % ENTRIES_TO_LOG == 0) { + end = System.currentTimeMillis(); + logger.info("Got " + (i+1) + " trades in " + (end-start) + " ms"); + start = System.currentTimeMillis(); + } + i++; + this.getOperations.incrementAndGet(); + } + logger.info("Stopping after getting " + i + " trades"); + } + + public void destroyForever(int numEntries) { + logger.info("Destroying " + numEntries + " trades forever"); + this.continueOperations = true; + this.destroyOperations.set(0); + int i=0; + long start=0, end=0; + start = System.currentTimeMillis(); + while (continueOperations()) { + destroy(RANDOM.nextInt(numEntries), false); + if ((i+1) % ENTRIES_TO_LOG == 0) { + end = System.currentTimeMillis(); + logger.info("Destroyed " + (i+1) + " trades in " + (end-start) + " ms"); + start = System.currentTimeMillis(); + } + i++; + this.destroyOperations.incrementAndGet(); + } + logger.info("Stopping after destroying " + i + " trades"); + } + + public void queryByCusipForever() { + logger.info("Executing cusip queries forever"); + this.continueOperations = true; + this.queryByCusipOperations.set(0); + int i=0; + long start=0, end=0; + start = System.currentTimeMillis(); + while (continueOperations()) { + executeFindByCusipQuery(CusipHelper.getCusip()); + if ((i+1) % ENTRIES_TO_LOG == 0) { + end = System.currentTimeMillis(); + logger.info("Executed " + (i+1) + " cusip queries in " + (end-start) + " ms"); + start = System.currentTimeMillis(); + } + i++; + this.queryByCusipOperations.incrementAndGet(); + } + logger.info("Stopping after executing " + i + " cusip queries"); + } + + public void functionUpdateForever(int numEntries) { + logger.info("Updating " + numEntries + " trades with function forever"); + this.continueOperations = true; + this.functionUpdateOperations.set(0); + int i=0; + long start=0, end=0; + start = System.currentTimeMillis(); + while (continueOperations()) { + executUpdateFunction(RANDOM.nextInt(numEntries)); + if ((i+1) % ENTRIES_TO_LOG == 0) { + end = System.currentTimeMillis(); + logger.info("Updated " + (i+1) + " trades with function in " + (end-start) + " ms"); + start = System.currentTimeMillis(); + } + i++; + this.functionUpdateOperations.incrementAndGet(); + } + logger.info("Stopping after updating " + i + " trades with function"); + } + + public OperationResponse putForever(final int numEntries, final int entrySize, Optional numThreads) { + for (int i=0; i putForever(numEntries, entrySize)); + thread.start(); + } + return new OperationResponse(PUT_FOREVER, Status.SUCCESS, 0); + } + + public OperationResponse getForever(final int numEntries, Optional numThreads) { + for (int i=0; i getForever(numEntries)); + thread.start(); + } + return new OperationResponse(GET_FOREVER, Status.SUCCESS, 0); + } + + public OperationResponse destroyForever(final int numEntries, Optional numThreads) { + for (int i=0; i destroyForever(numEntries)); + thread.start(); + } + return new OperationResponse(DESTROY_FOREVER, Status.SUCCESS, 0); + } + + public OperationResponse queryByCusipForever(Optional numThreads) { + for (int i=0; i queryByCusipForever()); + thread.start(); + } + return new OperationResponse(QUERY_BY_CUSIP_FOREVER, Status.SUCCESS, 0); + } + + public OperationResponse functionUpdateForever(final int numEntries, Optional numThreads) { + for (int i=0; i functionUpdateForever(numEntries)); + thread.start(); + } + return new OperationResponse(FUNCTION_UPDATE_FOREVER, Status.SUCCESS, 0); + } + + public OperationResponse[] startTest(int numEntries, int entrySize, Optional numThreads) { + OperationResponse putResponse = putForever(numEntries, entrySize, numThreads); + OperationResponse getResponse = getForever(numEntries, numThreads); + OperationResponse queryResponse = queryByCusipForever(numThreads); + OperationResponse functionResponse = functionUpdateForever(numEntries, numThreads); + return new OperationResponse[] {putResponse, getResponse, queryResponse, functionResponse}; + } + + public OperationResponse stopOperations() { + this.continueOperations = false; + logger.info("Stopping operations"); + return new OperationResponse(STOP_OPERATIONS, Status.SUCCESS, 0); + } + + public Object getMetrics(String type) { + return new Metrics(getClientMetrics(type), getServerMetrics(type)); + } + + private void put(int index, int entrySize, boolean log) { + Trade trade = new Trade(String.valueOf(index), CusipHelper.getCusip(), RANDOM.nextInt(100), new BigDecimal(BigInteger.valueOf(RANDOM.nextInt(100000)), 2), new byte[entrySize]); + trade = this.repository.save(trade); + if (log) { + logger.info("Saved " + trade); + } + } + + private Trade get(int index, boolean log) { + String key = String.valueOf(index); + Optional tradeOptional = this.repository.findById(key); + Trade trade = null; + if (tradeOptional.isPresent()) { + trade = tradeOptional.get(); + } + if (log) { + logger.info(trade == null ? "No trade exists for key=" + key : "Got " + trade); + } + return trade; + } + + private void destroy(int index, boolean log) { + String key = String.valueOf(index); + this.repository.deleteById(key); + if (log) { + logger.info("Destroyed key=" + key); + } + } + + private Collection executeFindByCusipQuery(String cusip) { + return this.repository.findByCusip(cusip); + } + + private Object executUpdateFunction(int index) { + return this.tradeFunctions.updateTrade(Collections.singleton(String.valueOf(index)), RANDOM.nextInt(100), new BigDecimal(BigInteger.valueOf(RANDOM.nextInt(100000)), 2)); + } + + private Map getServerMetrics(String type) { + Map serverMetrics = null; + if (type.equals("all") || type.equals("server")) { + Iterable serverMetricsIter = (Iterable) this.adminFunctions.getMetrics(); + serverMetrics = (Map) serverMetricsIter.iterator().next(); + } + return serverMetrics; + } + + private Map getClientMetrics(String type) { + Map clientMetrics = null; + if (type.equals("all") || type.equals("client")) { + clientMetrics = new TreeMap(); + addOperationMetrics(clientMetrics); + MetricsHelper.addOSMetrics(clientMetrics); + MetricsHelper.addGCMetrics(clientMetrics); + MetricsHelper.addMemoryMetrics(clientMetrics); + } + return clientMetrics; + } + + private void addOperationMetrics(Map clientMetrics) { + Map operationMetrics = new TreeMap(); + clientMetrics.put("operations", operationMetrics); + operationMetrics.put("puts", this.putOperations.get()); + operationMetrics.put("gets", this.getOperations.get()); + operationMetrics.put("destroys", this.destroyOperations.get()); + operationMetrics.put("cusipQueries", this.queryByCusipOperations.get()); + operationMetrics.put("functionUpdates", this.functionUpdateOperations.get()); + } + + private boolean continueOperations() { + return this.continueOperations; + } +} diff --git a/client/src/main/resources/application-local.properties b/client/src/main/resources/application-local.properties new file mode 100644 index 0000000..083d9ff --- /dev/null +++ b/client/src/main/resources/application-local.properties @@ -0,0 +1,10 @@ +# GemFire properties +spring.data.gemfire.name=client +spring.data.gemfire.pool.locators=localhost[10334] +spring.data.gemfire.pool.statistic-interval=1000 +spring.data.gemfire.stats.archive-file=client.gfs +spring.data.gemfire.logging.log-file=client.log + +# Spring Actuator Properties +management.endpoint.health.show-details=always +management.endpoints.web.exposure.include=* diff --git a/client/src/main/resources/application.properties b/client/src/main/resources/application.properties new file mode 100644 index 0000000..adefae8 --- /dev/null +++ b/client/src/main/resources/application.properties @@ -0,0 +1,12 @@ +# GemFire properties +# This property was causing this exception in pcfone: +# org.apache.geode.security.GemFireSecurityException: Instance could not be obtained from org.springframework.data.gemfire.config.annotation.support.AutoConfiguredAuthenticationInitializer.newAuthenticationInitializer +#spring.data.gemfire.pool.statistic-interval=1000 + +# Spring Actuator Properties +management.endpoint.health.show-details=always +management.endpoints.web.exposure.include=* + +# GemFire properties +spring.data.gemfire.stats.archive-file=client.gfs +spring.data.gemfire.logging.log-file=client.log diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..cc4fdc293d0e50b0ad9b65c16e7ddd1db2f6025b GIT binary patch literal 58702 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

@up^y4&I8N>~wvL%f(S2W%NN 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 D613UA literal 0 HcmV?d00001 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..2da813a --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jan 03 13:40:41 PST 2020 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-all.zip diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..2fe81a7 --- /dev/null +++ b/gradlew @@ -0,0 +1,183 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..24467a1 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,100 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/server/README.md b/server/README.md new file mode 100644 index 0000000..9edda81 --- /dev/null +++ b/server/README.md @@ -0,0 +1,785 @@ +# Spring Boot Data Geode Example + +## Description +This project contains the functions for the Spring Boot Data Geode client. + +It uses: + +- GEODE 1.9.2 + +## Build Application +Build the application jar using **mvn** like: + +``` +mvn clean package +[INFO] Scanning for projects... +[INFO] +[INFO] --------------------------< io.pivotal:test >--------------------------- +[INFO] Building test 0.0.1-SNAPSHOT +[INFO] --------------------------------[ jar ]--------------------------------- +[INFO] +[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ test --- +[INFO] +[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ test --- +[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent! +[INFO] skip non existing resourceDirectory /Users/boglesby/Dev/Tests/spring-boot/long_running_test/server/src/main/resources +[INFO] +[INFO] --- maven-compiler-plugin:3.3:compile (default-compile) @ test --- +[INFO] Changes detected - recompiling the module! +[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent! +[INFO] Compiling 2 source files to /Users/boglesby/Dev/Tests/spring-boot/long_running_test/server/target/classes +[INFO] /Users/boglesby/Dev/Tests/spring-boot/long_running_test/server/src/main/java/io/pivotal/test/server/function/GetMetricsFunction.java: Some input files use unchecked or unsafe operations. +[INFO] /Users/boglesby/Dev/Tests/spring-boot/long_running_test/server/src/main/java/io/pivotal/test/server/function/GetMetricsFunction.java: Recompile with -Xlint:unchecked for details. +[INFO] +[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ test --- +[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent! +[INFO] skip non existing resourceDirectory /Users/boglesby/Dev/Tests/spring-boot/long_running_test/server/src/test/resources +[INFO] +[INFO] --- maven-compiler-plugin:3.3:testCompile (default-testCompile) @ test --- +[INFO] No sources to compile +[INFO] +[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ test --- +[INFO] No tests to run. +[INFO] +[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ test --- +[INFO] Building jar: /Users/boglesby/Dev/Tests/spring-boot/long_running_test/server/target/test-0.0.1-SNAPSHOT.jar +[INFO] ------------------------------------------------------------------------ +[INFO] BUILD SUCCESS +[INFO] ------------------------------------------------------------------------ +[INFO] Total time: 1.558 s +[INFO] Finished at: 2019-12-13T09:44:10-08:00 +[INFO] ------------------------------------------------------------------------ +``` + +## Start Locator and Servers +### Local +#### Start Locator and Servers with Configuration +Start and configure the locator and servers using the **startandconfigurelocal.sh** script like: + +``` +startandconfigurelocal.sh +1. Executing - start locator --name=locator + +.... +Locator in /Users/boglesby/Dev/Tests/spring-boot/long_running_test/server/locator on 192.168.1.4[10334] as locator is currently online. +Process ID: 95653 +Uptime: 5 seconds +Geode Version: 9.8.3 +Java Version: 1.8.0_121 +Log File: /Users/boglesby/Dev/Tests/spring-boot/long_running_test/server/locator/locator.log +JVM Arguments: -Dgemfire.enable-cluster-configuration=true -Dgemfire.load-cluster-configuration-from-dir=false -Dgemfire.launcher.registerSignalHandlers=true -Djava.awt.headless=true -Dsun.rmi.dgc.server.gcInterval=9223372036854775806 +Class-Path: /Users/boglesby/Dev/GemFire/GitBuilds/gemfire983/geode-assembly/build/install/apache-geode/lib/geode-core-9.8.3.jar:/Users/boglesby/Dev/GemFire/GitBuilds/gemfire983/geode-assembly/build/install/apache-geode/lib/geode-dependencies.jar + +Successfully connected to: JMX Manager [host=192.168.1.4, port=1099] + +Cluster configuration service is up and running. + +2. Executing - set variable --name=APP_RESULT_VIEWER --value=any + +Value for variable APP_RESULT_VIEWER is now: any. + +3. Executing - configure pdx --read-serialized=true + +read-serialized = true +ignore-unread-fields = false +persistent = false +Changes to configuration for group 'cluster' are persisted. + +4. Executing - start server --name=server-1 --server-port=0 --enable-time-statistics=true --statistic-archive-file=cacheserver.gfs --J=-Dgemfire.conserve-sockets=false --J=-Dgemfire.log-file=cacheserver.log --eviction-heap-percentage=75 --critical-heap-percentage=95 --J=-XX:NewSize=189m --J=-XX:MaxNewSize=189m --J=-Xms1897m --J=-Xmx1897m --J=-XX:CMSInitiatingOccupancyFraction=60 --J=-XX:+UseConcMarkSweepGC --J=-XX:+UseCMSInitiatingOccupancyOnly + +.... +Server in /Users/boglesby/Dev/Tests/spring-boot/long_running_test/server/server-1 on 192.168.1.4[64406] as server-1 is currently online. +Process ID: 95772 +Uptime: 4 seconds +Geode Version: 9.8.3 +Java Version: 1.8.0_121 +Log File: /Users/boglesby/Dev/Tests/spring-boot/long_running_test/server/server-1/cacheserver.log +JVM Arguments: -Dgemfire.default.locators=192.168.1.4[10334] -Dgemfire.start-dev-rest-api=false -Dgemfire.use-cluster-configuration=true -Dgemfire.statistic-archive-file=cacheserver.gfs -Dgemfire.enable-time-statistics=true -Dgemfire.conserve-sockets=false -Dgemfire.log-file=cacheserver.log -XX:NewSize=189m -XX:MaxNewSize=189m -Xms1897m -Xmx1897m -XX:CMSInitiatingOccupancyFraction=60 -XX:+UseConcMarkSweepGC -XX:+UseCMSInitiatingOccupancyOnly -XX:OnOutOfMemoryError=kill -KILL %p -Dgemfire.launcher.registerSignalHandlers=true -Djava.awt.headless=true -Dsun.rmi.dgc.server.gcInterval=9223372036854775806 +Class-Path: /Users/boglesby/Dev/GemFire/GitBuilds/gemfire983/geode-assembly/build/install/apache-geode/lib/geode-core-9.8.3.jar:/Users/boglesby/Dev/GemFire/GitBuilds/gemfire983/geode-assembly/build/install/apache-geode/lib/geode-dependencies.jar + +5. Executing - start server --name=server-2 --server-port=0 --enable-time-statistics=true --statistic-archive-file=cacheserver.gfs --J=-Dgemfire.conserve-sockets=false --J=-Dgemfire.log-file=cacheserver.log --eviction-heap-percentage=75 --critical-heap-percentage=95 --J=-XX:NewSize=189m --J=-XX:MaxNewSize=189m --J=-Xms1897m --J=-Xmx1897m --J=-XX:CMSInitiatingOccupancyFraction=60 --J=-XX:+UseConcMarkSweepGC --J=-XX:+UseCMSInitiatingOccupancyOnly + +... +Server in /Users/boglesby/Dev/Tests/spring-boot/long_running_test/server/server-2 on 192.168.1.4[64428] as server-2 is currently online. +Process ID: 95791 +Uptime: 4 seconds +Geode Version: 9.8.3 +Java Version: 1.8.0_121 +Log File: /Users/boglesby/Dev/Tests/spring-boot/long_running_test/server/server-2/cacheserver.log +JVM Arguments: -Dgemfire.default.locators=192.168.1.4[10334] -Dgemfire.start-dev-rest-api=false -Dgemfire.use-cluster-configuration=true -Dgemfire.statistic-archive-file=cacheserver.gfs -Dgemfire.enable-time-statistics=true -Dgemfire.conserve-sockets=false -Dgemfire.log-file=cacheserver.log -XX:NewSize=189m -XX:MaxNewSize=189m -Xms1897m -Xmx1897m -XX:CMSInitiatingOccupancyFraction=60 -XX:+UseConcMarkSweepGC -XX:+UseCMSInitiatingOccupancyOnly -XX:OnOutOfMemoryError=kill -KILL %p -Dgemfire.launcher.registerSignalHandlers=true -Djava.awt.headless=true -Dsun.rmi.dgc.server.gcInterval=9223372036854775806 +Class-Path: /Users/boglesby/Dev/GemFire/GitBuilds/gemfire983/geode-assembly/build/install/apache-geode/lib/geode-core-9.8.3.jar:/Users/boglesby/Dev/GemFire/GitBuilds/gemfire983/geode-assembly/build/install/apache-geode/lib/geode-dependencies.jar + +6. Executing - start server --name=server-3 --server-port=0 --enable-time-statistics=true --statistic-archive-file=cacheserver.gfs --J=-Dgemfire.conserve-sockets=false --J=-Dgemfire.log-file=cacheserver.log --eviction-heap-percentage=75 --critical-heap-percentage=95 --J=-XX:NewSize=189m --J=-XX:MaxNewSize=189m --J=-Xms1897m --J=-Xmx1897m --J=-XX:CMSInitiatingOccupancyFraction=60 --J=-XX:+UseConcMarkSweepGC --J=-XX:+UseCMSInitiatingOccupancyOnly + +... +Server in /Users/boglesby/Dev/Tests/spring-boot/long_running_test/server/server-3 on 192.168.1.4[64455] as server-3 is currently online. +Process ID: 95799 +Uptime: 4 seconds +Geode Version: 9.8.3 +Java Version: 1.8.0_121 +Log File: /Users/boglesby/Dev/Tests/spring-boot/long_running_test/server/server-3/cacheserver.log +JVM Arguments: -Dgemfire.default.locators=192.168.1.4[10334] -Dgemfire.start-dev-rest-api=false -Dgemfire.use-cluster-configuration=true -Dgemfire.statistic-archive-file=cacheserver.gfs -Dgemfire.enable-time-statistics=true -Dgemfire.conserve-sockets=false -Dgemfire.log-file=cacheserver.log -XX:NewSize=189m -XX:MaxNewSize=189m -Xms1897m -Xmx1897m -XX:CMSInitiatingOccupancyFraction=60 -XX:+UseConcMarkSweepGC -XX:+UseCMSInitiatingOccupancyOnly -XX:OnOutOfMemoryError=kill -KILL %p -Dgemfire.launcher.registerSignalHandlers=true -Djava.awt.headless=true -Dsun.rmi.dgc.server.gcInterval=9223372036854775806 +Class-Path: /Users/boglesby/Dev/GemFire/GitBuilds/gemfire983/geode-assembly/build/install/apache-geode/lib/geode-core-9.8.3.jar:/Users/boglesby/Dev/GemFire/GitBuilds/gemfire983/geode-assembly/build/install/apache-geode/lib/geode-dependencies.jar + +7. Executing - start server --name=server-4 --server-port=0 --enable-time-statistics=true --statistic-archive-file=cacheserver.gfs --J=-Dgemfire.conserve-sockets=false --J=-Dgemfire.log-file=cacheserver.log --eviction-heap-percentage=75 --critical-heap-percentage=95 --J=-XX:NewSize=189m --J=-XX:MaxNewSize=189m --J=-Xms1897m --J=-Xmx1897m --J=-XX:CMSInitiatingOccupancyFraction=60 --J=-XX:+UseConcMarkSweepGC --J=-XX:+UseCMSInitiatingOccupancyOnly + +.... +Server in /Users/boglesby/Dev/Tests/spring-boot/long_running_test/server/server-4 on 192.168.1.4[64486] as server-4 is currently online. +Process ID: 95804 +Uptime: 4 seconds +Geode Version: 9.8.3 +Java Version: 1.8.0_121 +Log File: /Users/boglesby/Dev/Tests/spring-boot/long_running_test/server/server-4/cacheserver.log +JVM Arguments: -Dgemfire.default.locators=192.168.1.4[10334] -Dgemfire.start-dev-rest-api=false -Dgemfire.use-cluster-configuration=true -Dgemfire.statistic-archive-file=cacheserver.gfs -Dgemfire.enable-time-statistics=true -Dgemfire.conserve-sockets=false -Dgemfire.log-file=cacheserver.log -XX:NewSize=189m -XX:MaxNewSize=189m -Xms1897m -Xmx1897m -XX:CMSInitiatingOccupancyFraction=60 -XX:+UseConcMarkSweepGC -XX:+UseCMSInitiatingOccupancyOnly -XX:OnOutOfMemoryError=kill -KILL %p -Dgemfire.launcher.registerSignalHandlers=true -Djava.awt.headless=true -Dsun.rmi.dgc.server.gcInterval=9223372036854775806 +Class-Path: /Users/boglesby/Dev/GemFire/GitBuilds/gemfire983/geode-assembly/build/install/apache-geode/lib/geode-core-9.8.3.jar:/Users/boglesby/Dev/GemFire/GitBuilds/gemfire983/geode-assembly/build/install/apache-geode/lib/geode-dependencies.jar + +8. Executing - list members + + Name | Id +-------- | -------------------------------------------------------------- +locator | 192.168.1.4(locator:95653:locator):41000 [Coordinator] +server-1 | 192.168.1.4(server-1:95772):41001 +server-2 | 192.168.1.4(server-2:95791):41002 +server-3 | 192.168.1.4(server-3:95799):41003 +server-4 | 192.168.1.4(server-4:95804):41004 + +9. Executing - deploy --jar=target/test-0.0.1-SNAPSHOT.jar + + Member | Deployed JAR | Deployed JAR Location +-------- | ----------------------- | -------------------------------------------------------------------------------------------------- +server-1 | test-0.0.1-SNAPSHOT.jar | /Users/boglesby/Dev/Tests/spring-boot/long_running_test/server/server-1/test-0.0.1-SNAPSHOT.v1.jar +server-2 | test-0.0.1-SNAPSHOT.jar | /Users/boglesby/Dev/Tests/spring-boot/long_running_test/server/server-2/test-0.0.1-SNAPSHOT.v1.jar +server-3 | test-0.0.1-SNAPSHOT.jar | /Users/boglesby/Dev/Tests/spring-boot/long_running_test/server/server-3/test-0.0.1-SNAPSHOT.v1.jar +server-4 | test-0.0.1-SNAPSHOT.jar | /Users/boglesby/Dev/Tests/spring-boot/long_running_test/server/server-4/test-0.0.1-SNAPSHOT.v1.jar + +10. Executing - list functions + + Member | Function +-------- | ------------------- +server-1 | GetMetricsFunction +server-1 | UpdateTradeFunction +server-2 | GetMetricsFunction +server-2 | UpdateTradeFunction +server-3 | GetMetricsFunction +server-3 | UpdateTradeFunction +server-4 | GetMetricsFunction +server-4 | UpdateTradeFunction + +11. Executing - create region --name=Trades --type=PARTITION_REDUNDANT + + Member | Status | Message +-------- | ------ | -------------------------------------- +server-1 | OK | Region "/Trades" created on "server-1" +server-2 | OK | Region "/Trades" created on "server-2" +server-3 | OK | Region "/Trades" created on "server-3" +server-4 | OK | Region "/Trades" created on "server-4" + + + + +Changes to configuration for group 'cluster' are persisted. + +12. Executing - list regions + +List of regions +--------------- +Trades + +13. Executing - create index --name=cusip_index --expression=cusip --region=/Trades + + Member | Status | Message +------------------------------------- | ------ | -------------------------- +192.168.1.4(server-1:95772):41001 | OK | Index successfully created +192.168.1.4(server-2:95791):41002 | OK | Index successfully created +192.168.1.4(server-3:95799):41003 | OK | Index successfully created +192.168.1.4(server-4:95804):41004 | OK | Index successfully created + + + + +Changes to configuration for group 'cluster' are persisted. + +14. Executing - list indexes + +Member Name | Member ID | Region Path | Name | Type | Indexed Expression | From Clause | Valid Index +----------- | ------------------------------------- | ----------- | ----------- | ----- | ------------------ | ----------- | ----------- +server-1 | 192.168.1.4(server-1:95772):41001 | /Trades | cusip_index | RANGE | cusip | /Trades | true +server-2 | 192.168.1.4(server-2:95791):41002 | /Trades | cusip_index | RANGE | cusip | /Trades | true +server-3 | 192.168.1.4(server-3:95799):41003 | /Trades | cusip_index | RANGE | cusip | /Trades | true +server-4 | 192.168.1.4(server-4:95804):41004 | /Trades | cusip_index | RANGE | cusip | /Trades | true + +************************* Execution Summary *********************** +Script file: config/startandconfigurelocal.gfsh + + +Command-1 : start locator --name=locator +Status : PASSED + + + + +Command-2 : set variable --name=APP_RESULT_VIEWER --value=any +Status : PASSED + + + + +Command-3 : configure pdx --read-serialized=true +Status : PASSED + + + + +Command-4 : start server --name=server-1 --server-port=0 --enable-time-statistics=true --statistic-archive-file=cacheserver.gfs --J=-Dgemfire.conserve-sockets=false --J=-Dgemfire.log-file=cacheserver.log --eviction-heap-percentage=75 --critical-heap-percentage=95 --J=-XX:NewSize=189m --J=-XX:MaxNewSize=189m --J=-Xms1897m --J=-Xmx1897m --J=-XX:CMSInitiatingOccupancyFraction=60 --J=-XX:+UseConcMarkSweepGC --J=-XX:+UseCMSInitiatingOccupancyOnly +Status : PASSED + + + + +Command-5 : start server --name=server-2 --server-port=0 --enable-time-statistics=true --statistic-archive-file=cacheserver.gfs --J=-Dgemfire.conserve-sockets=false --J=-Dgemfire.log-file=cacheserver.log --eviction-heap-percentage=75 --critical-heap-percentage=95 --J=-XX:NewSize=189m --J=-XX:MaxNewSize=189m --J=-Xms1897m --J=-Xmx1897m --J=-XX:CMSInitiatingOccupancyFraction=60 --J=-XX:+UseConcMarkSweepGC --J=-XX:+UseCMSInitiatingOccupancyOnly +Status : PASSED + + + + +Command-6 : start server --name=server-3 --server-port=0 --enable-time-statistics=true --statistic-archive-file=cacheserver.gfs --J=-Dgemfire.conserve-sockets=false --J=-Dgemfire.log-file=cacheserver.log --eviction-heap-percentage=75 --critical-heap-percentage=95 --J=-XX:NewSize=189m --J=-XX:MaxNewSize=189m --J=-Xms1897m --J=-Xmx1897m --J=-XX:CMSInitiatingOccupancyFraction=60 --J=-XX:+UseConcMarkSweepGC --J=-XX:+UseCMSInitiatingOccupancyOnly +Status : PASSED + + + + +Command-7 : start server --name=server-4 --server-port=0 --enable-time-statistics=true --statistic-archive-file=cacheserver.gfs --J=-Dgemfire.conserve-sockets=false --J=-Dgemfire.log-file=cacheserver.log --eviction-heap-percentage=75 --critical-heap-percentage=95 --J=-XX:NewSize=189m --J=-XX:MaxNewSize=189m --J=-Xms1897m --J=-Xmx1897m --J=-XX:CMSInitiatingOccupancyFraction=60 --J=-XX:+UseConcMarkSweepGC --J=-XX:+UseCMSInitiatingOccupancyOnly +Status : PASSED + + + + +Command-8 : list members +Status : PASSED + + + + +Command-9 : deploy --jar=target/test-0.0.1-SNAPSHOT.jar +Status : PASSED + + + + +Command-10 : list functions +Status : PASSED + + + + +Command-11 : create region --name=Trades --type=PARTITION_REDUNDANT +Status : PASSED + + + + +Command-12 : list regions +Status : PASSED + + + + +Command-13 : create index --name=cusip_index --expression=cusip --region=/Trades +Status : PASSED + + + + +Command-14 : list indexes +Status : PASSED +``` +#### Start Locator and Servers without Configuration +Start the locator and servers without configuration using the **startlocal.sh** script like: + +``` +startlocal.sh +1. Executing - set variable --name=APP_RESULT_VIEWER --value=any + +Value for variable APP_RESULT_VIEWER is now: any. + +2. Executing - start locator --name=locator + +.... +Locator in /Users/boglesby/Dev/Tests/spring-boot/long_running_test/server/locator on 192.168.1.4[10334] as locator is currently online. +Process ID: 97096 +Uptime: 17 seconds +Geode Version: 9.8.3 +Java Version: 1.8.0_121 +Log File: /Users/boglesby/Dev/Tests/spring-boot/long_running_test/server/locator/locator.log +JVM Arguments: -Dgemfire.enable-cluster-configuration=true -Dgemfire.load-cluster-configuration-from-dir=false -Dgemfire.launcher.registerSignalHandlers=true -Djava.awt.headless=true -Dsun.rmi.dgc.server.gcInterval=9223372036854775806 +Class-Path: /Users/boglesby/Dev/GemFire/GitBuilds/gemfire983/geode-assembly/build/install/apache-geode/lib/geode-core-9.8.3.jar:/Users/boglesby/Dev/GemFire/GitBuilds/gemfire983/geode-assembly/build/install/apache-geode/lib/geode-dependencies.jar + +Successfully connected to: JMX Manager [host=192.168.1.4, port=1099] + +Cluster configuration service is up and running. + +3. Executing - start server --name=server-1 --server-port=0 --enable-time-statistics=true --statistic-archive-file=cacheserver.gfs --J=-Dgemfire.conserve-sockets=false --J=-Dgemfire.log-file=cacheserver.log --eviction-heap-percentage=75 --critical-heap-percentage=95 --J=-XX:NewSize=189m --J=-XX:MaxNewSize=189m --J=-Xms1897m --J=-Xmx1897m --J=-XX:CMSInitiatingOccupancyFraction=60 --J=-XX:+UseConcMarkSweepGC --J=-XX:+UseCMSInitiatingOccupancyOnly + +... +Server in /Users/boglesby/Dev/Tests/spring-boot/long_running_test/server/server-1 on 192.168.1.4[64658] as server-1 is currently online. +Process ID: 97126 +Uptime: 4 seconds +Geode Version: 9.8.3 +Java Version: 1.8.0_121 +Log File: /Users/boglesby/Dev/Tests/spring-boot/long_running_test/server/server-1/cacheserver.log +JVM Arguments: -Dgemfire.default.locators=192.168.1.4[10334] -Dgemfire.start-dev-rest-api=false -Dgemfire.use-cluster-configuration=true -Dgemfire.statistic-archive-file=cacheserver.gfs -Dgemfire.enable-time-statistics=true -Dgemfire.conserve-sockets=false -Dgemfire.log-file=cacheserver.log -XX:NewSize=189m -XX:MaxNewSize=189m -Xms1897m -Xmx1897m -XX:CMSInitiatingOccupancyFraction=60 -XX:+UseConcMarkSweepGC -XX:+UseCMSInitiatingOccupancyOnly -XX:OnOutOfMemoryError=kill -KILL %p -Dgemfire.launcher.registerSignalHandlers=true -Djava.awt.headless=true -Dsun.rmi.dgc.server.gcInterval=9223372036854775806 +Class-Path: /Users/boglesby/Dev/GemFire/GitBuilds/gemfire983/geode-assembly/build/install/apache-geode/lib/geode-core-9.8.3.jar:/Users/boglesby/Dev/GemFire/GitBuilds/gemfire983/geode-assembly/build/install/apache-geode/lib/geode-dependencies.jar + +4. Executing - start server --name=server-2 --server-port=0 --enable-time-statistics=true --statistic-archive-file=cacheserver.gfs --J=-Dgemfire.conserve-sockets=false --J=-Dgemfire.log-file=cacheserver.log --eviction-heap-percentage=75 --critical-heap-percentage=95 --J=-XX:NewSize=189m --J=-XX:MaxNewSize=189m --J=-Xms1897m --J=-Xmx1897m --J=-XX:CMSInitiatingOccupancyFraction=60 --J=-XX:+UseConcMarkSweepGC --J=-XX:+UseCMSInitiatingOccupancyOnly + +... +Server in /Users/boglesby/Dev/Tests/spring-boot/long_running_test/server/server-2 on 192.168.1.4[64682] as server-2 is currently online. +Process ID: 97135 +Uptime: 4 seconds +Geode Version: 9.8.3 +Java Version: 1.8.0_121 +Log File: /Users/boglesby/Dev/Tests/spring-boot/long_running_test/server/server-2/cacheserver.log +JVM Arguments: -Dgemfire.default.locators=192.168.1.4[10334] -Dgemfire.start-dev-rest-api=false -Dgemfire.use-cluster-configuration=true -Dgemfire.statistic-archive-file=cacheserver.gfs -Dgemfire.enable-time-statistics=true -Dgemfire.conserve-sockets=false -Dgemfire.log-file=cacheserver.log -XX:NewSize=189m -XX:MaxNewSize=189m -Xms1897m -Xmx1897m -XX:CMSInitiatingOccupancyFraction=60 -XX:+UseConcMarkSweepGC -XX:+UseCMSInitiatingOccupancyOnly -XX:OnOutOfMemoryError=kill -KILL %p -Dgemfire.launcher.registerSignalHandlers=true -Djava.awt.headless=true -Dsun.rmi.dgc.server.gcInterval=9223372036854775806 +Class-Path: /Users/boglesby/Dev/GemFire/GitBuilds/gemfire983/geode-assembly/build/install/apache-geode/lib/geode-core-9.8.3.jar:/Users/boglesby/Dev/GemFire/GitBuilds/gemfire983/geode-assembly/build/install/apache-geode/lib/geode-dependencies.jar + +5. Executing - start server --name=server-3 --server-port=0 --enable-time-statistics=true --statistic-archive-file=cacheserver.gfs --J=-Dgemfire.conserve-sockets=false --J=-Dgemfire.log-file=cacheserver.log --eviction-heap-percentage=75 --critical-heap-percentage=95 --J=-XX:NewSize=189m --J=-XX:MaxNewSize=189m --J=-Xms1897m --J=-Xmx1897m --J=-XX:CMSInitiatingOccupancyFraction=60 --J=-XX:+UseConcMarkSweepGC --J=-XX:+UseCMSInitiatingOccupancyOnly + +... +Server in /Users/boglesby/Dev/Tests/spring-boot/long_running_test/server/server-3 on 192.168.1.4[64711] as server-3 is currently online. +Process ID: 97139 +Uptime: 4 seconds +Geode Version: 9.8.3 +Java Version: 1.8.0_121 +Log File: /Users/boglesby/Dev/Tests/spring-boot/long_running_test/server/server-3/cacheserver.log +JVM Arguments: -Dgemfire.default.locators=192.168.1.4[10334] -Dgemfire.start-dev-rest-api=false -Dgemfire.use-cluster-configuration=true -Dgemfire.statistic-archive-file=cacheserver.gfs -Dgemfire.enable-time-statistics=true -Dgemfire.conserve-sockets=false -Dgemfire.log-file=cacheserver.log -XX:NewSize=189m -XX:MaxNewSize=189m -Xms1897m -Xmx1897m -XX:CMSInitiatingOccupancyFraction=60 -XX:+UseConcMarkSweepGC -XX:+UseCMSInitiatingOccupancyOnly -XX:OnOutOfMemoryError=kill -KILL %p -Dgemfire.launcher.registerSignalHandlers=true -Djava.awt.headless=true -Dsun.rmi.dgc.server.gcInterval=9223372036854775806 +Class-Path: /Users/boglesby/Dev/GemFire/GitBuilds/gemfire983/geode-assembly/build/install/apache-geode/lib/geode-core-9.8.3.jar:/Users/boglesby/Dev/GemFire/GitBuilds/gemfire983/geode-assembly/build/install/apache-geode/lib/geode-dependencies.jar + +6. Executing - start server --name=server-4 --server-port=0 --enable-time-statistics=true --statistic-archive-file=cacheserver.gfs --J=-Dgemfire.conserve-sockets=false --J=-Dgemfire.log-file=cacheserver.log --eviction-heap-percentage=75 --critical-heap-percentage=95 --J=-XX:NewSize=189m --J=-XX:MaxNewSize=189m --J=-Xms1897m --J=-Xmx1897m --J=-XX:CMSInitiatingOccupancyFraction=60 --J=-XX:+UseConcMarkSweepGC --J=-XX:+UseCMSInitiatingOccupancyOnly + +... +Server in /Users/boglesby/Dev/Tests/spring-boot/long_running_test/server/server-4 on 192.168.1.4[64743] as server-4 is currently online. +Process ID: 97149 +Uptime: 4 seconds +Geode Version: 9.8.3 +Java Version: 1.8.0_121 +Log File: /Users/boglesby/Dev/Tests/spring-boot/long_running_test/server/server-4/cacheserver.log +JVM Arguments: -Dgemfire.default.locators=192.168.1.4[10334] -Dgemfire.start-dev-rest-api=false -Dgemfire.use-cluster-configuration=true -Dgemfire.statistic-archive-file=cacheserver.gfs -Dgemfire.enable-time-statistics=true -Dgemfire.conserve-sockets=false -Dgemfire.log-file=cacheserver.log -XX:NewSize=189m -XX:MaxNewSize=189m -Xms1897m -Xmx1897m -XX:CMSInitiatingOccupancyFraction=60 -XX:+UseConcMarkSweepGC -XX:+UseCMSInitiatingOccupancyOnly -XX:OnOutOfMemoryError=kill -KILL %p -Dgemfire.launcher.registerSignalHandlers=true -Djava.awt.headless=true -Dsun.rmi.dgc.server.gcInterval=9223372036854775806 +Class-Path: /Users/boglesby/Dev/GemFire/GitBuilds/gemfire983/geode-assembly/build/install/apache-geode/lib/geode-core-9.8.3.jar:/Users/boglesby/Dev/GemFire/GitBuilds/gemfire983/geode-assembly/build/install/apache-geode/lib/geode-dependencies.jar + +7. Executing - list members + + Name | Id +-------- | -------------------------------------------------------------- +locator | 192.168.1.4(locator:97096:locator):41000 [Coordinator] +server-1 | 192.168.1.4(server-1:97126):41001 +server-2 | 192.168.1.4(server-2:97135):41002 +server-3 | 192.168.1.4(server-3:97139):41003 +server-4 | 192.168.1.4(server-4:97149):41004 + +8. Executing - list functions + + Member | Function +-------- | ------------------- +server-1 | GetMetricsFunction +server-1 | UpdateTradeFunction +server-2 | GetMetricsFunction +server-2 | UpdateTradeFunction +server-3 | GetMetricsFunction +server-3 | UpdateTradeFunction +server-4 | GetMetricsFunction +server-4 | UpdateTradeFunction + +9. Executing - describe region --name=Trades + +Name : Trades +Data Policy : partition +Hosting Members : server-1 + server-4 + server-3 + server-2 + + + + +Non-Default Attributes Shared By Hosting Members + + + Type | Name | Value +--------- | ---------------- | --------- +Region | size | 0 + | data-policy | PARTITION +Partition | redundant-copies | 1 + + + + + +************************* Execution Summary *********************** +Script file: config/startlocal.gfsh + + +Command-1 : set variable --name=APP_RESULT_VIEWER --value=any +Status : PASSED + + + + +Command-2 : start locator --name=locator +Status : PASSED + + + + +Command-3 : start server --name=server-1 --server-port=0 --enable-time-statistics=true --statistic-archive-file=cacheserver.gfs --J=-Dgemfire.conserve-sockets=false --J=-Dgemfire.log-file=cacheserver.log --eviction-heap-percentage=75 --critical-heap-percentage=95 --J=-XX:NewSize=189m --J=-XX:MaxNewSize=189m --J=-Xms1897m --J=-Xmx1897m --J=-XX:CMSInitiatingOccupancyFraction=60 --J=-XX:+UseConcMarkSweepGC --J=-XX:+UseCMSInitiatingOccupancyOnly +Status : PASSED + + + + +Command-4 : start server --name=server-2 --server-port=0 --enable-time-statistics=true --statistic-archive-file=cacheserver.gfs --J=-Dgemfire.conserve-sockets=false --J=-Dgemfire.log-file=cacheserver.log --eviction-heap-percentage=75 --critical-heap-percentage=95 --J=-XX:NewSize=189m --J=-XX:MaxNewSize=189m --J=-Xms1897m --J=-Xmx1897m --J=-XX:CMSInitiatingOccupancyFraction=60 --J=-XX:+UseConcMarkSweepGC --J=-XX:+UseCMSInitiatingOccupancyOnly +Status : PASSED + + + + +Command-5 : start server --name=server-3 --server-port=0 --enable-time-statistics=true --statistic-archive-file=cacheserver.gfs --J=-Dgemfire.conserve-sockets=false --J=-Dgemfire.log-file=cacheserver.log --eviction-heap-percentage=75 --critical-heap-percentage=95 --J=-XX:NewSize=189m --J=-XX:MaxNewSize=189m --J=-Xms1897m --J=-Xmx1897m --J=-XX:CMSInitiatingOccupancyFraction=60 --J=-XX:+UseConcMarkSweepGC --J=-XX:+UseCMSInitiatingOccupancyOnly +Status : PASSED + + + + +Command-6 : start server --name=server-4 --server-port=0 --enable-time-statistics=true --statistic-archive-file=cacheserver.gfs --J=-Dgemfire.conserve-sockets=false --J=-Dgemfire.log-file=cacheserver.log --eviction-heap-percentage=75 --critical-heap-percentage=95 --J=-XX:NewSize=189m --J=-XX:MaxNewSize=189m --J=-Xms1897m --J=-Xmx1897m --J=-XX:CMSInitiatingOccupancyFraction=60 --J=-XX:+UseConcMarkSweepGC --J=-XX:+UseCMSInitiatingOccupancyOnly +Status : PASSED + + + + +Command-7 : list members +Status : PASSED + + + + +Command-8 : list functions +Status : PASSED + + + + +Command-9 : describe region --name=Trades +Status : PASSED +``` +### PCFOne +Configure the servers using the **configurepcc.sh** script like: + +``` +configurepcc.sh +1. Executing - connect --url=https://cloudcache-8a2cc6fd-02e0-4a08-ae66-1a3d9566fa89.run.pcfone.io/gemfire/v1 --user=cluster_operator_DybzOYuxj2V1QWyfav6hQ --password=******** --skip-ssl-validation + +Successfully connected to: GemFire Manager HTTP service @ https://cloudcache-8a2cc6fd-02e0-4a08-ae66-1a3d9566fa89.run.pcfone.io/gemfire/v1 + +2. Executing - set variable --name=APP_RESULT_VIEWER --value=any + +Value for variable APP_RESULT_VIEWER is now: any. + +3. Executing - list members + + Name | Id +------------------------------------------------ | -------------------------------------------------------------------------------------- +locator-672f0674-4972-449f-a9b7-fbbaa25a2e18 | 192.168.13.132(locator-672f0674-4972-449f-a9b7-fbbaa25a2e18:6:locator):56152 +locator-6ca5d36b-b0dc-4cd8-887d-ea611f672d70 | 192.168.14.90(locator-6ca5d36b-b0dc-4cd8-887d-ea611f672d70:6:locator):56152 +locator-79d74e75-201a-4479-a351-7795c4962d16 | 192.168.14.91(locator-79d74e75-201a-4479-a351-7795c4962d16:13:locator):56152 +cacheserver-db26021f-3861-4017-b838-16d9e62939fe | 192.168.14.92(cacheserver-db26021f-3861-4017-b838-16d9e62939fe:6):56152 +cacheserver-8317e6d4-3912-4f7c-92ac-f01146875140 | 192.168.14.93(cacheserver-8317e6d4-3912-4f7c-92ac-f01146875140:6):56152 +cacheserver-c7af346f-d341-48f6-b2c5-021485e29dc5 | 192.168.14.94(cacheserver-c7af346f-d341-48f6-b2c5-021485e29dc5:7):56152 +cacheserver-8693e679-ee85-4ed3-b12c-819e6e81de92 | 192.168.14.95(cacheserver-8693e679-ee85-4ed3-b12c-819e6e81de92:7):56152 + +4. Executing - deploy --jar=target/test-0.0.1-SNAPSHOT.jar + + Member | Deployed JAR | Deployed JAR Location +------------------------------------------------ | ----------------------- | --------------------------------------------------------- +cacheserver-8317e6d4-3912-4f7c-92ac-f01146875140 | test-0.0.1-SNAPSHOT.jar | /var/vcap/store/gemfire-server/test-0.0.1-SNAPSHOT.v1.jar +cacheserver-8693e679-ee85-4ed3-b12c-819e6e81de92 | test-0.0.1-SNAPSHOT.jar | /var/vcap/store/gemfire-server/test-0.0.1-SNAPSHOT.v1.jar +cacheserver-c7af346f-d341-48f6-b2c5-021485e29dc5 | test-0.0.1-SNAPSHOT.jar | /var/vcap/store/gemfire-server/test-0.0.1-SNAPSHOT.v1.jar +cacheserver-db26021f-3861-4017-b838-16d9e62939fe | test-0.0.1-SNAPSHOT.jar | /var/vcap/store/gemfire-server/test-0.0.1-SNAPSHOT.v1.jar + +5. Executing - list functions + + Member | Function +------------------------------------------------ | ------------------- +cacheserver-8317e6d4-3912-4f7c-92ac-f01146875140 | GetMetricsFunction +cacheserver-8317e6d4-3912-4f7c-92ac-f01146875140 | UpdateTradeFunction +cacheserver-8693e679-ee85-4ed3-b12c-819e6e81de92 | GetMetricsFunction +cacheserver-8693e679-ee85-4ed3-b12c-819e6e81de92 | UpdateTradeFunction +cacheserver-c7af346f-d341-48f6-b2c5-021485e29dc5 | GetMetricsFunction +cacheserver-c7af346f-d341-48f6-b2c5-021485e29dc5 | UpdateTradeFunction +cacheserver-db26021f-3861-4017-b838-16d9e62939fe | GetMetricsFunction +cacheserver-db26021f-3861-4017-b838-16d9e62939fe | UpdateTradeFunction + +6. Executing - create region --name=Trades --type=PARTITION_REDUNDANT + + Member | Status | Message +------------------------------------------------ | ------ | ------------------------------------------------------------------------------ +cacheserver-8317e6d4-3912-4f7c-92ac-f01146875140 | OK | Region "/Trades" created on "cacheserver-8317e6d4-3912-4f7c-92ac-f01146875140" +cacheserver-8693e679-ee85-4ed3-b12c-819e6e81de92 | OK | Region "/Trades" created on "cacheserver-8693e679-ee85-4ed3-b12c-819e6e81de92" +cacheserver-c7af346f-d341-48f6-b2c5-021485e29dc5 | OK | Region "/Trades" created on "cacheserver-c7af346f-d341-48f6-b2c5-021485e29dc5" +cacheserver-db26021f-3861-4017-b838-16d9e62939fe | OK | Region "/Trades" created on "cacheserver-db26021f-3861-4017-b838-16d9e62939fe" + + + + +Changes to configuration for group 'cluster' are persisted. + +7. Executing - list regions + +List of regions +--------------- +Trades + +8. Executing - create index --name=cusip_index --expression=cusip --region=/Trades + + Member | Status | Message +----------------------------------------------------------------------------- | ------ | -------------------------- +192.168.14.92(cacheserver-db26021f-3861-4017-b838-16d9e62939fe:6):56152 | OK | Index successfully created +192.168.14.93(cacheserver-8317e6d4-3912-4f7c-92ac-f01146875140:6):56152 | OK | Index successfully created +192.168.14.94(cacheserver-c7af346f-d341-48f6-b2c5-021485e29dc5:7):56152 | OK | Index successfully created +192.168.14.95(cacheserver-8693e679-ee85-4ed3-b12c-819e6e81de92:7):56152 | OK | Index successfully created + + + + +Changes to configuration for group 'cluster' are persisted. + +9. Executing - list indexes + + Member Name | Member ID | Region Path | Name | Type | Indexed Expression | From Clause | Valid Index +------------------------------------------------ | ----------------------------------------------------------------------------- | ----------- | ----------- | ----- | ------------------ | ----------- | ----------- +cacheserver-8317e6d4-3912-4f7c-92ac-f01146875140 | 192.168.14.93(cacheserver-8317e6d4-3912-4f7c-92ac-f01146875140:6):56152 | /Trades | cusip_index | RANGE | cusip | /Trades | true +cacheserver-8693e679-ee85-4ed3-b12c-819e6e81de92 | 192.168.14.95(cacheserver-8693e679-ee85-4ed3-b12c-819e6e81de92:7):56152 | /Trades | cusip_index | RANGE | cusip | /Trades | true +cacheserver-c7af346f-d341-48f6-b2c5-021485e29dc5 | 192.168.14.94(cacheserver-c7af346f-d341-48f6-b2c5-021485e29dc5:7):56152 | /Trades | cusip_index | RANGE | cusip | /Trades | true +cacheserver-db26021f-3861-4017-b838-16d9e62939fe | 192.168.14.92(cacheserver-db26021f-3861-4017-b838-16d9e62939fe:6):56152 | /Trades | cusip_index | RANGE | cusip | /Trades | true + +************************* Execution Summary *********************** +Script file: config/configurepcc.gfsh + + +Command-1 : connect --url=https://cloudcache-8a2cc6fd-02e0-4a08-ae66-1a3d9566fa89.run.pcfone.io/gemfire/v1 --user=cluster_operator_DybzOYuxj2V1QWyfav6hQ --password=tSsw94Rg4IA7vtLyK1Ow --skip-ssl-validation +Status : PASSED + + + + +Command-2 : set variable --name=APP_RESULT_VIEWER --value=any +Status : PASSED + + + + +Command-3 : list members +Status : PASSED + + + + +Command-4 : deploy --jar=target/test-0.0.1-SNAPSHOT.jar +Status : PASSED + + + + +Command-5 : list functions +Status : PASSED + + + + +Command-6 : create region --name=Trades --type=PARTITION_REDUNDANT +Status : PASSED + + + + +Command-7 : list regions +Status : PASSED + + + + +Command-8 : create index --name=cusip_index --expression=cusip --region=/Trades +Status : PASSED + + + + +Command-9 : list indexes +Status : PASSED +``` +## Cleanup +### Local +Cleanup the servers using the **cleanuplocal.sh** script like: + +``` +./cleanuplocal.sh +1. Executing - connect + +Connecting to Locator at [host=localhost, port=10334] .. +Connecting to Manager at [host=192.168.1.4, port=1099] .. +Successfully connected to: [host=192.168.1.4, port=1099] + +2. Executing - set variable --name=APP_RESULT_VIEWER --value=any + +Value for variable APP_RESULT_VIEWER is now: any. + +3. Executing - undeploy + + Member | Un-Deployed JAR | Un-Deployed From JAR Location +-------- | ----------------------- | -------------------------------------------------------------------------------------------------- +server-1 | test-0.0.1-SNAPSHOT.jar | /Users/boglesby/Dev/Tests/spring-boot/long_running_test/server/server-1/test-0.0.1-SNAPSHOT.v2.jar +server-2 | test-0.0.1-SNAPSHOT.jar | /Users/boglesby/Dev/Tests/spring-boot/long_running_test/server/server-2/test-0.0.1-SNAPSHOT.v2.jar + +4. Executing - list functions + +No Functions Found + +5. Executing - destroy region --name=Trades + + Member | Status | Message +-------- | ------ | --------------------------------------- +server-1 | OK | Region '/Trades' destroyed successfully +server-2 | OK | Region '/Trades' destroyed successfully + +6. Executing - list regions + +No Regions Found + +************************* Execution Summary *********************** +Script file: cleanuplocal.gfsh + + +Command-1 : connect +Status : PASSED + + + + +Command-2 : set variable --name=APP_RESULT_VIEWER --value=any +Status : PASSED + + + + +Command-3 : undeploy +Status : PASSED + + + + +Command-4 : list functions +Status : PASSED + + + + +Command-5 : destroy region --name=Trades +Status : PASSED + + + + +Command-6 : list regions +Status : PASSED +``` +### PCFOne +Cleanup the servers using the **cleanuppcc.sh** script like: + +``` +./cleanuppcc.sh +1. Executing - connect --url=https://cloudcache-8a2cc6fd-02e0-4a08-ae66-1a3d9566fa89.run.pcfone.io/gemfire/v1 --user=cluster_operator_DybzOYuxj2V1QWyfav6hQ --password=******** --skip-ssl-validation + +Successfully connected to: GemFire Manager HTTP service @ https://cloudcache-8a2cc6fd-02e0-4a08-ae66-1a3d9566fa89.run.pcfone.io/gemfire/v1 + +2. Executing - set variable --name=APP_RESULT_VIEWER --value=any + +Value for variable APP_RESULT_VIEWER is now: any. + +3. Executing - undeploy + + Member | Un-Deployed JAR | Un-Deployed From JAR Location +------------------------------------------------ | ----------------------- | --------------------------------------------------------- +cacheserver-8317e6d4-3912-4f7c-92ac-f01146875140 | test-0.0.1-SNAPSHOT.jar | /var/vcap/store/gemfire-server/test-0.0.1-SNAPSHOT.v1.jar +cacheserver-8693e679-ee85-4ed3-b12c-819e6e81de92 | test-0.0.1-SNAPSHOT.jar | /var/vcap/store/gemfire-server/test-0.0.1-SNAPSHOT.v1.jar +cacheserver-c7af346f-d341-48f6-b2c5-021485e29dc5 | test-0.0.1-SNAPSHOT.jar | /var/vcap/store/gemfire-server/test-0.0.1-SNAPSHOT.v1.jar +cacheserver-db26021f-3861-4017-b838-16d9e62939fe | test-0.0.1-SNAPSHOT.jar | /var/vcap/store/gemfire-server/test-0.0.1-SNAPSHOT.v1.jar + +4. Executing - list functions + +No Functions Found + +5. Executing - destroy region --name=Trades + + Member | Status | Message +------------------------------------------------ | ------ | --------------------------------------- +cacheserver-8317e6d4-3912-4f7c-92ac-f01146875140 | OK | Region '/Trades' destroyed successfully +cacheserver-8693e679-ee85-4ed3-b12c-819e6e81de92 | OK | Region '/Trades' destroyed successfully +cacheserver-c7af346f-d341-48f6-b2c5-021485e29dc5 | OK | Region '/Trades' destroyed successfully +cacheserver-db26021f-3861-4017-b838-16d9e62939fe | OK | Region '/Trades' destroyed successfully + +6. Executing - list regions + +No Regions Found + +************************* Execution Summary *********************** +Script file: cleanuppcc.gfsh + + +Command-1 : connect --url=https://cloudcache-8a2cc6fd-02e0-4a08-ae66-1a3d9566fa89.run.pcfone.io/gemfire/v1 --user=cluster_operator_DybzOYuxj2V1QWyfav6hQ --password=tSsw94Rg4IA7vtLyK1Ow --skip-ssl-validation +Status : PASSED + + + + +Command-2 : set variable --name=APP_RESULT_VIEWER --value=any +Status : PASSED + + + + +Command-3 : undeploy +Status : PASSED + + + + +Command-4 : list functions +Status : PASSED + + + + +Command-5 : destroy region --name=Trades +Status : PASSED + + + + +Command-6 : list regions +Status : PASSED +``` +## Shutdown +### Local +Shutdown the servers and locator using the **shutdownlocal.sh** script like: + +``` +./shutdownlocal.sh + +(1) Executing - connect + +Connecting to Locator at [host=localhost, port=10334] .. +Connecting to Manager at [host=192.168.1.4, port=1099] .. +Successfully connected to: [host=192.168.1.4, port=1099] + + +(2) Executing - shutdown --include-locators=true + +Shutdown is triggered +``` \ No newline at end of file diff --git a/server/bin/cleanup.sh b/server/bin/cleanup.sh new file mode 100755 index 0000000..9971b3a --- /dev/null +++ b/server/bin/cleanup.sh @@ -0,0 +1,8 @@ +gfsh \ +-e "connect --url=$URL --user=$USERNAME --password=$PASSWORD --skip-ssl-validation" \ +-e "set variable --name=APP_RESULT_VIEWER --value=any" \ +-e "undeploy" \ +-e "destroy region --name=Trades" \ +-e "list functions" \ +-e "list regions" \ +-e "list indexes" diff --git a/server/bin/configure.sh b/server/bin/configure.sh new file mode 100755 index 0000000..9a3175d --- /dev/null +++ b/server/bin/configure.sh @@ -0,0 +1,10 @@ +gfsh \ +-e "connect --url=$URL --user=$USERNAME --password=$PASSWORD --skip-ssl-validation" \ +-e "set variable --name=APP_RESULT_VIEWER --value=any" \ +-e "list members" \ +-e "deploy --jar=build/libs/server-0.0.1-SNAPSHOT.jar" \ +-e "list functions" \ +-e "create region --name=Trades --type=PARTITION_REDUNDANT" \ +-e "list regions" \ +-e "create index --name=cusip_index --expression=cusip --region=/Trades" \ +-e "list indexes" diff --git a/server/bin/deployfunctions.sh b/server/bin/deployfunctions.sh new file mode 100755 index 0000000..ec3c1d4 --- /dev/null +++ b/server/bin/deployfunctions.sh @@ -0,0 +1,5 @@ +gfsh \ +-e "connect --url=$URL --user=$USERNAME --password=$PASSWORD --skip-ssl-validation" \ +-e "set variable --name=APP_RESULT_VIEWER --value=any" \ +-e "deploy --jar=build/libs/server-0.0.1-SNAPSHOT.jar" \ +-e "list functions" diff --git a/server/bin/exportlogs.sh b/server/bin/exportlogs.sh new file mode 100755 index 0000000..8fdb7af --- /dev/null +++ b/server/bin/exportlogs.sh @@ -0,0 +1,4 @@ +gfsh \ +-e "connect --url=$URL --user=$USERNAME --password=$PASSWORD --skip-ssl-validation" \ +-e "set variable --name=APP_RESULT_VIEWER --value=any" \ +-e "export logs --file-size-limit=0" \ No newline at end of file diff --git a/server/src/main/java/io/pivotal/test/server/function/GetMetricsFunction.java b/server/src/main/java/io/pivotal/test/server/function/GetMetricsFunction.java new file mode 100644 index 0000000..a603103 --- /dev/null +++ b/server/src/main/java/io/pivotal/test/server/function/GetMetricsFunction.java @@ -0,0 +1,30 @@ +package io.pivotal.test.server.function; + +import io.pivotal.test.server.metrics.MetricsHelper; +import org.apache.geode.cache.execute.Function; +import org.apache.geode.cache.execute.FunctionContext; + +import java.util.Map; +import java.util.TreeMap; + +public class GetMetricsFunction implements Function { + + @Override + public void execute(FunctionContext context) { + Map allMetrics = new TreeMap(); + MetricsHelper.addOSMetrics(allMetrics); + MetricsHelper.addGCMetrics(allMetrics); + MetricsHelper.addMemoryMetrics(allMetrics); + context.getResultSender().lastResult(allMetrics); + } + + @Override + public String getId() { + return getClass().getSimpleName(); + } + + @Override + public boolean optimizeForWrite() { + return true; + } +} diff --git a/server/src/main/java/io/pivotal/test/server/function/UpdateTradeFunction.java b/server/src/main/java/io/pivotal/test/server/function/UpdateTradeFunction.java new file mode 100644 index 0000000..a4413d5 --- /dev/null +++ b/server/src/main/java/io/pivotal/test/server/function/UpdateTradeFunction.java @@ -0,0 +1,39 @@ +package io.pivotal.test.server.function; + +import org.apache.geode.cache.execute.Function; +import org.apache.geode.cache.execute.FunctionContext; +import org.apache.geode.cache.execute.RegionFunctionContext; +import org.apache.geode.pdx.PdxInstance; +import org.apache.geode.pdx.WritablePdxInstance; + +import java.math.BigDecimal; + +public class UpdateTradeFunction implements Function { + + @Override + public void execute(FunctionContext context) { + RegionFunctionContext rfc = (RegionFunctionContext) context; + Object key = rfc.getFilter().iterator().next(); + Object[] arguments = (Object[]) context.getArguments(); + int shares = (Integer) arguments[0]; + BigDecimal price = (BigDecimal) arguments[1]; + PdxInstance tradePdx = (PdxInstance) rfc.getDataSet().get(key); + if (tradePdx != null) { + WritablePdxInstance tradeWritablePdx = tradePdx.createWriter(); + tradeWritablePdx.setField("shares", shares); + tradeWritablePdx.setField("price", price); + rfc.getDataSet().put(key, tradeWritablePdx); + } + context.getResultSender().lastResult(true); + } + + @Override + public String getId() { + return getClass().getSimpleName(); + } + + @Override + public boolean optimizeForWrite() { + return true; + } +} diff --git a/server/src/main/java/io/pivotal/test/server/metrics/MetricsHelper.java b/server/src/main/java/io/pivotal/test/server/metrics/MetricsHelper.java new file mode 100644 index 0000000..47e244d --- /dev/null +++ b/server/src/main/java/io/pivotal/test/server/metrics/MetricsHelper.java @@ -0,0 +1,85 @@ +package io.pivotal.test.server.metrics; + +import org.apache.geode.StatisticDescriptor; +import org.apache.geode.Statistics; +import org.apache.geode.StatisticsType; +import org.apache.geode.cache.Cache; +import org.apache.geode.cache.CacheFactory; +import org.apache.geode.distributed.internal.InternalDistributedSystem; +import org.apache.geode.internal.statistics.platform.LinuxSystemStats; +import org.apache.geode.management.ManagementService; +import org.apache.geode.management.OSMetrics; +import org.apache.geode.management.internal.beans.MemberMBean; + +import java.lang.management.GarbageCollectorMXBean; +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryPoolMXBean; +import java.lang.management.MemoryUsage; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +public class MetricsHelper { + + public static void addOSMetrics(Map allMetrics) { + Cache cache = CacheFactory.getAnyInstance(); + InternalDistributedSystem system = (InternalDistributedSystem) cache.getDistributedSystem(); + + Map osMetrics = new TreeMap(); + allMetrics.put("os", osMetrics); + ManagementService managementService = ManagementService.getManagementService(cache); + MemberMBean bean = (MemberMBean) managementService.getMemberMXBean(); + OSMetrics osm = bean.showOSMetrics(); + osMetrics.put("fdsOpen", osm.getOpenFileDescriptorCount()); + osMetrics.put("fdLimit", osm.getMaxFileDescriptorCount()); + osMetrics.put("processCpuTime", osm.getProcessCpuTime()); + osMetrics.put("name", osm.getName()); + osMetrics.put("version", osm.getVersion()); + osMetrics.put("architecture", osm.getArch()); + + // If the linux system statistics exist, add them to the os metrics map. + // Otherwise add the available stats from the osmetrics. + Statistics[] systemStatisticsArr = system.findStatisticsByType(LinuxSystemStats.getType()); + if (systemStatisticsArr.length > 0) { + Statistics systemStatistics = systemStatisticsArr[0]; + StatisticsType type = systemStatistics.getType(); + for (StatisticDescriptor descriptor : type.getStatistics()) { + String statName = descriptor.getName(); + Number statValue = systemStatistics.get(statName); + osMetrics.put(statName, statValue); + } + } else { + osMetrics.put("totalMemory", osm.getTotalPhysicalMemorySize()); + osMetrics.put("freeMemory", osm.getFreePhysicalMemorySize()); + osMetrics.put("cpus", osm.getAvailableProcessors()); + osMetrics.put("loadAverage1", osm.getSystemLoadAverage()); + osMetrics.put("allocatedSwap", osm.getTotalSwapSpaceSize()); + osMetrics.put("freeSwap", osm.getFreeSwapSpaceSize()); + } + } + + public static void addGCMetrics(Map allMetrics) { + Map gcMetrics = new TreeMap(); + allMetrics.put("gc", gcMetrics); + List gcBeans = ManagementFactory.getGarbageCollectorMXBeans(); + for (GarbageCollectorMXBean gcBean : gcBeans) { + gcMetrics.put(gcBean.getName() + "_collections", gcBean.getCollectionCount()); + gcMetrics.put(gcBean.getName() + "_collectionTime", gcBean.getCollectionTime()); + } + } + + public static void addMemoryMetrics(Map allMetrics) { + Map memoryMetrics = new TreeMap(); + allMetrics.put("memory", memoryMetrics); + List memoryBeans = ManagementFactory.getMemoryPoolMXBeans(); + for (MemoryPoolMXBean memoryBean : memoryBeans) { + if (memoryBean.getName().contains("Old") || memoryBean.getName().contains("Eden")) { + String memoryBeanName = memoryBean.getName().replaceAll(" ", "_"); + MemoryUsage usage = memoryBean.getUsage(); + memoryMetrics.put(memoryBeanName + "_init", usage.getInit()); + memoryMetrics.put(memoryBeanName + "_used", usage.getUsed()); + memoryMetrics.put(memoryBeanName + "_max", usage.getMax()); + } + } + } +} diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..efdcae2 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'pcc-long-running-test' +include 'client','client-cq','server' \ No newline at end of file