diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index d1d1ebd1..00000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,58 +0,0 @@ -name: Codeanalyzer CI - -on: - push: - branches: - - 1.X.X - -permissions: - contents: write - -jobs: - build-and-package: - runs-on: ubuntu-latest - - env: - JAVA_HOME: ${{ github.workspace }}/graalvm-ce-java11-22.3.3 - - steps: - - name: Check out code - uses: actions/checkout@v4 - with: - persist-credentials: true - - - name: Set up JDK 11 from GraalVM - run: | - echo "${{ env.JAVA_HOME }}/bin" >> $GITHUB_PATH - wget https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-22.3.3/graalvm-ce-java11-linux-amd64-22.3.3.tar.gz - tar -xvzf graalvm-ce-java11-linux-amd64-22.3.3.tar.gz - ${{ env.JAVA_HOME }}/bin/gu install native-image - - - name: Make gradlew executable - run: chmod +x ./gradlew - - - name: Build with Gradle - run: ./gradlew clean fatJar - - - name: Determine new tag - id: newtag - run: | - VERSION=$(java -jar build/libs/*.jar --version | awk '{print $1}') - TAG="v$VERSION" - echo "tag=$TAG" >> $GITHUB_OUTPUT - - - name: Create Git Tag - run: | - git config --global user.name 'GitHub Actions' - git config --global user.email 'actions@github.com' - git tag ${{ steps.newtag.outputs.tag }} - git push origin ${{ steps.newtag.outputs.tag }} - - - name: Publish Release - uses: softprops/action-gh-release@v1 - with: - files: build/libs/*.jar - tag_name: ${{ steps.newtag.outputs.tag }} - prerelease: true - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..0fafd29c --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,59 @@ +name: Java Release + +on: + push: + tags: + - "v1.*.*" + +permissions: + contents: write + +jobs: + release: + runs-on: ubuntu-latest + + env: + JAVA_HOME: ${{ github.workspace }}/graalvm-ce-java11-22.3.3 + + steps: + - name: Check out code + uses: actions/checkout@v4 + + - name: Set up JDK 11 from GraalVM + run: | + echo "${{ env.JAVA_HOME }}/bin" >> $GITHUB_PATH + wget https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-22.3.3/graalvm-ce-java11-linux-amd64-22.3.3.tar.gz + tar -xvzf graalvm-ce-java11-linux-amd64-22.3.3.tar.gz + ${{ env.JAVA_HOME }}/bin/gu install native-image + + - name: Make gradlew executable + run: chmod +x ./gradlew + + - name: Build and Test + id: build + continue-on-error: true # Allow the workflow to continue if this fails + run: ./gradlew clean fatJar + + - name: Delete tag on failure + if: steps.build.outcome != 'success' + run: | + git push --delete origin ${GITHUB_REF#refs/tags/} + exit 1 # Fail the workflow + + - name: Build Changelog + id: gen_changelog + uses: mikepenz/release-changelog-builder-action@v5 + with: + failOnError: "true" + configuration: .github/workflows/release_config.json + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Publish Release + uses: softprops/action-gh-release@v1 + with: + files: build/libs/*.jar + body: ${{ steps.gen_changelog.outputs.changelog }} + prerelease: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/release_config.json b/.github/workflows/release_config.json new file mode 100644 index 00000000..7ddd165c --- /dev/null +++ b/.github/workflows/release_config.json @@ -0,0 +1,35 @@ +{ + "categories": [ + { + "title": "## 🚀 Features", + "labels": ["kind/feature", "enhancement"] + }, + { + "title": "## 🐛 Fixes", + "labels": ["fix", "bug"] + }, + { + "title": "## ♻️ Refactoring", + "labels": ["refactoring"] + }, + { + "title": "## ⚡️ Performance Improvements", + "labels": ["performance"] + }, + { + "title": "## \uD83D\uDCDA Documentation", + "labels": ["documentation", "doc"] + }, + { + "title": "## \uD83D\uDEA6 Tests", + "labels": ["test"] + }, + { + "title": "## \uD83D\uDEE0 Other Updates", + "labels": ["other", "kind/dependency-change"] + } + ], + "ignore_labels": [ + "ignore" + ] +} \ No newline at end of file diff --git a/src/main/java/com/ibm/cldk/utils/BuildProject.java b/src/main/java/com/ibm/cldk/utils/BuildProject.java index 87ae62e5..01ea2bee 100644 --- a/src/main/java/com/ibm/cldk/utils/BuildProject.java +++ b/src/main/java/com/ibm/cldk/utils/BuildProject.java @@ -46,7 +46,7 @@ public static String getGradleCommand() { String gradleSystemCommand = Arrays.stream(System.getenv("PATH").split(System.getProperty("path.separator"))).map(path -> new File(path, System.getProperty("os.name").toLowerCase().contains("windows") ? "gradle.bat" : "gradle")).filter(File::exists).findFirst().map(File::getAbsolutePath).orElse(null); File gradleWrapper = System.getProperty("os.name").toLowerCase().contains("windows") ? new File(projectRootPom, "gradlew.bat") : new File(projectRootPom, "gradlew"); - return commandExists(gradleWrapper.getAbsoluteFile()).getKey() ? gradleWrapper.getAbsoluteFile().toString() : gradleSystemCommand; + return commandExists(gradleWrapper.getAbsoluteFile()).getKey() ? gradleWrapper.getAbsoluteFile() .toString() : gradleSystemCommand; } public static Path tempInitScript; @@ -159,13 +159,13 @@ public static boolean gradleBuild(String projectPath) { } private static boolean buildProject(String projectPath, String build) { - File pomFile = new File(projectPath, "pom.xml"); + File pomFile = new File(String.valueOf(Paths.get(projectPath).toAbsolutePath()), "pom.xml"); if (build == null) { return true; } else if (build.equals("auto")) { if (pomFile.exists()) { Log.info("Found pom.xml in the project directory. Using Maven to build the project."); - return mavenBuild(projectPath); // Use Maven if pom.xml exists + return mavenBuild(Paths.get(projectPath).toAbsolutePath().toString()); // Use Maven if pom.xml exists } else { Log.info("Did not find a pom.xml in the project directory. Using Gradle to build the project."); return gradleBuild(projectPath); // Otherwise, use Gradle @@ -204,14 +204,14 @@ private static boolean mkLibDepDirs(String projectPath) { * Downloads library dependency jars of the given project so that the jars can be used * for type resolution during symbol table creation. * - * @param projectPath Path to the project under analysis + * @param projectPath Path to the project under javaee * @return true if dependency download succeeds; false otherwise */ public static boolean downloadLibraryDependencies(String projectPath, String projectRootPom) throws IOException { // created download dir if it does not exist String projectRoot = projectRootPom != null ? projectRootPom : projectPath; - File pomFile = new File(projectRoot, "pom.xml"); + File pomFile = new File((new File(projectRoot)).getAbsoluteFile(), "pom.xml"); if (pomFile.exists()) { libDownloadPath = Paths.get(projectPath, "target", LIB_DEPS_DOWNLOAD_DIR).toAbsolutePath(); if (mkLibDepDirs(projectPath)) @@ -231,21 +231,21 @@ public static boolean downloadLibraryDependencies(String projectPath, String pro )); } Log.info("Found pom.xml in the project directory. Using Maven to download dependencies."); - String[] mavenCommand = {MAVEN_CMD, "--no-transfer-progress", "-f", Paths.get(projectRoot, "pom.xml").toString(), "dependency:copy-dependencies", "-DoutputDirectory=" + libDownloadPath.toString()}; + String[] mavenCommand = {MAVEN_CMD, "--no-transfer-progress", "-f", Paths.get(projectRoot, "pom.xml").toAbsolutePath().toString(), "dependency:copy-dependencies", "-DoutputDirectory=" + libDownloadPath.toString()}; return buildWithTool(mavenCommand); } else if (new File(projectRoot, "build.gradle").exists() || new File(projectRoot, "build.gradle.kts").exists()) { - if (GRADLE_CMD == null || !commandExists(new File(GRADLE_CMD)).getKey()) { - libDownloadPath = Paths.get(projectPath, "build", LIB_DEPS_DOWNLOAD_DIR).toAbsolutePath(); - if (mkLibDepDirs(projectPath)) - Log.debug("Dependencies found/created in " + libDownloadPath); - else - throw new IllegalStateException("Error creating library dependency directory in " + libDownloadPath); + libDownloadPath = Paths.get(projectPath, "build", LIB_DEPS_DOWNLOAD_DIR).toAbsolutePath(); + if (mkLibDepDirs(projectPath)) + Log.debug("Dependencies found/created in " + libDownloadPath); + else + throw new IllegalStateException("Error creating library dependency directory in " + libDownloadPath); + if (GRADLE_CMD == null || !commandExists(new File(GRADLE_CMD)).getKey()) { String msg = GRADLE_CMD == null ? "Could not find Gradle or valid Gradle Wrapper" : MessageFormat.format("Could not verify that {0} exists", GRADLE_CMD); Log.error(msg); - throw new IllegalStateException("Unable to execute Maven command. " + + throw new IllegalStateException("Unable to execute Gradle command. " + (GRADLE_CMD == null ? "Could not find Gradle or valid Gradle Wrapper" : "Attempt failed with message\n" + commandExists(new File(GRADLE_CMD)).getValue() @@ -271,8 +271,10 @@ public static void cleanLibraryDependencies() { if (libDownloadPath != null) { Log.info("Cleaning up library dependency directory: " + libDownloadPath); try { - Files.walk(libDownloadPath).filter(Files::isRegularFile).map(Path::toFile).forEach(File::delete); - Files.delete(libDownloadPath); + if (libDownloadPath.toFile().getAbsoluteFile().exists()) { + Files.walk(libDownloadPath).filter(Files::isRegularFile).map(Path::toFile).forEach(File::delete); + Files.delete(libDownloadPath); + } } catch (IOException e) { Log.warn("Unable to fully delete library dependency directory: " + e.getMessage()); } @@ -285,4 +287,4 @@ public static void cleanLibraryDependencies() { } } } -} +} \ No newline at end of file diff --git a/src/main/java/com/ibm/cldk/utils/ProjectDirectoryScanner.java b/src/main/java/com/ibm/cldk/utils/ProjectDirectoryScanner.java index fb138dca..00eae40e 100644 --- a/src/main/java/com/ibm/cldk/utils/ProjectDirectoryScanner.java +++ b/src/main/java/com/ibm/cldk/utils/ProjectDirectoryScanner.java @@ -7,19 +7,20 @@ import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; public class ProjectDirectoryScanner { public static List classFilesStream(String projectPath) throws IOException { - Path projectDir = Paths.get(projectPath); + Path projectDir = Paths.get(projectPath).toAbsolutePath(); Log.info("Finding *.class files in " + projectDir); if (Files.exists(projectDir)) { try (Stream paths = Files.walk(projectDir)) { - return paths - .filter(file -> !Files.isDirectory(file) && file.toString().endsWith(".class")) - .filter(file -> !file.toAbsolutePath().toString().contains("test/resources/")) - .filter(file -> !file.toAbsolutePath().toString().contains("main/resources/")) + return paths.filter(file -> !Files.isDirectory(file) && file.toString().endsWith(".class")) + .filter(file -> { + // Let's find the path relative to the project directory + Path relativePath = projectDir.relativize(file.toAbsolutePath()); + String relativePathAsString = relativePath.toString().replace("\\", "/"); // Windows fix + return !relativePathAsString.contains("test/resources/") && !relativePathAsString.contains("main/resources/"); + }) .collect(Collectors.toList()); } } @@ -39,46 +40,22 @@ public static List jarFilesStream(String projectPath) throws IOException { return null; } - /** - * Returns a stream of class files inside the jars and class files in the project. - * @param projectPath - * @return - * @throws IOException - */ - public static Stream classesFromJarFileStream(String projectPath) throws IOException { - List jarPaths = jarFilesStream(projectPath); - - if (jarPaths == null) { - return Stream.empty(); - } - - return jarPaths.stream().flatMap(jarPath -> { - try (ZipFile zip = new ZipFile(jarPath.toFile())) { - return zip.stream() - .filter(entry -> !entry.isDirectory() && entry.getName().endsWith(".class")) - .map(ZipEntry::getName); - } catch (IOException e) { - return Stream.empty(); - } - }); - } - public static List sourceFilesStream(String projectPath) throws IOException { Path projectDir = Paths.get(projectPath); Log.info("Finding *.java files in " + projectDir); if (Files.exists(projectDir)) { try (Stream paths = Files.walk(projectDir)) { return paths - .filter(file -> !Files.isDirectory(file)) - .filter(file -> file.toString().endsWith(".java")) - .filter(file -> !file.toAbsolutePath().toString().contains("build/")) - .filter(file -> !file.toAbsolutePath().toString().contains("target/")) - .filter(file -> !file.toAbsolutePath().toString().contains("main/resources/")) - .filter(file -> !file.toAbsolutePath().toString().contains("test/resources/")) - .collect(Collectors.toList()); + .filter(file -> !Files.isDirectory(file)) + .filter(file -> file.toString().endsWith(".java")) + .filter(file -> !file.toAbsolutePath().toString().contains("build/")) + .filter(file -> !file.toAbsolutePath().toString().contains("target/")) + .filter(file -> !file.toAbsolutePath().toString().contains("main/resources/")) + .filter(file -> !file.toAbsolutePath().toString().contains("test/resources/")) + .collect(Collectors.toList()); } } return null; } -} +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/Dockerfile b/src/test/resources/test-applications/daytrader8/Dockerfile new file mode 100644 index 00000000..bce5ad82 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/Dockerfile @@ -0,0 +1,14 @@ +FROM open-liberty:full + +COPY --chown=1001:0 src/main/liberty/config/server.xml /config/server.xml +COPY --chown=1001:0 src/main/liberty/config/bootstrap.properties /config/bootstrap.properties +COPY --chown=1001:0 target/io.openliberty.sample.daytrader8.war /config/apps/ + +#Derby +COPY --chown=1001:0 target/liberty/wlp/usr/shared/resources/DerbyLibs/derby-10.14.2.0.jar /opt/ol/wlp/usr/shared/resources/DerbyLibs/derby-10.14.2.0.jar +COPY --chown=1001:0 target/liberty/wlp/usr/shared/resources/data /opt/ol/wlp/usr/shared/resources/data + +ENV MAX_USERS=1000 +ENV MAX_QUOTES=500 + +#RUN configure.sh diff --git a/src/test/resources/test-applications/daytrader8/Dockerfile-db2 b/src/test/resources/test-applications/daytrader8/Dockerfile-db2 new file mode 100644 index 00000000..c32a54e8 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/Dockerfile-db2 @@ -0,0 +1,21 @@ +# Create folder db2jars/ and copy db2jcc4.jar and db2jcc_license_cu.jar to it. +# Set Env below + +FROM open-liberty:full + +COPY --chown=1001:0 src/main/liberty/config/server.xml_db2 /config/server.xml +COPY --chown=1001:0 src/main/liberty/config/bootstrap.properties /config/bootstrap.properties +COPY --chown=1001:0 target/io.openliberty.sample.daytrader8.war /config/apps/ + +# DB2 JARS +COPY --chown=1001:0 /db2jars /opt/ol/wlp/usr/shared/resources/db2jars + +ENV contextRoot=daytrader +ENV dbUser= +ENV dbPass= +ENV tradeDbHost= +ENV tradeDbPort= +ENV tradeDbName= + + +#RUN configure.sh diff --git a/src/test/resources/test-applications/daytrader8/LICENSE b/src/test/resources/test-applications/daytrader8/LICENSE new file mode 100644 index 00000000..8f71f43f --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/LICENSE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + 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 + + http://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. + diff --git a/src/test/resources/test-applications/daytrader8/README.md b/src/test/resources/test-applications/daytrader8/README.md new file mode 100644 index 00000000..595a96da --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/README.md @@ -0,0 +1,45 @@ +# Java EE8: DayTrader8 Sample + +This sample contains the DayTrader 8 benchmark, which is an application built around the paradigm of an online stock trading system. The application allows users to login, view their portfolio, lookup stock quotes, and buy or sell stock shares. With the aid of a Web-based load driver such as Apache JMeter, the real-world workload provided by DayTrader can be used to measure and compare the performance of Java Platform, Enterprise Edition (Java EE) application servers offered by a variety of vendors. In addition to the full workload, the application also contains a set of primitives used for functional and performance testing of various Java EE components and common design patterns. + +DayTrader is an end-to-end benchmark and performance sample application. It provides a real world Java EE workload. DayTrader's new design spans Java EE 8. + +This sample can be installed onto Liberty runtime versions 18.0.0.2 and later. A prebuilt derby database is provided in resources/data + + +To run this sample, first [download](https://github.com/OpenLiberty/sample.daytrader8/archive/master.zip) or clone this repo - to clone: +``` +git clone git@github.com:OpenLiberty/sample.daytrader8.git +``` + +From inside the sample.daytrader8 directory, build and start the application in Open Liberty with the following command: +``` +mvn clean package liberty:run +``` + +The server will listen on port 9080 by default. You can change the port (for example, to port 9081) by adding `mvn clean package liberty:run -DtestServerHttpPort=9081` to the end of the Maven command. + +Once the server is started, you should be able to access the application at: +http://localhost:9080/daytrader + + + +## Notice + +© Copyright IBM Corporation 2019. + +## License + +```text +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 + + http://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. +```` diff --git a/src/test/resources/test-applications/daytrader8/README_LOAD_TEST.md b/src/test/resources/test-applications/daytrader8/README_LOAD_TEST.md new file mode 100644 index 00000000..23d468e1 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/README_LOAD_TEST.md @@ -0,0 +1,151 @@ +# Daytrader8: Load Testing +This readme explains how to setup DB2 and load test the Daytrader 8 application with Open Liberty. + +## Prerequisites + +1. Open Liberty Machine (Server with Open Liberty unzipped at , and a default profile created) +2. DB2 Machine (Server running DB2) +3. Driver Machine (Server running JMeter with jmeter files copied to /bin, and the WebSocket plugin copied to /lib/ext, see jmeter_files) + +## Setup Open Liberty + +Build Daytrader8; +[Download](https://github.com/OpenLiberty/sample.daytrader8/archive/master.zip) or clone this repo - to clone: +``` +git clone git@github.com:OpenLiberty/sample.daytrader8.git +``` + +From inside the sample.daytrader8 directory, build the application: +``` +mvn clean package +``` +* Copy target/io.openliberty.sample.daytrader8.war to /usr/servers/defaultServer/apps +* Copy src/main/liberty/config/server.xml_db2 to /usr/servers/defaultServer/server.xml (overwrite) +* Copy db2 jars from the DB2 Machine to /usr/shared/db2jars +``` +db2jcc4.jar +db2jcc_license_cu.jar +``` + +Create /usr/servers/defaultServer/jvm.options and add any JVM Arguments desired. +``` +-Xms1024m +-Xmx1024m +``` + +Set these environment variables. matching your environment (or hard code them in the server.xml): +``` +contextRoot=daytrader +dbUser +dbPass +tradeDbHost +tradeDbPort +tradeDbName +``` + +## Set up DB2 +Sign in to DB2 machine as db2 user and create tradedb database +``` +db2 create db tradedb +``` + +Note: When creating the database, DB2_APM_PERFORMANCE needs to be off, or you'll get: SQL1803N The requested operation cannot be executed in "No Package Lock" +``` +db2set DB2_APM_PERFORMANCE= +db2stop +db2start +``` + +## Load Database + +Start OpenLiberty: +``` +/bin/server start --clean +``` + +With a web browser go to http://openliberty-hostname:9080/daytrader/configure.html +``` +Click (Re)-create DayTrader Database Tables and Indexes +Click (Re)-populate DayTrader Database +``` + +Stop Liberty Server +``` +/bin/server stop +``` + +On the DB2 Server, Put the following into a script (backupTradeDB.sh) and run as the db2 user +``` +DB=tradedb +mkdir -p ~/backups/${DB} +db2 update dbm cfg using notifylevel 0 +db2 update dbm cfg using diaglevel 1 +db2 update dbm cfg using NUM_POOLAGENTS 500 automatic MAX_COORDAGENTS 500 automatic MAX_CONNECTIONS 500 automatic + +db2 -v update db cfg for ${DB} using MAXLOCKS 100 LOCKLIST 100000 + +db2 connect to ${DB} +db2 update db cfg for ${DB} using maxappls 500 automatic +db2 update db cfg for ${DB} using logfilsiz 8000 +db2 update db cfg for ${DB} using logprimary 32 +db2 update db cfg for ${DB} using dft_queryopt 0 + +db2 update db cfg for ${DB} using softmax 3000 +db2 update db cfg for ${DB} using chngpgs_thresh 99 + +db2 -v alter bufferpool IBMDEFAULTBP size -1 +db2 -v connect reset +db2 -v update db cfg for ${DB} using BUFFPAGE 262144 + +db2set DB2_APM_PERFORMANCE=ON +db2set DB2_KEEPTABLELOCK=CONNECTION +db2set DB2_USE_ALTERNATE_PAGE_CLEANING=ON +db2set DB2_MINIMIZE_LISTPREFETCH=YES +db2set DB2_LOGGER_NON_BUFFERED_IO=OFF + +db2 connect reset +db2 terminate + +db2stop force +db2start + +db2 connect to ${DB} +db2 reorgchk update statistics +db2 connect reset + +db2 terminate +db2 backup db tradedb to ~/backups/${DB} +``` + +Put the following into a script (restoreTradeDB.sh) to run before each server restart. (To make sure the database is in the same state every time) +``` +db2stop force +db2start +db2 restore db tradedb from ~/backups/tradedb replace existing +``` + +Note: If disk writing/reading becomes a bottleneck, you may need to create a ramdisk and restore the database to the ramdisk. + +## Apply Load +On the DB2 Server, restore the database (as db2 user) +``` +restoreTradeDB.sh +``` + +Start Liberty +``` +/bin/server start +``` + +On the JMETER Server, Start JMeter: +``` +cd /bin +./jmeter -n -t daytrader8.jmx -JHOST=openliberty-hostname -JDURATION=180 +``` + +Preferably, do three 180 second warm up runs and then three 180 second measurement runs with a 30 second break in between each. + +Also, a best practice is to reset the database between each run, which can be done on the configuration tab of the application. +``` +http://openliberty-hostname:9080/daytrader/config?action=resetTrade +``` diff --git a/src/test/resources/test-applications/daytrader8/jmeter_files/README.txt b/src/test/resources/test-applications/daytrader8/jmeter_files/README.txt new file mode 100644 index 00000000..50566ce0 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/jmeter_files/README.txt @@ -0,0 +1,54 @@ +# (C) Copyright IBM Corporation 2019, 2021. + # + # 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 + # + # http://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. + + +daytrader8.jmx is an Apache JMeter script that may be used for running the DayTrader8 benchmark. + +Jmeter version 3.3 or later is highly recommended. +To use the script, you will need to put the the WebSocket Sampler (and dependencies) from WebSocket Samplers by Peter Doornbosch into lib/ext. +Use the Jmeter plugin manager or download via https://bitbucket.org/pjtr/jmeter-websocket-samplers. + + +The script has the following options: + -JHOST The name of the machine running the DayTrader Application. The default is localhost. + -JPORT The HTTP port of the server running the DayTrader Application. The default is 9080. + -JPROTOCOL The transport either http or https + -JTHREADS The number of jmeter threads to start. The default is 50. + -JRAMP The ramp up time for starting the threads. Set this to the same value as -JTHREADS for a smoother startup. The default is 0. + -JDURATION The time (in seconds) to run jmeter. + -JMAXTHINKTIME The time in milliseconds to wait between each call. The default is 0 ms + -JSTOCKS The total amount of stocks/quotes in the database, minus one. The default is 9999, which assumes there are 10,000 stocks in the database. + -JBOTUID The lowest user id. The default is 0. + -JTOPUID The highest user id. The default is 14999, which assumes there are 15,000 users in the database. + +Example: ./jmeter -n -t daytrader8.jmx -JHOST=myserver -JPORT=9080 -JPROTOCOL=http -JMAXTHINKTIME=100 -JDURATION=300 + +To see output every five seconds from JMeter, edit the following section in /bin/jmeter.properties + +#--------------------------------------------------------------------------- +# Summariser - Generate Summary Results - configuration (mainly applies to non-GUI mode) +#--------------------------------------------------------------------------- +# +# Define the following property to automatically start a summariser with that name +# (applies to non-GUI mode only) +summariser.name=summary +# +# interval between summaries (in seconds) default 30 seconds +summariser.interval=5 +# +# Write messages to log file +summariser.log=true +# +# Write messages to System.out +summariser.out=true diff --git a/src/test/resources/test-applications/daytrader8/jmeter_files/daytrader8.jmx b/src/test/resources/test-applications/daytrader8/jmeter_files/daytrader8.jmx new file mode 100644 index 00000000..cfe98684 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/jmeter_files/daytrader8.jmx @@ -0,0 +1,2607 @@ + + + + + + false + false + + + + + + + + + false + -1 + + ${__P(THREADS,50)} + ${__P(RAMP,0)} + 1355173676000 + 1355173676000 + true + continue + ${__P(DURATION, 180)} + + true + + + + + false + false + rfc2109 + + + + + + User-Agent + Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322) + + + Accept + image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */* + + + Accept-Language + en-us + + + + + + + + minimumuid + ${__P(BOTUID,0)} + = + + + maximumuid + ${__P(TOPUID,14999)} + = + + + hostname + ${__P(HOST,localhost)} + = + + + port + ${__P(PORT,9080)} + = + + + maxthinkingtime + ${__P(MAXTHINKTIME,0)} + = + + + maximumsid + ${__P(STOCKS,9999)} + = + + + protocol + ${__P(PROTOCOL,http)} + = + http | https + + + + + + ${minimumuid} + ${maximumuid} + 1 + logincounter + + false + + + + 1 + + + + 1 + true + 50 + + ThroughputController.percentThroughput + 10.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/welcome.faces + POST + false + true + true + false + + HttpClient4 + + + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + xxx + = + true + login:password + + + false + Log in + = + true + login:submit + + + false + uid:${logincounter} + = + true + login:uid + + + false + 1 + = + true + login_SUBMIT + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/welcome.faces + POST + false + true + true + false + + HttpClient4 + + + + + + + loop + + + + true + + + true + + + + + Ready to Trade + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + + ${loop} + + + + 1 + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 36.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/quote.faces + GET + false + true + true + false + + HttpClient4 + + + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + s:${__Random(0,${maximumsid},)} + = + true + quotes:symbols + + + false + quotes + = + true + quotes:submit2 + + + false + 1 + = + true + quotes_SUBMIT + + + false + 100 + = + true + quotes:quotes:0:quantity + + + false + 100 + = + true + quotes:quotes:1:quantity + + + false + 100 + = + true + quotes:quotes:2:quantity + + + false + 100 + = + true + quotes:quotes:3:quantity + + + false + 100 + = + true + quotes:quotes:4:quantity + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/quote.faces + POST + false + true + true + false + + HttpClient4 + + + + + + + DayTrader Quotes + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 16.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/tradehome.faces + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 15.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/portfolio.faces + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 10.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/account.faces + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 8.0 + 0.0 + + + + + ${__jexl3("${protocol}"== "http",)} + false + true + + + + true + false + ${hostname} + ${port} + /daytrader/marketsummary + false + {"action":"updateMarketSummary"} + 20000 + open and close + 20000 + false + + + + + ${maxthinkingtime} + + + + + + ${__jexl3("${protocol}"== "https",)} + false + true + + + + true + true + ${hostname} + ${port} + /daytrader/marketsummary + false + {"action":"updateMarketSummary"} + 20000 + open and close + 20000 + false + + + + + ${maxthinkingtime} + + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 4.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/quote.faces + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + s:${__Random(0,${maximumsid},)} + = + true + quotes:symbols + + + false + quotes + = + true + quotes:submit2 + + + false + 1 + = + true + quotes_SUBMIT + + + false + 100 + = + true + quotes:quotes:0:quantity + + + false + 100 + = + true + quotes:quotes:1:quantity + + + false + 100 + = + true + quotes:quotes:2:quantity + + + false + 100 + = + true + quotes:quotes:3:quantity + + + false + 100 + = + true + quotes:quotes:4:quantity + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/quote.faces + POST + false + true + true + false + + HttpClient4 + + + + + + + DayTrader Quotes + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + false + tobuy + s:([0-9]+) + $1$ + 0 + 1 + all + + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + s:${tobuy} + = + true + quotes:symbols + + + false + ${__Random(1,200)} + = + true + quotes:quotes:0:quantity + + + false + buy + = + true + quotes:quotes:0:buy + + + false + 1 + = + true + quotes_SUBMIT + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/quote.faces + POST + false + true + true + false + + HttpClient4 + + + + + + + been submitted + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 4.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/portfolio.faces + GET + false + true + true + false + + HttpClient4 + + + + + + false + numHoldings + of Holdings: </b>([1-9][0-9]*)</td> + $1$ + 0 + 0 + all + + + + ${maxthinkingtime} + + + + + ${__jexl("${numHoldings}" != "0")} + false + true + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + portfolio:holdings:0:sell + = + true + portfolio:_idcl + + + false + 1 + = + true + portfolio_SUBMIT + + + false + s:0,s:1,s:2,s:3,s:4 + = + true + portfolio:symbols + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/portfolio.faces + POST + false + true + true + false + + HttpClient4 + + + + + + + been submitted + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 2.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/account.faces + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + uid:${logincounter} + = + true + updateProfile:uid + + + false + rnd${__threadNum}${logincounter} + = + true + updateProfile:fullname + + + false + xxx + = + true + updateProfile:password + + + false + rndAddress + = + true + updateProfile:address + + + false + xxx + = + true + updateProfile:cpassword + + + false + rndCC + = + true + updateProfile:ccn + + + false + rndEmail@email.com + = + true + updateProfile:email + + + false + 1 + = + true + updateProfile_SUBMIT + + + false + Update Profile + = + true + updateProfile:submit + + + false + s:0,s:1,s:2,s:3,s:4 + = + true + updateProfile:symbols + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/account.faces + POST + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 1.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/tradehome.faces + GET + false + true + true + false + + HttpClient4 + + + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + tradeHome:logoff + = + true + tradeHome:_idcl + + + false + s:0,s:1,s:2,s:3,s:4 + = + true + tradeHome:symbols + + + false + 1 + = + true + tradeHome_SUBMIT + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/tradehome.faces + POST + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + DayTrader Login + + Assertion.response_data + false + 2 + + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/register.faces + GET + false + true + true + false + + HttpClient4 + + + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + first:${__Random(0,999,)} last:${__Random(0,4999,)} + = + true + register:fullname + + + false + first:${__Random(0,999,)} last:${__Random(0,4999,)} + = + true + register:address + + + false + uid${logincounter}@${__Random(0,100,)}.com + = + true + register:email + + + false + ru:${logincounter}${__threadNum}:${__time(HMS)}${__Random(0,999,)} + = + true + register:uid + + + false + yyy + = + true + register:password + + + false + yyy + = + true + register:cpassword + + + false + 1000000 + = + true + register:money + + + false + 123-fake-ccnum-456 + = + true + register:ccn + + + false + 1 + = + true + register_SUBMIT + + + false + Register + = + true + register:submit + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/register.faces + POST + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + Registration operation succeeded + + Assertion.response_data + false + 2 + + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/tradehome.faces + GET + false + true + true + false + + HttpClient4 + + + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + tradeHome:logoff + = + true + tradeHome:_idcl + + + false + s:0,s:1,s:2,s:3,s:4 + = + true + tradeHome:symbols + + + false + 1 + = + true + tradeHome_SUBMIT + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/tradehome.faces + POST + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + DayTrader Login + + Assertion.response_data + false + 2 + + + + + + + loop + + + + false + + + false + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 4.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/tradehome.faces + GET + false + true + true + false + + HttpClient4 + + + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + tradeHome:logoff + = + true + tradeHome:_idcl + + + false + s:0,s:1,s:2,s:3,s:4 + = + true + tradeHome:symbols + + + false + 1 + = + true + tradeHome_SUBMIT + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/tradehome.faces + POST + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + DayTrader Login + + Assertion.response_data + false + 2 + + + + + + + loop + + + + false + + + false + + + + + + + false + jsfViewState + <input type="hidden" name="javax\.faces\.ViewState" id="j_id__v_0:javax\.faces\.ViewState:1" value="([^"]+)".*/> + $1$ + + 0 + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 70.0 + 0.0 + + + + + + + + true + uid:${logincounter} + = + true + uid + + + true + xxx + = + true + passwd + + + true + login + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + POST + false + true + true + false + + HttpClient4 + + + + + + + loop + + + + true + + + true + + + + + Welcome to DayTrader + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + + ${__jexl3("${protocol}"== "http",)} + false + true + + + + false + ${hostname} + ${port} + /daytrader/marketsummary + 20000 + 20000 + + + + + ${__jexl3("${protocol}"== "https",)} + false + true + + + + true + ${hostname} + ${port} + /daytrader/marketsummary + 20000 + 20000 + + + + + ${loop} + + + + 1 + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 36.0 + 0.0 + + + + + + + + true + quotes + = + true + action + + + true + s:${__Random(0,${maximumsid},)} + = + true + symbols + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + + DayTrader: Quotes and Trading + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 16.0 + 0.0 + + + + + + + + true + home + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 15.0 + 0.0 + + + + + + + + true + portfolio + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 10.0 + 0.0 + + + + + + + + true + account + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 8.0 + 0.0 + + + + + false + false + ${hostname} + ${port} + /daytrader/marketsummary + false + {"action":"updateMarketSummary"} + 20000 + use existing open connection + 20000 + false + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 4.0 + 0.0 + + + + + + + + true + quotes + = + true + action + + + true + s:${__Random(0,${maximumsid},tobuy)} + = + true + symbols + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + + + true + buy + = + true + action + + + true + s:${tobuy} + = + true + symbol + + + true + ${__Random(1,200)} + = + true + quantity + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + + has been submitted + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 4.0 + 0.0 + + + + + + + + true + portfolio + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + false + firstHoldingID + holdingID=([0-9]+) + $1$ + NotFound + 0 + all + + + + false + firstHoldingIDBool + holdingID=([0-9]+) + true + false + 1 + all + + + + ${maxthinkingtime} + + + + + ${firstHoldingIDBool} + false + true + + + + + + + true + sell + = + true + action + + + true + ${firstHoldingID} + = + true + holdingID + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + + has been submitted + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 2.0 + 0.0 + + + + + + + + true + account + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + + + true + update_profile + = + true + action + + + true + uid:${logincounter} + = + true + userID + + + true + rnd${__threadNum}${logincounter} + = + true + fullname + + + true + xxx + = + true + password + + + true + rndAddress + = + true + address + + + true + xxx + = + true + cpassword + + + true + rndCC + = + true + creditcard + + + true + rndEmail@email.com + = + true + email + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 1.0 + 0.0 + + + + + + + + true + logout + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/register.jsp + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + + + true + register + = + true + action + + + true + first:${__Random(0,999,)} last:${__Random(0,4999,)} + = + true + Full Name + + + true + first:${__Random(0,999,)} last:${__Random(0,4999,)} + = + true + snail mail + + + true + uid${logincounter}@${__Random(0,100,)}.com + = + true + email + + + true + ru:${logincounter}${__threadNum}:${__time(HMS)}${__Random(0,999,)} + = + true + user id + + + true + yyy + = + true + passwd + + + true + yyy + = + true + confirm passwd + + + true + 1000000 + = + true + money + + + true + 123-fake-ccnum-456 + = + true + Credit Card Number + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + + + true + logout + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + loop + + + + false + + + false + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 4.0 + 0.0 + + + + + + + + true + logout + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + DayTrader Login + + Assertion.response_data + false + 2 + + + + + + + loop + + + + false + + + false + + + + + + + 4000 + 6000 + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 20.0 + 0.0 + + + + + + + + true + s:${__Random(0,${maximumsid},)} + = + true + symbols + + + + ${hostname} + ${port} + ${protocol} + + daytrader/rest/quotes + POST + false + true + true + false + + + + + + + + 200 + + Assertion.response_code + false + 2 + + + + + ${maxthinkingtime} + + + + + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + true + false + false + false + false + false + 0 + true + true + true + true + + + daytrader8.aggregateReport.csv + + + + true + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + false + false + false + false + false + 0 + true + true + true + true + + + daytrader8.resultsTree.csv + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + true + false + false + false + false + false + 0 + true + true + true + true + + + daytrader8.resultsTable.csv + + + + + diff --git a/src/test/resources/test-applications/daytrader8/jmeter_files/daytrader8_mojarra.jmx b/src/test/resources/test-applications/daytrader8/jmeter_files/daytrader8_mojarra.jmx new file mode 100755 index 00000000..bcb3d4fa --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/jmeter_files/daytrader8_mojarra.jmx @@ -0,0 +1,2600 @@ + + + + + + false + false + + + + + + + + + false + -1 + + ${__P(THREADS,50)} + ${__P(RAMP,0)} + 1355173676000 + 1355173676000 + true + continue + ${__P(DURATION, 180)} + + true + + + + + false + false + rfc2109 + + + + + + User-Agent + Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322) + + + Accept + image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */* + + + Accept-Language + en-us + + + + + + + + minimumuid + ${__P(BOTUID,0)} + = + + + maximumuid + ${__P(TOPUID,14999)} + = + + + hostname + ${__P(HOST,localhost)} + = + + + port + ${__P(PORT,9080)} + = + + + maxthinkingtime + ${__P(MAXTHINKTIME,0)} + = + + + maximumsid + ${__P(STOCKS,9999)} + = + + + protocol + ${__P(PROTOCOL,http)} + = + http | https + + + + + + ${minimumuid} + ${maximumuid} + 1 + logincounter + + false + + + + 1 + + + + 1 + true + 50 + + ThroughputController.percentThroughput + 10.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/welcome.faces + POST + false + true + true + false + + HttpClient4 + + + + + + + + + false + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + xxx + = + true + login:password + + + false + Log in + = + true + login:submit + + + false + uid:${logincounter} + = + true + login:uid + + + false + login + = + true + login + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/welcome.faces + POST + false + true + true + false + + HttpClient4 + + + + + + + loop + + + + true + + + true + + + + + Ready to Trade + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + + ${loop} + + + + 1 + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 36.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/quote.faces + GET + false + true + true + false + + HttpClient4 + + + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + s:${__Random(0,${maximumsid},)} + = + true + quotes:symbols + + + false + quotes + = + true + quotes:submit + + + false + quotes + = + true + quotes + + + false + 100 + = + true + quotes:quotes:0:quantity + + + false + 100 + = + true + quotes:quotes:1:quantity + + + false + 100 + = + true + quotes:quotes:2:quantity + + + false + 100 + = + true + quotes:quotes:3:quantity + + + false + 100 + = + true + quotes:quotes:4:quantity + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/quote.faces + POST + false + true + true + false + + HttpClient4 + + + + + + + DayTrader Quotes + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 16.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/tradehome.faces + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 15.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/portfolio.faces + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 10.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/account.faces + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 8.0 + 0.0 + + + + + ${__jexl3("${protocol}"== "http",)} + false + true + + + + true + false + ${hostname} + ${port} + /daytrader/marketsummary + false + {"action":"updateMarketSummary"} + 20000 + open and close + 20000 + false + + + + + ${maxthinkingtime} + + + + + + ${__jexl3("${protocol}"== "https",)} + false + true + + + + true + true + ${hostname} + ${port} + /daytrader/marketsummary + false + {"action":"updateMarketSummary"} + 20000 + open and close + 20000 + false + + + + + ${maxthinkingtime} + + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 4.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/quote.faces + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + s:${__Random(0,${maximumsid},)} + = + true + quotes:symbols + + + false + quotes + = + true + quotes:submit + + + false + quotes + = + true + quotes + + + false + 100 + = + true + quotes:quotes:0:quantity + + + false + 100 + = + true + quotes:quotes:1:quantity + + + false + 100 + = + true + quotes:quotes:2:quantity + + + false + 100 + = + true + quotes:quotes:3:quantity + + + false + 100 + = + true + quotes:quotes:4:quantity + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/quote.faces + POST + false + true + true + false + + HttpClient4 + + + + + + + DayTrader Quotes + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + false + tobuy + s:([0-9]+) + $1$ + 0 + 1 + all + + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + s:${tobuy} + = + true + quotes:symbols + + + false + ${__Random(1,200)} + = + true + quotes:quotes:0:quantity + + + false + buy + = + true + quotes:quotes:0:buy + + + false + quotes + = + true + quotes + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/quote.faces + POST + false + true + true + false + + HttpClient4 + + + + + + + been submitted + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 4.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/portfolio.faces + GET + false + true + true + false + + HttpClient4 + + + + + + false + numHoldings + of Holdings: </b>([1-9][0-9]*)</td> + $1$ + 0 + 0 + all + + + + ${maxthinkingtime} + + + + + ${__jexl("${numHoldings}" != "0")} + false + true + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + portfolio:holdings:0:sell + = + true + portfolio:holdings:0:sell + + + false + portfolio + = + true + portfolio + + + false + s:0,s:1,s:2,s:3,s:4 + = + true + portfolio:symbols + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/portfolio.faces + POST + false + true + true + false + + HttpClient4 + + + + + + + been submitted + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 2.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/account.faces + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + uid:${logincounter} + = + true + updateProfile:uid + + + false + rnd${__threadNum}${logincounter} + = + true + updateProfile:fullname + + + false + xxx + = + true + updateProfile:password + + + false + rndAddress + = + true + updateProfile:address + + + false + xxx + = + true + updateProfile:cpassword + + + false + rndCC + = + true + updateProfile:ccn + + + false + rndEmail@email.com + = + true + updateProfile:email + + + false + updateProfile + = + true + updateProfile + + + false + Update Profile + = + true + updateProfile:submit + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/account.faces + POST + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 1.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/tradehome.faces + GET + false + true + true + false + + HttpClient4 + + + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + tradeHome:logoff + = + true + tradeHome:logoff + + + false + s:1,s:2,s:3,s:4 + = + true + tradeHome:symbols + + + false + tradeHome + = + true + tradeHome + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/tradehome.faces + POST + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + DayTrader Login + + Assertion.response_data + false + 2 + + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/register.faces + GET + false + true + true + false + + HttpClient4 + + + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + first:${__Random(0,999,)} last:${__Random(0,4999,)} + = + true + register:fullname + + + false + first:${__Random(0,999,)} last:${__Random(0,4999,)} + = + true + register:address + + + false + uid${logincounter}@${__Random(0,100,)}.com + = + true + register:email + + + false + ru:${logincounter}${__threadNum}:${__time(HMS)}${__Random(0,999,)} + = + true + register:uid + + + false + yyy + = + true + register:password + + + false + yyy + = + true + register:cpassword + + + false + 1000000 + = + true + register:money + + + false + 123-fake-ccnum-456 + = + true + register:ccn + + + false + register + = + true + register + + + false + Register + = + true + register:submit + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/register.faces + POST + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + Registration operation succeeded + + Assertion.response_data + false + 2 + + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/tradehome.faces + GET + false + true + true + false + + HttpClient4 + + + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + tradeHome:logoff + = + true + tradeHome:logoff + + + false + s:1,s:2,s:3,s:4 + = + true + tradeHome:symbols + + + false + tradeHome + = + true + tradeHome + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/tradehome.faces + POST + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + DayTrader Login + + Assertion.response_data + false + 2 + + + + + + + loop + + + + false + + + false + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 4.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/tradehome.faces + GET + false + true + true + false + + HttpClient4 + + + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + tradeHome:logoff + = + true + tradeHome:logoff + + + false + s:0,s:1,s:2,s:3,s:4 + = + true + tradeHome:symbols + + + false + tradeHome + = + true + tradeHome + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/tradehome.faces + POST + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + DayTrader Login + + Assertion.response_data + false + 2 + + + + + + + loop + + + + false + + + false + + + + + + + false + jsfViewState + <input type="hidden" name="javax\.faces\.ViewState" .* value="([^"]+)".*/> + $1$ + + 0 + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 70.0 + 0.0 + + + + + + + + true + uid:${logincounter} + = + true + uid + + + true + xxx + = + true + passwd + + + true + login + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + POST + false + true + true + false + + HttpClient4 + + + + + + + loop + + + + true + + + true + + + + + Welcome to DayTrader + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + + ${__jexl3("${protocol}"== "http",)} + false + true + + + + false + ${hostname} + ${port} + /daytrader/marketsummary + 20000 + 20000 + + + + + ${__jexl3("${protocol}"== "https",)} + false + true + + + + true + ${hostname} + ${port} + /daytrader/marketsummary + 20000 + 20000 + + + + + ${loop} + + + + 1 + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 36.0 + 0.0 + + + + + + + + true + quotes + = + true + action + + + true + s:${__Random(0,${maximumsid},)} + = + true + symbols + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + + DayTrader: Quotes and Trading + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 16.0 + 0.0 + + + + + + + + true + home + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 15.0 + 0.0 + + + + + + + + true + portfolio + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 10.0 + 0.0 + + + + + + + + true + account + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 8.0 + 0.0 + + + + + false + false + ${hostname} + ${port} + /daytrader/marketsummary + false + {"action":"updateMarketSummary"} + 20000 + use existing open connection + 20000 + false + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 4.0 + 0.0 + + + + + + + + true + quotes + = + true + action + + + true + s:${__Random(0,${maximumsid},tobuy)} + = + true + symbols + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + + + true + buy + = + true + action + + + true + s:${tobuy} + = + true + symbol + + + true + ${__Random(1,200)} + = + true + quantity + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + + has been submitted + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 4.0 + 0.0 + + + + + + + + true + portfolio + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + false + firstHoldingID + holdingID=([0-9]+) + $1$ + NotFound + 0 + all + + + + false + firstHoldingIDBool + holdingID=([0-9]+) + true + false + 1 + all + + + + ${maxthinkingtime} + + + + + ${firstHoldingIDBool} + false + true + + + + + + + true + sell + = + true + action + + + true + ${firstHoldingID} + = + true + holdingID + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + + has been submitted + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 2.0 + 0.0 + + + + + + + + true + account + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + + + true + update_profile + = + true + action + + + true + uid:${logincounter} + = + true + userID + + + true + rnd${__threadNum}${logincounter} + = + true + fullname + + + true + xxx + = + true + password + + + true + rndAddress + = + true + address + + + true + xxx + = + true + cpassword + + + true + rndCC + = + true + creditcard + + + true + rndEmail@email.com + = + true + email + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 1.0 + 0.0 + + + + + + + + true + logout + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/register.jsp + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + + + true + register + = + true + action + + + true + first:${__Random(0,999,)} last:${__Random(0,4999,)} + = + true + Full Name + + + true + first:${__Random(0,999,)} last:${__Random(0,4999,)} + = + true + snail mail + + + true + uid${logincounter}@${__Random(0,100,)}.com + = + true + email + + + true + ru:${logincounter}${__threadNum}:${__time(HMS)}${__Random(0,999,)} + = + true + user id + + + true + yyy + = + true + passwd + + + true + yyy + = + true + confirm passwd + + + true + 1000000 + = + true + money + + + true + 123-fake-ccnum-456 + = + true + Credit Card Number + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + + + true + logout + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + loop + + + + false + + + false + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 4.0 + 0.0 + + + + + + + + true + logout + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + DayTrader Login + + Assertion.response_data + false + 2 + + + + + + + loop + + + + false + + + false + + + + + + + 4000 + 6000 + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 20.0 + 0.0 + + + + + + + + true + s:${__Random(0,${maximumsid},)} + = + true + symbols + + + + ${hostname} + ${port} + ${protocol} + + daytrader/rest/quotes + POST + false + true + true + false + + + + + + + + 200 + + Assertion.response_code + false + 2 + + + + + ${maxthinkingtime} + + + + + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + true + false + false + false + false + false + 0 + true + true + true + true + + + daytrader8.aggregateReport.csv + + + + true + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + false + false + false + false + false + 0 + true + true + true + true + + + daytrader8.resultsTree.csv + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + true + false + false + false + false + false + 0 + true + true + true + true + + + daytrader8.resultsTable.csv + + + + + diff --git a/src/test/resources/test-applications/daytrader8/jmeter_files/daytrader8_mojarra_no_ws.jmx b/src/test/resources/test-applications/daytrader8/jmeter_files/daytrader8_mojarra_no_ws.jmx new file mode 100644 index 00000000..d294427d --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/jmeter_files/daytrader8_mojarra_no_ws.jmx @@ -0,0 +1,2600 @@ + + + + + + false + false + + + + + + + + + false + -1 + + ${__P(THREADS,50)} + ${__P(RAMP,0)} + 1355173676000 + 1355173676000 + true + continue + ${__P(DURATION, 180)} + + true + + + + + false + false + rfc2109 + + + + + + User-Agent + Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322) + + + Accept + image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */* + + + Accept-Language + en-us + + + + + + + + minimumuid + ${__P(BOTUID,0)} + = + + + maximumuid + ${__P(TOPUID,14999)} + = + + + hostname + ${__P(HOST,localhost)} + = + + + port + ${__P(PORT,9080)} + = + + + maxthinkingtime + ${__P(MAXTHINKTIME,0)} + = + + + maximumsid + ${__P(STOCKS,9999)} + = + + + protocol + ${__P(PROTOCOL,http)} + = + http | https + + + + + + ${minimumuid} + ${maximumuid} + 1 + logincounter + + false + + + + 1 + + + + 1 + true + 50 + + ThroughputController.percentThroughput + 10.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/welcome.faces + POST + false + true + true + false + + HttpClient4 + + + + + + + + + false + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + xxx + = + true + login:password + + + false + Log in + = + true + login:submit + + + false + uid:${logincounter} + = + true + login:uid + + + false + login + = + true + login + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/welcome.faces + POST + false + true + true + false + + HttpClient4 + + + + + + + loop + + + + true + + + true + + + + + Ready to Trade + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + + ${loop} + + + + 1 + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 36.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/quote.faces + GET + false + true + true + false + + HttpClient4 + + + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + s:${__Random(0,${maximumsid},)} + = + true + quotes:symbols + + + false + quotes + = + true + quotes:submit + + + false + quotes + = + true + quotes + + + false + 100 + = + true + quotes:quotes:0:quantity + + + false + 100 + = + true + quotes:quotes:1:quantity + + + false + 100 + = + true + quotes:quotes:2:quantity + + + false + 100 + = + true + quotes:quotes:3:quantity + + + false + 100 + = + true + quotes:quotes:4:quantity + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/quote.faces + POST + false + true + true + false + + HttpClient4 + + + + + + + DayTrader Quotes + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 16.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/tradehome.faces + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 15.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/portfolio.faces + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 10.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/account.faces + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 8.0 + 0.0 + + + + + ${__jexl3("${protocol}"== "http",)} + false + true + + + + true + false + ${hostname} + ${port} + /daytrader/marketsummary + false + {"action":"updateMarketSummary"} + 20000 + open and close + 20000 + false + + + + + ${maxthinkingtime} + + + + + + ${__jexl3("${protocol}"== "https",)} + false + true + + + + true + true + ${hostname} + ${port} + /daytrader/marketsummary + false + {"action":"updateMarketSummary"} + 20000 + open and close + 20000 + false + + + + + ${maxthinkingtime} + + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 4.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/quote.faces + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + s:${__Random(0,${maximumsid},)} + = + true + quotes:symbols + + + false + quotes + = + true + quotes:submit + + + false + quotes + = + true + quotes + + + false + 100 + = + true + quotes:quotes:0:quantity + + + false + 100 + = + true + quotes:quotes:1:quantity + + + false + 100 + = + true + quotes:quotes:2:quantity + + + false + 100 + = + true + quotes:quotes:3:quantity + + + false + 100 + = + true + quotes:quotes:4:quantity + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/quote.faces + POST + false + true + true + false + + HttpClient4 + + + + + + + DayTrader Quotes + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + false + tobuy + s:([0-9]+) + $1$ + 0 + 1 + all + + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + s:${tobuy} + = + true + quotes:symbols + + + false + ${__Random(1,200)} + = + true + quotes:quotes:0:quantity + + + false + buy + = + true + quotes:quotes:0:buy + + + false + quotes + = + true + quotes + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/quote.faces + POST + false + true + true + false + + HttpClient4 + + + + + + + been submitted + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 4.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/portfolio.faces + GET + false + true + true + false + + HttpClient4 + + + + + + false + numHoldings + of Holdings: </b>([1-9][0-9]*)</td> + $1$ + 0 + 0 + all + + + + ${maxthinkingtime} + + + + + ${__jexl("${numHoldings}" != "0")} + false + true + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + portfolio:holdings:0:sell + = + true + portfolio:holdings:0:sell + + + false + portfolio + = + true + portfolio + + + false + s:0,s:1,s:2,s:3,s:4 + = + true + portfolio:symbols + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/portfolio.faces + POST + false + true + true + false + + HttpClient4 + + + + + + + been submitted + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 2.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/account.faces + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + uid:${logincounter} + = + true + updateProfile:uid + + + false + rnd${__threadNum}${logincounter} + = + true + updateProfile:fullname + + + false + xxx + = + true + updateProfile:password + + + false + rndAddress + = + true + updateProfile:address + + + false + xxx + = + true + updateProfile:cpassword + + + false + rndCC + = + true + updateProfile:ccn + + + false + rndEmail@email.com + = + true + updateProfile:email + + + false + updateProfile + = + true + updateProfile + + + false + Update Profile + = + true + updateProfile:submit + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/account.faces + POST + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 1.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/tradehome.faces + GET + false + true + true + false + + HttpClient4 + + + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + tradeHome:logoff + = + true + tradeHome:logoff + + + false + s:1,s:2,s:3,s:4 + = + true + tradeHome:symbols + + + false + tradeHome + = + true + tradeHome + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/tradehome.faces + POST + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + DayTrader Login + + Assertion.response_data + false + 2 + + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/register.faces + GET + false + true + true + false + + HttpClient4 + + + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + first:${__Random(0,999,)} last:${__Random(0,4999,)} + = + true + register:fullname + + + false + first:${__Random(0,999,)} last:${__Random(0,4999,)} + = + true + register:address + + + false + uid${logincounter}@${__Random(0,100,)}.com + = + true + register:email + + + false + ru:${logincounter}${__threadNum}:${__time(HMS)}${__Random(0,999,)} + = + true + register:uid + + + false + yyy + = + true + register:password + + + false + yyy + = + true + register:cpassword + + + false + 1000000 + = + true + register:money + + + false + 123-fake-ccnum-456 + = + true + register:ccn + + + false + register + = + true + register + + + false + Register + = + true + register:submit + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/register.faces + POST + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + Registration operation succeeded + + Assertion.response_data + false + 2 + + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/tradehome.faces + GET + false + true + true + false + + HttpClient4 + + + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + tradeHome:logoff + = + true + tradeHome:logoff + + + false + s:1,s:2,s:3,s:4 + = + true + tradeHome:symbols + + + false + tradeHome + = + true + tradeHome + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/tradehome.faces + POST + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + DayTrader Login + + Assertion.response_data + false + 2 + + + + + + + loop + + + + false + + + false + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 4.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/tradehome.faces + GET + false + true + true + false + + HttpClient4 + + + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + tradeHome:logoff + = + true + tradeHome:logoff + + + false + s:0,s:1,s:2,s:3,s:4 + = + true + tradeHome:symbols + + + false + tradeHome + = + true + tradeHome + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/tradehome.faces + POST + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + DayTrader Login + + Assertion.response_data + false + 2 + + + + + + + loop + + + + false + + + false + + + + + + + false + jsfViewState + <input type="hidden" name="javax\.faces\.ViewState" .* value="([^"]+)".*/> + $1$ + + 0 + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 70.0 + 0.0 + + + + + + + + true + uid:${logincounter} + = + true + uid + + + true + xxx + = + true + passwd + + + true + login + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + POST + false + true + true + false + + HttpClient4 + + + + + + + loop + + + + true + + + true + + + + + Welcome to DayTrader + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + + ${__jexl3("${protocol}"== "http",)} + false + true + + + + false + ${hostname} + ${port} + /daytrader/marketsummary + 20000 + 20000 + + + + + ${__jexl3("${protocol}"== "https",)} + false + true + + + + true + ${hostname} + ${port} + /daytrader/marketsummary + 20000 + 20000 + + + + + ${loop} + + + + 1 + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 36.0 + 0.0 + + + + + + + + true + quotes + = + true + action + + + true + s:${__Random(0,${maximumsid},)} + = + true + symbols + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + + DayTrader: Quotes and Trading + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 16.0 + 0.0 + + + + + + + + true + home + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 15.0 + 0.0 + + + + + + + + true + portfolio + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 10.0 + 0.0 + + + + + + + + true + account + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 8.0 + 0.0 + + + + + false + false + ${hostname} + ${port} + /daytrader/marketsummary + false + {"action":"updateMarketSummary"} + 20000 + use existing open connection + 20000 + false + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 4.0 + 0.0 + + + + + + + + true + quotes + = + true + action + + + true + s:${__Random(0,${maximumsid},tobuy)} + = + true + symbols + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + + + true + buy + = + true + action + + + true + s:${tobuy} + = + true + symbol + + + true + ${__Random(1,200)} + = + true + quantity + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + + has been submitted + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 4.0 + 0.0 + + + + + + + + true + portfolio + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + false + firstHoldingID + holdingID=([0-9]+) + $1$ + NotFound + 0 + all + + + + false + firstHoldingIDBool + holdingID=([0-9]+) + true + false + 1 + all + + + + ${maxthinkingtime} + + + + + ${firstHoldingIDBool} + false + true + + + + + + + true + sell + = + true + action + + + true + ${firstHoldingID} + = + true + holdingID + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + + has been submitted + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 2.0 + 0.0 + + + + + + + + true + account + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + + + true + update_profile + = + true + action + + + true + uid:${logincounter} + = + true + userID + + + true + rnd${__threadNum}${logincounter} + = + true + fullname + + + true + xxx + = + true + password + + + true + rndAddress + = + true + address + + + true + xxx + = + true + cpassword + + + true + rndCC + = + true + creditcard + + + true + rndEmail@email.com + = + true + email + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 1.0 + 0.0 + + + + + + + + true + logout + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/register.jsp + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + + + true + register + = + true + action + + + true + first:${__Random(0,999,)} last:${__Random(0,4999,)} + = + true + Full Name + + + true + first:${__Random(0,999,)} last:${__Random(0,4999,)} + = + true + snail mail + + + true + uid${logincounter}@${__Random(0,100,)}.com + = + true + email + + + true + ru:${logincounter}${__threadNum}:${__time(HMS)}${__Random(0,999,)} + = + true + user id + + + true + yyy + = + true + passwd + + + true + yyy + = + true + confirm passwd + + + true + 1000000 + = + true + money + + + true + 123-fake-ccnum-456 + = + true + Credit Card Number + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + + + true + logout + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + loop + + + + false + + + false + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 4.0 + 0.0 + + + + + + + + true + logout + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + DayTrader Login + + Assertion.response_data + false + 2 + + + + + + + loop + + + + false + + + false + + + + + + + 4000 + 6000 + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 20.0 + 0.0 + + + + + + + + true + s:${__Random(0,${maximumsid},)} + = + true + symbols + + + + ${hostname} + ${port} + ${protocol} + + daytrader/rest/quotes + POST + false + true + true + false + + + + + + + + 200 + + Assertion.response_code + false + 2 + + + + + ${maxthinkingtime} + + + + + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + true + false + false + false + false + false + 0 + true + true + true + true + + + daytrader8.aggregateReport.csv + + + + true + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + false + false + false + false + false + 0 + true + true + true + true + + + daytrader8.resultsTree.csv + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + true + false + false + false + false + false + 0 + true + true + true + true + + + daytrader8.resultsTable.csv + + + + + diff --git a/src/test/resources/test-applications/daytrader8/jmeter_files/daytrader8_no_ws.jmx b/src/test/resources/test-applications/daytrader8/jmeter_files/daytrader8_no_ws.jmx new file mode 100644 index 00000000..026ca71e --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/jmeter_files/daytrader8_no_ws.jmx @@ -0,0 +1,2607 @@ + + + + + + false + false + + + + + + + + + false + -1 + + ${__P(THREADS,50)} + ${__P(RAMP,0)} + 1355173676000 + 1355173676000 + true + continue + ${__P(DURATION, 180)} + + true + + + + + false + false + rfc2109 + + + + + + User-Agent + Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322) + + + Accept + image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */* + + + Accept-Language + en-us + + + + + + + + minimumuid + ${__P(BOTUID,0)} + = + + + maximumuid + ${__P(TOPUID,14999)} + = + + + hostname + ${__P(HOST,localhost)} + = + + + port + ${__P(PORT,9080)} + = + + + maxthinkingtime + ${__P(MAXTHINKTIME,0)} + = + + + maximumsid + ${__P(STOCKS,9999)} + = + + + protocol + ${__P(PROTOCOL,http)} + = + http | https + + + + + + ${minimumuid} + ${maximumuid} + 1 + logincounter + + false + + + + 1 + + + + 1 + true + 50 + + ThroughputController.percentThroughput + 10.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/welcome.faces + POST + false + true + true + false + + HttpClient4 + + + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + xxx + = + true + login:password + + + false + Log in + = + true + login:submit + + + false + uid:${logincounter} + = + true + login:uid + + + false + 1 + = + true + login_SUBMIT + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/welcome.faces + POST + false + true + true + false + + HttpClient4 + + + + + + + loop + + + + true + + + true + + + + + Ready to Trade + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + + ${loop} + + + + 1 + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 36.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/quote.faces + GET + false + true + true + false + + HttpClient4 + + + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + s:${__Random(0,${maximumsid},)} + = + true + quotes:symbols + + + false + quotes + = + true + quotes:submit2 + + + false + 1 + = + true + quotes_SUBMIT + + + false + 100 + = + true + quotes:quotes:0:quantity + + + false + 100 + = + true + quotes:quotes:1:quantity + + + false + 100 + = + true + quotes:quotes:2:quantity + + + false + 100 + = + true + quotes:quotes:3:quantity + + + false + 100 + = + true + quotes:quotes:4:quantity + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/quote.faces + POST + false + true + true + false + + HttpClient4 + + + + + + + DayTrader Quotes + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 16.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/tradehome.faces + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 15.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/portfolio.faces + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 10.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/account.faces + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 8.0 + 0.0 + + + + + ${__jexl3("${protocol}"== "http",)} + false + true + + + + true + false + ${hostname} + ${port} + /daytrader/marketsummary + false + {"action":"updateMarketSummary"} + 20000 + open and close + 20000 + false + + + + + ${maxthinkingtime} + + + + + + ${__jexl3("${protocol}"== "https",)} + false + true + + + + true + true + ${hostname} + ${port} + /daytrader/marketsummary + false + {"action":"updateMarketSummary"} + 20000 + open and close + 20000 + false + + + + + ${maxthinkingtime} + + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 4.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/quote.faces + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + s:${__Random(0,${maximumsid},)} + = + true + quotes:symbols + + + false + quotes + = + true + quotes:submit2 + + + false + 1 + = + true + quotes_SUBMIT + + + false + 100 + = + true + quotes:quotes:0:quantity + + + false + 100 + = + true + quotes:quotes:1:quantity + + + false + 100 + = + true + quotes:quotes:2:quantity + + + false + 100 + = + true + quotes:quotes:3:quantity + + + false + 100 + = + true + quotes:quotes:4:quantity + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/quote.faces + POST + false + true + true + false + + HttpClient4 + + + + + + + DayTrader Quotes + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + false + tobuy + s:([0-9]+) + $1$ + 0 + 1 + all + + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + s:${tobuy} + = + true + quotes:symbols + + + false + ${__Random(1,200)} + = + true + quotes:quotes:0:quantity + + + false + buy + = + true + quotes:quotes:0:buy + + + false + 1 + = + true + quotes_SUBMIT + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/quote.faces + POST + false + true + true + false + + HttpClient4 + + + + + + + been submitted + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 4.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/portfolio.faces + GET + false + true + true + false + + HttpClient4 + + + + + + false + numHoldings + of Holdings: </b>([1-9][0-9]*)</td> + $1$ + 0 + 0 + all + + + + ${maxthinkingtime} + + + + + ${__jexl("${numHoldings}" != "0")} + false + true + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + portfolio:holdings:0:sell + = + true + portfolio:_idcl + + + false + 1 + = + true + portfolio_SUBMIT + + + false + s:0,s:1,s:2,s:3,s:4 + = + true + portfolio:symbols + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/portfolio.faces + POST + false + true + true + false + + HttpClient4 + + + + + + + been submitted + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 2.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/account.faces + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + uid:${logincounter} + = + true + updateProfile:uid + + + false + rnd${__threadNum}${logincounter} + = + true + updateProfile:fullname + + + false + xxx + = + true + updateProfile:password + + + false + rndAddress + = + true + updateProfile:address + + + false + xxx + = + true + updateProfile:cpassword + + + false + rndCC + = + true + updateProfile:ccn + + + false + rndEmail@email.com + = + true + updateProfile:email + + + false + 1 + = + true + updateProfile_SUBMIT + + + false + Update Profile + = + true + updateProfile:submit + + + false + s:0,s:1,s:2,s:3,s:4 + = + true + updateProfile:symbols + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/account.faces + POST + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 1.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/tradehome.faces + GET + false + true + true + false + + HttpClient4 + + + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + tradeHome:logoff + = + true + tradeHome:_idcl + + + false + s:0,s:1,s:2,s:3,s:4 + = + true + tradeHome:symbols + + + false + 1 + = + true + tradeHome_SUBMIT + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/tradehome.faces + POST + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + DayTrader Login + + Assertion.response_data + false + 2 + + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/register.faces + GET + false + true + true + false + + HttpClient4 + + + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + first:${__Random(0,999,)} last:${__Random(0,4999,)} + = + true + register:fullname + + + false + first:${__Random(0,999,)} last:${__Random(0,4999,)} + = + true + register:address + + + false + uid${logincounter}@${__Random(0,100,)}.com + = + true + register:email + + + false + ru:${logincounter}${__threadNum}:${__time(HMS)}${__Random(0,999,)} + = + true + register:uid + + + false + yyy + = + true + register:password + + + false + yyy + = + true + register:cpassword + + + false + 1000000 + = + true + register:money + + + false + 123-fake-ccnum-456 + = + true + register:ccn + + + false + 1 + = + true + register_SUBMIT + + + false + Register + = + true + register:submit + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/register.faces + POST + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + Registration operation succeeded + + Assertion.response_data + false + 2 + + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/tradehome.faces + GET + false + true + true + false + + HttpClient4 + + + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + tradeHome:logoff + = + true + tradeHome:_idcl + + + false + s:0,s:1,s:2,s:3,s:4 + = + true + tradeHome:symbols + + + false + 1 + = + true + tradeHome_SUBMIT + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/tradehome.faces + POST + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + DayTrader Login + + Assertion.response_data + false + 2 + + + + + + + loop + + + + false + + + false + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 4.0 + 0.0 + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/tradehome.faces + GET + false + true + true + false + + HttpClient4 + + + + + + + + + true + ${jsfViewState} + = + true + javax.faces.ViewState + + + false + tradeHome:logoff + = + true + tradeHome:_idcl + + + false + s:0,s:1,s:2,s:3,s:4 + = + true + tradeHome:symbols + + + false + 1 + = + true + tradeHome_SUBMIT + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/tradehome.faces + POST + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + DayTrader Login + + Assertion.response_data + false + 2 + + + + + + + loop + + + + false + + + false + + + + + + + false + jsfViewState + <input type="hidden" name="javax\.faces\.ViewState" id="j_id__v_0:javax\.faces\.ViewState:1" value="([^"]+)".*/> + $1$ + + 0 + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 70.0 + 0.0 + + + + + + + + true + uid:${logincounter} + = + true + uid + + + true + xxx + = + true + passwd + + + true + login + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + POST + false + true + true + false + + HttpClient4 + + + + + + + loop + + + + true + + + true + + + + + Welcome to DayTrader + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + + ${__jexl3("${protocol}"== "http",)} + false + true + + + + false + ${hostname} + ${port} + /daytrader/marketsummary + 20000 + 20000 + + + + + ${__jexl3("${protocol}"== "https",)} + false + true + + + + true + ${hostname} + ${port} + /daytrader/marketsummary + 20000 + 20000 + + + + + ${loop} + + + + 1 + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 36.0 + 0.0 + + + + + + + + true + quotes + = + true + action + + + true + s:${__Random(0,${maximumsid},)} + = + true + symbols + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + + DayTrader: Quotes and Trading + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 16.0 + 0.0 + + + + + + + + true + home + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 15.0 + 0.0 + + + + + + + + true + portfolio + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 10.0 + 0.0 + + + + + + + + true + account + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 8.0 + 0.0 + + + + + false + false + ${hostname} + ${port} + /daytrader/marketsummary + false + {"action":"updateMarketSummary"} + 20000 + use existing open connection + 20000 + false + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 4.0 + 0.0 + + + + + + + + true + quotes + = + true + action + + + true + s:${__Random(0,${maximumsid},tobuy)} + = + true + symbols + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + + + true + buy + = + true + action + + + true + s:${tobuy} + = + true + symbol + + + true + ${__Random(1,200)} + = + true + quantity + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + + has been submitted + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 4.0 + 0.0 + + + + + + + + true + portfolio + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + false + firstHoldingID + holdingID=([0-9]+) + $1$ + NotFound + 0 + all + + + + false + firstHoldingIDBool + holdingID=([0-9]+) + true + false + 1 + all + + + + ${maxthinkingtime} + + + + + ${firstHoldingIDBool} + false + true + + + + + + + true + sell + = + true + action + + + true + ${firstHoldingID} + = + true + holdingID + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + + has been submitted + + Assertion.response_data + false + 2 + + + + + ${maxthinkingtime} + + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 2.0 + 0.0 + + + + + + + + true + account + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + + + true + update_profile + = + true + action + + + true + uid:${logincounter} + = + true + userID + + + true + rnd${__threadNum}${logincounter} + = + true + fullname + + + true + xxx + = + true + password + + + true + rndAddress + = + true + address + + + true + xxx + = + true + cpassword + + + true + rndCC + = + true + creditcard + + + true + rndEmail@email.com + = + true + email + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 1.0 + 0.0 + + + + + + + + true + logout + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/register.jsp + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + + + true + register + = + true + action + + + true + first:${__Random(0,999,)} last:${__Random(0,4999,)} + = + true + Full Name + + + true + first:${__Random(0,999,)} last:${__Random(0,4999,)} + = + true + snail mail + + + true + uid${logincounter}@${__Random(0,100,)}.com + = + true + email + + + true + ru:${logincounter}${__threadNum}:${__time(HMS)}${__Random(0,999,)} + = + true + user id + + + true + yyy + = + true + passwd + + + true + yyy + = + true + confirm passwd + + + true + 1000000 + = + true + money + + + true + 123-fake-ccnum-456 + = + true + Credit Card Number + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + + + true + logout + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + loop + + + + false + + + false + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 4.0 + 0.0 + + + + + + + + true + logout + = + true + action + + + + ${hostname} + ${port} + ${protocol} + + /daytrader/app + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + DayTrader Login + + Assertion.response_data + false + 2 + + + + + + + loop + + + + false + + + false + + + + + + + 4000 + 6000 + + + + + 1 + true + 1 + + ThroughputController.percentThroughput + 20.0 + 0.0 + + + + + + + + true + s:${__Random(0,${maximumsid},)} + = + true + symbols + + + + ${hostname} + ${port} + ${protocol} + + daytrader/rest/quotes + POST + false + true + true + false + + + + + + + + 200 + + Assertion.response_code + false + 2 + + + + + ${maxthinkingtime} + + + + + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + true + false + false + false + false + false + 0 + true + true + true + true + + + daytrader8.aggregateReport.csv + + + + true + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + false + false + false + false + false + 0 + true + true + true + true + + + daytrader8.resultsTree.csv + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + true + false + false + false + false + false + 0 + true + true + true + true + + + daytrader7.resultsTable.csv + + + + + diff --git a/src/test/resources/test-applications/daytrader8/jmeter_files/daytrader_primitive.jmx b/src/test/resources/test-applications/daytrader8/jmeter_files/daytrader_primitive.jmx new file mode 100644 index 00000000..29ccdf4c --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/jmeter_files/daytrader_primitive.jmx @@ -0,0 +1,203 @@ + + + + + + false + false + + + + + + + + + false + -1 + + ${__P(THREADS, 50)} + 0 + 1355173676000 + 1355173676000 + true + continue + ${__P(DURATION, 180)} + + true + + + + + false + false + rfc2109 + + + + + + User-Agent + Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322) + + + Accept + image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */* + + + Accept-Language + en-us + + + + + + + + VIEWSTATE + + = + + + jsessionid + + = + + + minimumuid + ${__P(BOTUID,0)} + = + + + maximumuid + ${__P(TOPUID,14999)} + = + + + hostname + ${__P(HOST,)} + = + + + maxthinkingtime + 0 + = + + + maximumsid + ${__P(STOCKS,9999)} + = + + + url + ${__P(PRIMITIVE_URL,servlet/PingServlet)} + = + + + + + + true + -1 + + + + + + + ${hostname} + 9080 + http + + /daytrader/${url} + GET + false + true + true + false + + HttpClient4 + + + + + + ${maxthinkingtime} + + + + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + true + false + false + false + false + false + 0 + true + true + true + true + + + + + + + true + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + true + false + false + false + false + false + 0 + true + true + true + true + + + C:\jmeter\jmeter_script\report.csv + + + + + diff --git a/src/test/resources/test-applications/daytrader8/pom.xml b/src/test/resources/test-applications/daytrader8/pom.xml new file mode 100644 index 00000000..cd631847 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/pom.xml @@ -0,0 +1,104 @@ + + + 4.0.0 + io.openliberty.samples + io.openliberty.sample.daytrader8 + 1.0-SNAPSHOT + war + + UTF-8 + UTF-8 + 1.8 + 1.8 + + 10.14.2.0 + ${user.home}/.m2/repository/org/apache/derby/derby + + 9080 + 9443 + + + + javax + javaee-api + 8.0 + provided + + + taglibs + standard + 1.1.1 + compile + + + javax.xml.bind + jaxb-api + 2.3.0 + provided + + + + org.apache.derby + derby + ${version.derby} + test + + + + ${project.artifactId} + + + + io.openliberty.tools + liberty-maven-plugin + 3.3-M4 + + + ${testServerHttpPort} + ${testServerHttpsPort} + + + + + org.apache.maven.plugins + maven-dependency-plugin + 3.1.2 + + + copy-derby-dependency + package + + copy-dependencies + + + derby + ${project.build.directory}/liberty/wlp/usr/shared/resources/DerbyLibs/ + + + + + + maven-resources-plugin + 2.6 + + + copy-resources + package + + copy-resources + + + ${project.build.directory}/liberty/wlp/usr/shared/resources/data + + + resources/data + false + + + + + + + + + diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/README_DO_NOT_TOUCH_FILES.txt b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/README_DO_NOT_TOUCH_FILES.txt new file mode 100644 index 00000000..a4bc1452 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/README_DO_NOT_TOUCH_FILES.txt @@ -0,0 +1,9 @@ + +# ************************************************************************* +# *** DO NOT TOUCH FILES IN THIS DIRECTORY! *** +# *** FILES IN THIS DIRECTORY AND SUBDIRECTORIES CONSTITUTE A DERBY *** +# *** DATABASE, WHICH INCLUDES THE DATA (USER AND SYSTEM) AND THE *** +# *** FILES NECESSARY FOR DATABASE RECOVERY. *** +# *** EDITING, ADDING, OR DELETING ANY OF THESE FILES MAY CAUSE DATA *** +# *** CORRUPTION AND LEAVE THE DATABASE IN A NON-RECOVERABLE STATE. *** +# ************************************************************************* \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/log/README_DO_NOT_TOUCH_FILES.txt b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/log/README_DO_NOT_TOUCH_FILES.txt new file mode 100644 index 00000000..56df292f --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/log/README_DO_NOT_TOUCH_FILES.txt @@ -0,0 +1,8 @@ + +# ************************************************************************* +# *** DO NOT TOUCH FILES IN THIS DIRECTORY! *** +# *** FILES IN THIS DIRECTORY ARE USED BY THE DERBY DATABASE RECOVERY *** +# *** SYSTEM. EDITING, ADDING, OR DELETING FILES IN THIS DIRECTORY *** +# *** WILL CAUSE THE DERBY RECOVERY SYSTEM TO FAIL, LEADING TO *** +# *** NON-RECOVERABLE CORRUPT DATABASES. *** +# ************************************************************************* \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/log/log.ctrl b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/log/log.ctrl new file mode 100644 index 00000000..5ae5e491 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/log/log.ctrl differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/log/log286.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/log/log286.dat new file mode 100644 index 00000000..114bef65 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/log/log286.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/log/logmirror.ctrl b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/log/logmirror.ctrl new file mode 100644 index 00000000..5ae5e491 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/log/logmirror.ctrl differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/README_DO_NOT_TOUCH_FILES.txt b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/README_DO_NOT_TOUCH_FILES.txt new file mode 100644 index 00000000..2bdad061 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/README_DO_NOT_TOUCH_FILES.txt @@ -0,0 +1,8 @@ + +# ************************************************************************* +# *** DO NOT TOUCH FILES IN THIS DIRECTORY! *** +# *** FILES IN THIS DIRECTORY ARE USED BY THE DERBY DATABASE TO STORE *** +# *** USER AND SYSTEM DATA. EDITING, ADDING, OR DELETING FILES IN THIS *** +# *** DIRECTORY WILL CORRUPT THE ASSOCIATED DERBY DATABASE AND MAKE *** +# *** IT NON-RECOVERABLE. *** +# ************************************************************************* \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c10.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c10.dat new file mode 100644 index 00000000..ca061266 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c10.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c101.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c101.dat new file mode 100644 index 00000000..7c9fc8a0 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c101.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c111.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c111.dat new file mode 100644 index 00000000..8e4371b3 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c111.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c121.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c121.dat new file mode 100644 index 00000000..5f7789fe Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c121.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c130.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c130.dat new file mode 100644 index 00000000..f9de0051 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c130.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c141.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c141.dat new file mode 100644 index 00000000..2b9408a3 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c141.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c150.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c150.dat new file mode 100644 index 00000000..db2ff892 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c150.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c161.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c161.dat new file mode 100644 index 00000000..a2af9876 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c161.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c171.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c171.dat new file mode 100644 index 00000000..b3e1217b Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c171.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c180.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c180.dat new file mode 100644 index 00000000..e7b80ed0 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c180.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c191.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c191.dat new file mode 100644 index 00000000..5e31e3be Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c191.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c1a1.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c1a1.dat new file mode 100644 index 00000000..e578b73b Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c1a1.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c1b1.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c1b1.dat new file mode 100644 index 00000000..2e068140 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c1b1.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c1c0.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c1c0.dat new file mode 100644 index 00000000..c5b91e2c Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c1c0.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c1d1.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c1d1.dat new file mode 100644 index 00000000..451f02f4 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c1d1.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c1e0.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c1e0.dat new file mode 100644 index 00000000..761408d3 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c1e0.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c1f1.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c1f1.dat new file mode 100644 index 00000000..78d701f4 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c1f1.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c20.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c20.dat new file mode 100644 index 00000000..81d623f2 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c20.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c200.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c200.dat new file mode 100644 index 00000000..c3a7808d Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c200.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c211.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c211.dat new file mode 100644 index 00000000..54e15869 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c211.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c221.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c221.dat new file mode 100644 index 00000000..59900bc0 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c221.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c230.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c230.dat new file mode 100644 index 00000000..207264a3 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c230.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c241.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c241.dat new file mode 100644 index 00000000..4433404a Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c241.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c251.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c251.dat new file mode 100644 index 00000000..c6fab1e7 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c251.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c260.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c260.dat new file mode 100644 index 00000000..25f81fde Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c260.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c271.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c271.dat new file mode 100644 index 00000000..51cde573 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c271.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c281.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c281.dat new file mode 100644 index 00000000..cfed875d Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c281.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c290.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c290.dat new file mode 100644 index 00000000..a85589e5 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c290.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c2a1.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c2a1.dat new file mode 100644 index 00000000..8e2ed6af Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c2a1.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c2b1.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c2b1.dat new file mode 100644 index 00000000..2a296924 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c2b1.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c2c1.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c2c1.dat new file mode 100644 index 00000000..5511575f Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c2c1.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c2d0.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c2d0.dat new file mode 100644 index 00000000..c9063637 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c2d0.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c2e1.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c2e1.dat new file mode 100644 index 00000000..fccdbd67 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c2e1.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c2f0.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c2f0.dat new file mode 100644 index 00000000..d854b4b4 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c2f0.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c300.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c300.dat new file mode 100644 index 00000000..2053e010 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c300.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c31.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c31.dat new file mode 100644 index 00000000..ec081434 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c31.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c311.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c311.dat new file mode 100644 index 00000000..f60c260f Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c311.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c321.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c321.dat new file mode 100644 index 00000000..a9d74536 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c321.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c331.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c331.dat new file mode 100644 index 00000000..85ee72b3 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c331.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c340.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c340.dat new file mode 100644 index 00000000..d99b11a3 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c340.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c351.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c351.dat new file mode 100644 index 00000000..f822f4cb Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c351.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c361.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c361.dat new file mode 100644 index 00000000..b5c8f259 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c361.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c371.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c371.dat new file mode 100644 index 00000000..ad11f01b Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c371.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c380.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c380.dat new file mode 100644 index 00000000..26b6dd66 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c380.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c391.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c391.dat new file mode 100644 index 00000000..38ea5620 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c391.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c3a1.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c3a1.dat new file mode 100644 index 00000000..fe7a67b1 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c3a1.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c3b1.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c3b1.dat new file mode 100644 index 00000000..3a73f40c Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c3b1.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c3c0.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c3c0.dat new file mode 100644 index 00000000..4d061cf0 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c3c0.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c3d1.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c3d1.dat new file mode 100644 index 00000000..45c9fa24 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c3d1.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c3e1.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c3e1.dat new file mode 100644 index 00000000..48f53e68 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c3e1.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c3f1.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c3f1.dat new file mode 100644 index 00000000..08acdcee Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c3f1.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c400.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c400.dat new file mode 100644 index 00000000..a23e287b Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c400.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c41.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c41.dat new file mode 100644 index 00000000..6889bcb3 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c41.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c411.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c411.dat new file mode 100644 index 00000000..22d5ab93 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c411.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c421.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c421.dat new file mode 100644 index 00000000..c5274a22 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c421.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c430.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c430.dat new file mode 100644 index 00000000..55c948db Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c430.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c441.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c441.dat new file mode 100644 index 00000000..3948b2a3 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c441.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c451.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c451.dat new file mode 100644 index 00000000..fe1ab73e Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c451.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c461.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c461.dat new file mode 100644 index 00000000..e6d98541 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c461.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c470.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c470.dat new file mode 100644 index 00000000..c9f2eb1c Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c470.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c481.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c481.dat new file mode 100644 index 00000000..397b2917 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c481.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c490.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c490.dat new file mode 100644 index 00000000..63e4bc67 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c490.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c4a1.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c4a1.dat new file mode 100644 index 00000000..f0f0ecf8 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c4a1.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c4b0.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c4b0.dat new file mode 100644 index 00000000..a8fed1f8 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c4b0.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c4c1.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c4c1.dat new file mode 100644 index 00000000..6e1de5e6 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c4c1.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c4d0.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c4d0.dat new file mode 100644 index 00000000..f33c61a9 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c4d0.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c4e1.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c4e1.dat new file mode 100644 index 00000000..02b55f6d Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c4e1.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c4f1.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c4f1.dat new file mode 100644 index 00000000..5be3e313 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c4f1.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c51.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c51.dat new file mode 100644 index 00000000..0c3b53eb Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c51.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c60.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c60.dat new file mode 100644 index 00000000..4896921f Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c60.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c71.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c71.dat new file mode 100644 index 00000000..9df02c15 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c71.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c720.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c720.dat new file mode 100644 index 00000000..c3794777 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c720.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c731.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c731.dat new file mode 100644 index 00000000..756b908f Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c731.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c740.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c740.dat new file mode 100644 index 00000000..3f2ad6e6 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c740.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c751.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c751.dat new file mode 100644 index 00000000..fe2bb77c Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c751.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c760.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c760.dat new file mode 100644 index 00000000..98b96abf Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c760.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c771.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c771.dat new file mode 100644 index 00000000..789d9ae4 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c771.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c780.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c780.dat new file mode 100644 index 00000000..c24c67e9 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c780.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c791.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c791.dat new file mode 100644 index 00000000..ff867857 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c791.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c7a0.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c7a0.dat new file mode 100644 index 00000000..0593ae3e Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c7a0.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c7b1.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c7b1.dat new file mode 100644 index 00000000..7354db2e Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c7b1.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c7c0.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c7c0.dat new file mode 100644 index 00000000..907f038f Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c7c0.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c7d1.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c7d1.dat new file mode 100644 index 00000000..40100e61 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c7d1.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c7e1.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c7e1.dat new file mode 100644 index 00000000..85a139e4 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c7e1.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c7f1.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c7f1.dat new file mode 100644 index 00000000..2e558d6e Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c7f1.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c801.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c801.dat new file mode 100644 index 00000000..eb06862f Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c801.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c81.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c81.dat new file mode 100644 index 00000000..ab21c74c Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c81.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c811.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c811.dat new file mode 100644 index 00000000..e502c064 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c811.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c821.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c821.dat new file mode 100644 index 00000000..f426d4f7 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c821.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c90.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c90.dat new file mode 100644 index 00000000..72619ed7 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/c90.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/ca1.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/ca1.dat new file mode 100644 index 00000000..981a2c58 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/ca1.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/cb1.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/cb1.dat new file mode 100644 index 00000000..a4fb8f44 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/cb1.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/cc0.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/cc0.dat new file mode 100644 index 00000000..d6b3b0f4 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/cc0.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/cd1.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/cd1.dat new file mode 100644 index 00000000..3002ab5d Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/cd1.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/ce1.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/ce1.dat new file mode 100644 index 00000000..24edcc74 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/ce1.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/cf0.dat b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/cf0.dat new file mode 100644 index 00000000..b943f01d Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/seg0/cf0.dat differ diff --git a/src/test/resources/test-applications/daytrader8/resources/data/tradedb/service.properties b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/service.properties new file mode 100644 index 00000000..420cab1f --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/resources/data/tradedb/service.properties @@ -0,0 +1,23 @@ +#/Users/jdmcclur/git/sample.daytrader8/target/liberty/wlp/usr/shared/resources/data/tradedb +# ******************************************************************** +# *** Please do NOT edit this file. *** +# *** CHANGING THE CONTENT OF THIS FILE MAY CAUSE DATA CORRUPTION. *** +# ******************************************************************** +#Fri Jan 11 09:46:30 CST 2019 +SysschemasIndex2Identifier=225 +SyscolumnsIdentifier=144 +SysconglomeratesIndex1Identifier=49 +SysconglomeratesIdentifier=32 +SyscolumnsIndex2Identifier=177 +SysschemasIndex1Identifier=209 +SysconglomeratesIndex3Identifier=81 +SystablesIndex2Identifier=129 +SyscolumnsIndex1Identifier=161 +derby.serviceProtocol=org.apache.derby.database.Database +SysschemasIdentifier=192 +derby.storage.propertiesId=16 +SysconglomeratesIndex2Identifier=65 +derby.serviceLocale=en_US +SystablesIdentifier=96 +SystablesIndex1Identifier=113 +#--- last line, don't put anything after this line --- diff --git a/src/test/resources/test-applications/daytrader8/scripts/buildAll.sh b/src/test/resources/test-applications/daytrader8/scripts/buildAll.sh new file mode 100755 index 00000000..f57b6890 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/scripts/buildAll.sh @@ -0,0 +1,20 @@ +cd "$(dirname "$0")" +cd .. + +mvn clean package +cp target/io.openliberty.sample.daytrader8.war scripts/io.openliberty.sample.daytrader8.war + +cd scripts +./switchToWF.sh +cd .. +mvn clean package +cp target/io.openliberty.sample.daytrader8.war scripts/io.openliberty.sample.daytrader8-WF.war +cd scripts +./switchFromWF.sh + +./switchToPayara.sh +cd .. +mvn clean package +cp target/io.openliberty.sample.daytrader8.war scripts/io.openliberty.sample.daytrader8-Payara.war +cd scripts +./switchFromPayara.sh diff --git a/src/test/resources/test-applications/daytrader8/scripts/switchFromPayara.sh b/src/test/resources/test-applications/daytrader8/scripts/switchFromPayara.sh new file mode 100755 index 00000000..870c5695 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/scripts/switchFromPayara.sh @@ -0,0 +1,16 @@ +#!/bin/bash +cd "$(dirname "$0")" + +transform () { + sed -i.bak "s#@ActivationConfigProperty(propertyName = \"destination\", propertyValue = \"T#//@ActivationConfigProperty(propertyName = \"destination\", propertyValue = \"T#" $1 + sed -i.bak "s#//@ActivationConfigProperty(propertyName = \"destination\", propertyValue = \"j#@ActivationConfigProperty(propertyName = \"destination\", propertyValue = \"j#" $1 + rm $1.bak +} + +transform "../src/main/java/com/ibm/websphere/samples/daytrader/mdb/DTBroker3MDB.java" +transform "../src/main/java/com/ibm/websphere/samples/daytrader/mdb/DTStreamer3MDB.java" + +mv ../src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2MDBQueue.java_bak ../src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2MDBQueue.java +mv ../src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2MDBTopic.java_bak ../src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2MDBTopic.java + + diff --git a/src/test/resources/test-applications/daytrader8/scripts/switchFromWF.sh b/src/test/resources/test-applications/daytrader8/scripts/switchFromWF.sh new file mode 100755 index 00000000..4215abe3 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/scripts/switchFromWF.sh @@ -0,0 +1,17 @@ +#!/bin/bash +cd "$(dirname "$0")" + +transform () { + sed -i.bak "s#@Resource(name = \"java#//@Resource(name = \"java#" $1 + sed -i.bak "s#@Resource(lookup = \"java#//@Resource(lookup = \"java#" $1 + sed -i.bak "s#//@Resource(name = \"jm#@Resource(name = \"jm#" $1 + sed -i.bak "s#//@Resource(lookup = \"jm#@Resource(lookup = \"jm#" $1 + sed -i.bak "s#//@Resource(lookup = \"jd#@Resource(lookup = \"jd#" $1 + rm $1.bak +} + +transform "../src/main/java/com/ibm/websphere/samples/daytrader/impl/ejb3/TradeSLSBBean.java" +transform "../src/main/java/com/ibm/websphere/samples/daytrader/impl/direct/TradeDirect.java" +transform "../src/main/java/com/ibm/websphere/samples/daytrader/impl/direct/TradeDirectDBUtils.java" + + diff --git a/src/test/resources/test-applications/daytrader8/scripts/switchToPayara.sh b/src/test/resources/test-applications/daytrader8/scripts/switchToPayara.sh new file mode 100755 index 00000000..c8b7f34b --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/scripts/switchToPayara.sh @@ -0,0 +1,16 @@ +#!/bin/bash +cd "$(dirname "$0")" + +transform () { + sed -i.bak "s#//@ActivationConfigProperty(propertyName = \"destination\", propertyValue = \"T#@ActivationConfigProperty(propertyName = \"destination\", propertyValue = \"T#" $1 + sed -i.bak "s#@ActivationConfigProperty(propertyName = \"destination\", propertyValue = \"j#//@ActivationConfigProperty(propertyName = \"destination\", propertyValue = \"j#" $1 + rm $1.bak +} + +transform "../src/main/java/com/ibm/websphere/samples/daytrader/mdb/DTBroker3MDB.java" +transform "../src/main/java/com/ibm/websphere/samples/daytrader/mdb/DTStreamer3MDB.java" + +mv ../src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2MDBQueue.java ../src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2MDBQueue.java_bak +mv ../src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2MDBTopic.java ../src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2MDBTopic.java_bak + + diff --git a/src/test/resources/test-applications/daytrader8/scripts/switchToWF.sh b/src/test/resources/test-applications/daytrader8/scripts/switchToWF.sh new file mode 100755 index 00000000..79415a57 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/scripts/switchToWF.sh @@ -0,0 +1,17 @@ +#!/bin/bash +cd "$(dirname "$0")" + +transform () { + sed -i.bak "s#//@Resource(name = \"java#@Resource(name = \"java#" $1 + sed -i.bak "s#//@Resource(lookup = \"java#@Resource(lookup = \"java#" $1 + sed -i.bak "s#@Resource(name = \"jm#//@Resource(name = \"jm#" $1 + sed -i.bak "s#@Resource(lookup = \"jm#//@Resource(lookup = \"jm#" $1 + sed -i.bak "s#@Resource(lookup = \"jd#//@Resource(lookup = \"jd#" $1 + rm $1.bak +} + +transform "../src/main/java/com/ibm/websphere/samples/daytrader/impl/ejb3/TradeSLSBBean.java" +transform "../src/main/java/com/ibm/websphere/samples/daytrader/impl/direct/TradeDirect.java" +transform "../src/main/java/com/ibm/websphere/samples/daytrader/impl/direct/TradeDirectDBUtils.java" + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/META-INF/DEPENDENCIES b/src/test/resources/test-applications/daytrader8/src/main/java/META-INF/DEPENDENCIES new file mode 100644 index 00000000..cb8878a9 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/META-INF/DEPENDENCIES @@ -0,0 +1,15 @@ +// ------------------------------------------------------------------ +// Transitive dependencies of this project determined from the +// maven pom organized by organization. +// ------------------------------------------------------------------ + +DayTrader :: Web Application + + +From: 'an unknown organization' + - Unnamed - taglibs:standard:jar:1.1.1 taglibs:standard:jar:1.1.1 + + + + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/META-INF/LICENSE b/src/test/resources/test-applications/daytrader8/src/main/java/META-INF/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/META-INF/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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 + + http://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. diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/build.properties b/src/test/resources/test-applications/daytrader8/src/main/java/build.properties new file mode 100644 index 00000000..de47f1c7 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/build.properties @@ -0,0 +1,17 @@ +## +## (C) Copyright IBM Corporation 2015. +## +## 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 +## +## http://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. +## + +ejb_version=${pom.version} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/beans/MarketSummaryDataBean.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/beans/MarketSummaryDataBean.java new file mode 100644 index 00000000..b899509f --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/beans/MarketSummaryDataBean.java @@ -0,0 +1,287 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.beans; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.Iterator; + +import javax.json.Json; +import javax.json.JsonObject; +import javax.json.JsonObjectBuilder; + +import com.ibm.websphere.samples.daytrader.entities.QuoteDataBean; +import com.ibm.websphere.samples.daytrader.util.FinancialUtils; +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; + +public class MarketSummaryDataBean implements Serializable { + + private static final long serialVersionUID = 650652242288745600L; + private BigDecimal TSIA; /* Trade Stock Index Average */ + private BigDecimal openTSIA; /* Trade Stock Index Average at the open */ + private double volume; /* volume of shares traded */ + private Collection topGainers; /* + * Collection of top gaining + * stocks + */ + private Collection topLosers; /* + * Collection of top losing + * stocks + */ + // FUTURE private Collection topVolume; /* Collection of top stocks by + // volume */ + private Date summaryDate; /* Date this summary was taken */ + + // cache the gainPercent once computed for this bean + private BigDecimal gainPercent = null; + + public MarketSummaryDataBean() { + } + + public MarketSummaryDataBean(BigDecimal TSIA, BigDecimal openTSIA, double volume, Collection topGainers, Collection topLosers// , Collection topVolume + ) { + setTSIA(TSIA); + setOpenTSIA(openTSIA); + setVolume(volume); + setTopGainers(topGainers); + setTopLosers(topLosers); + setSummaryDate(new java.sql.Date(System.currentTimeMillis())); + gainPercent = FinancialUtils.computeGainPercent(getTSIA(), getOpenTSIA()); + + } + + public static MarketSummaryDataBean getRandomInstance() { + Collection gain = new ArrayList(); + Collection lose = new ArrayList(); + + for (int ii = 0; ii < 5; ii++) { + QuoteDataBean quote1 = QuoteDataBean.getRandomInstance(); + QuoteDataBean quote2 = QuoteDataBean.getRandomInstance(); + + gain.add(quote1); + lose.add(quote2); + } + + return new MarketSummaryDataBean(TradeConfig.rndBigDecimal(1000000.0f), TradeConfig.rndBigDecimal(1000000.0f), TradeConfig.rndQuantity(), gain, lose); + } + + @Override + public String toString() { + String ret = "\n\tMarket Summary at: " + getSummaryDate() + "\n\t\t TSIA:" + getTSIA() + "\n\t\t openTSIA:" + getOpenTSIA() + + "\n\t\t gain:" + getGainPercent() + "\n\t\t volume:" + getVolume(); + + if ((getTopGainers() == null) || (getTopLosers() == null)) { + return ret; + } + ret += "\n\t\t Current Top Gainers:"; + Iterator it = getTopGainers().iterator(); + while (it.hasNext()) { + QuoteDataBean quoteData = it.next(); + ret += ("\n\t\t\t" + quoteData.toString()); + } + ret += "\n\t\t Current Top Losers:"; + it = getTopLosers().iterator(); + while (it.hasNext()) { + QuoteDataBean quoteData = it.next(); + ret += ("\n\t\t\t" + quoteData.toString()); + } + return ret; + } + + public String toHTML() { + String ret = "
Market Summary at: " + getSummaryDate() + "
  • TSIA:" + getTSIA() + "
  • " + "
  • openTSIA:" + getOpenTSIA() + "
  • " + + "
  • volume:" + getVolume() + "
  • "; + if ((getTopGainers() == null) || (getTopLosers() == null)) { + return ret; + } + ret += "
    Current Top Gainers:"; + Iterator it = getTopGainers().iterator(); + + while (it.hasNext()) { + QuoteDataBean quoteData = it.next(); + ret += ("
  • " + quoteData.toString() + "
  • "); + } + ret += "
    Current Top Losers:"; + it = getTopLosers().iterator(); + while (it.hasNext()) { + QuoteDataBean quoteData = it.next(); + ret += ("
  • " + quoteData.toString() + "
  • "); + } + return ret; + } + + public JsonObject toJSON() { + + JsonObjectBuilder jObjectBuilder = Json.createObjectBuilder(); + + int i = 1; + for (Iterator iterator = topGainers.iterator(); iterator.hasNext();) { + QuoteDataBean quote = iterator.next(); + + jObjectBuilder.add("gainer" + i + "_stock",quote.getSymbol()); + jObjectBuilder.add("gainer" + i + "_price","$" + quote.getPrice()); + jObjectBuilder.add("gainer" + i + "_change",quote.getChange()); + i++; + } + + i = 1; + for (Iterator iterator = topLosers.iterator(); iterator.hasNext();) { + QuoteDataBean quote = iterator.next(); + + jObjectBuilder.add("loser" + i + "_stock",quote.getSymbol()); + jObjectBuilder.add("loser" + i + "_price","$" + quote.getPrice()); + jObjectBuilder.add("loser" + i + "_change",quote.getChange()); + i++; + } + + jObjectBuilder.add("tsia", TSIA); + jObjectBuilder.add("volume",volume); + jObjectBuilder.add("date", summaryDate.toString()); + + return jObjectBuilder.build(); + + } + + public void print() { + Log.log(this.toString()); + } + + public BigDecimal getGainPercent() { + if (gainPercent == null) { + gainPercent = FinancialUtils.computeGainPercent(getTSIA(), getOpenTSIA()); + } + return gainPercent; + } + + /** + * Gets the tSIA + * + * @return Returns a BigDecimal + */ + public BigDecimal getTSIA() { + return TSIA; + } + + /** + * Sets the tSIA + * + * @param tSIA + * The tSIA to set + */ + public void setTSIA(BigDecimal tSIA) { + TSIA = tSIA; + } + + /** + * Gets the openTSIA + * + * @return Returns a BigDecimal + */ + public BigDecimal getOpenTSIA() { + return openTSIA; + } + + /** + * Sets the openTSIA + * + * @param openTSIA + * The openTSIA to set + */ + public void setOpenTSIA(BigDecimal openTSIA) { + this.openTSIA = openTSIA; + } + + /** + * Gets the volume + * + * @return Returns a BigDecimal + */ + public double getVolume() { + return volume; + } + + /** + * Sets the volume + * + * @param volume + * The volume to set + */ + public void setVolume(double volume) { + this.volume = volume; + } + + /** + * Gets the topGainers + * + * @return Returns a Collection + */ + public Collection getTopGainers() { + return topGainers; + } + + /** + * Sets the topGainers + * + * @param topGainers + * The topGainers to set + */ + public void setTopGainers(Collection topGainers) { + this.topGainers = topGainers; + } + + /** + * Gets the topLosers + * + * @return Returns a Collection + */ + public Collection getTopLosers() { + return topLosers; + } + + /** + * Sets the topLosers + * + * @param topLosers + * The topLosers to set + */ + public void setTopLosers(Collection topLosers) { + this.topLosers = topLosers; + } + + /** + * Gets the summaryDate + * + * @return Returns a Date + */ + public Date getSummaryDate() { + return summaryDate; + } + + /** + * Sets the summaryDate + * + * @param summaryDate + * The summaryDate to set + */ + public void setSummaryDate(Date summaryDate) { + this.summaryDate = summaryDate; + } + +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/beans/RunStatsDataBean.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/beans/RunStatsDataBean.java new file mode 100644 index 00000000..1016b6cf --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/beans/RunStatsDataBean.java @@ -0,0 +1,294 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.beans; + +import java.io.Serializable; + +public class RunStatsDataBean implements Serializable { + private static final long serialVersionUID = 4017778674103242167L; + + // Constructors + public RunStatsDataBean() { + } + + // count of trade users in the database (users w/ userID like 'uid:%') + private int tradeUserCount; + // count of trade stocks in the database (stocks w/ symbol like 's:%') + private int tradeStockCount; + + // count of new registered users in this run (users w/ userID like 'ru:%') + // -- random user + private int newUserCount; + + // sum of logins by trade users + private int sumLoginCount; + // sum of logouts by trade users + private int sumLogoutCount; + + // count of holdings of trade users + private int holdingCount; + + // count of orders of trade users + private int orderCount; + // count of buy orders of trade users + private int buyOrderCount; + // count of sell orders of trade users + private int sellOrderCount; + // count of cancelled orders of trade users + private int cancelledOrderCount; + // count of open orders of trade users + private int openOrderCount; + // count of orders deleted during this trade Reset + private int deletedOrderCount; + + @Override + public String toString() { + return "\n\tRunStatsData for reset at " + new java.util.Date() + "\n\t\t tradeUserCount: " + getTradeUserCount() + "\n\t\t newUserCount: " + + getNewUserCount() + "\n\t\t sumLoginCount: " + getSumLoginCount() + "\n\t\t sumLogoutCount: " + getSumLogoutCount() + + "\n\t\t holdingCount: " + getHoldingCount() + "\n\t\t orderCount: " + getOrderCount() + "\n\t\t buyOrderCount: " + + getBuyOrderCount() + "\n\t\t sellOrderCount: " + getSellOrderCount() + "\n\t\t cancelledOrderCount: " + getCancelledOrderCount() + + "\n\t\t openOrderCount: " + getOpenOrderCount() + "\n\t\t deletedOrderCount: " + getDeletedOrderCount(); + } + + /** + * Gets the tradeUserCount + * + * @return Returns a int + */ + public int getTradeUserCount() { + return tradeUserCount; + } + + /** + * Sets the tradeUserCount + * + * @param tradeUserCount + * The tradeUserCount to set + */ + public void setTradeUserCount(int tradeUserCount) { + this.tradeUserCount = tradeUserCount; + } + + /** + * Gets the newUserCount + * + * @return Returns a int + */ + public int getNewUserCount() { + return newUserCount; + } + + /** + * Sets the newUserCount + * + * @param newUserCount + * The newUserCount to set + */ + public void setNewUserCount(int newUserCount) { + this.newUserCount = newUserCount; + } + + /** + * Gets the sumLoginCount + * + * @return Returns a int + */ + public int getSumLoginCount() { + return sumLoginCount; + } + + /** + * Sets the sumLoginCount + * + * @param sumLoginCount + * The sumLoginCount to set + */ + public void setSumLoginCount(int sumLoginCount) { + this.sumLoginCount = sumLoginCount; + } + + /** + * Gets the sumLogoutCount + * + * @return Returns a int + */ + public int getSumLogoutCount() { + return sumLogoutCount; + } + + /** + * Sets the sumLogoutCount + * + * @param sumLogoutCount + * The sumLogoutCount to set + */ + public void setSumLogoutCount(int sumLogoutCount) { + this.sumLogoutCount = sumLogoutCount; + } + + /** + * Gets the holdingCount + * + * @return Returns a int + */ + public int getHoldingCount() { + return holdingCount; + } + + /** + * Sets the holdingCount + * + * @param holdingCount + * The holdingCount to set + */ + public void setHoldingCount(int holdingCount) { + this.holdingCount = holdingCount; + } + + /** + * Gets the buyOrderCount + * + * @return Returns a int + */ + public int getBuyOrderCount() { + return buyOrderCount; + } + + /** + * Sets the buyOrderCount + * + * @param buyOrderCount + * The buyOrderCount to set + */ + public void setBuyOrderCount(int buyOrderCount) { + this.buyOrderCount = buyOrderCount; + } + + /** + * Gets the sellOrderCount + * + * @return Returns a int + */ + public int getSellOrderCount() { + return sellOrderCount; + } + + /** + * Sets the sellOrderCount + * + * @param sellOrderCount + * The sellOrderCount to set + */ + public void setSellOrderCount(int sellOrderCount) { + this.sellOrderCount = sellOrderCount; + } + + /** + * Gets the cancelledOrderCount + * + * @return Returns a int + */ + public int getCancelledOrderCount() { + return cancelledOrderCount; + } + + /** + * Sets the cancelledOrderCount + * + * @param cancelledOrderCount + * The cancelledOrderCount to set + */ + public void setCancelledOrderCount(int cancelledOrderCount) { + this.cancelledOrderCount = cancelledOrderCount; + } + + /** + * Gets the openOrderCount + * + * @return Returns a int + */ + public int getOpenOrderCount() { + return openOrderCount; + } + + /** + * Sets the openOrderCount + * + * @param openOrderCount + * The openOrderCount to set + */ + public void setOpenOrderCount(int openOrderCount) { + this.openOrderCount = openOrderCount; + } + + /** + * Gets the deletedOrderCount + * + * @return Returns a int + */ + public int getDeletedOrderCount() { + return deletedOrderCount; + } + + /** + * Sets the deletedOrderCount + * + * @param deletedOrderCount + * The deletedOrderCount to set + */ + public void setDeletedOrderCount(int deletedOrderCount) { + this.deletedOrderCount = deletedOrderCount; + } + + /** + * Gets the orderCount + * + * @return Returns a int + */ + public int getOrderCount() { + return orderCount; + } + + /** + * Sets the orderCount + * + * @param orderCount + * The orderCount to set + */ + public void setOrderCount(int orderCount) { + this.orderCount = orderCount; + } + + /** + * Gets the tradeStockCount + * + * @return Returns a int + */ + public int getTradeStockCount() { + return tradeStockCount; + } + + /** + * Sets the tradeStockCount + * + * @param tradeStockCount + * The tradeStockCount to set + */ + public void setTradeStockCount(int tradeStockCount) { + this.tradeStockCount = tradeStockCount; + } + +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/entities/AccountDataBean.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/entities/AccountDataBean.java new file mode 100644 index 00000000..7248dfe9 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/entities/AccountDataBean.java @@ -0,0 +1,286 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.entities; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.sql.Timestamp; +import java.util.Collection; +import java.util.Date; + +import javax.ejb.EJBException; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToMany; +import javax.persistence.OneToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.Transient; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.PastOrPresent; +import javax.validation.constraints.PositiveOrZero; + +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; + +@Entity(name = "accountejb") +@Table(name = "accountejb") +public class AccountDataBean implements Serializable { + + private static final long serialVersionUID = 8437841265136840545L; + + /* Accessor methods for persistent fields */ + @TableGenerator(name = "accountIdGen", table = "KEYGENEJB", pkColumnName = "KEYNAME", valueColumnName = "KEYVAL", pkColumnValue = "account", allocationSize = 1000) + @Id + @GeneratedValue(strategy = GenerationType.TABLE, generator = "accountIdGen") + @Column(name = "ACCOUNTID", nullable = false) + private Integer accountID; /* accountID */ + + @NotNull + @PositiveOrZero + @Column(name = "LOGINCOUNT", nullable = false) + private int loginCount; /* loginCount */ + + @NotNull + @PositiveOrZero + @Column(name = "LOGOUTCOUNT", nullable = false) + private int logoutCount; /* logoutCount */ + + @Column(name = "LASTLOGIN") + @Temporal(TemporalType.TIMESTAMP) + @PastOrPresent + private Date lastLogin; /* lastLogin Date */ + + @Column(name = "CREATIONDATE") + @Temporal(TemporalType.TIMESTAMP) + @PastOrPresent + private Date creationDate; /* creationDate */ + + @Column(name = "BALANCE") + private BigDecimal balance; /* balance */ + + @Column(name = "OPENBALANCE") + private BigDecimal openBalance; /* open balance */ + + @OneToMany(mappedBy = "account", fetch = FetchType.LAZY) + private Collection orders; + + @OneToMany(mappedBy = "account", fetch = FetchType.LAZY) + private Collection holdings; + + @OneToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "PROFILE_USERID") + private AccountProfileDataBean profile; + + /* + * Accessor methods for relationship fields are only included for the + * AccountProfile profileID + */ + @Transient + private String profileID; + + public AccountDataBean() { + } + + public AccountDataBean(Integer accountID, int loginCount, int logoutCount, Date lastLogin, Date creationDate, BigDecimal balance, BigDecimal openBalance, + String profileID) { + setAccountID(accountID); + setLoginCount(loginCount); + setLogoutCount(logoutCount); + setLastLogin(lastLogin); + setCreationDate(creationDate); + setBalance(balance); + setOpenBalance(openBalance); + setProfileID(profileID); + } + + public AccountDataBean(int loginCount, int logoutCount, Date lastLogin, Date creationDate, BigDecimal balance, BigDecimal openBalance, String profileID) { + setLoginCount(loginCount); + setLogoutCount(logoutCount); + setLastLogin(lastLogin); + setCreationDate(creationDate); + setBalance(balance); + setOpenBalance(openBalance); + setProfileID(profileID); + } + + public static AccountDataBean getRandomInstance() { + return new AccountDataBean(new Integer(TradeConfig.rndInt(100000)), // accountID + TradeConfig.rndInt(10000), // loginCount + TradeConfig.rndInt(10000), // logoutCount + new java.util.Date(), // lastLogin + new java.util.Date(TradeConfig.rndInt(Integer.MAX_VALUE)), // creationDate + TradeConfig.rndBigDecimal(1000000.0f), // balance + TradeConfig.rndBigDecimal(1000000.0f), // openBalance + TradeConfig.rndUserID() // profileID + ); + } + + @Override + public String toString() { + return "\n\tAccount Data for account: " + getAccountID() + "\n\t\t loginCount:" + getLoginCount() + "\n\t\t logoutCount:" + getLogoutCount() + + "\n\t\t lastLogin:" + getLastLogin() + "\n\t\t creationDate:" + getCreationDate() + "\n\t\t balance:" + getBalance() + + "\n\t\t openBalance:" + getOpenBalance() + "\n\t\t profileID:" + getProfileID(); + } + + public String toHTML() { + return "
    Account Data for account: " + getAccountID() + "" + "
  • loginCount:" + getLoginCount() + "
  • " + "
  • logoutCount:" + + getLogoutCount() + "
  • " + "
  • lastLogin:" + getLastLogin() + "
  • " + "
  • creationDate:" + getCreationDate() + "
  • " + + "
  • balance:" + getBalance() + "
  • " + "
  • openBalance:" + getOpenBalance() + "
  • " + "
  • profileID:" + getProfileID() + + "
  • "; + } + + public void print() { + Log.log(this.toString()); + } + + public Integer getAccountID() { + return accountID; + } + + public void setAccountID(Integer accountID) { + this.accountID = accountID; + } + + public int getLoginCount() { + return loginCount; + } + + public void setLoginCount(int loginCount) { + this.loginCount = loginCount; + } + + public int getLogoutCount() { + return logoutCount; + } + + public void setLogoutCount(int logoutCount) { + this.logoutCount = logoutCount; + } + + public Date getLastLogin() { + return lastLogin; + } + + public void setLastLogin(Date lastLogin) { + this.lastLogin = lastLogin; + } + + public Date getCreationDate() { + return creationDate; + } + + public void setCreationDate(Date creationDate) { + this.creationDate = creationDate; + } + + public BigDecimal getBalance() { + return balance; + } + + public void setBalance(BigDecimal balance) { + this.balance = balance; + } + + public BigDecimal getOpenBalance() { + return openBalance; + } + + public void setOpenBalance(BigDecimal openBalance) { + this.openBalance = openBalance; + } + + public String getProfileID() { + return profileID; + } + + public void setProfileID(String profileID) { + this.profileID = profileID; + } + + /* + * Disabled for D185273 public String getUserID() { return getProfileID(); } + */ + + public Collection getOrders() { + return orders; + } + + public void setOrders(Collection orders) { + this.orders = orders; + } + + public Collection getHoldings() { + return holdings; + } + + public void setHoldings(Collection holdings) { + this.holdings = holdings; + } + + public AccountProfileDataBean getProfile() { + return profile; + } + + public void setProfile(AccountProfileDataBean profile) { + this.profile = profile; + } + + public void login(String password) { + AccountProfileDataBean profile = getProfile(); + if ((profile == null) || (profile.getPassword().equals(password) == false)) { + String error = "AccountBean:Login failure for account: " + getAccountID() + + ((profile == null) ? "null AccountProfile" : "\n\tIncorrect password-->" + profile.getUserID() + ":" + profile.getPassword()); + throw new EJBException(error); + } + + setLastLogin(new Timestamp(System.currentTimeMillis())); + setLoginCount(getLoginCount() + 1); + } + + public void logout() { + setLogoutCount(getLogoutCount() + 1); + } + + @Override + public int hashCode() { + int hash = 0; + hash += (this.accountID != null ? this.accountID.hashCode() : 0); + return hash; + } + + @Override + public boolean equals(Object object) { + + if (!(object instanceof AccountDataBean)) { + return false; + } + AccountDataBean other = (AccountDataBean) object; + + if (this.accountID != other.accountID && (this.accountID == null || !this.accountID.equals(other.accountID))) { + return false; + } + + return true; + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/entities/AccountProfileDataBean.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/entities/AccountProfileDataBean.java new file mode 100644 index 00000000..24e8ad81 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/entities/AccountProfileDataBean.java @@ -0,0 +1,184 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.entities; + +//import java.sql.Timestamp; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.OneToOne; +import javax.persistence.Table; +import javax.validation.constraints.Email; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; + +@Entity(name = "accountprofileejb") +@Table(name = "accountprofileejb") +public class AccountProfileDataBean implements java.io.Serializable { + + /* Accessor methods for persistent fields */ + + private static final long serialVersionUID = 2794584136675420624L; + + @Id + @NotNull + @Column(name = "USERID", nullable = false) + private String userID; /* userID */ + + @Column(name = "PASSWD") + @NotBlank + private String passwd; /* password */ + + @Column(name = "FULLNAME") + @NotBlank + private String fullName; /* fullName */ + + @Column(name = "ADDRESS") + @NotBlank + private String address; /* address */ + + @Column(name = "EMAIL") + @Email(message = "Email should be valid") + private String email; /* email */ + + @Column(name = "CREDITCARD") + @NotBlank + private String creditCard; /* creditCard */ + + @OneToOne(mappedBy = "profile", fetch = FetchType.LAZY) + private AccountDataBean account; + + public AccountProfileDataBean() { + } + + public AccountProfileDataBean(String userID, String password, String fullName, String address, String email, String creditCard) { + setUserID(userID); + setPassword(password); + setFullName(fullName); + setAddress(address); + setEmail(email); + setCreditCard(creditCard); + } + + public static AccountProfileDataBean getRandomInstance() { + return new AccountProfileDataBean(TradeConfig.rndUserID(), // userID + TradeConfig.rndUserID(), // passwd + TradeConfig.rndFullName(), // fullname + TradeConfig.rndAddress(), // address + TradeConfig.rndEmail(TradeConfig.rndUserID()), // email + TradeConfig.rndCreditCard() // creditCard + ); + } + + @Override + public String toString() { + return "\n\tAccount Profile Data for userID:" + getUserID() + "\n\t\t passwd:" + getPassword() + "\n\t\t fullName:" + getFullName() + + "\n\t\t address:" + getAddress() + "\n\t\t email:" + getEmail() + "\n\t\t creditCard:" + getCreditCard(); + } + + public String toHTML() { + return "
    Account Profile Data for userID: " + getUserID() + "" + "
  • passwd:" + getPassword() + "
  • " + "
  • fullName:" + + getFullName() + "
  • " + "
  • address:" + getAddress() + "
  • " + "
  • email:" + getEmail() + "
  • " + "
  • creditCard:" + + getCreditCard() + "
  • "; + } + + public void print() { + Log.log(this.toString()); + } + + public String getUserID() { + return userID; + } + + public void setUserID(String userID) { + this.userID = userID; + } + + public String getPassword() { + return passwd; + } + + public void setPassword(String password) { + this.passwd = password; + } + + public String getFullName() { + return fullName; + } + + public void setFullName(String fullName) { + this.fullName = fullName; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getCreditCard() { + return creditCard; + } + + public void setCreditCard(String creditCard) { + this.creditCard = creditCard; + } + + public AccountDataBean getAccount() { + return account; + } + + public void setAccount(AccountDataBean account) { + this.account = account; + } + + @Override + public int hashCode() { + int hash = 0; + hash += (this.userID != null ? this.userID.hashCode() : 0); + return hash; + } + + @Override + public boolean equals(Object object) { + + if (!(object instanceof AccountProfileDataBean)) { + return false; + } + AccountProfileDataBean other = (AccountProfileDataBean) object; + + if (this.userID != other.userID && (this.userID == null || !this.userID.equals(other.userID))) { + return false; + } + + return true; + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/entities/HoldingDataBean.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/entities/HoldingDataBean.java new file mode 100644 index 00000000..2974ddc2 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/entities/HoldingDataBean.java @@ -0,0 +1,204 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.entities; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.Transient; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.PastOrPresent; +import javax.validation.constraints.Positive; + +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; + +@Entity(name = "holdingejb") +@Table(name = "holdingejb") +public class HoldingDataBean implements Serializable { + + /* persistent/relationship fields */ + + private static final long serialVersionUID = -2338411656251935480L; + + @Id + @TableGenerator(name = "holdingIdGen", table = "KEYGENEJB", pkColumnName = "KEYNAME", valueColumnName = "KEYVAL", pkColumnValue = "holding", allocationSize = 1000) + @GeneratedValue(strategy = GenerationType.TABLE, generator = "holdingIdGen") + @Column(name = "HOLDINGID", nullable = false) + private Integer holdingID; /* holdingID */ + + @NotNull + @Positive + @Column(name = "QUANTITY", nullable = false) + private double quantity; /* quantity */ + + @Column(name = "PURCHASEPRICE") + @Positive + private BigDecimal purchasePrice; /* purchasePrice */ + + @Column(name = "PURCHASEDATE") + @Temporal(TemporalType.TIMESTAMP) + @PastOrPresent + private Date purchaseDate; /* purchaseDate */ + + @Transient + private String quoteID; /* Holding(*) ---> Quote(1) */ + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "ACCOUNT_ACCOUNTID") + private AccountDataBean account; + + @ManyToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "QUOTE_SYMBOL") + private QuoteDataBean quote; + + public HoldingDataBean() { + } + + public HoldingDataBean(Integer holdingID, double quantity, BigDecimal purchasePrice, Date purchaseDate, String quoteID) { + setHoldingID(holdingID); + setQuantity(quantity); + setPurchasePrice(purchasePrice); + setPurchaseDate(purchaseDate); + setQuoteID(quoteID); + } + + public HoldingDataBean(double quantity, BigDecimal purchasePrice, Date purchaseDate, AccountDataBean account, QuoteDataBean quote) { + setQuantity(quantity); + setPurchasePrice(purchasePrice); + setPurchaseDate(purchaseDate); + setAccount(account); + setQuote(quote); + } + + public static HoldingDataBean getRandomInstance() { + return new HoldingDataBean(new Integer(TradeConfig.rndInt(100000)), // holdingID + TradeConfig.rndQuantity(), // quantity + TradeConfig.rndBigDecimal(1000.0f), // purchasePrice + new java.util.Date(TradeConfig.rndInt(Integer.MAX_VALUE)), // purchaseDate + TradeConfig.rndSymbol() // symbol + ); + } + + @Override + public String toString() { + return "\n\tHolding Data for holding: " + getHoldingID() + "\n\t\t quantity:" + getQuantity() + "\n\t\t purchasePrice:" + getPurchasePrice() + + "\n\t\t purchaseDate:" + getPurchaseDate() + "\n\t\t quoteID:" + getQuoteID(); + } + + public String toHTML() { + return "
    Holding Data for holding: " + getHoldingID() + "" + "
  • quantity:" + getQuantity() + "
  • " + "
  • purchasePrice:" + + getPurchasePrice() + "
  • " + "
  • purchaseDate:" + getPurchaseDate() + "
  • " + "
  • quoteID:" + getQuoteID() + "
  • "; + } + + public void print() { + Log.log(this.toString()); + } + + public Integer getHoldingID() { + return holdingID; + } + + public void setHoldingID(Integer holdingID) { + this.holdingID = holdingID; + } + + public double getQuantity() { + return quantity; + } + + public void setQuantity(double quantity) { + this.quantity = quantity; + } + + public BigDecimal getPurchasePrice() { + return purchasePrice; + } + + public void setPurchasePrice(BigDecimal purchasePrice) { + this.purchasePrice = purchasePrice; + } + + public Date getPurchaseDate() { + return purchaseDate; + } + + public void setPurchaseDate(Date purchaseDate) { + this.purchaseDate = purchaseDate; + } + + public String getQuoteID() { + if (quote != null) { + return quote.getSymbol(); + } + return quoteID; + } + + public void setQuoteID(String quoteID) { + this.quoteID = quoteID; + } + + public AccountDataBean getAccount() { + return account; + } + + public void setAccount(AccountDataBean account) { + this.account = account; + } + + public QuoteDataBean getQuote() { + return quote; + } + + public void setQuote(QuoteDataBean quote) { + this.quote = quote; + } + + @Override + public int hashCode() { + int hash = 0; + hash += (this.holdingID != null ? this.holdingID.hashCode() : 0); + return hash; + } + + @Override + public boolean equals(Object object) { + + if (!(object instanceof HoldingDataBean)) { + return false; + } + HoldingDataBean other = (HoldingDataBean) object; + + if (this.holdingID != other.holdingID && (this.holdingID == null || !this.holdingID.equals(other.holdingID))) { + return false; + } + + return true; + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/entities/OrderDataBean.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/entities/OrderDataBean.java new file mode 100644 index 00000000..b62b4993 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/entities/OrderDataBean.java @@ -0,0 +1,339 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.entities; + +import java.io.Serializable; +import java.math.BigDecimal; +//import java.sql.Timestamp; +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; +import javax.persistence.OneToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.Transient; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.PastOrPresent; +import javax.validation.constraints.Positive; + +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; + +@Entity(name = "orderejb") +@Table(name = "orderejb") +@NamedQueries({ + @NamedQuery(name = "orderejb.findByOrderfee", query = "SELECT o FROM orderejb o WHERE o.orderFee = :orderfee"), + @NamedQuery(name = "orderejb.findByCompletiondate", query = "SELECT o FROM orderejb o WHERE o.completionDate = :completiondate"), + @NamedQuery(name = "orderejb.findByOrdertype", query = "SELECT o FROM orderejb o WHERE o.orderType = :ordertype"), + @NamedQuery(name = "orderejb.findByOrderstatus", query = "SELECT o FROM orderejb o WHERE o.orderStatus = :orderstatus"), + @NamedQuery(name = "orderejb.findByPrice", query = "SELECT o FROM orderejb o WHERE o.price = :price"), + @NamedQuery(name = "orderejb.findByQuantity", query = "SELECT o FROM orderejb o WHERE o.quantity = :quantity"), + @NamedQuery(name = "orderejb.findByOpendate", query = "SELECT o FROM orderejb o WHERE o.openDate = :opendate"), + @NamedQuery(name = "orderejb.findByOrderid", query = "SELECT o FROM orderejb o WHERE o.orderID = :orderid"), + @NamedQuery(name = "orderejb.findByAccountAccountid", query = "SELECT o FROM orderejb o WHERE o.account.accountID = :accountAccountid"), + @NamedQuery(name = "orderejb.findByQuoteSymbol", query = "SELECT o FROM orderejb o WHERE o.quote.symbol = :quoteSymbol"), + @NamedQuery(name = "orderejb.findByHoldingHoldingid", query = "SELECT o FROM orderejb o WHERE o.holding.holdingID = :holdingHoldingid"), + @NamedQuery(name = "orderejb.closedOrders", query = "SELECT o FROM orderejb o WHERE o.orderStatus = 'closed' AND o.account.profile.userID = :userID"), + @NamedQuery(name = "orderejb.completeClosedOrders", query = "UPDATE orderejb o SET o.orderStatus = 'completed' WHERE o.orderStatus = 'closed' AND o.account.profile.userID = :userID") }) +public class OrderDataBean implements Serializable { + + private static final long serialVersionUID = 120650490200739057L; + + @Id + @TableGenerator(name = "orderIdGen", table = "KEYGENEJB", pkColumnName = "KEYNAME", valueColumnName = "KEYVAL", pkColumnValue = "order", allocationSize = 1000) + @GeneratedValue(strategy = GenerationType.TABLE, generator = "orderIdGen") + @Column(name = "ORDERID", nullable = false) + private Integer orderID; /* orderID */ + + @Column(name = "ORDERTYPE") + @NotBlank + private String orderType; /* orderType (buy, sell, etc.) */ + + @Column(name = "ORDERSTATUS") + @NotBlank + private String orderStatus; /* + * orderStatus (open, processing, completed, + * closed, cancelled) + */ + + @Column(name = "OPENDATE") + @Temporal(TemporalType.TIMESTAMP) + @PastOrPresent + private Date openDate; /* openDate (when the order was entered) */ + + @Column(name = "COMPLETIONDATE") + @PastOrPresent + @Temporal(TemporalType.TIMESTAMP) + private Date completionDate; /* completionDate */ + + @NotNull + @Column(name = "QUANTITY", nullable = false) + private double quantity; /* quantity */ + + @Column(name = "PRICE") + @Positive + private BigDecimal price; /* price */ + + @Column(name = "ORDERFEE") + @Positive + private BigDecimal orderFee; /* price */ + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "ACCOUNT_ACCOUNTID") + private AccountDataBean account; + + @ManyToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "QUOTE_SYMBOL") + private QuoteDataBean quote; + + @OneToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "HOLDING_HOLDINGID") + private HoldingDataBean holding; + + /* Fields for relationship fields are not kept in the Data Bean */ + @Transient + private String symbol; + + public OrderDataBean() { + } + + public OrderDataBean(Integer orderID, String orderType, String orderStatus, Date openDate, Date completionDate, double quantity, BigDecimal price, + BigDecimal orderFee, String symbol) { + setOrderID(orderID); + setOrderType(orderType); + setOrderStatus(orderStatus); + setOpenDate(openDate); + setCompletionDate(completionDate); + setQuantity(quantity); + setPrice(price); + setOrderFee(orderFee); + setSymbol(symbol); + } + + public OrderDataBean(String orderType, String orderStatus, Date openDate, Date completionDate, double quantity, BigDecimal price, BigDecimal orderFee, + AccountDataBean account, QuoteDataBean quote, HoldingDataBean holding) { + setOrderType(orderType); + setOrderStatus(orderStatus); + setOpenDate(openDate); + setCompletionDate(completionDate); + setQuantity(quantity); + setPrice(price); + setOrderFee(orderFee); + setAccount(account); + setQuote(quote); + setHolding(holding); + } + + public static OrderDataBean getRandomInstance() { + return new OrderDataBean(new Integer(TradeConfig.rndInt(100000)), TradeConfig.rndBoolean() ? "buy" : "sell", "open", new java.util.Date( + TradeConfig.rndInt(Integer.MAX_VALUE)), new java.util.Date(TradeConfig.rndInt(Integer.MAX_VALUE)), TradeConfig.rndQuantity(), + TradeConfig.rndBigDecimal(1000.0f), TradeConfig.rndBigDecimal(1000.0f), TradeConfig.rndSymbol()); + } + + @Override + public String toString() { + return "Order " + getOrderID() + "\n\t orderType: " + getOrderType() + "\n\t orderStatus: " + getOrderStatus() + "\n\t openDate: " + + getOpenDate() + "\n\t completionDate: " + getCompletionDate() + "\n\t quantity: " + getQuantity() + "\n\t price: " + + getPrice() + "\n\t orderFee: " + getOrderFee() + "\n\t symbol: " + getSymbol(); + } + + public String toHTML() { + return "
    Order " + getOrderID() + "" + "
  • orderType: " + getOrderType() + "
  • " + "
  • orderStatus: " + getOrderStatus() + + "
  • " + "
  • openDate: " + getOpenDate() + "
  • " + "
  • completionDate: " + getCompletionDate() + "
  • " + + "
  • quantity: " + getQuantity() + "
  • " + "
  • price: " + getPrice() + "
  • " + "
  • orderFee: " + getOrderFee() + + "
  • " + "
  • symbol: " + getSymbol() + "
  • "; + } + + public void print() { + Log.log(this.toString()); + } + + public Integer getOrderID() { + return orderID; + } + + public void setOrderID(Integer orderID) { + this.orderID = orderID; + } + + public String getOrderType() { + return orderType; + } + + public void setOrderType(String orderType) { + this.orderType = orderType; + } + + public String getOrderStatus() { + return orderStatus; + } + + public void setOrderStatus(String orderStatus) { + this.orderStatus = orderStatus; + } + + public Date getOpenDate() { + return openDate; + } + + public void setOpenDate(Date openDate) { + this.openDate = openDate; + } + + public Date getCompletionDate() { + return completionDate; + } + + public void setCompletionDate(Date completionDate) { + this.completionDate = completionDate; + } + + public double getQuantity() { + return quantity; + } + + public void setQuantity(double quantity) { + this.quantity = quantity; + } + + public BigDecimal getPrice() { + return price; + } + + public void setPrice(BigDecimal price) { + this.price = price; + } + + public BigDecimal getOrderFee() { + return orderFee; + } + + public void setOrderFee(BigDecimal orderFee) { + this.orderFee = orderFee; + } + + public String getSymbol() { + if (quote != null) { + return quote.getSymbol(); + } + return symbol; + } + + public void setSymbol(String symbol) { + this.symbol = symbol; + } + + public AccountDataBean getAccount() { + return account; + } + + public void setAccount(AccountDataBean account) { + this.account = account; + } + + public QuoteDataBean getQuote() { + return quote; + } + + public void setQuote(QuoteDataBean quote) { + this.quote = quote; + } + + public HoldingDataBean getHolding() { + return holding; + } + + public void setHolding(HoldingDataBean holding) { + this.holding = holding; + } + + public boolean isBuy() { + String orderType = getOrderType(); + if (orderType.compareToIgnoreCase("buy") == 0) { + return true; + } + return false; + } + + public boolean isSell() { + String orderType = getOrderType(); + if (orderType.compareToIgnoreCase("sell") == 0) { + return true; + } + return false; + } + + public boolean isOpen() { + String orderStatus = getOrderStatus(); + if ((orderStatus.compareToIgnoreCase("open") == 0) || (orderStatus.compareToIgnoreCase("processing") == 0)) { + return true; + } + return false; + } + + public boolean isCompleted() { + String orderStatus = getOrderStatus(); + if ((orderStatus.compareToIgnoreCase("completed") == 0) || (orderStatus.compareToIgnoreCase("alertcompleted") == 0) + || (orderStatus.compareToIgnoreCase("cancelled") == 0)) { + return true; + } + return false; + } + + public boolean isCancelled() { + String orderStatus = getOrderStatus(); + if (orderStatus.compareToIgnoreCase("cancelled") == 0) { + return true; + } + return false; + } + + public void cancel() { + setOrderStatus("cancelled"); + } + + @Override + public int hashCode() { + int hash = 0; + hash += (this.orderID != null ? this.orderID.hashCode() : 0); + return hash; + } + + @Override + public boolean equals(Object object) { + + if (!(object instanceof OrderDataBean)) { + return false; + } + OrderDataBean other = (OrderDataBean) object; + if (this.orderID != other.orderID && (this.orderID == null || !this.orderID.equals(other.orderID))) { + return false; + } + return true; + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/entities/QuoteDataBean.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/entities/QuoteDataBean.java new file mode 100644 index 00000000..188873a0 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/entities/QuoteDataBean.java @@ -0,0 +1,213 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.entities; + +import java.io.Serializable; +import java.math.BigDecimal; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.NamedNativeQueries; +import javax.persistence.NamedNativeQuery; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; +import javax.persistence.Table; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Positive; + +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; + +@Entity(name = "quoteejb") +@Table(name = "quoteejb") +@NamedQueries({ + @NamedQuery(name = "quoteejb.allQuotes", query = "SELECT q FROM quoteejb q")}) +@NamedNativeQueries({ @NamedNativeQuery(name = "quoteejb.quoteForUpdate", query = "select * from quoteejb q where q.symbol=? for update", resultClass = com.ibm.websphere.samples.daytrader.entities.QuoteDataBean.class) }) +public class QuoteDataBean implements Serializable { + + /* Accessor methods for persistent fields */ + + private static final long serialVersionUID = 1847932261895838791L; + + @Id + @NotNull + @Column(name = "SYMBOL", nullable = false) + private String symbol; /* symbol */ + + @Column(name = "COMPANYNAME") + @NotBlank + private String companyName; /* companyName */ + + @NotNull + @Column(name = "VOLUME", nullable = false) + private double volume; /* volume */ + + @Column(name = "PRICE") + @Positive + private BigDecimal price; /* price */ + + @Column(name = "OPEN1") + @Positive + private BigDecimal open1; /* open1 price */ + + @Column(name = "LOW") + @Positive + private BigDecimal low; /* low price */ + + @Column(name = "HIGH") + @Positive + private BigDecimal high; /* high price */ + + @NotNull + @Column(name = "CHANGE1", nullable = false) + private double change1; /* price change */ + + /* Accessor methods for relationship fields are not kept in the DataBean */ + + public QuoteDataBean() { + } + + public QuoteDataBean(String symbol, String companyName, double volume, BigDecimal price, BigDecimal open, BigDecimal low, BigDecimal high, double change) { + setSymbol(symbol); + setCompanyName(companyName); + setVolume(volume); + setPrice(price); + setOpen(open); + setLow(low); + setHigh(high); + setChange(change); + } + + public static QuoteDataBean getRandomInstance() { + return new QuoteDataBean(TradeConfig.rndSymbol(), // symbol + TradeConfig.rndSymbol() + " Incorporated", // Company Name + TradeConfig.rndFloat(100000), // volume + TradeConfig.rndBigDecimal(1000.0f), // price + TradeConfig.rndBigDecimal(1000.0f), // open1 + TradeConfig.rndBigDecimal(1000.0f), // low + TradeConfig.rndBigDecimal(1000.0f), // high + TradeConfig.rndFloat(100000) // volume + ); + } + + // Create a "zero" value quoteDataBean for the given symbol + public QuoteDataBean(String symbol) { + setSymbol(symbol); + } + + @Override + public String toString() { + return "\n\tQuote Data for: " + getSymbol() + "\n\t\t companyName: " + getCompanyName() + "\n\t\t volume: " + getVolume() + "\n\t\t price: " + + getPrice() + "\n\t\t open1: " + getOpen() + "\n\t\t low: " + getLow() + "\n\t\t high: " + getHigh() + + "\n\t\t change1: " + getChange(); + } + + public String toHTML() { + return "
    Quote Data for: " + getSymbol() + "
  • companyName: " + getCompanyName() + "
  • " + "
  • volume: " + getVolume() + "
  • " + + "
  • price: " + getPrice() + "
  • " + "
  • open1: " + getOpen() + "
  • " + "
  • low: " + getLow() + "
  • " + + "
  • high: " + getHigh() + "
  • " + "
  • change1: " + getChange() + "
  • "; + } + + public void print() { + Log.log(this.toString()); + } + + public String getSymbol() { + return symbol; + } + + public void setSymbol(String symbol) { + this.symbol = symbol; + } + + public String getCompanyName() { + return companyName; + } + + public void setCompanyName(String companyName) { + this.companyName = companyName; + } + + public BigDecimal getPrice() { + return price; + } + + public void setPrice(BigDecimal price) { + this.price = price; + } + + public BigDecimal getOpen() { + return open1; + } + + public void setOpen(BigDecimal open) { + this.open1 = open; + } + + public BigDecimal getLow() { + return low; + } + + public void setLow(BigDecimal low) { + this.low = low; + } + + public BigDecimal getHigh() { + return high; + } + + public void setHigh(BigDecimal high) { + this.high = high; + } + + public double getChange() { + return change1; + } + + public void setChange(double change) { + this.change1 = change; + } + + public double getVolume() { + return volume; + } + + public void setVolume(double volume) { + this.volume = volume; + } + + @Override + public int hashCode() { + int hash = 0; + hash += (this.symbol != null ? this.symbol.hashCode() : 0); + return hash; + } + + @Override + public boolean equals(Object object) { + + if (!(object instanceof QuoteDataBean)) { + return false; + } + QuoteDataBean other = (QuoteDataBean) object; + if (this.symbol != other.symbol && (this.symbol == null || !this.symbol.equals(other.symbol))) { + return false; + } + return true; + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/impl/direct/AsyncOrder.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/impl/direct/AsyncOrder.java new file mode 100644 index 00000000..eae3935c --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/impl/direct/AsyncOrder.java @@ -0,0 +1,71 @@ +/** + * (C) Copyright IBM Corporation 2019. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.impl.direct; + +import javax.annotation.Resource; +import javax.enterprise.context.Dependent; +import javax.inject.Inject; +import javax.transaction.UserTransaction; + +import com.ibm.websphere.samples.daytrader.interfaces.TradeJDBC; +import com.ibm.websphere.samples.daytrader.interfaces.TradeServices; + +@Dependent +public class AsyncOrder implements Runnable { + + @Inject + @TradeJDBC + TradeServices tradeService; + + @Resource + UserTransaction ut; + + Integer orderID; + boolean twoPhase; + + public void setProperties(Integer orderID, boolean twoPhase) { + this.orderID = orderID; + this.twoPhase = twoPhase; + } + + @Override + public void run() { + + + try { + ut.begin(); + tradeService.completeOrder(orderID, twoPhase); + ut.commit(); + } catch (Exception e) { + + try { + ut.rollback(); + } catch (Exception e1) { + try { + throw new Exception(e1); + } catch (Exception e2) { + e2.printStackTrace(); + } + } + try { + throw new Exception(e); + } catch (Exception e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + } + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/impl/direct/AsyncOrderSubmitter.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/impl/direct/AsyncOrderSubmitter.java new file mode 100644 index 00000000..75770d4a --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/impl/direct/AsyncOrderSubmitter.java @@ -0,0 +1,40 @@ +/** + * (C) Copyright IBM Corporation 2019. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.impl.direct; + +import java.util.concurrent.Future; + +import javax.annotation.Resource; +import javax.enterprise.concurrent.ManagedExecutorService; +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; + +@RequestScoped +public class AsyncOrderSubmitter { + + + @Resource + private ManagedExecutorService mes; + + @Inject + private AsyncOrder asyncOrder; + + + public Future submitOrder(Integer orderID, boolean twoPhase) { + asyncOrder.setProperties(orderID,twoPhase); + return mes.submit(asyncOrder); + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/impl/direct/KeySequenceDirect.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/impl/direct/KeySequenceDirect.java new file mode 100644 index 00000000..dfd7beba --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/impl/direct/KeySequenceDirect.java @@ -0,0 +1,114 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.impl.direct; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; + +import com.ibm.websphere.samples.daytrader.util.KeyBlock; +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; + +public class KeySequenceDirect { + + private static HashMap> keyMap = new HashMap>(); + + public static synchronized Integer getNextID(Connection conn, String keyName, boolean inSession, boolean inGlobalTxn) throws Exception { + Integer nextID = null; + // First verify we have allocated a block of keys + // for this key name + // Then verify the allocated block has not been depleted + // allocate a new block if necessary + if (keyMap.containsKey(keyName) == false) { + allocNewBlock(conn, keyName, inSession, inGlobalTxn); + } + Collection block = keyMap.get(keyName); + + Iterator ids = block.iterator(); + if (ids.hasNext() == false) { + ids = allocNewBlock(conn, keyName, inSession, inGlobalTxn).iterator(); + } + // get and return a new unique key + nextID = (Integer) ids.next(); + + + Log.trace("KeySequenceDirect:getNextID inSession(" + inSession + ") - return new PK ID for Entity type: " + keyName + " ID=" + nextID); + + return nextID; + } + + private static Collection allocNewBlock(Connection conn, String keyName, boolean inSession, boolean inGlobalTxn) throws Exception { + try { + + if (inGlobalTxn == false && !inSession) { + conn.commit(); // commit any pending txns + } + + PreparedStatement stmt = conn.prepareStatement(getKeyForUpdateSQL); + stmt.setString(1, keyName); + ResultSet rs = stmt.executeQuery(); + + if (!rs.next()) { + // No keys found for this name - create a new one + PreparedStatement stmt2 = conn.prepareStatement(createKeySQL); + int keyVal = 0; + stmt2.setString(1, keyName); + stmt2.setInt(2, keyVal); + stmt2.executeUpdate(); + stmt2.close(); + stmt.close(); + stmt = conn.prepareStatement(getKeyForUpdateSQL); + stmt.setString(1, keyName); + rs = stmt.executeQuery(); + rs.next(); + } + + int keyVal = rs.getInt("keyval"); + + stmt.close(); + + stmt = conn.prepareStatement(updateKeyValueSQL); + stmt.setInt(1, keyVal + TradeConfig.KEYBLOCKSIZE); + stmt.setString(2, keyName); + stmt.executeUpdate(); + stmt.close(); + + Collection block = new KeyBlock(keyVal, keyVal + TradeConfig.KEYBLOCKSIZE - 1); + keyMap.put(keyName, block); + + if (inGlobalTxn == false && !inSession) { + conn.commit(); + } + + return block; + } catch (Exception e) { + String error = "KeySequenceDirect:allocNewBlock - failure to allocate new block of keys for Entity type: " + keyName; + Log.error(e, error); + throw new Exception(error + e.toString()); + } + } + + private static final String getKeyForUpdateSQL = "select * from keygenejb kg where kg.keyname = ? for update"; + + private static final String createKeySQL = "insert into keygenejb " + "( keyname, keyval ) " + "VALUES ( ? , ? )"; + + private static final String updateKeyValueSQL = "update keygenejb set keyval = ? " + "where keyname = ?"; + +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/impl/direct/TradeDirect.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/impl/direct/TradeDirect.java new file mode 100644 index 00000000..071ee3d1 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/impl/direct/TradeDirect.java @@ -0,0 +1,1837 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.impl.direct; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Collection; +import java.util.concurrent.Future; + +import javax.annotation.Resource; +import javax.enterprise.concurrent.ManagedExecutorService; +import javax.enterprise.context.Dependent; +import javax.enterprise.event.Event; +import javax.enterprise.event.NotificationOptions; +import javax.inject.Inject; +import javax.jms.JMSContext; +import javax.jms.JMSException; +import javax.jms.Queue; +import javax.jms.QueueConnectionFactory; +import javax.jms.TextMessage; +import javax.jms.Topic; +import javax.jms.TopicConnectionFactory; +import javax.sql.DataSource; +import javax.transaction.UserTransaction; +import javax.validation.constraints.NotNull; + +import com.ibm.websphere.samples.daytrader.interfaces.TradeServices; +import com.ibm.websphere.samples.daytrader.beans.MarketSummaryDataBean; +import com.ibm.websphere.samples.daytrader.entities.AccountDataBean; +import com.ibm.websphere.samples.daytrader.entities.AccountProfileDataBean; +import com.ibm.websphere.samples.daytrader.entities.HoldingDataBean; +import com.ibm.websphere.samples.daytrader.entities.OrderDataBean; +import com.ibm.websphere.samples.daytrader.entities.QuoteDataBean; +import com.ibm.websphere.samples.daytrader.util.FinancialUtils; +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.MDBStats; +import com.ibm.websphere.samples.daytrader.util.RecentQuotePriceChangeList; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; +import com.ibm.websphere.samples.daytrader.interfaces.MarketSummaryUpdate; +import com.ibm.websphere.samples.daytrader.interfaces.RuntimeMode; +import com.ibm.websphere.samples.daytrader.interfaces.Trace; +import com.ibm.websphere.samples.daytrader.interfaces.TradeJDBC; + +/** + * TradeDirect uses direct JDBC and JMS access to a + * javax.sql.DataSource to implement the business methods of the + * Trade online broker application. These business methods represent the + * features and operations that can be performed by customers of the brokerage + * such as login, logout, get a stock quote, buy or sell a stock, etc. and are + * specified in the {@link com.ibm.websphere.samples.daytrader.TradeServices} + * interface + * + * Note: In order for this class to be thread-safe, a new TradeJDBC must be + * created for each call to a method from the TradeInterface interface. + * Otherwise, pooled connections may not be released. + * + * @see com.ibm.websphere.samples.daytrader.TradeServices + * + */ + +@Dependent +@TradeJDBC +@RuntimeMode("Direct (JDBC)") +@Trace +public class TradeDirect implements TradeServices, Serializable { + /** + * + */ + private static final long serialVersionUID = -8089049090952927985L; + + //This lock is used to serialize market summary operations. + private static final Integer marketSummaryLock = new Integer(0); + private static long nextMarketSummary = System.currentTimeMillis(); + private static MarketSummaryDataBean cachedMSDB = MarketSummaryDataBean.getRandomInstance(); + + private static BigDecimal ZERO = new BigDecimal(0.0); + private boolean inGlobalTxn = false; + private boolean inSession = false; + + // For Wildfly - add java:/ to these resource names. + + @Resource(name = "jms/QueueConnectionFactory", authenticationType = javax.annotation.Resource.AuthenticationType.APPLICATION) + //@Resource(name = "java:/jms/QueueConnectionFactory", authenticationType = javax.annotation.Resource.AuthenticationType.APPLICATION) + private QueueConnectionFactory queueConnectionFactory; + + @Resource(name = "jms/TopicConnectionFactory", authenticationType = javax.annotation.Resource.AuthenticationType.APPLICATION) + //@Resource(name = "java:/jms/TopicConnectionFactory", authenticationType = javax.annotation.Resource.AuthenticationType.APPLICATION) + private TopicConnectionFactory topicConnectionFactory; + + @Resource(lookup = "jms/TradeStreamerTopic") + //@Resource(lookup = "java:/jms/TradeStreamerTopic") + private Topic tradeStreamerTopic; + + @Resource(lookup = "jms/TradeBrokerQueue") + //@Resource(lookup = "java:/jms/TradeBrokerQueue") + private Queue tradeBrokerQueue; + + @Resource(lookup = "jdbc/TradeDataSource") + //@Resource(lookup = "java:/jdbc/TradeDataSource") + private DataSource datasource; + + @Resource + private UserTransaction txn; + + @Inject + RecentQuotePriceChangeList recentQuotePriceChangeList; + + @Inject + AsyncOrderSubmitter asyncOrderSubmitter; + + @Inject + @MarketSummaryUpdate + Event mkSummaryUpdateEvent; + + @Resource + private ManagedExecutorService mes; + + + @Override + public MarketSummaryDataBean getMarketSummary() throws Exception { + + if (TradeConfig.getMarketSummaryInterval() == 0) { + return getMarketSummaryInternal(); + } + if (TradeConfig.getMarketSummaryInterval() < 0) { + return cachedMSDB; + } + + /** + * This is a little funky. If its time to fetch a new Market summary + * then we'll synchronize access to make sure only one requester does + * it. Others will merely return the old copy until the new + * MarketSummary has been executed. + */ + + long currentTime = System.currentTimeMillis(); + + if (currentTime > nextMarketSummary) { + long oldNextMarketSummary = nextMarketSummary; + boolean fetch = false; + + synchronized (marketSummaryLock) { + /** + * Is it still ahead or did we miss lose the race? If we lost + * then let's get out of here as the work has already been done. + */ + if (oldNextMarketSummary == nextMarketSummary) { + fetch = true; + nextMarketSummary += TradeConfig.getMarketSummaryInterval() * 1000; + + /** + * If the server has been idle for a while then its possible + * that nextMarketSummary could be way off. Rather than try + * and play catch up we'll simply get in sync with the + * current time + the interval. + */ + if (nextMarketSummary < currentTime) { + nextMarketSummary = currentTime + TradeConfig.getMarketSummaryInterval() * 1000; + } + } + } + + /** + * If we're the lucky one then let's update the MarketSummary + */ + if (fetch) { + cachedMSDB = getMarketSummaryInternal(); + + } + } + + return cachedMSDB; + } + + + + /** + * @see TradeServices#getMarketSummary() + */ + + public MarketSummaryDataBean getMarketSummaryInternal() throws Exception { + + MarketSummaryDataBean marketSummaryData = null; + Connection conn = null; + try { + + Log.trace("TradeDirect:getMarketSummary - inSession(" + this.inSession + ")"); + + conn = getConn(); + PreparedStatement stmt = getStatement(conn, getTSIAQuotesOrderByChangeSQL, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); + + ArrayList topGainersData = new ArrayList(5); + ArrayList topLosersData = new ArrayList(5); + + ResultSet rs = stmt.executeQuery(); + + int count = 0; + while (rs.next() && (count++ < 5)) { + QuoteDataBean quoteData = getQuoteDataFromResultSet(rs); + topLosersData.add(quoteData); + } + + stmt.close(); + stmt = getStatement(conn, "select * from quoteejb q order by q.change1 DESC", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); + rs = stmt.executeQuery(); + + count = 0; + while (rs.next() && (count++ < 5)) { + QuoteDataBean quoteData = getQuoteDataFromResultSet(rs); + topGainersData.add(quoteData); + } + + /* + * rs.last(); count = 0; while (rs.previous() && (count++ < 5) ) { + * QuoteDataBean quoteData = getQuoteDataFromResultSet(rs); + * topGainersData.add(quoteData); } + */ + + stmt.close(); + + BigDecimal TSIA = ZERO; + BigDecimal openTSIA = ZERO; + double volume = 0.0; + + if ((topGainersData.size() > 0) || (topLosersData.size() > 0)) { + + stmt = getStatement(conn, getTSIASQL); + rs = stmt.executeQuery(); + + if (!rs.next()) { + Log.error("TradeDirect:getMarketSummary -- error w/ getTSIASQL -- no results"); + } else { + TSIA = rs.getBigDecimal("TSIA"); + } + stmt.close(); + + stmt = getStatement(conn, getOpenTSIASQL); + rs = stmt.executeQuery(); + + if (!rs.next()) { + Log.error("TradeDirect:getMarketSummary -- error w/ getOpenTSIASQL -- no results"); + } else { + openTSIA = rs.getBigDecimal("openTSIA"); + } + stmt.close(); + + stmt = getStatement(conn, getTSIATotalVolumeSQL); + rs = stmt.executeQuery(); + + if (!rs.next()) { + Log.error("TradeDirect:getMarketSummary -- error w/ getTSIATotalVolumeSQL -- no results"); + } else { + volume = rs.getDouble("totalVolume"); + } + stmt.close(); + } + commit(conn); + + marketSummaryData = new MarketSummaryDataBean(TSIA, openTSIA, volume, topGainersData, topLosersData); + mkSummaryUpdateEvent.fireAsync("MarketSummaryUpdate", NotificationOptions.builder().setExecutor(mes).build()); + + } + + catch (Exception e) { + Log.error("TradeDirect:login -- error logging in user", e); + rollBack(conn, e); + } finally { + releaseConn(conn); + } + return marketSummaryData; + + } + + /** + * @see TradeServices#buy(String, String, double) + */ + @Override + @NotNull + public OrderDataBean buy(String userID, String symbol, double quantity, int orderProcessingMode) throws Exception { + + final Connection conn = getConn(); + OrderDataBean orderData = null; + + BigDecimal total; + + try { + + Log.trace("TradeDirect:buy - inSession(" + this.inSession + ")");//, userID, symbol, new Double(quantity)); + + + if (!inSession && orderProcessingMode == TradeConfig.ASYNCH_2PHASE) { + + Log.trace("TradeDirect:buy create/begin global transaction"); + + + txn.begin(); + setInGlobalTxn(true); + } + + //conn = getConn(); + + AccountDataBean accountData = getAccountData(conn, userID); + QuoteDataBean quoteData = getQuoteData(conn, symbol); + HoldingDataBean holdingData = null; // the buy operation will create + // the holding + + orderData = createOrder(accountData, quoteData, holdingData, "buy", quantity); + + // Update -- account should be credited during completeOrder + BigDecimal price = quoteData.getPrice(); + BigDecimal orderFee = orderData.getOrderFee(); + total = (new BigDecimal(quantity).multiply(price)).add(orderFee); + // subtract total from account balance + creditAccountBalance(conn, accountData, total.negate()); + final Integer orderID = orderData.getOrderID(); + + try { + + if (orderProcessingMode == TradeConfig.SYNCH) { + completeOrder(conn, orderData.getOrderID()); + } else if (orderProcessingMode == TradeConfig.ASYNCH) { + completeOrderAsync(orderID, true); + } else if (orderProcessingMode == TradeConfig.ASYNCH_2PHASE) { + queueOrder(orderID, true); // 2-phase + } + } catch (JMSException je) { + Log.error("TradeBean:buy(" + userID + "," + symbol + "," + quantity + ") --> failed to queueOrder", je); + + + cancelOrder(conn, orderData.getOrderID()); + } + + orderData = getOrderData(conn, orderData.getOrderID().intValue()); + + if (getInGlobalTxn()) { + + Log.trace("TradeDirect:buy committing global transaction"); + + if (!inSession && orderProcessingMode == TradeConfig.ASYNCH_2PHASE) { + txn.commit(); + setInGlobalTxn(false); + } + } else { + commit(conn); + } + } catch (Exception e) { + Log.error("TradeDirect:buy error - rolling back", e); + if (getInGlobalTxn()) { + txn.rollback(); + } else { + rollBack(conn, e); + } + } finally { + releaseConn(conn); + } + + return orderData; + } + + /** + * @see TradeServices#sell(String, Integer) + */ + @Override + @NotNull + public OrderDataBean sell(String userID, Integer holdingID, int orderProcessingMode) throws Exception { + Connection conn = null; + OrderDataBean orderData = null; + //UserTransaction txn = null; + + /* + * total = (quantity * purchasePrice) + orderFee + */ + BigDecimal total; + + try { + + Log.trace("TradeDirect:sell - inSession(" + this.inSession + ")", userID, holdingID); + + + if (!inSession && orderProcessingMode == TradeConfig.ASYNCH_2PHASE) { + + Log.trace("TradeDirect:sell create/begin global transaction"); + + txn.begin(); + setInGlobalTxn(true); + } + + conn = getConn(); + + AccountDataBean accountData = getAccountData(conn, userID); + HoldingDataBean holdingData = getHoldingData(conn, holdingID.intValue()); + QuoteDataBean quoteData = null; + if (holdingData != null) { + quoteData = getQuoteData(conn, holdingData.getQuoteID()); + } + + if ((accountData == null) || (holdingData == null) || (quoteData == null)) { + String error = "TradeDirect:sell -- error selling stock -- unable to find: \n\taccount=" + accountData + "\n\tholding=" + holdingData + + "\n\tquote=" + quoteData + "\nfor user: " + userID + " and holdingID: " + holdingID; + Log.debug(error); + if (getInGlobalTxn()) { + txn.rollback(); + } else { + rollBack(conn, new Exception(error)); + } + orderData = new OrderDataBean(); + orderData.setOrderStatus("cancelled"); + return orderData; + } + + double quantity = holdingData.getQuantity(); + + orderData = createOrder(accountData, quoteData, holdingData, "sell", quantity); + + // Set the holdingSymbol purchaseDate to selling to signify the sell + // is "inflight" + updateHoldingStatus(conn, holdingData.getHoldingID(), holdingData.getQuoteID()); + + // UPDATE -- account should be credited during completeOrder + BigDecimal price = quoteData.getPrice(); + BigDecimal orderFee = orderData.getOrderFee(); + total = (new BigDecimal(quantity).multiply(price)).subtract(orderFee); + creditAccountBalance(conn, accountData, total); + + try { + if (orderProcessingMode == TradeConfig.SYNCH) { + completeOrder(conn, orderData.getOrderID()); + } else if (orderProcessingMode == TradeConfig.ASYNCH) { + this.completeOrderAsync(orderData.getOrderID(), true); + } else if (orderProcessingMode == TradeConfig.ASYNCH_2PHASE) { + queueOrder(orderData.getOrderID(), true); + } + } catch (JMSException je) { + Log.error("TradeBean:sell(" + userID + "," + holdingID + ") --> failed to queueOrder", je); + + cancelOrder(conn, orderData.getOrderID()); + } + + orderData = getOrderData(conn, orderData.getOrderID().intValue()); + + if (!inSession && orderProcessingMode == TradeConfig.ASYNCH_2PHASE) { + + Log.trace("TradeDirect:sell committing global transaction"); + + txn.commit(); + setInGlobalTxn(false); + } else { + commit(conn); + } + } catch (Exception e) { + Log.error("TradeDirect:sell error", e); + if (getInGlobalTxn()) { + txn.rollback(); + } else { + rollBack(conn, e); + } + } finally { + releaseConn(conn); + } + + return orderData; + } + + /** + * @see TradeServices#queueOrder(Integer) + */ + @Override + public void queueOrder(Integer orderID, boolean twoPhase) throws Exception { + + + Log.trace("TradeDirect:queueOrder - inSession(" + this.inSession + ")", orderID); + + + try (JMSContext context = queueConnectionFactory.createContext();){ + TextMessage message = context.createTextMessage(); + + message.setStringProperty("command", "neworder"); + message.setIntProperty("orderID", orderID.intValue()); + message.setBooleanProperty("twoPhase", twoPhase); + message.setBooleanProperty("direct", true); + message.setLongProperty("publishTime", System.currentTimeMillis()); + message.setText("neworder: orderID=" + orderID + " runtimeMode=Direct twoPhase=" + twoPhase); + + context.createProducer().send(tradeBrokerQueue, message); + } catch (Exception e) { + throw e; // pass the exception + } + } + + /** + * @see TradeServices#completeOrder(Integer) + */ + @Override + public OrderDataBean completeOrder(Integer orderID, boolean twoPhase) throws Exception { + OrderDataBean orderData = null; + Connection conn = null; + + try { // twoPhase + + + Log.trace("TradeDirect:completeOrder - inSession(" + this.inSession + ")", orderID); + + setInGlobalTxn(!inSession && twoPhase); + conn = getConn(); + + orderData = completeOrder(conn, orderID); + + commit(conn); + + } catch (Exception e) { + Log.error("TradeDirect:completeOrder -- error completing order", e); + rollBack(conn, e); + cancelOrder(orderID, twoPhase); + } finally { + releaseConn(conn); + } + + return orderData; + + } + + @Override + public Future completeOrderAsync(Integer orderID, boolean twoPhase) throws Exception { + if (!inSession) { + asyncOrderSubmitter.submitOrder(orderID, twoPhase); + } + return null; + } + + + private OrderDataBean completeOrder(Connection conn, Integer orderID) throws Exception { + //conn = getConn(); + OrderDataBean orderData = null; + + Log.trace("TradeDirect:completeOrderInternal - inSession(" + this.inSession + ")", orderID); + + + PreparedStatement stmt = getStatement(conn, getOrderSQL); + stmt.setInt(1, orderID.intValue()); + + ResultSet rs = stmt.executeQuery(); + + if (!rs.next()) { + Log.error("TradeDirect:completeOrder -- unable to find order: " + orderID); + stmt.close(); + return orderData; + } + orderData = getOrderDataFromResultSet(rs); + + String orderType = orderData.getOrderType(); + String orderStatus = orderData.getOrderStatus(); + + // if (order.isCompleted()) + if ((orderStatus.compareToIgnoreCase("completed") == 0) || (orderStatus.compareToIgnoreCase("alertcompleted") == 0) + || (orderStatus.compareToIgnoreCase("cancelled") == 0)) { + throw new Exception("TradeDirect:completeOrder -- attempt to complete Order that is already completed"); + } + + int accountID = rs.getInt("account_accountID"); + String quoteID = rs.getString("quote_symbol"); + int holdingID = rs.getInt("holding_holdingID"); + + BigDecimal price = orderData.getPrice(); + double quantity = orderData.getQuantity(); + + // get the data for the account and quote + // the holding will be created for a buy or extracted for a sell + + /* + * Use the AccountID and Quote Symbol from the Order AccountDataBean + * accountData = getAccountData(accountID, conn); QuoteDataBean + * quoteData = getQuoteData(conn, quoteID); + */ + String userID = getAccountProfileData(conn, new Integer(accountID)).getUserID(); + + HoldingDataBean holdingData = null; + + + Log.trace("TradeDirect:completeOrder--> Completing Order " + orderData.getOrderID() + "\n\t Order info: " + orderData + "\n\t Account info: " + + accountID + "\n\t Quote info: " + quoteID); + + + // if (order.isBuy()) + if (orderType.compareToIgnoreCase("buy") == 0) { + /* + * Complete a Buy operation - create a new Holding for the Account - + * deduct the Order cost from the Account balance + */ + + holdingData = createHolding(conn, accountID, quoteID, quantity, price); + updateOrderHolding(conn, orderID.intValue(), holdingData.getHoldingID().intValue()); + updateOrderStatus(conn, orderData.getOrderID(), "closed"); + updateQuotePriceVolume(orderData.getSymbol(), TradeConfig.getRandomPriceChangeFactor(), orderData.getQuantity()); + } + + // if (order.isSell()) { + if (orderType.compareToIgnoreCase("sell") == 0) { + /* + * Complete a Sell operation - remove the Holding from the Account - + * deposit the Order proceeds to the Account balance + */ + holdingData = getHoldingData(conn, holdingID); + if (holdingData == null) { + Log.debug("TradeDirect:completeOrder:sell -- user: " + userID + " already sold holding: " + holdingID); + updateOrderStatus(conn, orderData.getOrderID(), "cancelled"); + } else { + removeHolding(conn, holdingID, orderID.intValue()); + updateOrderStatus(conn, orderData.getOrderID(), "closed"); + updateQuotePriceVolume(orderData.getSymbol(), TradeConfig.getRandomPriceChangeFactor(), orderData.getQuantity()); + } + + } + + + + Log.trace("TradeDirect:completeOrder--> Completed Order " + orderData.getOrderID() + "\n\t Order info: " + orderData + "\n\t Account info: " + + accountID + "\n\t Quote info: " + quoteID + "\n\t Holding info: " + holdingData); + + stmt.close(); + + commit(conn); + + + + return orderData; + } + + /** + * @see TradeServices#cancelOrder(Integer, boolean) + */ + @Override + public void cancelOrder(Integer orderID, boolean twoPhase) throws Exception { + + Connection conn = null; + try { + + Log.trace("TradeDirect:cancelOrder - inSession(" + this.inSession + ")", orderID); + + setInGlobalTxn(!inSession && twoPhase); + conn = getConn(); + cancelOrder(conn, orderID); + commit(conn); + + } catch (Exception e) { + Log.error("TradeDirect:cancelOrder -- error cancelling order: " + orderID, e); + rollBack(conn, e); + } finally { + releaseConn(conn); + } + } + + private void cancelOrder(Connection conn, Integer orderID) throws Exception { + updateOrderStatus(conn, orderID, "cancelled"); + } + + @Override + public void orderCompleted(String userID, Integer orderID) throws Exception { + throw new UnsupportedOperationException("TradeDirect:orderCompleted method not supported"); + } + + private HoldingDataBean createHolding(Connection conn, int accountID, String symbol, double quantity, BigDecimal purchasePrice) throws Exception { + + Timestamp purchaseDate = new Timestamp(System.currentTimeMillis()); + PreparedStatement stmt = getStatement(conn, createHoldingSQL); + + Integer holdingID = KeySequenceDirect.getNextID(conn, "holding", inSession, getInGlobalTxn()); + stmt.setInt(1, holdingID.intValue()); + stmt.setTimestamp(2, purchaseDate); + stmt.setBigDecimal(3, purchasePrice); + stmt.setDouble(4, quantity); + stmt.setString(5, symbol); + stmt.setInt(6, accountID); + stmt.executeUpdate(); + + stmt.close(); + + return getHoldingData(conn, holdingID.intValue()); + } + + private void removeHolding(Connection conn, int holdingID, int orderID) throws Exception { + PreparedStatement stmt = getStatement(conn, removeHoldingSQL); + + stmt.setInt(1, holdingID); + stmt.executeUpdate(); + stmt.close(); + + // set the HoldingID to NULL for the purchase and sell order now that + // the holding as been removed + stmt = getStatement(conn, removeHoldingFromOrderSQL); + + stmt.setInt(1, holdingID); + stmt.executeUpdate(); + stmt.close(); + + } + + public OrderDataBean createOrder(AccountDataBean accountData, QuoteDataBean quoteData, HoldingDataBean holdingData, String orderType, + double quantity) throws Exception { + OrderDataBean orderData = null; + Connection conn = null; + try { + + conn = getConn(); + Timestamp currentDate = new Timestamp(System.currentTimeMillis()); + + PreparedStatement stmt = getStatement(conn, createOrderSQL); + + Integer orderID = KeySequenceDirect.getNextID(conn, "order", inSession, getInGlobalTxn()); + stmt.setInt(1, orderID.intValue()); + stmt.setString(2, orderType); + stmt.setString(3, "open"); + stmt.setTimestamp(4, currentDate); + stmt.setDouble(5, quantity); + stmt.setBigDecimal(6, quoteData.getPrice().setScale(FinancialUtils.SCALE, FinancialUtils.ROUND)); + stmt.setBigDecimal(7, TradeConfig.getOrderFee(orderType)); + stmt.setInt(8, accountData.getAccountID().intValue()); + if (holdingData == null) { + stmt.setNull(9, java.sql.Types.INTEGER); + } else { + stmt.setInt(9, holdingData.getHoldingID().intValue()); + } + stmt.setString(10, quoteData.getSymbol()); + stmt.executeUpdate(); + + orderData = getOrderData(conn, orderID.intValue()); + + stmt.close(); + + commit(conn); + } catch (Exception e) { + Log.error("TradeDirect:createOrder -- error getting user orders", e); + rollBack(conn, e); + } finally { + releaseConn(conn); + } + + return orderData; + } + + /** + * @see TradeServices#getOrders(String) + */ + @Override + public Collection getOrders(String userID) throws Exception { + Collection orderDataBeans = new ArrayList(); + Connection conn = null; + try { + Log.trace("TradeDirect:getOrders - inSession(" + this.inSession + ")", userID); + + + conn = getConn(); + PreparedStatement stmt = getStatement(conn, getOrdersByUserSQL); + stmt.setString(1, userID); + + ResultSet rs = stmt.executeQuery(); + + // TODO: return top 5 orders for now -- next version will add a + // getAllOrders method + // also need to get orders sorted by order id descending + int i = 0; + while ((rs.next()) && (i++ < 5)) { + OrderDataBean orderData = getOrderDataFromResultSet(rs); + orderDataBeans.add(orderData); + } + + stmt.close(); + commit(conn); + + } catch (Exception e) { + Log.error("TradeDirect:getOrders -- error getting user orders", e); + rollBack(conn, e); + } finally { + releaseConn(conn); + } + return orderDataBeans; + } + + /** + * @see TradeServices#getClosedOrders(String) + */ + @Override + public Collection getClosedOrders(String userID) throws Exception { + Collection orderDataBeans = new ArrayList(); + Connection conn = null; + try { + + Log.trace("TradeDirect:getClosedOrders - inSession(" + this.inSession + ")", userID); + + + conn = getConn(); + PreparedStatement stmt = getStatement(conn, getClosedOrdersSQL); + stmt.setString(1, userID); + + ResultSet rs = stmt.executeQuery(); + + while (rs.next()) { + OrderDataBean orderData = getOrderDataFromResultSet(rs); + orderData.setOrderStatus("completed"); + updateOrderStatus(conn, orderData.getOrderID(), orderData.getOrderStatus()); + orderDataBeans.add(orderData); + + } + + stmt.close(); + commit(conn); + } catch (Exception e) { + Log.error("TradeDirect:getOrders -- error getting user orders", e); + rollBack(conn, e); + } finally { + releaseConn(conn); + } + return orderDataBeans; + } + + /** + * @see TradeServices#createQuote(String, String, BigDecimal) + */ + @Override + public QuoteDataBean createQuote(String symbol, String companyName, BigDecimal price) throws Exception { + + QuoteDataBean quoteData = null; + Connection conn = null; + try { + + Log.trace("TradeDirect:createQuote - inSession(" + this.inSession + ")"); + + + price = price.setScale(FinancialUtils.SCALE, FinancialUtils.ROUND); + double volume = 0.0, change = 0.0; + + conn = getConn(); + PreparedStatement stmt = getStatement(conn, createQuoteSQL); + stmt.setString(1, symbol); // symbol + stmt.setString(2, companyName); // companyName + stmt.setDouble(3, volume); // volume + stmt.setBigDecimal(4, price); // price + stmt.setBigDecimal(5, price); // open + stmt.setBigDecimal(6, price); // low + stmt.setBigDecimal(7, price); // high + stmt.setDouble(8, change); // change + + stmt.executeUpdate(); + stmt.close(); + commit(conn); + + quoteData = new QuoteDataBean(symbol, companyName, volume, price, price, price, price, change); + } catch (Exception e) { + Log.error("TradeDirect:createQuote -- error creating quote", e); + } finally { + releaseConn(conn); + } + return quoteData; + } + + /** + * @see TradeServices#getQuote(String) + */ + + @Override + public QuoteDataBean getQuote(String symbol) throws Exception { + QuoteDataBean quoteData = null; + Connection conn = null; + + try { + + Log.trace("TradeDirect:getQuote - inSession(" + this.inSession + ")", symbol); + + + conn = getConn(); + quoteData = getQuote(conn, symbol); + commit(conn); + } catch (Exception e) { + Log.error("TradeDirect:getQuote -- error getting quote", e); + rollBack(conn, e); + } finally { + releaseConn(conn); + } + return quoteData; + } + + private QuoteDataBean getQuote(Connection conn, String symbol) throws Exception { + QuoteDataBean quoteData = null; + PreparedStatement stmt = getStatement(conn, getQuoteSQL); + stmt.setString(1, symbol); // symbol + + ResultSet rs = stmt.executeQuery(); + + if (!rs.next()) { + Log.error("TradeDirect:getQuote -- failure no result.next() for symbol: " + symbol); + } else { + quoteData = getQuoteDataFromResultSet(rs); + } + + stmt.close(); + + return quoteData; + } + + private QuoteDataBean getQuoteForUpdate(Connection conn, String symbol) throws Exception { + QuoteDataBean quoteData = null; + PreparedStatement stmt = getStatement(conn, getQuoteForUpdateSQL); + stmt.setString(1, symbol); // symbol + + ResultSet rs = stmt.executeQuery(); + + if (!rs.next()) { + Log.error("TradeDirect:getQuote -- failure no result.next()"); + } else { + quoteData = getQuoteDataFromResultSet(rs); + } + + stmt.close(); + + return quoteData; + } + + /** + * @see TradeServices#getAllQuotes(String) + */ + @Override + public Collection getAllQuotes() throws Exception { + Collection quotes = new ArrayList(); + QuoteDataBean quoteData = null; + + Connection conn = null; + try { + conn = getConn(); + + PreparedStatement stmt = getStatement(conn, getAllQuotesSQL); + + ResultSet rs = stmt.executeQuery(); + + while (!rs.next()) { + quoteData = getQuoteDataFromResultSet(rs); + quotes.add(quoteData); + } + + stmt.close(); + } catch (Exception e) { + Log.error("TradeDirect:getAllQuotes", e); + rollBack(conn, e); + } finally { + releaseConn(conn); + } + + return quotes; + } + + /** + * @see TradeServices#getHoldings(String) + */ + @Override + public Collection getHoldings(String userID) throws Exception { + Collection holdingDataBeans = new ArrayList(); + Connection conn = null; + try { + + Log.trace("TradeDirect:getHoldings - inSession(" + this.inSession + ")", userID); + + + conn = getConn(); + PreparedStatement stmt = getStatement(conn, getHoldingsForUserSQL); + stmt.setString(1, userID); + + ResultSet rs = stmt.executeQuery(); + + while (rs.next()) { + HoldingDataBean holdingData = getHoldingDataFromResultSet(rs); + holdingDataBeans.add(holdingData); + } + + stmt.close(); + commit(conn); + + } catch (Exception e) { + Log.error("TradeDirect:getHoldings -- error getting user holings", e); + rollBack(conn, e); + } finally { + releaseConn(conn); + } + return holdingDataBeans; + } + + /** + * @see TradeServices#getHolding(Integer) + */ + @Override + public HoldingDataBean getHolding(Integer holdingID) throws Exception { + HoldingDataBean holdingData = null; + Connection conn = null; + try { + + Log.trace("TradeDirect:getHolding - inSession(" + this.inSession + ")", holdingID); + + + conn = getConn(); + holdingData = getHoldingData(holdingID.intValue()); + + commit(conn); + + } catch (Exception e) { + Log.error("TradeDirect:getHolding -- error getting holding " + holdingID + "", e); + rollBack(conn, e); + } finally { + releaseConn(conn); + } + return holdingData; + } + + /** + * @see TradeServices#getAccountData(String) + */ + @Override + public AccountDataBean getAccountData(String userID) throws Exception { + try { + AccountDataBean accountData = null; + Connection conn = null; + try { + + Log.trace("TradeDirect:getAccountData - inSession(" + this.inSession + ")", userID); + + + conn = getConn(); + accountData = getAccountData(conn, userID); + commit(conn); + + } catch (Exception e) { + Log.error("TradeDirect:getAccountData -- error getting account data", e); + rollBack(conn, e); + } finally { + releaseConn(conn); + } + return accountData; + } catch (Exception e) { + throw new Exception(e.getMessage(), e); + } + } + + private AccountDataBean getAccountData(Connection conn, String userID) throws Exception { + PreparedStatement stmt = getStatement(conn, getAccountForUserSQL); + stmt.setString(1, userID); + ResultSet rs = stmt.executeQuery(); + AccountDataBean accountData = getAccountDataFromResultSet(rs); + stmt.close(); + return accountData; + } + + /** + * @see TradeServices#getAccountData(String) + */ + public AccountDataBean getAccountData(int accountID) throws Exception { + AccountDataBean accountData = null; + Connection conn = null; + try { + + Log.trace("TradeDirect:getAccountData - inSession(" + this.inSession + ")", new Integer(accountID)); + + conn = getConn(); + accountData = getAccountData(accountID, conn); + commit(conn); + + } catch (Exception e) { + Log.error("TradeDirect:getAccountData -- error getting account data", e); + rollBack(conn, e); + } finally { + releaseConn(conn); + } + return accountData; + } + + private AccountDataBean getAccountData(int accountID, Connection conn) throws Exception { + PreparedStatement stmt = getStatement(conn, getAccountSQL); + stmt.setInt(1, accountID); + ResultSet rs = stmt.executeQuery(); + AccountDataBean accountData = getAccountDataFromResultSet(rs); + stmt.close(); + return accountData; + } + + private QuoteDataBean getQuoteData(Connection conn, String symbol) throws Exception { + QuoteDataBean quoteData = null; + PreparedStatement stmt = getStatement(conn, getQuoteSQL); + stmt.setString(1, symbol); + ResultSet rs = stmt.executeQuery(); + if (!rs.next()) { + Log.error("TradeDirect:getQuoteData -- could not find quote for symbol=" + symbol); + } else { + quoteData = getQuoteDataFromResultSet(rs); + } + stmt.close(); + return quoteData; + } + + private HoldingDataBean getHoldingData(int holdingID) throws Exception { + HoldingDataBean holdingData = null; + Connection conn = null; + try { + conn = getConn(); + holdingData = getHoldingData(conn, holdingID); + commit(conn); + } catch (Exception e) { + Log.error("TradeDirect:getHoldingData -- error getting data", e); + rollBack(conn, e); + } finally { + releaseConn(conn); + } + return holdingData; + } + + private HoldingDataBean getHoldingData(Connection conn, int holdingID) throws Exception { + HoldingDataBean holdingData = null; + PreparedStatement stmt = getStatement(conn, getHoldingSQL); + stmt.setInt(1, holdingID); + ResultSet rs = stmt.executeQuery(); + if (!rs.next()) { + // already sold + Log.debug("TradeDirect:getHoldingData -- no results -- holdingID=" + holdingID); + } else { + holdingData = getHoldingDataFromResultSet(rs); + } + + stmt.close(); + return holdingData; + } + + private OrderDataBean getOrderData(Connection conn, int orderID) throws Exception { + OrderDataBean orderData = null; + + Log.trace("TradeDirect:getOrderData(conn, " + orderID + ")"); + + PreparedStatement stmt = getStatement(conn, getOrderSQL); + stmt.setInt(1, orderID); + ResultSet rs = stmt.executeQuery(); + if (!rs.next()) { + // already sold + Log.error("TradeDirect:getOrderData -- no results for orderID:" + orderID); + } else { + orderData = getOrderDataFromResultSet(rs); + } + stmt.close(); + return orderData; + } + + /** + * @see TradeServices#getAccountProfileData(String) + */ + @Override + public AccountProfileDataBean getAccountProfileData(String userID) throws Exception { + AccountProfileDataBean accountProfileData = null; + Connection conn = null; + + try { + + Log.trace("TradeDirect:getAccountProfileData - inSession(" + this.inSession + ")", userID); + + + conn = getConn(); + accountProfileData = getAccountProfileData(conn, userID); + commit(conn); + } catch (Exception e) { + Log.error("TradeDirect:getAccountProfileData -- error getting profile data", e); + rollBack(conn, e); + } finally { + releaseConn(conn); + } + return accountProfileData; + } + + private AccountProfileDataBean getAccountProfileData(Connection conn, String userID) throws Exception { + PreparedStatement stmt = getStatement(conn, getAccountProfileSQL); + stmt.setString(1, userID); + + ResultSet rs = stmt.executeQuery(); + + AccountProfileDataBean accountProfileData = getAccountProfileDataFromResultSet(rs); + stmt.close(); + return accountProfileData; + } + + private AccountProfileDataBean getAccountProfileData(Connection conn, Integer accountID) throws Exception { + PreparedStatement stmt = getStatement(conn, getAccountProfileForAccountSQL); + stmt.setInt(1, accountID.intValue()); + + ResultSet rs = stmt.executeQuery(); + + AccountProfileDataBean accountProfileData = getAccountProfileDataFromResultSet(rs); + stmt.close(); + return accountProfileData; + } + + /** + * @see TradeServices#updateAccountProfile(AccountProfileDataBean) + */ + @Override + public AccountProfileDataBean updateAccountProfile(AccountProfileDataBean profileData) throws Exception { + AccountProfileDataBean accountProfileData = null; + Connection conn = null; + + try { + + Log.trace("TradeDirect:updateAccountProfileData - inSession(" + this.inSession + ")", profileData.getUserID()); + + conn = getConn(); + updateAccountProfile(conn, profileData); + + accountProfileData = getAccountProfileData(conn, profileData.getUserID()); + commit(conn); + } catch (Exception e) { + Log.error("TradeDirect:getAccountProfileData -- error getting profile data", e); + rollBack(conn, e); + } finally { + releaseConn(conn); + } + return accountProfileData; + } + + private void creditAccountBalance(Connection conn, AccountDataBean accountData, BigDecimal credit) throws Exception { + PreparedStatement stmt = getStatement(conn, creditAccountBalanceSQL); + + stmt.setBigDecimal(1, credit); + stmt.setInt(2, accountData.getAccountID().intValue()); + + stmt.executeUpdate(); + stmt.close(); + + } + + // Set Timestamp to zero to denote sell is inflight + // UPDATE -- could add a "status" attribute to holding + private void updateHoldingStatus(Connection conn, Integer holdingID, String symbol) throws Exception { + Timestamp ts = new Timestamp(0); + PreparedStatement stmt = getStatement(conn, "update holdingejb set purchasedate= ? where holdingid = ?"); + + stmt.setTimestamp(1, ts); + stmt.setInt(2, holdingID.intValue()); + stmt.executeUpdate(); + stmt.close(); + } + + private void updateOrderStatus(Connection conn, Integer orderID, String status) throws Exception { + PreparedStatement stmt = getStatement(conn, updateOrderStatusSQL); + + stmt.setString(1, status); + stmt.setTimestamp(2, new Timestamp(System.currentTimeMillis())); + stmt.setInt(3, orderID.intValue()); + stmt.executeUpdate(); + stmt.close(); + } + + private void updateOrderHolding(Connection conn, int orderID, int holdingID) throws Exception { + PreparedStatement stmt = getStatement(conn, updateOrderHoldingSQL); + + stmt.setInt(1, holdingID); + stmt.setInt(2, orderID); + stmt.executeUpdate(); + stmt.close(); + } + + private void updateAccountProfile(Connection conn, AccountProfileDataBean profileData) throws Exception { + PreparedStatement stmt = getStatement(conn, updateAccountProfileSQL); + + stmt.setString(1, profileData.getPassword()); + stmt.setString(2, profileData.getFullName()); + stmt.setString(3, profileData.getAddress()); + stmt.setString(4, profileData.getEmail()); + stmt.setString(5, profileData.getCreditCard()); + stmt.setString(6, profileData.getUserID()); + + stmt.executeUpdate(); + stmt.close(); + } + + @Override + public QuoteDataBean updateQuotePriceVolume(String symbol, BigDecimal changeFactor, double sharesTraded) throws Exception { + return updateQuotePriceVolumeInt(symbol, changeFactor, sharesTraded, TradeConfig.getPublishQuotePriceChange()); + } + + /** + * Update a quote's price and volume + * + * @param symbol + * The PK of the quote + * @param changeFactor + * the percent to change the old price by (between 50% and 150%) + * @param sharedTraded + * the ammount to add to the current volume + * @param publishQuotePriceChange + * used by the PingJDBCWrite Primitive to ensure no JMS is used, + * should be true for all normal calls to this API + */ + public QuoteDataBean updateQuotePriceVolumeInt(String symbol, BigDecimal changeFactor, double sharesTraded, boolean publishQuotePriceChange) + throws Exception { + + if (TradeConfig.getUpdateQuotePrices() == false) { + return new QuoteDataBean(); + } + + QuoteDataBean quoteData = null; + Connection conn = null; + + try { + Log.trace("TradeDirect:updateQuotePriceVolume - inSession(" + this.inSession + ")", symbol, changeFactor, new Double(sharesTraded)); + + conn = getConn(); + + quoteData = getQuoteForUpdate(conn, symbol); + BigDecimal oldPrice = quoteData.getPrice(); + BigDecimal openPrice = quoteData.getOpen(); + + double newVolume = quoteData.getVolume() + sharesTraded; + + if (oldPrice.equals(TradeConfig.PENNY_STOCK_PRICE)) { + changeFactor = TradeConfig.PENNY_STOCK_RECOVERY_MIRACLE_MULTIPLIER; + } else if (oldPrice.compareTo(TradeConfig.MAXIMUM_STOCK_PRICE) > 0) { + changeFactor = TradeConfig.MAXIMUM_STOCK_SPLIT_MULTIPLIER; + } + + BigDecimal newPrice = changeFactor.multiply(oldPrice).setScale(2, BigDecimal.ROUND_HALF_UP); + double change = newPrice.subtract(openPrice).doubleValue(); + + updateQuotePriceVolume(conn, quoteData.getSymbol(), newPrice, newVolume, change); + quoteData = getQuote(conn, symbol); + + commit(conn); + + if (publishQuotePriceChange) { + publishQuotePriceChange(quoteData, oldPrice, changeFactor, sharesTraded); + } + + recentQuotePriceChangeList.add(quoteData); + + } catch (Exception e) { + Log.error("TradeDirect:updateQuotePriceVolume -- error updating quote price/volume for symbol:" + symbol); + rollBack(conn, e); + throw e; + } finally { + releaseConn(conn); + } + return quoteData; + } + + private void updateQuotePriceVolume(Connection conn, String symbol, BigDecimal newPrice, double newVolume, double change) throws Exception { + + PreparedStatement stmt = getStatement(conn, updateQuotePriceVolumeSQL); + + stmt.setBigDecimal(1, newPrice); + stmt.setDouble(2, change); + stmt.setDouble(3, newVolume); + stmt.setString(4, symbol); + + stmt.executeUpdate(); + stmt.close(); + } + + private void publishQuotePriceChange(QuoteDataBean quoteData, BigDecimal oldPrice, BigDecimal changeFactor, double sharesTraded) throws Exception { + + Log.trace("TradeDirect:publishQuotePrice PUBLISHING to MDB quoteData = " + quoteData); + + try (JMSContext context = topicConnectionFactory.createContext();){ + TextMessage message = context.createTextMessage(); + + message.setStringProperty("command", "updateQuote"); + message.setStringProperty("symbol", quoteData.getSymbol()); + message.setStringProperty("company", quoteData.getCompanyName()); + message.setStringProperty("price", quoteData.getPrice().toString()); + message.setStringProperty("oldPrice", oldPrice.toString()); + message.setStringProperty("open", quoteData.getOpen().toString()); + message.setStringProperty("low", quoteData.getLow().toString()); + message.setStringProperty("high", quoteData.getHigh().toString()); + message.setDoubleProperty("volume", quoteData.getVolume()); + + message.setStringProperty("changeFactor", changeFactor.toString()); + message.setDoubleProperty("sharesTraded", sharesTraded); + message.setLongProperty("publishTime", System.currentTimeMillis()); + message.setText("Update Stock price for " + quoteData.getSymbol() + " old price = " + oldPrice + " new price = " + quoteData.getPrice()); + + + context.createProducer().send(tradeStreamerTopic, message); + + } catch (Exception e) { + throw e; // pass exception back + + } + } + + /** + * @see TradeServices#login(String, String) + */ + + @Override + public AccountDataBean login(String userID, String password) throws Exception { + + AccountDataBean accountData = null; + Connection conn = null; + try { + Log.trace("TradeDirect:login - inSession(" + this.inSession + ")", userID, password); + + conn = getConn(); + PreparedStatement stmt = getStatement(conn, getAccountProfileSQL); + stmt.setString(1, userID); + + ResultSet rs = stmt.executeQuery(); + if (!rs.next()) { + Log.error("TradeDirect:login -- failure to find account for" + userID); + throw new javax.ejb.FinderException("Cannot find account for" + userID); + } + + String pw = rs.getString("passwd"); + stmt.close(); + if ((pw == null) || (pw.equals(password) == false)) { + String error = "TradeDirect:Login failure for user: " + userID + "\n\tIncorrect password-->" + userID + ":" + password; + Log.error(error); + throw new Exception(error); + } + + stmt = getStatement(conn, loginSQL); + stmt.setTimestamp(1, new Timestamp(System.currentTimeMillis())); + stmt.setString(2, userID); + + stmt.executeUpdate(); + stmt.close(); + + stmt = getStatement(conn, getAccountForUserSQL); + stmt.setString(1, userID); + rs = stmt.executeQuery(); + + accountData = getAccountDataFromResultSet(rs); + + stmt.close(); + + commit(conn); + } catch (Exception e) { + Log.error("TradeDirect:login -- error logging in user", e); + rollBack(conn, e); + } finally { + releaseConn(conn); + } + return accountData; + + /* + * setLastLogin( new Timestamp(System.currentTimeMillis()) ); + * setLoginCount( getLoginCount() + 1 ); + */ + } + + /** + * @see TradeServices#logout(String) + */ + @Override + public void logout(String userID) throws Exception { + Log.trace("TradeDirect:logout - inSession(" + this.inSession + ")", userID); + + Connection conn = null; + try { + conn = getConn(); + PreparedStatement stmt = getStatement(conn, logoutSQL); + stmt.setString(1, userID); + stmt.executeUpdate(); + stmt.close(); + + commit(conn); + } catch (Exception e) { + Log.error("TradeDirect:logout -- error logging out user", e); + rollBack(conn, e); + } finally { + releaseConn(conn); + } + } + + /** + * @see TradeServices#register(String, String, String, String, String, + * String, BigDecimal, boolean) + */ + + @Override + public AccountDataBean register(String userID, String password, String fullname, String address, String email, String creditcard, BigDecimal openBalance) + throws Exception { + + AccountDataBean accountData = null; + Connection conn = null; + try { + Log.trace("TradeDirect:register - inSession(" + this.inSession + ")"); + + conn = getConn(); + PreparedStatement stmt = getStatement(conn, createAccountSQL); + + Integer accountID = KeySequenceDirect.getNextID(conn, "account", inSession, getInGlobalTxn()); + BigDecimal balance = openBalance; + Timestamp creationDate = new Timestamp(System.currentTimeMillis()); + Timestamp lastLogin = creationDate; + int loginCount = 0; + int logoutCount = 0; + + stmt.setInt(1, accountID.intValue()); + stmt.setTimestamp(2, creationDate); + stmt.setBigDecimal(3, openBalance); + stmt.setBigDecimal(4, balance); + stmt.setTimestamp(5, lastLogin); + stmt.setInt(6, loginCount); + stmt.setInt(7, logoutCount); + stmt.setString(8, userID); + stmt.executeUpdate(); + stmt.close(); + + stmt = getStatement(conn, createAccountProfileSQL); + stmt.setString(1, userID); + stmt.setString(2, password); + stmt.setString(3, fullname); + stmt.setString(4, address); + stmt.setString(5, email); + stmt.setString(6, creditcard); + stmt.executeUpdate(); + stmt.close(); + + commit(conn); + + accountData = new AccountDataBean(accountID, loginCount, logoutCount, lastLogin, creationDate, balance, openBalance, userID); + + } catch (Exception e) { + Log.error("TradeDirect:register -- error registering new user", e); + } finally { + releaseConn(conn); + } + return accountData; + } + + private AccountDataBean getAccountDataFromResultSet(ResultSet rs) throws Exception { + AccountDataBean accountData = null; + + if (!rs.next()) { + Log.error("TradeDirect:getAccountDataFromResultSet -- cannot find account data"); + } else { + accountData = new AccountDataBean(new Integer(rs.getInt("accountID")), rs.getInt("loginCount"), rs.getInt("logoutCount"), + rs.getTimestamp("lastLogin"), rs.getTimestamp("creationDate"), rs.getBigDecimal("balance"), rs.getBigDecimal("openBalance"), + rs.getString("profile_userID")); + } + return accountData; + } + + private AccountProfileDataBean getAccountProfileDataFromResultSet(ResultSet rs) throws Exception { + AccountProfileDataBean accountProfileData = null; + + if (!rs.next()) { + Log.error("TradeDirect:getAccountProfileDataFromResultSet -- cannot find accountprofile data"); + } else { + accountProfileData = new AccountProfileDataBean(rs.getString("userID"), rs.getString("passwd"), rs.getString("fullName"), rs.getString("address"), + rs.getString("email"), rs.getString("creditCard")); + } + + return accountProfileData; + } + + private HoldingDataBean getHoldingDataFromResultSet(ResultSet rs) throws Exception { + HoldingDataBean holdingData = null; + + holdingData = new HoldingDataBean(new Integer(rs.getInt("holdingID")), rs.getDouble("quantity"), rs.getBigDecimal("purchasePrice"), + rs.getTimestamp("purchaseDate"), rs.getString("quote_symbol")); + return holdingData; + } + + private QuoteDataBean getQuoteDataFromResultSet(ResultSet rs) throws Exception { + QuoteDataBean quoteData = null; + + quoteData = new QuoteDataBean(rs.getString("symbol"), rs.getString("companyName"), rs.getDouble("volume"), rs.getBigDecimal("price"), + rs.getBigDecimal("open1"), rs.getBigDecimal("low"), rs.getBigDecimal("high"), rs.getDouble("change1")); + return quoteData; + } + + private OrderDataBean getOrderDataFromResultSet(ResultSet rs) throws Exception { + OrderDataBean orderData = null; + + orderData = new OrderDataBean(new Integer(rs.getInt("orderID")), rs.getString("orderType"), rs.getString("orderStatus"), rs.getTimestamp("openDate"), + rs.getTimestamp("completionDate"), rs.getDouble("quantity"), rs.getBigDecimal("price"), rs.getBigDecimal("orderFee"), + rs.getString("quote_symbol")); + return orderData; + } + + public boolean recreateDBTables(Object[] sqlBuffer, java.io.PrintWriter out) throws Exception { + // Clear MDB Statistics + MDBStats.getInstance().reset(); + + Connection conn = null; + boolean success = false; + try { + + Log.trace("TradeDirect:recreateDBTables"); + + conn = getConn(); + Statement stmt = conn.createStatement(); + int bufferLength = sqlBuffer.length; + for (int i = 0; i < bufferLength; i++) { + try { + stmt.executeUpdate((String) sqlBuffer[i]); + // commit(conn); + } catch (SQLException ex) { + // Ignore DROP statements as tables won't always exist. + if (((String) sqlBuffer[i]).indexOf("DROP ") < 0) { + Log.error("TradeDirect:recreateDBTables SQL Exception thrown on executing the foll sql command: " + sqlBuffer[i], ex); + out.println("
    SQL Exception thrown on executing the foll sql command: " + sqlBuffer[i] + " . Check log for details.
    "); + } + } + } + stmt.close(); + commit(conn); + success = true; + } catch (Exception e) { + Log.error(e, "TradeDirect:recreateDBTables() -- Error dropping and recreating the database tables"); + } finally { + releaseConn(conn); + } + return success; + } + + ; + + + + private void releaseConn(Connection conn) throws Exception { + try { + if (conn != null) { + conn.close(); + if (Log.doTrace()) { + synchronized (lock) { + connCount--; + } + Log.trace("TradeDirect:releaseConn -- connection closed, connCount=" + connCount); + } + } + } catch (Exception e) { + Log.error("TradeDirect:releaseConnection -- failed to close connection", e); + } + } + + + /* + * Allocate a new connection to the datasource + */ + private static int connCount = 0; + + private static Integer lock = new Integer(0); + + private Connection getConn() throws Exception { + + Connection conn = datasource.getConnection(); + + if (!this.inGlobalTxn) { + conn.setAutoCommit(false); + } + if (Log.doTrace()) { + synchronized (lock) { + connCount++; + } + Log.trace("TradeDirect:getConn -- new connection allocated, IsolationLevel=" + conn.getTransactionIsolation() + " connectionCount = " + connCount); + } + + return conn; + } + + public Connection getConnPublic() throws Exception { + return getConn(); + } + + /* + * Commit the provided connection if not under Global Transaction scope - + * conn.commit() is not allowed in a global transaction. the txn manager + * will perform the commit + */ + private void commit(Connection conn) throws Exception { + if (!inSession) { + if ((getInGlobalTxn() == false) && (conn != null)) { + conn.commit(); + } + } + } + + /* + * Rollback the statement for the given connection + */ + private void rollBack(Connection conn, Exception e) throws Exception { + if (!inSession) { + Log.log("TradeDirect:rollBack -- rolling back conn due to previously caught exception -- inGlobalTxn=" + getInGlobalTxn()); + if ((getInGlobalTxn() == false) && (conn != null)) { + conn.rollback(); + } else { + throw e; // Throw the exception + // so the Global txn manager will rollBack + } + } + } + + /* + * Allocate a new prepared statment for this connection + */ + private PreparedStatement getStatement(Connection conn, String sql) throws Exception { + return conn.prepareStatement(sql); + } + + private PreparedStatement getStatement(Connection conn, String sql, int type, int concurrency) throws Exception { + return conn.prepareStatement(sql, type, concurrency); + } + + private static final String createQuoteSQL = "insert into quoteejb " + "( symbol, companyName, volume, price, open1, low, high, change1 ) " + + "VALUES ( ? , ? , ? , ? , ? , ? , ? , ? )"; + + private static final String createAccountSQL = "insert into accountejb " + + "( accountid, creationDate, openBalance, balance, lastLogin, loginCount, logoutCount, profile_userid) " + + "VALUES ( ? , ? , ? , ? , ? , ? , ? , ? )"; + + private static final String createAccountProfileSQL = "insert into accountprofileejb " + "( userid, passwd, fullname, address, email, creditcard ) " + + "VALUES ( ? , ? , ? , ? , ? , ? )"; + + private static final String createHoldingSQL = "insert into holdingejb " + + "( holdingid, purchaseDate, purchasePrice, quantity, quote_symbol, account_accountid ) " + "VALUES ( ? , ? , ? , ? , ? , ? )"; + + private static final String createOrderSQL = "insert into orderejb " + + "( orderid, ordertype, orderstatus, opendate, quantity, price, orderfee, account_accountid, holding_holdingid, quote_symbol) " + + "VALUES ( ? , ? , ? , ? , ? , ? , ? , ? , ? , ?)"; + + private static final String removeHoldingSQL = "delete from holdingejb where holdingid = ?"; + + private static final String removeHoldingFromOrderSQL = "update orderejb set holding_holdingid=null where holding_holdingid = ?"; + + private static final String updateAccountProfileSQL = "update accountprofileejb set " + "passwd = ?, fullname = ?, address = ?, email = ?, creditcard = ? " + + "where userid = (select profile_userid from accountejb a " + "where a.profile_userid=?)"; + + private static final String loginSQL = "update accountejb set lastLogin=?, logincount=logincount+1 " + "where profile_userid=?"; + + private static final String logoutSQL = "update accountejb set logoutcount=logoutcount+1 " + "where profile_userid=?"; + + private static final String getAccountSQL = "select * from accountejb a where a.accountid = ?"; + + private static final String getAccountProfileSQL = "select * from accountprofileejb ap where ap.userid = " + + "(select profile_userid from accountejb a where a.profile_userid=?)"; + + private static final String getAccountProfileForAccountSQL = "select * from accountprofileejb ap where ap.userid = " + + "(select profile_userid from accountejb a where a.accountid=?)"; + + private static final String getAccountForUserSQL = "select * from accountejb a where a.profile_userid = " + + "( select userid from accountprofileejb ap where ap.userid = ?)"; + + private static final String getHoldingSQL = "select * from holdingejb h where h.holdingid = ?"; + + private static final String getHoldingsForUserSQL = "select * from holdingejb h where h.account_accountid = " + + "(select a.accountid from accountejb a where a.profile_userid = ?)"; + + private static final String getOrderSQL = "select * from orderejb o where o.orderid = ?"; + + private static final String getOrdersByUserSQL = "select * from orderejb o where o.account_accountid = " + + "(select a.accountid from accountejb a where a.profile_userid = ?)"; + + private static final String getClosedOrdersSQL = "select * from orderejb o " + "where o.orderstatus = 'closed' AND o.account_accountid = " + + "(select a.accountid from accountejb a where a.profile_userid = ?)"; + + private static final String getQuoteSQL = "select * from quoteejb q where q.symbol=?"; + + private static final String getAllQuotesSQL = "select * from quoteejb q"; + + private static final String getQuoteForUpdateSQL = "select * from quoteejb q where q.symbol=? For Update"; + + private static final String getTSIAQuotesOrderByChangeSQL = "select * from quoteejb q order by q.change1"; + + private static final String getTSIASQL = "select SUM(price)/count(*) as TSIA from quoteejb q "; + + private static final String getOpenTSIASQL = "select SUM(open1)/count(*) as openTSIA from quoteejb q "; + + private static final String getTSIATotalVolumeSQL = "select SUM(volume) as totalVolume from quoteejb q "; + + private static final String creditAccountBalanceSQL = "update accountejb set " + "balance = balance + ? " + "where accountid = ?"; + + private static final String updateOrderStatusSQL = "update orderejb set " + "orderstatus = ?, completiondate = ? " + "where orderid = ?"; + + private static final String updateOrderHoldingSQL = "update orderejb set " + "holding_holdingID = ? " + "where orderid = ?"; + + private static final String updateQuotePriceVolumeSQL = "update quoteejb set " + "price = ?, change1 = ?, volume = ? " + "where symbol = ?"; + + /** + * Gets the inGlobalTxn + * + * @return Returns a boolean + */ + private boolean getInGlobalTxn() { + return inGlobalTxn; + } + + /** + * Sets the inGlobalTxn + * + * @param inGlobalTxn + * The inGlobalTxn to set + */ + private void setInGlobalTxn(boolean inGlobalTxn) { + this.inGlobalTxn = inGlobalTxn; + } + + public void setInSession(boolean inSession) { + this.inSession = inSession; + } + + @Override + public int getImpl() { + return TradeConfig.DIRECT; + } + + + + @Override + public QuoteDataBean pingTwoPhase(String symbol) { + throw new UnsupportedOperationException(); + } + + + + @Override + public double investmentReturn(double rnd1, double rnd2) { + throw new UnsupportedOperationException(); + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/impl/direct/TradeDirectDBUtils.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/impl/direct/TradeDirectDBUtils.java new file mode 100644 index 00000000..c9284dc7 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/impl/direct/TradeDirectDBUtils.java @@ -0,0 +1,472 @@ +/** + * (C) Copyright IBM Corporation 2019. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.impl.direct; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.math.BigDecimal; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; + +import javax.annotation.Resource; +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; +import javax.sql.DataSource; + +import com.ibm.websphere.samples.daytrader.beans.RunStatsDataBean; +import com.ibm.websphere.samples.daytrader.entities.AccountDataBean; +import com.ibm.websphere.samples.daytrader.interfaces.TradeDB; +import com.ibm.websphere.samples.daytrader.interfaces.TradeJDBC; +import com.ibm.websphere.samples.daytrader.interfaces.TradeServices; +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.MDBStats; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; + +/** + * TradeBuildDB uses operations provided by the TradeApplication to (a) create the Database tables + * (b)populate a DayTrader database without creating the tables. Specifically, a + * new DayTrader User population is created using UserIDs of the form "uid:xxx" + * where xxx is a sequential number (e.g. uid:0, uid:1, etc.). New stocks are also created of the + * form "s:xxx", again where xxx represents sequential numbers (e.g. s:1, s:2, etc.) + */ +@ApplicationScoped +public class TradeDirectDBUtils implements TradeDB { + + // For Wildfly - add java:/ to this resource. + + @Resource(lookup = "jdbc/TradeDataSource") + //@Resource(lookup = "java:/jdbc/TradeDataSource") + private DataSource datasource; + + @Inject + @TradeJDBC + TradeServices ts; + + public String checkDBProductName() throws Exception { + Connection conn = null; + String dbProductName = null; + + try { + + conn = datasource.getConnection(); + DatabaseMetaData dbmd = conn.getMetaData(); + dbProductName = dbmd.getDatabaseProductName(); + } catch (SQLException e) { + Log.error(e, "TradeDirect:checkDBProductName() -- Error checking the Daytrader Database Product Name"); + } finally { + conn.close(); + } + return dbProductName; + } + + + /** + * Re-create the DayTrader db tables and populate them OR just populate a DayTrader DB, logging to the provided output stream + */ + public void buildDB(java.io.PrintWriter out, InputStream ddlFile) throws Exception { + String symbol, companyName; + int errorCount = 0; // Give up gracefully after 10 errors + + // TradeStatistics.statisticsEnabled=false; // disable statistics + out.println("
    TradeBuildDB: Building DayTrader Database...
    This operation will take several minutes. Please wait..."); + out.println(""); + + if (ddlFile != null) { + //out.println("
    TradeBuildDB: **** warPath= "+warPath+" ****
    "); + + boolean success = false; + + Object[] sqlBuffer = null; + + //parse the DDL file and fill the SQL commands into a buffer + try { + sqlBuffer = parseDDLToBuffer(ddlFile); + } catch (Exception e) { + Log.error(e, "TradeBuildDB: Unable to parse DDL file"); + out.println("
    TradeBuildDB: **** Unable to parse DDL file for the specified database ****
    "); + return; + } + if ((sqlBuffer == null) || (sqlBuffer.length == 0)) { + out.println("
    TradeBuildDB: **** Parsing DDL file returned empty buffer, please check that a valid DB specific DDL file is available and retry ****
    "); + return; + } + + // send the sql commands buffer to drop and recreate the Daytrader tables + out.println("
    TradeBuildDB: **** Dropping and Recreating the DayTrader tables... ****
    "); + try { + success = recreateDBTables(sqlBuffer, out); + } catch (Exception e) { + Log.error(e, "TradeBuildDB: Unable to drop and recreate DayTrader Db Tables, please check for database consistency before continuing"); + out.println("TradeBuildDB: Unable to drop and recreate DayTrader Db Tables, please check for database consistency before continuing"); + return; + } + if (!success) { + out.println("
    TradeBuildDB: **** Unable to drop and recreate DayTrader Db Tables, please check for database consistency before continuing ****
    "); + return; + } + out.println("
    TradeBuildDB: **** DayTrader tables successfully created! ****

    Please Stop and Re-start your Daytrader application (or your application server) and then use the \"Repopulate Daytrader Database\" link to populate your database.


    "); + return; + } // end of createDBTables + + out.println("
    TradeBuildDB: **** Creating " + TradeConfig.getMAX_QUOTES() + " Quotes ****
    "); + //Attempt to delete all of the Trade users and Trade Quotes first + try { + resetTrade(true); + } catch (Exception e) { + Log.error(e, "TradeBuildDB: Unable to delete Trade users (uid:0, uid:1, ...) and Trade Quotes (s:0, s:1, ...)"); + } + for (int i = 0; i < TradeConfig.getMAX_QUOTES(); i++) { + symbol = "s:" + i; + companyName = "S" + i + " Incorporated"; + try { + ts.createQuote(symbol, companyName, new java.math.BigDecimal(TradeConfig.rndPrice())); + if (i % 10 == 0) { + out.print("....." + symbol); + if (i % 100 == 0) { + out.println(" -
    "); + out.flush(); + } + } + } catch (Exception e) { + if (errorCount++ >= 10) { + String error = "Populate Trade DB aborting after 10 create quote errors. Check the EJB datasource configuration. Check the log for details

    Exception is:
    " + + e.toString(); + Log.error(e, error); + throw e; + } + } + } + out.println("
    "); + out.println("
    **** Registering " + TradeConfig.getMAX_USERS() + " Users **** "); + errorCount = 0; //reset for user registrations + + // Registration is a formal operation in Trade 2. + for (int i = 0; i < TradeConfig.getMAX_USERS(); i++) { + String userID = "uid:" + i; + String fullname = TradeConfig.rndFullName(); + String email = TradeConfig.rndEmail(userID); + String address = TradeConfig.rndAddress(); + String creditcard = TradeConfig.rndCreditCard(); + double initialBalance = (double) (TradeConfig.rndInt(100000)) + 200000; + if (i == 0) { + initialBalance = 1000000; // uid:0 starts with a cool million. + } + try { + AccountDataBean accountData = ts.register(userID, "xxx", fullname, address, email, creditcard, new BigDecimal(initialBalance)); + + if (accountData != null) { + if (i % 50 == 0) { + out.print("
    Account# " + accountData.getAccountID() + " userID=" + userID); + } // end-if + + int holdings = TradeConfig.rndInt(TradeConfig.getMAX_HOLDINGS() + 1); // 0-MAX_HOLDING (inclusive), avg holdings per user = (MAX-0)/2 + double quantity = 0; + + for (int j = 0; j < holdings; j++) { + symbol = TradeConfig.rndSymbol(); + quantity = TradeConfig.rndQuantity(); + ts.buy(userID, symbol, quantity, TradeConfig.getOrderProcessingMode()); + } // end-for + if (i % 50 == 0) { + out.println(" has " + holdings + " holdings."); + out.flush(); + } // end-if + } else { + out.println("
    UID " + userID + " already registered.
    "); + out.flush(); + } // end-if + + } catch (Exception e) { + if (errorCount++ >= 10) { + String error = "Populate Trade DB aborting after 10 user registration errors. Check the log for details.

    Exception is:
    " + + e.toString(); + Log.error(e, error); + throw e; + } + } + } // end-for + out.println(""); + } + + private boolean recreateDBTables(Object[] sqlBuffer, java.io.PrintWriter out) throws Exception { + // Clear MDB Statistics + MDBStats.getInstance().reset(); + + Connection conn = null; + boolean success = false; + try { + conn = datasource.getConnection(); + Statement stmt = conn.createStatement(); + int bufferLength = sqlBuffer.length; + for (int i = 0; i < bufferLength; i++) { + try { + stmt.executeUpdate((String) sqlBuffer[i]); + // commit(conn); + } catch (SQLException ex) { + // Ignore DROP statements as tables won't always exist. + if (((String) sqlBuffer[i]).indexOf("DROP ") < 0) { + Log.error("TradeDirect:recreateDBTables SQL Exception thrown on executing the foll sql command: " + sqlBuffer[i], ex); + out.println("
    SQL Exception thrown on executing the foll sql command: " + sqlBuffer[i] + " . Check log for details.
    "); + } + } + } + stmt.close(); + conn.commit(); + success = true; + } catch (Exception e) { + Log.error(e, "TradeDirect:recreateDBTables() -- Error dropping and recreating the database tables"); + } finally { + conn.close(); + } + return success; + } + + + public RunStatsDataBean resetTrade(boolean deleteAll) throws Exception { + // Clear MDB Statistics + MDBStats.getInstance().reset(); + // Reset Trade + + RunStatsDataBean runStatsData = new RunStatsDataBean(); + Connection conn = null; + try { + + conn = datasource.getConnection(); + conn.setAutoCommit(false); + PreparedStatement stmt = null; + ResultSet rs = null; + + if (deleteAll) { + try { + stmt = getStatement(conn, "delete from quoteejb"); + stmt.executeUpdate(); + stmt.close(); + stmt = getStatement(conn, "delete from accountejb"); + stmt.executeUpdate(); + stmt.close(); + stmt = getStatement(conn, "delete from accountprofileejb"); + stmt.executeUpdate(); + stmt.close(); + stmt = getStatement(conn, "delete from holdingejb"); + stmt.executeUpdate(); + stmt.close(); + stmt = getStatement(conn, "delete from orderejb"); + stmt.executeUpdate(); + stmt.close(); + // FUTURE: - DuplicateKeyException - For now, don't start at + // zero as KeySequenceDirect and KeySequenceBean will still + // give out + // the cached Block and then notice this change. Better + // solution is + // to signal both classes to drop their cached blocks + // stmt = getStatement(conn, "delete from keygenejb"); + // stmt.executeUpdate(); + // stmt.close(); + conn.commit(); + } catch (Exception e) { + Log.error(e, "TradeDirect:resetTrade(deleteAll) -- Error deleting Trade users and stock from the Trade database"); + } + return runStatsData; + } + + stmt = getStatement(conn, "delete from holdingejb where holdingejb.account_accountid is null"); + stmt.executeUpdate(); + stmt.close(); + + // Count and Delete newly registered users (users w/ id that start + // "ru:%": + stmt = getStatement(conn, "delete from accountprofileejb where userid like 'ru:%'"); + stmt.executeUpdate(); + stmt.close(); + + stmt = getStatement(conn, "delete from orderejb where account_accountid in (select accountid from accountejb a where a.profile_userid like 'ru:%')"); + stmt.executeUpdate(); + stmt.close(); + + stmt = getStatement(conn, + "delete from holdingejb where account_accountid in (select accountid from accountejb a where a.profile_userid like 'ru:%')"); + stmt.executeUpdate(); + stmt.close(); + + stmt = getStatement(conn, "delete from accountejb where profile_userid like 'ru:%'"); + int newUserCount = stmt.executeUpdate(); + runStatsData.setNewUserCount(newUserCount); + stmt.close(); + + // Count of trade users + stmt = getStatement(conn, "select count(accountid) as \"tradeUserCount\" from accountejb a where a.profile_userid like 'uid:%'"); + rs = stmt.executeQuery(); + rs.next(); + int tradeUserCount = rs.getInt("tradeUserCount"); + runStatsData.setTradeUserCount(tradeUserCount); + stmt.close(); + + rs.close(); + // Count of trade stocks + stmt = getStatement(conn, "select count(symbol) as \"tradeStockCount\" from quoteejb a where a.symbol like 's:%'"); + rs = stmt.executeQuery(); + rs.next(); + int tradeStockCount = rs.getInt("tradeStockCount"); + runStatsData.setTradeStockCount(tradeStockCount); + stmt.close(); + + // Count of trade users login, logout + stmt = getStatement(conn, + "select sum(loginCount) as \"sumLoginCount\", sum(logoutCount) as \"sumLogoutCount\" from accountejb a where a.profile_userID like 'uid:%'"); + rs = stmt.executeQuery(); + rs.next(); + int sumLoginCount = rs.getInt("sumLoginCount"); + int sumLogoutCount = rs.getInt("sumLogoutCount"); + runStatsData.setSumLoginCount(sumLoginCount); + runStatsData.setSumLogoutCount(sumLogoutCount); + stmt.close(); + + rs.close(); + // Update logoutcount and loginCount back to zero + + stmt = getStatement(conn, "update accountejb set logoutCount=0,loginCount=0 where profile_userID like 'uid:%'"); + stmt.executeUpdate(); + stmt.close(); + + // count holdings for trade users + stmt = getStatement(conn, "select count(holdingid) as \"holdingCount\" from holdingejb h where h.account_accountid in " + + "(select accountid from accountejb a where a.profile_userid like 'uid:%')"); + + rs = stmt.executeQuery(); + rs.next(); + int holdingCount = rs.getInt("holdingCount"); + runStatsData.setHoldingCount(holdingCount); + stmt.close(); + rs.close(); + + // count orders for trade users + stmt = getStatement(conn, "select count(orderid) as \"orderCount\" from orderejb o where o.account_accountid in " + + "(select accountid from accountejb a where a.profile_userid like 'uid:%')"); + + rs = stmt.executeQuery(); + rs.next(); + int orderCount = rs.getInt("orderCount"); + runStatsData.setOrderCount(orderCount); + stmt.close(); + rs.close(); + + // count orders by type for trade users + stmt = getStatement(conn, "select count(orderid) \"buyOrderCount\"from orderejb o where (o.account_accountid in " + + "(select accountid from accountejb a where a.profile_userid like 'uid:%')) AND " + " (o.orderType='buy')"); + + rs = stmt.executeQuery(); + rs.next(); + int buyOrderCount = rs.getInt("buyOrderCount"); + runStatsData.setBuyOrderCount(buyOrderCount); + stmt.close(); + rs.close(); + + // count orders by type for trade users + stmt = getStatement(conn, "select count(orderid) \"sellOrderCount\"from orderejb o where (o.account_accountid in " + + "(select accountid from accountejb a where a.profile_userid like 'uid:%')) AND " + " (o.orderType='sell')"); + + rs = stmt.executeQuery(); + rs.next(); + int sellOrderCount = rs.getInt("sellOrderCount"); + runStatsData.setSellOrderCount(sellOrderCount); + stmt.close(); + rs.close(); + + // Delete cancelled orders + stmt = getStatement(conn, "delete from orderejb where orderStatus='cancelled'"); + int cancelledOrderCount = stmt.executeUpdate(); + runStatsData.setCancelledOrderCount(cancelledOrderCount); + stmt.close(); + rs.close(); + + // count open orders by type for trade users + stmt = getStatement(conn, "select count(orderid) \"openOrderCount\"from orderejb o where (o.account_accountid in " + + "(select accountid from accountejb a where a.profile_userid like 'uid:%')) AND " + " (o.orderStatus='open')"); + + rs = stmt.executeQuery(); + rs.next(); + int openOrderCount = rs.getInt("openOrderCount"); + runStatsData.setOpenOrderCount(openOrderCount); + + stmt.close(); + rs.close(); + // Delete orders for holding which have been purchased and sold + stmt = getStatement(conn, "delete from orderejb where holding_holdingid is null"); + int deletedOrderCount = stmt.executeUpdate(); + runStatsData.setDeletedOrderCount(deletedOrderCount); + stmt.close(); + rs.close(); + + conn.commit(); + + System.out.println("TradeDirect:reset Run stats data\n\n" + runStatsData); + } catch (Exception e) { + Log.error(e, "Failed to reset Trade"); + conn.rollback(); + throw e; + } finally { + conn.close(); + } + return runStatsData; + + } + + private PreparedStatement getStatement(Connection conn, String sql) throws Exception { + return conn.prepareStatement(sql); + } + + public Object[] parseDDLToBuffer(InputStream ddlFile) throws Exception { + BufferedReader br = null; + ArrayList sqlBuffer = new ArrayList(30); //initial capacity 30 assuming we have 30 ddl-sql statements to read + + try { + br = new BufferedReader(new InputStreamReader(ddlFile)); + String s; + String sql = new String(); + while ((s = br.readLine()) != null) { + s = s.trim(); + if ((s.length() != 0) && (s.charAt(0) != '#')) // Empty lines or lines starting with "#" are ignored + { + sql = sql + " " + s; + if (s.endsWith(";")) { // reached end of sql statement + sql = sql.replace(';', ' '); //remove the semicolon + sqlBuffer.add(sql); + sql = ""; + } + } + } + } catch (IOException ex) { + Log.error("TradeBuildDB:parseDDLToBuffer Exeception during open/read of File: " + ddlFile, ex); + throw ex; + } finally { + if (br != null) { + try { + br.close(); + } catch (IOException ex) { + Log.error("TradeBuildDB:parseDDLToBuffer Failed to close BufferedReader", ex); + } + } + } + return sqlBuffer.toArray(); + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/impl/ejb3/AsyncScheduledOrder.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/impl/ejb3/AsyncScheduledOrder.java new file mode 100644 index 00000000..5b00b1bb --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/impl/ejb3/AsyncScheduledOrder.java @@ -0,0 +1,59 @@ +/** + * (C) Copyright IBM Corporation 2019. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.impl.ejb3; + + +import javax.enterprise.context.Dependent; +import javax.enterprise.inject.Any; +import javax.enterprise.inject.Instance; +import javax.inject.Inject; + +import com.ibm.websphere.samples.daytrader.interfaces.TradeServices; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; +import com.ibm.websphere.samples.daytrader.util.TradeRunTimeModeLiteral; + + +@Dependent +public class AsyncScheduledOrder implements Runnable { + + TradeServices tradeService; + + Integer orderID; + boolean twoPhase; + + @Inject + public AsyncScheduledOrder(@Any Instance services) { + tradeService = services.select(new TradeRunTimeModeLiteral(TradeConfig.getRunTimeModeNames()[TradeConfig.getRunTimeMode()])).get(); + } + + public void setProperties(Integer orderID, boolean twoPhase) { + this.orderID = orderID; + this.twoPhase = twoPhase; + } + + @Override + public void run() { + + + try { + tradeService.completeOrder(orderID, twoPhase); + + } catch (Exception e) { + + e.printStackTrace(); + } + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/impl/ejb3/AsyncScheduledOrderSubmitter.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/impl/ejb3/AsyncScheduledOrderSubmitter.java new file mode 100644 index 00000000..24290eda --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/impl/ejb3/AsyncScheduledOrderSubmitter.java @@ -0,0 +1,41 @@ +/** + * (C) Copyright IBM Corporation 2019. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.impl.ejb3; + +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +import javax.annotation.Resource; +import javax.enterprise.concurrent.ManagedScheduledExecutorService; +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; + +@RequestScoped +public class AsyncScheduledOrderSubmitter { + + + @Resource + private ManagedScheduledExecutorService mes; + + @Inject + private AsyncScheduledOrder asyncOrder; + + + public Future submitOrder(Integer orderID, boolean twoPhase) { + asyncOrder.setProperties(orderID,twoPhase); + return mes.schedule(asyncOrder,500,TimeUnit.MILLISECONDS); + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/impl/ejb3/MarketSummarySingleton.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/impl/ejb3/MarketSummarySingleton.java new file mode 100644 index 00000000..ceef6ff0 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/impl/ejb3/MarketSummarySingleton.java @@ -0,0 +1,138 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.impl.ejb3; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +import javax.annotation.Resource; +import javax.ejb.Lock; +import javax.ejb.LockType; +import javax.ejb.Schedule; +import javax.ejb.Singleton; +import javax.enterprise.concurrent.ManagedExecutorService; +import javax.enterprise.event.Event; +import javax.enterprise.event.NotificationOptions; +import javax.inject.Inject; +import javax.json.JsonObject; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.persistence.TypedQuery; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Root; + +import com.ibm.websphere.samples.daytrader.beans.MarketSummaryDataBean; +import com.ibm.websphere.samples.daytrader.entities.QuoteDataBean; +import com.ibm.websphere.samples.daytrader.interfaces.MarketSummaryUpdate; +import com.ibm.websphere.samples.daytrader.util.FinancialUtils; +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; + +@Singleton +public class MarketSummarySingleton { + + private MarketSummaryDataBean marketSummaryDataBean; + + @PersistenceContext + private EntityManager entityManager; + + @Inject + @MarketSummaryUpdate + Event mkSummaryUpdateEvent; + + @Resource + private ManagedExecutorService mes; + + + /* Update Market Summary every 20 seconds */ + @Schedule(second = "*/20",minute = "*", hour = "*", persistent = false) + private void updateMarketSummary() { + + + Log.trace("MarketSummarySingleton:updateMarketSummary -- updating market summary"); + + + if (TradeConfig.getRunTimeMode() != TradeConfig.EJB3) + { + Log.trace("MarketSummarySingleton:updateMarketSummary -- Not EJB3 Mode, so not updating"); + return; // Only do the actual work if in EJB3 Mode + } + + List quotes; + + try { + // Find Trade Stock Index Quotes (Top 100 quotes) ordered by their change in value + CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); + CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(QuoteDataBean.class); + Root quoteRoot = criteriaQuery.from(QuoteDataBean.class); + criteriaQuery.orderBy(criteriaBuilder.desc(quoteRoot.get("change1"))); + criteriaQuery.select(quoteRoot); + TypedQuery q = entityManager.createQuery(criteriaQuery); + quotes = q.getResultList(); + } catch (Exception e) { + Log.debug("Warning: The database has not been configured. If this is the first time the application has been started, please create and populate the database tables. Then restart the server."); + return; + } + + /* TODO: Make this cleaner? */ + QuoteDataBean[] quoteArray = quotes.toArray(new QuoteDataBean[quotes.size()]); + ArrayList topGainers = new ArrayList(5); + ArrayList topLosers = new ArrayList(5); + BigDecimal TSIA = FinancialUtils.ZERO; + BigDecimal openTSIA = FinancialUtils.ZERO; + double totalVolume = 0.0; + + if (quoteArray.length > 5) { + for (int i = 0; i < 5; i++) { + topGainers.add(quoteArray[i]); + } + for (int i = quoteArray.length - 1; i >= quoteArray.length - 5; i--) { + topLosers.add(quoteArray[i]); + } + + for (QuoteDataBean quote : quoteArray) { + BigDecimal price = quote.getPrice(); + BigDecimal open = quote.getOpen(); + double volume = quote.getVolume(); + TSIA = TSIA.add(price); + openTSIA = openTSIA.add(open); + totalVolume += volume; + } + TSIA = TSIA.divide(new BigDecimal(quoteArray.length), FinancialUtils.ROUND); + openTSIA = openTSIA.divide(new BigDecimal(quoteArray.length), FinancialUtils.ROUND); + } + + setMarketSummaryDataBean(new MarketSummaryDataBean(TSIA, openTSIA, totalVolume, topGainers, topLosers)); + mkSummaryUpdateEvent.fireAsync("MarketSummaryUpdate", NotificationOptions.builder().setExecutor(mes).build()); + } + + @Lock(LockType.READ) + public MarketSummaryDataBean getMarketSummaryDataBean() { + if (marketSummaryDataBean == null){ + updateMarketSummary(); + } + + return marketSummaryDataBean; + } + + @Lock(LockType.WRITE) + public void setMarketSummaryDataBean(MarketSummaryDataBean marketSummaryDataBean) { + this.marketSummaryDataBean = marketSummaryDataBean; + } + +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/impl/ejb3/TradeSLSBBean.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/impl/ejb3/TradeSLSBBean.java new file mode 100644 index 00000000..780e5219 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/impl/ejb3/TradeSLSBBean.java @@ -0,0 +1,618 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.impl.ejb3; + +import java.math.BigDecimal; +import java.sql.Timestamp; +import java.util.Collection; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.Future; + +import javax.annotation.Resource; +import javax.ejb.EJB; +import javax.ejb.EJBException; +import javax.ejb.SessionContext; +import javax.ejb.Stateless; +import javax.ejb.TransactionAttribute; +import javax.ejb.TransactionAttributeType; +import javax.ejb.TransactionManagement; +import javax.ejb.TransactionManagementType; +import javax.inject.Inject; +import javax.jms.JMSContext; +import javax.jms.Queue; +import javax.jms.QueueConnectionFactory; +import javax.jms.TextMessage; +import javax.jms.Topic; +import javax.jms.TopicConnectionFactory; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.persistence.TypedQuery; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Root; +import javax.transaction.RollbackException; +import javax.validation.constraints.NotNull; + +import com.ibm.websphere.samples.daytrader.interfaces.RuntimeMode; +import com.ibm.websphere.samples.daytrader.interfaces.Trace; +import com.ibm.websphere.samples.daytrader.interfaces.TradeEJB; +import com.ibm.websphere.samples.daytrader.interfaces.TradeServices; +import com.ibm.websphere.samples.daytrader.beans.MarketSummaryDataBean; +import com.ibm.websphere.samples.daytrader.entities.AccountDataBean; +import com.ibm.websphere.samples.daytrader.entities.AccountProfileDataBean; +import com.ibm.websphere.samples.daytrader.entities.HoldingDataBean; +import com.ibm.websphere.samples.daytrader.entities.OrderDataBean; +import com.ibm.websphere.samples.daytrader.entities.QuoteDataBean; +import com.ibm.websphere.samples.daytrader.util.FinancialUtils; +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.RecentQuotePriceChangeList; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; + +@Stateless +@TradeEJB +@RuntimeMode("Full EJB3") +@Trace +@TransactionAttribute(TransactionAttributeType.REQUIRED) +@TransactionManagement(TransactionManagementType.CONTAINER) +public class TradeSLSBBean implements TradeServices { + + // For Wildfly - add java:/ to these resource names. + @Resource(name = "jms/QueueConnectionFactory", authenticationType = javax.annotation.Resource.AuthenticationType.APPLICATION) + //@Resource(name = "java:/jms/QueueConnectionFactory", authenticationType = javax.annotation.Resource.AuthenticationType.APPLICATION) + private QueueConnectionFactory queueConnectionFactory; + + @Resource(name = "jms/TopicConnectionFactory", authenticationType = javax.annotation.Resource.AuthenticationType.APPLICATION) + //@Resource(name = "java:/jms/TopicConnectionFactory", authenticationType = javax.annotation.Resource.AuthenticationType.APPLICATION) + private TopicConnectionFactory topicConnectionFactory; + + @Resource(lookup = "jms/TradeStreamerTopic") + //@Resource(lookup = "java:/jms/TradeStreamerTopic") + private Topic tradeStreamerTopic; + + @Resource(lookup = "jms/TradeBrokerQueue") + //@Resource(lookup = "java:/jms/TradeBrokerQueue") + private Queue tradeBrokerQueue; + + @PersistenceContext + private EntityManager entityManager; + + @Resource + private SessionContext context; + + @EJB + MarketSummarySingleton marketSummarySingleton; + + @Inject + AsyncScheduledOrderSubmitter asyncEJBOrderSubmitter; + + @Inject + RecentQuotePriceChangeList recentQuotePriceChangeList; + + @Override + public MarketSummaryDataBean getMarketSummary() { + return marketSummarySingleton.getMarketSummaryDataBean(); + } + + @Override + @NotNull + public OrderDataBean buy(String userID, String symbol, double quantity, int orderProcessingMode) { + OrderDataBean order = null; + BigDecimal total; + try { + + AccountProfileDataBean profile = entityManager.find(AccountProfileDataBean.class, userID); + AccountDataBean account = profile.getAccount(); + QuoteDataBean quote = entityManager.find(QuoteDataBean.class, symbol); + HoldingDataBean holding = null; // The holding will be created by + // this buy order + + order = createOrder(account, quote, holding, "buy", quantity); + + // UPDATE - account should be credited during completeOrder + BigDecimal price = quote.getPrice(); + BigDecimal orderFee = order.getOrderFee(); + BigDecimal balance = account.getBalance(); + total = (new BigDecimal(quantity).multiply(price)).add(orderFee); + account.setBalance(balance.subtract(total)); + final Integer orderID=order.getOrderID(); + + if (orderProcessingMode == TradeConfig.SYNCH) { + completeOrder(orderID, false); + } else if (orderProcessingMode == TradeConfig.ASYNCH) { + completeOrderAsync(orderID, false); + } else if (orderProcessingMode == TradeConfig.ASYNCH_2PHASE) { + queueOrder(orderID, true); + } + } catch (Exception e) { + Log.error("TradeSLSBBean:buy(" + userID + "," + symbol + "," + quantity + ") --> failed", e); + /* On exception - cancel the order */ + // TODO figure out how to do this with JPA + // if (order != null) order.cancel(); + throw new EJBException(e); + } + return order; + } + + @Override + @NotNull + public OrderDataBean sell(final String userID, final Integer holdingID, int orderProcessingMode) { + OrderDataBean order=null; + BigDecimal total; + try { + AccountProfileDataBean profile = entityManager.find(AccountProfileDataBean.class, userID); + AccountDataBean account = profile.getAccount(); + + HoldingDataBean holding = entityManager.find(HoldingDataBean.class, holdingID); + + if (holding == null) { + Log.debug("TradeSLSBBean:sell User " + userID + " attempted to sell holding " + holdingID + " which has already been sold"); + + OrderDataBean orderData = new OrderDataBean(); + orderData.setOrderStatus("cancelled"); + entityManager.persist(orderData); + + return orderData; + } + + QuoteDataBean quote = holding.getQuote(); + double quantity = holding.getQuantity(); + + order = createOrder(account, quote, holding, "sell", quantity); + + // UPDATE the holding purchase data to signify this holding is + // "inflight" to be sold + // -- could add a new holdingStatus attribute to holdingEJB + holding.setPurchaseDate(new java.sql.Timestamp(0)); + + // UPDATE - account should be credited during completeOrder + BigDecimal price = quote.getPrice(); + BigDecimal orderFee = order.getOrderFee(); + BigDecimal balance = account.getBalance(); + total = (new BigDecimal(quantity).multiply(price)).subtract(orderFee); + account.setBalance(balance.add(total)); + final Integer orderID=order.getOrderID(); + + if (orderProcessingMode == TradeConfig.SYNCH) { + completeOrder(orderID, false); + } else if (orderProcessingMode == TradeConfig.ASYNCH) { + completeOrderAsync(orderID, false); + } else if (orderProcessingMode == TradeConfig.ASYNCH_2PHASE) { + queueOrder(orderID, true); + } + + } catch (Exception e) { + Log.error("TradeSLSBBean:sell(" + userID + "," + holdingID + ") --> failed", e); + // if (order != null) order.cancel(); + // UPDATE - handle all exceptions like: + throw new EJBException("TradeSLSBBean:sell(" + userID + "," + holdingID + ")", e); + } + return order; + } + + public void queueOrder(Integer orderID, boolean twoPhase) { + + // 2 phase + try (JMSContext queueContext = queueConnectionFactory.createContext();) { + TextMessage message = queueContext.createTextMessage(); + + message.setStringProperty("command", "neworder"); + message.setIntProperty("orderID", orderID); + message.setBooleanProperty("twoPhase", twoPhase); + message.setText("neworder: orderID=" + orderID + " runtimeMode=EJB twoPhase=" + twoPhase); + message.setLongProperty("publishTime", System.currentTimeMillis()); + + queueContext.createProducer().send(tradeBrokerQueue, message); + + } catch (Exception e) { + throw new EJBException(e.getMessage(), e); // pass the exception + } + } + + @Override + public OrderDataBean completeOrder(Integer orderID, boolean twoPhase) throws Exception { + OrderDataBean order = entityManager.find(OrderDataBean.class, orderID); + + if (order == null) { + System.out.println("error"); + throw new EJBException("Error: attempt to complete Order that is null\n" + order); + } + + order.getQuote(); + + if (order.isCompleted()) { + throw new EJBException("Error: attempt to complete Order that is already completed\n" + order); + } + + AccountDataBean account = order.getAccount(); + QuoteDataBean quote = order.getQuote(); + HoldingDataBean holding = order.getHolding(); + BigDecimal price = order.getPrice(); + double quantity = order.getQuantity(); + + if (order.isBuy()) { + /* + * Complete a Buy operation - create a new Holding for the Account - + * deduct the Order cost from the Account balance + */ + + HoldingDataBean newHolding = createHolding(account, quote, quantity, price); + order.setHolding(newHolding); + order.setOrderStatus("closed"); + order.setCompletionDate(new java.sql.Timestamp(System.currentTimeMillis())); + updateQuotePriceVolume(quote.getSymbol(), TradeConfig.getRandomPriceChangeFactor(), quantity); + } + + if (order.isSell()) { + /* + * Complete a Sell operation - remove the Holding from the Account - + * deposit the Order proceeds to the Account balance + */ + if (holding == null) { + Log.debug("TradeSLSBBean:completeOrder -- Unable to sell order " + order.getOrderID() + " holding already sold"); + order.cancel(); + //throw new EJBException("TradeSLSBBean:completeOrder -- Unable to sell order " + order.getOrderID() + " holding already sold"); + } else { + entityManager.remove(holding); + order.setHolding(null); + order.setOrderStatus("closed"); + order.setCompletionDate(new java.sql.Timestamp(System.currentTimeMillis())); + updateQuotePriceVolume(quote.getSymbol(), TradeConfig.getRandomPriceChangeFactor(), quantity); + } + } + + Log.trace("TradeSLSBBean:completeOrder--> Completed Order " + order.getOrderID() + "\n\t Order info: " + order + "\n\t Account info: " + account + + "\n\t Quote info: " + quote + "\n\t Holding info: " + holding); + + return order; + } + + @Override + public Future completeOrderAsync(Integer orderID, boolean twoPhase) throws Exception { + asyncEJBOrderSubmitter.submitOrder(orderID, twoPhase); + return null; + } + + @Override + public void cancelOrder(Integer orderID, boolean twoPhase) { + OrderDataBean order = entityManager.find(OrderDataBean.class, orderID); + order.cancel(); + } + + @Override + public void orderCompleted(String userID, Integer orderID) { + throw new UnsupportedOperationException("TradeSLSBBean:orderCompleted method not supported"); + } + + @Override + public Collection getOrders(String userID) { + AccountProfileDataBean profile = entityManager.find(AccountProfileDataBean.class, userID); + AccountDataBean account = profile.getAccount(); + return account.getOrders(); + } + + @Override + public Collection getClosedOrders(String userID) { + + try { + /* I want to do a CriteriaUpdate here, but there are issues with JBoss/Hibernate */ + CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); + CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(OrderDataBean.class); + Root orders = criteriaQuery.from(OrderDataBean.class); + criteriaQuery.select(orders); + criteriaQuery.where( + criteriaBuilder.equal(orders.get("orderStatus"), + criteriaBuilder.parameter(String.class, "p_status")), + criteriaBuilder.equal(orders.get("account").get("profile").get("userID"), + criteriaBuilder.parameter(String.class, "p_userid"))); + + TypedQuery q = entityManager.createQuery(criteriaQuery); + q.setParameter("p_status", "closed"); + q.setParameter("p_userid", userID); + List results = q.getResultList(); + + Iterator itr = results.iterator(); + // Spin through the orders to remove or mark completed + while (itr.hasNext()) { + OrderDataBean order = itr.next(); + // TODO: Investigate ConncurrentModification Exceptions + if (TradeConfig.getLongRun()) { + //Added this for Longruns (to prevent orderejb growth) + entityManager.remove(order); + } + else { + order.setOrderStatus("completed"); + } + } + + return results; + } catch (Exception e) { + Log.error("TradeSLSBBean.getClosedOrders", e); + throw new EJBException("TradeSLSBBean.getClosedOrders - error", e); + } + } + + @Override + public QuoteDataBean createQuote(String symbol, String companyName, BigDecimal price) { + try { + QuoteDataBean quote = new QuoteDataBean(symbol, companyName, 0, price, price, price, price, 0); + entityManager.persist(quote); + + Log.trace("TradeSLSBBean:createQuote-->" + quote); + + return quote; + } catch (Exception e) { + Log.error("TradeSLSBBean:createQuote -- exception creating Quote", e); + throw new EJBException(e); + } + } + + @Override + public QuoteDataBean getQuote(String symbol) { + return entityManager.find(QuoteDataBean.class, symbol); + } + + @Override + public Collection getAllQuotes() { + TypedQuery query = entityManager.createNamedQuery("quoteejb.allQuotes", QuoteDataBean.class); + return query.getResultList(); + } + + @Override + public QuoteDataBean updateQuotePriceVolume(String symbol, BigDecimal changeFactor, double sharesTraded) { + if (!TradeConfig.getUpdateQuotePrices()) { + return new QuoteDataBean(); + } + + Log.trace("TradeSLSBBean:updateQuote", symbol, changeFactor); + + TypedQuery q = entityManager.createNamedQuery("quoteejb.quoteForUpdate", QuoteDataBean.class); + q.setParameter(1, symbol); + QuoteDataBean quote = q.getSingleResult(); + + BigDecimal oldPrice = quote.getPrice(); + BigDecimal openPrice = quote.getOpen(); + + if (oldPrice.equals(TradeConfig.PENNY_STOCK_PRICE)) { + changeFactor = TradeConfig.PENNY_STOCK_RECOVERY_MIRACLE_MULTIPLIER; + } else if (oldPrice.compareTo(TradeConfig.MAXIMUM_STOCK_PRICE) > 0) { + changeFactor = TradeConfig.MAXIMUM_STOCK_SPLIT_MULTIPLIER; + } + + BigDecimal newPrice = changeFactor.multiply(oldPrice).setScale(2, BigDecimal.ROUND_HALF_UP); + + quote.setPrice(newPrice); + quote.setChange(newPrice.subtract(openPrice).doubleValue()); + quote.setVolume(quote.getVolume() + sharesTraded); + entityManager.merge(quote); + + if (TradeConfig.getPublishQuotePriceChange()) { + publishQuotePriceChange(quote, oldPrice, changeFactor, sharesTraded); + } + + recentQuotePriceChangeList.add(quote); + + return quote; + } + + @Override + public Collection<@NotNull HoldingDataBean> getHoldings(String userID) { + CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); + CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(HoldingDataBean.class); + Root holdings = criteriaQuery.from(HoldingDataBean.class); + criteriaQuery.where( + criteriaBuilder.equal(holdings.get("account").get("profile").get("userID"), + criteriaBuilder.parameter(String.class, "p_userid"))); + criteriaQuery.select(holdings); + + TypedQuery typedQuery = entityManager.createQuery(criteriaQuery); + typedQuery.setParameter("p_userid", userID); + return typedQuery.getResultList(); + } + + @Override + public HoldingDataBean getHolding(Integer holdingID) { + return entityManager.find(HoldingDataBean.class, holdingID); + } + + @Override + public AccountDataBean getAccountData(String userID) { + AccountProfileDataBean profile = entityManager.find(AccountProfileDataBean.class, userID); + AccountDataBean account = profile.getAccount(); + + // Added to populate transient field for account + account.setProfileID(profile.getUserID()); + + return account; + } + + @Override + public AccountProfileDataBean getAccountProfileData(String userID) { + return entityManager.find(AccountProfileDataBean.class, userID); + } + + @Override + public AccountProfileDataBean updateAccountProfile(AccountProfileDataBean profileData) { + AccountProfileDataBean temp = entityManager.find(AccountProfileDataBean.class, profileData.getUserID()); + temp.setAddress(profileData.getAddress()); + temp.setPassword(profileData.getPassword()); + temp.setFullName(profileData.getFullName()); + temp.setCreditCard(profileData.getCreditCard()); + temp.setEmail(profileData.getEmail()); + + entityManager.merge(temp); + + return temp; + } + + @Override + public AccountDataBean login(String userID, String password) throws RollbackException { + AccountProfileDataBean profile = entityManager.find(AccountProfileDataBean.class, userID); + if (profile == null) { + throw new EJBException("No such user: " + userID); + } + + AccountDataBean account = profile.getAccount(); + account.login(password); + + Log.trace("TradeSLSBBean:login(" + userID + "," + password + ") success" + account); + + return account; + } + + @Override + public void logout(String userID) { + AccountProfileDataBean profile = entityManager.find(AccountProfileDataBean.class, userID); + AccountDataBean account = profile.getAccount(); + account.logout(); + + Log.trace("TradeSLSBBean:logout(" + userID + ") success"); + } + + @Override + public AccountDataBean register(String userID, String password, String fullname, String address, String email, String creditcard, BigDecimal openBalance) { + AccountDataBean account = null; + AccountProfileDataBean profile = null; + + // Check to see if a profile with the desired userID already exists + profile = entityManager.find(AccountProfileDataBean.class, userID); + + if (profile != null) { + Log.error("Failed to register new Account - AccountProfile with userID(" + userID + ") already exists"); + return null; + } else { + profile = new AccountProfileDataBean(userID, password, fullname, address, email, creditcard); + account = new AccountDataBean(0, 0, null, new Timestamp(System.currentTimeMillis()), openBalance, openBalance, userID); + + profile.setAccount(account); + account.setProfile(profile); + + entityManager.persist(profile); + entityManager.persist(account); + } + + return account; + } + + @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) + public void publishQuotePriceChange(QuoteDataBean quote, BigDecimal oldPrice, BigDecimal changeFactor, double sharesTraded) { + if (!TradeConfig.getPublishQuotePriceChange()) { + return; + } + + try (JMSContext topicContext = topicConnectionFactory.createContext();) { + TextMessage message = topicContext.createTextMessage(); + + message.setStringProperty("command", "updateQuote"); + message.setStringProperty("symbol", quote.getSymbol()); + message.setStringProperty("company", quote.getCompanyName()); + message.setStringProperty("price", quote.getPrice().toString()); + message.setStringProperty("oldPrice", oldPrice.toString()); + message.setStringProperty("open", quote.getOpen().toString()); + message.setStringProperty("low", quote.getLow().toString()); + message.setStringProperty("high", quote.getHigh().toString()); + message.setDoubleProperty("volume", quote.getVolume()); + message.setStringProperty("changeFactor", changeFactor.toString()); + message.setDoubleProperty("sharesTraded", sharesTraded); + message.setLongProperty("publishTime", System.currentTimeMillis()); + message.setText("Update Stock price for " + quote.getSymbol() + " old price = " + oldPrice + " new price = " + quote.getPrice()); + + topicContext.createProducer().send(tradeStreamerTopic, message); + } catch (Exception e) { + throw new EJBException(e.getMessage(), e); // pass the exception + } + } + + public OrderDataBean createOrder(AccountDataBean account, QuoteDataBean quote, HoldingDataBean holding, String orderType, double quantity) { + OrderDataBean order; + + try { + order = new OrderDataBean(orderType, "open", new Timestamp(System.currentTimeMillis()), null, quantity, quote.getPrice().setScale( + FinancialUtils.SCALE, FinancialUtils.ROUND), TradeConfig.getOrderFee(orderType), account, quote, holding); + entityManager.persist(order); + } catch (Exception e) { + Log.error("TradeSLSBBean:createOrder -- failed to create Order. The stock/quote may not exist in the database.", e); + throw new EJBException("TradeSLSBBean:createOrder -- failed to create Order. Check that the symbol exists in the database.", e); + } + return order; + } + + private HoldingDataBean createHolding(AccountDataBean account, QuoteDataBean quote, double quantity, BigDecimal purchasePrice) throws Exception { + HoldingDataBean newHolding = new HoldingDataBean(quantity, purchasePrice, new Timestamp(System.currentTimeMillis()), account, quote); + entityManager.persist(newHolding); + return newHolding; + } + + @Override + public double investmentReturn(double investment, double NetValue) throws Exception { + double diff = NetValue - investment; + double ir = diff / investment; + return ir; + } + + @Override + public QuoteDataBean pingTwoPhase(String symbol) throws Exception { + QuoteDataBean quoteData = null; + + try (JMSContext queueContext = queueConnectionFactory.createContext();) { + // Get a Quote and send a JMS message in a 2-phase commit + quoteData = entityManager.find(QuoteDataBean.class, symbol); + + double sharesTraded = (Math.random() * 100) + 1 ; + BigDecimal oldPrice = quoteData.getPrice(); + BigDecimal openPrice = quoteData.getOpen(); + BigDecimal changeFactor = new BigDecimal (Math.random() * 100); + + BigDecimal newPrice = changeFactor.multiply(oldPrice).setScale(2, BigDecimal.ROUND_HALF_UP); + + quoteData.setPrice(newPrice); + quoteData.setChange(newPrice.subtract(openPrice).doubleValue()); + quoteData.setVolume(quoteData.getVolume() + sharesTraded); + entityManager.merge(quoteData); + + TextMessage message = queueContext.createTextMessage(); + + message.setStringProperty("command", "ping"); + message.setLongProperty("publishTime", System.currentTimeMillis()); + message.setText("Ping message for queue java:comp/env/jms/TradeBrokerQueue sent from TradeSLSBBean:pingTwoPhase at " + new java.util.Date()); + queueContext.createProducer().send(tradeBrokerQueue, message); + } catch (Exception e) { + Log.error("TradeSLSBBean:pingTwoPhase -- exception caught", e); + } + + return quoteData; + } + + class quotePriceComparator implements Comparator { + @Override + public int compare(QuoteDataBean quote1, QuoteDataBean quote2) { + double change1 = quote1.getChange(); + double change2 = quote2.getChange(); + return new Double(change2).compareTo(change1); + } + } + + @Override + public int getImpl() { + return TradeConfig.EJB3; + } + + @Override + public void setInSession(boolean inSession) { + throw new UnsupportedOperationException("TradeSLSBBean::setInGlobalTxn not supported"); + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/impl/session2direct/DirectSLSBBean.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/impl/session2direct/DirectSLSBBean.java new file mode 100644 index 00000000..b6cabe9b --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/impl/session2direct/DirectSLSBBean.java @@ -0,0 +1,237 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.impl.session2direct; + +import java.math.BigDecimal; +import java.util.Collection; +import java.util.concurrent.Future; + +import javax.ejb.Stateless; +import javax.ejb.TransactionAttribute; +import javax.ejb.TransactionAttributeType; +import javax.ejb.TransactionManagement; +import javax.ejb.TransactionManagementType; +import javax.inject.Inject; +import javax.validation.constraints.NotNull; + +import com.ibm.websphere.samples.daytrader.interfaces.RuntimeMode; +import com.ibm.websphere.samples.daytrader.interfaces.Trace; +import com.ibm.websphere.samples.daytrader.interfaces.TradeJDBC; +import com.ibm.websphere.samples.daytrader.interfaces.TradeServices; +import com.ibm.websphere.samples.daytrader.interfaces.TradeSession2Direct; +import com.ibm.websphere.samples.daytrader.beans.MarketSummaryDataBean; +import com.ibm.websphere.samples.daytrader.entities.AccountDataBean; +import com.ibm.websphere.samples.daytrader.entities.AccountProfileDataBean; +import com.ibm.websphere.samples.daytrader.entities.HoldingDataBean; +import com.ibm.websphere.samples.daytrader.entities.OrderDataBean; +import com.ibm.websphere.samples.daytrader.entities.QuoteDataBean; +import com.ibm.websphere.samples.daytrader.impl.ejb3.AsyncScheduledOrderSubmitter; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; + +@Stateless +@TradeSession2Direct +@RuntimeMode("Session to Direct") +@Trace +@TransactionAttribute(TransactionAttributeType.REQUIRED) +@TransactionManagement(TransactionManagementType.CONTAINER) +public class DirectSLSBBean implements TradeServices { + + @Inject + @TradeJDBC + TradeServices tradeDirect; + + @Inject + AsyncScheduledOrderSubmitter asyncEJBOrderSubmitter; + + @Override + public int getImpl() { + return TradeConfig.SESSION_TO_DIRECT; + } + + @Override + public MarketSummaryDataBean getMarketSummary() throws Exception { + tradeDirect.setInSession(true); + return tradeDirect.getMarketSummary(); + } + + @Override + public OrderDataBean createOrder(AccountDataBean account, QuoteDataBean quote, HoldingDataBean holding, + String orderType, double quantity) throws Exception { + tradeDirect.setInSession(true); + return tradeDirect.createOrder(account, quote, holding, orderType, quantity); + } + + @Override + @NotNull + public OrderDataBean buy(String userID, String symbol, double quantity, int orderProcessingMode) throws Exception { + tradeDirect.setInSession(true); + OrderDataBean orderdata = tradeDirect.buy(userID, symbol, quantity, orderProcessingMode); + + if (orderProcessingMode == TradeConfig.ASYNCH) { + this.completeOrderAsync(orderdata.getOrderID(), false); + } + + return orderdata; + } + + @Override + @NotNull + public OrderDataBean sell(String userID, Integer holdingID, int orderProcessingMode) throws Exception { + tradeDirect.setInSession(true); + OrderDataBean orderdata = tradeDirect.sell(userID, holdingID, orderProcessingMode); + + if (orderProcessingMode == TradeConfig.ASYNCH) { + this.completeOrderAsync(orderdata.getOrderID(), false); + } + return orderdata; + + } + + @Override + public void queueOrder(Integer orderID, boolean twoPhase) throws Exception { + tradeDirect.setInSession(true); + tradeDirect.queueOrder(orderID, twoPhase); + + } + + @Override + public OrderDataBean completeOrder(Integer orderID, boolean twoPhase) throws Exception { + tradeDirect.setInSession(true); + return tradeDirect.completeOrder(orderID, twoPhase); + } + + @Override + public Future completeOrderAsync(Integer orderID, boolean twoPhase) throws Exception { + asyncEJBOrderSubmitter.submitOrder(orderID, twoPhase); + return null; + } + + @Override + public void cancelOrder(Integer orderID, boolean twoPhase) throws Exception { + tradeDirect.setInSession(true); + tradeDirect.cancelOrder(orderID, twoPhase); + + } + + @Override + public void orderCompleted(String userID, Integer orderID) throws Exception { + tradeDirect.setInSession(true); + tradeDirect.orderCompleted(userID, orderID); + + } + + @Override + public Collection getOrders(String userID) throws Exception { + tradeDirect.setInSession(true); + return tradeDirect.getOrders(userID); + } + + @Override + public Collection getClosedOrders(String userID) throws Exception { + tradeDirect.setInSession(true); + return tradeDirect.getClosedOrders(userID); + } + + @Override + public QuoteDataBean createQuote(String symbol, String companyName, BigDecimal price) throws Exception { + tradeDirect.setInSession(true); + return tradeDirect.createQuote(symbol, companyName, price); + } + + @Override + public QuoteDataBean getQuote(String symbol) throws Exception { + tradeDirect.setInSession(true); + return tradeDirect.getQuote(symbol); + } + + @Override + public Collection getAllQuotes() throws Exception { + tradeDirect.setInSession(true); + return tradeDirect.getAllQuotes(); + } + + @Override + public QuoteDataBean updateQuotePriceVolume(String symbol, BigDecimal newPrice, double sharesTraded) + throws Exception { + tradeDirect.setInSession(true); + return tradeDirect.updateQuotePriceVolume(symbol, newPrice, sharesTraded); + } + + @Override + public Collection getHoldings(String userID) throws Exception { + tradeDirect.setInSession(true); + return tradeDirect.getHoldings(userID); + } + + @Override + public HoldingDataBean getHolding(Integer holdingID) throws Exception { + tradeDirect.setInSession(true); + return tradeDirect.getHolding(holdingID); + } + + @Override + public AccountDataBean getAccountData(String userID) throws Exception { + tradeDirect.setInSession(true); + return tradeDirect.getAccountData(userID); + } + + @Override + public AccountProfileDataBean getAccountProfileData(String userID) throws Exception { + tradeDirect.setInSession(true); + return tradeDirect.getAccountProfileData(userID); + } + + @Override + public AccountProfileDataBean updateAccountProfile(AccountProfileDataBean profileData) throws Exception { + tradeDirect.setInSession(true); + return tradeDirect.updateAccountProfile(profileData); + } + + @Override + public AccountDataBean login(String userID, String password) throws Exception { + tradeDirect.setInSession(true); + return tradeDirect.login(userID, password); + } + + @Override + public void logout(String userID) throws Exception { + tradeDirect.setInSession(true); + tradeDirect.logout(userID); + } + + @Override + public AccountDataBean register(String userID, String password, String fullname, String address, String email, + String creditcard, BigDecimal openBalance) throws Exception { + tradeDirect.setInSession(true); + return tradeDirect.register(userID, password, fullname, address, email, creditcard, openBalance); + } + + @Override + public QuoteDataBean pingTwoPhase(String symbol) throws Exception { + throw new UnsupportedOperationException(); + } + + @Override + public double investmentReturn(double rnd1, double rnd2) throws Exception { + throw new UnsupportedOperationException(); + } + + + @Override + public void setInSession(boolean inSession) { + throw new UnsupportedOperationException("DirectSLSBBean::setInGlobalTxn not supported"); + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/interfaces/MarketSummaryUpdate.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/interfaces/MarketSummaryUpdate.java new file mode 100644 index 00000000..16ddc303 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/interfaces/MarketSummaryUpdate.java @@ -0,0 +1,27 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.interfaces; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import javax.inject.Qualifier; + +@Qualifier +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE}) +public @interface MarketSummaryUpdate {} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/interfaces/QuotePriceChange.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/interfaces/QuotePriceChange.java new file mode 100644 index 00000000..936097b4 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/interfaces/QuotePriceChange.java @@ -0,0 +1,31 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.interfaces; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import javax.inject.Qualifier; + +@Qualifier +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE}) +public @interface QuotePriceChange { +} + + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/interfaces/RuntimeMode.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/interfaces/RuntimeMode.java new file mode 100644 index 00000000..9c55d709 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/interfaces/RuntimeMode.java @@ -0,0 +1,33 @@ +/******************************************************************************* +* Copyright (c) 2017 IBM Corp. +* +* 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 +* +* http://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. +*******************************************************************************/ +package com.ibm.websphere.samples.daytrader.interfaces; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import javax.inject.Qualifier; + +@Qualifier +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.METHOD, + ElementType.FIELD, ElementType.PARAMETER}) +public @interface RuntimeMode { + /** + * Default to jaxrs client impl + */ + String value() default "Full EJB3"; +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/interfaces/Trace.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/interfaces/Trace.java new file mode 100644 index 00000000..1c24008b --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/interfaces/Trace.java @@ -0,0 +1,33 @@ +/** + * (C) Copyright IBM Corporation 2019. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.interfaces; + +import javax.interceptor.InterceptorBinding; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Inherited; + +@Inherited +@InterceptorBinding +@Target({ TYPE, METHOD }) +@Retention(RUNTIME) +public @interface Trace { +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/interfaces/TradeDB.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/interfaces/TradeDB.java new file mode 100644 index 00000000..ee07a020 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/interfaces/TradeDB.java @@ -0,0 +1,44 @@ +/** + * (C) Copyright IBM Corporation 2019. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.interfaces; + +import com.ibm.websphere.samples.daytrader.beans.RunStatsDataBean; + +public interface TradeDB { + + /** + * Reset the TradeData by - removing all newly registered users by scenario + * servlet (i.e. users with userID's beginning with "ru:") * - removing all + * buy/sell order pairs - setting logoutCount = loginCount + * + * return statistics for this benchmark run + */ + RunStatsDataBean resetTrade(boolean deleteAll) throws Exception; + + /** + * Get the Database Product Name + * + * return DB Product Name String + */ + String checkDBProductName() throws Exception; + + /** + * Get the impl for the TradeService + * + * return int matching the implementation + */ + +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/interfaces/TradeEJB.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/interfaces/TradeEJB.java new file mode 100644 index 00000000..13330044 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/interfaces/TradeEJB.java @@ -0,0 +1,32 @@ +/** + * (C) Copyright IBM Corporation 2019. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.interfaces; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import javax.inject.Qualifier; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Qualifier +@Retention(RUNTIME) +@Target({TYPE, METHOD, FIELD, PARAMETER}) +public @interface TradeEJB {} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/interfaces/TradeJDBC.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/interfaces/TradeJDBC.java new file mode 100644 index 00000000..57086a49 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/interfaces/TradeJDBC.java @@ -0,0 +1,32 @@ +/** + * (C) Copyright IBM Corporation 2019. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.interfaces; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import javax.inject.Qualifier; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Qualifier +@Retention(RUNTIME) +@Target({TYPE, METHOD, FIELD, PARAMETER}) +public @interface TradeJDBC {} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/interfaces/TradeServices.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/interfaces/TradeServices.java new file mode 100644 index 00000000..dc91be1d --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/interfaces/TradeServices.java @@ -0,0 +1,338 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.interfaces; + +import java.math.BigDecimal; +import java.util.Collection; +import java.util.concurrent.Future; + +import com.ibm.websphere.samples.daytrader.beans.MarketSummaryDataBean; +import com.ibm.websphere.samples.daytrader.entities.AccountDataBean; +import com.ibm.websphere.samples.daytrader.entities.AccountProfileDataBean; +import com.ibm.websphere.samples.daytrader.entities.HoldingDataBean; +import com.ibm.websphere.samples.daytrader.entities.OrderDataBean; +import com.ibm.websphere.samples.daytrader.entities.QuoteDataBean; + +/** + * TradeServices interface specifies the business methods provided by the Trade + * online broker application. These business methods represent the features and + * operations that can be performed by customers of the brokerage such as login, + * logout, get a stock quote, buy or sell a stock, etc. This interface is + * implemented by {@link Trade} providing an EJB implementation of these + * business methods and also by {@link TradeDirect} providing a JDBC + * implementation. + * + * @see TradeDirect + * @see TradeSLSB + * + */ + +public interface TradeServices { + + /** + * Compute and return a snapshot of the current market conditions This + * includes the TSIA - an index of the price of the top 100 Trade stock + * quotes The openTSIA ( the index at the open) The volume of shares traded, + * Top Stocks gain and loss + * + * @return A snapshot of the current market summary + */ + MarketSummaryDataBean getMarketSummary() throws Exception; + + /** + * Create an order (buy or sell) + * + * @param accoount + * the accountdatabean + * @param quote + * the quptedatabean + * @param holding + * the holdingdatabean + * @param orderType + * buy or sell + * @param quantity + * quantity + * @return Collection OrderDataBeans providing detailed order information + */ + OrderDataBean createOrder(AccountDataBean account, QuoteDataBean quote, HoldingDataBean holding, String orderType, + double quantity) throws Exception; + + /** + * Purchase a stock and create a new holding for the given user. Given a + * stock symbol and quantity to purchase, retrieve the current quote price, + * debit the user's account balance, and add holdings to user's portfolio. + * buy/sell are asynchronous, using J2EE messaging, A new order is created + * and submitted for processing to the TradeBroker + * + * @param userID + * the customer requesting the stock purchase + * @param symbol + * the symbol of the stock being purchased + * @param quantity + * the quantity of shares to purchase + * @return OrderDataBean providing the status of the newly created buy order + */ + + OrderDataBean buy(String userID, String symbol, double quantity, int orderProcessingMode) throws Exception; + + /** + * Sell a stock holding and removed the holding for the given user. Given a + * Holding, retrieve current quote, credit user's account, and reduce + * holdings in user's portfolio. + * + * @param userID + * the customer requesting the sell + * @param holdingID + * the users holding to be sold + * @return OrderDataBean providing the status of the newly created sell + * order + */ + OrderDataBean sell(String userID, Integer holdingID, int orderProcessingMode) throws Exception; + + /** + * Queue the Order identified by orderID to be processed + * + * Orders are submitted through JMS to a Trading Broker and completed + * asynchronously. This method queues the order for processing + * + * The boolean twoPhase specifies to the server implementation whether or + * not the method is to participate in a global transaction + * + * @param orderID + * the Order being queued for processing + * @return OrderDataBean providing the status of the completed order + */ + void queueOrder(Integer orderID, boolean twoPhase) throws Exception; + + /** + * Complete the Order identified by orderID. This method completes + * the order For a buy, the stock is purchased creating a holding and the + * users account is debited For a sell, the stock holding is removed and the + * users account is credited with the proceeds + * + * The boolean twoPhase specifies to the server implementation whether or + * not the method is to participate in a global transaction + * + * @param orderID + * the Order to complete + * @return OrderDataBean providing the status of the completed order + */ + OrderDataBean completeOrder(Integer orderID, boolean twoPhase) throws Exception; + + /** + * Complete the Order identefied by orderID Orders are completed + * asynchronously. This method completes + * the order For a buy, the stock is purchased creating a holding and the + * users account is debited For a sell, the stock holding is removed and the + * users account is credited with the proceeds + * + * The boolean twoPhase specifies to the server implementation whether or + * not the method is to participate in a global transaction + * + * @param orderID + * the Order to complete + * @return OrderDataBean providing the status of the completed order + */ + Future completeOrderAsync(Integer orderID, boolean twoPhase) throws Exception; + + /** + * Cancel the Order identefied by orderID + * + * The boolean twoPhase specifies to the server implementation whether or + * not the method is to participate in a global transaction + * + * @param orderID + * the Order to complete + * @return OrderDataBean providing the status of the completed order + */ + void cancelOrder(Integer orderID, boolean twoPhase) throws Exception; + + /** + * Signify an order has been completed for the given userID + * + * @param userID + * the user for which an order has completed + * @param orderID + * the order which has completed + * + */ + void orderCompleted(String userID, Integer orderID) throws Exception; + + /** + * Get the collection of all orders for a given account + * + * @param userID + * the customer account to retrieve orders for + * @return Collection OrderDataBeans providing detailed order information + */ + Collection getOrders(String userID) throws Exception; + + /** + * Get the collection of completed orders for a given account that need to + * be alerted to the user + * + * @param userID + * the customer account to retrieve orders for + * @return Collection OrderDataBeans providing detailed order information + */ + Collection getClosedOrders(String userID) throws Exception; + + /** + * Given a market symbol, price, and details, create and return a new + * {@link QuoteDataBean} + * + * @param symbol + * the symbol of the stock + * @param price + * the current stock price + * @param details + * a short description of the stock or company + * @return a new QuoteDataBean or null if Quote could not be created + */ + QuoteDataBean createQuote(String symbol, String companyName, BigDecimal price) throws Exception; + + /** + * Return a {@link QuoteDataBean} describing a current quote for the given + * stock symbol + * + * @param symbol + * the stock symbol to retrieve the current Quote + * @return the QuoteDataBean + */ + QuoteDataBean getQuote(String symbol) throws Exception; + + /** + * Return a {@link java.util.Collection} of {@link QuoteDataBean} describing + * all current quotes + * + * @return A collection of QuoteDataBean + */ + Collection getAllQuotes() throws Exception; + + /** + * Update the stock quote price and volume for the specified stock symbol + * + * @param symbol + * for stock quote to update + * @param price + * the updated quote price + * @return the QuoteDataBean describing the stock + */ + QuoteDataBean updateQuotePriceVolume(String symbol, BigDecimal newPrice, double sharesTraded) throws Exception; + + /** + * Return the portfolio of stock holdings for the specified customer as a + * collection of HoldingDataBeans + * + * @param userID + * the customer requesting the portfolio + * @return Collection of the users portfolio of stock holdings + */ + Collection getHoldings(String userID) throws Exception; + + /** + * Return a specific user stock holding identifed by the holdingID + * + * @param holdingID + * the holdingID to return + * @return a HoldingDataBean describing the holding + */ + HoldingDataBean getHolding(Integer holdingID) throws Exception; + + /** + * Return an AccountDataBean object for userID describing the account + * + * @param userID + * the account userID to lookup + * @return User account data in AccountDataBean + */ + AccountDataBean getAccountData(String userID) throws Exception; + + /** + * Return an AccountProfileDataBean for userID providing the users profile + * + * @param userID + * the account userID to lookup + * @param User + * account profile data in AccountProfileDataBean + */ + AccountProfileDataBean getAccountProfileData(String userID) throws Exception; + + /** + * Update userID's account profile information using the provided + * AccountProfileDataBean object + * + * @param userID + * the account userID to lookup + * @param User + * account profile data in AccountProfileDataBean + */ + AccountProfileDataBean updateAccountProfile(AccountProfileDataBean profileData) throws Exception; + + /** + * Attempt to authenticate and login a user with the given password + * + * @param userID + * the customer to login + * @param password + * the password entered by the customer for authentication + * @return User account data in AccountDataBean + */ + AccountDataBean login(String userID, String password) throws Exception; + + /** + * Logout the given user + * + * @param userID + * the customer to logout + * @return the login status + */ + + void logout(String userID) throws Exception; + + /** + * Register a new Trade customer. Create a new user profile, user registry + * entry, account with initial balance, and empty portfolio. + * + * @param userID + * the new customer to register + * @param password + * the customers password + * @param fullname + * the customers fullname + * @param address + * the customers street address + * @param email + * the customers email address + * @param creditcard + * the customers creditcard number + * @param initialBalance + * the amount to charge to the customers credit to open the + * account and set the initial balance + * @return the userID if successful, null otherwise + */ + AccountDataBean register(String userID, String password, String fullname, String address, String email, String creditcard, BigDecimal openBalance) + throws Exception; + + + int getImpl(); + + QuoteDataBean pingTwoPhase(String symbol) throws Exception; + + double investmentReturn(double rnd1, double rnd2) throws Exception; + + void setInSession(boolean inSession); +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/interfaces/TradeSession2Direct.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/interfaces/TradeSession2Direct.java new file mode 100644 index 00000000..e39b6842 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/interfaces/TradeSession2Direct.java @@ -0,0 +1,32 @@ +/** + * (C) Copyright IBM Corporation 2019. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.interfaces; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import javax.inject.Qualifier; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Qualifier +@Retention(RUNTIME) +@Target({TYPE, METHOD, FIELD, PARAMETER}) +public @interface TradeSession2Direct {} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/jaxrs/BroadcastResource.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/jaxrs/BroadcastResource.java new file mode 100644 index 00000000..3b280fde --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/jaxrs/BroadcastResource.java @@ -0,0 +1,70 @@ +/** + * (C) Copyright IBM Corporation 2019. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.jaxrs; + +import java.util.List; + +import javax.annotation.Priority; +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.event.ObservesAsync; +import javax.inject.Inject; +import javax.interceptor.Interceptor; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.sse.OutboundSseEvent.Builder; +import javax.ws.rs.sse.Sse; +import javax.ws.rs.sse.SseBroadcaster; +import javax.ws.rs.sse.SseEventSink; + +import com.ibm.websphere.samples.daytrader.interfaces.QuotePriceChange; +import com.ibm.websphere.samples.daytrader.util.RecentQuotePriceChangeList; + +@Path("broadcastevents") +@ApplicationScoped +public class BroadcastResource { + + private SseBroadcaster broadcaster; + private Builder builder; + + @Inject RecentQuotePriceChangeList recentQuotePriceChangeList; + + @Context + public void setSse(Sse sse) { + broadcaster = sse.newBroadcaster(); + builder = sse.newEventBuilder(); + } + + @GET + @Produces(MediaType.SERVER_SENT_EVENTS) + public void register(@Context SseEventSink eventSink) { + if (recentQuotePriceChangeList.isEmpty()) { + eventSink.send(builder.data(new String("welcome!")).build()); + } else { + eventSink.send(builder.mediaType(MediaType.APPLICATION_JSON_TYPE) + .data(List.class,recentQuotePriceChangeList.recentList()).build()); + } + broadcaster.register(eventSink); + } + + public void eventStreamCdi(@ObservesAsync @Priority(Interceptor.Priority.APPLICATION + 1) @QuotePriceChange String event) { + broadcaster.broadcast(builder.mediaType(MediaType.APPLICATION_JSON_TYPE) + .data(List.class,recentQuotePriceChangeList.recentList()).build()); + + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/jaxrs/JAXRSApplication.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/jaxrs/JAXRSApplication.java new file mode 100644 index 00000000..1266ede0 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/jaxrs/JAXRSApplication.java @@ -0,0 +1,28 @@ +/** + * (C) Copyright IBM Corporation 2019. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.jaxrs; + +import javax.ws.rs.ApplicationPath; +import javax.ws.rs.core.Application; + +/** + * + * @author hantsy + */ +@ApplicationPath("/rest") +public class JAXRSApplication extends Application { + +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/jaxrs/QuoteResource.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/jaxrs/QuoteResource.java new file mode 100644 index 00000000..cf1d5a45 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/jaxrs/QuoteResource.java @@ -0,0 +1,84 @@ +/** + * (C) Copyright IBM Corporation 2019. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.jaxrs; + +import java.util.ArrayList; +import java.util.List; + +import javax.enterprise.context.RequestScoped; +import javax.enterprise.inject.Any; +import javax.enterprise.inject.Instance; +import javax.inject.Inject; +import javax.ws.rs.Consumes; +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import com.ibm.websphere.samples.daytrader.entities.QuoteDataBean; +import com.ibm.websphere.samples.daytrader.interfaces.TradeServices; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; +import com.ibm.websphere.samples.daytrader.util.TradeRunTimeModeLiteral; + +@Path("quotes") +@RequestScoped +public class QuoteResource { + + private TradeServices tradeService; + + + public QuoteResource() { + } + + @Inject + public QuoteResource(@Any Instance services) { + tradeService = services.select(new TradeRunTimeModeLiteral(TradeConfig.getRunTimeModeNames()[TradeConfig.getRunTimeMode()])).get(); + } + + @GET + @Produces(MediaType.APPLICATION_JSON) + @Path("/{symbols}") + public List quotesGet(@PathParam("symbols") String symbols) { + return getQuotes(symbols); + } + + @POST + @Consumes({ "application/x-www-form-urlencoded" }) + @Produces(MediaType.APPLICATION_JSON) + public List quotesPost(@FormParam("symbols") String symbols) { + return getQuotes(symbols); + } + + private List getQuotes(String symbols) { + ArrayList quoteDataBeans = new ArrayList(); + + try { + String[] symbolsSplit = symbols.split(","); + for (String symbol: symbolsSplit) { + QuoteDataBean quoteData = tradeService.getQuote(symbol); + quoteDataBeans.add(quoteData); + } + } catch (Exception e) { + e.printStackTrace(); + } + + return (List)quoteDataBeans; + } + +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/mdb/DTBroker3MDB.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/mdb/DTBroker3MDB.java new file mode 100644 index 00000000..a5024fc0 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/mdb/DTBroker3MDB.java @@ -0,0 +1,159 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.mdb; + +import javax.annotation.PostConstruct; +import javax.annotation.Resource; +import javax.ejb.ActivationConfigProperty; +import javax.ejb.MessageDriven; +import javax.ejb.MessageDrivenContext; +import javax.ejb.TransactionAttribute; +import javax.ejb.TransactionAttributeType; +import javax.ejb.TransactionManagement; +import javax.ejb.TransactionManagementType; +import javax.enterprise.inject.Any; +import javax.enterprise.inject.Instance; +import javax.inject.Inject; +import javax.jms.Message; +import javax.jms.MessageListener; +import javax.jms.TextMessage; + +import com.ibm.websphere.samples.daytrader.interfaces.Trace; +import com.ibm.websphere.samples.daytrader.interfaces.TradeServices; +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.MDBStats; +import com.ibm.websphere.samples.daytrader.util.TimerStat; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; +import com.ibm.websphere.samples.daytrader.util.TradeRunTimeModeLiteral; + +// For Glassfish/Payara - take jms/ off of the destination name + +@TransactionAttribute(TransactionAttributeType.REQUIRED) +@TransactionManagement(TransactionManagementType.CONTAINER) +@MessageDriven(activationConfig = { @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"), + @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"), + @ActivationConfigProperty(propertyName = "destination", propertyValue = "jms/TradeBrokerQueue"), + //@ActivationConfigProperty(propertyName = "destination", propertyValue = "TradeBrokerQueue"), + @ActivationConfigProperty(propertyName = "subscriptionDurability", propertyValue = "NonDurable") }) +@Trace +public class DTBroker3MDB implements MessageListener { + private final MDBStats mdbStats; + private int statInterval = 10000; + + @Resource + public MessageDrivenContext mdc; + + @Inject @Any + Instance services; + + private TradeServices trade; + + public DTBroker3MDB() { + + if (statInterval <= 0) { + statInterval = 10000; + } + mdbStats = MDBStats.getInstance(); + } + + @PostConstruct + void boostrapTradeServices() { + trade = services.select(new TradeRunTimeModeLiteral(TradeConfig.getRunTimeModeNames()[TradeConfig.getRunTimeMode()])).get(); + } + + @Override + public void onMessage(Message message) { + try { + + Log.trace("TradeBroker:onMessage -- received message -->" + ((TextMessage) message).getText() + "command-->" + + message.getStringProperty("command") + "<--"); + + if (message.getJMSRedelivered()) { + Log.log("DTBroker3MDB: The following JMS message was redelivered due to a rollback:\n" + ((TextMessage) message).getText()); + // Order has been cancelled -- ignore returned messages + return; + } + String command = message.getStringProperty("command"); + if (command == null) { + Log.debug("DTBroker3MDB:onMessage -- received message with null command. Message-->" + message); + return; + } + if (command.equalsIgnoreCase("neworder")) { + /* Get the Order ID and complete the Order */ + Integer orderID = new Integer(message.getIntProperty("orderID")); + boolean twoPhase = message.getBooleanProperty("twoPhase"); + boolean direct = message.getBooleanProperty("direct"); + long publishTime = message.getLongProperty("publishTime"); + long receiveTime = System.currentTimeMillis(); + + try { + //TODO: why direct? + //trade = getTrade(direct); + + Log.trace("DTBroker3MDB:onMessage - completing order " + orderID + " twoPhase=" + twoPhase + " direct=" + direct); + + trade.completeOrder(orderID, twoPhase); + + TimerStat currentStats = mdbStats.addTiming("DTBroker3MDB:neworder", publishTime, receiveTime); + + if ((currentStats.getCount() % statInterval) == 0) { + Log.log(" DTBroker3MDB: processed " + statInterval + " stock trading orders." + + " Total NewOrders process = " + currentStats.getCount() + + "Time (in seconds):" + + " min: " +currentStats.getMinSecs()+ + " max: " +currentStats.getMaxSecs()+ + " avg: " +currentStats.getAvgSecs()); + } + } catch (Exception e) { + Log.error("DTBroker3MDB:onMessage Exception completing order: " + orderID + "\n", e); + mdc.setRollbackOnly(); + /* + * UPDATE - order is cancelled in trade if an error is + * caught try { trade.cancelOrder(orderID, twoPhase); } + * catch (Exception e2) { Log.error("order cancel failed", + * e); } + */ + } + } else if (command.equalsIgnoreCase("ping")) { + + Log.trace("DTBroker3MDB:onMessage received test command -- message: " + ((TextMessage) message).getText()); + + long publishTime = message.getLongProperty("publishTime"); + long receiveTime = System.currentTimeMillis(); + + TimerStat currentStats = mdbStats.addTiming("DTBroker3MDB:ping", publishTime, receiveTime); + + if ((currentStats.getCount() % statInterval) == 0) { + Log.log(" DTBroker3MDB: received " + statInterval + " ping messages." + + " Total ping message count = " + currentStats.getCount() + + " Time (in seconds):" + + " min: " +currentStats.getMinSecs()+ + " max: " +currentStats.getMaxSecs()+ + " avg: " +currentStats.getAvgSecs()); + } + } else { + Log.error("DTBroker3MDB:onMessage - unknown message request command-->" + command + "<-- message=" + ((TextMessage) message).getText()); + } + } catch (Throwable t) { + // JMS onMessage should handle all exceptions + Log.error("DTBroker3MDB: Error rolling back transaction", t); + mdc.setRollbackOnly(); + } + } + + + +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/mdb/DTStreamer3MDB.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/mdb/DTStreamer3MDB.java new file mode 100644 index 00000000..49fc8a5b --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/mdb/DTStreamer3MDB.java @@ -0,0 +1,123 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.mdb; + +import javax.annotation.Resource; +import javax.ejb.ActivationConfigProperty; +import javax.ejb.MessageDriven; +import javax.ejb.MessageDrivenContext; +import javax.ejb.TransactionAttribute; +import javax.ejb.TransactionAttributeType; +import javax.ejb.TransactionManagement; +import javax.ejb.TransactionManagementType; +import javax.jms.Message; +import javax.jms.MessageListener; +import javax.jms.TextMessage; + + +import com.ibm.websphere.samples.daytrader.interfaces.Trace; +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.MDBStats; +import com.ibm.websphere.samples.daytrader.util.TimerStat; + +//For Glassfish/Payara - take jms/ off of the destination name + +@TransactionAttribute(TransactionAttributeType.REQUIRED) +@TransactionManagement(TransactionManagementType.CONTAINER) +@MessageDriven(activationConfig = { @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"), + @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"), + @ActivationConfigProperty(propertyName = "destination", propertyValue = "jms/TradeStreamerTopic"), + //@ActivationConfigProperty(propertyName = "destination", propertyValue = "TradeStreamerTopic"), + @ActivationConfigProperty(propertyName = "subscriptionDurability", propertyValue = "NonDurable") }) +@Trace +public class DTStreamer3MDB implements MessageListener { + + private final MDBStats mdbStats; + private int statInterval = 10000; + + @Resource + public MessageDrivenContext mdc; + + + /** Creates a new instance of TradeSteamerMDB */ + public DTStreamer3MDB() { + Log.trace("DTStreamer3MDB:DTStreamer3MDB()"); + + if (statInterval <= 0) { + statInterval = 10000; + } + mdbStats = MDBStats.getInstance(); + } + + @Override + public void onMessage(Message message) { + + try { + Log.trace("DTStreamer3MDB:onMessage -- received message -->" + ((TextMessage) message).getText() + "command-->" + + message.getStringProperty("command") + "<--"); + + String command = message.getStringProperty("command"); + if (command == null) { + Log.debug("DTStreamer3MDB:onMessage -- received message with null command. Message-->" + message); + return; + } + if (command.equalsIgnoreCase("updateQuote")) { + Log.trace("DTStreamer3MDB:onMessage -- received message -->" + ((TextMessage) message).getText() + "\n\t symbol = " + + message.getStringProperty("symbol") + "\n\t current price =" + message.getStringProperty("price") + "\n\t old price =" + + message.getStringProperty("oldPrice")); + + long publishTime = message.getLongProperty("publishTime"); + long receiveTime = System.currentTimeMillis(); + + TimerStat currentStats = mdbStats.addTiming("DTStreamer3MDB:udpateQuote", publishTime, receiveTime); + + if ((currentStats.getCount() % statInterval) == 0) { + Log.log(" DTStreamer3MDB: " + statInterval + " prices updated:" + + " Total message count = " + currentStats.getCount() + + " Time (in seconds):" + + " min: " +currentStats.getMinSecs()+ + " max: " +currentStats.getMaxSecs()+ + " avg: " +currentStats.getAvgSecs() ); + } + } else if (command.equalsIgnoreCase("ping")) { + Log.trace("DTStreamer3MDB:onMessage received ping command -- message: " + ((TextMessage) message).getText()); + + + long publishTime = message.getLongProperty("publishTime"); + long receiveTime = System.currentTimeMillis(); + + TimerStat currentStats = mdbStats.addTiming("DTStreamer3MDB:ping", publishTime, receiveTime); + + if ((currentStats.getCount() % statInterval) == 0) { + Log.log(" DTStreamer3MDB: received " + statInterval + " ping messages." + + " Total message count = " + currentStats.getCount() + + " Time (in seconds):" + + " min: " +currentStats.getMinSecs()+ + " max: " +currentStats.getMaxSecs()+ + " avg: " +currentStats.getAvgSecs()); + } + } else { + Log.error("DTStreamer3MDB:onMessage - unknown message request command-->" + command + "<-- message=" + ((TextMessage) message).getText()); + } + } catch (Throwable t) { + // JMS onMessage should handle all exceptions + Log.error("DTStreamer3MDB: Exception", t); + //UPDATE - Not rolling back for now -- so error messages are not redelivered + mdc.setRollbackOnly(); + } + } + +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/util/Diagnostics.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/util/Diagnostics.java new file mode 100644 index 00000000..0c53c60c --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/util/Diagnostics.java @@ -0,0 +1,77 @@ +/** + * (C) Copyright IBM Corporation 2022. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.util; + +import java.util.concurrent.ArrayBlockingQueue; + +public class Diagnostics { + private static final int DRIVE_MEMORY = Integer.getInteger("DRIVE_MEMORY", 0); + private static final int DRIVE_LATENCY = Integer.getInteger("DRIVE_LATENCY", 0); + private static final int DRIVE_MEMACCUMULATION = Integer.getInteger("DRIVE_MEMACCUMULATION", 0); + private static final ArrayBlockingQueue accumulation; + + static { + if (DRIVE_MEMORY > 0) { + Log.warning("DRIVE_MEMORY=" + DRIVE_MEMORY + + " has been specified which will allocate that many bytes on some app requests"); + } + if (DRIVE_MEMACCUMULATION > 0) { + Log.warning("DRIVE_MEMACCUMULATION=" + DRIVE_MEMACCUMULATION + + " has been specified which will accumulate up to " + (DRIVE_MEMORY * DRIVE_MEMACCUMULATION) + + " bytes"); + accumulation = new ArrayBlockingQueue(DRIVE_MEMACCUMULATION); + } else { + accumulation = null; + } + if (DRIVE_LATENCY > 0) { + Log.warning("DRIVE_LATENCY=" + DRIVE_LATENCY + + " has been specified which will sleep that many milliseconds on some app requests"); + } + } + + public static void checkDiagnostics() { + if (DRIVE_MEMORY > 0) { + byte[] memory = new byte[DRIVE_MEMORY]; + // Not sure if Java will optimize this away if we don't use it, so just + // do something trivial + int count = 0; + for (byte b : memory) { + if ((b & 0x01) > 0) { + count++; + } + } + if (count > 0) { + Log.error("Something that shouldn't happen"); + } + if (DRIVE_MEMACCUMULATION > 0) { + synchronized (accumulation) { + if (accumulation.size() >= DRIVE_MEMACCUMULATION) { + accumulation.remove(); + } + accumulation.add(memory); + } + } + } + + if (DRIVE_LATENCY > 0) { + try { + Thread.sleep(DRIVE_LATENCY); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/util/FinancialUtils.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/util/FinancialUtils.java new file mode 100644 index 00000000..076529ce --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/util/FinancialUtils.java @@ -0,0 +1,105 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.util; + +import java.math.BigDecimal; +import java.util.Collection; +import java.util.Iterator; + +import com.ibm.websphere.samples.daytrader.entities.HoldingDataBean; + +public class FinancialUtils { + + public static final int ROUND = BigDecimal.ROUND_HALF_UP; + public static final int SCALE = 2; + public static final BigDecimal ZERO = (new BigDecimal(0.00)).setScale(SCALE); + public static final BigDecimal ONE = (new BigDecimal(1.00)).setScale(SCALE); + public static final BigDecimal HUNDRED = (new BigDecimal(100.00)).setScale(SCALE); + + public static BigDecimal computeGain(BigDecimal currentBalance, BigDecimal openBalance) { + return currentBalance.subtract(openBalance).setScale(SCALE); + } + + public static BigDecimal computeGainPercent(BigDecimal currentBalance, BigDecimal openBalance) { + if (openBalance.doubleValue() == 0.0) { + return ZERO; + } + BigDecimal gainPercent = currentBalance.divide(openBalance, ROUND).subtract(ONE).multiply(HUNDRED); + return gainPercent; + } + + public static BigDecimal computeHoldingsTotal(Collection holdingDataBeans) { + BigDecimal holdingsTotal = new BigDecimal(0.0).setScale(SCALE); + if (holdingDataBeans == null) { + return holdingsTotal; + } + Iterator it = holdingDataBeans.iterator(); + while (it.hasNext()) { + HoldingDataBean holdingData = (HoldingDataBean) it.next(); + BigDecimal total = holdingData.getPurchasePrice().multiply(new BigDecimal(holdingData.getQuantity())); + holdingsTotal = holdingsTotal.add(total); + } + return holdingsTotal.setScale(SCALE); + } + + public static String printGainHTML(BigDecimal gain) { + String htmlString, arrow; + if (gain.doubleValue() < 0.0) { + htmlString = ""; + arrow = "arrowdown.gif"; + } else { + htmlString = ""; + arrow = "arrowup.gif"; + } + + htmlString += gain.setScale(SCALE, ROUND) + ""; + return htmlString; + } + + public static String printChangeHTML(double change) { + String htmlString, arrow; + if (change < 0.0) { + htmlString = ""; + arrow = "arrowdown.gif"; + } else { + htmlString = ""; + arrow = "arrowup.gif"; + } + + htmlString += change + ""; + return htmlString; + } + + public static String printGainPercentHTML(BigDecimal gain) { + String htmlString, arrow; + if (gain.doubleValue() < 0.0) { + htmlString = "("; + arrow = "arrowdown.gif"; + } else { + htmlString = "(+"; + arrow = "arrowup.gif"; + } + + htmlString += gain.setScale(SCALE, ROUND); + htmlString += "%)"; + return htmlString; + } + + public static String printQuoteLink(String symbol) { + return "" + symbol + ""; + } + +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/util/KeyBlock.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/util/KeyBlock.java new file mode 100644 index 00000000..8133d60f --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/util/KeyBlock.java @@ -0,0 +1,140 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.util; + +import java.util.AbstractSequentialList; +import java.util.ListIterator; + +public class KeyBlock extends AbstractSequentialList { + + // min and max provide range of valid primary keys for this KeyBlock + private int min = 0; + private int max = 0; + private int index = 0; + + /** + * Constructor for KeyBlock + */ + public KeyBlock() { + super(); + min = 0; + max = 0; + index = min; + } + + /** + * Constructor for KeyBlock + */ + public KeyBlock(int min, int max) { + super(); + this.min = min; + this.max = max; + index = min; + } + + /** + * @see AbstractCollection#size() + */ + @Override + public int size() { + return (max - min) + 1; + } + + /** + * @see AbstractSequentialList#listIterator(int) + */ + @Override + public ListIterator listIterator(int arg0) { + return new KeyBlockIterator(); + } + + class KeyBlockIterator implements ListIterator { + + /** + * @see ListIterator#hasNext() + */ + @Override + public boolean hasNext() { + return index <= max; + } + + /** + * @see ListIterator#next() + */ + @Override + public synchronized Object next() { + if (index > max) { + throw new java.lang.RuntimeException("KeyBlock:next() -- Error KeyBlock depleted"); + } + return new Integer(index++); + } + + /** + * @see ListIterator#hasPrevious() + */ + @Override + public boolean hasPrevious() { + return index > min; + } + + /** + * @see ListIterator#previous() + */ + @Override + public Object previous() { + return new Integer(--index); + } + + /** + * @see ListIterator#nextIndex() + */ + @Override + public int nextIndex() { + return index - min; + } + + /** + * @see ListIterator#previousIndex() + */ + @Override + public int previousIndex() { + throw new UnsupportedOperationException("KeyBlock: previousIndex() not supported"); + } + + /** + * @see ListIterator#add() + */ + @Override + public void add(Object o) { + throw new UnsupportedOperationException("KeyBlock: add() not supported"); + } + + /** + * @see ListIterator#remove() + */ + @Override + public void remove() { + throw new UnsupportedOperationException("KeyBlock: remove() not supported"); + } + + /** + * @see ListIterator#set(Object) + */ + @Override + public void set(Object arg0) { + } + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/util/Log.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/util/Log.java new file mode 100644 index 00000000..83928517 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/util/Log.java @@ -0,0 +1,162 @@ +/** + * (C) Copyright IBM Corporation 2015, 2022. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.util; + +import java.util.Collection; +import java.util.Iterator; +import java.util.logging.Level; +import java.util.logging.Logger; + + + +public class Log { + + private final static Logger log = Logger.getLogger("daytrader"); + + + // A general purpose, high performance logging, tracing, statistic service + + public static void log(String message) { + log.log(Level.INFO, message); + } + + public static void log(String msg1, String msg2) { + log(msg1 + msg2); + } + + public static void log(String msg1, String msg2, String msg3) { + log(msg1 + msg2 + msg3); + } + + public static void error(String message) { + message = "Error: " + message; + log.severe(message); + } + + public static void error(String message, Throwable e) { + error(message + "\n\t" + e.toString()); + e.printStackTrace(System.out); + } + + public static void error(String msg1, String msg2, Throwable e) { + error(msg1 + "\n" + msg2 + "\n\t", e); + } + + public static void error(String msg1, String msg2, String msg3, Throwable e) { + error(msg1 + "\n" + msg2 + "\n" + msg3 + "\n\t", e); + } + + public static void error(Throwable e, String message) { + error(message + "\n\t", e); + e.printStackTrace(System.out); + } + + public static void error(Throwable e, String msg1, String msg2) { + error(msg1 + "\n" + msg2 + "\n\t", e); + } + + public static void error(Throwable e, String msg1, String msg2, String msg3) { + error(msg1 + "\n" + msg2 + "\n" + msg3 + "\n\t", e); + } + + public static void trace(String message) { + log.log(Level.FINE, message + " threadID=" + Thread.currentThread()); + } + + public static void traceInterceptor(String message, Object parm1) { + log.log(Level.SEVERE,message,parm1); + } + + public static void trace(String message, Object parm1) { + trace(message + "(" + parm1 + ")"); + } + + public static void trace(String message, Object parm1, Object parm2) { + trace(message + "(" + parm1 + ", " + parm2 + ")"); + } + + public static void trace(String message, Object parm1, Object parm2, Object parm3) { + trace(message + "(" + parm1 + ", " + parm2 + ", " + parm3 + ")"); + } + + public static void trace(String message, Object parm1, Object parm2, Object parm3, Object parm4) { + trace(message + "(" + parm1 + ", " + parm2 + ", " + parm3 + ")" + ", " + parm4); + } + + public static void trace(String message, Object parm1, Object parm2, Object parm3, Object parm4, Object parm5) { + trace(message + "(" + parm1 + ", " + parm2 + ", " + parm3 + ")" + ", " + parm4 + ", " + parm5); + } + + public static void trace(String message, Object parm1, Object parm2, Object parm3, Object parm4, Object parm5, Object parm6) { + trace(message + "(" + parm1 + ", " + parm2 + ", " + parm3 + ")" + ", " + parm4 + ", " + parm5 + ", " + parm6); + } + + public static void trace(String message, Object parm1, Object parm2, Object parm3, Object parm4, Object parm5, Object parm6, Object parm7) { + trace(message + "(" + parm1 + ", " + parm2 + ", " + parm3 + ")" + ", " + parm4 + ", " + parm5 + ", " + parm6 + ", " + parm7); + } + + public static void traceEnter(String message) { + log.log(Level.FINE,"Method enter --" + message); + } + + public static void traceExit(String message) { + log.log(Level.FINE,"Method exit --" + message); + } + + public static void stat(String message) { + log(message); + } + + public static void debug(String message) { + log.log(Level.INFO,message); + } + + public static void print(String message) { + log(message); + } + + public static void printObject(Object o) { + log("\t" + o.toString()); + } + + public static void printCollection(Collection c) { + log("\t---Log.printCollection -- collection size=" + c.size()); + Iterator it = c.iterator(); + + while (it.hasNext()) { + log("\t\t" + it.next().toString()); + } + log("\t---Log.printCollection -- complete"); + } + + public static void printCollection(String message, Collection c) { + log(message); + printCollection(c); + } + + + public static boolean doDebug() { + return true; + } + + public static boolean doTrace() { + return log.isLoggable(Level.FINE); + } + + public static void warning(String message) { + log.log(Level.WARNING, message); + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/util/MDBStats.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/util/MDBStats.java new file mode 100644 index 00000000..fc49ba01 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/util/MDBStats.java @@ -0,0 +1,68 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.util; + +/** + * + * To change this generated comment edit the template variable "typecomment": + * Window>Preferences>Java>Templates. To enable and disable the creation of type + * comments go to Window>Preferences>Java>Code Generation. + */ +public class MDBStats extends java.util.HashMap { + + private static final long serialVersionUID = -3759835921094193760L; + // Singleton class + private static MDBStats mdbStats = null; + + private MDBStats() { + } + + public static synchronized MDBStats getInstance() { + if (mdbStats == null) { + mdbStats = new MDBStats(); + } + return mdbStats; + } + + public TimerStat addTiming(String type, long sendTime, long recvTime) { + TimerStat stats = null; + synchronized (type) { + + stats = get(type); + if (stats == null) { + stats = new TimerStat(); + } + + long time = recvTime - sendTime; + if (time > stats.getMax()) { + stats.setMax(time); + } + if (time < stats.getMin()) { + stats.setMin(time); + } + stats.setCount(stats.getCount() + 1); + stats.setTotalTime(stats.getTotalTime() + time); + + put(type, stats); + } + return stats; + } + + public synchronized void reset() { + clear(); + } + +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/util/RecentQuotePriceChangeList.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/util/RecentQuotePriceChangeList.java new file mode 100644 index 00000000..cf3966da --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/util/RecentQuotePriceChangeList.java @@ -0,0 +1,77 @@ +/** + * (C) Copyright IBM Corporation 2019. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.util; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +import javax.annotation.Resource; +import javax.enterprise.concurrent.ManagedExecutorService; +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.event.Event; +import javax.enterprise.event.NotificationOptions; +import javax.inject.Inject; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +import com.ibm.websphere.samples.daytrader.entities.QuoteDataBean; +import com.ibm.websphere.samples.daytrader.interfaces.QuotePriceChange; + + +/** This class is a holds the last 5 stock changes, used by the MarketSummary WebSocket + * and the JAX-RS SSE Broadcaster + * It fires a CDI event everytime a price change is added + **/ + +@ApplicationScoped +public class RecentQuotePriceChangeList { + + private List list = new CopyOnWriteArrayList(); + private int maxSize = 5; + + @Resource + private ManagedExecutorService mes; + + @Inject + @QuotePriceChange + Event quotePriceChangeEvent; + + public boolean add(QuoteDataBean quoteData) { + + int symbolNumber = new Integer(quoteData.getSymbol().substring(2)); + + if ( symbolNumber < TradeConfig.getMAX_QUOTES() * TradeConfig.getListQuotePriceChangeFrequency() * 0.01) { + list.add(0, quoteData); + + // Add stock, remove if needed + if(list.size() > maxSize) { + list.remove(maxSize); + } + quotePriceChangeEvent.fireAsync("quotePriceChange for symbol: " + quoteData.getSymbol(), NotificationOptions.builder().setExecutor(mes).build()); + } + return true; + } + + public boolean isEmpty() { + return list.isEmpty(); + } + + @Size(max=5) + @NotEmpty + public List<@NotNull QuoteDataBean> recentList() { + return list; + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/util/TimerStat.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/util/TimerStat.java new file mode 100644 index 00000000..c3057b48 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/util/TimerStat.java @@ -0,0 +1,133 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.util; + +/** + * + * To change this generated comment edit the template variable "typecomment": + * Window>Preferences>Java>Templates. To enable and disable the creation of type + * comments go to Window>Preferences>Java>Code Generation. + */ +public class TimerStat { + + private double min = 1000000000.0, max = 0.0, totalTime = 0.0; + private int count; + + /** + * Returns the count. + * + * @return int + */ + public int getCount() { + return count; + } + + /** + * Returns the max. + * + * @return double + */ + public double getMax() { + return max; + } + + /** + * Returns the min. + * + * @return double + */ + public double getMin() { + return min; + } + + /** + * Sets the count. + * + * @param count + * The count to set + */ + public void setCount(int count) { + this.count = count; + } + + /** + * Sets the max. + * + * @param max + * The max to set + */ + public void setMax(double max) { + this.max = max; + } + + /** + * Sets the min. + * + * @param min + * The min to set + */ + public void setMin(double min) { + this.min = min; + } + + /** + * Returns the totalTime. + * + * @return double + */ + public double getTotalTime() { + return totalTime; + } + + /** + * Sets the totalTime. + * + * @param totalTime + * The totalTime to set + */ + public void setTotalTime(double totalTime) { + this.totalTime = totalTime; + } + + /** + * Returns the max in Secs + * + * @return double + */ + public double getMaxSecs() { + return max / 1000.0; + } + + /** + * Returns the min in Secs + * + * @return double + */ + public double getMinSecs() { + return min / 1000.0; + } + + /** + * Returns the average time in Secs + * + * @return double + */ + public double getAvgSecs() { + + double avg = getTotalTime() / getCount(); + return avg / 1000.0; + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/util/TraceInterceptor.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/util/TraceInterceptor.java new file mode 100644 index 00000000..5af7f4b3 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/util/TraceInterceptor.java @@ -0,0 +1,49 @@ +/** + * (C) Copyright IBM Corporation 2019. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.util; + +import java.io.Serializable; +import java.text.MessageFormat; +import java.util.Arrays; + +import javax.annotation.Priority; + +import javax.interceptor.AroundInvoke; +import javax.interceptor.Interceptor; +import javax.interceptor.InvocationContext; + +import com.ibm.websphere.samples.daytrader.interfaces.Trace; + + +@Trace +@Interceptor +@Priority(Interceptor.Priority.APPLICATION) +public class TraceInterceptor implements Serializable { + + private static final long serialVersionUID = -4195975993998268072L; + private static final MessageFormat form = new MessageFormat("Method enter -- {0} called with {1}"); + + @AroundInvoke + public Object logMethodEntry(InvocationContext ctx) throws Exception { + Log.trace(form.format( + new String[]{ + ctx.getMethod().getDeclaringClass().getSimpleName() + ":"+ ctx.getMethod().getName(), + Arrays.deepToString(ctx.getParameters()) + })); + + return ctx.proceed(); + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/util/TradeConfig.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/util/TradeConfig.java new file mode 100644 index 00000000..34a03983 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/util/TradeConfig.java @@ -0,0 +1,752 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.util; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Random; + +/** + * TradeConfig is a JavaBean holding all configuration and runtime parameters + * for the Trade application TradeConfig sets runtime parameters such as the + * RunTimeMode (EJB, JDBC, EJB_ALT) + * + */ + +public class TradeConfig { + + /* Trade Runtime Configuration Parameters */ + + /* Trade Runtime Mode parameters */ + private static String[] runTimeModeNames = { "Full EJB3", "Direct (JDBC)", "Session to Direct"}; + public static final int EJB3 = 0; + public static final int DIRECT = 1; + public static final int SESSION_TO_DIRECT = 2; + private static int runTimeMode = EJB3; + + private static String[] orderProcessingModeNames = { "Sync", "Async","Async_2-Phase" }; + public static final int SYNCH = 0; + public static final int ASYNCH = 1; + public static final int ASYNCH_2PHASE = 2; + private static int orderProcessingMode = SYNCH; + + private static String[] accessModeNames = { "Standard", "WebServices" }; + public static final int STANDARD = 0; + private static int accessMode = STANDARD; + + /* Trade Web Interface parameters */ + private static String[] webInterfaceNames = { "JSP", "JSP-Images", "JSP-Images-Http2" }; + public static final int JSP = 0; + public static final int JSP_Images = 1; + public static final int JSP_Images_HTTP2 = 2; + private static int webInterface = JSP; + + /* Trade Database Scaling parameters */ + private static int MAX_USERS = 15000; + private static int MAX_QUOTES = 10000; + + + /* Trade XA Datasource specific parameters */ + public static boolean JDBCDriverNeedsGlobalTransation = false; + + /* Trade Config Miscellaneous itmes */ + public static String DATASOURCE = "java:comp/env/jdbc/TradeDataSource"; + public static int KEYBLOCKSIZE = 1000; + public static int QUOTES_PER_PAGE = 10; + public static boolean RND_USER = true; + // public static int RND_SEED = 0; + private static int MAX_HOLDINGS = 10; + private static int count = 0; + private static Object userID_count_semaphore = new Object(); + private static int userID_count = 0; + private static String hostName = null; + private static Random r0 = new Random(System.currentTimeMillis()); + // private static Random r1 = new Random(RND_SEED); + private static Random randomNumberGenerator = r0; + public static final String newUserPrefix = "ru:"; + public static final int verifyPercent = 5; + private static boolean updateQuotePrices = true; + private static int primIterations = 1; + private static boolean longRun = true; + private static boolean publishQuotePriceChange = true; + private static int listQuotePriceChangeFrequency = 100; + private static boolean displayOrderAlerts = true; + + /** + * -1 means every operation 0 means never perform a market summary > 0 means + * number of seconds between summaries. These will be synchronized so only + * one transaction in this period will create a summary and will cache its + * results. + */ + private static int marketSummaryInterval = 20; + + /* + * Penny stocks is a problem where the random price change factor gets a + * stock down to $.01. In this case trade jumpstarts the price back to $6.00 + * to keep the math interesting. + */ + public static BigDecimal PENNY_STOCK_PRICE; + public static BigDecimal PENNY_STOCK_RECOVERY_MIRACLE_MULTIPLIER; + static { + PENNY_STOCK_PRICE = new BigDecimal(0.01); + PENNY_STOCK_PRICE = PENNY_STOCK_PRICE.setScale(2, BigDecimal.ROUND_HALF_UP); + PENNY_STOCK_RECOVERY_MIRACLE_MULTIPLIER = new BigDecimal(600.0); + PENNY_STOCK_RECOVERY_MIRACLE_MULTIPLIER.setScale(2, BigDecimal.ROUND_HALF_UP); + } + + /* + * CJB (DAYTRADER-25) - Also need to impose a ceiling on the quote price to + * ensure prevent account and holding balances from exceeding the databases + * decimal precision. At some point, this maximum value can be used to + * trigger a stock split. + */ + + public static BigDecimal MAXIMUM_STOCK_PRICE; + public static BigDecimal MAXIMUM_STOCK_SPLIT_MULTIPLIER; + static { + MAXIMUM_STOCK_PRICE = new BigDecimal(400); + MAXIMUM_STOCK_PRICE.setScale(2, BigDecimal.ROUND_HALF_UP); + MAXIMUM_STOCK_SPLIT_MULTIPLIER = new BigDecimal(0.5); + MAXIMUM_STOCK_SPLIT_MULTIPLIER.setScale(2, BigDecimal.ROUND_HALF_UP); + } + + /* + * Trade Scenario actions mixes. Each of the array rows represents a + * specific Trade Scenario Mix. The columns give the percentages for each + * action in the column header. Note: "login" is always 0. logout represents + * both login and logout (because each logout operation will cause a new + * login when the user context attempts the next action. + */ + /* Trade Scenario Workload parameters */ + public static final int HOME_OP = 0; + public static final int QUOTE_OP = 1; + public static final int LOGIN_OP = 2; + public static final int LOGOUT_OP = 3; + public static final int REGISTER_OP = 4; + public static final int ACCOUNT_OP = 5; + public static final int PORTFOLIO_OP = 6; + public static final int BUY_OP = 7; + public static final int SELL_OP = 8; + public static final int UPDATEACCOUNT_OP = 9; + + private static int[][] scenarioMixes = { + // h q l o r a p b s u + { 20, 40, 0, 4, 2, 10, 12, 4, 4, 4 }, // STANDARD + { 20, 40, 0, 4, 2, 7, 7, 7, 7, 6 }, // High Volume + }; + private static char[] actions = { 'h', 'q', 'l', 'o', 'r', 'a', 'p', 'b', 's', 'u' }; + private static int sellDeficit = 0; + // Tracks the number of buys over sell when a users portfolio is empty + // Used to maintain the correct ratio of buys/sells + + /* JSP pages for all Trade Actions */ + + public static final int WELCOME_PAGE = 0; + public static final int REGISTER_PAGE = 1; + public static final int PORTFOLIO_PAGE = 2; + public static final int QUOTE_PAGE = 3; + public static final int HOME_PAGE = 4; + public static final int ACCOUNT_PAGE = 5; + public static final int ORDER_PAGE = 6; + public static final int CONFIG_PAGE = 7; + public static final int STATS_PAGE = 8; + public static final int MARKET_SUMMARY_PAGE = 9; + + // FUTURE Add XML/XSL View + public static String[][] webUI = { + { "/welcome.jsp", "/register.jsp", "/portfolio.jsp", "/quote.jsp", "/tradehome.jsp", "/account.jsp", "/order.jsp", "/config.jsp", "/runStats.jsp", + "/marketSummary.jsp" }, + // JSP Interface + { "/welcomeImg.jsp", "/registerImg.jsp", "/portfolioImg.jsp", "/quoteImg.jsp", "/tradehomeImg.jsp", "/accountImg.jsp", "/orderImg.jsp", + "/config.jsp", "/runStats.jsp", "/marketSummary.jsp" }, + // JSP Interface + { "/welcomeImg.jsp", "/registerImg.jsp", "/portfolioImg.jsp", "/quoteImg.jsp", "/tradehomeImg.jsp", "/accountImg.jsp", "/orderImg.jsp", + "/config.jsp", "/runStats.jsp", "/marketSummary.jsp" }, + }; + + + /** + * Return the hostname for this system Creation date: (2/16/2000 9:02:25 PM) + */ + + private static String getHostname() { + try { + if (hostName == null) { + hostName = java.net.InetAddress.getLocalHost().getHostName(); + // Strip of fully qualifed domain if necessary + try { + hostName = hostName.substring(0, hostName.indexOf('.')); + } catch (Exception e) { + } + } + } catch (Exception e) { + Log.error("Exception getting local host name using 'localhost' - ", e); + hostName = "localhost"; + } + return hostName; + } + + /** + * Return a Trade UI Web page based on the current configuration This may + * return a JSP page or a Servlet page Creation date: (3/14/2000 9:08:34 PM) + */ + + public static String getPage(int pageNumber) { + return webUI[webInterface][pageNumber]; + } + + /** + * Return the list of run time mode names Creation date: (3/8/2000 5:58:34 + * PM) + * + * @return java.lang.String[] + */ + public static java.lang.String[] getRunTimeModeNames() { + return runTimeModeNames; + } + + private static int scenarioCount = 0; + + /** + * Return a Trade Scenario Operation based on the setting of the current mix + * (TradeScenarioMix) Creation date: (2/10/2000 9:08:34 PM) + */ + + public static char getScenarioAction(boolean newUser) { + int r = rndInt(100); // 0 to 99 = 100 + int i = 0; + int sum = scenarioMixes[0][i]; + while (sum <= r) { + i++; + sum += scenarioMixes[0][i]; + } + + incrementScenarioCount(); + + /* + * In TradeScenarioServlet, if a sell action is selected, but the users + * portfolio is empty, a buy is executed instead and sellDefecit is + * incremented. This allows the number of buy/sell operations to stay in + * sync w/ the given Trade mix. + */ + + if ((!newUser) && (actions[i] == 'b')) { + synchronized (TradeConfig.class) { + if (sellDeficit > 0) { + sellDeficit--; + return 's'; + // Special case for TradeScenarioServlet to note this is a + // buy switched to a sell to fix sellDeficit + } + } + } + + return actions[i]; + } + + public static String getUserID() { + String userID; + if (RND_USER) { + userID = rndUserID(); + } else { + userID = nextUserID(); + } + return userID; + } + + private static final BigDecimal orderFee = new BigDecimal("24.95"); + private static final BigDecimal cashFee = new BigDecimal("0.0"); + + public static BigDecimal getOrderFee(String orderType) { + if ((orderType.compareToIgnoreCase("BUY") == 0) || (orderType.compareToIgnoreCase("SELL") == 0)) { + return orderFee; + } + + return cashFee; + + } + + /** + * Increment the sell deficit counter Creation date: (6/21/2000 11:33:45 AM) + */ + public static synchronized void incrementSellDeficit() { + sellDeficit++; + } + + public static String nextUserID() { + String userID; + synchronized (userID_count_semaphore) { + userID = "uid:" + userID_count; + userID_count++; + if (userID_count % MAX_USERS == 0) { + userID_count = 0; + } + } + return userID; + } + + public static double random() { + return randomNumberGenerator.nextDouble(); + } + + public static String rndAddress() { + return rndInt(1000) + " Oak St."; + } + + public static String rndBalance() { + // Give all new users a cool mill in which to trade + return "1000000"; + } + + public static String rndCreditCard() { + return rndInt(100) + "-" + rndInt(1000) + "-" + rndInt(1000) + "-" + rndInt(1000); + } + + public static String rndEmail(String userID) { + return userID.replace(":", "") + "@" + rndInt(100) + ".com"; + } + + public static String rndFullName() { + return "first:" + rndInt(1000) + " last:" + rndInt(5000); + } + + public static int rndInt(int i) { + return (new Float(random() * i)).intValue(); + } + + public static float rndFloat(int i) { + return (new Float(random() * i)).floatValue(); + } + + public static BigDecimal rndBigDecimal(float f) { + return (new BigDecimal(random() * f)).setScale(2, BigDecimal.ROUND_HALF_UP); + } + + public static boolean rndBoolean() { + return randomNumberGenerator.nextBoolean(); + } + + /** + * Returns a new Trade user Creation date: (2/16/2000 8:50:35 PM) + */ + public static synchronized String rndNewUserID() { + + return newUserPrefix + getHostname() + System.currentTimeMillis() + count++; + } + + public static float rndPrice() { + return ((new Integer(rndInt(200))).floatValue()) + 1.0f; + } + + private static final BigDecimal ONE = new BigDecimal(1.0); + + public static BigDecimal getRandomPriceChangeFactor() { + // CJB (DAYTRADER-25) - Vary change factor between 1.1 and 0.9 + double percentGain = rndFloat(1) * 0.1; + if (random() < .5) { + percentGain *= -1; + } + percentGain += 1; + + // change factor is between +/- 20% + BigDecimal percentGainBD = (new BigDecimal(percentGain)).setScale(2, BigDecimal.ROUND_HALF_UP); + if (percentGainBD.doubleValue() <= 0.0) { + percentGainBD = ONE; + } + + return percentGainBD; + } + + public static float rndQuantity() { + return ((new Integer(rndInt(200))).floatValue()) + 1.0f; + } + + public static String rndSymbol() { + return "s:" + rndInt(MAX_QUOTES - 1); + } + + public static String rndSymbols() { + + String symbols = ""; + int num_symbols = rndInt(QUOTES_PER_PAGE); + + for (int i = 0; i <= num_symbols; i++) { + symbols += "s:" + rndInt(MAX_QUOTES - 1); + if (i < num_symbols) { + symbols += ","; + } + } + return symbols; + } + + public static String rndUserID() { + String nextUser = getNextUserIDFromDeck(); + + Log.trace("TradeConfig:rndUserID -- new trader = " + nextUser); + + + return nextUser; + } + + private static synchronized String getNextUserIDFromDeck() { + int numUsers = getMAX_USERS(); + if (deck == null) { + deck = new ArrayList(numUsers); + for (int i = 0; i < numUsers; i++) { + deck.add(i, new Integer(i)); + } + java.util.Collections.shuffle(deck, r0); + } + if (card >= numUsers) { + card = 0; + } + return "uid:" + deck.get(card++); + + } + + // Trade implements a card deck approach to selecting + // users for trading with tradescenarioservlet + private static ArrayList deck = null; + private static int card = 0; + + /** + * This is a convenience method for servlets to set Trade configuration + * parameters from servlet initialization parameters. The servlet provides + * the init param and its value as strings. This method then parses the + * parameter, converts the value to the correct type and sets the + * corresponding TradeConfig parameter to the converted value + * + */ + public static void setConfigParam(String parm, String value) { + Log.log("TradeConfig setting parameter: " + parm + "=" + value); + // Compare the parm value to valid TradeConfig parameters that can be + // set + // by servlet initialization + + // First check the proposed new parm and value - if empty or null ignore + // it + if (parm == null) { + return; + } + parm = parm.trim(); + if (parm.length() <= 0) { + return; + } + if (value == null) { + return; + } + value = value.trim(); + + if (parm.equalsIgnoreCase("orderProcessingMode")) { + try { + for (int i = 0; i < orderProcessingModeNames.length; i++) { + if (value.equalsIgnoreCase(orderProcessingModeNames[i])) { + orderProcessingMode = i; + break; + } + } + } catch (Exception e) { + Log.error("TradeConfig.setConfigParm(..): minor exception caught" + "trying to set orderProcessingMode to " + value + + "reverting to current value: " + orderProcessingModeNames[orderProcessingMode], e); + } // If the value is bad, simply revert to current + } else if (parm.equalsIgnoreCase("accessMode")) { + try { + for (int i = 0; i < accessModeNames.length; i++) { + if (value.equalsIgnoreCase(accessModeNames[i])) { + accessMode = i; + break; + } + } + } catch (Exception e) { + Log.error("TradeConfig.setConfigParm(..): minor exception caught" + "trying to set accessMode to " + value + "reverting to current value: " + + accessModeNames[accessMode], e); + } + } else if (parm.equalsIgnoreCase("WebInterface")) { + try { + for (int i = 0; i < webInterfaceNames.length; i++) { + if (value.equalsIgnoreCase(webInterfaceNames[i])) { + webInterface = i; + break; + } + } + } catch (Exception e) { + Log.error("TradeConfig.setConfigParm(..): minor exception caught" + "trying to set WebInterface to " + value + "reverting to current value: " + + webInterfaceNames[webInterface], e); + + } // If the value is bad, simply revert to current + } else if (parm.equalsIgnoreCase("maxUsers")) { + try { + MAX_USERS = Integer.parseInt(value); + } catch (Exception e) { + Log.error("TradeConfig.setConfigParm(..): minor exception caught" + "Setting maxusers, error parsing string to int:" + value + + "revering to current value: " + MAX_USERS, e); + } // On error, revert to saved + } else if (parm.equalsIgnoreCase("maxQuotes")) { + try { + MAX_QUOTES = Integer.parseInt(value); + } catch (Exception e) { + // >>rjm + Log.error("TradeConfig.setConfigParm(...) minor exception caught" + "Setting max_quotes, error parsing string to int " + value + + "reverting to current value: " + MAX_QUOTES, e); + // < implements RuntimeMode { + + private static final long serialVersionUID = -252789556335033400L; + private String value; + public TradeRunTimeModeLiteral(String value) { + this.value = value; + } + + @Override + public String value() { + return value; + } + +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/AccountDataJSF.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/AccountDataJSF.java new file mode 100644 index 00000000..9c14067d --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/AccountDataJSF.java @@ -0,0 +1,327 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.jsf; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.Iterator; + +import javax.annotation.PostConstruct; +import javax.enterprise.context.RequestScoped; +import javax.enterprise.inject.Any; +import javax.enterprise.inject.Instance; +import javax.faces.context.ExternalContext; +import javax.inject.Inject; +import javax.inject.Named; +import javax.servlet.http.HttpSession; +import javax.validation.constraints.PastOrPresent; +import javax.validation.constraints.PositiveOrZero; + +import com.ibm.websphere.samples.daytrader.entities.AccountDataBean; +import com.ibm.websphere.samples.daytrader.entities.HoldingDataBean; +import com.ibm.websphere.samples.daytrader.entities.OrderDataBean; +import com.ibm.websphere.samples.daytrader.interfaces.Trace; +import com.ibm.websphere.samples.daytrader.interfaces.TradeServices; +import com.ibm.websphere.samples.daytrader.util.FinancialUtils; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; +import com.ibm.websphere.samples.daytrader.util.TradeRunTimeModeLiteral; + +@Named("accountdata") +@RequestScoped +@Trace +public class AccountDataJSF { + + @Inject + private ExternalContext context; + + private TradeServices tradeAction; + + private Date sessionCreationDate; + private Date currentTime; + private String profileID; + private Integer accountID; + + @PastOrPresent + private Date creationDate; + + @PositiveOrZero + private int loginCount; + + @PastOrPresent + private Date lastLogin; + + @PositiveOrZero + private int logoutCount; + private BigDecimal balance; + private BigDecimal openBalance; + private Integer numberHoldings; + private BigDecimal holdingsTotal; + private BigDecimal sumOfCashHoldings; + private BigDecimal gain; + private BigDecimal gainPercent; + + private OrderData[] closedOrders; + private OrderData[] allOrders; + + private Integer numberOfOrders = 0; + private Integer numberOfOrderRows = 5; + + public void toggleShowAllRows() { + setNumberOfOrderRows(0); + } + + @Inject + public AccountDataJSF(@Any Instance services) { + tradeAction = services.select(new TradeRunTimeModeLiteral(TradeConfig.getRunTimeModeNames()[TradeConfig.getRunTimeMode()])).get(); + } + + @PostConstruct + public void home() { + try { + HttpSession session = (HttpSession) context.getSession(true); + + // Get the data and then parse + String userID = (String) session.getAttribute("uidBean"); + AccountDataBean accountData = tradeAction.getAccountData(userID); + Collection holdingDataBeans = tradeAction.getHoldings(userID); + + if (TradeConfig.getDisplayOrderAlerts()) { + + Collection closedOrders = tradeAction.getClosedOrders(userID); + + if (closedOrders != null && closedOrders.size() > 0) { + session.setAttribute("closedOrders", closedOrders); + OrderData[] orderjsfs = new OrderData[closedOrders.size()]; + Iterator it = closedOrders.iterator(); + int i = 0; + + while (it.hasNext()) { + OrderDataBean order = (OrderDataBean) it.next(); + OrderData r = new OrderData(order.getOrderID(), order.getOrderStatus(), order.getOpenDate(), order.getCompletionDate(), + order.getOrderFee(), order.getOrderType(), order.getQuantity(), order.getSymbol()); + orderjsfs[i] = r; + i++; + } + + setClosedOrders(orderjsfs); + } + } + + Collection orderDataBeans = (TradeConfig.getLongRun() ? new ArrayList() : (Collection) tradeAction.getOrders(userID)); + + if (orderDataBeans != null && orderDataBeans.size() > 0) { + session.setAttribute("orderDataBeans", orderDataBeans); + OrderData[] orderjsfs = new OrderData[orderDataBeans.size()]; + Iterator it = orderDataBeans.iterator(); + int i = 0; + + while (it.hasNext()) { + OrderDataBean order = (OrderDataBean) it.next(); + OrderData r = new OrderData(order.getOrderID(), order.getOrderStatus(), order.getOpenDate(), order.getCompletionDate(), + order.getOrderFee(), order.getOrderType(), order.getQuantity(), order.getSymbol(),order.getPrice()); + orderjsfs[i] = r; + i++; + } + setNumberOfOrders(orderDataBeans.size()); + setAllOrders(orderjsfs); + } + + setSessionCreationDate((Date) session.getAttribute("sessionCreationDate")); + setCurrentTime(new java.util.Date()); + doAccountData(accountData, holdingDataBeans); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void doAccountData(AccountDataBean accountData, Collection holdingDataBeans) { + setProfileID(accountData.getProfileID()); + setAccountID(accountData.getAccountID()); + setCreationDate(accountData.getCreationDate()); + setLoginCount(accountData.getLoginCount()); + setLogoutCount(accountData.getLogoutCount()); + setLastLogin(accountData.getLastLogin()); + setOpenBalance(accountData.getOpenBalance()); + setBalance(accountData.getBalance()); + setNumberHoldings(holdingDataBeans.size()); + setHoldingsTotal(FinancialUtils.computeHoldingsTotal(holdingDataBeans)); + setSumOfCashHoldings(balance.add(holdingsTotal)); + setGain(FinancialUtils.computeGain(sumOfCashHoldings, openBalance)); + setGainPercent(FinancialUtils.computeGainPercent(sumOfCashHoldings, openBalance)); + } + + public Date getSessionCreationDate() { + return sessionCreationDate; + } + + public void setSessionCreationDate(Date sessionCreationDate) { + this.sessionCreationDate = sessionCreationDate; + } + + public Date getCurrentTime() { + return currentTime; + } + + public void setCurrentTime(Date currentTime) { + this.currentTime = currentTime; + } + + public String getProfileID() { + return profileID; + } + + public void setProfileID(String profileID) { + this.profileID = profileID; + } + + public void setAccountID(Integer accountID) { + this.accountID = accountID; + } + + public Integer getAccountID() { + return accountID; + } + + public void setCreationDate(Date creationDate) { + this.creationDate = creationDate; + } + + public Date getCreationDate() { + return creationDate; + } + + public void setLoginCount(int loginCount) { + this.loginCount = loginCount; + } + + public int getLoginCount() { + return loginCount; + } + + public void setBalance(BigDecimal balance) { + this.balance = balance; + } + + public BigDecimal getBalance() { + return balance; + } + + public void setOpenBalance(BigDecimal openBalance) { + this.openBalance = openBalance; + } + + public BigDecimal getOpenBalance() { + return openBalance; + } + + public void setHoldingsTotal(BigDecimal holdingsTotal) { + this.holdingsTotal = holdingsTotal; + } + + public BigDecimal getHoldingsTotal() { + return holdingsTotal; + } + + public void setSumOfCashHoldings(BigDecimal sumOfCashHoldings) { + this.sumOfCashHoldings = sumOfCashHoldings; + } + + public BigDecimal getSumOfCashHoldings() { + return sumOfCashHoldings; + } + + public void setGain(BigDecimal gain) { + this.gain = gain; + } + + public BigDecimal getGain() { + return gain; + } + + public void setGainPercent(BigDecimal gainPercent) { + this.gainPercent = gainPercent.setScale(2); + } + + public BigDecimal getGainPercent() { + return gainPercent; + } + + public void setNumberHoldings(Integer numberHoldings) { + this.numberHoldings = numberHoldings; + } + + public Integer getNumberHoldings() { + return numberHoldings; + } + + public OrderData[] getClosedOrders() { + return closedOrders; + } + + public void setClosedOrders(OrderData[] closedOrders) { + this.closedOrders = closedOrders; + } + + public void setLastLogin(Date lastLogin) { + this.lastLogin = lastLogin; + } + + public Date getLastLogin() { + return lastLogin; + } + + public void setLogoutCount(int logoutCount) { + this.logoutCount = logoutCount; + } + + public int getLogoutCount() { + return logoutCount; + } + + public void setAllOrders(OrderData[] allOrders) { + this.allOrders = allOrders; + } + + public OrderData[] getAllOrders() { + return allOrders; + } + + public String getGainHTML() { + return FinancialUtils.printGainHTML(gain); + } + + public String getGainPercentHTML() { + return FinancialUtils.printGainPercentHTML(gainPercent); + } + + public Integer getNumberOfOrderRows() { + return numberOfOrderRows; + } + + public void setNumberOfOrderRows(Integer numberOfOrderRows) { + this.numberOfOrderRows = numberOfOrderRows; + } + + public Integer getNumberOfOrders() { + return numberOfOrders; + } + + public void setNumberOfOrders(Integer numberOfOrders) { + this.numberOfOrders = numberOfOrders; + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/HoldingData.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/HoldingData.java new file mode 100644 index 00000000..a0a395ea --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/HoldingData.java @@ -0,0 +1,118 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.jsf; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Named; + +import com.ibm.websphere.samples.daytrader.util.FinancialUtils; + +@Named +@RequestScoped +public class HoldingData implements Serializable { + + private static final long serialVersionUID = -4760036695773749721L; + + private Integer holdingID; + private double quantity; + private BigDecimal purchasePrice; + private Date purchaseDate; + private String quoteID; + private BigDecimal price; + private BigDecimal basis; + private BigDecimal marketValue; + private BigDecimal gain; + + public void setHoldingID(Integer holdingID) { + this.holdingID = holdingID; + } + + public Integer getHoldingID() { + return holdingID; + } + + public void setQuantity(double quantity) { + this.quantity = quantity; + } + + public double getQuantity() { + return quantity; + } + + public void setPurchasePrice(BigDecimal purchasePrice) { + this.purchasePrice = purchasePrice; + } + + public BigDecimal getPurchasePrice() { + return purchasePrice; + } + + public void setPurchaseDate(Date purchaseDate) { + this.purchaseDate = purchaseDate; + } + + public Date getPurchaseDate() { + return purchaseDate; + } + + public void setQuoteID(String quoteID) { + this.quoteID = quoteID; + } + + public String getQuoteID() { + return quoteID; + } + + public void setPrice(BigDecimal price) { + this.price = price; + } + + public BigDecimal getPrice() { + return price; + } + + public void setBasis(BigDecimal basis) { + this.basis = basis; + } + + public BigDecimal getBasis() { + return basis; + } + + public void setMarketValue(BigDecimal marketValue) { + this.marketValue = marketValue; + } + + public BigDecimal getMarketValue() { + return marketValue; + } + + public void setGain(BigDecimal gain) { + this.gain = gain; + } + + public BigDecimal getGain() { + return gain; + } + + public String getGainHTML() { + return FinancialUtils.printGainHTML(gain); + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/JSFLoginFilter.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/JSFLoginFilter.java new file mode 100644 index 00000000..e9732088 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/JSFLoginFilter.java @@ -0,0 +1,88 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.jsf; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +//import javax.servlet.annotation.WebFilter; +import javax.servlet.annotation.WebFilter; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +@WebFilter(filterName = "JSFLoginFilter", urlPatterns = "*.faces") +public class JSFLoginFilter implements Filter { + + public JSFLoginFilter() { + super(); + } + + /** + * @see Filter#init(FilterConfig) + */ + private FilterConfig filterConfig = null; + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + this.filterConfig = filterConfig; + } + + /** + * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) + */ + @Override + public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { + if (filterConfig == null) { + return; + } + + HttpServletRequest request = (HttpServletRequest) req; + HttpServletResponse response = (HttpServletResponse) resp; + + HttpSession session = request.getSession(); + String userID = (String) session.getAttribute("uidBean"); + + // If user has not logged in and is trying access account information, + // redirect to login page. + if (userID == null) { + String url = request.getServletPath(); + + if (url.contains("home") || url.contains("account") || url.contains("portfolio") || url.contains("quote") || url.contains("order") + || url.contains("marketSummary")) { + System.out.println("JSF service error: User Not Logged in"); + response.sendRedirect("welcome.faces"); + return; + } + } + + chain.doFilter(req, resp/* wrapper */); + } + + /** + * @see Filter#destroy() + */ + @Override + public void destroy() { + this.filterConfig = null; + } + +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/LoginValidator.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/LoginValidator.java new file mode 100644 index 00000000..5c5c973c --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/LoginValidator.java @@ -0,0 +1,55 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.jsf; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.faces.application.FacesMessage; +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; +import javax.faces.validator.FacesValidator; +import javax.faces.validator.Validator; +import javax.faces.validator.ValidatorException; + +import com.ibm.websphere.samples.daytrader.util.Log; + +@SuppressWarnings("rawtypes") +@FacesValidator("loginValidator") +public class LoginValidator implements Validator{ + + static String loginRegex = "uid:\\d+"; + static Pattern pattern = Pattern.compile(loginRegex); + static Matcher matcher; + + // Simple JSF validator to make sure username starts with uid: and at least 1 number. + public LoginValidator() { + } + + @Override + public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { + Log.trace("LoginValidator.validate","Validating submitted login name -- " + value.toString()); + + matcher = pattern.matcher(value.toString()); + + if (!matcher.matches()) { + FacesMessage msg = new FacesMessage("Username validation failed. Please provide username in this format: uid:#"); + msg.setSeverity(FacesMessage.SEVERITY_ERROR); + + throw new ValidatorException(msg); + } + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/MarketSummaryJSF.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/MarketSummaryJSF.java new file mode 100644 index 00000000..3677753a --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/MarketSummaryJSF.java @@ -0,0 +1,166 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.jsf; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.Collection; +import java.util.Date; +import java.util.Iterator; + +import javax.annotation.PostConstruct; +import javax.enterprise.context.RequestScoped; +import javax.enterprise.inject.Any; +import javax.enterprise.inject.Instance; +import javax.inject.Inject; +import javax.inject.Named; + +import com.ibm.websphere.samples.daytrader.beans.MarketSummaryDataBean; +import com.ibm.websphere.samples.daytrader.entities.QuoteDataBean; +import com.ibm.websphere.samples.daytrader.interfaces.Trace; +import com.ibm.websphere.samples.daytrader.interfaces.TradeServices; +import com.ibm.websphere.samples.daytrader.util.FinancialUtils; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; +import com.ibm.websphere.samples.daytrader.util.TradeRunTimeModeLiteral; + +@Named("marketdata") +@RequestScoped +@Trace +public class MarketSummaryJSF { + + private TradeServices tradeAction; + + private BigDecimal TSIA; + private BigDecimal openTSIA; + private double volume; + private QuoteData[] topGainers; + private QuoteData[] topLosers; + private Date summaryDate; + + // cache the gainPercent once computed for this bean + private BigDecimal gainPercent = null; + + @Inject + public MarketSummaryJSF(@Any Instance services) { + tradeAction = services.select(new TradeRunTimeModeLiteral(TradeConfig.getRunTimeModeNames()[TradeConfig.getRunTimeMode()])).get(); + } + + @PostConstruct + public void getMarketSummary() { + + try { + MarketSummaryDataBean marketSummaryData = tradeAction.getMarketSummary(); + setSummaryDate(marketSummaryData.getSummaryDate()); + setTSIA(marketSummaryData.getTSIA()); + setVolume(marketSummaryData.getVolume()); + setGainPercent(marketSummaryData.getGainPercent()); + + Collection topGainers = marketSummaryData.getTopGainers(); + + Iterator gainers = topGainers.iterator(); + int count = 0; + QuoteData[] gainerjsfs = new QuoteData[5]; + + while (gainers.hasNext() && (count < 5)) { + QuoteDataBean quote = (QuoteDataBean) gainers.next(); + QuoteData r = new QuoteData(quote.getPrice(), quote.getOpen(), quote.getSymbol()); + gainerjsfs[count] = r; + count++; + } + + setTopGainers(gainerjsfs); + + Collection topLosers = marketSummaryData.getTopLosers(); + + QuoteData[] loserjsfs = new QuoteData[5]; + count = 0; + Iterator losers = topLosers.iterator(); + + while (losers.hasNext() && (count < 5)) { + QuoteDataBean quote = (QuoteDataBean) losers.next(); + QuoteData r = new QuoteData(quote.getPrice(), quote.getOpen(), quote.getSymbol()); + loserjsfs[count] = r; + count++; + } + + setTopLosers(loserjsfs); + + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void setTSIA(BigDecimal tSIA) { + TSIA = tSIA; + } + + public BigDecimal getTSIA() { + return TSIA; + } + + public void setOpenTSIA(BigDecimal openTSIA) { + this.openTSIA = openTSIA; + } + + public BigDecimal getOpenTSIA() { + return openTSIA; + } + + public void setVolume(double volume) { + this.volume = volume; + } + + public double getVolume() { + return volume; + } + + public void setTopGainers(QuoteData[] topGainers) { + this.topGainers = topGainers; + } + + public QuoteData[] getTopGainers() { + return topGainers; + } + + public void setTopLosers(QuoteData[] topLosers) { + this.topLosers = topLosers; + } + + public QuoteData[] getTopLosers() { + return topLosers; + } + + public void setSummaryDate(Date summaryDate) { + this.summaryDate = summaryDate; + } + + public Date getSummaryDate() { + return summaryDate; + } + + public void setGainPercent(BigDecimal gainPercent) { + this.gainPercent = gainPercent.setScale(2,RoundingMode.HALF_UP); + } + + public BigDecimal getGainPercent() { + return gainPercent; + } + + public String getGainPercentHTML() { + return FinancialUtils.printGainPercentHTML(gainPercent); + } + +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/OrderData.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/OrderData.java new file mode 100644 index 00000000..c05f810c --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/OrderData.java @@ -0,0 +1,140 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.jsf; + +import java.math.BigDecimal; +import java.util.Date; + +public class OrderData { + private Integer orderID; + private String orderStatus; + private Date openDate; + private Date completionDate; + private BigDecimal orderFee; + private String orderType; + private double quantity; + private String symbol; + private BigDecimal total; + private BigDecimal price; + + public OrderData(Integer orderID, String orderStatus, Date openDate, Date completeDate, BigDecimal orderFee, String orderType, double quantity, + String symbol) { + this.orderID = orderID; + this.completionDate = completeDate; + this.openDate = openDate; + this.orderFee = orderFee; + this.orderType = orderType; + this.orderStatus = orderStatus; + this.quantity = quantity; + this.symbol = symbol; + } + + public OrderData(Integer orderID, String orderStatus, Date openDate, Date completeDate, BigDecimal orderFee, String orderType, double quantity, + String symbol, BigDecimal price) { + this.orderID = orderID; + this.completionDate = completeDate; + this.openDate = openDate; + this.orderFee = orderFee; + this.orderType = orderType; + this.orderStatus = orderStatus; + this.quantity = quantity; + this.symbol = symbol; + this.price = price; + this.total = price.multiply(new BigDecimal(quantity)); + + } + + public void setOrderID(Integer orderID) { + this.orderID = orderID; + } + + public Integer getOrderID() { + return orderID; + } + + public void setOrderStatus(String orderStatus) { + this.orderStatus = orderStatus; + } + + public String getOrderStatus() { + return orderStatus; + } + + public void setOpenDate(Date openDate) { + this.openDate = openDate; + } + + public Date getOpenDate() { + return openDate; + } + + public void setCompletionDate(Date completionDate) { + this.completionDate = completionDate; + } + + public Date getCompletionDate() { + return completionDate; + } + + public void setOrderFee(BigDecimal orderFee) { + this.orderFee = orderFee; + } + + public BigDecimal getOrderFee() { + return orderFee; + } + + public void setOrderType(String orderType) { + this.orderType = orderType; + } + + public String getOrderType() { + return orderType; + } + + public void setQuantity(double quantity) { + this.quantity = quantity; + } + + public double getQuantity() { + return quantity; + } + + public void setSymbol(String symbol) { + this.symbol = symbol; + } + + public String getSymbol() { + return symbol; + } + + public void setTotal(BigDecimal total) { + this.total = total; + } + + public BigDecimal getTotal() { + return total; + } + + public void setPrice(BigDecimal price) { + this.price = price; + } + + public BigDecimal getPrice() { + return price; + } + +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/OrderDataJSF.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/OrderDataJSF.java new file mode 100644 index 00000000..8f9c70dd --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/OrderDataJSF.java @@ -0,0 +1,106 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.jsf; + +import java.math.BigDecimal; +import java.util.ArrayList; + +import javax.annotation.PostConstruct; +import javax.enterprise.inject.Any; +import javax.enterprise.inject.Instance; +import javax.faces.context.ExternalContext; +import javax.inject.Inject; +import javax.inject.Named; +import javax.servlet.http.HttpSession; + +import com.ibm.websphere.samples.daytrader.entities.OrderDataBean; +import com.ibm.websphere.samples.daytrader.interfaces.Trace; +import com.ibm.websphere.samples.daytrader.interfaces.TradeServices; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; +import com.ibm.websphere.samples.daytrader.util.TradeRunTimeModeLiteral; + +@Named("orderdata") +@Trace +public class OrderDataJSF { + + @Inject + private ExternalContext context; + + private TradeServices tradeAction; + + private OrderData[] allOrders; + private OrderData orderData; + + @Inject + public OrderDataJSF(@Any Instance services) { + tradeAction = services.select(new TradeRunTimeModeLiteral(TradeConfig.getRunTimeModeNames()[TradeConfig.getRunTimeMode()])).get(); + } + + public void getAllOrder() { + try { + HttpSession session = (HttpSession) context.getSession(true); + String userID = (String) session.getAttribute("uidBean"); + + ArrayList orderDataBeans = (TradeConfig.getLongRun() ? new ArrayList() : (ArrayList) tradeAction.getOrders(userID)); + OrderData[] orders = new OrderData[orderDataBeans.size()]; + + int count = 0; + + for (Object order : orderDataBeans) { + OrderData r = new OrderData(((OrderDataBean) order).getOrderID(), ((OrderDataBean) order).getOrderStatus(), + ((OrderDataBean) order).getOpenDate(), ((OrderDataBean) order).getCompletionDate(), ((OrderDataBean) order).getOrderFee(), + ((OrderDataBean) order).getOrderType(), ((OrderDataBean) order).getQuantity(), ((OrderDataBean) order).getSymbol()); + r.setPrice(((OrderDataBean) order).getPrice()); + r.setTotal(r.getPrice().multiply(new BigDecimal(r.getQuantity()))); + orders[count] = r; + count++; + } + + setAllOrders(orders); + } catch (Exception e) { + e.printStackTrace(); + } + + } + + @PostConstruct + public void getOrder() { + + + HttpSession session = (HttpSession) context.getSession(true); + OrderData order = (OrderData) session.getAttribute("orderData"); + + if (order != null) { + setOrderData(order); + } + } + + public void setAllOrders(OrderData[] allOrders) { + this.allOrders = allOrders; + } + + public OrderData[] getAllOrders() { + return allOrders; + } + + public void setOrderData(OrderData orderData) { + this.orderData = orderData; + } + + public OrderData getOrderData() { + return orderData; + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/PortfolioJSF.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/PortfolioJSF.java new file mode 100644 index 00000000..34a68d17 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/PortfolioJSF.java @@ -0,0 +1,235 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.jsf; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +import javax.annotation.PostConstruct; +import javax.enterprise.context.RequestScoped; +import javax.enterprise.inject.Any; +import javax.enterprise.inject.Instance; +import javax.faces.component.html.HtmlDataTable; +import javax.faces.context.ExternalContext; +import javax.inject.Inject; +import javax.inject.Named; +import javax.servlet.http.HttpSession; + +import javax.validation.constraints.PositiveOrZero; + +import com.ibm.websphere.samples.daytrader.entities.HoldingDataBean; +import com.ibm.websphere.samples.daytrader.entities.OrderDataBean; +import com.ibm.websphere.samples.daytrader.entities.QuoteDataBean; +import com.ibm.websphere.samples.daytrader.interfaces.Trace; +import com.ibm.websphere.samples.daytrader.interfaces.TradeServices; +import com.ibm.websphere.samples.daytrader.util.FinancialUtils; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; +import com.ibm.websphere.samples.daytrader.util.TradeRunTimeModeLiteral; + +@Named("portfolio") +@RequestScoped +@Trace +public class PortfolioJSF { + @Inject + private ExternalContext context; + + private TradeServices tradeAction; + + private BigDecimal balance; + private BigDecimal openBalance; + + @PositiveOrZero + private Integer numberHoldings; + + private BigDecimal holdingsTotal; + private BigDecimal sumOfCashHoldings; + private BigDecimal totalGain = new BigDecimal(0.0); + private BigDecimal totalValue = new BigDecimal(0.0); + private BigDecimal totalBasis = new BigDecimal(0.0); + private BigDecimal totalGainPercent = new BigDecimal(0.0); + private ArrayList holdingDatas; + private HtmlDataTable dataTable; + + @Inject + public PortfolioJSF(@Any Instance services) { + tradeAction = services.select(new TradeRunTimeModeLiteral(TradeConfig.getRunTimeModeNames()[TradeConfig.getRunTimeMode()])).get(); + } + + @PostConstruct + public void getPortfolio() { + try { + + HttpSession session = (HttpSession) context.getSession(true); + String userID = (String) session.getAttribute("uidBean"); + Collection holdingDataBeans = tradeAction.getHoldings(userID); + + numberHoldings = holdingDataBeans.size(); + + // Walk through the collection of user holdings and creating a list + // of quotes + if (holdingDataBeans.size() > 0) { + Iterator it = holdingDataBeans.iterator(); + holdingDatas = new ArrayList(holdingDataBeans.size()); + + while (it.hasNext()) { + HoldingDataBean holdingData = (HoldingDataBean) it.next(); + QuoteDataBean quoteData = tradeAction.getQuote(holdingData.getQuoteID()); + + BigDecimal basis = holdingData.getPurchasePrice().multiply(new BigDecimal(holdingData.getQuantity())); + BigDecimal marketValue = quoteData.getPrice().multiply(new BigDecimal(holdingData.getQuantity())); + totalBasis = totalBasis.add(basis); + totalValue = totalValue.add(marketValue); + BigDecimal gain = marketValue.subtract(basis); + totalGain = totalGain.add(gain); + + HoldingData h = new HoldingData(); + h.setHoldingID(holdingData.getHoldingID()); + h.setPurchaseDate(holdingData.getPurchaseDate()); + h.setQuoteID(holdingData.getQuoteID()); + h.setQuantity(holdingData.getQuantity()); + h.setPurchasePrice(holdingData.getPurchasePrice()); + h.setBasis(basis); + h.setGain(gain); + h.setMarketValue(marketValue); + h.setPrice(quoteData.getPrice()); + holdingDatas.add(h); + + } + // dataTable + setTotalGainPercent(FinancialUtils.computeGainPercent(totalValue, totalBasis)); + + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + public String sell() { + + HttpSession session = (HttpSession) context.getSession(true); + String userID = (String) session.getAttribute("uidBean"); + + OrderDataBean orderDataBean = null; + HoldingData holdingData = (HoldingData) dataTable.getRowData(); + + try { + orderDataBean = tradeAction.sell(userID, holdingData.getHoldingID(), TradeConfig.getOrderProcessingMode()); + holdingDatas.remove(holdingData); + } catch (Exception e) { + e.printStackTrace(); + } + + OrderData orderData = new OrderData(orderDataBean.getOrderID(), orderDataBean.getOrderStatus(), orderDataBean.getOpenDate(), + orderDataBean.getCompletionDate(), orderDataBean.getOrderFee(), orderDataBean.getOrderType(), orderDataBean.getQuantity(), + orderDataBean.getSymbol()); + session.setAttribute("orderData", orderData); + return "sell"; + } + + public void setDataTable(HtmlDataTable dataTable) { + this.dataTable = dataTable; + } + + public HtmlDataTable getDataTable() { + return dataTable; + } + + public void setBalance(BigDecimal balance) { + this.balance = balance; + } + + public BigDecimal getBalance() { + return balance; + } + + public void setOpenBalance(BigDecimal openBalance) { + this.openBalance = openBalance; + } + + public BigDecimal getOpenBalance() { + return openBalance; + } + + public void setHoldingsTotal(BigDecimal holdingsTotal) { + this.holdingsTotal = holdingsTotal; + } + + public BigDecimal getHoldingsTotal() { + return holdingsTotal; + } + + public void setSumOfCashHoldings(BigDecimal sumOfCashHoldings) { + this.sumOfCashHoldings = sumOfCashHoldings; + } + + public BigDecimal getSumOfCashHoldings() { + return sumOfCashHoldings; + } + + public void setNumberHoldings(Integer numberHoldings) { + this.numberHoldings = numberHoldings; + } + + public Integer getNumberHoldings() { + return numberHoldings; + } + + public void setTotalGain(BigDecimal totalGain) { + this.totalGain = totalGain; + } + + public BigDecimal getTotalGain() { + return totalGain; + } + + public void setTotalValue(BigDecimal totalValue) { + this.totalValue = totalValue; + } + + public BigDecimal getTotalValue() { + return totalValue; + } + + public void setTotalBasis(BigDecimal totalBasis) { + this.totalBasis = totalBasis; + } + + public BigDecimal getTotalBasis() { + return totalBasis; + } + + public void setHoldingDatas(ArrayList holdingDatas) { + this.holdingDatas = holdingDatas; + } + + public ArrayList getHoldingDatas() { + return holdingDatas; + } + + public void setTotalGainPercent(BigDecimal totalGainPercent) { + this.totalGainPercent = totalGainPercent; + } + + public BigDecimal getTotalGainPercent() { + return totalGainPercent; + } + + public String getTotalGainPercentHTML() { + return FinancialUtils.printGainPercentHTML(totalGainPercent); + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/QuoteData.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/QuoteData.java new file mode 100644 index 00000000..ad3425b7 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/QuoteData.java @@ -0,0 +1,167 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.jsf; + +import java.math.BigDecimal; +import java.text.DecimalFormat; + +import com.ibm.websphere.samples.daytrader.util.FinancialUtils; + +public class QuoteData { + private BigDecimal price; + private BigDecimal open; + private String symbol; + private BigDecimal high; + private BigDecimal low; + private String companyName; + private double volume; + private double change; + private String range; + private BigDecimal gainPercent; + private BigDecimal gain; + + public QuoteData(BigDecimal price, BigDecimal open, String symbol) { + this.open = open; + this.price = price; + this.symbol = symbol; + this.change = price.subtract(open).setScale(2).doubleValue(); + } + + public QuoteData(BigDecimal open, BigDecimal price, String symbol, BigDecimal high, BigDecimal low, String companyName, Double volume, Double change) { + this.open = open; + this.price = price; + this.symbol = symbol; + this.high = high; + this.low = low; + this.companyName = companyName; + this.volume = volume; + this.change = change; + this.range = high.toString() + "-" + low.toString(); + this.gainPercent = FinancialUtils.computeGainPercent(price, open).setScale(2); + this.gain = FinancialUtils.computeGain(price, open).setScale(2); + } + + public void setSymbol(String symbol) { + this.symbol = symbol; + } + + public String getSymbol() { + return symbol; + } + + public void setPrice(BigDecimal price) { + this.price = price; + } + + public BigDecimal getPrice() { + return price; + } + + public void setOpen(BigDecimal open) { + this.open = open; + } + + public BigDecimal getOpen() { + return open; + } + + public void setHigh(BigDecimal high) { + this.high = high; + } + + public BigDecimal getHigh() { + return high; + } + + public void setLow(BigDecimal low) { + this.low = low; + } + + public BigDecimal getLow() { + return low; + } + + public void setCompanyName(String companyName) { + this.companyName = companyName; + } + + public String getCompanyName() { + return companyName; + } + + public void setVolume(double volume) { + this.volume = volume; + } + + public double getVolume() { + return volume; + } + + public void setChange(double change) { + this.change = change; + } + + public double getChange() { + return change; + } + + public void setRange(String range) { + this.range = range; + } + + public String getRange() { + return range; + } + + public void setGainPercent(BigDecimal gainPercent) { + this.gainPercent = gainPercent.setScale(2); + } + + public BigDecimal getGainPercent() { + return gainPercent; + } + + public void setGain(BigDecimal gain) { + this.gain = gain; + } + + public BigDecimal getGain() { + return gain; + } + + public String getGainPercentHTML() { + return FinancialUtils.printGainPercentHTML(gainPercent); + } + + public String getGainHTML() { + return FinancialUtils.printGainHTML(gain); + } + + public String getChangeHTML() { + String htmlString, arrow; + if (change < 0.0) { + htmlString = ""; + arrow = "arrowdown.gif"; + } else { + htmlString = ""; + arrow = "arrowup.gif"; + } + DecimalFormat df = new DecimalFormat("####0.00"); + + htmlString += df.format(change) + ""; + return htmlString; + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/QuoteJSF.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/QuoteJSF.java new file mode 100644 index 00000000..f8c5d7c2 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/QuoteJSF.java @@ -0,0 +1,146 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.jsf; + +import javax.annotation.PostConstruct; +import javax.enterprise.context.RequestScoped; +import javax.enterprise.inject.Any; +import javax.enterprise.inject.Instance; +import javax.faces.component.html.HtmlDataTable; +import javax.faces.context.ExternalContext; +import javax.inject.Inject; +import javax.inject.Named; +import javax.servlet.http.HttpSession; + +import com.ibm.websphere.samples.daytrader.entities.OrderDataBean; +import com.ibm.websphere.samples.daytrader.entities.QuoteDataBean; +import com.ibm.websphere.samples.daytrader.interfaces.Trace; +import com.ibm.websphere.samples.daytrader.interfaces.TradeServices; +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; +import com.ibm.websphere.samples.daytrader.util.TradeRunTimeModeLiteral; + +@Named("quotedata") +@RequestScoped +@Trace +public class QuoteJSF { + + @Inject + private ExternalContext context; + + private TradeServices tradeAction; + + private QuoteData[] quotes; + private String symbols = null; + private HtmlDataTable dataTable; + private Integer quantity = 100; + + @Inject + public QuoteJSF(@Any Instance services) { + tradeAction = services.select(new TradeRunTimeModeLiteral(TradeConfig.getRunTimeModeNames()[TradeConfig.getRunTimeMode()])).get(); + } + + @PostConstruct + public void getAllQuotes() { + getQuotesBySymbols(); + } + + public String getQuotesBySymbols() { + HttpSession session = (HttpSession) context.getSession(true); + + if (symbols == null && (session.getAttribute("symbols") == null)) { + setSymbols("s:0,s:1,s:2,s:3,s:4"); + session.setAttribute("symbols", getSymbols()); + } else if (symbols == null && session.getAttribute("symbols") != null) { + setSymbols((String) session.getAttribute("symbols")); + } + + else { + session.setAttribute("symbols", getSymbols()); + } + + java.util.StringTokenizer st = new java.util.StringTokenizer(symbols, " ,"); + QuoteData[] quoteDatas = new QuoteData[st.countTokens()]; + int count = 0; + + while (st.hasMoreElements()) { + String symbol = st.nextToken(); + + try { + QuoteDataBean quoteData = tradeAction.getQuote(symbol); + quoteDatas[count] = new QuoteData(quoteData.getOpen(), quoteData.getPrice(), quoteData.getSymbol(), quoteData.getHigh(), quoteData.getLow(), + quoteData.getCompanyName(), quoteData.getVolume(), quoteData.getChange()); + count++; + } catch (Exception e) { + Log.error(e.toString()); + } + } + setQuotes(quoteDatas); + return "quotes"; + } + + public String buy() { + HttpSession session = (HttpSession) context.getSession(true); + String userID = (String) session.getAttribute("uidBean"); + QuoteData quoteData = (QuoteData) dataTable.getRowData(); + OrderDataBean orderDataBean; + + try { + orderDataBean = tradeAction.buy(userID, quoteData.getSymbol(), new Double(this.quantity).doubleValue(), TradeConfig.getOrderProcessingMode()); + + OrderData orderData = new OrderData(orderDataBean.getOrderID(), orderDataBean.getOrderStatus(), orderDataBean.getOpenDate(), + orderDataBean.getCompletionDate(), orderDataBean.getOrderFee(), orderDataBean.getOrderType(), orderDataBean.getQuantity(), + orderDataBean.getSymbol()); + session.setAttribute("orderData", orderData); + } catch (Exception e) { + Log.error(e.toString()); + e.printStackTrace(); + } + return "buy"; + } + + public void setQuotes(QuoteData[] quotes) { + this.quotes = quotes; + } + + public QuoteData[] getQuotes() { + return quotes; + } + + public void setSymbols(String symbols) { + this.symbols = symbols; + } + + public String getSymbols() { + return symbols; + } + + public void setDataTable(HtmlDataTable dataTable) { + this.dataTable = dataTable; + } + + public HtmlDataTable getDataTable() { + return dataTable; + } + + public void setQuantity(Integer quantity) { + this.quantity = quantity; + } + + public Integer getQuantity() { + return quantity; + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/TradeAppJSF.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/TradeAppJSF.java new file mode 100644 index 00000000..b8271641 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/TradeAppJSF.java @@ -0,0 +1,298 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.jsf; + +import java.io.Serializable; +import java.math.BigDecimal; + +import javax.enterprise.context.SessionScoped; +import javax.enterprise.inject.Any; +import javax.enterprise.inject.Instance; +import javax.faces.context.ExternalContext; +import javax.inject.Inject; +import javax.inject.Named; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; +import javax.validation.constraints.Email; +import javax.validation.constraints.NotBlank; + +import com.ibm.websphere.samples.daytrader.entities.AccountDataBean; +import com.ibm.websphere.samples.daytrader.entities.AccountProfileDataBean; +import com.ibm.websphere.samples.daytrader.interfaces.Trace; +import com.ibm.websphere.samples.daytrader.interfaces.TradeServices; +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; +import com.ibm.websphere.samples.daytrader.util.TradeRunTimeModeLiteral; + +@Named("tradeapp") +@SessionScoped +@Trace +public class TradeAppJSF implements Serializable { + + @Inject ExternalContext context; + + private TradeServices tradeAction; + + private static final long serialVersionUID = 2L; + + @NotBlank + private String userID = "uid:0"; + + @NotBlank + private String password = "xxx"; + + @NotBlank + private String cpassword; + + @NotBlank + private String results; + + @NotBlank + private String fullname; + + @NotBlank + private String address; + + @Email + private String email; + + @NotBlank + private String ccn; + + @NotBlank + private String money; + + @Inject + public TradeAppJSF(@Any Instance services) { + tradeAction = services.select(new TradeRunTimeModeLiteral(TradeConfig.getRunTimeModeNames()[TradeConfig.getRunTimeMode()])).get(); + } + + public String login() { + try { + AccountDataBean accountData = tradeAction.login(userID, password); + + AccountProfileDataBean accountProfileData = tradeAction.getAccountProfileData(userID); + if (accountData != null) { + HttpSession session = (HttpSession) context.getSession(true); + + session.setAttribute("uidBean", userID); + session.setAttribute("sessionCreationDate", new java.util.Date()); + setResults("Ready to Trade"); + + // Get account profile information + setAddress(accountProfileData.getAddress()); + setCcn(accountProfileData.getCreditCard()); + setEmail(accountProfileData.getEmail()); + setFullname(accountProfileData.getFullName()); + setCpassword(accountProfileData.getPassword()); + return "Ready to Trade"; + } else { + Log.log("TradeServletAction.doLogin(...)", "Error finding account for user " + userID + "", + "user entered a bad username or the database is not populated"); + throw new NullPointerException("User does not exist or password is incorrect!"); + } + } + + catch (Exception se) { + // Go to welcome page + setResults("Could not find account"); + return "welcome"; + } + } + + public String register() { + + // Validate user passwords match and are atleast 1 char in length + try { + if ((password.equals(cpassword)) && (password.length() >= 1)) { + AccountDataBean accountData = tradeAction.register(userID, password, fullname, address, email, ccn, new BigDecimal(money)); + + if (accountData == null) { + setResults("Registration operation failed;"); + // Go to register page + return "Registration operation failed"; + + } else { + login(); + setResults("Registration operation succeeded; Account " + accountData.getAccountID() + " has been created."); + return "Registration operation succeeded"; + } + } + + else { + // Password validation failed + setResults("Registration operation failed, your passwords did not match"); + // Go to register page + return "Registration operation failed"; + } + } + + catch (Exception e) { + // log the exception with error page + Log.log("TradeServletAction.doRegister(...)" + " exception user =" + userID); + try { + throw new Exception("TradeServletAction.doRegister(...)" + " exception user =" + userID, e); + } catch (Exception e1) { + e1.printStackTrace(); + } + + } + return "Registration operation succeeded"; + } + + public String updateProfile() { + + // First verify input data + boolean doUpdate = true; + + if (password.equals(cpassword) == false) { + results = "Update profile error: passwords do not match"; + doUpdate = false; + } + + AccountProfileDataBean accountProfileData = new AccountProfileDataBean(userID, password, fullname, address, email, ccn); + + try { + if (doUpdate) { + accountProfileData = tradeAction.updateAccountProfile(accountProfileData); + results = "Account profile update successful"; + } + + } catch (java.lang.IllegalArgumentException e) { + // this is a user error so I will + // forward them to another page rather than throw a 500 + setResults("invalid argument, check userID is correct, and the database is populated" + userID); + Log.error(e, "TradeServletAction.doAccount(...)", "illegal argument, information should be in exception string", + "treating this as a user error and forwarding on to a new page"); + } catch (Exception e) { + // log the exception with error page + e.printStackTrace(); + } + // Go to account.xhtml + return "Go to account"; + } + + public String logout() { + + try { + setResults(""); + tradeAction.logout(userID); + } catch (java.lang.IllegalArgumentException e) { + // this is a user error so I will + // forward them to another page, at the end of the page. + setResults("illegal argument:" + e.getMessage()); + + // log the exception with an error level of 3 which means, handled + // exception but would invalidate a automation run + Log.error(e, "TradeServletAction.doLogout(...)", "illegal argument, information should be in exception string", + "treating this as a user error and forwarding on to a new page"); + } catch (Exception e) { + // log the exception and foward to a error page + Log.error(e, "TradeAppJSF.logout():", "Error logging out" + userID, "fowarding to an error page"); + } + + HttpSession session = (HttpSession)context.getSession(false); + + if (session != null) { + session.invalidate(); + } + + // Added to actually remove a user from the authentication cache + try { + ((HttpServletRequest) context.getRequest()).logout(); + } catch (ServletException e) { + Log.error(e, "TradeAppJSF.logout():", "Error logging out request" + userID, "fowarding to an error page"); + } + + // Go to welcome page + return "welcome"; + } + + public String getUserID() { + return userID; + } + + public void setUserID(String userID) { + this.userID = userID; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getCpassword() { + return cpassword; + } + + public void setCpassword(String cpassword) { + this.cpassword = cpassword; + } + + public String getFullname() { + return fullname; + } + + public void setFullname(String fullname) { + this.fullname = fullname; + } + + public String getResults() { + String tempResults=results; + results=""; + return tempResults; + } + + public void setResults(String results) { + this.results = results; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getCcn() { + return ccn; + } + + public void setCcn(String ccn) { + this.ccn = ccn; + } + + public String getMoney() { + return money; + } + + public void setMoney(String money) { + this.money = money; + } +}; diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/TradeConfigJSF.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/TradeConfigJSF.java new file mode 100644 index 00000000..fd7cb859 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/jsf/TradeConfigJSF.java @@ -0,0 +1,331 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.jsf; + +import javax.enterprise.context.RequestScoped; +import javax.faces.context.ExternalContext; +import javax.inject.Inject; +import javax.inject.Named; +import javax.servlet.http.HttpSession; + +import com.ibm.websphere.samples.daytrader.beans.RunStatsDataBean; +import com.ibm.websphere.samples.daytrader.impl.direct.TradeDirectDBUtils; +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; + +@Named("tradeconfig") +@RequestScoped +public class TradeConfigJSF { + + @Inject + private ExternalContext context; + + @Inject + TradeDirectDBUtils dbUtils; + + private String runtimeMode = TradeConfig.getRunTimeModeNames()[TradeConfig.getRunTimeMode()]; + private String orderProcessingMode = TradeConfig.getOrderProcessingModeNames()[TradeConfig.getOrderProcessingMode()]; + private int maxUsers = TradeConfig.getMAX_USERS(); + private int maxQuotes = TradeConfig.getMAX_QUOTES(); + private int marketSummaryInterval = TradeConfig.getMarketSummaryInterval(); + private String webInterface = TradeConfig.getWebInterfaceNames()[TradeConfig.getWebInterface()]; + private int primIterations = TradeConfig.getPrimIterations(); + private int listQuotePriceChangeFrequency = TradeConfig.getListQuotePriceChangeFrequency(); + private boolean publishQuotePriceChange = TradeConfig.getPublishQuotePriceChange(); + private boolean longRun = TradeConfig.getLongRun(); + private boolean displayOrderAlerts = TradeConfig.getDisplayOrderAlerts(); + private String[] runtimeModeList = TradeConfig.getRunTimeModeNames(); + private String[] orderProcessingModeList = TradeConfig.getOrderProcessingModeNames(); + + private String[] webInterfaceList = TradeConfig.getWebInterfaceNames(); + private String result = ""; + + public void updateConfig() { + String currentConfigStr = "\n\n########## Trade configuration update. Current config:\n\n"; + + currentConfigStr += "\t\tRunTimeMode:\t\t\t" + TradeConfig.getRunTimeModeNames()[TradeConfig.getRunTimeMode()] + "\n"; + + String orderProcessingModeStr = this.orderProcessingMode; + if (orderProcessingModeStr != null) { + try { + for (int i = 0; i < orderProcessingModeList.length; i++) { + if (orderProcessingModeStr.equals(orderProcessingModeList[i])) { + TradeConfig.setOrderProcessingMode(i); + } + } + } catch (Exception e) { + Log.error(e, "TradeConfigJSF.updateConfig(..): minor exception caught", "trying to set orderProcessing to " + orderProcessingModeStr, + "reverting to current value"); + + } // If the value is bad, simply revert to current + } + currentConfigStr += "\t\tOrderProcessingMode:\t\t" + TradeConfig.getOrderProcessingModeNames()[TradeConfig.getOrderProcessingMode()] + "\n"; + + String webInterfaceStr = webInterface; + if (webInterfaceStr != null) { + try { + for (int i = 0; i < webInterfaceList.length; i++) { + if (webInterfaceStr.equals(webInterfaceList[i])) { + TradeConfig.setWebInterface(i); + } + } + } catch (Exception e) { + Log.error(e, "TradeConfigJSF.updateConfig(..): minor exception caught", "trying to set WebInterface to " + webInterfaceStr, + "reverting to current value"); + + } // If the value is bad, simply revert to current + } + currentConfigStr += "\t\tWeb Interface:\t\t\t" + TradeConfig.getWebInterfaceNames()[TradeConfig.getWebInterface()] + "\n"; + + TradeConfig.setMAX_USERS(maxUsers); + TradeConfig.setMAX_QUOTES(maxQuotes); + + currentConfigStr += "\t\tTrade Users:\t\t\t" + TradeConfig.getMAX_USERS() + "\n"; + currentConfigStr += "\t\tTrade Quotes:\t\t\t" + TradeConfig.getMAX_QUOTES() + "\n"; + + TradeConfig.setMarketSummaryInterval(marketSummaryInterval); + + currentConfigStr += "\t\tMarket Summary Interval:\t" + TradeConfig.getMarketSummaryInterval() + "\n"; + + TradeConfig.setPrimIterations(primIterations); + + currentConfigStr += "\t\tPrimitive Iterations:\t\t" + TradeConfig.getPrimIterations() + "\n"; + + TradeConfig.setPublishQuotePriceChange(publishQuotePriceChange); + currentConfigStr += "\t\tTradeStreamer MDB Enabled:\t" + TradeConfig.getPublishQuotePriceChange() + "\n"; + + TradeConfig.setListQuotePriceChangeFrequency(listQuotePriceChangeFrequency); + currentConfigStr += "\t\t% of trades on Websocket:\t" + TradeConfig.getListQuotePriceChangeFrequency() + "\n"; + + TradeConfig.setLongRun(longRun); + currentConfigStr += "\t\tLong Run Enabled:\t\t" + TradeConfig.getLongRun() + "\n"; + + TradeConfig.setDisplayOrderAlerts(displayOrderAlerts); + currentConfigStr += "\t\tDisplay Order Alerts:\t\t" + TradeConfig.getDisplayOrderAlerts() + "\n"; + + System.out.println(currentConfigStr); + setResult("DayTrader Configuration Updated"); + } + + public String resetTrade() { + RunStatsDataBean runStatsData = new RunStatsDataBean(); + TradeConfig currentConfig = new TradeConfig(); + HttpSession session = (HttpSession) context.getSession(true); + + + try { + runStatsData = dbUtils.resetTrade(false); + session.setAttribute("runStatsData", runStatsData); + session.setAttribute("tradeConfig", currentConfig); + result += "Trade Reset completed successfully"; + + } catch (Exception e) { + result += "Trade Reset Error - see log for details"; + session.setAttribute("result", result); + Log.error(e, result); + } + + return "stats"; + } + + public String populateDatabase() { + + try { + dbUtils.buildDB(new java.io.PrintWriter(System.out), null); + } catch (Exception e) { + e.printStackTrace(); + } + + result = "TradeBuildDB: **** DayTrader Database Built - " + TradeConfig.getMAX_USERS() + " users created, " + TradeConfig.getMAX_QUOTES() + + " quotes created. ****
    "; + result += "TradeBuildDB: **** Check System.Out for any errors. ****
    "; + + return "database"; + } + + public String buildDatabaseTables() { + try { + String dbProductName = null; + try { + dbProductName = dbUtils.checkDBProductName(); + } catch (Exception e) { + Log.error(e, "TradeBuildDB: Unable to check DB Product name"); + } + if (dbProductName == null) { + result += "TradeBuildDB: **** Unable to check DB Product name, please check Database/AppServer configuration and retry ****
    "; + return "database"; + } + + String ddlFile = null; + //Locate DDL file for the specified database + try { + result = result + "TradeBuildDB: **** Database Product detected: " + dbProductName + " ****
    "; + if (dbProductName.startsWith("DB2/")) { // if db is DB2 + ddlFile = "/dbscripts/db2/Table.ddl"; + } else if (dbProductName.startsWith("Apache Derby")) { //if db is Derby + ddlFile = "/dbscripts/derby/Table.ddl"; + } else if (dbProductName.startsWith("Oracle")) { // if the Db is Oracle + ddlFile = "/dbscripts/oracle/Table.ddl"; + } else { // Unsupported "Other" Database + ddlFile = "/dbscripts/other/Table.ddl"; + result = result + "TradeBuildDB: **** This Database is unsupported/untested use at your own risk ****
    "; + } + + result = result + "TradeBuildDB: **** The DDL file at path" + ddlFile + " will be used ****
    "; + } catch (Exception e) { + Log.error(e, "TradeBuildDB: Unable to locate DDL file for the specified database"); + result = result + "TradeBuildDB: **** Unable to locate DDL file for the specified database ****
    "; + return "database"; + } + + dbUtils.buildDB(new java.io.PrintWriter(System.out), context.getResourceAsStream(ddlFile)); + + result = result + "TradeBuildDB: **** DayTrader Database Created, Check System.Out for any errors. ****
    "; + + } catch (Exception e) { + e.printStackTrace(); + } + + // Go to configure.xhtml + return "database"; + } + + + + + public String getRuntimeMode() { + return runtimeMode; + } + + public void setRuntimeMode(String runtimeMode) { + this.runtimeMode = runtimeMode; + } + + public void setOrderProcessingMode(String orderProcessingMode) { + this.orderProcessingMode = orderProcessingMode; + } + + public String getOrderProcessingMode() { + return orderProcessingMode; + } + + + public void setMaxUsers(int maxUsers) { + this.maxUsers = maxUsers; + } + + public int getMaxUsers() { + return maxUsers; + } + + public void setmaxQuotes(int maxQuotes) { + this.maxQuotes = maxQuotes; + } + + public int getMaxQuotes() { + return maxQuotes; + } + + public void setMarketSummaryInterval(int marketSummaryInterval) { + this.marketSummaryInterval = marketSummaryInterval; + } + + public int getMarketSummaryInterval() { + return marketSummaryInterval; + } + + public void setPrimIterations(int primIterations) { + this.primIterations = primIterations; + } + + public int getPrimIterations() { + return primIterations; + } + + public void setPublishQuotePriceChange(boolean publishQuotePriceChange) { + this.publishQuotePriceChange = publishQuotePriceChange; + } + + public boolean isPublishQuotePriceChange() { + return publishQuotePriceChange; + } + + public void setListQuotePriceChangeFrequency(int listQuotePriceChangeFrequency) { + this.listQuotePriceChangeFrequency = listQuotePriceChangeFrequency; + } + + public int getListQuotePriceChangeFrequency() { + return listQuotePriceChangeFrequency; + } + + public void setDisplayOrderAlerts(boolean displayOrderAlerts) { + this.displayOrderAlerts = displayOrderAlerts; + } + + public boolean isDisplayOrderAlerts() { + return displayOrderAlerts; + } + + + public void setLongRun(boolean longRun) { + this.longRun = longRun; + } + + public boolean isLongRun() { + return longRun; + } + + public String[] getRuntimeModeList() { + return runtimeModeList; + } + + public void setRuntimeModeList(String[] runtimeModeList) { + this.runtimeModeList = runtimeModeList; + } + + public void setOrderProcessingModeList(String[] orderProcessingModeList) { + this.orderProcessingModeList = orderProcessingModeList; + } + + public String[] getOrderProcessingModeList() { + return orderProcessingModeList; + } + + public void setWebInterface(String webInterface) { + this.webInterface = webInterface; + } + + public String getWebInterface() { + return webInterface; + } + + public void setWebInterfaceList(String[] webInterfaceList) { + this.webInterfaceList = webInterfaceList; + } + + public String[] getWebInterfaceList() { + return webInterfaceList; + } + + public void setResult(String result) { + this.result = result; + } + + public String getResult() { + return result; + } + +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ExplicitGC.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ExplicitGC.java new file mode 100644 index 00000000..073a4709 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ExplicitGC.java @@ -0,0 +1,158 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims; + +import java.io.IOException; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ibm.websphere.samples.daytrader.util.Log; + +/** + * + * ExplicitGC invokes System.gc(). This allows one to gather min / max heap + * statistics. + * + */ +@WebServlet(name = "ExplicitGC", urlPatterns = { "/servlet/ExplicitGC" }) +public class ExplicitGC extends HttpServlet { + + private static final long serialVersionUID = -3758934393801102408L; + private static String initTime; + private static int hitCount; + + /** + * forwards post requests to the doGet method Creation date: (01/29/2006 + * 20:10:00 PM) + * + * @param res + * javax.servlet.http.HttpServletRequest + * @param res2 + * javax.servlet.http.HttpServletResponse + */ + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + /** + * this is the main method of the servlet that will service all get + * requests. + * + * @param request + * HttpServletRequest + * @param responce + * HttpServletResponce + **/ + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + try { + res.setContentType("text/html"); + + ServletOutputStream out = res.getOutputStream(); + hitCount++; + long totalMemory = Runtime.getRuntime().totalMemory(); + + long maxMemoryBeforeGC = Runtime.getRuntime().maxMemory(); + long freeMemoryBeforeGC = Runtime.getRuntime().freeMemory(); + long startTime = System.currentTimeMillis(); + + System.gc(); // Invoke the GC. + + long endTime = System.currentTimeMillis(); + long maxMemoryAfterGC = Runtime.getRuntime().maxMemory(); + long freeMemoryAfterGC = Runtime.getRuntime().freeMemory(); + + out.println("ExplicitGC" + + "

    Explicit Garbage Collection
    Init time : " + + initTime + + "

    Hit Count: " + + hitCount + + "
    " + + "" + + "" + + "
    Total Memory" + + totalMemory + + "
    " + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "
    " + + "Statistics before GC
    " + + "Max Memory" + + maxMemoryBeforeGC + + "
    " + + "Free Memory" + + freeMemoryBeforeGC + + "
    " + + "Used Memory" + + (totalMemory - freeMemoryBeforeGC) + + "
    Statistics after GC
    " + + "Max Memory" + + maxMemoryAfterGC + + "
    " + + "Free Memory" + + freeMemoryAfterGC + + "
    " + + "Used Memory" + + (totalMemory - freeMemoryAfterGC) + + "
    " + + "Total Time in GC" + + Float.toString((endTime - startTime) / 1000) + + "s
    " + ""); + } catch (Exception e) { + Log.error(e, "ExplicitGC.doGet(...): general exception caught"); + res.sendError(500, e.toString()); + + } + } + + /** + * returns a string of information about the servlet + * + * @return info String: contains info about the servlet + **/ + @Override + public String getServletInfo() { + return "Generate Explicit GC to VM"; + } + + /** + * called when the class is loaded to initialize the servlet + * + * @param config + * ServletConfig: + **/ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + initTime = new java.util.Date().toString(); + hitCount = 0; + + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingBean.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingBean.java new file mode 100644 index 00000000..1e8a05c7 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingBean.java @@ -0,0 +1,41 @@ +/** + * (C) Copyright IBM Corporation 2016. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims; + +/** + * Simple bean to get and set messages + */ + +public class PingBean { + + private String msg; + + /** + * returns the message contained in the bean + * + * @return message String + **/ + public String getMsg() { + return msg; + } + + /** + * sets the message contained in the bean param message String + **/ + public void setMsg(String s) { + msg = s; + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingJDBCRead.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingJDBCRead.java new file mode 100644 index 00000000..46e7b49a --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingJDBCRead.java @@ -0,0 +1,135 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims; + +import java.io.IOException; + +import javax.inject.Inject; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ibm.websphere.samples.daytrader.entities.QuoteDataBean; +import com.ibm.websphere.samples.daytrader.interfaces.TradeJDBC; +import com.ibm.websphere.samples.daytrader.interfaces.TradeServices; +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; + +/** + * + * PingJDBCReadPrepStmt uses a prepared statement for database read access. This + * primative uses + * {@link com.ibm.websphere.samples.daytrader.impl.direct.TradeDirect} to set the + * price of a random stock (generated by + * {@link com.ibm.websphere.samples.daytrader.util.TradeConfig}) through the use + * of prepared statements. + * + */ + +@WebServlet(name = "PingJDBCRead", urlPatterns = { "/servlet/PingJDBCRead" }) +public class PingJDBCRead extends HttpServlet { + + @Inject + @TradeJDBC + TradeServices trade; + + private static final long serialVersionUID = -8810390150632488526L; + private static String initTime; + private static int hitCount; + + /** + * forwards post requests to the doGet method Creation date: (11/6/2000 + * 10:52:39 AM) + * + * @param res + * javax.servlet.http.HttpServletRequest + * @param res2 + * javax.servlet.http.HttpServletResponse + */ + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + /** + * this is the main method of the servlet that will service all get + * requests. + * + * @param request + * HttpServletRequest + * @param responce + * HttpServletResponce + **/ + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + res.setContentType("text/html"); + java.io.PrintWriter out = res.getWriter(); + String symbol = null; + StringBuffer output = new StringBuffer(100); + + try { + // TradeJDBC uses prepared statements so I am going to make use of + // it's code. + + symbol = TradeConfig.rndSymbol(); + + QuoteDataBean quoteData = null; + int iter = TradeConfig.getPrimIterations(); + for (int ii = 0; ii < iter; ii++) { + quoteData = trade.getQuote(symbol); + } + + output.append("Ping JDBC Read w/ Prepared Stmt." + + "
    Ping JDBC Read w/ Prep Stmt:
    Init time : " + + initTime); + hitCount++; + output.append("
    Hit Count: " + hitCount); + output.append("
    Quote Information

    : " + quoteData.toHTML()); + output.append("
    "); + out.println(output.toString()); + } catch (Exception e) { + Log.error(e, "PingJDBCRead w/ Prep Stmt -- error getting quote for symbol", symbol); + res.sendError(500, "PingJDBCRead Exception caught: " + e.toString()); + } + + } + + /** + * returns a string of information about the servlet + * + * @return info String: contains info about the servlet + **/ + @Override + public String getServletInfo() { + return "Basic JDBC Read using a prepared statment, makes use of TradeJDBC class"; + } + + /** + * called when the class is loaded to initialize the servlet + * + * @param config + * ServletConfig: + **/ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + hitCount = 0; + initTime = new java.util.Date().toString(); + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingJDBCRead2JSP.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingJDBCRead2JSP.java new file mode 100644 index 00000000..2e89277f --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingJDBCRead2JSP.java @@ -0,0 +1,128 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims; + +import java.io.IOException; + +import javax.inject.Inject; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ibm.websphere.samples.daytrader.entities.QuoteDataBean; +import com.ibm.websphere.samples.daytrader.impl.direct.TradeDirect; +import com.ibm.websphere.samples.daytrader.interfaces.TradeJDBC; +import com.ibm.websphere.samples.daytrader.interfaces.TradeServices; +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; + +/** + * + * PingJDBCReadPrepStmt uses a prepared statement for database read access. This + * primative uses + * {@link com.ibm.websphere.samples.daytrader.impl.direct.TradeDirect} to set the + * price of a random stock (generated by + * {@link com.ibm.websphere.samples.daytrader.util.TradeConfig}) through the use + * of prepared statements. + * + */ + +@WebServlet(name = "PingJDBCRead2JSP", urlPatterns = { "/servlet/PingJDBCRead2JSP" }) +public class PingJDBCRead2JSP extends HttpServlet { + + @Inject + @TradeJDBC + TradeServices trade; + + private static final long serialVersionUID = 1118803761565654806L; + + /** + * forwards post requests to the doGet method Creation date: (11/6/2000 + * 10:52:39 AM) + * + * @param res + * javax.servlet.http.HttpServletRequest + * @param res2 + * javax.servlet.http.HttpServletResponse + */ + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + /** + * this is the main method of the servlet that will service all get + * requests. + * + * @param request + * HttpServletRequest + * @param responce + * HttpServletResponce + **/ + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + String symbol = null; + QuoteDataBean quoteData = null; + ServletContext ctx = getServletConfig().getServletContext(); + + try { + + symbol = TradeConfig.rndSymbol(); + + int iter = TradeConfig.getPrimIterations(); + for (int ii = 0; ii < iter; ii++) { + quoteData = trade.getQuote(symbol); + } + + req.setAttribute("quoteData", quoteData); + // req.setAttribute("hitCount", hitCount); + // req.setAttribute("initTime", initTime); + + ctx.getRequestDispatcher("/quoteDataPrimitive.jsp").include(req, res); + } catch (Exception e) { + Log.error(e, "PingJDBCRead2JPS -- error getting quote for symbol", symbol); + res.sendError(500, "PingJDBCRead2JSP Exception caught: " + e.toString()); + } + + } + + /** + * returns a string of information about the servlet + * + * @return info String: contains info about the servlet + **/ + @Override + public String getServletInfo() { + return "Basic JDBC Read using a prepared statment forwarded to a JSP, makes use of TradeJDBC class"; + } + + /** + * called when the class is loaded to initialize the servlet + * + * @param config + * ServletConfig: + **/ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + // hitCount = 0; + // initTime = new java.util.Date().toString(); + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingJDBCWrite.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingJDBCWrite.java new file mode 100644 index 00000000..de451091 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingJDBCWrite.java @@ -0,0 +1,140 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims; + +import java.io.IOException; +import java.math.BigDecimal; + +import javax.inject.Inject; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ibm.websphere.samples.daytrader.entities.QuoteDataBean; +import com.ibm.websphere.samples.daytrader.impl.direct.TradeDirect; +import com.ibm.websphere.samples.daytrader.interfaces.TradeJDBC; +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; + +/** + * + * PingJDBCReadPrepStmt uses a prepared statement for database update. Statement + * parameters are set dynamically on each request. This primative uses + * {@link com.ibm.websphere.samples.daytrader.impl.direct.TradeDirect} to set the + * price of a random stock (generated by + * {@link com.ibm.websphere.samples.daytrader.util.TradeConfig}) through the use + * of prepared statements. + * + */ +@WebServlet(name = "PingJDBCWrite", urlPatterns = { "/servlet/PingJDBCWrite" }) +public class PingJDBCWrite extends HttpServlet { + + @Inject + @TradeJDBC + TradeDirect trade; + + private static final long serialVersionUID = -4938035109655376503L; + private static String initTime; + private static int hitCount; + + /** + * this is the main method of the servlet that will service all get + * requests. + * + * @param request + * HttpServletRequest + * @param responce + * HttpServletResponce + **/ + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + + String symbol = null; + BigDecimal newPrice; + StringBuffer output = new StringBuffer(100); + res.setContentType("text/html"); + java.io.PrintWriter out = res.getWriter(); + + try { + // get a random symbol to update and a random price. + symbol = TradeConfig.rndSymbol(); + newPrice = TradeConfig.getRandomPriceChangeFactor(); + + + // update the price of our symbol + QuoteDataBean quoteData = null; + int iter = TradeConfig.getPrimIterations(); + for (int ii = 0; ii < iter; ii++) { + quoteData = trade.updateQuotePriceVolumeInt(symbol, newPrice, 100.0, false); + } + + // write the output + output.append("Ping JDBC Write w/ Prepared Stmt." + + "
    Ping JDBC Write w/ Prep Stmt:
    Init time : " + + initTime); + hitCount++; + output.append("
    Hit Count: " + hitCount); + output.append("
    Update Information
    "); + output.append("
    " + quoteData.toHTML() + "
    "); + out.println(output.toString()); + + } catch (Exception e) { + Log.error(e, "PingJDBCWrite -- error updating quote for symbol", symbol); + res.sendError(500, "PingJDBCWrite Exception caught: " + e.toString()); + } + } + + /** + * returns a string of information about the servlet + * + * @return info String: contains info about the servlet + **/ + @Override + public String getServletInfo() { + return "Basic JDBC Write using a prepared statment makes use of TradeJDBC code."; + } + + /** + * called when the class is loaded to initialize the servlet + * + * @param config + * ServletConfig: + **/ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + initTime = new java.util.Date().toString(); + hitCount = 0; + + } + + /** + * forwards post requests to the doGet method Creation date: (11/6/2000 + * 10:52:39 AM) + * + * @param res + * javax.servlet.http.HttpServletRequest + * @param res2 + * javax.servlet.http.HttpServletResponse + */ + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingJSONPObject.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingJSONPObject.java new file mode 100644 index 00000000..5f2cfbb8 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingJSONPObject.java @@ -0,0 +1,128 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims; + +import java.io.IOException; +import java.io.StringReader; +import java.io.StringWriter; + +import javax.json.Json; +import javax.json.JsonObject; +import javax.json.JsonReader; +import javax.json.stream.JsonGenerator; +import javax.json.stream.JsonParser; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ibm.websphere.samples.daytrader.util.Log; + +/** + * + * PingJSONP tests JSON generating and parsing + * + */ + +@WebServlet(name = "PingJSONPObject", urlPatterns = { "/servlet/PingJSONPObject" }) +public class PingJSONPObject extends HttpServlet { + + + /** + * + */ + private static final long serialVersionUID = -5348806619121122708L; + private static String initTime; + private static int hitCount; + + /** + * forwards post requests to the doGet method Creation date: (11/6/2000 + * 10:52:39 AM) + * + * @param res + * javax.servlet.http.HttpServletRequest + * @param res2 + * javax.servlet.http.HttpServletResponse + */ + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + /** + * this is the main method of the servlet that will service all get + * requests. + * + * @param request + * HttpServletRequest + * @param responce + * HttpServletResponce + **/ + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + try { + res.setContentType("text/html"); + + ServletOutputStream out = res.getOutputStream(); + + hitCount++; + + // JSON generate + JsonObject json = Json.createObjectBuilder() + .add("initTime", initTime) + .add("hitCount", hitCount).build(); + String generatedJSON = json.toString(); + + // Read back + JsonReader jsonReader = Json.createReader(new StringReader(generatedJSON)); + String parsedJSON = jsonReader.readObject().toString(); + + + out.println("Ping JSONP" + + "

    Ping JSONP
    Generated JSON: " + generatedJSON + "
    Parsed JSON: " + parsedJSON + ""); + } catch (Exception e) { + Log.error(e, "PingJSONPObject.doGet(...): general exception caught"); + res.sendError(500, e.toString()); + + } + } + + /** + * returns a string of information about the servlet + * + * @return info String: contains info about the servlet + **/ + @Override + public String getServletInfo() { + return "Basic JSON generation and parsing in a servlet"; + } + + /** + * called when the class is loaded to initialize the servlet + * + * @param config + * ServletConfig: + **/ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + initTime = new java.util.Date().toString(); + hitCount = 0; + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingJSONPObjectFactory.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingJSONPObjectFactory.java new file mode 100644 index 00000000..1798797b --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingJSONPObjectFactory.java @@ -0,0 +1,127 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims; + +import java.io.IOException; +import java.io.StringReader; + +import javax.json.Json; +import javax.json.JsonBuilderFactory; +import javax.json.JsonObject; +import javax.json.JsonReader; +import javax.json.JsonReaderFactory; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ibm.websphere.samples.daytrader.util.Log; + +/** + * + * PingJSONP tests JSON generating and parsing + * + */ +@WebServlet(name = "PingJSONPObjectFactory", urlPatterns = { "/servlet/PingJSONPObjectFactory" }) +public class PingJSONPObjectFactory extends HttpServlet { + + private static final JsonBuilderFactory jSONObjectFactory = Json.createBuilderFactory(null); + private static final JsonReaderFactory jSONReaderFactory = Json.createReaderFactory(null); + /** + * + */ + private static final long serialVersionUID = -5348806619121122708L; + private static String initTime; + private static int hitCount; + + /** + * forwards post requests to the doGet method Creation date: (11/6/2000 + * 10:52:39 AM) + * + * @param res + * javax.servlet.http.HttpServletRequest + * @param res2 + * javax.servlet.http.HttpServletResponse + */ + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + /** + * this is the main method of the servlet that will service all get + * requests. + * + * @param request + * HttpServletRequest + * @param responce + * HttpServletResponce + **/ + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + try { + res.setContentType("text/html"); + + ServletOutputStream out = res.getOutputStream(); + + hitCount++; + + // JSON generate + JsonObject json = jSONObjectFactory.createObjectBuilder() + .add("initTime", initTime) + .add("hitCount", hitCount).build(); + String generatedJSON = json.toString(); + + // Read back + JsonReader jsonReader = jSONReaderFactory.createReader(new StringReader(generatedJSON)); + String parsedJSON = jsonReader.readObject().toString(); + + + out.println("Ping JSONP" + + "

    Ping JSONP
    Generated JSON: " + generatedJSON + "
    Parsed JSON: " + parsedJSON + ""); + } catch (Exception e) { + Log.error(e, "PingJSONPObject.doGet(...): general exception caught"); + res.sendError(500, e.toString()); + + } + } + + /** + * returns a string of information about the servlet + * + * @return info String: contains info about the servlet + **/ + @Override + public String getServletInfo() { + return "Basic JSON generation and parsing in a servlet"; + } + + /** + * called when the class is loaded to initialize the servlet + * + * @param config + * ServletConfig: + **/ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + initTime = new java.util.Date().toString(); + hitCount = 0; + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingJSONPStreaming.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingJSONPStreaming.java new file mode 100644 index 00000000..a1039381 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingJSONPStreaming.java @@ -0,0 +1,151 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims; + +import java.io.IOException; +import java.io.StringReader; +import java.io.StringWriter; + +import javax.json.Json; +import javax.json.stream.JsonGenerator; +import javax.json.stream.JsonParser; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ibm.websphere.samples.daytrader.util.Log; + +/** + * + * PingJSONP tests JSON generating and parsing + * + */ + +@WebServlet(name = "PingJSONPStreaming", urlPatterns = { "/servlet/PingJSONPStreaming" }) +public class PingJSONPStreaming extends HttpServlet { + + + /** + * + */ + private static final long serialVersionUID = -5348806619121122708L; + private static String initTime; + private static int hitCount; + + /** + * forwards post requests to the doGet method Creation date: (11/6/2000 + * 10:52:39 AM) + * + * @param res + * javax.servlet.http.HttpServletRequest + * @param res2 + * javax.servlet.http.HttpServletResponse + */ + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + /** + * this is the main method of the servlet that will service all get + * requests. + * + * @param request + * HttpServletRequest + * @param responce + * HttpServletResponce + **/ + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + try { + res.setContentType("text/html"); + + ServletOutputStream out = res.getOutputStream(); + + hitCount++; + + // JSON generate + StringWriter sw = new StringWriter(); + JsonGenerator generator = Json.createGenerator(sw); + + generator.writeStartObject(); + generator.write("initTime",initTime); + generator.write("hitCount", hitCount); + generator.writeEnd(); + generator.flush(); + + String generatedJSON = sw.toString(); + StringBuffer parsedJSON = new StringBuffer(); + + // JSON parse + JsonParser parser = Json.createParser(new StringReader(generatedJSON)); + while (parser.hasNext()) { + JsonParser.Event event = parser.next(); + switch(event) { + case START_ARRAY: + case END_ARRAY: + case START_OBJECT: + case END_OBJECT: + case VALUE_FALSE: + case VALUE_NULL: + case VALUE_TRUE: + break; + case KEY_NAME: + parsedJSON.append(parser.getString() + ":"); + break; + case VALUE_STRING: + case VALUE_NUMBER: + parsedJSON.append(parser.getString() + " "); + break; + } + } + + out.println("Ping JSONP" + + "

    Ping JSONP
    Generated JSON: " + generatedJSON + "
    Parsed JSON: " + parsedJSON + ""); + } catch (Exception e) { + Log.error(e, "PingJSONP.doGet(...): general exception caught"); + res.sendError(500, e.toString()); + + } + } + + /** + * returns a string of information about the servlet + * + * @return info String: contains info about the servlet + **/ + @Override + public String getServletInfo() { + return "Basic JSON generation and parsing in a servlet"; + } + + /** + * called when the class is loaded to initialize the servlet + * + * @param config + * ServletConfig: + **/ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + initTime = new java.util.Date().toString(); + hitCount = 0; + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingManagedExecutor.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingManagedExecutor.java new file mode 100644 index 00000000..a86aeaa2 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingManagedExecutor.java @@ -0,0 +1,120 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims; + +import java.io.IOException; + +import javax.annotation.Resource; +import javax.enterprise.concurrent.ManagedExecutorService; +import javax.servlet.AsyncContext; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@WebServlet(asyncSupported=true,name = "PingManagedExecutor", urlPatterns = { "/servlet/PingManagedExecutor" }) +public class PingManagedExecutor extends HttpServlet{ + + private static final long serialVersionUID = -4695386150928451234L; + private static String initTime; + private static int hitCount; + + @Resource + private ManagedExecutorService mes; + + /** + * forwards post requests to the doGet method Creation date: (03/18/2014 + * 10:52:39 AM) + * + * @param res + * javax.servlet.http.HttpServletRequest + * @param res2 + * javax.servlet.http.HttpServletResponse + */ + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + /** + * this is the main method of the servlet that will service all get + * requests. + * + * @param request + * HttpServletRequest + * @param responce + * HttpServletResponce + **/ + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + + final AsyncContext asyncContext = req.startAsync(); + final ServletOutputStream out = res.getOutputStream(); + + try { + res.setContentType("text/html"); + + out.println("Ping ManagedExecutor" + + "

    Ping ManagedExecutor
    Init time : " + initTime + + "

    "); + + // Runnable task + mes.submit(new Runnable() { + @Override + public void run() { + try { + out.println("HitCount: " + ++hitCount +"
    "); + } catch (IOException e) { + e.printStackTrace(); + } + asyncContext.complete(); + } + }); + + + } catch (Exception e) { + e.printStackTrace(); + } + } + + + /** + * returns a string of information about the servlet + * + * @return info String: contains info about the servlet + **/ + @Override + public String getServletInfo() { + return "Tests a ManagedExecutor"; + } + + /** + * called when the class is loaded to initialize the servlet + * + * @param config + * ServletConfig: + **/ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + initTime = new java.util.Date().toString(); + hitCount = 0; + } + +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingManagedThread.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingManagedThread.java new file mode 100644 index 00000000..6ecdd98b --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingManagedThread.java @@ -0,0 +1,126 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims; + +import java.io.IOException; + +import javax.annotation.Resource; +import javax.enterprise.concurrent.ManagedThreadFactory; +import javax.servlet.AsyncContext; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ibm.websphere.samples.daytrader.util.Log; + +@WebServlet(asyncSupported=true,name = "PingManagedThread", urlPatterns = { "/servlet/PingManagedThread" }) +public class PingManagedThread extends HttpServlet{ + + private static final long serialVersionUID = -4695386150928451234L; + private static String initTime; + private static int hitCount; + + @Resource + private ManagedThreadFactory managedThreadFactory; + + /** + * forwards post requests to the doGet method Creation date: (03/18/2014 + * 10:52:39 AM) + * + * @param res + * javax.servlet.http.HttpServletRequest + * @param res2 + * javax.servlet.http.HttpServletResponse + */ + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + /** + * this is the main method of the servlet that will service all get + * requests. + * + * @param request + * HttpServletRequest + * @param responce + * HttpServletResponce + **/ + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + + final AsyncContext asyncContext = req.startAsync(); + final ServletOutputStream out = res.getOutputStream(); + + try { + + res.setContentType("text/html"); + + out.println("Ping ManagedThread" + + "

    Ping ManagedThread
    Init time : " + initTime + "

    "); + + Thread thread = managedThreadFactory.newThread(new Runnable() { + @Override + public void run() { + try { + out.println("HitCount: " + ++hitCount +"
    "); + } catch (IOException e) { + e.printStackTrace(); + } + asyncContext.complete(); + } + }); + + thread.start(); + + } catch (Exception e) { + Log.error(e, "PingManagedThreadServlet.doGet(...): general exception caught"); + res.sendError(500, e.toString()); + } + + } + + + + /** + * returns a string of information about the servlet + * + * @return info String: contains info about the servlet + **/ + @Override + public String getServletInfo() { + return "Tests a ManagedThread asynchronous servlet"; + } + + /** + * called when the class is loaded to initialize the servlet + * + * @param config + * ServletConfig: + **/ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + initTime = new java.util.Date().toString(); + hitCount = 0; + + } + +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingReentryServlet.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingReentryServlet.java new file mode 100644 index 00000000..00b5cb08 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingReentryServlet.java @@ -0,0 +1,138 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@WebServlet(name = "PingReentryServlet", urlPatterns = { "/servlet/PingReentryServlet" }) +public class PingReentryServlet extends HttpServlet { + + private static final long serialVersionUID = -2536027021580175706L; + + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + /** + * this is the main method of the servlet that will service all get + * requests. + * + * @param request + * HttpServletRequest + * @param responce + * HttpServletResponce + **/ + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + try { + res.setContentType("text/html"); + + // The following 2 lines are the difference between PingServlet and + // PingServletWriter + // the latter uses a PrintWriter for output versus a binary output + // stream. + ServletOutputStream out = res.getOutputStream(); + // java.io.PrintWriter out = res.getWriter(); + int numReentriesLeft; + int sleepTime; + + if(req.getParameter("numReentries") != null){ + numReentriesLeft = Integer.parseInt(req.getParameter("numReentries")); + } else { + numReentriesLeft = 0; + } + + if(req.getParameter("sleep") != null){ + sleepTime = Integer.parseInt(req.getParameter("sleep")); + } else { + sleepTime = 0; + } + + if(numReentriesLeft <= 0) { + Thread.sleep(sleepTime); + out.println(numReentriesLeft); + } else { + String hostname = req.getServerName(); + int port = req.getServerPort(); + req.getContextPath(); + int saveNumReentriesLeft = numReentriesLeft; + int nextNumReentriesLeft = numReentriesLeft - 1; + + // Recursively call into the same server, decrementing the counter by 1. + String url = "http://" + hostname + ":" + port + "/" + req.getRequestURI() + + "?numReentries=" + nextNumReentriesLeft + + "&sleep=" + sleepTime; + URL obj = new URL(url); + HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + con.setRequestMethod("GET"); + con.setRequestProperty("User-Agent", "Mozilla/5.0"); + + //Append the recursion count to the response and return it. + BufferedReader in = new BufferedReader( + new InputStreamReader(con.getInputStream())); + String inputLine; + StringBuffer response = new StringBuffer(); + + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + in.close(); + + Thread.sleep(sleepTime); + out.println(saveNumReentriesLeft + response.toString()); + } + } catch (Exception e) { + //Log.error(e, "PingReentryServlet.doGet(...): general exception caught"); + res.sendError(500, e.toString()); + + } + } + + /** + * returns a string of information about the servlet + * + * @return info String: contains info about the servlet + **/ + @Override + public String getServletInfo() { + return "Basic dynamic HTML generation through a servlet"; + } + + /** + * called when the class is loaded to initialize the servlet + * + * @param config + * ServletConfig: + **/ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet.java new file mode 100644 index 00000000..a8996e1e --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet.java @@ -0,0 +1,112 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims; + +import java.io.IOException; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ibm.websphere.samples.daytrader.util.Log; + +/** + * + * PingServlet tests fundamental dynamic HTML creation functionality through + * server side servlet processing. + * + */ + +@WebServlet(name = "PingServlet", urlPatterns = { "/servlet/PingServlet" }) +public class PingServlet extends HttpServlet { + + private static final long serialVersionUID = 7097023236709683760L; + private static String initTime; + private static int hitCount; + + /** + * forwards post requests to the doGet method Creation date: (11/6/2000 + * 10:52:39 AM) + * + * @param res + * javax.servlet.http.HttpServletRequest + * @param res2 + * javax.servlet.http.HttpServletResponse + */ + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + /** + * this is the main method of the servlet that will service all get + * requests. + * + * @param request + * HttpServletRequest + * @param responce + * HttpServletResponce + **/ + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + try { + res.setContentType("text/html"); + + // The following 2 lines are the difference between PingServlet and + // PingServletWriter + // the latter uses a PrintWriter for output versus a binary output + // stream. + ServletOutputStream out = res.getOutputStream(); + // java.io.PrintWriter out = res.getWriter(); + hitCount++; + out.println("Ping Servlet" + + "

    Ping Servlet
    Init time : " + initTime + + "

    Hit Count: " + hitCount + ""); + } catch (Exception e) { + Log.error(e, "PingServlet.doGet(...): general exception caught"); + res.sendError(500, e.toString()); + + } + } + + /** + * returns a string of information about the servlet + * + * @return info String: contains info about the servlet + **/ + @Override + public String getServletInfo() { + return "Basic dynamic HTML generation through a servlet"; + } + + /** + * called when the class is loaded to initialize the servlet + * + * @param config + * ServletConfig: + **/ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + initTime = new java.util.Date().toString(); + hitCount = 0; + + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet2DB.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet2DB.java new file mode 100644 index 00000000..e003c41e --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet2DB.java @@ -0,0 +1,114 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims; + +import java.io.IOException; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ibm.websphere.samples.daytrader.impl.direct.TradeDirect; +import com.ibm.websphere.samples.daytrader.util.Log; + +/** + * + * PingServlet2DB tests the path of a servlet making a JDBC connection to a + * database + * + */ + +@WebServlet(name = "PingServlet2DB", urlPatterns = { "/servlet/PingServlet2DB" }) +public class PingServlet2DB extends HttpServlet { + + private static final long serialVersionUID = -6456675185605592049L; + private static String initTime; + private static int hitCount; + + /** + * forwards post requests to the doGet method Creation date: (11/6/2000 + * 10:52:39 AM) + * + * @param res + * javax.servlet.http.HttpServletRequest + * @param res2 + * javax.servlet.http.HttpServletResponse + */ + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + /** + * this is the main method of the servlet that will service all get + * requests. + * + * @param request + * HttpServletRequest + * @param responce + * HttpServletResponce + **/ + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + res.setContentType("text/html"); + java.io.PrintWriter out = res.getWriter(); + String symbol = null; + StringBuffer output = new StringBuffer(100); + + try { + // TradeJDBC uses prepared statements so I am going to make use of + // it's code. + TradeDirect trade = new TradeDirect(); + trade.getConnPublic(); + + output.append("PingServlet2DB." + + "
    PingServlet2DB:
    Init time : " + initTime); + hitCount++; + output.append("
    Hit Count: " + hitCount); + output.append("
    "); + out.println(output.toString()); + } catch (Exception e) { + Log.error(e, "PingServlet2DB -- error getting connection to the database", symbol); + res.sendError(500, "PingServlet2DB Exception caught: " + e.toString()); + } + } + + /** + * returns a string of information about the servlet + * + * @return info String: contains info about the servlet + **/ + @Override + public String getServletInfo() { + return "Basic JDBC Read using a prepared statment, makes use of TradeJDBC class"; + } + + /** + * called when the class is loaded to initialize the servlet + * + * @param config + * ServletConfig: + **/ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + hitCount = 0; + initTime = new java.util.Date().toString(); + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet2Include.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet2Include.java new file mode 100644 index 00000000..29a81cdf --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet2Include.java @@ -0,0 +1,104 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims; + +import java.io.IOException; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; + +/** + * + * PingServlet2Include tests servlet to servlet request dispatching. Servlet 1, + * the controller, creates a new JavaBean object forwards the servlet request + * with the JavaBean added to Servlet 2. Servlet 2 obtains access to the + * JavaBean through the Servlet request object and provides the dynamic HTML + * output based on the JavaBean data. PingServlet2Servlet is the initial servlet + * that sends a request to {@link PingServlet2ServletRcv} + * + */ +@WebServlet(name = "PingServlet2Include", urlPatterns = { "/servlet/PingServlet2Include" }) +public class PingServlet2Include extends HttpServlet { + + private static final long serialVersionUID = 1063447780151198793L; + private static String initTime; + private static int hitCount; + + /** + * forwards post requests to the doGet method Creation date: (11/6/2000 + * 10:52:39 AM) + * + * @param res + * javax.servlet.http.HttpServletRequest + * @param res2 + * javax.servlet.http.HttpServletResponse + */ + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + /** + * this is the main method of the servlet that will service all get + * requests. + * + * @param request + * HttpServletRequest + * @param responce + * HttpServletResponce + **/ + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + + try { + res.setContentType("text/html"); + + int iter = TradeConfig.getPrimIterations(); + for (int ii = 0; ii < iter; ii++) { + getServletConfig().getServletContext().getRequestDispatcher("/servlet/PingServlet2IncludeRcv").include(req, res); + } + + // ServletOutputStream out = res.getOutputStream(); + java.io.PrintWriter out = res.getWriter(); + out.println("Ping Servlet 2 Include" + + "

    Ping Servlet 2 Include
    Init time : " + + initTime + "

    Hit Count: " + hitCount++ + ""); + } catch (Exception ex) { + Log.error(ex, "PingServlet2Include.doGet(...): general exception"); + res.sendError(500, "PingServlet2Include.doGet(...): general exception" + ex.toString()); + } + } + + /** + * called when the class is loaded to initialize the servlet + * + * @param config + * ServletConfig: + **/ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + initTime = new java.util.Date().toString(); + hitCount = 0; + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet2IncludeRcv.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet2IncludeRcv.java new file mode 100644 index 00000000..3b8e1a70 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet2IncludeRcv.java @@ -0,0 +1,68 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * + * PingServlet2Include tests servlet to servlet request dispatching. Servlet 1, + * the controller, creates a new JavaBean object forwards the servlet request + * with the JavaBean added to Servlet 2. Servlet 2 obtains access to the + * JavaBean through the Servlet request object and provides the dynamic HTML + * output based on the JavaBean data. PingServlet2Servlet is the initial servlet + * that sends a request to {@link PingServlet2ServletRcv} + * + */ +@WebServlet(name = "PingServlet2IncludeRcv", urlPatterns = { "/servlet/PingServlet2IncludeRcv" }) +public class PingServlet2IncludeRcv extends HttpServlet { + + private static final long serialVersionUID = 2628801298561220872L; + + /** + * forwards post requests to the doGet method Creation date: (11/6/2000 + * 10:52:39 AM) + * + * @param res + * javax.servlet.http.HttpServletRequest + * @param res2 + * javax.servlet.http.HttpServletResponse + */ + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + /** + * this is the main method of the servlet that will service all get + * requests. + * + * @param request + * HttpServletRequest + * @param responce + * HttpServletResponce + **/ + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + // do nothing but get included by PingServlet2Include + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet2JNDI.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet2JNDI.java new file mode 100644 index 00000000..44031d13 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet2JNDI.java @@ -0,0 +1,109 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims; + +import java.io.IOException; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ibm.websphere.samples.daytrader.util.Log; + +/** + * + * PingServlet2JNDI performs a basic JNDI lookup of a JDBC DataSource + * + */ + +@WebServlet(name = "PingServlet2JNDI", urlPatterns = { "/servlet/PingServlet2JNDI" }) +public class PingServlet2JNDI extends HttpServlet { + + private static final long serialVersionUID = -8236271998141415347L; + private static String initTime; + private static int hitCount; + + /** + * forwards post requests to the doGet method Creation date: (11/6/2000 + * 10:52:39 AM) + * + * @param res + * javax.servlet.http.HttpServletRequest + * @param res2 + * javax.servlet.http.HttpServletResponse + */ + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + /** + * this is the main method of the servlet that will service all get + * requests. + * + * @param request + * HttpServletRequest + * @param responce + * HttpServletResponce + **/ + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + res.setContentType("text/html"); + java.io.PrintWriter out = res.getWriter(); + + StringBuffer output = new StringBuffer(100); + + try { + output.append("Ping JNDI -- lookup of JDBC DataSource" + + "
    Ping JNDI -- lookup of JDBC DataSource
    Init time : " + + initTime); + hitCount++; + output.append("
    Hit Count: " + hitCount); + output.append("
    "); + out.println(output.toString()); + } catch (Exception e) { + Log.error(e, "PingServlet2JNDI -- error look up of a JDBC DataSource"); + res.sendError(500, "PingServlet2JNDI Exception caught: " + e.toString()); + } + + } + + /** + * returns a string of information about the servlet + * + * @return info String: contains info about the servlet + **/ + @Override + public String getServletInfo() { + return "Basic JNDI look up of a JDBC DataSource"; + } + + /** + * called when the class is loaded to initialize the servlet + * + * @param config + * ServletConfig: + **/ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + hitCount = 0; + initTime = new java.util.Date().toString(); + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet2Jsp.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet2Jsp.java new file mode 100644 index 00000000..719e7209 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet2Jsp.java @@ -0,0 +1,78 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ibm.websphere.samples.daytrader.util.Log; + +/** + * + * PingServlet2JSP tests a call from a servlet to a JavaServer Page providing + * server-side dynamic HTML through JSP scripting. + * + */ +@WebServlet(name = "PingServlet2Jsp", urlPatterns = { "/servlet/PingServlet2Jsp" }) +public class PingServlet2Jsp extends HttpServlet { + private static final long serialVersionUID = -5199543766883932389L; + private static int hitCount = 0; + + /** + * forwards post requests to the doGet method Creation date: (11/6/2000 + * 10:52:39 AM) + * + * @param res + * javax.servlet.http.HttpServletRequest + * @param res2 + * javax.servlet.http.HttpServletResponse + */ + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + /** + * this is the main method of the servlet that will service all get + * requests. + * + * @param request + * HttpServletRequest + * @param responce + * HttpServletResponce + **/ + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + PingBean ab; + try { + ab = new PingBean(); + hitCount++; + ab.setMsg("Hit Count: " + hitCount); + req.setAttribute("ab", ab); + + getServletConfig().getServletContext().getRequestDispatcher("/PingServlet2Jsp.jsp").forward(req, res); + } catch (Exception ex) { + Log.error(ex, "PingServlet2Jsp.doGet(...): request error"); + res.sendError(500, "PingServlet2Jsp.doGet(...): request error" + ex.toString()); + + } + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet2PDF.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet2PDF.java new file mode 100644 index 00000000..4b6b2f2a --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet2PDF.java @@ -0,0 +1,115 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.IOException; +import java.net.URL; +import java.net.URLConnection; + +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ibm.websphere.samples.daytrader.util.Log; + +/** + * + * PingServlet2PDF tests a call to a servlet which then loads a PDF document. + * + */ +@WebServlet(name = "PingServlet2PDF", urlPatterns = { "/servlet/PingServlet2PDF" }) +public class PingServlet2PDF extends HttpServlet { + + private static final long serialVersionUID = -1321793174442755868L; + private static int hitCount = 0; + private static final int BUFFER_SIZE = 1024 * 8; // 8 KB + + /** + * forwards post requests to the doGet method Creation date: (11/6/2000 + * 10:52:39 AM) + * + * @param res + * javax.servlet.http.HttpServletRequest + * @param res2 + * javax.servlet.http.HttpServletResponse + */ + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + /** + * this is the main method of the servlet that will service all get + * requests. + * + * @param request + * HttpServletRequest + * @param responce + * HttpServletResponce + **/ + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + PingBean ab; + BufferedInputStream bis = null; + BufferedOutputStream bos = null; + try { + ab = new PingBean(); + hitCount++; + ab.setMsg("Hit Count: " + hitCount); + req.setAttribute("ab", ab); + + ServletOutputStream out = res.getOutputStream(); + + // MIME type for pdf doc + res.setContentType("application/pdf"); + + // Open an InputStream to the PDF document + String fileURL = "http://localhost:9080/daytrader/WAS_V7_64-bit_performance.pdf"; + URL url = new URL(fileURL); + URLConnection conn = url.openConnection(); + bis = new BufferedInputStream(conn.getInputStream()); + + // Transfer the InputStream (PDF Document) to OutputStream (servlet) + bos = new BufferedOutputStream(out); + byte[] buff = new byte[BUFFER_SIZE]; + int bytesRead; + // Simple read/write loop. + while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) { + bos.write(buff, 0, bytesRead); + } + + } catch (Exception ex) { + Log.error(ex, "PingServlet2Jsp.doGet(...): request error"); + res.sendError(500, "PingServlet2Jsp.doGet(...): request error" + ex.toString()); + + } + + finally { + if (bis != null) { + bis.close(); + } + if (bos != null) { + bos.close(); + } + } + + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet2Servlet.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet2Servlet.java new file mode 100644 index 00000000..8550ed6b --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet2Servlet.java @@ -0,0 +1,82 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ibm.websphere.samples.daytrader.util.Log; + +/** + * + * PingServlet2Servlet tests servlet to servlet request dispatching. Servlet 1, + * the controller, creates a new JavaBean object forwards the servlet request + * with the JavaBean added to Servlet 2. Servlet 2 obtains access to the + * JavaBean through the Servlet request object and provides the dynamic HTML + * output based on the JavaBean data. PingServlet2Servlet is the initial servlet + * that sends a request to {@link PingServlet2ServletRcv} + * + */ +@WebServlet(name = "PingServlet2Servlet", urlPatterns = { "/servlet/PingServlet2Servlet" }) +public class PingServlet2Servlet extends HttpServlet { + private static final long serialVersionUID = -955942781902636048L; + private static int hitCount = 0; + + /** + * forwards post requests to the doGet method Creation date: (11/6/2000 + * 10:52:39 AM) + * + * @param res + * javax.servlet.http.HttpServletRequest + * @param res2 + * javax.servlet.http.HttpServletResponse + */ + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + /** + * this is the main method of the servlet that will service all get + * requests. + * + * @param request + * HttpServletRequest + * @param responce + * HttpServletResponce + **/ + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + PingBean ab; + try { + ab = new PingBean(); + hitCount++; + ab.setMsg("Hit Count: " + hitCount); + req.setAttribute("ab", ab); + + getServletConfig().getServletContext().getRequestDispatcher("/servlet/PingServlet2ServletRcv").forward(req, res); + } catch (Exception ex) { + Log.error(ex, "PingServlet2Servlet.doGet(...): general exception"); + res.sendError(500, "PingServlet2Servlet.doGet(...): general exception" + ex.toString()); + + } + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet2ServletRcv.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet2ServletRcv.java new file mode 100644 index 00000000..c195a8e6 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet2ServletRcv.java @@ -0,0 +1,97 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims; + +import java.io.IOException; +import java.io.PrintWriter; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ibm.websphere.samples.daytrader.util.Log; + +/** + * + * PingServlet2Servlet tests servlet to servlet request dispatching. Servlet 1, + * the controller, creates a new JavaBean object forwards the servlet request + * with the JavaBean added to Servlet 2. Servlet 2 obtains access to the + * JavaBean through the Servlet request object and provides the dynamic HTML + * output based on the JavaBean data. PingServlet2ServletRcv receives a request + * from {@link PingServlet2Servlet} and displays output. + * + */ +@WebServlet(name = "PingServlet2ServletRcv", urlPatterns = { "/servlet/PingServlet2ServletRcv" }) +public class PingServlet2ServletRcv extends HttpServlet { + private static final long serialVersionUID = -5241563129216549706L; + private static String initTime = null; + + /** + * forwards post requests to the doGet method Creation date: (11/6/2000 + * 10:52:39 AM) + * + * @param res + * javax.servlet.http.HttpServletRequest + * @param res2 + * javax.servlet.http.HttpServletResponse + */ + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + /** + * this is the main method of the servlet that will service all get + * requests. + * + * @param request + * HttpServletRequest + * @param responce + * HttpServletResponce + **/ + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + PingBean ab; + try { + ab = (PingBean) req.getAttribute("ab"); + res.setContentType("text/html"); + PrintWriter out = res.getWriter(); + out.println("Ping Servlet2Servlet" + + "

    PingServlet2Servlet:
    Init time: " + + initTime + "

    Message from Servlet: " + ab.getMsg() + ""); + } catch (Exception ex) { + Log.error(ex, "PingServlet2ServletRcv.doGet(...): general exception"); + res.sendError(500, "PingServlet2ServletRcv.doGet(...): general exception" + ex.toString()); + } + + } + + /** + * called when the class is loaded to initialize the servlet + * + * @param config + * ServletConfig: + **/ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + initTime = new java.util.Date().toString(); + + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet30Async.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet30Async.java new file mode 100644 index 00000000..803bf6b6 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet30Async.java @@ -0,0 +1,118 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims; + +import java.io.IOException; + +import javax.servlet.AsyncContext; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletInputStream; +import javax.servlet.ServletOutputStream; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +//import com.ibm.websphere.samples.daytrader.util.Log; + +/** + * + * PingServlet31Async tests fundamental dynamic HTML creation functionality through + * server side servlet processing asynchronously. + * + */ + +@WebServlet(name = "PingServlet30Async", urlPatterns = { "/servlet/PingServlet30Async" }, asyncSupported=true) +public class PingServlet30Async extends HttpServlet { + + private static final long serialVersionUID = 8731300373855056660L; + private static String initTime; + private static int hitCount; + + /** + * forwards post requests to the doGet method Creation date: (11/6/2000 + * 10:52:39 AM) + * + * @param res + * javax.servlet.http.HttpServletRequest + * @param res2 + * javax.servlet.http.HttpServletResponse + */ + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + res.setContentType("text/html"); + + AsyncContext ac = req.startAsync(); + StringBuilder sb = new StringBuilder(); + + ServletInputStream input = req.getInputStream(); + byte[] b = new byte[1024]; + int len = -1; + while ((len = input.read(b)) != -1) { + String data = new String(b, 0, len); + sb.append(data); + } + + ServletOutputStream output = res.getOutputStream(); + + output.println("Ping Servlet 3.0 Async" + + "

    Ping Servlet 3.0 Async
    " + + "Init time : " + initTime + + "

    Hit Count: " + ++hitCount + "
    Data Received: "+ sb.toString() + ""); + + ac.complete(); + } + + + /** + * this is the main method of the servlet that will service all get + * requests. + * + * @param request + * HttpServletRequest + * @param responce + * HttpServletResponce + **/ + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doPost(req,res); + + } + /** + * returns a string of information about the servlet + * + * @return info String: contains info about the servlet + **/ + @Override + public String getServletInfo() { + return "Basic dynamic HTML generation through a servlet"; + } + + /** + * called when the class is loaded to initialize the servlet + * + * @param config + * ServletConfig: + **/ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + initTime = new java.util.Date().toString(); + hitCount = 0; + + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet31Async.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet31Async.java new file mode 100644 index 00000000..2bc313b8 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet31Async.java @@ -0,0 +1,186 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims; + +import java.io.IOException; + +import java.util.Queue; +import java.util.concurrent.LinkedBlockingQueue; + +import javax.servlet.AsyncContext; +import javax.servlet.ReadListener; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletInputStream; +import javax.servlet.ServletOutputStream; +import javax.servlet.WriteListener; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +//import com.ibm.websphere.samples.daytrader.util.Log; + +/** + * + * PingServlet31Async tests fundamental dynamic HTML creation functionality through + * server side servlet processing asynchronously with non-blocking i/o. + * + */ + +@WebServlet(name = "PingServlet31Async", urlPatterns = { "/servlet/PingServlet31Async" }, asyncSupported=true) +public class PingServlet31Async extends HttpServlet { + + private static final long serialVersionUID = 8731300373855056660L; + private static String initTime; + private static int hitCount; + + /** + * forwards post requests to the doGet method Creation date: (11/6/2000 + * 10:52:39 AM) + * + * @param res + * javax.servlet.http.HttpServletRequest + * @param res2 + * javax.servlet.http.HttpServletResponse + */ + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + res.setContentType("text/html"); + + AsyncContext ac = req.startAsync(); + + ServletInputStream input = req.getInputStream(); + ReadListener readListener = new ReadListenerImpl(input, res, ac); + input.setReadListener(readListener); + } + + class ReadListenerImpl implements ReadListener { + private ServletInputStream input = null; + private HttpServletResponse res = null; + private AsyncContext ac = null; + private Queue queue = new LinkedBlockingQueue(); + + ReadListenerImpl(ServletInputStream in, HttpServletResponse r, AsyncContext c) { + input = in; + res = r; + ac = c; + } + + public void onDataAvailable() throws IOException { + StringBuilder sb = new StringBuilder(); + int len = -1; + byte b[] = new byte[1024]; + + while (input.isReady() && (len = input.read(b)) != -1) { + String data = new String(b, 0, len); + sb.append(data); + } + queue.add(sb.toString()); + + } + + public void onAllDataRead() throws IOException { + ServletOutputStream output = res.getOutputStream(); + WriteListener writeListener = new WriteListenerImpl(output, queue, ac); + output.setWriteListener(writeListener); + } + + public void onError(final Throwable t) { + ac.complete(); + t.printStackTrace(); + } + } + + class WriteListenerImpl implements WriteListener { + private ServletOutputStream output = null; + private Queue queue = null; + private AsyncContext ac = null; + + WriteListenerImpl(ServletOutputStream sos, Queue q, AsyncContext c) { + output = sos; + queue = q; + ac = c; + + try { + output.print("Ping Servlet 3.1 Async" + + "

    Ping Servlet 3.1 Async" + + "
    Init time : " + initTime + + "

    Hit Count: " + ++hitCount + "
    Data Received: "); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + public void onWritePossible() throws IOException { + + while (queue.peek() != null && output.isReady()) { + String data = (String) queue.poll(); + output.print(data); + } + + if (queue.peek() == null) { + output.println(""); + ac.complete(); + } + } + + public void onError(final Throwable t) { + ac.complete(); + t.printStackTrace(); + } + } + + + + /** + * this is the main method of the servlet that will service all get + * requests. + * + * @param request + * HttpServletRequest + * @param responce + * HttpServletResponce + **/ + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doPost(req,res); + } + /** + * returns a string of information about the servlet + * + * @return info String: contains info about the servlet + **/ + @Override + public String getServletInfo() { + return "Basic dynamic HTML generation through a servlet"; + } + + /** + * called when the class is loaded to initialize the servlet + * + * @param config + * ServletConfig: + **/ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + initTime = new java.util.Date().toString(); + hitCount = 0; + + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet31AsyncRead.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet31AsyncRead.java new file mode 100644 index 00000000..e23994ed --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServlet31AsyncRead.java @@ -0,0 +1,145 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims; + +import java.io.IOException; + +import javax.servlet.AsyncContext; +import javax.servlet.ReadListener; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletInputStream; +import javax.servlet.ServletOutputStream; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +//import com.ibm.websphere.samples.daytrader.util.Log; + +/** + * + * PingServlet31Async tests fundamental dynamic HTML creation functionality through + * server side servlet processing asynchronously with non-blocking i/o. + * + */ + +@WebServlet(name = "PingServlet31AsyncRead", urlPatterns = { "/servlet/PingServlet31AsyncRead" }, asyncSupported=true) +public class PingServlet31AsyncRead extends HttpServlet { + + private static final long serialVersionUID = 8731300373855056660L; + private static String initTime; + private static int hitCount; + + /** + * forwards post requests to the doGet method Creation date: (11/6/2000 + * 10:52:39 AM) + * + * @param res + * javax.servlet.http.HttpServletRequest + * @param res2 + * javax.servlet.http.HttpServletResponse + */ + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + res.setContentType("text/html"); + + AsyncContext ac = req.startAsync(); + + ServletInputStream input = req.getInputStream(); + ReadListener readListener = new ReadListenerImpl(input, res, ac); + input.setReadListener(readListener); + } + + class ReadListenerImpl implements ReadListener { + private ServletInputStream input = null; + private HttpServletResponse res = null; + private AsyncContext ac = null; + private StringBuilder sb = new StringBuilder(); + + ReadListenerImpl(ServletInputStream in, HttpServletResponse r, AsyncContext c) { + input = in; + res = r; + ac = c; + } + + public void onDataAvailable() throws IOException { + + int len = -1; + byte b[] = new byte[1024]; + + while (input.isReady() && (len = input.read(b)) != -1) { + String data = new String(b, 0, len); + sb.append(data); + } + + + } + + public void onAllDataRead() throws IOException { + ServletOutputStream output = res.getOutputStream(); + output.println("Ping Servlet 3.1 Async" + + "

    Ping Servlet 3.1 AsyncRead" + + "
    Init time : " + initTime + + "

    Hit Count: " + ++hitCount + "
    Data Received: " + sb.toString() + ""); + ac.complete(); + } + + public void onError(final Throwable t) { + ac.complete(); + t.printStackTrace(); + } + } + + + + /** + * this is the main method of the servlet that will service all get + * requests. + * + * @param request + * HttpServletRequest + * @param responce + * HttpServletResponce + **/ + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doPost(req,res); + } + /** + * returns a string of information about the servlet + * + * @return info String: contains info about the servlet + **/ + @Override + public String getServletInfo() { + return "Basic dynamic HTML generation through a servlet"; + } + + /** + * called when the class is loaded to initialize the servlet + * + * @param config + * ServletConfig: + **/ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + initTime = new java.util.Date().toString(); + hitCount = 0; + + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServletLargeContentLength.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServletLargeContentLength.java new file mode 100644 index 00000000..6246a5c5 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServletLargeContentLength.java @@ -0,0 +1,95 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims; + +import java.io.IOException; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * + * PingServletSetContentLength tests fundamental dynamic HTML creation + * functionality through server side servlet processing. + * + */ + +@WebServlet(name = "PingServletLargeContentLength", urlPatterns = { "/servlet/PingServletLargeContentLength" }) +public class PingServletLargeContentLength extends HttpServlet { + + + + /** + * + */ + private static final long serialVersionUID = -7979576220528252408L; + + /** + * forwards post requests to the doGet method Creation date: (02/07/2013 + * 10:52:39 AM) + * + * @param res + * javax.servlet.http.HttpServletRequest + * @param res2 + * javax.servlet.http.HttpServletResponse + */ + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + System.out.println("Length: " + req.getContentLengthLong()); + + + + + } + + /** + * this is the main method of the servlet that will service all get + * requests. + * + * @param request + * HttpServletRequest + * @param responce + * HttpServletResponce + **/ + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doPost(req,res); } + + /** + * returns a string of information about the servlet + * + * @return info String: contains info about the servlet + **/ + @Override + public String getServletInfo() { + return "Basic dynamic HTML generation through a servlet, with " + "contentLength set by contentLength parameter."; + } + + /** + * called when the class is loaded to initialize the servlet + * + * @param config + * ServletConfig: + **/ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServletSetContentLength.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServletSetContentLength.java new file mode 100644 index 00000000..4ec93595 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServletSetContentLength.java @@ -0,0 +1,121 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims; + +import java.io.IOException; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ibm.websphere.samples.daytrader.util.Log; + +/** + * + * PingServletSetContentLength tests fundamental dynamic HTML creation + * functionality through server side servlet processing. + * + */ + +@WebServlet(name = "PingServletSetContentLength", urlPatterns = { "/servlet/PingServletSetContentLength" }) +public class PingServletSetContentLength extends HttpServlet { + + private static final long serialVersionUID = 8731300373855056661L; + + /** + * forwards post requests to the doGet method Creation date: (02/07/2013 + * 10:52:39 AM) + * + * @param res + * javax.servlet.http.HttpServletRequest + * @param res2 + * javax.servlet.http.HttpServletResponse + */ + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + /** + * this is the main method of the servlet that will service all get + * requests. + * + * @param request + * HttpServletRequest + * @param responce + * HttpServletResponce + **/ + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + try { + res.setContentType("text/html"); + String lengthParam = req.getParameter("contentLength"); + Integer length; + + if (lengthParam == null) { + length = 0; + } else { + length = Integer.parseInt(lengthParam); + } + + ServletOutputStream out = res.getOutputStream(); + + // Add characters (a's) to the SOS to equal the requested length + // 167 is the smallest length possible. + + int i = 0; + String buffer = ""; + + while (i + 167 < length) { + buffer = buffer + "a"; + i++; + } + + out.println("Ping Servlet" + + "

    Ping Servlet
    " + buffer + + "
    "); + } catch (Exception e) { + Log.error(e, "PingServlet.doGet(...): general exception caught"); + res.sendError(500, e.toString()); + + } + } + + /** + * returns a string of information about the servlet + * + * @return info String: contains info about the servlet + **/ + @Override + public String getServletInfo() { + return "Basic dynamic HTML generation through a servlet, with " + "contentLength set by contentLength parameter."; + } + + /** + * called when the class is loaded to initialize the servlet + * + * @param config + * ServletConfig: + **/ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServletWriter.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServletWriter.java new file mode 100644 index 00000000..bda01cd8 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingServletWriter.java @@ -0,0 +1,110 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims; + +import java.io.IOException; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ibm.websphere.samples.daytrader.util.Log; + +/** + * + * PingServlet extends PingServlet by using a PrintWriter for formatted output + * vs. the output stream used by {@link PingServlet}. + * + */ +@WebServlet(name = "PingServletWriter", urlPatterns = { "/servlet/PingServletWriter" }) +public class PingServletWriter extends HttpServlet { + + private static final long serialVersionUID = -267847365014523225L; + private static String initTime; + private static int hitCount; + + /** + * forwards post requests to the doGet method Creation date: (11/6/2000 + * 10:52:39 AM) + * + * @param res + * javax.servlet.http.HttpServletRequest + * @param res2 + * javax.servlet.http.HttpServletResponse + */ + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + /** + * this is the main method of the servlet that will service all get + * requests. + * + * @param request + * HttpServletRequest + * @param responce + * HttpServletResponce + **/ + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + try { + res.setContentType("text/html"); + + // The following 2 lines are the difference between PingServlet and + // PingServletWriter + // the latter uses a PrintWriter for output versus a binary output + // stream. + // ServletOutputStream out = res.getOutputStream(); + java.io.PrintWriter out = res.getWriter(); + hitCount++; + out.println("Ping Servlet Writer" + + "

    Ping Servlet Writer:
    Init time : " + + initTime + "

    Hit Count: " + hitCount + ""); + } catch (Exception e) { + Log.error(e, "PingServletWriter.doGet(...): general exception caught"); + res.sendError(500, e.toString()); + } + } + + /** + * returns a string of information about the servlet + * + * @return info String: contains info about the servlet + **/ + + @Override + public String getServletInfo() { + return "Basic dynamic HTML generation through a servlet using a PrintWriter"; + } + + /** + * called when the class is loaded to initialize the servlet + * + * @param config + * ServletConfig: + **/ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + hitCount = 0; + initTime = new java.util.Date().toString(); + + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingSession1.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingSession1.java new file mode 100644 index 00000000..3abb342b --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingSession1.java @@ -0,0 +1,136 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims; + +import java.io.IOException; +import java.io.PrintWriter; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import com.ibm.websphere.samples.daytrader.util.Log; + +/** + * + * PingHTTPSession1 - SessionID tests fundamental HTTP session functionality by + * creating a unique session ID for each individual user. The ID is stored in + * the users session and is accessed and displayed on each user request. + * + */ +@WebServlet(name = "PingSession1", urlPatterns = { "/servlet/PingSession1" }) +public class PingSession1 extends HttpServlet { + private static final long serialVersionUID = -3703858656588519807L; + private static int count; + // For each new session created, add a session ID of the form "sessionID:" + + // count + private static String initTime; + private static int hitCount; + + /** + * forwards post requests to the doGet method Creation date: (11/6/2000 + * 10:52:39 AM) + * + * @param res + * javax.servlet.http.HttpServletRequest + * @param res2 + * javax.servlet.http.HttpServletResponse + */ + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + /** + * this is the main method of the servlet that will service all get + * requests. + * + * @param request + * HttpServletRequest + * @param responce + * HttpServletResponce + **/ + @Override + public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + HttpSession session = null; + try { + try { + // get the users session, if the user does not have a session + // create one. + session = request.getSession(true); + } catch (Exception e) { + Log.error(e, "PingSession1.doGet(...): error getting session"); + // rethrow the exception for handling in one place. + throw e; + } + + // Get the session data value + Integer ival = (Integer) session.getAttribute("sessiontest.counter"); + // if their is not a counter create one. + if (ival == null) { + ival = new Integer(count++); + session.setAttribute("sessiontest.counter", ival); + } + String SessionID = "SessionID:" + ival.toString(); + + // Output the page + response.setContentType("text/html"); + response.setHeader("SessionKeyTest-SessionID", SessionID); + + PrintWriter out = response.getWriter(); + out.println("HTTP Session Key Test

    HTTP Session Test 1: Session Key
    Init time: " + + initTime + "

    "); + hitCount++; + out.println("Hit Count: " + hitCount + "
    Your HTTP Session key is " + SessionID + "
    "); + } catch (Exception e) { + // log the excecption + Log.error(e, "PingSession1.doGet(..l.): error."); + // set the server responce to 500 and forward to the web app defined + // error page + response.sendError(500, "PingSession1.doGet(...): error. " + e.toString()); + } + } + + /** + * returns a string of information about the servlet + * + * @return info String: contains info about the servlet + **/ + + @Override + public String getServletInfo() { + return "HTTP Session Key: Tests management of a read only unique id"; + } + + /** + * called when the class is loaded to initialize the servlet + * + * @param config + * ServletConfig: + **/ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + count = 0; + hitCount = 0; + initTime = new java.util.Date().toString(); + + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingSession2.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingSession2.java new file mode 100644 index 00000000..9a47f87a --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingSession2.java @@ -0,0 +1,145 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims; + +import java.io.IOException; +import java.io.PrintWriter; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import com.ibm.websphere.samples.daytrader.util.Log; + +/** + * + * PingHTTPSession2 session create/destroy further extends the previous test by + * invalidating the HTTP Session on every 5th user access. This results in + * testing HTTPSession create and destroy + * + */ +@WebServlet(name = "PingSession2", urlPatterns = { "/servlet/PingSession2" }) +public class PingSession2 extends HttpServlet { + + private static final long serialVersionUID = -273579463475455800L; + private static String initTime; + private static int hitCount; + + /** + * forwards post requests to the doGet method Creation date: (11/6/2000 + * 10:52:39 AM) + * + * @param res + * javax.servlet.http.HttpServletRequest + * @param res2 + * javax.servlet.http.HttpServletResponse + */ + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + /** + * this is the main method of the servlet that will service all get + * requests. + * + * @param request + * HttpServletRequest + * @param responce + * HttpServletResponce + **/ + @Override + public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + HttpSession session = null; + try { + try { + session = request.getSession(true); + } catch (Exception e) { + Log.error(e, "PingSession2.doGet(...): error getting session"); + // rethrow the exception for handling in one place. + throw e; + + } + + // Get the session data value + Integer ival = (Integer) session.getAttribute("sessiontest.counter"); + // if there is not a counter then create one. + if (ival == null) { + ival = new Integer(1); + } else { + ival = new Integer(ival.intValue() + 1); + } + session.setAttribute("sessiontest.counter", ival); + // if the session count is equal to five invalidate the session + if (ival.intValue() == 5) { + session.invalidate(); + } + + try { + // Output the page + response.setContentType("text/html"); + response.setHeader("SessionTrackingTest-counter", ival.toString()); + + PrintWriter out = response.getWriter(); + out.println("Session Tracking Test 2

    HTTP Session Test 2: Session create/invalidate
    Init time: " + + initTime + "

    "); + hitCount++; + out.println("Hit Count: " + hitCount + "
    Session hits: " + ival + "
    "); + } catch (Exception e) { + Log.error(e, "PingSession2.doGet(...): error getting session information"); + // rethrow the exception for handling in one place. + throw e; + } + + } + + catch (Exception e) { + // log the excecption + Log.error(e, "PingSession2.doGet(...): error."); + // set the server responce to 500 and forward to the web app defined + // error page + response.sendError(500, "PingSession2.doGet(...): error. " + e.toString()); + } + } // end of the method + + /** + * returns a string of information about the servlet + * + * @return info String: contains info about the servlet + **/ + @Override + public String getServletInfo() { + return "HTTP Session Key: Tests management of a read/write unique id"; + } + + /** + * called when the class is loaded to initialize the servlet + * + * @param config + * ServletConfig: + **/ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + hitCount = 0; + initTime = new java.util.Date().toString(); + + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingSession3.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingSession3.java new file mode 100644 index 00000000..7e49518e --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingSession3.java @@ -0,0 +1,182 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims; + +import java.io.IOException; +import java.io.PrintWriter; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import com.ibm.websphere.samples.daytrader.util.Log; + +/** + * + * PingHTTPSession3 tests the servers ability to manage and persist large + * HTTPSession data objects. The servlet creates the large custom java object + * {@link PingSession3Object}. This large session object is retrieved and stored + * to the session on each user request. The default settings result in approx + * 2024 bits being retrieved and stored upon each request. + * + */ +@WebServlet(name = "PingSession3", urlPatterns = { "/servlet/PingSession3" }) +public class PingSession3 extends HttpServlet { + private static final long serialVersionUID = -6129599971684210414L; + private static int NUM_OBJECTS = 2; + private static String initTime = null; + private static int hitCount = 0; + + /** + * forwards post requests to the doGet method Creation date: (11/6/2000 + * 10:52:39 AM) + * + * @param res + * javax.servlet.http.HttpServletRequest + * @param res2 + * javax.servlet.http.HttpServletResponse + */ + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + /** + * this is the main method of the servlet that will service all get + * requests. + * + * @param request + * HttpServletRequest + * @param responce + * HttpServletResponce + **/ + @Override + public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + + PrintWriter out = response.getWriter(); + // Using a StringBuffer to output all at once. + StringBuffer outputBuffer = new StringBuffer(); + HttpSession session = null; + PingSession3Object[] sessionData; + response.setContentType("text/html"); + + // this is a general try/catch block. The catch block at the end of this + // will forward the responce + // to an error page if there is an exception + try { + + try { + session = request.getSession(true); + } catch (Exception e) { + Log.error(e, "PingSession3.doGet(...): error getting session"); + // rethrow the exception for handling in one place. + throw e; + + } + // Each PingSession3Object in the PingSession3Object array is 1K in + // size + // NUM_OBJECTS sets the size of the array to allocate and thus set + // the size in KBytes of the session object + // NUM_OBJECTS can be initialized by the servlet + // Here we check for the request parameter to change the size and + // invalidate the session if it exists + // NOTE: Current user sessions will remain the same (i.e. when + // NUM_OBJECTS is changed, all user thread must be restarted + // for the change to fully take effect + + String num_objects; + if ((num_objects = request.getParameter("num_objects")) != null) { + // validate input + try { + int x = Integer.parseInt(num_objects); + if (x > 0) { + NUM_OBJECTS = x; + } + } catch (Exception e) { + Log.error(e, "PingSession3.doGet(...): input should be an integer, input=" + num_objects); + } // revert to current value on exception + + outputBuffer.append(" Session object size set to " + NUM_OBJECTS + "K bytes "); + if (session != null) { + session.invalidate(); + } + out.print(outputBuffer.toString()); + out.close(); + return; + } + + // Get the session data value + sessionData = (PingSession3Object[]) session.getAttribute("sessiontest.sessionData"); + if (sessionData == null) { + sessionData = new PingSession3Object[NUM_OBJECTS]; + for (int i = 0; i < NUM_OBJECTS; i++) { + sessionData[i] = new PingSession3Object(); + } + } + + session.setAttribute("sessiontest.sessionData", sessionData); + + // Each PingSession3Object is about 1024 bits, there are 8 bits in a + // byte. + int num_bytes = (NUM_OBJECTS * 1024) / 8; + response.setHeader("SessionTrackingTest-largeSessionData", num_bytes + "bytes"); + + outputBuffer + .append("Session Large Data Test

    HTTP Session Test 3: Large Data
    Init time: ") + .append(initTime).append("

    "); + hitCount++; + outputBuffer.append("Hit Count: ").append(hitCount) + .append("
    Session object updated. Session Object size = " + num_bytes + " bytes
    "); + // output the Buffer to the printWriter. + out.println(outputBuffer.toString()); + + } catch (Exception e) { + // log the excecption + Log.error(e, "PingSession3.doGet(..l.): error."); + // set the server responce to 500 and forward to the web app defined + // error page + response.sendError(500, "PingSession3.doGet(...): error. " + e.toString()); + } + } + + /** + * returns a string of information about the servlet + * + * @return info String: contains info about the servlet + **/ + @Override + public String getServletInfo() { + return "HTTP Session Object: Tests management of a large custom session class"; + } + + /** + * called when the class is loaded to initialize the servlet + * + * @param config + * ServletConfig: + **/ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + hitCount = 0; + initTime = new java.util.Date().toString(); + + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingSession3Object.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingSession3Object.java new file mode 100644 index 00000000..362f0a93 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingSession3Object.java @@ -0,0 +1,92 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims; + +import java.io.Serializable; + +/** + * + * An object that contains approximately 1024 bits of information. This is used + * by {@link PingSession3} + * + */ +public class PingSession3Object implements Serializable { + // PingSession3Object represents a BLOB of session data of various. + // Each instantiation of this class is approximately 1K in size (not + // including overhead for arrays and Strings) + // Using different datatype exercises the various serialization algorithms + // for each type + + private static final long serialVersionUID = 1452347702903504717L; + byte[] byteVal = new byte[16]; // 8 * 16 = 128 bits + char[] charVal = new char[8]; // 16 * 8 = 128 bits + int a, b, c, d; // 4 * 32 = 128 bits + float e, f, g, h; // 4 * 32 = 128 bits + double i, j; // 2 * 64 = 128 bits + // Primitive type size = ~5*128= 640 + + String s1 = new String("123456789012"); + String s2 = new String("abcdefghijkl"); + + // String type size = ~2*12*16 = 384 + // Total blob size (w/o overhead) = 1024 + + // The Session blob must be filled with data to avoid compression of the + // blob during serialization + PingSession3Object() { + int index; + byte b = 0x8; + for (index = 0; index < 16; index++) { + byteVal[index] = (byte) (b + 2); + } + + char c = 'a'; + for (index = 0; index < 8; index++) { + charVal[index] = (char) (c + 2); + } + + a = 1; + b = 2; + c = 3; + d = 5; + e = (float) 7.0; + f = (float) 11.0; + g = (float) 13.0; + h = (float) 17.0; + i = 19.0; + j = 23.0; + } + /** + * Main method to test the serialization of the Session Data blob object + * Creation date: (4/3/2000 3:07:34 PM) + * + * @param args + * java.lang.String[] + */ + + /** + * Since the following main method were written for testing purpose, we + * comment them out public static void main(String[] args) { try { + * PingSession3Object data = new PingSession3Object(); + * + * FileOutputStream ostream = new + * FileOutputStream("c:\\temp\\datablob.xxx"); ObjectOutputStream p = new + * ObjectOutputStream(ostream); p.writeObject(data); p.flush(); + * ostream.close(); } catch (Exception e) { System.out.println("Exception: " + * + e.toString()); } } + */ + +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingUpgradeServlet.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingUpgradeServlet.java new file mode 100644 index 00000000..339986ed --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingUpgradeServlet.java @@ -0,0 +1,157 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ + +package com.ibm.websphere.samples.daytrader.web.prims; + +import java.io.IOException; + +import javax.servlet.ReadListener; +import javax.servlet.ServletException; +import javax.servlet.ServletInputStream; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpUpgradeHandler; +import javax.servlet.http.WebConnection; +import javax.servlet.annotation.WebServlet; + +import com.ibm.websphere.samples.daytrader.util.Log; + +@WebServlet(name = "PingUpgradeServlet", urlPatterns = { "/servlet/PingUpgradeServlet" }, asyncSupported=true) +public class PingUpgradeServlet extends HttpServlet { + private static final long serialVersionUID = -6955518532146927509L; + + + @Override + protected void doGet(final HttpServletRequest req, final HttpServletResponse res) throws ServletException, IOException { + doPost(req,res); + } + + @Override + protected void doPost(final HttpServletRequest req, final HttpServletResponse res) throws ServletException, IOException { + + + Log.trace("PingUpgradeServlet:doPost"); + + + if ("echo".equals(req.getHeader("Upgrade"))) { + + + Log.trace("PingUpgradeServlet:doPost -- found echo, doing upgrade"); + + + res.setStatus(101); + res.setHeader("Upgrade", "echo"); + res.setHeader("Connection", "Upgrade"); + + req.upgrade(Handler.class); + + } else { + + + Log.trace("PingUpgradeServlet:doPost -- did not find echo, no upgrade"); + + + res.getWriter().println("No upgrade: " + req.getHeader("Upgrade")); + } + } + + public static class Handler implements HttpUpgradeHandler { + + @Override + public void init(final WebConnection wc) { + Listener listener = null; + try { + listener = new Listener(wc); + + } catch (IOException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + + try { + + Log.trace("PingUpgradeServlet$Handler.init() -- Initializing Handler"); + + + // flush headers if any + wc.getOutputStream().flush(); + wc.getInputStream().setReadListener(listener); + + } catch (IOException e) { + throw new IllegalArgumentException(e); + } + } + + @Override + public void destroy() { + Log.trace("PingUpgradeServlet$Handler.destroy() -- Destroying Handler"); + } + } + + private static class Listener implements ReadListener { + private final WebConnection connection; + private ServletInputStream input = null; + private ServletOutputStream output = null; + + private Listener(final WebConnection connection) throws IOException { + this.connection = connection; + this.input = connection.getInputStream(); + this.output = connection.getOutputStream(); + } + + @Override + public void onDataAvailable() throws IOException { + + Log.trace("PingUpgradeServlet$Listener.onDataAvailable() called"); + + byte[] data = new byte[1024]; + int len = -1; + + while (input.isReady() && (len = input.read(data)) != -1) { + String dataRead = new String(data, 0, len); + + Log.trace("PingUpgradeServlet$Listener.onDataAvailable() -- Adding data to queue -->" + dataRead + "<--"); + + output.println(dataRead); + output.flush(); + } + + closeConnection(); + } + + private void closeConnection() { + try { + connection.close(); + } catch (Exception e) { + + Log.error(e.toString()); + } + } + + + @Override + public void onAllDataRead() throws IOException { + closeConnection(); + } + + @Override + public void onError(final Throwable t) { + closeConnection(); + } + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingWebSocketBinary.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingWebSocketBinary.java new file mode 100644 index 00000000..5f55fbc8 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingWebSocketBinary.java @@ -0,0 +1,65 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ + +package com.ibm.websphere.samples.daytrader.web.prims; + +import java.io.IOException; +import java.nio.ByteBuffer; + +import javax.websocket.CloseReason; +import javax.websocket.EndpointConfig; +import javax.websocket.OnClose; +import javax.websocket.OnError; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +/** This class a simple websocket that echos the binary it has been sent. */ + +@ServerEndpoint(value = "/pingBinary") +public class PingWebSocketBinary { + + private Session currentSession = null; + + @OnOpen + public void onOpen(final Session session, EndpointConfig ec) { + currentSession = session; + } + + @OnMessage + public void ping(ByteBuffer data) { + currentSession.getAsyncRemote().sendBinary(data); + } + + @OnError + public void onError(Throwable t) { + t.printStackTrace(); + } + + @OnClose + public void onClose(Session session, CloseReason reason) { + + try { + if (session.isOpen()) { + session.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingWebSocketJson.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingWebSocketJson.java new file mode 100644 index 00000000..fd0ab76f --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingWebSocketJson.java @@ -0,0 +1,116 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ + +package com.ibm.websphere.samples.daytrader.web.prims; + +import java.io.IOException; + +import javax.enterprise.concurrent.ManagedThreadFactory; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import javax.websocket.CloseReason; +import javax.websocket.EndpointConfig; +import javax.websocket.OnClose; +import javax.websocket.OnError; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +import com.ibm.websphere.samples.daytrader.web.websocket.JsonDecoder; +import com.ibm.websphere.samples.daytrader.web.websocket.JsonEncoder; +import com.ibm.websphere.samples.daytrader.web.websocket.JsonMessage; + +/** This class a simple websocket that sends the number of times it has been pinged. */ + +@ServerEndpoint(value = "/pingWebSocketJson",encoders=JsonEncoder.class ,decoders=JsonDecoder.class) +public class PingWebSocketJson { + + private Session currentSession = null; + private Integer sentHitCount = null; + private Integer receivedHitCount = null; + + @OnOpen + public void onOpen(final Session session, EndpointConfig ec) { + currentSession = session; + sentHitCount = 0; + receivedHitCount = 0; + + + InitialContext context; + ManagedThreadFactory mtf = null; + + try { + context = new InitialContext(); + mtf = (ManagedThreadFactory) context.lookup("java:comp/DefaultManagedThreadFactory"); + + } catch (NamingException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + + Thread thread = mtf.newThread(new Runnable() { + + @Override + public void run() { + + try { + + Thread.sleep(500); + + while (currentSession.isOpen()) { + sentHitCount++; + + JsonMessage response = new JsonMessage(); + response.setKey("sentHitCount"); + response.setValue(sentHitCount.toString()); + currentSession.getAsyncRemote().sendObject(response); + + Thread.sleep(100); + } + + + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + }); + + thread.start(); + + } + + @OnMessage + public void ping(JsonMessage message) throws IOException { + receivedHitCount++; + JsonMessage response = new JsonMessage(); + response.setKey("receivedHitCount"); + response.setValue(receivedHitCount.toString()); + currentSession.getAsyncRemote().sendObject(response); + } + + @OnError + public void onError(Throwable t) { + t.printStackTrace(); + } + + @OnClose + public void onClose(Session session, CloseReason reason) { + + } + +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingWebSocketTextAsync.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingWebSocketTextAsync.java new file mode 100644 index 00000000..90d8350d --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingWebSocketTextAsync.java @@ -0,0 +1,70 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims; + +import javax.websocket.CloseReason; +import javax.websocket.EndpointConfig; +import javax.websocket.OnClose; +import javax.websocket.OnError; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.SendHandler; +import javax.websocket.SendResult; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +/** This class a simple websocket that sends the number of times it has been pinged. */ + +@ServerEndpoint(value = "/pingTextAsync") +public class PingWebSocketTextAsync { + + private Session currentSession = null; + private Integer hitCount = null; + + @OnOpen + public void onOpen(final Session session, EndpointConfig ec) { + currentSession = session; + hitCount = 0; + } + + @OnMessage + public void ping(String text) { + + + hitCount++; + currentSession.getAsyncRemote().sendText(hitCount.toString(), new SendHandler() { + + @Override + public void onResult(SendResult result) { + if (!result.isOK()) { + System.out.println("NOT OK"); + } + } + } + ); + } + + @OnError + public void onError(Throwable t) { + t.printStackTrace(); + } + + @OnClose + public void onClose(Session session, CloseReason reason) { + + } + +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingWebSocketTextSync.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingWebSocketTextSync.java new file mode 100644 index 00000000..facdbcc6 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/PingWebSocketTextSync.java @@ -0,0 +1,67 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims; + +import java.io.IOException; +//import java.util.Collections; +//import java.util.HashSet; +//import java.util.Set; + +import javax.websocket.CloseReason; +import javax.websocket.EndpointConfig; +import javax.websocket.OnClose; +import javax.websocket.OnError; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +/** This class a simple websocket that sends the number of times it has been pinged. */ + +@ServerEndpoint(value = "/pingTextSync") +public class PingWebSocketTextSync { + + private Session currentSession = null; + private Integer hitCount = null; + + @OnOpen + public void onOpen(final Session session, EndpointConfig ec) { + currentSession = session; + hitCount = 0; + } + + @OnMessage + public void ping(String text) { + hitCount++; + + try { + currentSession.getBasicRemote().sendText(hitCount.toString()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @OnError + public void onError(Throwable t) { + t.printStackTrace(); + } + + @OnClose + public void onClose(Session session, CloseReason reason) { + + } + +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/beanval/CDIMethodConstraintBean.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/beanval/CDIMethodConstraintBean.java new file mode 100644 index 00000000..755014a3 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/beanval/CDIMethodConstraintBean.java @@ -0,0 +1,47 @@ +/** + * (C) Copyright IBM Corporation 2019. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.beanval; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +import javax.enterprise.context.RequestScoped; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.PastOrPresent; +import javax.validation.constraints.Size; + +@RequestScoped +public class CDIMethodConstraintBean { + + private static int hitCount = 0; + private List list = new ArrayList<>(); + + // Dumb primitive, beanval checks that the date passed in is valid and that the + // return is > 0; + @Min(1) + public int getHitCount(@NotNull @PastOrPresent LocalDateTime now) { + list.add(++hitCount); + return hitCount; + } + + @Size(max=1) + public List<@Min(1) Integer> hitList() { + return list; + } + +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/beanval/PingServletBeanValCDI.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/beanval/PingServletBeanValCDI.java new file mode 100644 index 00000000..e9654526 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/beanval/PingServletBeanValCDI.java @@ -0,0 +1,107 @@ +/** + * (C) Copyright IBM Corporation 2019. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.beanval; + +import java.io.IOException; +import java.time.LocalDateTime; + +import javax.inject.Inject; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ibm.websphere.samples.daytrader.util.Log; + +@WebServlet(name = "PingServletBeanValCDI", urlPatterns = { "/servlet/PingServletBeanValCDI" }) +public class PingServletBeanValCDI extends HttpServlet { + + @Inject CDIMethodConstraintBean hitCountBean; + + private static final long serialVersionUID = 7097023236709683760L; + private static LocalDateTime initTime; + + + /** + * forwards post requests to the doGet method Creation date: (11/6/2000 + * 10:52:39 AM) + * + * @param res + * javax.servlet.http.HttpServletRequest + * @param res2 + * javax.servlet.http.HttpServletResponse + */ + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + /** + * this is the main method of the servlet that will service all get + * requests. + * + * @param request + * HttpServletRequest + * @param responce + * HttpServletResponce + **/ + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + try { + res.setContentType("text/html"); + + ServletOutputStream out = res.getOutputStream(); + + int currentHitCount = hitCountBean.getHitCount(initTime); + hitCountBean.hitList(); + + out.println("Ping Servlet Bean Validation CDI" + + "

    Ping Servlet Bean Validation CDI
    Init time : " + initTime + + "

    Hit Count: " + currentHitCount + ""); + } catch (Exception e) { + Log.error(e, "PingServlet.doGet(...): general exception caught"); + res.sendError(500, e.toString()); + + } + } + + /** + * returns a string of information about the servlet + * + * @return info String: contains info about the servlet + **/ + @Override + public String getServletInfo() { + return "Basic dynamic HTML generation through a servlet"; + } + + /** + * called when the class is loaded to initialize the servlet + * + * @param config + * ServletConfig: + **/ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + initTime = LocalDateTime.now(); + + + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/beanval/PingServletBeanValSimple1.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/beanval/PingServletBeanValSimple1.java new file mode 100644 index 00000000..a137556e --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/beanval/PingServletBeanValSimple1.java @@ -0,0 +1,106 @@ +/** + * (C) Copyright IBM Corporation 2019. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.beanval; + +import java.io.IOException; +import java.time.LocalDateTime; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ibm.websphere.samples.daytrader.util.Log; + +@WebServlet(name = "PingServletBeanValSimple1", urlPatterns = { "/servlet/PingServletBeanValSimple1" }) +public class PingServletBeanValSimple1 extends HttpServlet { + + private static final long serialVersionUID = 7097023236709683760L; + private static LocalDateTime initTime; + private static int hitCount = 0; + + + /** + * forwards post requests to the doGet method Creation date: (11/6/2000 + * 10:52:39 AM) + * + * @param res + * javax.servlet.http.HttpServletRequest + * @param res2 + * javax.servlet.http.HttpServletResponse + */ + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + /** + * this is the main method of the servlet that will service all get + * requests. + * + * @param request + * HttpServletRequest + * @param responce + * HttpServletResponce + **/ + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + try { + res.setContentType("text/html"); + + SimpleBean1 simpleBean1 = new SimpleBean1(); + simpleBean1.checkInjectionValidation(); + + ServletOutputStream out = res.getOutputStream(); + + int currentHitCount = ++hitCount; + out.println("Ping Servlet Bean Validation Simple" + + "

    Ping Servlet Bean Validation Simple
    Init time : " + initTime + + "

    Hit Count: " + currentHitCount + ""); + } catch (Exception e) { + Log.error(e, "PingServlet.doGet(...): general exception caught"); + res.sendError(500, e.toString()); + + } + } + + /** + * returns a string of information about the servlet + * + * @return info String: contains info about the servlet + **/ + @Override + public String getServletInfo() { + return "Basic dynamic HTML generation through a servlet"; + } + + /** + * called when the class is loaded to initialize the servlet + * + * @param config + * ServletConfig: + **/ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + initTime = LocalDateTime.now(); + + + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/beanval/PingServletBeanValSimple2.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/beanval/PingServletBeanValSimple2.java new file mode 100644 index 00000000..7bbc238b --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/beanval/PingServletBeanValSimple2.java @@ -0,0 +1,106 @@ +/** + * (C) Copyright IBM Corporation 2019. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.beanval; + +import java.io.IOException; +import java.time.LocalDateTime; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ibm.websphere.samples.daytrader.util.Log; + +@WebServlet(name = "PingServletBeanValSimple2", urlPatterns = { "/servlet/PingServletBeanValSimple2" }) +public class PingServletBeanValSimple2 extends HttpServlet { + + private static final long serialVersionUID = 7097023236709683760L; + private static LocalDateTime initTime; + private static int hitCount = 0; + + + /** + * forwards post requests to the doGet method Creation date: (11/6/2000 + * 10:52:39 AM) + * + * @param res + * javax.servlet.http.HttpServletRequest + * @param res2 + * javax.servlet.http.HttpServletResponse + */ + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + /** + * this is the main method of the servlet that will service all get + * requests. + * + * @param request + * HttpServletRequest + * @param responce + * HttpServletResponce + **/ + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + try { + res.setContentType("text/html"); + + SimpleBean2 simpleBean2 = new SimpleBean2(); + simpleBean2.checkInjectionValidation(); + + ServletOutputStream out = res.getOutputStream(); + + int currentHitCount = ++hitCount; + out.println("Ping Servlet Bean Validation Simple" + + "

    Ping Servlet Bean Validation Simple
    Init time : " + initTime + + "

    Hit Count: " + currentHitCount + ""); + } catch (Exception e) { + Log.error(e, "PingServlet.doGet(...): general exception caught"); + res.sendError(500, e.toString()); + + } + } + + /** + * returns a string of information about the servlet + * + * @return info String: contains info about the servlet + **/ + @Override + public String getServletInfo() { + return "Basic dynamic HTML generation through a servlet"; + } + + /** + * called when the class is loaded to initialize the servlet + * + * @param config + * ServletConfig: + **/ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + initTime = LocalDateTime.now(); + + + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/beanval/SimpleBean1.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/beanval/SimpleBean1.java new file mode 100644 index 00000000..6ac7752d --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/beanval/SimpleBean1.java @@ -0,0 +1,116 @@ +/** + * (C) Copyright IBM Corporation 2019. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.beanval; + +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.validation.ConstraintViolation; +import javax.validation.Validator; +import javax.validation.ValidatorFactory; +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; +import javax.validation.constraints.Size; + +public class SimpleBean1 { + /** + * Logging support and the static initializer for this class. Used to trace file + * version information. This will display the current version of the class in the + * debug log at the time the class is loaded. + */ + private static final String thisClass = SimpleBean1.class.getName(); + private static Logger traceLogger = Logger.getLogger(thisClass); + private static ValidatorFactory validatorFactory = null; + private Validator validator; + + @Min(1) + int iMin = 1; + @Max(1) + Integer iMax = 1; + @Size(min = 1) + int[] iMinArray = { 1 }; + @Size(max = 1) + Integer[] iMaxArray = { 1 }; + @Pattern(regexp = "[a-z][a-z]*", message = "go to your room!") + String pattern = "mypattern"; + + + + boolean setToFail = false; + + + + public SimpleBean1() throws Exception { + if (validatorFactory == null) { + Context nContext = new InitialContext(); + validatorFactory = (ValidatorFactory) nContext.lookup("java:comp/ValidatorFactory"); + + } + validator = validatorFactory.getValidator(); + } + + @NotNull + public String getDesc() { + return pattern; + } + + public void checkInjectionValidation() { + + traceLogger.entering(thisClass, "checkInjectionValidation", this); + + Set> cvSet = validator.validate(this); + + if (!cvSet.isEmpty()) { + String msg = formatConstraintViolations(cvSet); + traceLogger.log(Level.INFO, "Some reason cvSet was not null: " + cvSet + ", " + msg); + + throw new IllegalStateException("validation should not have found constraints: " + msg); + } + + traceLogger.exiting(thisClass, "checkInjectionValidation "); + } + + + @Override + public String toString() { + String result = "iMin:" + iMin + " iMax:" + iMax + " iMinArray:" + iMinArray + " iMaxArray:" + iMaxArray + " pattern:" + pattern + + " setToFail:" + setToFail; + + return result; + } + + /** + * Convert the constraint violations for use within WAS diagnostic logs. + * + * @return a String representation of the constraint violations formatted one per line and uniformly indented. + */ + public String formatConstraintViolations(Set> cvSet) { + traceLogger.entering(thisClass, "formatConstraintViolations " + cvSet); + + StringBuffer msg = new StringBuffer(); + for (ConstraintViolation cv : cvSet) { + msg.append("\n\t" + cv.toString()); + } + + traceLogger.exiting(thisClass, "formatConstraintViolations " + msg); + return msg.toString(); + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/beanval/SimpleBean2.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/beanval/SimpleBean2.java new file mode 100644 index 00000000..a899e8d2 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/beanval/SimpleBean2.java @@ -0,0 +1,47 @@ +/** + * (C) Copyright IBM Corporation 2019. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.beanval; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +import javax.validation.constraints.PositiveOrZero; +import javax.validation.constraints.FutureOrPresent; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.PastOrPresent; + +public class SimpleBean2 extends SimpleBean1 { + + private List<@PositiveOrZero Integer> numbers= new ArrayList(); + private List<@NotBlank String> strings = new ArrayList(); + + @PastOrPresent + LocalDateTime now = LocalDateTime.now(); + + @FutureOrPresent + LocalDateTime future = LocalDateTime.now().plusDays(1); + + public SimpleBean2() throws Exception { + super(); + + numbers.add(1); + numbers.add(2); + + strings.add("string1"); + strings.add("string2"); + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/CDIEventProducer.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/CDIEventProducer.java new file mode 100644 index 00000000..ef99073d --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/CDIEventProducer.java @@ -0,0 +1,49 @@ +/** + * (C) Copyright IBM Corporation 2019. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.cdi; + +import javax.annotation.Resource; +import javax.enterprise.concurrent.ManagedExecutorService; +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.event.Event; +import javax.enterprise.event.NotificationOptions; +import javax.inject.Inject; + +@ApplicationScoped //? +public class CDIEventProducer { + + @Resource + private ManagedExecutorService mes; + + @Inject + @Hit + Event hitCountEvent; + + @Inject + @HitAsync + Event hitCountEventAsync; + + public void produceSyncEvent() { + hitCountEvent.fire("hitCount++"); + } + + public void produceAsyncEvent() { + hitCountEventAsync.fireAsync("hitCount++", NotificationOptions.builder().setExecutor(mes).build()); + } + + + +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/Hit.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/Hit.java new file mode 100644 index 00000000..6eb830a3 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/Hit.java @@ -0,0 +1,29 @@ +/** + * (C) Copyright IBM Corporation 2019. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.cdi; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.inject.Qualifier; + +@Qualifier +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE}) +public @interface Hit { +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/HitAsync.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/HitAsync.java new file mode 100644 index 00000000..addca624 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/HitAsync.java @@ -0,0 +1,29 @@ +/** + * (C) Copyright IBM Corporation 2019. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.cdi; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.inject.Qualifier; + +@Qualifier +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE}) +public @interface HitAsync { +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingCDIBean.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingCDIBean.java new file mode 100755 index 00000000..43e5a735 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingCDIBean.java @@ -0,0 +1,59 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.cdi; + +import java.util.Set; + +import javax.enterprise.context.RequestScoped; +import javax.enterprise.inject.spi.Bean; +import javax.enterprise.inject.spi.BeanManager; +import javax.enterprise.inject.spi.CDI; +import javax.naming.InitialContext; + +@RequestScoped +@PingInterceptorBinding +public class PingCDIBean { + + private static int helloHitCount = 0; + private static int getBeanManagerHitCountJNDI = 0; + private static int getBeanManagerHitCountSPI = 0; + + + public int hello() { + return ++helloHitCount; + } + + public int getBeanMangerViaJNDI() throws Exception { + BeanManager beanManager = (BeanManager) new InitialContext().lookup("java:comp/BeanManager"); + Set> beans = beanManager.getBeans(Object.class); + if (beans.size() > 0) { + return ++getBeanManagerHitCountJNDI; + } + return 0; + + } + + public int getBeanMangerViaCDICurrent() throws Exception { + BeanManager beanManager = CDI.current().getBeanManager(); + Set> beans = beanManager.getBeans(Object.class); + + if (beans.size() > 0) { + return ++getBeanManagerHitCountSPI; + } + return 0; + + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingCDIJSFBean.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingCDIJSFBean.java new file mode 100755 index 00000000..e618788c --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingCDIJSFBean.java @@ -0,0 +1,33 @@ +/** + * (C) Copyright IBM Corporation 2016. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.cdi; + +import java.io.Serializable; + +import javax.enterprise.context.SessionScoped; +import javax.inject.Named; + +@Named +@SessionScoped +public class PingCDIJSFBean implements Serializable { + + private static final long serialVersionUID = -7475815494313679416L; + private int hitCount = 0; + + public int getHitCount() { + return ++hitCount; + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingEJBIFace.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingEJBIFace.java new file mode 100755 index 00000000..28bd563f --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingEJBIFace.java @@ -0,0 +1,24 @@ +/** + * (C) Copyright IBM Corporation 2016. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.cdi; + +/** + * EJB interface + */ +public interface PingEJBIFace { + + public String getMsg(); +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingEJBLocal.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingEJBLocal.java new file mode 100755 index 00000000..d9bf999b --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingEJBLocal.java @@ -0,0 +1,41 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.cdi; + +import javax.ejb.Local; +import javax.ejb.Stateful; + +/** + * + */ +@Stateful +@Local +public class PingEJBLocal implements PingEJBIFace { + + private static int hitCount; + + /* + * (non-Javadoc) + * + * @see com.ibm.websphere.samples.daytrader.web.prims.EJBIFace#getMsg() + */ + @Override + public String getMsg() { + + return "PingEJBLocal: " + hitCount++; + } + +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingEJBLocalDecorator.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingEJBLocalDecorator.java new file mode 100755 index 00000000..dcfb07ba --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingEJBLocalDecorator.java @@ -0,0 +1,43 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.cdi; + +import javax.annotation.Priority; +import javax.decorator.Decorator; +import javax.decorator.Delegate; +import javax.inject.Inject; +import javax.interceptor.Interceptor; + +@Decorator +@Priority(Interceptor.Priority.APPLICATION) +public class PingEJBLocalDecorator implements PingEJBIFace { + + /* + * (non-Javadoc) + * + * @see com.ibm.websphere.samples.daytrader.web.prims.EJBIFace#getMsg() + */ + @Delegate + @Inject + PingEJBIFace ejb; + + @Override + public String getMsg() { + + return "Decorated " + ejb.getMsg(); + } + +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingInterceptor.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingInterceptor.java new file mode 100755 index 00000000..dcc99693 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingInterceptor.java @@ -0,0 +1,42 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.cdi; + +import java.io.Serializable; + +import javax.annotation.Priority; +import javax.interceptor.AroundInvoke; +import javax.interceptor.Interceptor; +import javax.interceptor.InvocationContext; + +/** + * + */ +@PingInterceptorBinding +@Interceptor +@Priority(Interceptor.Priority.APPLICATION) +public class PingInterceptor implements Serializable { + + /** */ + private static final long serialVersionUID = 1L; + + @AroundInvoke + public Object methodInterceptor(InvocationContext ctx) throws Exception { + + //noop + return ctx.proceed(); + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingInterceptorBinding.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingInterceptorBinding.java new file mode 100755 index 00000000..240b7b2c --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingInterceptorBinding.java @@ -0,0 +1,33 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.cdi; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.interceptor.InterceptorBinding; + +/** + * + */ +@InterceptorBinding +@Target({ ElementType.TYPE, ElementType.CONSTRUCTOR }) +@Retention(RetentionPolicy.RUNTIME) +public @interface PingInterceptorBinding { + +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingServletCDI.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingServletCDI.java new file mode 100755 index 00000000..9696465a --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingServletCDI.java @@ -0,0 +1,70 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.cdi; + +import java.io.IOException; +import java.io.PrintWriter; + +import javax.ejb.EJB; +import javax.inject.Inject; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@WebServlet("/servlet/PingServletCDI") +public class PingServletCDI extends HttpServlet { + + private static final long serialVersionUID = -1803544618879689949L; + private static String initTime; + + @Inject + PingCDIBean cdiBean; + + @EJB + PingEJBIFace ejb; + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { + + PrintWriter pw = response.getWriter(); + pw.write("Ping Servlet CDI" + + "

    Ping Servlet CDI
    Init time : " + initTime + + "

    "); + + pw.write("hitCount: " + cdiBean.hello() + "
    "); + pw.write("hitCount: " + ejb.getMsg() + "
    "); + + pw.flush(); + pw.close(); + + } + + /** + * called when the class is loaded to initialize the servlet + * + * @param config + * ServletConfig: + **/ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + initTime = new java.util.Date().toString(); + + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingServletCDIBeanManagerViaCDICurrent.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingServletCDIBeanManagerViaCDICurrent.java new file mode 100644 index 00000000..b4292e9e --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingServletCDIBeanManagerViaCDICurrent.java @@ -0,0 +1,71 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.cdi; + +import java.io.IOException; +import java.io.PrintWriter; + +import javax.inject.Inject; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@WebServlet("/servlet/PingServletCDIBeanManagerViaCDICurrent") +public class PingServletCDIBeanManagerViaCDICurrent extends HttpServlet { + + private static final long serialVersionUID = -1803544618879689949L; + private static String initTime; + + @Inject + PingCDIBean cdiBean; + + + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { + + PrintWriter pw = response.getWriter(); + pw.write("Ping Servlet CDI Bean Manager" + + "

    Ping Servlet CDI Bean Manager
    Init time : " + initTime + + "

    "); + + try { + pw.write("hitCount: " + cdiBean.getBeanMangerViaCDICurrent() + ""); + } catch (Exception e) { + e.printStackTrace(); + } + + pw.flush(); + pw.close(); + + } + + /** + * called when the class is loaded to initialize the servlet + * + * @param config + * ServletConfig: + **/ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + initTime = new java.util.Date().toString(); + + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingServletCDIBeanManagerViaJNDI.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingServletCDIBeanManagerViaJNDI.java new file mode 100755 index 00000000..5ce3d914 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingServletCDIBeanManagerViaJNDI.java @@ -0,0 +1,71 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.cdi; + +import java.io.IOException; +import java.io.PrintWriter; + +import javax.inject.Inject; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@WebServlet("/servlet/PingServletCDIBeanManagerViaJNDI") +public class PingServletCDIBeanManagerViaJNDI extends HttpServlet { + + private static final long serialVersionUID = -1803544618879689949L; + private static String initTime; + + @Inject + PingCDIBean cdiBean; + + + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { + + PrintWriter pw = response.getWriter(); + pw.write("Ping Servlet CDI Bean Manager" + + "

    Ping Servlet CDI Bean Manager
    Init time : " + initTime + + "

    "); + + try { + pw.write("hitCount: " + cdiBean.getBeanMangerViaJNDI() + ""); + } catch (Exception e) { + e.printStackTrace(); + } + + pw.flush(); + pw.close(); + + } + + /** + * called when the class is loaded to initialize the servlet + * + * @param config + * ServletConfig: + **/ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + initTime = new java.util.Date().toString(); + + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingServletCDIEvent.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingServletCDIEvent.java new file mode 100644 index 00000000..9838dc33 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingServletCDIEvent.java @@ -0,0 +1,80 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.cdi; + +import java.io.IOException; +import java.io.PrintWriter; + +import javax.enterprise.event.Observes; +import javax.inject.Inject; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + + +@WebServlet("/servlet/PingServletCDIEvent") +public class PingServletCDIEvent extends HttpServlet { + + private static final long serialVersionUID = -1803544618879689949L; + private static String initTime; + private static int hitCount; + + @Inject + CDIEventProducer cdiEventProducer; + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { + + cdiEventProducer.produceSyncEvent(); + + PrintWriter pw = response.getWriter(); + pw.write("Ping Servlet CDI Event" + + "

    Ping Servlet CDI Event
    Init time : " + initTime + + "

    "); + + try { + pw.write("hitCount1: " + hitCount + ""); + } catch (Exception e) { + e.printStackTrace(); + } + + pw.flush(); + pw.close(); + } + + /** + * called when the class is loaded to initialize the servlet + * + * @param config + * ServletConfig: + **/ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + initTime = new java.util.Date().toString(); + hitCount = 0; + + } + + public void onEvent(@Observes @Hit String event) { + hitCount++; + } +} + diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingServletCDIEventAsync.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingServletCDIEventAsync.java new file mode 100644 index 00000000..4a1b8b06 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/cdi/PingServletCDIEventAsync.java @@ -0,0 +1,90 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.cdi; + +import java.io.IOException; +import java.io.PrintWriter; + +import javax.annotation.Priority; +import javax.enterprise.event.ObservesAsync; +import javax.inject.Inject; +import javax.interceptor.Interceptor; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ibm.websphere.samples.daytrader.util.Log; + +@WebServlet("/servlet/PingServletCDIEventAsync") +public class PingServletCDIEventAsync extends HttpServlet { + + private static final long serialVersionUID = -1803544618879689949L; + private static String initTime; + private static int hitCount1; + private static int hitCount2; + + @Inject + CDIEventProducer cdiEventProducer; + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { + + cdiEventProducer.produceAsyncEvent(); + + PrintWriter pw = response.getWriter(); + pw.write("Ping Servlet CDI Event Async" + + "

    Ping Servlet CDI Event Async
    Init time : " + initTime + + "

    "); + + try { + pw.write("hitCount1: " + hitCount1 + "
    hitCount2: " + hitCount2 + ""); + } catch (Exception e) { + e.printStackTrace(); + } + + pw.flush(); + pw.close(); + } + + /** + * called when the class is loaded to initialize the servlet + * + * @param config + * ServletConfig: + **/ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + initTime = new java.util.Date().toString(); + hitCount1 = 0; + hitCount2 = 0; + } + + public void onAsyncEvent1(@ObservesAsync @Priority(Interceptor.Priority.APPLICATION) @HitAsync String event) { + hitCount1++; + } + + public void onAsyncEvent2(@ObservesAsync @Priority(Interceptor.Priority.APPLICATION + 1) @HitAsync String event) { + if (hitCount1 <= hitCount2 ) { + Log.error("Priority Error");; + } + hitCount2++; + } +} + diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/drive/PingServletDrive.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/drive/PingServletDrive.java new file mode 100644 index 00000000..5420b38e --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/drive/PingServletDrive.java @@ -0,0 +1,112 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.drive; + +import java.io.IOException; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ibm.websphere.samples.daytrader.util.Log; + +/** + * + * PingServlet tests fundamental dynamic HTML creation functionality through + * server side servlet processing. + * + */ + +@WebServlet(name = "PingServletDrive", urlPatterns = { "/drive/PingServlet" }) +public class PingServletDrive extends HttpServlet { + + private static final long serialVersionUID = 7097023236709683760L; + private static String initTime; + private static int hitCount; + + /** + * forwards post requests to the doGet method Creation date: (11/6/2000 + * 10:52:39 AM) + * + * @param res + * javax.servlet.http.HttpServletRequest + * @param res2 + * javax.servlet.http.HttpServletResponse + */ + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + /** + * this is the main method of the servlet that will service all get + * requests. + * + * @param request + * HttpServletRequest + * @param responce + * HttpServletResponce + **/ + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + try { + res.setContentType("text/html"); + + // The following 2 lines are the difference between PingServlet and + // PingServletWriter + // the latter uses a PrintWriter for output versus a binary output + // stream. + ServletOutputStream out = res.getOutputStream(); + // java.io.PrintWriter out = res.getWriter(); + hitCount++; + out.println("Ping Servlet" + + "

    Ping Servlet
    Init time : " + initTime + + "

    Hit Count: " + hitCount + ""); + } catch (Exception e) { + Log.error(e, "PingServlet.doGet(...): general exception caught"); + res.sendError(500, e.toString()); + + } + } + + /** + * returns a string of information about the servlet + * + * @return info String: contains info about the servlet + **/ + @Override + public String getServletInfo() { + return "Basic dynamic HTML generation through a servlet"; + } + + /** + * called when the class is loaded to initialize the servlet + * + * @param config + * ServletConfig: + **/ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + initTime = new java.util.Date().toString(); + hitCount = 0; + + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2Entity.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2Entity.java new file mode 100644 index 00000000..79dfc3d8 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2Entity.java @@ -0,0 +1,114 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.ejb3; + +import java.io.IOException; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ibm.websphere.samples.daytrader.entities.QuoteDataBean; +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; + +/** + * + * Primitive designed to run within the TradeApplication and makes use of + * {@link trade_client.TradeConfig} for config parameters and random stock + * symbols. Servlet will generate a random stock symbol and get the price of + * that symbol using a {@link trade.Quote} Entity EJB This tests the common path + * of a Servlet calling an Entity EJB to get data + * + */ + +@WebServlet(name = "ejb3.PingServlet2Entity", urlPatterns = { "/ejb3/PingServlet2Entity" }) +public class PingServlet2Entity extends HttpServlet { + private static final long serialVersionUID = -9004026114063894842L; + + private static String initTime; + + private static int hitCount; + + @PersistenceContext(unitName = "daytrader") + private EntityManager em; + + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { + + res.setContentType("text/html"); + java.io.PrintWriter out = res.getWriter(); + + QuoteDataBean quote = null; + String symbol = null; + + StringBuffer output = new StringBuffer(100); + output.append("Servlet2Entity" + "
    PingServlet2Entity
    " + + "
    PingServlet2Entity accesses an EntityManager" + + " using a PersistenceContext annotaion and then gets the price of a random symbol (generated by TradeConfig)" + + " through the EntityManager find method"); + try { + // generate random symbol + try { + int iter = TradeConfig.getPrimIterations(); + for (int ii = 0; ii < iter; ii++) { + // get a random symbol to look up and get the key to that + // symbol. + symbol = TradeConfig.rndSymbol(); + // find the EntityInstance. + quote = em.find(QuoteDataBean.class, symbol); + } + } catch (Exception e) { + Log.error("web_primtv.PingServlet2Entity.doGet(...): error performing find"); + throw e; + } + // get the price and print the output. + + output.append("
    initTime: " + initTime + "
    Hit Count: ").append(hitCount++); + output.append("
    Quote Information

    " + quote.toHTML()); + output.append("

    "); + out.println(output.toString()); + } catch (Exception e) { + Log.error(e, "PingServlet2Entity.doGet(...): error"); + // this will send an Error to teh web applications defined error + // page. + res.sendError(500, "PingServlet2Entity.doGet(...): error" + e.toString()); + + } + } + + @Override + public String getServletInfo() { + return "web primitive, tests Servlet to Entity EJB path"; + } + + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + hitCount = 0; + initTime = new java.util.Date().toString(); + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2MDBQueue.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2MDBQueue.java new file mode 100644 index 00000000..c1941f86 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2MDBQueue.java @@ -0,0 +1,147 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.ejb3; + +import java.io.IOException; + +import javax.annotation.Resource; +import javax.jms.Connection; +import javax.jms.ConnectionFactory; +import javax.jms.JMSContext; +import javax.jms.Queue; +import javax.jms.TextMessage; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; + +/** + * This primitive is designed to run inside the TradeApplication and relies upon + * the {@link com.ibm.websphere.samples.daytrader.util.TradeConfig} class to set + * configuration parameters. PingServlet2MDBQueue tests key functionality of a + * servlet call to a post a message to an MDB Queue. The TradeBrokerMDB receives + * the message This servlet makes use of the MDB EJB + * {@link com.ibm.websphere.samples.daytrader.ejb3.DTBroker3MDB} by posting a + * message to the MDB Queue + */ +@WebServlet(name = "ejb3.PingServlet2MDBQueue", urlPatterns = { "/ejb3/PingServlet2MDBQueue" }) +public class PingServlet2MDBQueue extends HttpServlet { + + private static final long serialVersionUID = 2637271552188745216L; + + private static String initTime; + + private static int hitCount; + + @Resource(name = "jms/QueueConnectionFactory", authenticationType = javax.annotation.Resource.AuthenticationType.APPLICATION) + private ConnectionFactory queueConnectionFactory; + + // TODO: Glassfish does not like this - change to lookup? + @Resource(name = "jms/TradeBrokerQueue") + private Queue tradeBrokerQueue; + + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { + + res.setContentType("text/html"); + java.io.PrintWriter out = res.getWriter(); + // use a stringbuffer to avoid concatenation of Strings + StringBuffer output = new StringBuffer(100); + output.append("PingServlet2MDBQueue" + + "
    PingServlet2MDBQueue
    " + "" + + "Tests the basic operation of a servlet posting a message to an EJB MDB through a JMS Queue.
    " + + "Note: Not intended for performance testing."); + + try { + Connection conn = queueConnectionFactory.createConnection(); + + try { + TextMessage message = null; + int iter = TradeConfig.getPrimIterations(); + for (int ii = 0; ii < iter; ii++) { + /*Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); + try { + MessageProducer producer = sess.createProducer(tradeBrokerQueue); + + message = sess.createTextMessage(); + + String command = "ping"; + message.setStringProperty("command", command); + message.setLongProperty("publishTime", System.currentTimeMillis()); + message.setText("Ping message for queue java:comp/env/jms/TradeBrokerQueue sent from PingServlet2MDBQueue at " + new java.util.Date()); + producer.send(message); + } finally { + sess.close(); + }*/ + + JMSContext context = queueConnectionFactory.createContext(); + + message = context.createTextMessage(); + + message.setStringProperty("command", "ping"); + message.setLongProperty("publishTime", System.currentTimeMillis()); + message.setText("Ping message for queue java:comp/env/jms/TradeBrokerQueue sent from PingServlet2MDBQueue at " + new java.util.Date()); + + context.createProducer().send(tradeBrokerQueue, message); + } + + // write out the output + output.append("
    initTime: ").append(initTime); + output.append("
    Hit Count: ").append(hitCount++); + output.append("
    Posted Text message to java:comp/env/jms/TradeBrokerQueue destination"); + output.append("
    Message: ").append(message); + output.append("

    Message text: ").append(message.getText()); + output.append("

    "); + out.println(output.toString()); + + } catch (Exception e) { + Log.error("PingServlet2MDBQueue.doGet(...):exception posting message to TradeBrokerQueue destination "); + throw e; + } finally { + conn.close(); + } + } // this is where I actually handle the exceptions + catch (Exception e) { + Log.error(e, "PingServlet2MDBQueue.doGet(...): error"); + res.sendError(500, "PingServlet2MDBQueue.doGet(...): error, " + e.toString()); + + } + } + + @Override + public String getServletInfo() { + return "web primitive, configured with trade runtime configs, tests Servlet to Session EJB path"; + + } + + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + hitCount = 0; + initTime = new java.util.Date().toString(); + } + +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2MDBTopic.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2MDBTopic.java new file mode 100644 index 00000000..722cab74 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2MDBTopic.java @@ -0,0 +1,148 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.ejb3; + +import java.io.IOException; + +import javax.annotation.Resource; +import javax.jms.Connection; +import javax.jms.ConnectionFactory; +import javax.jms.JMSContext; +import javax.jms.TextMessage; +import javax.jms.Topic; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; + +/** + * This primitive is designed to run inside the TradeApplication and relies upon + * the {@link com.ibm.websphere.samples.daytrader.util.TradeConfig} class to set + * configuration parameters. PingServlet2MDBQueue tests key functionality of a + * servlet call to a post a message to an MDB Topic. The TradeStreamerMDB (and + * any other subscribers) receives the message This servlet makes use of the MDB + * EJB {@link com.ibm.websphere.samples.daytrader.ejb3.DTStreamer3MDB} by + * posting a message to the MDB Topic + */ +@WebServlet(name = "ejb3.PingServlet2MDBTopic", urlPatterns = { "/ejb3/PingServlet2MDBTopic" }) +public class PingServlet2MDBTopic extends HttpServlet { + + private static final long serialVersionUID = 5925470158886928225L; + + private static String initTime; + + private static int hitCount; + + @Resource(name = "jms/TopicConnectionFactory", authenticationType = javax.annotation.Resource.AuthenticationType.APPLICATION) + private ConnectionFactory topicConnectionFactory; + + // TODO: Glassfish does not like this - change to lookup? + @Resource(name = "jms/TradeStreamerTopic") + private Topic tradeStreamerTopic; + + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { + + res.setContentType("text/html"); + java.io.PrintWriter out = res.getWriter(); + // use a stringbuffer to avoid concatenation of Strings + StringBuffer output = new StringBuffer(100); + output.append("PingServlet2MDBTopic" + + "
    PingServlet2MDBTopic
    " + "" + + "Tests the basic operation of a servlet posting a message to an EJB MDB (and other subscribers) through a JMS Topic.
    " + + "Note: Not intended for performance testing."); + + // we only want to look up the JMS resources once + try { + + Connection conn = topicConnectionFactory.createConnection(); + + try { + TextMessage message = null; + int iter = TradeConfig.getPrimIterations(); + for (int ii = 0; ii < iter; ii++) { + /*Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); + try { + MessageProducer producer = sess.createProducer(tradeStreamerTopic); + message = sess.createTextMessage(); + + String command = "ping"; + message.setStringProperty("command", command); + message.setLongProperty("publishTime", System.currentTimeMillis()); + message.setText("Ping message for topic java:comp/env/jms/TradeStreamerTopic sent from PingServlet2MDBTopic at " + new java.util.Date()); + + producer.send(message); + } finally { + sess.close(); + }*/ + + JMSContext context = topicConnectionFactory.createContext(); + + message = context.createTextMessage(); + + message.setStringProperty("command", "ping"); + message.setLongProperty("publishTime", System.currentTimeMillis()); + message.setText("Ping message for topic java:comp/env/jms/TradeStreamerTopic sent from PingServlet2MDBTopic at " + new java.util.Date()); + + context.createProducer().send(tradeStreamerTopic, message); + } + + // write out the output + output.append("
    initTime: ").append(initTime); + output.append("
    Hit Count: ").append(hitCount++); + output.append("
    Posted Text message to java:comp/env/jms/TradeStreamerTopic topic"); + output.append("
    Message: ").append(message); + output.append("

    Message text: ").append(message.getText()); + output.append("

    "); + out.println(output.toString()); + + } catch (Exception e) { + Log.error("PingServlet2MDBTopic.doGet(...):exception posting message to TradeStreamerTopic topic"); + throw e; + } finally { + conn.close(); + } + } // this is where I actually handle the exceptions + catch (Exception e) { + Log.error(e, "PingServlet2MDBTopic.doGet(...): error"); + res.sendError(500, "PingServlet2MDBTopic.doGet(...): error, " + e.toString()); + + } + } + + @Override + public String getServletInfo() { + return "web primitive, configured with trade runtime configs, tests Servlet to Session EJB path"; + } + + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + hitCount = 0; + initTime = new java.util.Date().toString(); + } + +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2Session.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2Session.java new file mode 100644 index 00000000..4b9b159e --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2Session.java @@ -0,0 +1,121 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.ejb3; + +import java.io.IOException; + +import javax.annotation.PostConstruct; +import javax.inject.Inject; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ibm.websphere.samples.daytrader.impl.ejb3.TradeSLSBBean; +import com.ibm.websphere.samples.daytrader.interfaces.TradeEJB; +import com.ibm.websphere.samples.daytrader.interfaces.TradeServices; +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; + +/** + * + * This primitive is designed to run inside the TradeApplication and relies upon + * the {@link trade_client.TradeConfig} class to set configuration parameters. + * PingServlet2SessionEJB tests key functionality of a servlet call to a + * stateless SessionEJB. This servlet makes use of the Stateless Session EJB + * {@link trade.Trade} by calling calculateInvestmentReturn with three random + * numbers. + * + */ +@WebServlet(name = "ejb3.PingServlet2Session", urlPatterns = { "/ejb3/PingServlet2Session" }) +public class PingServlet2Session extends HttpServlet { + + private static final long serialVersionUID = 6854998080392777053L; + + private static String initTime; + + private static int hitCount; + + @Inject + @TradeEJB + private TradeServices tradeSLSBLocal; + + + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { + + res.setContentType("text/html"); + java.io.PrintWriter out = res.getWriter(); + // use a stringbuffer to avoid concatenation of Strings + StringBuffer output = new StringBuffer(100); + output.append("PingServlet2SessionLocal" + + "
    PingServlet2SessionLocal
    " + "" + + "Tests the basis path from a Servlet to a Session Bean."); + + try { + + try { + // create three random numbers + double rnd1 = Math.random() * 1000000; + double rnd2 = Math.random() * 1000000; + + // use a function to do some work. + double increase = 0.0; + int iter = TradeConfig.getPrimIterations(); + for (int ii = 0; ii < iter; ii++) { + increase = tradeSLSBLocal.investmentReturn(rnd1, rnd2); + } + + // write out the output + output.append("
    initTime: " + initTime); + output.append("
    Hit Count: " + hitCount++); + output.append("
    Investment Return Information

    investment: " + rnd1); + output.append("
    current Value: " + rnd2); + output.append("
    investment return " + increase + "
    "); + out.println(output.toString()); + + } catch (Exception e) { + Log.error("PingServlet2Session.doGet(...):exception calling trade.investmentReturn "); + throw e; + } + } // this is where I actually handle the exceptions + catch (Exception e) { + Log.error(e, "PingServlet2Session.doGet(...): error"); + res.sendError(500, "PingServlet2Session.doGet(...): error, " + e.toString()); + + } + } + + @Override + public String getServletInfo() { + return "web primitive, configured with trade runtime configs, tests Servlet to Session EJB path"; + + } + + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + hitCount = 0; + initTime = new java.util.Date().toString(); + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2Session2CMROne2Many.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2Session2CMROne2Many.java new file mode 100644 index 00000000..cfcda22b --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2Session2CMROne2Many.java @@ -0,0 +1,114 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.ejb3; + +import java.io.IOException; +import java.util.Collection; +import java.util.Iterator; + +import javax.inject.Inject; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ibm.websphere.samples.daytrader.entities.OrderDataBean; +import com.ibm.websphere.samples.daytrader.interfaces.TradeEJB; +import com.ibm.websphere.samples.daytrader.interfaces.TradeServices; +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; + +/** + * Primitive to test Entity Container Managed Relationshiop One to One Servlet + * will generate a random userID and get the profile for that user using a + * {@link trade.Account} Entity EJB This tests the common path of a Servlet + * calling a Session to Entity EJB to get CMR One to One data + * + */ +@WebServlet(name = "ejb3.PingServlet2Session2CMR2One2Many", urlPatterns = { "/ejb3/PingServlet2Session2CMROne2Many" }) +public class PingServlet2Session2CMROne2Many extends HttpServlet { + private static final long serialVersionUID = -8658929449987440032L; + + private static String initTime; + + private static int hitCount; + + @Inject + @TradeEJB + private TradeServices tradeSLSBLocal; + + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { + + res.setContentType("text/html"); + java.io.PrintWriter out = res.getWriter(); + + String userID = null; + + StringBuffer output = new StringBuffer(100); + output.append("Servlet2Session2CMROne20ne" + + "
    PingServlet2Session2CMROne2Many
    " + + "
    PingServlet2Session2CMROne2Many uses the Trade Session EJB" + + " to get the orders for a user using an EJB 3.0 Entity CMR one to many relationship"); + try { + + Collection orderDataBeans = null; + int iter = TradeConfig.getPrimIterations(); + for (int ii = 0; ii < iter; ii++) { + userID = TradeConfig.rndUserID(); + + // get the users orders and print the output. + orderDataBeans = tradeSLSBLocal.getOrders(userID); + } + + output.append("
    initTime: " + initTime + "
    Hit Count: ").append(hitCount++); + output.append("
    One to Many CMR access of Account Orders from Account Entity
    "); + output.append("
    User: " + userID + " currently has " + orderDataBeans.size() + " stock orders:"); + Iterator it = orderDataBeans.iterator(); + while (it.hasNext()) { + OrderDataBean orderData = (OrderDataBean) it.next(); + output.append("
    " + orderData.toHTML()); + } + output.append("

    "); + out.println(output.toString()); + } catch (Exception e) { + Log.error(e, "PingServlet2Session2CMROne2Many.doGet(...): error"); + // this will send an Error to teh web applications defined error + // page. + res.sendError(500, "PingServlet2Session2CMROne2Many.doGet(...): error" + e.toString()); + + } + } + + @Override + public String getServletInfo() { + return "web primitive, tests Servlet to Entity EJB path"; + } + + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + hitCount = 0; + initTime = new java.util.Date().toString(); + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2Session2CMROne2One.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2Session2CMROne2One.java new file mode 100644 index 00000000..21801863 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2Session2CMROne2One.java @@ -0,0 +1,107 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.ejb3; + +import java.io.IOException; + +import javax.ejb.EJB; +import javax.inject.Inject; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ibm.websphere.samples.daytrader.entities.AccountProfileDataBean; +import com.ibm.websphere.samples.daytrader.impl.ejb3.TradeSLSBBean; +import com.ibm.websphere.samples.daytrader.interfaces.TradeEJB; +import com.ibm.websphere.samples.daytrader.interfaces.TradeServices; +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; + +/** + * Primitive to test Entity Container Managed Relationshiop One to One Servlet + * will generate a random userID and get the profile for that user using a + * {@link trade.Account} Entity EJB This tests the common path of a Servlet + * calling a Session to Entity EJB to get CMR One to One data + * + */ +@WebServlet(name = "ejb3.PingServlet2Session2CMR2One2One", urlPatterns = { "/ejb3/PingServlet2Session2CMROne2One" }) +public class PingServlet2Session2CMROne2One extends HttpServlet { + private static final long serialVersionUID = 567062418489199248L; + + private static String initTime; + + private static int hitCount; + + @Inject + @TradeEJB + private TradeServices tradeSLSBLocal; + + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { + + res.setContentType("text/html"); + java.io.PrintWriter out = res.getWriter(); + + String userID = null; + + StringBuffer output = new StringBuffer(100); + output.append("Servlet2Session2CMROne20ne" + + "
    PingServlet2Session2CMROne2One
    " + + "
    PingServlet2Session2CMROne2One uses the Trade Session EJB" + + " to get the profile for a user using an EJB 3.0 CMR one to one relationship"); + try { + + AccountProfileDataBean accountProfileData = null; + int iter = TradeConfig.getPrimIterations(); + for (int ii = 0; ii < iter; ii++) { + userID = TradeConfig.rndUserID(); + // get the price and print the output. + accountProfileData = tradeSLSBLocal.getAccountProfileData(userID); + } + + output.append("
    initTime: " + initTime + "
    Hit Count: ").append(hitCount++); + output.append("
    One to One CMR access of AccountProfile Information from Account Entity

    " + accountProfileData.toHTML()); + output.append("

    "); + out.println(output.toString()); + } catch (Exception e) { + Log.error(e, "PingServlet2Session2CMROne2One.doGet(...): error"); + // this will send an Error to teh web applications defined error + // page. + res.sendError(500, "PingServlet2Session2CMROne2One.doGet(...): error" + e.toString()); + + } + } + + @Override + public String getServletInfo() { + return "web primitive, tests Servlet to Entity EJB path"; + } + + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + hitCount = 0; + initTime = new java.util.Date().toString(); + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2Session2Entity.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2Session2Entity.java new file mode 100644 index 00000000..17e892cc --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2Session2Entity.java @@ -0,0 +1,126 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.ejb3; + +import java.io.IOException; + +import javax.ejb.EJB; +import javax.inject.Inject; +import javax.naming.InitialContext; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ibm.websphere.samples.daytrader.entities.QuoteDataBean; +import com.ibm.websphere.samples.daytrader.impl.ejb3.TradeSLSBBean; +import com.ibm.websphere.samples.daytrader.interfaces.TradeEJB; +import com.ibm.websphere.samples.daytrader.interfaces.TradeServices; +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; + +/** + * + * PingServlet2Session2Entity tests key functionality of a servlet call to a + * stateless SessionEJB, and then to a Entity EJB representing data in a + * database. This servlet makes use of the Stateless Session EJB {@link Trade}, + * and then uses {@link TradeConfig} to generate a random stock symbol. The + * stocks price is looked up using the Quote Entity EJB. + * + */ +@WebServlet(name = "ejb3.PingServlet2Session2Entity", urlPatterns = { "/ejb3/PingServlet2Session2Entity" }) +public class PingServlet2Session2Entity extends HttpServlet { + + private static final long serialVersionUID = -5043457201022265012L; + + private static String initTime; + + private static int hitCount; + + @Inject + @TradeEJB + private TradeServices tradeSLSBLocal; + + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { + + res.setContentType("text/html"); + java.io.PrintWriter out = res.getWriter(); + String symbol = null; + QuoteDataBean quoteData = null; + StringBuffer output = new StringBuffer(100); + + output.append("PingServlet2Session2Entity" + + "
    PingServlet2Session2Entity
    " + "" + + "PingServlet2Session2Entity tests the common path of a Servlet calling a Session EJB " + "which in turn calls an Entity EJB.
    "); + + try { + try { + int iter = TradeConfig.getPrimIterations(); + for (int ii = 0; ii < iter; ii++) { + symbol = TradeConfig.rndSymbol(); + // getQuote will call findQuote which will instaniate the + // Quote Entity Bean + // and then will return a QuoteObject + quoteData = tradeSLSBLocal.getQuote(symbol); + } + } catch (Exception ne) { + Log.error(ne, "PingServlet2Session2Entity.goGet(...): exception getting QuoteData through Trade"); + throw ne; + } + + output.append("
    initTime: " + initTime).append("
    Hit Count: " + hitCount++); + output.append("
    Quote Information

    " + quoteData.toHTML()); + out.println(output.toString()); + + } catch (Exception e) { + Log.error(e, "PingServlet2Session2Entity.doGet(...): General Exception caught"); + res.sendError(500, "General Exception caught, " + e.toString()); + } + } + + @Override + public String getServletInfo() { + return "web primitive, tests Servlet to Session to Entity EJB path"; + + } + + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + hitCount = 0; + initTime = new java.util.Date().toString(); + + if (tradeSLSBLocal == null) { + Log.error("PingServlet2Session2Entity:init - Injection of tradeSLSBLocal failed - performing JNDI lookup!"); + + try { + InitialContext context = new InitialContext(); + tradeSLSBLocal = (TradeSLSBBean) context.lookup("java:comp/env/ejb/TradeSLSBBean"); + } catch (Exception ex) { + Log.error("PingServlet2Session2Entity:init - Lookup of tradeSLSBLocal failed!!!"); + ex.printStackTrace(); + } + } + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2Session2Entity2JSP.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2Session2Entity2JSP.java new file mode 100644 index 00000000..e8f1c268 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2Session2Entity2JSP.java @@ -0,0 +1,106 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.ejb3; + +import java.io.IOException; + +import javax.ejb.EJB; +import javax.inject.Inject; +import javax.naming.InitialContext; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ibm.websphere.samples.daytrader.entities.QuoteDataBean; +import com.ibm.websphere.samples.daytrader.impl.ejb3.TradeSLSBBean; +import com.ibm.websphere.samples.daytrader.interfaces.TradeEJB; +import com.ibm.websphere.samples.daytrader.interfaces.TradeServices; +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; + +/** + * + * PingServlet2Session2Entity tests key functionality of a servlet call to a + * stateless SessionEJB, and then to a Entity EJB representing data in a + * database. This servlet makes use of the Stateless Session EJB {@link Trade}, + * and then uses {@link TradeConfig} to generate a random stock symbol. The + * stocks price is looked up using the Quote Entity EJB. + * + */ +@WebServlet(name = "ejb3.PingServlet2Session2Entity2JSP", urlPatterns = { "/ejb3/PingServlet2Session2Entity2JSP" }) +public class PingServlet2Session2Entity2JSP extends HttpServlet { + + private static final long serialVersionUID = -8966014710582651693L; + + @Inject + @TradeEJB + private TradeServices tradeSLSBLocal; + + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { + String symbol = null; + QuoteDataBean quoteData = null; + ServletContext ctx = getServletConfig().getServletContext(); + + try { + try { + int iter = TradeConfig.getPrimIterations(); + for (int ii = 0; ii < iter; ii++) { + symbol = TradeConfig.rndSymbol(); + // getQuote will call findQuote which will instaniate the + // Quote Entity Bean + // and then will return a QuoteObject + quoteData = tradeSLSBLocal.getQuote(symbol); + } + + req.setAttribute("quoteData", quoteData); + // req.setAttribute("hitCount", hitCount); + // req.setAttribute("initTime", initTime); + + ctx.getRequestDispatcher("/quoteDataPrimitive.jsp").include(req, res); + } catch (Exception ne) { + Log.error(ne, "PingServlet2Session2Entity2JSP.goGet(...): exception getting QuoteData through Trade"); + throw ne; + } + + } catch (Exception e) { + Log.error(e, "PingServlet2Session2Entity2JSP.doGet(...): General Exception caught"); + res.sendError(500, "General Exception caught, " + e.toString()); + } + } + + @Override + public String getServletInfo() { + return "web primitive, tests Servlet to Session to Entity EJB to JSP path"; + + } + + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + // hitCount = 0; + // initTime = new java.util.Date().toString(); + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2Session2EntityCollection.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2Session2EntityCollection.java new file mode 100644 index 00000000..ded2e882 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2Session2EntityCollection.java @@ -0,0 +1,123 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.ejb3; + +import java.io.IOException; +import java.util.Collection; +import java.util.Iterator; + +import javax.ejb.EJB; +import javax.inject.Inject; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ibm.websphere.samples.daytrader.entities.HoldingDataBean; +import com.ibm.websphere.samples.daytrader.impl.ejb3.TradeSLSBBean; +import com.ibm.websphere.samples.daytrader.interfaces.TradeEJB; +import com.ibm.websphere.samples.daytrader.interfaces.TradeServices; +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; + +/** + * + * PingServlet2Session2Entity tests key functionality of a servlet call to a + * stateless SessionEJB, and then to a Entity EJB representing data in a + * database. This servlet makes use of the Stateless Session EJB {@link Trade}, + * and then uses {@link TradeConfig} to generate a random user. The users + * portfolio is looked up using the Holding Entity EJB returnin a collection of + * Holdings + * + */ +@WebServlet(name = "ejb3.PingServlet2Session2EntityCollection", urlPatterns = { "/ejb3/PingServlet2Session2EntityCollection" }) +public class PingServlet2Session2EntityCollection extends HttpServlet { + + private static final long serialVersionUID = 6171380014749902308L; + + private static String initTime; + + private static int hitCount; + + @Inject + @TradeEJB + private TradeServices tradeSLSBLocal; + + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { + + res.setContentType("text/html"); + java.io.PrintWriter out = res.getWriter(); + String userID = null; + Collection holdingDataBeans = null; + StringBuffer output = new StringBuffer(100); + + output.append("PingServlet2Session2EntityCollection" + + "
    PingServlet2Session2EntityCollection
    " + "" + + "PingServlet2Session2EntityCollection tests the common path of a Servlet calling a Session EJB " + + "which in turn calls a finder on an Entity EJB returning a collection of Entity EJBs.
    "); + + try { + + try { + int iter = TradeConfig.getPrimIterations(); + for (int ii = 0; ii < iter; ii++) { + userID = TradeConfig.rndUserID(); + // getQuote will call findQuote which will instaniate the + // Quote Entity Bean + // and then will return a QuoteObject + holdingDataBeans = tradeSLSBLocal.getHoldings(userID); + // trade.remove(); + } + } catch (Exception ne) { + Log.error(ne, "PingServlet2Session2EntityCollection.goGet(...): exception getting HoldingData collection through Trade for user " + userID); + throw ne; + } + + output.append("
    initTime: " + initTime).append("
    Hit Count: " + hitCount++); + output.append("
    User: " + userID + " is currently holding " + holdingDataBeans.size() + " stock holdings:"); + Iterator it = holdingDataBeans.iterator(); + while (it.hasNext()) { + HoldingDataBean holdingData = (HoldingDataBean) it.next(); + output.append("
    " + holdingData.toHTML()); + } + out.println(output.toString()); + + } catch (Exception e) { + Log.error(e, "PingServlet2Session2EntityCollection.doGet(...): General Exception caught"); + res.sendError(500, "General Exception caught, " + e.toString()); + } + } + + @Override + public String getServletInfo() { + return "web primitive, tests Servlet to Session to Entity returning a collection of Entity EJBs"; + } + + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + hitCount = 0; + initTime = new java.util.Date().toString(); + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2TwoPhase.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2TwoPhase.java new file mode 100644 index 00000000..3e184f06 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/ejb3/PingServlet2TwoPhase.java @@ -0,0 +1,118 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.ejb3; + +import java.io.IOException; + +import javax.inject.Inject; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ibm.websphere.samples.daytrader.entities.QuoteDataBean; +import com.ibm.websphere.samples.daytrader.interfaces.TradeEJB; +import com.ibm.websphere.samples.daytrader.interfaces.TradeServices; +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; + + +/** + * + * PingServlet2TwoPhase tests key functionality of a TwoPhase commit In this + * primitive a servlet calls a Session EJB which begins a global txn The Session + * EJB then reads a DB row and sends a message to JMS Queue The txn is closed w/ + * a 2-phase commit + * + */ +@WebServlet(name = "ejb3.PingServlet2TwoPhase", urlPatterns = { "/ejb3/PingServlet2TwoPhase" }) +public class PingServlet2TwoPhase extends HttpServlet { + + private static final long serialVersionUID = -1563251786527079548L; + + private static String initTime; + + private static int hitCount; + + @Inject + @TradeEJB + private TradeServices tradeSLSBLocal; + + @Override + public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + doGet(req, res); + } + + + + @Override + public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { + + res.setContentType("text/html"); + java.io.PrintWriter out = res.getWriter(); + String symbol = null; + QuoteDataBean quoteData = null; + StringBuffer output = new StringBuffer(100); + + output.append("PingServlet2TwoPhase" + + "
    PingServlet2TwoPhase
    " + "" + + "PingServlet2TwoPhase tests the path of a Servlet calling a Session EJB " + + "which in turn calls an Entity EJB to read a DB row (quote). The Session EJB " + "then posts a message to a JMS Queue. " + + "
    These operations are wrapped in a 2-phase commit
    "); + + try { + + try { + int iter = TradeConfig.getPrimIterations(); + for (int ii = 0; ii < iter; ii++) { + symbol = TradeConfig.rndSymbol(); + // getQuote will call findQuote which will instaniate the + // Quote Entity Bean + // and then will return a QuoteObject + quoteData = tradeSLSBLocal.pingTwoPhase(symbol); + + } + } catch (Exception ne) { + Log.error(ne, "PingServlet2TwoPhase.goGet(...): exception getting QuoteData through Trade"); + throw ne; + } + + output.append("
    initTime: " + initTime).append("
    Hit Count: " + hitCount++); + output.append("
    Two phase ping selected a quote and sent a message to TradeBrokerQueue JMS queue
    Quote Information

    " + + quoteData.toHTML()); + out.println(output.toString()); + + } catch (Exception e) { + Log.error(e, "PingServlet2TwoPhase.doGet(...): General Exception caught"); + res.sendError(500, "General Exception caught, " + e.toString()); + } + } + + @Override + public String getServletInfo() { + return "web primitive, tests Servlet to Session to Entity EJB and JMS -- 2-phase commit path"; + + } + + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + hitCount = 0; + initTime = new java.util.Date().toString(); + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/http2/PingServletPush.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/http2/PingServletPush.java new file mode 100644 index 00000000..296a564a --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/http2/PingServletPush.java @@ -0,0 +1,73 @@ +/** + * (C) Copyright IBM Corporation 2019. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.http2; + +import java.io.IOException; +import java.io.PrintWriter; + +// +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.PushBuilder; + +import com.ibm.websphere.samples.daytrader.util.Log; + +@WebServlet(name = "PingServletPush", urlPatterns = { "/PingServletPush" }) +public class PingServletPush extends HttpServlet { + + private static final long serialVersionUID = -1687383294950455998L; + private static String initTime; + private static int hitCount; + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + + try { + PushBuilder pushBuilder = req.newPushBuilder(); + if (pushBuilder != null) { + pushBuilder + .path("images/graph.gif") + .push(); + + } else { + Log.error("HTTP/2 not enabled or Push not supported"); + } + } catch (Exception e) { + e.printStackTrace(); + } + + try(PrintWriter respWriter = resp.getWriter();){ + hitCount++; + //System.out.println("Sending hit count: " + hitCount); + respWriter.write("Ping Servlet HTTP/2" + + "

    Ping Servlet HTTP/2
    Init time : " + initTime + + "

    Hit Count: " + hitCount + "
    " + + "" + + ""); + } + } + + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + initTime = new java.util.Date().toString(); + hitCount = 0; + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/http2/PingServletSimple.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/http2/PingServletSimple.java new file mode 100644 index 00000000..5c9b7e69 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/http2/PingServletSimple.java @@ -0,0 +1,55 @@ +/** + * (C) Copyright IBM Corporation 2019. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.http2; + +import java.io.IOException; +import java.io.PrintWriter; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@WebServlet(name = "PingServletHttpSimple", urlPatterns = { "/PingServletHttpSimple" }) +public class PingServletSimple extends HttpServlet { + + private static final long serialVersionUID = -1687383294950455998L; + private static String initTime; + private static int hitCount; + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + + try(PrintWriter respWriter = resp.getWriter();){ + hitCount++; + //System.out.println("Sending hit count: " + hitCount); + respWriter.write("Ping Servlet HTTP/2" + + "

    Ping Servlet HTTP/2
    Init time : " + initTime + + "

    Hit Count: " + hitCount + "
    " + + "" + + ""); + } + } + + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + initTime = new java.util.Date().toString(); + hitCount = 0; + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/jaxrs/JAXRSSyncService.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/jaxrs/JAXRSSyncService.java new file mode 100644 index 00000000..aff1ea9b --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/jaxrs/JAXRSSyncService.java @@ -0,0 +1,63 @@ +/** + * (C) Copyright IBM Corporation 2019. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.jaxrs; + +import javax.ws.rs.ApplicationPath; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; + +@ApplicationPath("/jaxrs") +@Path("sync") +public class JAXRSSyncService { + + /** + * note: this should be the basic code path for jaxrs process + * @param input + * @return + */ + @GET + @Path("echoText") + public String echoString(@QueryParam("input") String input) { + return input; + } + + /** + * note: this code path involves JSON marshaller & un-marshaller based on basic code path + * @param p Person Object + * @return Person Object + */ + @POST + @Path("echoJSON") + @Produces(value={MediaType.APPLICATION_JSON}) + @Consumes(value={MediaType.APPLICATION_JSON}) + public TestJSONObject echoObject(TestJSONObject jsonObject) { + return jsonObject; + } + + @POST + @Path("echoXML") + @Produces(value={MediaType.TEXT_XML,MediaType.APPLICATION_XML}) + @Consumes(value={MediaType.TEXT_XML,MediaType.APPLICATION_XML}) + public XMLObject echoObject(XMLObject xmlObject) { + return xmlObject; + } +} + diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/jaxrs/ObjectFactory.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/jaxrs/ObjectFactory.java new file mode 100644 index 00000000..f7993d8c --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/jaxrs/ObjectFactory.java @@ -0,0 +1,28 @@ +/** + * (C) Copyright IBM Corporation 2019. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.jaxrs; + +import javax.xml.bind.annotation.XmlRegistry; + + +@XmlRegistry +public class ObjectFactory { + + public XMLObject createXMLObject() { + XMLObject xo = new XMLObject(); + return xo; + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/jaxrs/TestJSONObject.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/jaxrs/TestJSONObject.java new file mode 100644 index 00000000..20c229d1 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/jaxrs/TestJSONObject.java @@ -0,0 +1,134 @@ +/** + * (C) Copyright IBM Corporation 2019. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.jaxrs; + +public class TestJSONObject { + + private String prop0001; + private String prop0002; + private String prop0003; + private String prop0004; + private String prop0005; + private String prop0006; + private String prop0007; + private String prop0008; + private String prop0009; + private String prop0010; + private String prop0011; + private String prop0012; + private String prop0013; + private String prop0014; + private String prop0015; + private String prop0016; + + public String getProp0001() { + return prop0001; + } + public void setProp0001(String prop0001) { + this.prop0001 = prop0001; + } + public String getProp0002() { + return prop0002; + } + public void setProp0002(String prop0002) { + this.prop0002 = prop0002; + } + public String getProp0003() { + return prop0003; + } + public void setProp0003(String prop0003) { + this.prop0003 = prop0003; + } + public String getProp0004() { + return prop0004; + } + public void setProp0004(String prop0004) { + this.prop0004 = prop0004; + } + public String getProp0005() { + return prop0005; + } + public void setProp0005(String prop0005) { + this.prop0005 = prop0005; + } + public String getProp0006() { + return prop0006; + } + public void setProp0006(String prop0006) { + this.prop0006 = prop0006; + } + public String getProp0007() { + return prop0007; + } + public void setProp0007(String prop0007) { + this.prop0007 = prop0007; + } + public String getProp0008() { + return prop0008; + } + public void setProp0008(String prop0008) { + this.prop0008 = prop0008; + } + public String getProp0009() { + return prop0009; + } + public void setProp0009(String prop0009) { + this.prop0009 = prop0009; + } + public String getProp0010() { + return prop0010; + } + public void setProp0010(String prop0010) { + this.prop0010 = prop0010; + } + public String getProp0011() { + return prop0011; + } + public void setProp0011(String prop0011) { + this.prop0011 = prop0011; + } + public String getProp0012() { + return prop0012; + } + public void setProp0012(String prop0012) { + this.prop0012 = prop0012; + } + public String getProp0013() { + return prop0013; + } + public void setProp0013(String prop0013) { + this.prop0013 = prop0013; + } + public String getProp0014() { + return prop0014; + } + public void setProp0014(String prop0014) { + this.prop0014 = prop0014; + } + public String getProp0015() { + return prop0015; + } + public void setProp0015(String prop0015) { + this.prop0015 = prop0015; + } + public String getProp0016() { + return prop0016; + } + public void setProp0016(String prop0016) { + this.prop0016 = prop0016; + } +} + diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/jaxrs/XMLObject.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/jaxrs/XMLObject.java new file mode 100644 index 00000000..eb427650 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/prims/jaxrs/XMLObject.java @@ -0,0 +1,152 @@ +/** + * (C) Copyright IBM Corporation 2019. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.prims.jaxrs; + +import javax.xml.bind.annotation.XmlRootElement; + +/** + * with @XmlRootElement, make the XMLObject as a JAXB object + * then add/remove any atteribute with setter& getter + * + * note: please change all XMLObjects in project JAXRSJ2SEClient,JAXRSBenchService,JAXRS20Client + * they should share the same XMLObject + * @author alexzan + * + */ +@XmlRootElement +public class XMLObject { + + private String prop0001; + private String prop0002; + private String prop0003; + private String prop0004; + private String prop0005; + private String prop0006; + private String prop0007; + private String prop0008; + private String prop0009; + private String prop0010; + private String prop0011; + private String prop0012; + private String prop0013; + private String prop0014; + private String prop0015; + private String prop0016; + private String x; + + public String getProp0001() { + return prop0001; + } + public void setProp0001(String prop0001) { + this.prop0001 = prop0001; + } + public String getProp0002() { + return prop0002; + } + public void setProp0002(String prop0002) { + this.prop0002 = prop0002; + } + public String getProp0003() { + return prop0003; + } + public void setProp0003(String prop0003) { + this.prop0003 = prop0003; + } + public String getProp0004() { + return prop0004; + } + public void setProp0004(String prop0004) { + this.prop0004 = prop0004; + } + public String getProp0005() { + return prop0005; + } + public void setProp0005(String prop0005) { + this.prop0005 = prop0005; + } + public String getProp0006() { + return prop0006; + } + public void setProp0006(String prop0006) { + this.prop0006 = prop0006; + } + public String getProp0007() { + return prop0007; + } + public void setProp0007(String prop0007) { + this.prop0007 = prop0007; + } + public String getProp0008() { + return prop0008; + } + public void setProp0008(String prop0008) { + this.prop0008 = prop0008; + } + public String getProp0009() { + return prop0009; + } + public void setProp0009(String prop0009) { + this.prop0009 = prop0009; + } + public String getProp0010() { + return prop0010; + } + public void setProp0010(String prop0010) { + this.prop0010 = prop0010; + } + public String getProp0011() { + return prop0011; + } + public void setProp0011(String prop0011) { + this.prop0011 = prop0011; + } + public String getProp0012() { + return prop0012; + } + public void setProp0012(String prop0012) { + this.prop0012 = prop0012; + } + public String getProp0013() { + return prop0013; + } + public void setProp0013(String prop0013) { + this.prop0013 = prop0013; + } + public String getProp0014() { + return prop0014; + } + public void setProp0014(String prop0014) { + this.prop0014 = prop0014; + } + public String getProp0015() { + return prop0015; + } + public void setProp0015(String prop0015) { + this.prop0015 = prop0015; + } + public String getProp0016() { + return prop0016; + } + public void setProp0016(String prop0016) { + this.prop0016 = prop0016; + } + public String getX() { + return x; + } + public void setX(String x) { + this.x = x; + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/servlet/OrdersAlertFilter.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/servlet/OrdersAlertFilter.java new file mode 100644 index 00000000..9bbfa1d9 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/servlet/OrdersAlertFilter.java @@ -0,0 +1,116 @@ +/** + * (C) Copyright IBM Corporation 2015, 2022. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.servlet; + +import java.io.IOException; +import java.util.Collection; + +import javax.enterprise.inject.Any; +import javax.enterprise.inject.Instance; +import javax.inject.Inject; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.annotation.WebFilter; +import javax.servlet.http.HttpServletRequest; + +import com.ibm.websphere.samples.daytrader.interfaces.Trace; +import com.ibm.websphere.samples.daytrader.interfaces.TradeServices; +import com.ibm.websphere.samples.daytrader.util.Diagnostics; +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; +import com.ibm.websphere.samples.daytrader.util.TradeRunTimeModeLiteral; + +@WebFilter(filterName = "OrdersAlertFilter", urlPatterns = "/app") +@Trace +public class OrdersAlertFilter implements Filter { + + private TradeServices tradeAction; + + @Inject + public OrdersAlertFilter(@Any Instance services) { + super(); + tradeAction = services.select(new TradeRunTimeModeLiteral(TradeConfig.getRunTimeModeNames()[TradeConfig.getRunTimeMode()])).get(); + } + + + /** + * @see Filter#init(FilterConfig) + */ + private FilterConfig filterConfig = null; + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + this.filterConfig = filterConfig; + } + + /** + * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) + */ + @Override + public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { + if (filterConfig == null) { + return; + } + + if (TradeConfig.getDisplayOrderAlerts() == true) { + + try { + String action = req.getParameter("action"); + if (action != null) { + action = action.trim(); + if ((action.length() > 0) && (!action.equals("logout"))) { + String userID; + if (action.equals("login")) { + userID = req.getParameter("uid"); + } else { + userID = (String) ((HttpServletRequest) req).getSession().getAttribute("uidBean"); + } + + if ((userID != null) && (userID.trim().length() > 0)) { + + Collection closedOrders = tradeAction.getClosedOrders(userID); + if ((closedOrders != null) && (closedOrders.size() > 0)) { + req.setAttribute("closedOrders", closedOrders); + } + if (Log.doTrace()) { + Log.printCollection("OrderAlertFilter: userID=" + userID + " closedOrders=", closedOrders); + } + } + } + } + } catch (Exception e) { + Log.error(e, "OrdersAlertFilter - Error checking for closedOrders"); + } + } + + Diagnostics.checkDiagnostics(); + + chain.doFilter(req, resp/* wrapper */); + } + + /** + * @see Filter#destroy() + */ + @Override + public void destroy() { + this.filterConfig = null; + } + +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/servlet/PrimFilter.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/servlet/PrimFilter.java new file mode 100644 index 00000000..64aaa2a6 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/servlet/PrimFilter.java @@ -0,0 +1,68 @@ +/** + * (C) Copyright IBM Corporation 2015, 2022. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.servlet; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.annotation.WebFilter; + +import com.ibm.websphere.samples.daytrader.interfaces.Trace; +import com.ibm.websphere.samples.daytrader.util.Diagnostics; + +@WebFilter(filterName = "PrimFilter", urlPatterns = "/drive/*") +@Trace +public class PrimFilter implements Filter { + + /** + * @see Filter#init(FilterConfig) + */ + private FilterConfig filterConfig = null; + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + this.filterConfig = filterConfig; + } + + /** + * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) + */ + @Override + public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { + + if (filterConfig == null) { + return; + } + + Diagnostics.checkDiagnostics(); + + chain.doFilter(req, resp/* wrapper */); + } + + /** + * @see Filter#destroy() + */ + @Override + public void destroy() { + this.filterConfig = null; + } + +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/servlet/TestServlet.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/servlet/TestServlet.java new file mode 100644 index 00000000..6b644d77 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/servlet/TestServlet.java @@ -0,0 +1,122 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.servlet; + +import java.io.IOException; +import java.math.BigDecimal; + +import javax.enterprise.inject.Any; +import javax.enterprise.inject.Instance; +import javax.inject.Inject; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ibm.websphere.samples.daytrader.interfaces.TradeServices; +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; +import com.ibm.websphere.samples.daytrader.util.TradeRunTimeModeLiteral; + +@WebServlet(name = "TestServlet", urlPatterns = { "/TestServlet" }) +public class TestServlet extends HttpServlet { + + private static final long serialVersionUID = -2927579146688173127L; + + private TradeServices tradeAction; + + @Inject + public TestServlet(@Any Instance services) { + tradeAction = services.select(new TradeRunTimeModeLiteral(TradeConfig.getRunTimeModeNames()[TradeConfig.getRunTimeMode()])).get(); + } + + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + } + + /** + * Process incoming HTTP GET requests + * + * @param request + * Object that encapsulates the request to the servlet + * @param response + * Object that encapsulates the response from the servlet + */ + @Override + public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + performTask(request, response); + } + + /** + * Process incoming HTTP POST requests + * + * @param request + * Object that encapsulates the request to the servlet + * @param response + * Object that encapsulates the response from the servlet + */ + @Override + public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + performTask(request, response); + } + + /** + * Main service method for TradeAppServlet + * + * @param request + * Object that encapsulates the request to the servlet + * @param response + * Object that encapsulates the response from the servlet + */ + public void performTask(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + try { + Log.debug("Enter TestServlet doGet"); + //TradeDirect tradeDirect = new TradeDirect(); + for (int i = 0; i < 10; i++) { + tradeAction.createQuote("s:" + i, "Company " + i, new BigDecimal(i * 1.1)); + } + /* + * + * AccountDataBean accountData = new TradeAction().register("user1", + * "password", "fullname", "address", "email", "creditCard", new + * BigDecimal(123.45), false); + * + * OrderDataBean orderData = new TradeAction().buy("user1", "s:1", + * 100.0); orderData = new TradeAction().buy("user1", "s:2", 200.0); + * Thread.sleep(5000); accountData = new + * TradeAction().getAccountData("user1"); Collection + * holdingDataBeans = new TradeAction().getHoldings("user1"); + * PrintWriter out = resp.getWriter(); + * resp.setContentType("text/html"); + * out.write("

    "); + * out.write(accountData.toString()); + * Log.printCollection("user1 Holdings", holdingDataBeans); + * ServletContext sc = getServletContext(); + * req.setAttribute("results", "Success"); + * req.setAttribute("accountData", accountData); + * req.setAttribute("holdingDataBeans", holdingDataBeans); + * getServletContext + * ().getRequestDispatcher("/tradehome.jsp").include(req, resp); + * out.write("

    done."); + */ + } catch (Exception e) { + Log.error("TestServletException", e); + } + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/servlet/TradeAppServlet.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/servlet/TradeAppServlet.java new file mode 100644 index 00000000..4b7c529f --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/servlet/TradeAppServlet.java @@ -0,0 +1,221 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.servlet; + +import java.io.IOException; + +import javax.inject.Inject; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import javax.servlet.http.PushBuilder; + +import com.ibm.websphere.samples.daytrader.interfaces.Trace; +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; + + +/** + * + * TradeAppServlet provides the standard web interface to Trade and can be + * accessed with the Go Trade! link. Driving benchmark load using this interface + * requires a sophisticated web load generator that is capable of filling HTML + * forms and posting dynamic data. + */ + +@WebServlet(name = "TradeAppServlet", urlPatterns = { "/app" }) +@Trace +public class TradeAppServlet extends HttpServlet { + + @Inject + TradeServletAction tsAction; + + private static final long serialVersionUID = 481530522846648373L; + + /** + * Servlet initialization method. + */ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + java.util.Enumeration en = config.getInitParameterNames(); + while (en.hasMoreElements()) { + String parm = en.nextElement(); + String value = config.getInitParameter(parm); + TradeConfig.setConfigParam(parm, value); + } + try { + // TODO: Uncomment this once split-tier issue is resolved + // TradeDirect.init(); + } catch (Exception e) { + Log.error(e, "TradeAppServlet:init -- Error initializing TradeDirect"); + } + } + + /** + * Returns a string that contains information about TradeScenarioServlet + * + * @return The servlet information + */ + @Override + public java.lang.String getServletInfo() { + return "TradeAppServlet provides the standard web interface to Trade"; + } + + /** + * Process incoming HTTP GET requests + * + * @param request + * Object that encapsulates the request to the servlet + * @param response + * Object that encapsulates the response from the servlet + */ + @Override + public void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws ServletException, IOException { + performTask(request, response); + } + + /** + * Process incoming HTTP POST requests + * + * @param request + * Object that encapsulates the request to the servlet + * @param response + * Object that encapsulates the response from the servlet + */ + @Override + public void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws ServletException, IOException { + performTask(request, response); + } + + /** + * Main service method for TradeAppServlet + * + * @param request + * Object that encapsulates the request to the servlet + * @param response + * Object that encapsulates the response from the servlet + */ + public void performTask(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + + String action = null; + String userID = null; + // String to create full dispatch path to TradeAppServlet w/ request + // Parameters + + resp.setContentType("text/html"); + + // Dyna - need status string - prepended to output + action = req.getParameter("action"); + + ServletContext ctx = getServletConfig().getServletContext(); + + if (action == null) { + tsAction.doWelcome(ctx, req, resp, ""); + return; + } else if (action.equals("login")) { + userID = req.getParameter("uid"); + String passwd = req.getParameter("passwd"); + tsAction.doLogin(ctx, req, resp, userID, passwd); + return; + } else if (action.equals("register")) { + userID = req.getParameter("user id"); + String passwd = req.getParameter("passwd"); + String cpasswd = req.getParameter("confirm passwd"); + String fullname = req.getParameter("Full Name"); + String ccn = req.getParameter("Credit Card Number"); + String money = req.getParameter("money"); + String email = req.getParameter("email"); + String smail = req.getParameter("snail mail"); + tsAction.doRegister(ctx, req, resp, userID, passwd, cpasswd, fullname, ccn, money, email, smail); + return; + } + + // The rest of the operations require the user to be logged in - + // Get the Session and validate the user. + HttpSession session = req.getSession(); + userID = (String) session.getAttribute("uidBean"); + + if (userID == null) { + System.out.println("TradeAppServlet service error: User Not Logged in"); + tsAction.doWelcome(ctx, req, resp, "User Not Logged in"); + return; + } + + // try http/2 push if we get here + // should be logged in and doing real work by this point + if (!action.equals("logout") && TradeConfig.getWebInterface() == TradeConfig.JSP_Images_HTTP2) { + pushHeaderImages(req.newPushBuilder()); + } + + if (action.equals("quotes")) { + String symbols = req.getParameter("symbols"); + tsAction.doQuotes(ctx, req, resp, userID, symbols); + } else if (action.equals("buy")) { + String symbol = req.getParameter("symbol"); + String quantity = req.getParameter("quantity"); + tsAction.doBuy(ctx, req, resp, userID, symbol, quantity); + } else if (action.equals("sell")) { + int holdingID = Integer.parseInt(req.getParameter("holdingID")); + tsAction.doSell(ctx, req, resp, userID, new Integer(holdingID)); + } else if (action.equals("portfolio") || action.equals("portfolioNoEdge")) { + tsAction.doPortfolio(ctx, req, resp, userID, "Portfolio as of " + new java.util.Date()); + } else if (action.equals("logout")) { + tsAction.doLogout(ctx, req, resp, userID); + } else if (action.equals("home")) { + tsAction.doHome(ctx, req, resp, userID, "Ready to Trade"); + } else if (action.equals("account")) { + tsAction.doAccount(ctx, req, resp, userID, ""); + } else if (action.equals("update_profile")) { + String password = req.getParameter("password"); + String cpassword = req.getParameter("cpassword"); + String fullName = req.getParameter("fullname"); + String address = req.getParameter("address"); + String creditcard = req.getParameter("creditcard"); + String email = req.getParameter("email"); + tsAction.doAccountUpdate(ctx, req, resp, userID, password == null ? "" : password.trim(), cpassword == null ? "" : cpassword.trim(), + fullName == null ? "" : fullName.trim(), address == null ? "" : address.trim(), creditcard == null ? "" : creditcard.trim(), + email == null ? "" : email.trim()); + } else if (action.equals("mksummary")) { + tsAction.doMarketSummary(ctx, req, resp, userID); + } else { + System.out.println("TradeAppServlet: Invalid Action=" + action); + tsAction.doWelcome(ctx, req, resp, "TradeAppServlet: Invalid Action" + action); + } + } + + private void pushHeaderImages(PushBuilder pushBuilder) { + if (pushBuilder != null) { + pushBuilder.path("images/menuHome.gif").addHeader("content-type", "image/gif").push(); + pushBuilder.path("images/account.gif").addHeader("content-type", "image/gif").push(); + pushBuilder.path("images/portfolio.gif").addHeader("content-type", "image/gif").push(); + pushBuilder.path("images/quotes.gif").addHeader("content-type", "image/gif").push(); + pushBuilder.path("images/logout.gif").addHeader("content-type", "image/gif").push(); + pushBuilder.path("images/graph.gif").addHeader("content-type", "image/gif").push(); + pushBuilder.path("images/line.gif").addHeader("content-type", "image/gif").push(); + Log.trace("HTTP/2 is enabled"); + } else { + Log.error("HTTP/2 not enabled"); + } + + } + +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/servlet/TradeConfigServlet.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/servlet/TradeConfigServlet.java new file mode 100644 index 00000000..4abbeca6 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/servlet/TradeConfigServlet.java @@ -0,0 +1,292 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.servlet; + +import java.io.IOException; + +import javax.inject.Inject; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + + +import com.ibm.websphere.samples.daytrader.beans.RunStatsDataBean; +import com.ibm.websphere.samples.daytrader.impl.direct.TradeDirectDBUtils; +import com.ibm.websphere.samples.daytrader.interfaces.Trace; +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; + + +/** + * TradeConfigServlet provides a servlet interface to adjust DayTrader runtime parameters. + * TradeConfigServlet updates values in the {@link com.ibm.websphere.samples.daytrader.web.TradeConfig} JavaBean holding + * all configuration and runtime parameters for the Trade application + * + */ +@WebServlet(name = "TradeConfigServlet", urlPatterns = { "/config" }) +@Trace +public class TradeConfigServlet extends HttpServlet { + + @Inject + private TradeDirectDBUtils dbUtils; + + private static final long serialVersionUID = -1910381529792500095L; + + /** + * Servlet initialization method. + */ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + } + + /** + * Create the TradeConfig bean and pass it the config.jsp page + * to display the current Trade runtime configuration + * Creation date: (2/8/2000 3:43:59 PM) + */ + void doConfigDisplay(HttpServletRequest req, HttpServletResponse resp, String results) throws Exception { + + TradeConfig currentConfig = new TradeConfig(); + + req.setAttribute("tradeConfig", currentConfig); + req.setAttribute("status", results); + getServletConfig().getServletContext().getRequestDispatcher(TradeConfig.getPage(TradeConfig.CONFIG_PAGE)).include(req, resp); + } + + void doResetTrade(HttpServletRequest req, HttpServletResponse resp, String results) throws Exception { + RunStatsDataBean runStatsData = new RunStatsDataBean(); + TradeConfig currentConfig = new TradeConfig(); + + try { + runStatsData = dbUtils.resetTrade(false); + + req.setAttribute("runStatsData", runStatsData); + req.setAttribute("tradeConfig", currentConfig); + results += "Trade Reset completed successfully"; + req.setAttribute("status", results); + + } catch (Exception e) { + results += "Trade Reset Error - see log for details"; + Log.error(e, results); + throw e; + } + getServletConfig().getServletContext().getRequestDispatcher(TradeConfig.getPage(TradeConfig.STATS_PAGE)).include(req, resp); + + } + + /** + * Update Trade runtime configuration paramaters + * Creation date: (2/8/2000 3:44:24 PM) + */ + void doConfigUpdate(HttpServletRequest req, HttpServletResponse resp) throws Exception { + String currentConfigStr = "\n\n########## Trade configuration update. Current config:\n\n"; + + currentConfigStr += "\t\tRuntimeMode:\t\t" + TradeConfig.getRunTimeModeNames()[TradeConfig.getRunTimeMode()] + "\n"; + + String orderProcessingModeStr = req.getParameter("OrderProcessingMode"); + if (orderProcessingModeStr != null) { + try { + int i = Integer.parseInt(orderProcessingModeStr); + if ((i >= 0) && (i < TradeConfig.getOrderProcessingModeNames().length)) //Input validation + TradeConfig.setOrderProcessingMode(i); + } catch (Exception e) { + //>>rjm + Log.error(e, "TradeConfigServlet.doConfigUpdate(..): minor exception caught", "trying to set orderProcessing to " + orderProcessingModeStr, + "reverting to current value"); + + } // If the value is bad, simply revert to current + } + currentConfigStr += "\t\tOrderProcessingMode:\t\t" + TradeConfig.getOrderProcessingModeNames()[TradeConfig.getOrderProcessingMode()] + "\n"; + + String webInterfaceStr = req.getParameter("WebInterface"); + if (webInterfaceStr != null) { + try { + int i = Integer.parseInt(webInterfaceStr); + if ((i >= 0) && (i < TradeConfig.getWebInterfaceNames().length)) //Input validation + TradeConfig.setWebInterface(i); + } catch (Exception e) { + Log.error(e, "TradeConfigServlet.doConfigUpdate(..): minor exception caught", "trying to set WebInterface to " + webInterfaceStr, + "reverting to current value"); + + } // If the value is bad, simply revert to current + } + currentConfigStr += "\t\tWeb Interface:\t\t\t" + TradeConfig.getWebInterfaceNames()[TradeConfig.getWebInterface()] + "\n"; + + String parm = req.getParameter("MaxUsers"); + if ((parm != null) && (parm.length() > 0)) { + try { + TradeConfig.setMAX_USERS(Integer.parseInt(parm)); + } catch (Exception e) { + Log.error(e, "TradeConfigServlet.doConfigUpdate(..): minor exception caught", "Setting maxusers, probably error parsing string to int:" + parm, + "revertying to current value: " + TradeConfig.getMAX_USERS()); + + } //On error, revert to saved + } + parm = req.getParameter("MaxQuotes"); + if ((parm != null) && (parm.length() > 0)) { + try { + TradeConfig.setMAX_QUOTES(Integer.parseInt(parm)); + } catch (Exception e) { + //>>rjm + Log.error(e, "TradeConfigServlet: minor exception caught", "trying to set max_quotes, error on parsing int " + parm, + "reverting to current value " + TradeConfig.getMAX_QUOTES()); + //< 0)) { + try { + TradeConfig.setMarketSummaryInterval(Integer.parseInt(parm)); + } catch (Exception e) { + Log.error(e, "TradeConfigServlet: minor exception caught", "trying to set marketSummaryInterval, error on parsing int " + parm, + "reverting to current value " + TradeConfig.getMarketSummaryInterval()); + + } + } + currentConfigStr += "\t\tMarket Summary Interval:\t" + TradeConfig.getMarketSummaryInterval() + "\n"; + + parm = req.getParameter("primIterations"); + if ((parm != null) && (parm.length() > 0)) { + try { + TradeConfig.setPrimIterations(Integer.parseInt(parm)); + } catch (Exception e) { + Log.error(e, "TradeConfigServlet: minor exception caught", "trying to set primIterations, error on parsing int " + parm, + "reverting to current value " + TradeConfig.getPrimIterations()); + + } + } + currentConfigStr += "\t\tPrimitive Iterations:\t\t" + TradeConfig.getPrimIterations() + "\n"; + + String enablePublishQuotePriceChange = req.getParameter("EnablePublishQuotePriceChange"); + + if (enablePublishQuotePriceChange != null) + TradeConfig.setPublishQuotePriceChange(true); + else + TradeConfig.setPublishQuotePriceChange(false); + currentConfigStr += "\t\tTradeStreamer MDB Enabled:\t" + TradeConfig.getPublishQuotePriceChange() + "\n"; + + parm = req.getParameter("ListQuotePriceChangeFrequency"); + if ((parm != null) && (parm.length() > 0)) { + try { + TradeConfig.setListQuotePriceChangeFrequency(Integer.parseInt(parm)); + } catch (Exception e) { + Log.error(e, "TradeConfigServlet: minor exception caught", "trying to set percentSentToWebSocket, error on parsing int " + parm, + "reverting to current value " + TradeConfig.getListQuotePriceChangeFrequency()); + + } + } + currentConfigStr += "\t\t% of trades on Websocket:\t" + TradeConfig.getListQuotePriceChangeFrequency() + "\n"; + + String enableLongRun = req.getParameter("EnableLongRun"); + + if (enableLongRun != null) + TradeConfig.setLongRun(true); + else + TradeConfig.setLongRun(false); + currentConfigStr += "\t\tLong Run Enabled:\t\t" + TradeConfig.getLongRun() + "\n"; + + String displayOrderAlerts = req.getParameter("DisplayOrderAlerts"); + + if (displayOrderAlerts != null) + TradeConfig.setDisplayOrderAlerts(true); + else + TradeConfig.setDisplayOrderAlerts(false); + currentConfigStr += "\t\tDisplay Order Alerts:\t\t" + TradeConfig.getDisplayOrderAlerts() + "\n"; + + System.out.println(currentConfigStr); + } + + @Override + public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + + String action = null; + String result = ""; + + resp.setContentType("text/html"); + try { + action = req.getParameter("action"); + if (action == null) { + doConfigDisplay(req, resp, result + "
    Current DayTrader Configuration:
    "); + return; + } else if (action.equals("updateConfig")) { + doConfigUpdate(req, resp); + result = "
    DayTrader Configuration Updated
    "; + } else if (action.equals("resetTrade")) { + doResetTrade(req, resp, ""); + return; + } else if (action.equals("buildDB")) { + resp.setContentType("text/html"); + dbUtils.buildDB(resp.getWriter(), null); + result = "DayTrader Database Built - " + TradeConfig.getMAX_USERS() + "users created"; + } else if (action.equals("buildDBTables")) { + + resp.setContentType("text/html"); + + String dbProductName = null; + try { + dbProductName = dbUtils.checkDBProductName(); + } catch (Exception e) { + Log.error(e, "TradeBuildDB: Unable to check DB Product name"); + } + if (dbProductName == null) { + resp.getWriter().println( + "
    TradeBuildDB: **** Unable to check DB Product name, please check Database/AppServer configuration and retry ****
    "); + return; + } + + String ddlFile = null; + //Locate DDL file for the specified database + try { + resp.getWriter().println("
    TradeBuildDB: **** Database Product detected: " + dbProductName + " ****
    "); + if (dbProductName.startsWith("DB2/")) {// if db is DB2 + ddlFile = "/dbscripts/db2/Table.ddl"; + } else if (dbProductName.startsWith("Apache Derby")) { //if db is Derby + ddlFile = "/dbscripts/derby/Table.ddl"; + } else if (dbProductName.startsWith("Oracle")) { // if the Db is Oracle + ddlFile = "/dbscripts/oracle/Table.ddl"; + } else {// Unsupported "Other" Database + ddlFile = "/dbscripts/other/Table.ddl"; + resp.getWriter().println("
    TradeBuildDB: **** This Database is unsupported/untested use at your own risk ****
    "); + } + + resp.getWriter().println("
    TradeBuildDB: **** The DDL file at path " + ddlFile + " will be used ****
    "); + resp.getWriter().flush(); + } catch (Exception e) { + Log.error(e, "TradeBuildDB: Unable to locate DDL file for the specified database"); + resp.getWriter().println("
    TradeBuildDB: **** Unable to locate DDL file for the specified database ****
    "); + return; + } + + dbUtils.buildDB(resp.getWriter(), getServletContext().getResourceAsStream(ddlFile)); + + } + doConfigDisplay(req, resp, result + "Current DayTrader Configuration:"); + } catch (Exception e) { + Log.error(e, "TradeConfigServlet.service(...)", "Exception trying to perform action=" + action); + + resp.sendError(500, "TradeConfigServlet.service(...)" + "Exception trying to perform action=" + action + "\nException details: " + e.toString()); + + } + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/servlet/TradeScenarioServlet.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/servlet/TradeScenarioServlet.java new file mode 100644 index 00000000..5c05399b --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/servlet/TradeScenarioServlet.java @@ -0,0 +1,297 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.servlet; + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Collection; +import java.util.Iterator; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import com.ibm.websphere.samples.daytrader.entities.HoldingDataBean; +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; + +/** + * TradeScenarioServlet emulates a population of web users by generating a + * specific Trade operation for a randomly chosen user on each access to the + * URL. Test this servlet by clicking Trade Scenario and hit "Reload" on your + * browser to step through a Trade Scenario. To benchmark using this URL aim + * your favorite web load generator (such as AKStress) at the Trade Scenario URL + * and fire away. + */ +@WebServlet(name = "TradeScenarioServlet", urlPatterns = { "/scenario" }) +public class TradeScenarioServlet extends HttpServlet { + + private static final long serialVersionUID = 1410005249314201829L; + + /** + * Servlet initialization method. + */ + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + java.util.Enumeration en = config.getInitParameterNames(); + while (en.hasMoreElements()) { + String parm = en.nextElement(); + String value = config.getInitParameter(parm); + TradeConfig.setConfigParam(parm, value); + } + } + + /** + * Returns a string that contains information about TradeScenarioServlet + * + * @return The servlet information + */ + @Override + public java.lang.String getServletInfo() { + return "TradeScenarioServlet emulates a population of web users"; + } + + /** + * Process incoming HTTP GET requests + * + * @param request + * Object that encapsulates the request to the servlet + * @param response + * Object that encapsulates the response from the servlet + */ + @Override + public void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws ServletException, IOException { + performTask(request, response); + } + + /** + * Process incoming HTTP POST requests + * + * @param request + * Object that encapsulates the request to the servlet + * @param response + * Object that encapsulates the response from the servlet + */ + @Override + public void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws ServletException, IOException { + performTask(request, response); + } + + /** + * Main service method for TradeScenarioServlet + * + * @param request + * Object that encapsulates the request to the servlet + * @param response + * Object that encapsulates the response from the servlet + */ + public void performTask(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + + // Scenario generator for Trade2 + char action = ' '; + String userID = null; + + // String to create full dispatch path to TradeAppServlet w/ request + // Parameters + String dispPath = null; // Dispatch Path to TradeAppServlet + + resp.setContentType("text/html"); + + String scenarioAction = req.getParameter("action"); + if ((scenarioAction != null) && (scenarioAction.length() >= 1)) { + action = scenarioAction.charAt(0); + if (action == 'n') { // null; + try { + // resp.setContentType("text/html"); + PrintWriter out = new PrintWriter(resp.getOutputStream()); + out.println("TradeScenarioServletHello"); + out.close(); + return; + + } catch (Exception e) { + Log.error("trade_client.TradeScenarioServlet.service(...)" + "error creating printwriter from responce.getOutputStream", e); + + resp.sendError(500, + "trade_client.TradeScenarioServlet.service(...): erorr creating and writing to PrintStream created from response.getOutputStream()"); + } // end of catch + + } // end of action=='n' + } + + ServletContext ctx = null; + HttpSession session = null; + try { + ctx = getServletConfig().getServletContext(); + // These operations require the user to be logged in. Verify the + // user and if not logged in + // change the operation to a login + session = req.getSession(true); + userID = (String) session.getAttribute("uidBean"); + } catch (Exception e) { + Log.error("trade_client.TradeScenarioServlet.service(...): performing " + scenarioAction + + "error getting ServletContext,HttpSession, or UserID from session" + "will make scenarioAction a login and try to recover from there", e); + userID = null; + action = 'l'; + } + + if (userID == null) { + action = 'l'; // change to login + TradeConfig.incrementScenarioCount(); + } else if (action == ' ') { + // action is not specified perform a random operation according to + // current mix + // Tell getScenarioAction if we are an original user or a registered + // user + // -- sellDeficits should only be compensated for with original + // users. + action = TradeConfig.getScenarioAction(userID.startsWith(TradeConfig.newUserPrefix)); + } + switch (action) { + + case 'q': // quote + dispPath = tasPathPrefix + "quotes&symbols=" + TradeConfig.rndSymbols(); + ctx.getRequestDispatcher(dispPath).include(req, resp); + break; + case 'a': // account + dispPath = tasPathPrefix + "account"; + ctx.getRequestDispatcher(dispPath).include(req, resp); + break; + case 'u': // update account profile + dispPath = tasPathPrefix + "account"; + ctx.getRequestDispatcher(dispPath).include(req, resp); + + String fullName = "rnd" + System.currentTimeMillis(); + String address = "rndAddress"; + String password = "xxx"; + String email = "rndEmail"; + String creditcard = "rndCC"; + dispPath = tasPathPrefix + "update_profile&fullname=" + fullName + "&password=" + password + "&cpassword=" + password + "&address=" + address + + "&email=" + email + "&creditcard=" + creditcard; + ctx.getRequestDispatcher(dispPath).include(req, resp); + break; + case 'h': // home + dispPath = tasPathPrefix + "home"; + ctx.getRequestDispatcher(dispPath).include(req, resp); + break; + case 'l': // login + userID = TradeConfig.getUserID(); + String password2 = "xxx"; + dispPath = tasPathPrefix + "login&inScenario=true&uid=" + userID + "&passwd=" + password2; + ctx.getRequestDispatcher(dispPath).include(req, resp); + + // login is successful if the userID is written to the HTTP session + if (session.getAttribute("uidBean") == null) { + System.out.println("TradeScenario login failed. Reset DB between runs"); + } + break; + case 'o': // logout + dispPath = tasPathPrefix + "logout"; + ctx.getRequestDispatcher(dispPath).include(req, resp); + break; + case 'p': // portfolio + dispPath = tasPathPrefix + "portfolio"; + ctx.getRequestDispatcher(dispPath).include(req, resp); + break; + case 'r': // register + // Logout the current user to become a new user + // see note in TradeServletAction + req.setAttribute("TSS-RecreateSessionInLogout", Boolean.TRUE); + dispPath = tasPathPrefix + "logout"; + ctx.getRequestDispatcher(dispPath).include(req, resp); + + userID = TradeConfig.rndNewUserID(); + String passwd = "yyy"; + fullName = TradeConfig.rndFullName(); + creditcard = TradeConfig.rndCreditCard(); + String money = TradeConfig.rndBalance(); + email = TradeConfig.rndEmail(userID); + String smail = TradeConfig.rndAddress(); + dispPath = tasPathPrefix + "register&Full Name=" + fullName + "&snail mail=" + smail + "&email=" + email + "&user id=" + userID + "&passwd=" + + passwd + "&confirm passwd=" + passwd + "&money=" + money + "&Credit Card Number=" + creditcard; + ctx.getRequestDispatcher(dispPath).include(req, resp); + break; + case 's': // sell + dispPath = tasPathPrefix + "portfolioNoEdge"; + ctx.getRequestDispatcher(dispPath).include(req, resp); + + Collection holdings = (Collection) req.getAttribute("holdingDataBeans"); + int numHoldings = holdings.size(); + if (numHoldings > 0) { + // sell first available security out of holding + + Iterator it = holdings.iterator(); + boolean foundHoldingToSell = false; + while (it.hasNext()) { + HoldingDataBean holdingData = (HoldingDataBean) it.next(); + if (!(holdingData.getPurchaseDate().equals(new java.util.Date(0)))) { + Integer holdingID = holdingData.getHoldingID(); + + dispPath = tasPathPrefix + "sell&holdingID=" + holdingID; + ctx.getRequestDispatcher(dispPath).include(req, resp); + foundHoldingToSell = true; + break; + } + } + if (foundHoldingToSell) { + break; + } + + Log.trace("TradeScenario: No holding to sell -switch to buy -- userID = " + userID + " Collection count = " + numHoldings); + + + } + // At this point: A TradeScenario Sell was requested with No Stocks + // in Portfolio + // This can happen when a new registered user happens to request a + // sell before a buy + // In this case, fall through and perform a buy instead + + /* + * Trade 2.037: Added sell_deficit counter to maintain correct + * buy/sell mix. When a users portfolio is reduced to 0 holdings, a + * buy is requested instead of a sell. This throws off the buy/sell + * mix by 1. This results in unwanted holding table growth To fix + * this we increment a sell deficit counter to maintain the correct + * ratio in getScenarioAction The 'z' action from getScenario + * denotes that this is a sell action that was switched from a buy + * to reduce a sellDeficit + */ + if (userID.startsWith(TradeConfig.newUserPrefix) == false) { + TradeConfig.incrementSellDeficit(); + } + case 'b': // buy + String symbol = TradeConfig.rndSymbol(); + String amount = TradeConfig.rndQuantity() + ""; + + dispPath = tasPathPrefix + "quotes&symbols=" + symbol; + ctx.getRequestDispatcher(dispPath).include(req, resp); + + dispPath = tasPathPrefix + "buy&quantity=" + amount + "&symbol=" + symbol; + ctx.getRequestDispatcher(dispPath).include(req, resp); + break; + } // end of switch statement + } + + // URL Path Prefix for dispatching to TradeAppServlet + private static final String tasPathPrefix = "/app?action="; + +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/servlet/TradeServletAction.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/servlet/TradeServletAction.java new file mode 100644 index 00000000..9ffb4fc3 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/servlet/TradeServletAction.java @@ -0,0 +1,654 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.servlet; + +import java.io.IOException; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +import javax.enterprise.context.SessionScoped; +import javax.enterprise.inject.Any; +import javax.enterprise.inject.Instance; +import javax.inject.Inject; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import com.ibm.websphere.samples.daytrader.interfaces.Trace; +import com.ibm.websphere.samples.daytrader.interfaces.TradeServices; +import com.ibm.websphere.samples.daytrader.entities.AccountDataBean; +import com.ibm.websphere.samples.daytrader.entities.AccountProfileDataBean; +import com.ibm.websphere.samples.daytrader.entities.HoldingDataBean; +import com.ibm.websphere.samples.daytrader.entities.OrderDataBean; +import com.ibm.websphere.samples.daytrader.entities.QuoteDataBean; +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; +import com.ibm.websphere.samples.daytrader.util.TradeRunTimeModeLiteral; + + +/** + * TradeServletAction provides servlet specific client side access to each of + * the Trade brokerage user operations. These include login, logout, buy, sell, + * getQuote, etc. TradeServletAction manages a web interface to Trade handling + * HttpRequests/HttpResponse objects and forwarding results to the appropriate + * JSP page for the web interface. TradeServletAction invokes + * {@link TradeAction} methods to actually perform each trading operation. + * + */ +@SessionScoped +@Trace +public class TradeServletAction implements Serializable { + + private static final long serialVersionUID = 7732313125198761455L; + + private TradeServices tAction; + + @Inject + public TradeServletAction(@Any Instance services) { + tAction = services.select(new TradeRunTimeModeLiteral(TradeConfig.getRunTimeModeNames()[TradeConfig.getRunTimeMode()])).get(); + } + + public TradeServletAction() { + } + + /** + * Display User Profile information such as address, email, etc. for the + * given Trader Dispatch to the Trade Account JSP for display + * + * @param userID + * The User to display profile info + * @param ctx + * the servlet context + * @param req + * the HttpRequest object + * @param resp + * the HttpResponse object + * @param results + * A short description of the results/success of this web request + * provided on the web page + * @exception javax.servlet.ServletException + * If a servlet specific exception is encountered + * @exception javax.io.IOException + * If an exception occurs while writing results back to the + * user + * + */ + void doAccount(ServletContext ctx, HttpServletRequest req, HttpServletResponse resp, String userID, String results) throws javax.servlet.ServletException, + java.io.IOException { + try { + + AccountDataBean accountData = tAction.getAccountData(userID); + AccountProfileDataBean accountProfileData = tAction.getAccountProfileData(userID); + Collection orderDataBeans = (TradeConfig.getLongRun() ? new ArrayList() : (Collection) tAction.getOrders(userID)); + + req.setAttribute("accountData", accountData); + req.setAttribute("accountProfileData", accountProfileData); + req.setAttribute("orderDataBeans", orderDataBeans); + req.setAttribute("results", results); + requestDispatch(ctx, req, resp, userID, TradeConfig.getPage(TradeConfig.ACCOUNT_PAGE)); + } catch (java.lang.IllegalArgumentException e) { // this is a user + // error so I will + // forward them to another page rather than throw a 500 + req.setAttribute("results", results + "could not find account for userID = " + userID); + requestDispatch(ctx, req, resp, userID, TradeConfig.getPage(TradeConfig.HOME_PAGE)); + // log the exception with an error level of 3 which means, handled + // exception but would invalidate a automation run + Log.error("TradeServletAction.doAccount(...)", "illegal argument, information should be in exception string", e); + } catch (Exception e) { + // log the exception with error page + throw new ServletException("TradeServletAction.doAccount(...)" + " exception user =" + userID, e); + } + + } + + /** + * Update User Profile information such as address, email, etc. for the + * given Trader Dispatch to the Trade Account JSP for display If any in put + * is incorrect revert back to the account page w/ an appropriate message + * + * @param userID + * The User to upddate profile info + * @param password + * The new User password + * @param cpassword + * Confirm password + * @param fullname + * The new User fullname info + * @param address + * The new User address info + * @param cc + * The new User credit card info + * @param email + * The new User email info + * @param ctx + * the servlet context + * @param req + * the HttpRequest object + * @param resp + * the HttpResponse object + * @exception javax.servlet.ServletException + * If a servlet specific exception is encountered + * @exception javax.io.IOException + * If an exception occurs while writing results back to the + * user + * + */ + void doAccountUpdate(ServletContext ctx, HttpServletRequest req, HttpServletResponse resp, String userID, String password, String cpassword, + String fullName, String address, String creditcard, String email) throws javax.servlet.ServletException, java.io.IOException { + String results = ""; + + // First verify input data + boolean doUpdate = true; + if (password.equals(cpassword) == false) { + results = "Update profile error: passwords do not match"; + doUpdate = false; + } else if (password.length() <= 0 || fullName.length() <= 0 || address.length() <= 0 || creditcard.length() <= 0 || email.length() <= 0) { + results = "Update profile error: please fill in all profile information fields"; + doUpdate = false; + } + AccountProfileDataBean accountProfileData = new AccountProfileDataBean(userID, password, fullName, address, email, creditcard); + try { + if (doUpdate) { + accountProfileData = tAction.updateAccountProfile(accountProfileData); + results = "Account profile update successful"; + } + + } catch (java.lang.IllegalArgumentException e) { // this is a user + // error so I will + // forward them to another page rather than throw a 500 + req.setAttribute("results", results + "invalid argument, check userID is correct, and the database is populated" + userID); + Log.error(e, "TradeServletAction.doAccount(...)", "illegal argument, information should be in exception string", + "treating this as a user error and forwarding on to a new page"); + } catch (Exception e) { + // log the exception with error page + throw new ServletException("TradeServletAction.doAccountUpdate(...)" + " exception user =" + userID, e); + } + doAccount(ctx, req, resp, userID, results); + } + + /** + * Buy a new holding of shares for the given trader Dispatch to the Trade + * Portfolio JSP for display + * + * @param userID + * The User buying shares + * @param symbol + * The stock to purchase + * @param amount + * The quantity of shares to purchase + * @param ctx + * the servlet context + * @param req + * the HttpRequest object + * @param resp + * the HttpResponse object + * @exception javax.servlet.ServletException + * If a servlet specific exception is encountered + * @exception javax.io.IOException + * If an exception occurs while writing results back to the + * user + * + */ + void doBuy(ServletContext ctx, HttpServletRequest req, HttpServletResponse resp, String userID, String symbol, String quantity) throws ServletException, + IOException { + + String results = ""; + + try { + + OrderDataBean orderData = tAction.buy(userID, symbol, new Double(quantity).doubleValue(), TradeConfig.getOrderProcessingMode()); + + req.setAttribute("orderData", orderData); + req.setAttribute("results", results); + } catch (java.lang.IllegalArgumentException e) { // this is a user + // error so I will + // forward them to another page rather than throw a 500 + req.setAttribute("results", results + "illegal argument:"); + requestDispatch(ctx, req, resp, userID, TradeConfig.getPage(TradeConfig.HOME_PAGE)); + // log the exception with an error level of 3 which means, handled + // exception but would invalidate a automation run + Log.error(e, "TradeServletAction.doBuy(...)", "illegal argument. userID = " + userID, "symbol = " + symbol); + } catch (Exception e) { + // log the exception with error page + throw new ServletException("TradeServletAction.buy(...)" + " exception buying stock " + symbol + " for user " + userID, e); + } + requestDispatch(ctx, req, resp, userID, TradeConfig.getPage(TradeConfig.ORDER_PAGE)); + } + + /** + * Create the Trade Home page with personalized information such as the + * traders account balance Dispatch to the Trade Home JSP for display + * + * @param ctx + * the servlet context + * @param req + * the HttpRequest object + * @param resp + * the HttpResponse object + * @param results + * A short description of the results/success of this web request + * provided on the web page + * @exception javax.servlet.ServletException + * If a servlet specific exception is encountered + * @exception javax.io.IOException + * If an exception occurs while writing results back to the + * user + * + */ + void doHome(ServletContext ctx, HttpServletRequest req, HttpServletResponse resp, String userID, String results) throws javax.servlet.ServletException, + java.io.IOException { + + try { + AccountDataBean accountData = tAction.getAccountData(userID); + Collection holdingDataBeans = tAction.getHoldings(userID); + + // Edge Caching: + // Getting the MarketSummary has been moved to the JSP + // MarketSummary.jsp. This makes the MarketSummary a + // standalone "fragment", and thus is a candidate for + // Edge caching. + // marketSummaryData = tAction.getMarketSummary(); + + req.setAttribute("accountData", accountData); + req.setAttribute("holdingDataBeans", holdingDataBeans); + // See Edge Caching above + // req.setAttribute("marketSummaryData", marketSummaryData); + req.setAttribute("results", results); + } catch (java.lang.IllegalArgumentException e) { // this is a user + // error so I will + // forward them to another page rather than throw a 500 + req.setAttribute("results", results + "check userID = " + userID + " and that the database is populated"); + requestDispatch(ctx, req, resp, userID, TradeConfig.getPage(TradeConfig.HOME_PAGE)); + // log the exception with an error level of 3 which means, handled + // exception but would invalidate a automation run + Log.error("TradeServletAction.doHome(...)" + "illegal argument, information should be in exception string" + + "treating this as a user error and forwarding on to a new page", e); + } catch (javax.ejb.FinderException e) { + // this is a user error so I will + // forward them to another page rather than throw a 500 + req.setAttribute("results", results + "\nCould not find account for + " + userID); + // requestDispatch(ctx, req, resp, + // TradeConfig.getPage(TradeConfig.HOME_PAGE)); + // log the exception with an error level of 3 which means, handled + // exception but would invalidate a automation run + Log.error("TradeServletAction.doHome(...)" + "Error finding account for user " + userID + + "treating this as a user error and forwarding on to a new page", e); + } catch (Exception e) { + // log the exception with error page + throw new ServletException("TradeServletAction.doHome(...)" + " exception user =" + userID, e); + } + + requestDispatch(ctx, req, resp, userID, TradeConfig.getPage(TradeConfig.HOME_PAGE)); + } + + /** + * Login a Trade User. Dispatch to the Trade Home JSP for display + * + * @param userID + * The User to login + * @param passwd + * The password supplied by the trader used to authenticate + * @param ctx + * the servlet context + * @param req + * the HttpRequest object + * @param resp + * the HttpResponse object + * @param results + * A short description of the results/success of this web request + * provided on the web page + * @exception javax.servlet.ServletException + * If a servlet specific exception is encountered + * @exception javax.io.IOException + * If an exception occurs while writing results back to the + * user + * + */ + void doLogin(ServletContext ctx, HttpServletRequest req, HttpServletResponse resp, String userID, String passwd) throws javax.servlet.ServletException, + java.io.IOException { + + String results = ""; + try { + // Got a valid userID and passwd, attempt login + if (tAction==null) { + System.out.println("null"); } + AccountDataBean accountData = tAction.login(userID, passwd); + + if (accountData != null) { + HttpSession session = req.getSession(true); + session.setAttribute("uidBean", userID); + session.setAttribute("sessionCreationDate", new java.util.Date()); + + results = "Ready to Trade"; + doHome(ctx, req, resp, userID, results); + return; + } else { + req.setAttribute("results", results + "\nCould not find account for + " + userID); + // log the exception with an error level of 3 which means, + // handled exception but would invalidate a automation run + Log.log("TradeServletAction.doLogin(...)", "Error finding account for user " + userID + "", + "user entered a bad username or the database is not populated"); + } + } catch (java.lang.IllegalArgumentException e) { // this is a user + // error so I will + // forward them to another page rather than throw a 500 + req.setAttribute("results", results + "illegal argument:" + e.getMessage()); + // log the exception with an error level of 3 which means, handled + // exception but would invalidate a automation run + Log.error(e, "TradeServletAction.doLogin(...)", "illegal argument, information should be in exception string", + "treating this as a user error and forwarding on to a new page"); + + } catch (Exception e) { + // log the exception with error page + throw new ServletException("TradeServletAction.doLogin(...)" + "Exception logging in user " + userID + "with password" + passwd, e); + } + + requestDispatch(ctx, req, resp, userID, TradeConfig.getPage(TradeConfig.WELCOME_PAGE)); + + } + + /** + * Logout a Trade User Dispatch to the Trade Welcome JSP for display + * + * @param userID + * The User to logout + * @param ctx + * the servlet context + * @param req + * the HttpRequest object + * @param resp + * the HttpResponse object + * @param results + * A short description of the results/success of this web request + * provided on the web page + * @exception javax.servlet.ServletException + * If a servlet specific exception is encountered + * @exception javax.io.IOException + * If an exception occurs while writing results back to the + * user + * + */ + void doLogout(ServletContext ctx, HttpServletRequest req, HttpServletResponse resp, String userID) throws ServletException, IOException { + String results = ""; + + try { + tAction.logout(userID); + + } catch (java.lang.IllegalArgumentException e) { // this is a user + // error so I will + // forward them to another page, at the end of the page. + req.setAttribute("results", results + "illegal argument:" + e.getMessage()); + + // log the exception with an error level of 3 which means, handled + // exception but would invalidate a automation run + Log.error(e, "TradeServletAction.doLogout(...)", "illegal argument, information should be in exception string", + "treating this as a user error and forwarding on to a new page"); + } catch (Exception e) { + // log the exception and foward to a error page + Log.error(e, "TradeServletAction.doLogout(...):", "Error logging out" + userID, "fowarding to an error page"); + // set the status_code to 500 + throw new ServletException("TradeServletAction.doLogout(...)" + "exception logging out user " + userID, e); + } + HttpSession session = req.getSession(); + if (session != null) { + session.invalidate(); + } + + // Added to actually remove a user from the authentication cache + req.logout(); + + Object o = req.getAttribute("TSS-RecreateSessionInLogout"); + if (o != null && ((Boolean) o).equals(Boolean.TRUE)) { + // Recreate Session object before writing output to the response + // Once the response headers are written back to the client the + // opportunity + // to create a new session in this request may be lost + // This is to handle only the TradeScenarioServlet case + session = req.getSession(true); + } + requestDispatch(ctx, req, resp, userID, TradeConfig.getPage(TradeConfig.WELCOME_PAGE)); + } + + /** + * Retrieve the current portfolio of stock holdings for the given trader + * Dispatch to the Trade Portfolio JSP for display + * + * @param userID + * The User requesting to view their portfolio + * @param ctx + * the servlet context + * @param req + * the HttpRequest object + * @param resp + * the HttpResponse object + * @param results + * A short description of the results/success of this web request + * provided on the web page + * @exception javax.servlet.ServletException + * If a servlet specific exception is encountered + * @exception javax.io.IOException + * If an exception occurs while writing results back to the + * user + * + */ + void doPortfolio(ServletContext ctx, HttpServletRequest req, HttpServletResponse resp, String userID, String results) throws ServletException, IOException { + + try { + // Get the holdiings for this user + + Collection quoteDataBeans = new ArrayList(); + Collection holdingDataBeans = tAction.getHoldings(userID); + + // Walk through the collection of user + // holdings and creating a list of quotes + if (holdingDataBeans.size() > 0) { + + Iterator it = holdingDataBeans.iterator(); + while (it.hasNext()) { + HoldingDataBean holdingData = (HoldingDataBean) it.next(); + QuoteDataBean quoteData = tAction.getQuote(holdingData.getQuoteID()); + quoteDataBeans.add(quoteData); + } + } else { + results = results + ". Your portfolio is empty."; + } + req.setAttribute("results", results); + req.setAttribute("holdingDataBeans", holdingDataBeans); + req.setAttribute("quoteDataBeans", quoteDataBeans); + requestDispatch(ctx, req, resp, userID, TradeConfig.getPage(TradeConfig.PORTFOLIO_PAGE)); + } catch (java.lang.IllegalArgumentException e) { // this is a user + // error so I will + // forward them to another page rather than throw a 500 + req.setAttribute("results", results + "illegal argument:" + e.getMessage()); + requestDispatch(ctx, req, resp, userID, TradeConfig.getPage(TradeConfig.PORTFOLIO_PAGE)); + // log the exception with an error level of 3 which means, handled + // exception but would invalidate a automation run + Log.error(e, "TradeServletAction.doPortfolio(...)", "illegal argument, information should be in exception string", "user error"); + } catch (Exception e) { + // log the exception with error page + throw new ServletException("TradeServletAction.doPortfolio(...)" + " exception user =" + userID, e); + } + } + + /** + * Retrieve the current Quote for the given stock symbol Dispatch to the + * Trade Quote JSP for display + * + * @param userID + * The stock symbol used to get the current quote + * @param ctx + * the servlet context + * @param req + * the HttpRequest object + * @param resp + * the HttpResponse object + * @exception javax.servlet.ServletException + * If a servlet specific exception is encountered + * @exception javax.io.IOException + * If an exception occurs while writing results back to the + * user + * + */ + void doQuotes(ServletContext ctx, HttpServletRequest req, HttpServletResponse resp, String userID, String symbols) throws ServletException, IOException { + + try { + Collection quoteDataBeans = new ArrayList(); + String[] symbolsSplit = symbols.split(","); + for (String symbol: symbolsSplit) { + QuoteDataBean quoteData = tAction.getQuote(symbol.trim()); + quoteDataBeans.add(quoteData); + } + req.setAttribute("quoteDataBeans", quoteDataBeans); + requestDispatch(ctx, req, resp, userID, TradeConfig.getPage(TradeConfig.QUOTE_PAGE)); + + } catch (Exception e) { + // log the exception with error page + throw new ServletException("TradeServletAction.doQuotes(...)" + " exception user =" + userID, e); + } + } + + /** + * Register a new trader given the provided user Profile information such as + * address, email, etc. Dispatch to the Trade Home JSP for display + * + * @param userID + * The User to create + * @param passwd + * The User password + * @param fullname + * The new User fullname info + * @param ccn + * The new User credit card info + * @param money + * The new User opening account balance + * @param address + * The new User address info + * @param email + * The new User email info + * @return The userID of the new trader + * @param ctx + * the servlet context + * @param req + * the HttpRequest object + * @param resp + * the HttpResponse object + * @exception javax.servlet.ServletException + * If a servlet specific exception is encountered + * @exception javax.io.IOException + * If an exception occurs while writing results back to the + * user + * + */ + void doRegister(ServletContext ctx, HttpServletRequest req, HttpServletResponse resp, String userID, String passwd, String cpasswd, String fullname, + String ccn, String openBalanceString, String email, String address) throws ServletException, IOException { + String results = ""; + + try { + // Validate user passwords match and are atleast 1 char in length + if ((passwd.equals(cpasswd)) && (passwd.length() >= 1)) { + + AccountDataBean accountData = tAction.register(userID, passwd, fullname, address, email, ccn, new BigDecimal(openBalanceString)); + if (accountData == null) { + results = "Registration operation failed;"; + System.out.println(results); + req.setAttribute("results", results); + requestDispatch(ctx, req, resp, userID, TradeConfig.getPage(TradeConfig.REGISTER_PAGE)); + } else { + doLogin(ctx, req, resp, userID, passwd); + results = "Registration operation succeeded; Account " + accountData.getAccountID() + " has been created."; + req.setAttribute("results", results); + + } + } else { + // Password validation failed + results = "Registration operation failed, your passwords did not match"; + System.out.println(results); + req.setAttribute("results", results); + requestDispatch(ctx, req, resp, userID, TradeConfig.getPage(TradeConfig.REGISTER_PAGE)); + } + + } catch (Exception e) { + // log the exception with error page + throw new ServletException("TradeServletAction.doRegister(...)" + " exception user =" + userID, e); + } + } + + /** + * Sell a current holding of stock shares for the given trader. Dispatch to + * the Trade Portfolio JSP for display + * + * @param userID + * The User buying shares + * @param symbol + * The stock to sell + * @param indx + * The unique index identifying the users holding to sell + * @param ctx + * the servlet context + * @param req + * the HttpRequest object + * @param resp + * the HttpResponse object + * @exception javax.servlet.ServletException + * If a servlet specific exception is encountered + * @exception javax.io.IOException + * If an exception occurs while writing results back to the + * user + * + */ + void doSell(ServletContext ctx, HttpServletRequest req, HttpServletResponse resp, String userID, Integer holdingID) throws ServletException, IOException { + String results = ""; + try { + OrderDataBean orderData = tAction.sell(userID, holdingID, TradeConfig.getOrderProcessingMode()); + + req.setAttribute("orderData", orderData); + req.setAttribute("results", results); + } catch (java.lang.IllegalArgumentException e) { // this is a user + // error so I will + // just log the exception and then later on I will redisplay the + // portfolio page + // because this is just a user exception + Log.error(e, "TradeServletAction.doSell(...)", "illegal argument, information should be in exception string", "user error"); + } catch (Exception e) { + // log the exception with error page + throw new ServletException("TradeServletAction.doSell(...)" + " exception selling holding " + holdingID + " for user =" + userID, e); + } + requestDispatch(ctx, req, resp, userID, TradeConfig.getPage(TradeConfig.ORDER_PAGE)); + } + + void doWelcome(ServletContext ctx, HttpServletRequest req, HttpServletResponse resp, String status) throws ServletException, IOException { + + req.setAttribute("results", status); + requestDispatch(ctx, req, resp, null, TradeConfig.getPage(TradeConfig.WELCOME_PAGE)); + } + + private void requestDispatch(ServletContext ctx, HttpServletRequest req, HttpServletResponse resp, String userID, String page) throws ServletException, + IOException { + + ctx.getRequestDispatcher(page).include(req, resp); + } + + void doMarketSummary(ServletContext ctx, HttpServletRequest req, HttpServletResponse resp, String userID) throws ServletException, IOException { + req.setAttribute("results", "test"); + requestDispatch(ctx, req, resp, userID, TradeConfig.getPage(TradeConfig.MARKET_SUMMARY_PAGE)); + + } +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/servlet/TradeWebContextListener.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/servlet/TradeWebContextListener.java new file mode 100644 index 00000000..8931f576 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/servlet/TradeWebContextListener.java @@ -0,0 +1,116 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.servlet; + +import static javax.faces.annotation.FacesConfig.Version.JSF_2_3; + +import java.io.InputStream; +import java.util.Properties; + +import javax.faces.annotation.FacesConfig; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import javax.servlet.annotation.WebListener; + +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; + +@WebListener() +@FacesConfig(version = JSF_2_3) +public class TradeWebContextListener implements ServletContextListener { + + + + // receieve trade web app startup/shutown events to start(initialized)/stop + // TradeDirect + @Override + public void contextInitialized(ServletContextEvent event) { + Log.trace("TradeWebContextListener contextInitialized -- initializing TradeDirect"); + + // Load settings from properties file (if it exists) + Properties prop = new Properties(); + InputStream stream = event.getServletContext().getResourceAsStream("/properties/daytrader.properties"); + + try { + prop.load(stream); + System.out.println("Settings from daytrader.properties: " + prop); + + if (System.getenv("RUNTIME_MODE") != null) { + TradeConfig.setRunTimeMode(Integer.parseInt(System.getenv("RUNTIME_MODE"))); + } else { + TradeConfig.setRunTimeMode(Integer.parseInt(prop.getProperty("runtimeMode"))); + } + System.out.print("Running in " + TradeConfig.getRunTimeModeNames()[TradeConfig.getRunTimeMode()] + " Mode"); + + if (System.getenv("ORDER_PROCESSING_MODE") != null) { + TradeConfig.setOrderProcessingMode(Integer.parseInt(System.getenv("ORDER_PROCESSING_MODE"))); + } else { + TradeConfig.setOrderProcessingMode(Integer.parseInt(prop.getProperty("orderProcessingMode"))); + } + System.out.print("Running in " + TradeConfig.getOrderProcessingModeNames()[TradeConfig.getOrderProcessingMode()] + " Order Processing Mode"); + + if (System.getenv("MAX_USERS") != null) { + TradeConfig.setMAX_USERS(Integer.parseInt(System.getenv("MAX_USERS"))); + } else { + TradeConfig.setMAX_USERS(Integer.parseInt(prop.getProperty("maxUsers"))); + } + System.out.print("MAX_USERS = " + TradeConfig.getMAX_USERS() + " users"); + + if (System.getenv("MAX_QUOTES") != null) { + TradeConfig.setMAX_QUOTES(Integer.parseInt(System.getenv("MAX_QUOTES"))); + } else { + TradeConfig.setMAX_QUOTES(Integer.parseInt(prop.getProperty("maxQuotes"))); + } + System.out.print("MAX_QUOTES = " + TradeConfig.getMAX_QUOTES() + " quotes"); + + if (System.getenv("PUBLISH_QUOTES") != null) { + TradeConfig.setPublishQuotePriceChange(Boolean.parseBoolean(System.getenv("PUBLISH_QUOTES"))); + } else { + TradeConfig.setPublishQuotePriceChange(Boolean.parseBoolean(prop.getProperty("publishQuotePriceChange"))); + } + + if (System.getenv("DISPLAY_ORDER_ALERTS") != null) { + TradeConfig.setDisplayOrderAlerts(Boolean.parseBoolean(System.getenv("DISPLAY_ORDER_ALERTS"))); + } else { + TradeConfig.setDisplayOrderAlerts(Boolean.parseBoolean(prop.getProperty("displayOrderAlerts"))); + } + if (System.getenv("WEB_INTERFACE") != null) { + TradeConfig.setWebInterface(Integer.parseInt(System.getenv("WEB_INTERFACE"))); + } else { + TradeConfig.setWebInterface(Integer.parseInt(prop.getProperty("webInterface"))); + } + if (System.getenv("LIST_QUOTE_PRICE_CHANGE_FREQUENCY") != null) { + TradeConfig.setListQuotePriceChangeFrequency(Integer.parseInt(System.getenv("LIST_QUOTE_PRICE_CHANGE_FREQUENCY"))); + } else { + TradeConfig.setListQuotePriceChangeFrequency(Integer.parseInt(prop.getProperty("listQuotePriceChangeFrequency"))); + } + + TradeConfig.setPrimIterations(Integer.parseInt(prop.getProperty("primIterations"))); + TradeConfig.setMarketSummaryInterval(Integer.parseInt(prop.getProperty("marketSummaryInterval"))); + TradeConfig.setLongRun(Boolean.parseBoolean(prop.getProperty("longRun"))); + + } catch (Exception e) { + System.out.println("daytrader.properties not found"); + } + + } + + @Override + public void contextDestroyed(ServletContextEvent event) { + Log.trace("TradeWebContextListener contextDestroy calling TradeDirect:destroy()"); + } + +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/websocket/ActionDecoder.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/websocket/ActionDecoder.java new file mode 100644 index 00000000..51001d5d --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/websocket/ActionDecoder.java @@ -0,0 +1,57 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.websocket; + +import javax.websocket.DecodeException; +import javax.websocket.Decoder; +import javax.websocket.EndpointConfig; + +import com.ibm.websphere.samples.daytrader.util.Log; + +// This is coded to be a Text type decoder expecting JSON format. +// It will decode incoming messages into object of type String +public class ActionDecoder implements Decoder.Text { + + public ActionDecoder() { + } + + @Override + public void destroy() { + } + + @Override + public void init(EndpointConfig config) { + } + + @Override + public ActionMessage decode(String jsonText) throws DecodeException { + + + Log.trace("ActionDecoder:decode -- received -->" + jsonText + "<--"); + + + ActionMessage actionMessage = new ActionMessage(); + actionMessage.doDecoding(jsonText); + return actionMessage; + + } + + @Override + public boolean willDecode(String s) { + return true; + } + +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/websocket/ActionMessage.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/websocket/ActionMessage.java new file mode 100644 index 00000000..5abfb997 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/websocket/ActionMessage.java @@ -0,0 +1,85 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.websocket; + +import java.io.StringReader; + +import javax.json.Json; +import javax.json.stream.JsonParser; + +import com.ibm.websphere.samples.daytrader.util.Log; + +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 + * + * http://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. + */ +public class ActionMessage { + + String decodedAction = null; + + public ActionMessage() { + } + + public void doDecoding(String jsonText) { + + String keyName = null; + try + { + // JSON parse + JsonParser parser = Json.createParser(new StringReader(jsonText)); + while (parser.hasNext()) { + JsonParser.Event event = parser.next(); + switch(event) { + case KEY_NAME: + keyName=parser.getString(); + break; + case VALUE_STRING: + if (keyName != null && keyName.equals("action")) { + decodedAction=parser.getString(); + } + break; + default: + break; + } + } + } catch (Exception e) { + Log.error("ActionMessage:doDecoding(" + jsonText + ") --> failed", e); + } + + + Log.trace("ActionMessage:doDecoding -- decoded action -->" + decodedAction + "<--"); + + } + + +public String getDecodedAction() { + return decodedAction; +} + +} + diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/websocket/JsonDecoder.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/websocket/JsonDecoder.java new file mode 100644 index 00000000..0a9b0827 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/websocket/JsonDecoder.java @@ -0,0 +1,57 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.websocket; + +import java.io.StringReader; + +import javax.json.Json; +import javax.json.JsonObject; +import javax.websocket.DecodeException; +import javax.websocket.Decoder; +import javax.websocket.EndpointConfig; + +public class JsonDecoder implements Decoder.Text { + + @Override + public void destroy() { + } + + @Override + public void init(EndpointConfig ec) { + } + + @Override + public JsonMessage decode(String json) throws DecodeException { + JsonObject jsonObject = Json.createReader(new StringReader(json)).readObject(); + + JsonMessage message = new JsonMessage(); + message.setKey(jsonObject.getString("key")); + message.setValue(jsonObject.getString("value")); + + return message; + } + + @Override + public boolean willDecode(String json) { + try { + Json.createReader(new StringReader(json)).readObject(); + return true; + } catch (Exception e) { + return false; + } + } + +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/websocket/JsonEncoder.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/websocket/JsonEncoder.java new file mode 100644 index 00000000..d9629561 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/websocket/JsonEncoder.java @@ -0,0 +1,46 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.websocket; + +import javax.json.Json; +import javax.json.JsonObject; +import javax.websocket.EncodeException; +import javax.websocket.Encoder; +import javax.websocket.EndpointConfig; + +public class JsonEncoder implements Encoder.Text{ + + @Override + public void destroy() { + } + + @Override + public void init(EndpointConfig ec) { + } + + @Override + public String encode(JsonMessage message) throws EncodeException { + + JsonObject jsonObject = Json.createObjectBuilder() + .add("key", message.getKey()) + .add("value", message.getValue()).build(); + + return jsonObject.toString(); + } + + + +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/websocket/JsonMessage.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/websocket/JsonMessage.java new file mode 100644 index 00000000..1483b960 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/websocket/JsonMessage.java @@ -0,0 +1,40 @@ +/** + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.websocket; + +public class JsonMessage { + + private String key; + private String value; + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/websocket/MarketSummaryWebSocket.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/websocket/MarketSummaryWebSocket.java new file mode 100644 index 00000000..ba879abd --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/websocket/MarketSummaryWebSocket.java @@ -0,0 +1,161 @@ +/** + * (C) Copyright IBM Corporation 2015, 2021. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.websocket; + +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.CountDownLatch; + +import javax.annotation.Priority; +import javax.enterprise.event.ObservesAsync; +import javax.enterprise.inject.Any; +import javax.enterprise.inject.Instance; +import javax.interceptor.Interceptor; +import javax.inject.Inject; +import javax.json.JsonObject; +import javax.websocket.CloseReason; +import javax.websocket.EndpointConfig; +import javax.websocket.OnClose; +import javax.websocket.OnError; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + + + +import com.ibm.websphere.samples.daytrader.interfaces.MarketSummaryUpdate; +import com.ibm.websphere.samples.daytrader.interfaces.QuotePriceChange; +import com.ibm.websphere.samples.daytrader.interfaces.TradeServices; +import com.ibm.websphere.samples.daytrader.util.Log; +import com.ibm.websphere.samples.daytrader.util.RecentQuotePriceChangeList; +import com.ibm.websphere.samples.daytrader.util.TradeConfig; +import com.ibm.websphere.samples.daytrader.util.TradeRunTimeModeLiteral; + + +/** This class is a WebSocket EndPoint that sends the Market Summary in JSON form and + * encodes recent quote price changes when requested or when triggered by CDI events. + **/ + +@ServerEndpoint(value = "/marketsummary",encoders={QuotePriceChangeListEncoder.class},decoders={ActionDecoder.class}) +public class MarketSummaryWebSocket { + + @Inject + RecentQuotePriceChangeList recentQuotePriceChangeList; + + private TradeServices tradeAction; + + private static final List sessions = new CopyOnWriteArrayList<>(); + private final CountDownLatch latch = new CountDownLatch(1); + + @Inject + public MarketSummaryWebSocket(@Any Instance services) { + tradeAction = services.select(new TradeRunTimeModeLiteral(TradeConfig.getRunTimeModeNames()[TradeConfig.getRunTimeMode()])).get(); + } + + // should never be used + public MarketSummaryWebSocket(){ + } + + @OnOpen + public void onOpen(final Session session, EndpointConfig ec) { + Log.trace("MarketSummaryWebSocket:onOpen -- session -->" + session + "<--"); + + sessions.add(session); + latch.countDown(); + } + + @OnMessage + public void sendMarketSummary(ActionMessage message, Session currentSession) { + + String action = message.getDecodedAction(); + + Log.trace("MarketSummaryWebSocket:sendMarketSummary -- received -->" + action + "<--"); + + // Make sure onopen is finished + try { + latch.await(); + } catch (Exception e) { + e.printStackTrace(); + return; + } + + + if (action != null && action.equals("updateMarketSummary")) { + + try { + + JsonObject mkSummary = tradeAction.getMarketSummary().toJSON(); + + Log.trace("MarketSummaryWebSocket:sendMarketSummary -- sending -->" + mkSummary + "<--"); + + currentSession.getAsyncRemote().sendText(mkSummary.toString()); + + } catch (Exception e) { + e.printStackTrace(); + } + } else if (action != null && action.equals("updateRecentQuotePriceChange")) { + if (!recentQuotePriceChangeList.isEmpty()) { + currentSession.getAsyncRemote().sendObject(recentQuotePriceChangeList.recentList()); + } + } + } + + @OnError + public void onError(Throwable t, Session currentSession) { + Log.trace("MarketSummaryWebSocket:onError -- session -->" + currentSession + "<--"); + t.printStackTrace(); + } + + @OnClose + public void onClose(Session session, CloseReason reason) { + Log.trace("MarketSummaryWebSocket:onClose -- session -->" + session + "<--"); + sessions.remove(session); + } + + public void onStockChange(@ObservesAsync @Priority(Interceptor.Priority.APPLICATION) @QuotePriceChange String event) { + + Log.trace("MarketSummaryWebSocket:onStockChange"); + + Iterator failSafeIterator = sessions.iterator(); + while(failSafeIterator.hasNext()) { + Session s = failSafeIterator.next(); + if (s.isOpen()) { + s.getAsyncRemote().sendObject(recentQuotePriceChangeList.recentList()); + } + } + } + + public void onMarketSummarytUpdate(@ObservesAsync @Priority(Interceptor.Priority.APPLICATION) @MarketSummaryUpdate String event) { + + Log.trace("MarketSummaryWebSocket:onJMSMessage"); + + try { + JsonObject mkSummary = tradeAction.getMarketSummary().toJSON(); + + Iterator failSafeIterator = sessions.iterator(); + while(failSafeIterator.hasNext()) { + Session s = failSafeIterator.next(); + if (s.isOpen()) { + s.getAsyncRemote().sendText(mkSummary.toString()); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/websocket/QuotePriceChangeListEncoder.java b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/websocket/QuotePriceChangeListEncoder.java new file mode 100644 index 00000000..0f090cee --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/java/com/ibm/websphere/samples/daytrader/web/websocket/QuotePriceChangeListEncoder.java @@ -0,0 +1,67 @@ +/** + * (C) Copyright IBM Corporation 2019. + * + * 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 + * + * http://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. + */ +package com.ibm.websphere.samples.daytrader.web.websocket; + +import java.util.Iterator; +import java.util.concurrent.CopyOnWriteArrayList; + +import javax.json.Json; +import javax.json.JsonBuilderFactory; +import javax.json.JsonObjectBuilder; +import javax.websocket.EncodeException; +import javax.websocket.Encoder; +import javax.websocket.EndpointConfig; + +import com.ibm.websphere.samples.daytrader.entities.QuoteDataBean; + + +/** This class takes a list of quotedata (from the RecentQuotePriceChangeList bean) and encodes + it to the json format the client (marektsummary.html) is expecting. **/ +public class QuotePriceChangeListEncoder implements Encoder.Text> { + + private static final JsonBuilderFactory jsonObjectFactory = Json.createBuilderFactory(null); + + public String encode(CopyOnWriteArrayList list) throws EncodeException { + + JsonObjectBuilder jObjectBuilder = jsonObjectFactory.createObjectBuilder(); + + int i = 1; + + for (Iterator iterator = list.iterator(); iterator.hasNext();) { + QuoteDataBean quotedata = iterator.next(); + + jObjectBuilder.add("change" + i + "_stock", quotedata.getSymbol()); + jObjectBuilder.add("change" + i + "_price","$" + quotedata.getPrice()); + jObjectBuilder.add("change" + i + "_change", quotedata.getChange()); + i++; + } + + return jObjectBuilder.build().toString(); + } + + @Override + public void init(EndpointConfig config) { + // TODO Auto-generated method stub + + } + + @Override + public void destroy() { + // TODO Auto-generated method stub + + } + +} diff --git a/src/test/resources/test-applications/daytrader8/src/main/liberty/config/bootstrap.properties b/src/test/resources/test-applications/daytrader8/src/main/liberty/config/bootstrap.properties new file mode 100644 index 00000000..b20b3d57 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/liberty/config/bootstrap.properties @@ -0,0 +1,2 @@ +default.http.port=9080 +default.https.port=9443 diff --git a/src/test/resources/test-applications/daytrader8/src/main/liberty/config/server.env b/src/test/resources/test-applications/daytrader8/src/main/liberty/config/server.env new file mode 100644 index 00000000..e56f3dd7 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/liberty/config/server.env @@ -0,0 +1,2 @@ +MAX_QUOTES=1000 +MAX_USERS=500 diff --git a/src/test/resources/test-applications/daytrader8/src/main/liberty/config/server.xml b/src/test/resources/test-applications/daytrader8/src/main/liberty/config/server.xml new file mode 100644 index 00000000..c951cac3 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/liberty/config/server.xml @@ -0,0 +1,79 @@ + + + + ejb-3.2 + servlet-4.0 + jsf-2.3 + jpa-2.2 + mdb-3.2 + wasJmsServer-1.0 + wasJmsClient-2.0 + cdi-2.0 + websocket-1.1 + concurrent-1.0 + jsonp-1.1 + jsonb-1.0 + beanValidation-2.0 + jaxrs-2.1 + ssl-1.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/liberty/config/server.xml_db2 b/src/test/resources/test-applications/daytrader8/src/main/liberty/config/server.xml_db2 new file mode 100644 index 00000000..a9287130 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/liberty/config/server.xml_db2 @@ -0,0 +1,74 @@ + + + ejb-3.2 + servlet-4.0 + jsf-2.3 + jpa-2.2 + mdb-3.2 + wasJmsServer-1.0 + wasJmsClient-2.0 + cdi-2.0 + websocket-1.1 + concurrent-1.0 + jsonp-1.1 + jsonb-1.0 + beanValidation-2.0 + jaxrs-2.1 + ssl-1.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/META-INF/LICENSE b/src/test/resources/test-applications/daytrader8/src/main/webapp/META-INF/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/META-INF/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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 + + http://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. diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/META-INF/MANIFEST.MF b/src/test/resources/test-applications/daytrader8/src/main/webapp/META-INF/MANIFEST.MF new file mode 100644 index 00000000..7b603592 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/META-INF/MANIFEST.MF @@ -0,0 +1,5 @@ +Manifest-Version: 1.0 +Ant-Version: Apache Ant 1.7.1 +Class-Path: daytrader-ee7-ejb.jar +Created-By: 2.6 (IBM Corporation) + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/PingCDIJSF.xhtml b/src/test/resources/test-applications/daytrader8/src/main/webapp/PingCDIJSF.xhtml new file mode 100644 index 00000000..949bdce7 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/PingCDIJSF.xhtml @@ -0,0 +1,39 @@ + + + + + +DayTrader PingJSF + + + + + + + + + + +
    Hit Count: #{pingCDIJSFBean.hitCount}
    +
    + + \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/PingHtml.html b/src/test/resources/test-applications/daytrader8/src/main/webapp/PingHtml.html new file mode 100644 index 00000000..53ec32d5 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/PingHtml.html @@ -0,0 +1,29 @@ + + + +PingHTML.html + + +
    +

    + PING HTML: +

    +

    + Hello World +

    + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/PingJsf.xhtml b/src/test/resources/test-applications/daytrader8/src/main/webapp/PingJsf.xhtml new file mode 100644 index 00000000..e06ab7ec --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/PingJsf.xhtml @@ -0,0 +1,145 @@ + + + + + +DayTrader PingJSF + + + + + + + + + + +
    + + + + + + + + + +
    Quotes
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    +
    +
    +
    + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/PingJsp.jsp b/src/test/resources/test-applications/daytrader8/src/main/webapp/PingJsp.jsp new file mode 100644 index 00000000..787f8793 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/PingJsp.jsp @@ -0,0 +1,39 @@ + + + + + + + +PingJsp + + + <%!int hitCount = 0; + String initTime = new java.util.Date().toString();%> +
    +
    + PING JSP:
    +
    + Init time: <%=initTime%> + <% + hitCount++; + %> +

    + Hit Count: <%=hitCount%> +

    + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/PingJspEL.jsp b/src/test/resources/test-applications/daytrader8/src/main/webapp/PingJspEL.jsp new file mode 100644 index 00000000..56fc66df --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/PingJspEL.jsp @@ -0,0 +1,124 @@ + + + + +PingJspEL + + + <%@ page + import="com.ibm.websphere.samples.daytrader.util.TradeConfig,com.ibm.websphere.samples.daytrader.entities.QuoteDataBean" + session="false"%> + + <%!int hitCount = 0; + String initTime = new java.util.Date().toString();%> + + <% + // setup some variables to work with later + int someint1 = TradeConfig.rndInt(100) + 1; + pageContext.setAttribute("someint1", new Integer(someint1)); + int someint2 = TradeConfig.rndInt(100) + 1; + pageContext.setAttribute("someint2", new Integer(someint2)); + float somefloat1 = TradeConfig.rndFloat(100) + 1.0f; + pageContext.setAttribute("somefloat1", new Float(somefloat1)); + float somefloat2 = TradeConfig.rndFloat(100) + 1.0f; + pageContext.setAttribute("somefloat2", new Float(somefloat2)); + + QuoteDataBean quoteData1 = QuoteDataBean.getRandomInstance(); + pageContext.setAttribute("quoteData1", quoteData1); + QuoteDataBean quoteData2 = QuoteDataBean.getRandomInstance(); + pageContext.setAttribute("quoteData2", quoteData2); + QuoteDataBean quoteData3 = QuoteDataBean.getRandomInstance(); + pageContext.setAttribute("quoteData3", quoteData3); + QuoteDataBean quoteData4 = QuoteDataBean.getRandomInstance(); + pageContext.setAttribute("quoteData4", quoteData4); + + QuoteDataBean quoteData[] = new QuoteDataBean[4]; + quoteData[0] = quoteData1; + quoteData[1] = quoteData2; + quoteData[2] = quoteData3; + quoteData[3] = quoteData4; + pageContext.setAttribute("quoteData", quoteData); + %> + +
    +
    + PING JSP EL:
    + Init time: <%=initTime%> +

    + Hit Count: <%=hitCount++%> +

    +
    + +

    + + someint1 = + <%=someint1%>
    someint2 = + <%=someint2%>
    somefloat1 = + <%=somefloat1%>
    somefloat2 = + <%=somefloat2%>
    +

    +


    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    EL TypeEL ExpressionsResult
    Integer Arithmetic\${someint1 + someint2 - someint1 * someint2 mod + someint1}${someint1 + someint2 - someint1 * someint2 mod someint1}
    Floating Point Arithmetic\${somefloat1 + somefloat2 - somefloat1 * + somefloat2 / somefloat1}${somefloat1 + somefloat2 - somefloat1 * somefloat2 / somefloat1}
    Logical Operations\${(someint1 < someint2) && (someint1 <= someint2) + || (someint1 == someint2) && !Boolean.FALSE}${(someint1 < someint2) && (someint1 <= someint2) || (someint1 == someint2) && !Boolean.FALSE}
    Indexing Operations\${quoteData3.symbol}
    + \${quoteData[2].symbol}
    \${quoteData4["symbol"]}
    + \${header["host"]}
    \${header.host}
    +
    ${quoteData3.symbol}
    ${quoteData[1].symbol}
    + ${quoteData4["symbol"]}
    ${header["host"]}
    + ${header.host} +
    Variable Scope Tests\${(quoteData3 == null) ? "null" : quoteData3}
    + \${(noSuchVariableAtAnyScope == null) ? "null" : noSuchVariableAtAnyScope} +
    ${(quoteData3 == null) ? "null" : quoteData3}
    + ${(noSuchVariableAtAnyScope == null) ? "null" : noSuchVariableAtAnyScope} +
    + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/PingServlet2Jsp.jsp b/src/test/resources/test-applications/daytrader8/src/main/webapp/PingServlet2Jsp.jsp new file mode 100644 index 00000000..dfe06f6c --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/PingServlet2Jsp.jsp @@ -0,0 +1,39 @@ + + + + + + + +PingJsp + + + <%!String initTime = (new java.util.Date()).toString();%> + +
    +
    Ping Servlet2JSP:
    +
    + Init time: <%=initTime%> +
    +
    + Message from Servlet: + <%= ab.getMsg() %> + + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/PingWebSocketBinary.html b/src/test/resources/test-applications/daytrader8/src/main/webapp/PingWebSocketBinary.html new file mode 100644 index 00000000..8aa71445 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/PingWebSocketBinary.html @@ -0,0 +1,92 @@ + + + + +WebSocket Primitive - PingWebSocketBinary + + + + + +

    +
    + Ping WebSocket Binary
    + Init time :
    0


    + Hit Count:
    0

    + +
    + + \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/PingWebSocketJson.html b/src/test/resources/test-applications/daytrader8/src/main/webapp/PingWebSocketJson.html new file mode 100644 index 00000000..026a40b1 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/PingWebSocketJson.html @@ -0,0 +1,112 @@ + + + + +WebSocket Primitive - PingWebSocketJson + + + + + +

    +
    + Ping WebSocket Json
    + Init time :
    0


    + Sent Count :
    0

    + Received Count:
    0

    + +
    + + \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/PingWebSocketTextAsync.html b/src/test/resources/test-applications/daytrader8/src/main/webapp/PingWebSocketTextAsync.html new file mode 100644 index 00000000..96dfe2bb --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/PingWebSocketTextAsync.html @@ -0,0 +1,90 @@ + + + + +WebSocket Primitive - PingWebSocketTextAsync + + + + + +

    +
    + Ping WebSocket Text Async
    + Init time :
    0


    + Hit Count:
    0

    + +
    + + \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/PingWebSocketTextSync.html b/src/test/resources/test-applications/daytrader8/src/main/webapp/PingWebSocketTextSync.html new file mode 100644 index 00000000..e454f185 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/PingWebSocketTextSync.html @@ -0,0 +1,90 @@ + + + + +WebSocket Primitive - PingWebSocketTextSync + + + + + +

    +
    + Ping WebSocket Text Sync
    + Init time :
    0


    + Hit Count:
    0

    + +
    + + \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/WAS_V7_64-bit_performance.pdf b/src/test/resources/test-applications/daytrader8/src/main/webapp/WAS_V7_64-bit_performance.pdf new file mode 100644 index 00000000..2f75b129 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/src/main/webapp/WAS_V7_64-bit_performance.pdf differ diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/beans.xml b/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/beans.xml new file mode 100644 index 00000000..99546567 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/beans.xml @@ -0,0 +1,22 @@ + + + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/classes/META-INF/DEPENDENCIES b/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/classes/META-INF/DEPENDENCIES new file mode 100644 index 00000000..cb8878a9 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/classes/META-INF/DEPENDENCIES @@ -0,0 +1,15 @@ +// ------------------------------------------------------------------ +// Transitive dependencies of this project determined from the +// maven pom organized by organization. +// ------------------------------------------------------------------ + +DayTrader :: Web Application + + +From: 'an unknown organization' + - Unnamed - taglibs:standard:jar:1.1.1 taglibs:standard:jar:1.1.1 + + + + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/classes/META-INF/LICENSE b/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/classes/META-INF/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/classes/META-INF/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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 + + http://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. diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/classes/META-INF/NOTICE b/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/classes/META-INF/NOTICE new file mode 100644 index 00000000..883959db --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/classes/META-INF/NOTICE @@ -0,0 +1,8 @@ + +DayTrader :: Web Application +Copyright 2005-2010 Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/classes/META-INF/persistence.xml b/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/classes/META-INF/persistence.xml new file mode 100644 index 00000000..4400b9fb --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/classes/META-INF/persistence.xml @@ -0,0 +1,34 @@ + + + + + + + jdbc/TradeDataSource + + com.ibm.websphere.samples.daytrader.entities.AccountDataBean + com.ibm.websphere.samples.daytrader.entities.AccountProfileDataBean + com.ibm.websphere.samples.daytrader.entities.HoldingDataBean + com.ibm.websphere.samples.daytrader.entities.OrderDataBean + com.ibm.websphere.samples.daytrader.entities.QuoteDataBean + true + NONE + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/classes/build.properties b/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/classes/build.properties new file mode 100644 index 00000000..65f995b4 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/classes/build.properties @@ -0,0 +1,16 @@ +## Licensed to the Apache Software Foundation (ASF) under one or more +## contributor license agreements. See the NOTICE file distributed with +## this work for additional information regarding copyright ownership. +## The ASF licenses this file to You 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 +## +## http://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. + +ejb_version=${pom.version} diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/classes/persistence.xml b/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/classes/persistence.xml new file mode 100644 index 00000000..4400b9fb --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/classes/persistence.xml @@ -0,0 +1,34 @@ + + + + + + + jdbc/TradeDataSource + + com.ibm.websphere.samples.daytrader.entities.AccountDataBean + com.ibm.websphere.samples.daytrader.entities.AccountProfileDataBean + com.ibm.websphere.samples.daytrader.entities.HoldingDataBean + com.ibm.websphere.samples.daytrader.entities.OrderDataBean + com.ibm.websphere.samples.daytrader.entities.QuoteDataBean + true + NONE + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/ejb-jar.xml b/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/ejb-jar.xml new file mode 100644 index 00000000..04cc73bf --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/ejb-jar.xml @@ -0,0 +1,446 @@ + + + DayTrader Enterprise Bean Definitions + + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/faces-config.xml b/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/faces-config.xml new file mode 100644 index 00000000..f3c699ea --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/faces-config.xml @@ -0,0 +1,120 @@ + + + + + /welcome.xhtml + + Ready to Trade + /tradehome.xhtml + + + welcome + /welcome.xhtml + + + + /register.xhtml + + Registration operation succeeded + /tradehome.xhtml + + + Registration operation failed + /register.xhtml + + + + /tradehome.xhtml + + quotes + /quote.xhtml + + + Registration operation failed + /register.xhtml + + + + /account.xhtml + + quotes + /quote.xhtml + + + Go to account + /account.xhtml + + + welcome + /welcome.xhtml + + + + /portfolio.xhtml + + quotes + /quote.xhtml + + + sell + /order.xhtml + + + + /marketSummary.xhtml + + quotes + /quote.xhtml + + + + /configure.xhtml + + welcome + /welcome.xhtml + + + config + /config.xhtml + + + database + /configure.xhtml + + + stats + /configure.xhtml + + + + /order.xhtml + + quotes + /quote.xhtml + + + + /quote.xhtml + + buy + /order.xhtml + + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/ibm-web-bnd.xml b/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/ibm-web-bnd.xml new file mode 100644 index 00000000..255c8fa6 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/ibm-web-bnd.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/ibm-web-ext.xml b/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/ibm-web-ext.xml new file mode 100644 index 00000000..93291de1 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/ibm-web-ext.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/web.xml b/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 00000000..ea357968 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,215 @@ + + + + DayTrader Web + + javax.faces.PROJECT_STAGE + Production + + + javax.faces.STATE_SAVING_METHOD + server + + + javax.faces.DEFAULT_SUFFIX + .xhtml + + + + Faces Servlet + javax.faces.webapp.FacesServlet + 0 + true + false + + + + Faces Servlet + *.faces + + + + 30 + + + + index.html + index.jsp + index.faces + + + + java.lang.Exception + /error.jsp + + + + 500 + /error.jsp + + + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/account.jsp b/src/test/resources/test-applications/daytrader8/src/main/webapp/account.jsp new file mode 100644 index 00000000..ebf882a4 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/account.jsp @@ -0,0 +1,392 @@ + + + + + +DayTrader Account Information + + + + + <%@ page + import="java.util.Collection, + java.util.Iterator, + java.math.BigDecimal,com.ibm.websphere.samples.daytrader.entities.OrderDataBean,com.ibm.websphere.samples.daytrader.util.FinancialUtils" + session="true" isThreadSafe="true" isErrorPage="false"%> + + + + + + + + + + + + + + + + + + + + + + + <% + boolean showAllOrders = request.getParameter("showAllOrders") == null ? false : true; + Collection closedOrders = (Collection) request.getAttribute("closedOrders"); + if ((closedOrders != null) && (closedOrders.size() > 0)) { + %> + + + + + + + <% + } + %> + +
    DayTrader AccountDayTrader
    HomeAccountMarket SummaryPortfolioQuotes/TradeLogoff
    +
    <%=new java.util.Date()%> +
    + Alert: The + following Order(s) have completed. +
    + + + <% + Iterator it = closedOrders.iterator(); + while (it.hasNext()) { + OrderDataBean closedOrderData = (OrderDataBean) it.next(); + %> + + + + + + + + + + + + + + + + + + + + + <% + } + %> + + +
    order + IDorder + statuscreation + datecompletion + datetxn + feetypesymbolquantity
    <%=closedOrderData.getOrderID()%><%=closedOrderData.getOrderStatus()%><%=closedOrderData.getOpenDate()%><%=closedOrderData.getCompletionDate()%><%=closedOrderData.getOrderFee()%><%=closedOrderData.getOrderType()%><%=FinancialUtils.printQuoteLink(closedOrderData.getSymbol())%><%=closedOrderData.getQuantity()%>
    +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    <%=results%>
    Account + Information
    account + created:<%=accountData.getCreationDate()%>last + login: <%=accountData.getLastLogin()%>
    account + ID<%=accountData.getAccountID()%>total + logins: <%=accountData.getLoginCount()%>cash + balance: <%=accountData.getBalance()%>
    user + ID:<%=accountData.getProfileID()%>total + logouts: <%=accountData.getLogoutCount()%>opening + balance: <%=accountData.getOpenBalance()%>
    + + + + + + + + + + + + + + +
    Total + Orders: <%=orderDataBeans.size()%>show + all orders
    + + + + + + + + + + + + + + + + <% + Iterator it = orderDataBeans.iterator(); + int count = 0; + while (it.hasNext()) { + if ((showAllOrders == false) && (count++ >= 5)) + break; + OrderDataBean orderData = (OrderDataBean) it.next(); + %> + + + + + + + + + + + + + <% + } + %> + +
    + Recent Orders +
    order + IDorder + Statuscreation + datecompletion + datetxn + feetypesymbolquantitypricetotal
    <%=orderData.getOrderID()%><%=orderData.getOrderStatus()%><%=orderData.getOpenDate()%><%=orderData.getCompletionDate()%><%=orderData.getOrderFee()%><%=orderData.getOrderType()%><%=FinancialUtils.printQuoteLink(orderData.getSymbol())%><%=orderData.getQuantity()%><%=orderData.getPrice()%><%=orderData.getPrice().multiply(new BigDecimal(orderData.getQuantity()))%>
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Account + Profile
    user + ID:full + name:
    password: + address: +
    confirm + password:
    credit + card:
    email + address:
    +
    +
    + + + + + + + + + + + + + +
    +
    +
    + + + + + + + +
    Note: Click any symbol + for a quote or to trade. + +
    + + +
    +
    +
    DayTrader + AccountDayTrader
    + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/account.xhtml b/src/test/resources/test-applications/daytrader8/src/main/webapp/account.xhtml new file mode 100644 index 00000000..30d87d69 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/account.xhtml @@ -0,0 +1,430 @@ + + + + + + DayTrader Account + + + + + +
    + + + +
    + +
    + + + + + + + + + + + +
    + + Alert: The following Order(s) have completed. + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    Account Information

    +
    + account created: + + + + last login: + + +
    + account ID: + + + + total logins: + + + + cash balance: + + +
    + user ID: + + + + total logouts: + + + + opening balance: + + +
    + + + + + + + + + + + + + + +
    +

    Total Orders: ${accountdata.numberOfOrders}

    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    Account Profile

    +
    + user ID: + + + + full name: + + +
    + password: + + + + + + address: + + +
    + confirm password: +
    +
    + + + credit card: + + + + +
    + email address: + + + + +
    +
    + + + + + + + + + +
    +
    +
    + + + + + + + +
    + + + + +
    +
    +
    +
    +
    +
    + + +
    + \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/accountImg.jsp b/src/test/resources/test-applications/daytrader8/src/main/webapp/accountImg.jsp new file mode 100644 index 00000000..b6c6a9d1 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/accountImg.jsp @@ -0,0 +1,409 @@ + + + + + +DayTrader Account Information + + + + + <%@ page + import="java.util.Collection, + java.util.Iterator, + java.math.BigDecimal,com.ibm.websphere.samples.daytrader.entities.OrderDataBean,com.ibm.websphere.samples.daytrader.util.FinancialUtils" + session="true" isThreadSafe="true" isErrorPage="false"%> + + + + + + + + + + + + + + + + + + + + + + <% + boolean showAllOrders = request.getParameter("showAllOrders") == null ? false : true; + Collection closedOrders = (Collection) request.getAttribute("closedOrders"); + if ((closedOrders != null) && (closedOrders.size() > 0)) { + %> + + + + + + + <% + } + %> + +
    DayTrader AccountDayTrader

    <%=new java.util.Date()%>
    + Alert: The + following Order(s) have completed. +
    + + + <% + Iterator it = closedOrders.iterator(); + while (it.hasNext()) { + OrderDataBean closedOrderData = (OrderDataBean) it.next(); + %> + + + + + + + + + + + + + + + + + + + + + <% + } + %> + + +
    order + IDorder + statuscreation + datecompletion + datetxn + feetypesymbolquantity
    <%=closedOrderData.getOrderID()%><%=closedOrderData.getOrderStatus()%><%=closedOrderData.getOpenDate()%><%=closedOrderData.getCompletionDate()%><%=closedOrderData.getOrderFee()%><%=closedOrderData.getOrderType()%><%=FinancialUtils.printQuoteLink(closedOrderData.getSymbol())%><%=closedOrderData.getQuantity()%>
    +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    <%=results%>
    Account + Information
    account + created:<%=accountData.getCreationDate()%>last + login: <%=accountData.getLastLogin()%>
    account + ID<%=accountData.getAccountID()%>total + logins: <%=accountData.getLoginCount()%>cash + balance: <%=accountData.getBalance()%>
    user + ID:<%=accountData.getProfileID()%>total + logouts: <%=accountData.getLogoutCount()%>opening + balance: <%=accountData.getOpenBalance()%>
    + + + + + + + + + + + + + + +
    Total + Orders: <%=orderDataBeans.size()%>show + all orders
    + + + + + + + + + + + + + + + + <% + Iterator it = orderDataBeans.iterator(); + int count = 0; + while (it.hasNext()) { + if ((showAllOrders == false) && (count++ >= 5)) + break; + OrderDataBean orderData = (OrderDataBean) it.next(); + %> + + + + + + + + + + + + + <% + } + %> + +
    + Recent Orders +
    order + IDorder + Statuscreation + datecompletion + datetxn + feetypesymbolquantitypricetotal
    <%=orderData.getOrderID()%><%=orderData.getOrderStatus()%><%=orderData.getOpenDate()%><%=orderData.getCompletionDate()%><%=orderData.getOrderFee()%><%=orderData.getOrderType()%><%=FinancialUtils.printQuoteLink(orderData.getSymbol())%><%=orderData.getQuantity()%><%=orderData.getPrice()%><%=orderData.getPrice().multiply(new BigDecimal(orderData.getQuantity()))%>
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Account + Profile
    user + ID:full + name:
    password: + address: +
    confirm + password:
    credit + card:
    email + address:
    +
    +
    + + + + + + + + + + + + + + + + +
    +
    +
    + + + + + + + +
    Note: Click any symbol + for a quote or to trade. + +
    + + +
    +
    +
    DayTrader + AccountDayTrader
    + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/config.jsp b/src/test/resources/test-applications/daytrader8/src/main/webapp/config.jsp new file mode 100644 index 00000000..119712d8 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/config.jsp @@ -0,0 +1,251 @@ + + + + + + +Welcome to DayTrader + + + <%@ page + import="com.ibm.websphere.samples.daytrader.util.TradeConfig" + session="false" isThreadSafe="true" isErrorPage="false"%> + + + + + + + + + + + + + +
    DayTrader + ConfigurationDayTrader
    +
    +
    + + <% + String status; + status = (String) request.getAttribute("status"); + if (status != null) { + %> + + + + + + + + +
    <% + out.print(status); + %> +
    + <% + } + %> + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    The current DayTrader runtime + configuration is detailed below. View and + optionally update run-time parameters.  
    +
    NOTE: Parameters settings will + return to default on server restart. To + make configuration settings persistent across + application server stop/starts, edit the daytrader.props + file inside daytrader-ee7-web.war (which is inside the + daytrader ear file).
    +
    +
    Run-Time Mode +

    + <% + String configParm = "RunTimeMode"; + String names[] = TradeConfig.getRunTimeModeNames(); + int index = TradeConfig.getRunTimeMode(); + for (int i = 0; i < names.length; i++) { + out.print(" " + names[i] + "
    "); + } + %> +


    Run Time Mode determines server + implementation of the TradeServices to use in + the DayTrader application Enterprise Java Beans + including Session, Entity and Message beans or + Direct mode which uses direct database and JMS + access. See DayTrader + FAQ for details.
    Order-Processing Mode +

    + <% + configParm = "OrderProcessingMode"; + names = TradeConfig.getOrderProcessingModeNames(); + index = TradeConfig.getOrderProcessingMode(); + for (int i = 0; i < names.length; i++) { + out.print(" " + names[i] + "
    "); + } + %> +


    Order Processing Mode determines + the mode for completing stock purchase and sell + operations. Synchronous mode completes the order + immediately. Asychronous_2-Phase performs a + 2-phase commit over the EJB Entity/DB and + MDB/JMS transactions. See DayTrader FAQ for + details.
    WebInterface +

    + <% + configParm = "WebInterface"; + names = TradeConfig.getWebInterfaceNames(); + index = TradeConfig.getWebInterface(); + for (int i = 0; i < names.length; i++) { + out.print(" " + names[i] + "
    "); + } + %> +

    This setting determines the Web interface + technology used, JSPs or JSPs with static images + and GIFs.
    Miscellaneous + Settings
    DayTrader Max Users
    +
    + Trade Max Quotes
    By default the DayTrader database is + populated with 15,000 users (uid:0 - uid:199) + and 10,000 quotes (s:0 - s:399).
    +
    Market Summary Interval
    +
    < 0 Do not perform Market Summary + Operations.
    = 0 Perform market Summary + on every request.

    > 0 number of + seconds between Market Summary Operations
    +
    Primitive Iteration
    +
    By default the DayTrader primitives are + execute one operation per web request. Change + this value to repeat operations multiple times + per web request.
    + name="EnablePublishQuotePriceChange"> Publish Quote Updates
    Publish quote price changes to a JMS topic.
    +
    Percent of Quote Price Changes to List
    +
    The percent of recent trades to display on the Market Summary websocket.
    + name="DisplayOrderAlerts"> Display Order Alerts
    Display completed order alerts.
    +
    + name="EnableLongRun"> Enable long run support
    Enable long run support by disabling the + show all orders query performed on the Account + page.
    +
    +
    + + + + + + + + + + + + + + +
    +
    +
    DayTrader + ConfigurationDayTrader
    +
    + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/config.xhtml b/src/test/resources/test-applications/daytrader8/src/main/webapp/config.xhtml new file mode 100644 index 00000000..c0b3d78c --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/config.xhtml @@ -0,0 +1,232 @@ + + + + + DayTrader Config + + + + +
    + + +
    +
    + + + + + + + + + +
    + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    The current DayTrader runtime configuration is detailed below. View and optionally update run-time parameters.  

    +
    +
    + NOTE: + Parameters settings will return to default on server restart. To + make configuration settings persistent across + application server stop/starts, edit the daytrader.props + file inside daytrader-ee7-web.war (which is inside the + daytrader ear file). +
    +
    + Run-Time Mode +

    + + + +

    +
    +
    + Run Time Mode determines server implementation of the TradeServices to use in the DayTrader application Enterprise Java Beans including + Session, Entity and Message beans or Direct mode which uses direct database and JMS access. See + DayTrader FAQ + for details. +
    +
    + Order-Processing Mode +

    + + + +

    +
    +
    + Order Processing Mode determines the mode for completing stock purchase and sell operations. Synchronous mode completes the order + immediately. Asychronous_2-Phase performs a 2-phase commit over the EJB Entity/DB and MDB/JMS transactions. See + DayTrader FAQ + for details. + +
    +
    + WebInterface +

    + + + +

    +
    This setting determines the Web interface technology used, JSPs or JSPs with static images and GIFs.
    + Miscellaneous Settings +
    + DayTrader Max Users +
    + +
    + Trade Max Quotes +
    + +
    + By default the DayTrader database is populated with 15000 users (uid:0 - uid:14999) and 10000 quotes (s:0 - s:9999). +
    +
    + Market Summary Interval +
    + +
    + < 0 Do not perform Market Summary Operations. +
    + = 0 Perform market Summary on every request. +
    + > 0 number of seconds between Market Summary Operations +
    +
    + Primitive Iteration +
    + +
    By default the DayTrader primitives are execute one operation per web request. Change this value to repeat + operations multiple times per web request.
    + + Publish Quote Updates +
    +
    + Publish quote price changes to a JMS topic. +
    +
    + Percent of Quote Price Changes to List +
    + +
    The percent of recent trades to display on the Market Summary websocket.
    + + Display Order Alerts +
    +
    + Display completed order alerts +
    +
    + + Enable long run support +
    +
    + Enable long run support by disabling the show all orders query performed on the Account page. +
    +
    + +
    +
    +
    +
    +
    + +
    + \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/configure.html b/src/test/resources/test-applications/daytrader8/src/main/webapp/configure.html new file mode 100644 index 00000000..a5669233 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/configure.html @@ -0,0 +1,115 @@ + + + + + + +Configuration and utilities + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    Configuration Utilities

    +
    Benchmark + Configuration
    Tools +
    Description +
    Reset + DayTrader
    (to be done before each + run) +
    Reset the DayTrader runtime to a clean starting + point by logging off all users, removing new + registrations and other general cleanup. For + consistent results this URL should be run before + each Trade run. +
    Configure + DayTrader run-time parametersThis link provides an interface to set + configuration parameters that control DayTrader + run-time characteristics such as using EJBs or JDBC. + This link also provides utilities such as setting + the UID and Password for a remote or protected + database when using JDBC.
    (Re)-create +  DayTrader Database Tables and + IndexesThis link is used to (a) initially create or + (b) drop and re-create the DayTrader tables. A + DayTrader database should exist before doing + this action, the existing DayTrader tables, if + any, are dropped, then new tables and indexes are + created. Please stop and re-start the + Daytrader application (or your application + server) after this action and then use the + "Repopulate DayTrader Database" link below to + repopulate the new database tables. +
    (Re)-populate +  DayTrader DatabaseThis link is used to initially populate or + re-populate the DayTrader database with fictitious + users (uid:0, uid:1, ...) and stocks (s:0, s:1, + ...). First all existing users and stocks are + deleted (if any). The database is then populated + with a new set of DayTrader users and stocks. This + option does not drop and recreate the Daytrader db + tables.
    Test + DayTrader ScenarioThis links pops up a browser to manually step + through a DayTrader scenario by hitting + "Reload" on your browser
    DayTrader + VersionDayTrader application version and change + history information
    + + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/configure.xhtml b/src/test/resources/test-applications/daytrader8/src/main/webapp/configure.xhtml new file mode 100644 index 00000000..9e334bd1 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/configure.xhtml @@ -0,0 +1,148 @@ + + + + + DayTrader Configure + + + + + +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    Configuration Utilities

    +
    + + Benchmark Configuration Tools + + + + + Description + +
    + + + Reset DayTrader +
    + (to be done before each run) +
    +
    +
    + Reset the DayTrader runtime to a clean starting point by logging off all users, removing new registrations and other general cleanup. For + consistent results this URL should be run + before each + Trade run. +
    + + Configure DayTrader run-time parameters + + This link provides an interface to set configuration parameters that control DayTrader run-time characteristics + such as using EJBs or JDBC. This link also provides utilities such as setting the UID and Password for a remote or protected database when + using JDBC.
    + + (Re)-create  DayTrader Database Tables and Indexes + + + This link is used to (a) initially create or (b) drop and re-create the DayTrader tables. + A DayTrader database should exist before doing this action + , the existing DayTrader tables, if any, are dropped, then new tables and indexes are created. + Please stop and re-start the Daytrader application (or your application server) after this action and then use the "Repopulate + DayTrader Database" link below to repopulate the new database tables. +
    + + (Re)-populate  DayTrader Database + + This link is used to initially populate or re-populate the DayTrader database with fictitious users (uid:0, + uid:1, ...) and stocks (s:0, s:1, ...). First all existing users and stocks are deleted (if any). The database is then populated with a new + set of DayTrader users and stocks. This option does not drop and recreate the Daytrader db tables.
    + DayTrader Version + DayTrader application version and change history information
    +
    +
    +
    +
    + + +
    + \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/contentHome.html b/src/test/resources/test-applications/daytrader8/src/main/webapp/contentHome.html new file mode 100644 index 00000000..a30929c9 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/contentHome.html @@ -0,0 +1,87 @@ + + + + + +Daytrader performance benchmark sample overview + + + + + + + + + + + + + + +
    +
    +
    +

    + Overview +

    +
    + The + Daytrader performance benchmark sample provides a suite of workloads for characterizing performance of + Java EE Application Servers. The workloads + consist of an end to end web application and a full set of primitives. The applications are a + collection of Java classes, Java Servlets, JavaServer Pages, and Enterprise Java + Beans built to open Java EE APIs. Together these provide versatile and portable test cases + designed to measure aspects of scalability and performance. + +
    +

    + +
    DayTrader J2EE Components
    + Model-View-Controller Architecture +

    +
    + DayTrader
    + DayTrader is an end-to-end benchmark + and performance sample application. It provides a + real world Java EE workload.

    DayTrader's new + design spans Java EE 7, including the new WebSockets specification. Other Java EE features include JSPs, Servlets, EJBs, JPA, JDBC, JSF, JMS, MDBs, and + transactions (synchronous and asynchronous/2-phase commit).

    Primitives
    +
    The Primitives provide a + set of workloads to individually test various + components of an Application Server. + The primitives leverage the DayTrader + application infrastructure to test specific + Java EE components such as the servlet + engine, JSP support, EJB Entitiy, Session and + Message Driven beans, HTTP Session support and + more. + +
    +
    + Additional + overview information is included in the FAQ + +
    +
    +
    +
    + + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/dbscripts/db2/Table.ddl b/src/test/resources/test-applications/daytrader8/src/main/webapp/dbscripts/db2/Table.ddl new file mode 100644 index 00000000..124e43a2 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/dbscripts/db2/Table.ddl @@ -0,0 +1,289 @@ +## (C) Copyright IBM Corporation 2015. +## +## 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 +## +## http://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. + +DROP TABLE HOLDINGEJB; +DROP TABLE ACCOUNTPROFILEEJB; +DROP TABLE QUOTEEJB; +DROP TABLE KEYGENEJB; +DROP TABLE ACCOUNTEJB; +DROP TABLE ORDEREJB; + +DROP TABLESPACE "HOLDING_TS"; +DROP TABLESPACE "ACCOUNTP_TS"; +DROP TABLESPACE "QUOTE_TS"; + +DROP TABLESPACE "ACCOUNT_ITS1"; +DROP TABLESPACE "ACCOUNT_ITS2"; +DROP TABLESPACE "ACCOUNT_ITS3"; +DROP TABLESPACE "ACCOUNT_ITS4"; +DROP TABLESPACE "ACCOUNT_ITS5"; +DROP TABLESPACE "ACCOUNT_ITS6"; +DROP TABLESPACE "ACCOUNT_ITS7"; + +DROP TABLESPACE "QUOTE_ITS1"; +DROP TABLESPACE "QUOTE_ITS2"; +DROP TABLESPACE "QUOTE_ITS3"; +DROP TABLESPACE "QUOTE_ITS4"; +DROP TABLESPACE "QUOTE_ITS5"; +DROP TABLESPACE "QUOTE_ITS6"; +DROP TABLESPACE "QUOTE_ITS7"; +DROP TABLESPACE "QUOTE_ITS8"; +DROP TABLESPACE "QUOTE_ITS9"; +DROP TABLESPACE "QUOTE_ITS10"; +DROP TABLESPACE "QUOTE_ITS11"; +DROP TABLESPACE "QUOTE_ITS12"; +DROP TABLESPACE "QUOTE_ITS13"; +DROP TABLESPACE "QUOTE_ITS14"; +DROP TABLESPACE "QUOTE_ITS15"; +DROP TABLESPACE "QUOTE_ITS16"; +DROP TABLESPACE "QUOTE_ITS17"; +DROP TABLESPACE "QUOTE_ITS18"; +DROP TABLESPACE "QUOTE_ITS19"; +DROP TABLESPACE "QUOTE_ITS20"; + +DROP TABLESPACE "KEYGENE_TS"; +DROP TABLESPACE "ACCOUNTE_TS"; +DROP TABLESPACE "ORDER_TS"; + +DROP BUFFERPOOL "HOLDING_BP"; +CREATE BUFFERPOOL "HOLDING_BP" SIZE AUTOMATIC PAGESIZE 4096; +DROP BUFFERPOOL "ACCOUNTP_BP"; +CREATE BUFFERPOOL "ACCOUNTP_BP" SIZE AUTOMATIC PAGESIZE 4096; +DROP BUFFERPOOL "QUOTE_BP"; +CREATE BUFFERPOOL "QUOTE_BP" SIZE AUTOMATIC PAGESIZE 4096; + + +DROP BUFFERPOOL "ACCOUNT_IBP1"; +CREATE BUFFERPOOL "ACCOUNT_IBP1" SIZE AUTOMATIC PAGESIZE 4096; +DROP BUFFERPOOL "ACCOUNT_IBP2"; +CREATE BUFFERPOOL "ACCOUNT_IBP2" SIZE AUTOMATIC PAGESIZE 4096; +DROP BUFFERPOOL "ACCOUNT_IBP3"; +CREATE BUFFERPOOL "ACCOUNT_IBP3" SIZE AUTOMATIC PAGESIZE 4096; +DROP BUFFERPOOL "ACCOUNT_IBP4"; +CREATE BUFFERPOOL "ACCOUNT_IBP4" SIZE AUTOMATIC PAGESIZE 4096; +DROP BUFFERPOOL "ACCOUNT_IBP5"; +CREATE BUFFERPOOL "ACCOUNT_IBP5" SIZE AUTOMATIC PAGESIZE 4096; +DROP BUFFERPOOL "ACCOUNT_IBP6"; +CREATE BUFFERPOOL "ACCOUNT_IBP6" SIZE AUTOMATIC PAGESIZE 4096; +DROP BUFFERPOOL "ACCOUNT_IBP7"; +CREATE BUFFERPOOL "ACCOUNT_IBP7" SIZE AUTOMATIC PAGESIZE 4096; + +DROP BUFFERPOOL "QUOTE_IBP1"; +CREATE BUFFERPOOL "QUOTE_IBP1" SIZE AUTOMATIC PAGESIZE 4096; +DROP BUFFERPOOL "QUOTE_IBP2"; +CREATE BUFFERPOOL "QUOTE_IBP2" SIZE AUTOMATIC PAGESIZE 4096; +DROP BUFFERPOOL "QUOTE_IBP3"; +CREATE BUFFERPOOL "QUOTE_IBP3" SIZE AUTOMATIC PAGESIZE 4096; +DROP BUFFERPOOL "QUOTE_IBP4"; +CREATE BUFFERPOOL "QUOTE_IBP4" SIZE AUTOMATIC PAGESIZE 4096; +DROP BUFFERPOOL "QUOTE_IBP5"; +CREATE BUFFERPOOL "QUOTE_IBP5" SIZE AUTOMATIC PAGESIZE 4096; +DROP BUFFERPOOL "QUOTE_IBP6"; +CREATE BUFFERPOOL "QUOTE_IBP6" SIZE AUTOMATIC PAGESIZE 4096; +DROP BUFFERPOOL "QUOTE_IBP7"; +CREATE BUFFERPOOL "QUOTE_IBP7" SIZE AUTOMATIC PAGESIZE 4096; +DROP BUFFERPOOL "QUOTE_IBP8"; +CREATE BUFFERPOOL "QUOTE_IBP8" SIZE AUTOMATIC PAGESIZE 4096; +DROP BUFFERPOOL "QUOTE_IBP9"; +CREATE BUFFERPOOL "QUOTE_IBP9" SIZE AUTOMATIC PAGESIZE 4096; +DROP BUFFERPOOL "QUOTE_IBP10"; +CREATE BUFFERPOOL "QUOTE_IBP10" SIZE AUTOMATIC PAGESIZE 4096; +DROP BUFFERPOOL "QUOTE_IBP11"; +CREATE BUFFERPOOL "QUOTE_IBP11" SIZE AUTOMATIC PAGESIZE 4096; +DROP BUFFERPOOL "QUOTE_IBP12"; +CREATE BUFFERPOOL "QUOTE_IBP12" SIZE AUTOMATIC PAGESIZE 4096; +DROP BUFFERPOOL "QUOTE_IBP13"; +CREATE BUFFERPOOL "QUOTE_IBP13" SIZE AUTOMATIC PAGESIZE 4096; +DROP BUFFERPOOL "QUOTE_IBP14"; +CREATE BUFFERPOOL "QUOTE_IBP14" SIZE AUTOMATIC PAGESIZE 4096; +DROP BUFFERPOOL "QUOTE_IBP15"; +CREATE BUFFERPOOL "QUOTE_IBP15" SIZE AUTOMATIC PAGESIZE 4096; +DROP BUFFERPOOL "QUOTE_IBP16"; +CREATE BUFFERPOOL "QUOTE_IBP16" SIZE AUTOMATIC PAGESIZE 4096; +DROP BUFFERPOOL "QUOTE_IBP17"; +CREATE BUFFERPOOL "QUOTE_IBP17" SIZE AUTOMATIC PAGESIZE 4096; +DROP BUFFERPOOL "QUOTE_IBP18"; +CREATE BUFFERPOOL "QUOTE_IBP18" SIZE AUTOMATIC PAGESIZE 4096; +DROP BUFFERPOOL "QUOTE_IBP19"; +CREATE BUFFERPOOL "QUOTE_IBP19" SIZE AUTOMATIC PAGESIZE 4096; +DROP BUFFERPOOL "QUOTE_IBP20"; +CREATE BUFFERPOOL "QUOTE_IBP20" SIZE AUTOMATIC PAGESIZE 4096; + + + +DROP BUFFERPOOL "KEYGENE_BP"; +CREATE BUFFERPOOL "KEYGENE_BP" SIZE AUTOMATIC PAGESIZE 4096; +DROP BUFFERPOOL "ACCOUNTE_BP"; +CREATE BUFFERPOOL "ACCOUNTE_BP" SIZE AUTOMATIC PAGESIZE 4096; +DROP BUFFERPOOL "ORDER_BP"; +CREATE BUFFERPOOL "ORDER_BP" SIZE AUTOMATIC PAGESIZE 4096; + +CREATE LARGE TABLESPACE "HOLDING_TS" PAGESIZE 4096 MANAGED BY AUTOMATIC STORAGE BUFFERPOOL "HOLDING_BP" AUTORESIZE YES NO FILE SYSTEM CACHING; +CREATE LARGE TABLESPACE "ACCOUNTP_TS" PAGESIZE 4096 MANAGED BY AUTOMATIC STORAGE BUFFERPOOL "ACCOUNTP_BP" AUTORESIZE YES NO FILE SYSTEM CACHING; +CREATE LARGE TABLESPACE "QUOTE_TS" PAGESIZE 4096 MANAGED BY AUTOMATIC STORAGE BUFFERPOOL "QUOTE_BP" AUTORESIZE YES NO FILE SYSTEM CACHING; + +CREATE LARGE TABLESPACE "QUOTE_ITS1" PAGESIZE 4096 MANAGED BY AUTOMATIC STORAGE BUFFERPOOL "QUOTE_IBP1" AUTORESIZE YES NO FILE SYSTEM CACHING; +CREATE LARGE TABLESPACE "QUOTE_ITS2" PAGESIZE 4096 MANAGED BY AUTOMATIC STORAGE BUFFERPOOL "QUOTE_IBP2" AUTORESIZE YES NO FILE SYSTEM CACHING; +CREATE LARGE TABLESPACE "QUOTE_ITS3" PAGESIZE 4096 MANAGED BY AUTOMATIC STORAGE BUFFERPOOL "QUOTE_IBP3" AUTORESIZE YES NO FILE SYSTEM CACHING; +CREATE LARGE TABLESPACE "QUOTE_ITS4" PAGESIZE 4096 MANAGED BY AUTOMATIC STORAGE BUFFERPOOL "QUOTE_IBP4" AUTORESIZE YES NO FILE SYSTEM CACHING; +CREATE LARGE TABLESPACE "QUOTE_ITS5" PAGESIZE 4096 MANAGED BY AUTOMATIC STORAGE BUFFERPOOL "QUOTE_IBP5" AUTORESIZE YES NO FILE SYSTEM CACHING; +CREATE LARGE TABLESPACE "QUOTE_ITS6" PAGESIZE 4096 MANAGED BY AUTOMATIC STORAGE BUFFERPOOL "QUOTE_IBP6" AUTORESIZE YES NO FILE SYSTEM CACHING; +CREATE LARGE TABLESPACE "QUOTE_ITS7" PAGESIZE 4096 MANAGED BY AUTOMATIC STORAGE BUFFERPOOL "QUOTE_IBP7" AUTORESIZE YES NO FILE SYSTEM CACHING; +CREATE LARGE TABLESPACE "QUOTE_ITS8" PAGESIZE 4096 MANAGED BY AUTOMATIC STORAGE BUFFERPOOL "QUOTE_IBP8" AUTORESIZE YES NO FILE SYSTEM CACHING; +CREATE LARGE TABLESPACE "QUOTE_ITS9" PAGESIZE 4096 MANAGED BY AUTOMATIC STORAGE BUFFERPOOL "QUOTE_IBP9" AUTORESIZE YES NO FILE SYSTEM CACHING; +CREATE LARGE TABLESPACE "QUOTE_ITS10" PAGESIZE 4096 MANAGED BY AUTOMATIC STORAGE BUFFERPOOL "QUOTE_IBP10" AUTORESIZE YES NO FILE SYSTEM CACHING; +CREATE LARGE TABLESPACE "QUOTE_ITS11" PAGESIZE 4096 MANAGED BY AUTOMATIC STORAGE BUFFERPOOL "QUOTE_IBP11" AUTORESIZE YES NO FILE SYSTEM CACHING; +CREATE LARGE TABLESPACE "QUOTE_ITS12" PAGESIZE 4096 MANAGED BY AUTOMATIC STORAGE BUFFERPOOL "QUOTE_IBP12" AUTORESIZE YES NO FILE SYSTEM CACHING; +CREATE LARGE TABLESPACE "QUOTE_ITS13" PAGESIZE 4096 MANAGED BY AUTOMATIC STORAGE BUFFERPOOL "QUOTE_IBP13" AUTORESIZE YES NO FILE SYSTEM CACHING; +CREATE LARGE TABLESPACE "QUOTE_ITS14" PAGESIZE 4096 MANAGED BY AUTOMATIC STORAGE BUFFERPOOL "QUOTE_IBP14" AUTORESIZE YES NO FILE SYSTEM CACHING; +CREATE LARGE TABLESPACE "QUOTE_ITS15" PAGESIZE 4096 MANAGED BY AUTOMATIC STORAGE BUFFERPOOL "QUOTE_IBP15" AUTORESIZE YES NO FILE SYSTEM CACHING; +CREATE LARGE TABLESPACE "QUOTE_ITS16" PAGESIZE 4096 MANAGED BY AUTOMATIC STORAGE BUFFERPOOL "QUOTE_IBP16" AUTORESIZE YES NO FILE SYSTEM CACHING; +CREATE LARGE TABLESPACE "QUOTE_ITS17" PAGESIZE 4096 MANAGED BY AUTOMATIC STORAGE BUFFERPOOL "QUOTE_IBP17" AUTORESIZE YES NO FILE SYSTEM CACHING; +CREATE LARGE TABLESPACE "QUOTE_ITS18" PAGESIZE 4096 MANAGED BY AUTOMATIC STORAGE BUFFERPOOL "QUOTE_IBP18" AUTORESIZE YES NO FILE SYSTEM CACHING; +CREATE LARGE TABLESPACE "QUOTE_ITS19" PAGESIZE 4096 MANAGED BY AUTOMATIC STORAGE BUFFERPOOL "QUOTE_IBP19" AUTORESIZE YES NO FILE SYSTEM CACHING; +CREATE LARGE TABLESPACE "QUOTE_ITS20" PAGESIZE 4096 MANAGED BY AUTOMATIC STORAGE BUFFERPOOL "QUOTE_IBP20" AUTORESIZE YES NO FILE SYSTEM CACHING; + +CREATE LARGE TABLESPACE "ACCOUNT_ITS1" PAGESIZE 4096 MANAGED BY AUTOMATIC STORAGE BUFFERPOOL "ACCOUNT_IBP1" AUTORESIZE YES NO FILE SYSTEM CACHING; +CREATE LARGE TABLESPACE "ACCOUNT_ITS2" PAGESIZE 4096 MANAGED BY AUTOMATIC STORAGE BUFFERPOOL "ACCOUNT_IBP2" AUTORESIZE YES NO FILE SYSTEM CACHING; +CREATE LARGE TABLESPACE "ACCOUNT_ITS3" PAGESIZE 4096 MANAGED BY AUTOMATIC STORAGE BUFFERPOOL "ACCOUNT_IBP3" AUTORESIZE YES NO FILE SYSTEM CACHING; +CREATE LARGE TABLESPACE "ACCOUNT_ITS4" PAGESIZE 4096 MANAGED BY AUTOMATIC STORAGE BUFFERPOOL "ACCOUNT_IBP4" AUTORESIZE YES NO FILE SYSTEM CACHING; +CREATE LARGE TABLESPACE "ACCOUNT_ITS5" PAGESIZE 4096 MANAGED BY AUTOMATIC STORAGE BUFFERPOOL "ACCOUNT_IBP5" AUTORESIZE YES NO FILE SYSTEM CACHING; +CREATE LARGE TABLESPACE "ACCOUNT_ITS6" PAGESIZE 4096 MANAGED BY AUTOMATIC STORAGE BUFFERPOOL "ACCOUNT_IBP6" AUTORESIZE YES NO FILE SYSTEM CACHING; +CREATE LARGE TABLESPACE "ACCOUNT_ITS7" PAGESIZE 4096 MANAGED BY AUTOMATIC STORAGE BUFFERPOOL "ACCOUNT_IBP7" AUTORESIZE YES NO FILE SYSTEM CACHING; + +CREATE LARGE TABLESPACE "KEYGENE_TS" PAGESIZE 4096 MANAGED BY AUTOMATIC STORAGE BUFFERPOOL "KEYGENE_BP" AUTORESIZE YES NO FILE SYSTEM CACHING; +CREATE LARGE TABLESPACE "ACCOUNTE_TS" PAGESIZE 4096 MANAGED BY AUTOMATIC STORAGE BUFFERPOOL "ACCOUNTE_BP" AUTORESIZE YES NO FILE SYSTEM CACHING; +CREATE LARGE TABLESPACE "ORDER_TS" PAGESIZE 4096 MANAGED BY AUTOMATIC STORAGE BUFFERPOOL "ORDER_BP" AUTORESIZE YES NO FILE SYSTEM CACHING; + +CREATE TABLE HOLDINGEJB + (PURCHASEPRICE DECIMAL(14, 2), + HOLDINGID INTEGER NOT NULL, + QUANTITY DOUBLE NOT NULL, + PURCHASEDATE TIMESTAMP, + ACCOUNT_ACCOUNTID INTEGER, + QUOTE_SYMBOL VARCHAR(250)) IN "HOLDING_TS" INDEX IN "HOLDING_TS"; + +ALTER TABLE HOLDINGEJB + ADD CONSTRAINT PK_HOLDINGEJB PRIMARY KEY (HOLDINGID); + +ALTER TABLE HOLDINGEJB APPEND ON; + +CREATE TABLE ACCOUNTPROFILEEJB + (ADDRESS VARCHAR(250), + PASSWD VARCHAR(250), + USERID VARCHAR(250) NOT NULL, + EMAIL VARCHAR(250), + CREDITCARD VARCHAR(250), + FULLNAME VARCHAR(250)) IN "ACCOUNTP_TS" INDEX IN "ACCOUNTP_TS"; + +ALTER TABLE ACCOUNTPROFILEEJB + ADD CONSTRAINT PK_ACCOUNTPROFILE2 PRIMARY KEY (USERID); + +CREATE TABLE QUOTEEJB + (LOW DECIMAL(14, 2), + OPEN1 DECIMAL(14, 2), + VOLUME DOUBLE NOT NULL, + PRICE DECIMAL(14, 2), + HIGH DECIMAL(14, 2), + COMPANYNAME VARCHAR(250), + SYMBOL VARCHAR(250) NOT NULL, + CHANGE1 DOUBLE NOT NULL) IN "QUOTE_TS" INDEX IN "QUOTE_TS" PARTITION BY RANGE("SYMBOL") + (PART "PART0" STARTING('s:0') ENDING('s:1000') IN "QUOTE_TS" INDEX IN "QUOTE_ITS1", + PART "PART10" ENDING('s:10999') IN "QUOTE_TS" INDEX IN "QUOTE_ITS11", + PART "PART11" ENDING('s:11999') IN "QUOTE_TS" INDEX IN "QUOTE_ITS12", + PART "PART12" ENDING('s:12999') IN "QUOTE_TS" INDEX IN "QUOTE_ITS13", + PART "PART13" ENDING('s:13999') IN "QUOTE_TS" INDEX IN "QUOTE_ITS14", + PART "PART14" ENDING('s:14999') IN "QUOTE_TS" INDEX IN "QUOTE_ITS15", + PART "PART15" ENDING('s:15999') IN "QUOTE_TS" INDEX IN "QUOTE_ITS16", + PART "PART16" ENDING('s:16999') IN "QUOTE_TS" INDEX IN "QUOTE_ITS17", + PART "PART17" ENDING('s:17999') IN "QUOTE_TS" INDEX IN "QUOTE_ITS18", + PART "PART18" ENDING('s:18999') IN "QUOTE_TS" INDEX IN "QUOTE_ITS19", + PART "PART1" ENDING('s:1999') IN "QUOTE_TS" INDEX IN "QUOTE_ITS2", + PART "PART19" ENDING('s:20001') IN "QUOTE_TS" INDEX IN "QUOTE_ITS20", + PART "PART2" ENDING('s:2999') IN "QUOTE_TS" INDEX IN "QUOTE_ITS3", + PART "PART3" ENDING('s:3999') IN "QUOTE_TS" INDEX IN "QUOTE_ITS4", + PART "PART4" ENDING('s:4999') IN "QUOTE_TS" INDEX IN "QUOTE_ITS5", + PART "PART5" ENDING('s:5999') IN "QUOTE_TS" INDEX IN "QUOTE_ITS6", + PART "PART6" ENDING('s:6999') IN "QUOTE_TS" INDEX IN "QUOTE_ITS7", + PART "PART7" ENDING('s:7999') IN "QUOTE_TS" INDEX IN "QUOTE_ITS8", + PART "PART8" ENDING('s:8999') IN "QUOTE_TS" INDEX IN "QUOTE_ITS9", + PART "PART9" ENDING('s:9999') IN "QUOTE_TS" INDEX IN "QUOTE_ITS10"); + +CREATE UNIQUE INDEX QUOTE_SYM ON QUOTEEJB(SYMBOL); + +ALTER TABLE QUOTEEJB + ADD CONSTRAINT PK_QUOTEEJB PRIMARY KEY (SYMBOL); + + +CREATE TABLE KEYGENEJB + (KEYVAL INTEGER NOT NULL, + KEYNAME VARCHAR(250) NOT NULL) IN "KEYGENE_TS" INDEX IN "KEYGENE_TS"; + +ALTER TABLE KEYGENEJB + ADD CONSTRAINT PK_KEYGENEJB PRIMARY KEY (KEYNAME); + +INSERT INTO KEYGENEJB (KEYNAME,KEYVAL) VALUES ('account', 0); +INSERT INTO KEYGENEJB (KEYNAME,KEYVAL) VALUES ('holding', 0); +INSERT INTO KEYGENEJB (KEYNAME,KEYVAL) VALUES ('order', 0); + +CREATE TABLE ACCOUNTEJB + (CREATIONDATE TIMESTAMP, + OPENBALANCE DECIMAL(14, 2), + LOGOUTCOUNT INTEGER NOT NULL, + BALANCE DECIMAL(14, 2), + ACCOUNTID INTEGER NOT NULL, + LASTLOGIN TIMESTAMP, + LOGINCOUNT INTEGER NOT NULL, + PROFILE_USERID VARCHAR(250)) IN "ACCOUNTE_TS" INDEX IN "ACCOUNTE_TS" PARTITION BY RANGE("ACCOUNTID") + (PART "PART0" STARTING(0) ENDING(4999) IN "ACCOUNTE_TS" INDEX IN "ACCOUNT_ITS1", + PART "PART1" ENDING(9999) IN "ACCOUNTE_TS" INDEX IN "ACCOUNT_ITS2", + PART "PART2" ENDING(14999) IN "ACCOUNTE_TS" INDEX IN "ACCOUNT_ITS3", + PART "PART3" ENDING(19999) IN "ACCOUNTE_TS" INDEX IN "ACCOUNT_ITS4", + PART "PART4" ENDING(24999) IN "ACCOUNTE_TS" INDEX IN "ACCOUNT_ITS5", + PART "PART5" ENDING(300001) IN "ACCOUNTE_TS" INDEX IN "ACCOUNT_ITS6", + PART "PART6" ENDING(2147483646) IN "ACCOUNTE_TS" INDEX IN "ACCOUNT_ITS6"); + +ALTER TABLE ACCOUNTEJB + ADD CONSTRAINT PK_ACCOUNTEJB PRIMARY KEY (ACCOUNTID); + +CREATE TABLE ORDEREJB + (ORDERFEE DECIMAL(14, 2), + COMPLETIONDATE TIMESTAMP, + ORDERTYPE VARCHAR(250), + ORDERSTATUS VARCHAR(250), + PRICE DECIMAL(14, 2), + QUANTITY DOUBLE NOT NULL, + OPENDATE TIMESTAMP, + ORDERID INTEGER NOT NULL, + ACCOUNT_ACCOUNTID INTEGER, + QUOTE_SYMBOL VARCHAR(250), + HOLDING_HOLDINGID INTEGER) IN "ORDER_TS" INDEX IN "ORDER_TS"; + +ALTER TABLE ORDEREJB + ADD CONSTRAINT PK_ORDEREJB PRIMARY KEY (ORDERID); + +ALTER TABLE ORDEREJB APPEND ON; + +ALTER TABLE HOLDINGEJB VOLATILE; +ALTER TABLE ACCOUNTPROFILEEJB VOLATILE; +ALTER TABLE QUOTEEJB VOLATILE; +ALTER TABLE KEYGENEJB VOLATILE; +ALTER TABLE ACCOUNTEJB VOLATILE; +ALTER TABLE ORDEREJB VOLATILE; + +CREATE INDEX ACCOUNT_USERID ON ACCOUNTEJB(PROFILE_USERID); +CREATE INDEX HOLDING_ACCOUNTID ON HOLDINGEJB(ACCOUNT_ACCOUNTID); +CREATE INDEX ORDER_ACCOUNTID ON ORDEREJB(ACCOUNT_ACCOUNTID); +CREATE INDEX ORDER_HOLDINGID ON ORDEREJB(HOLDING_HOLDINGID); +CREATE INDEX CLOSED_ORDERS ON ORDEREJB(ACCOUNT_ACCOUNTID,ORDERSTATUS); diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/dbscripts/derby/Table.ddl b/src/test/resources/test-applications/daytrader8/src/main/webapp/dbscripts/derby/Table.ddl new file mode 100644 index 00000000..08ac681f --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/dbscripts/derby/Table.ddl @@ -0,0 +1,104 @@ +## (C) Copyright IBM Corporation 2015. +## +## 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 +## +## http://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. + +# Each SQL statement in this file should terminate with a semicolon (;) +# Lines starting with the pound character (#) are considered as comments +DROP TABLE HOLDINGEJB; +DROP TABLE ACCOUNTPROFILEEJB; +DROP TABLE QUOTEEJB; +DROP TABLE KEYGENEJB; +DROP TABLE ACCOUNTEJB; +DROP TABLE ORDEREJB; + +CREATE TABLE HOLDINGEJB + (PURCHASEPRICE DECIMAL(14, 2), + HOLDINGID INTEGER NOT NULL, + QUANTITY DOUBLE NOT NULL, + PURCHASEDATE TIMESTAMP, + ACCOUNT_ACCOUNTID INTEGER, + QUOTE_SYMBOL VARCHAR(250)); + +ALTER TABLE HOLDINGEJB + ADD CONSTRAINT PK_HOLDINGEJB PRIMARY KEY (HOLDINGID); + +CREATE TABLE ACCOUNTPROFILEEJB + (ADDRESS VARCHAR(250), + PASSWD VARCHAR(250), + USERID VARCHAR(250) NOT NULL, + EMAIL VARCHAR(250), + CREDITCARD VARCHAR(250), + FULLNAME VARCHAR(250)); + +ALTER TABLE ACCOUNTPROFILEEJB + ADD CONSTRAINT PK_ACCOUNTPROFILE2 PRIMARY KEY (USERID); + +CREATE TABLE QUOTEEJB + (LOW DECIMAL(14, 2), + OPEN1 DECIMAL(14, 2), + VOLUME DOUBLE NOT NULL, + PRICE DECIMAL(14, 2), + HIGH DECIMAL(14, 2), + COMPANYNAME VARCHAR(250), + SYMBOL VARCHAR(250) NOT NULL, + CHANGE1 DOUBLE NOT NULL); + +ALTER TABLE QUOTEEJB + ADD CONSTRAINT PK_QUOTEEJB PRIMARY KEY (SYMBOL); + +CREATE TABLE KEYGENEJB + (KEYVAL INTEGER NOT NULL, + KEYNAME VARCHAR(250) NOT NULL); + +ALTER TABLE KEYGENEJB + ADD CONSTRAINT PK_KEYGENEJB PRIMARY KEY (KEYNAME); + +INSERT INTO KEYGENEJB (KEYNAME,KEYVAL) VALUES ('account', 0); +INSERT INTO KEYGENEJB (KEYNAME,KEYVAL) VALUES ('holding', 0); +INSERT INTO KEYGENEJB (KEYNAME,KEYVAL) VALUES ('order', 0); + +CREATE TABLE ACCOUNTEJB + (CREATIONDATE TIMESTAMP, + OPENBALANCE DECIMAL(14, 2), + LOGOUTCOUNT INTEGER NOT NULL, + BALANCE DECIMAL(14, 2), + ACCOUNTID INTEGER NOT NULL, + LASTLOGIN TIMESTAMP, + LOGINCOUNT INTEGER NOT NULL, + PROFILE_USERID VARCHAR(250)); + +ALTER TABLE ACCOUNTEJB + ADD CONSTRAINT PK_ACCOUNTEJB PRIMARY KEY (ACCOUNTID); + +CREATE TABLE ORDEREJB + (ORDERFEE DECIMAL(14, 2), + COMPLETIONDATE TIMESTAMP, + ORDERTYPE VARCHAR(250), + ORDERSTATUS VARCHAR(250), + PRICE DECIMAL(14, 2), + QUANTITY DOUBLE NOT NULL, + OPENDATE TIMESTAMP, + ORDERID INTEGER NOT NULL, + ACCOUNT_ACCOUNTID INTEGER, + QUOTE_SYMBOL VARCHAR(250), + HOLDING_HOLDINGID INTEGER); + +ALTER TABLE ORDEREJB + ADD CONSTRAINT PK_ORDEREJB PRIMARY KEY (ORDERID); + +CREATE INDEX ACCOUNT_USERID ON ACCOUNTEJB(PROFILE_USERID); +CREATE INDEX HOLDING_ACCOUNTID ON HOLDINGEJB(ACCOUNT_ACCOUNTID); +CREATE INDEX ORDER_ACCOUNTID ON ORDEREJB(ACCOUNT_ACCOUNTID); +CREATE INDEX ORDER_HOLDINGID ON ORDEREJB(HOLDING_HOLDINGID); +CREATE INDEX CLOSED_ORDERS ON ORDEREJB(ACCOUNT_ACCOUNTID,ORDERSTATUS); + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/dbscripts/oracle/Table.ddl b/src/test/resources/test-applications/daytrader8/src/main/webapp/dbscripts/oracle/Table.ddl new file mode 100644 index 00000000..3fa33c27 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/dbscripts/oracle/Table.ddl @@ -0,0 +1,103 @@ +## (C) Copyright IBM Corporation 2015. +## +## 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 +## +## http://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. + +# Each SQL statement in this file should terminate with a semicolon (;) +# Lines starting with the pound character (#) are considered as comments +DROP TABLE HOLDINGEJB cascade constraints; +DROP TABLE ACCOUNTPROFILEEJB cascade constraints; +DROP TABLE QUOTEEJB cascade constraints; +DROP TABLE KEYGENEJB cascade constraints; +DROP TABLE ACCOUNTEJB cascade constraints; +DROP TABLE ORDEREJB cascade constraints; + +CREATE TABLE HOLDINGEJB + (PURCHASEPRICE DECIMAL(14, 2) NULL, + HOLDINGID INTEGER NOT NULL, + QUANTITY NUMBER NOT NULL, + PURCHASEDATE DATE NULL, + ACCOUNT_ACCOUNTID INTEGER NULL, + QUOTE_SYMBOL VARCHAR2(250) NULL); + +ALTER TABLE HOLDINGEJB + ADD CONSTRAINT PK_HOLDINGEJB PRIMARY KEY (HOLDINGID); + +CREATE TABLE ACCOUNTPROFILEEJB + (ADDRESS VARCHAR2(250) NULL, + PASSWD VARCHAR2(250) NULL, + USERID VARCHAR2(250) NOT NULL, + EMAIL VARCHAR2(250) NULL, + CREDITCARD VARCHAR2(250) NULL, + FULLNAME VARCHAR2(250) NULL); + +ALTER TABLE ACCOUNTPROFILEEJB + ADD CONSTRAINT PK_ACCOUNTPROFILEEJB PRIMARY KEY (USERID); + +CREATE TABLE QUOTEEJB + (LOW DECIMAL(14, 2) NULL, + OPEN1 DECIMAL(14, 2) NULL, + VOLUME NUMBER NOT NULL, + PRICE DECIMAL(14, 2) NULL, + HIGH DECIMAL(14, 2) NULL, + COMPANYNAME VARCHAR2(250) NULL, + SYMBOL VARCHAR2(250) NOT NULL, + CHANGE1 NUMBER NOT NULL); + +ALTER TABLE QUOTEEJB + ADD CONSTRAINT PK_QUOTEEJB PRIMARY KEY (SYMBOL); + +CREATE TABLE KEYGENEJB + (KEYVAL INTEGER NOT NULL, + KEYNAME VARCHAR2(250) NOT NULL); + +ALTER TABLE KEYGENEJB + ADD CONSTRAINT PK_KEYGENEJB PRIMARY KEY (KEYNAME); + +INSERT INTO KEYGENEJB (KEYNAME,KEYVAL) VALUES ('account', 0); +INSERT INTO KEYGENEJB (KEYNAME,KEYVAL) VALUES ('holding', 0); +INSERT INTO KEYGENEJB (KEYNAME,KEYVAL) VALUES ('order', 0); + +CREATE TABLE ACCOUNTEJB + (CREATIONDATE DATE NULL, + OPENBALANCE DECIMAL(14, 2) NULL, + LOGOUTCOUNT INTEGER NOT NULL, + BALANCE DECIMAL(14, 2) NULL, + ACCOUNTID INTEGER NOT NULL, + LASTLOGIN DATE NULL, + LOGINCOUNT INTEGER NOT NULL, + PROFILE_USERID VARCHAR2(250) NULL); + +ALTER TABLE ACCOUNTEJB + ADD CONSTRAINT PK_ACCOUNTEJB PRIMARY KEY (ACCOUNTID); + +CREATE TABLE ORDEREJB + (ORDERFEE DECIMAL(14, 2) NULL, + COMPLETIONDATE DATE NULL, + ORDERTYPE VARCHAR2(250) NULL, + ORDERSTATUS VARCHAR2(250) NULL, + PRICE DECIMAL(14, 2) NULL, + QUANTITY NUMBER NOT NULL, + OPENDATE DATE NULL, + ORDERID INTEGER NOT NULL, + ACCOUNT_ACCOUNTID INTEGER NULL, + QUOTE_SYMBOL VARCHAR2(250) NULL, + HOLDING_HOLDINGID INTEGER NULL); + +ALTER TABLE ORDEREJB + ADD CONSTRAINT PK_ORDEREJB PRIMARY KEY (ORDERID); + +CREATE INDEX ACCOUNT_USERID ON ACCOUNTEJB(PROFILE_USERID); +CREATE INDEX HOLDING_ACCOUNTID ON HOLDINGEJB(ACCOUNT_ACCOUNTID); +CREATE INDEX ORDER_ACCOUNTID ON ORDEREJB(ACCOUNT_ACCOUNTID); +CREATE INDEX ORDER_HOLDINGID ON ORDEREJB(HOLDING_HOLDINGID); +CREATE INDEX CLOSED_ORDERS ON ORDEREJB(ACCOUNT_ACCOUNTID,ORDERSTATUS); diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/docs/benchmarking.html b/src/test/resources/test-applications/daytrader8/src/main/webapp/docs/benchmarking.html new file mode 100644 index 00000000..0a7cb9b4 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/docs/benchmarking.html @@ -0,0 +1,67 @@ + + + + + + +Benchmarking Details + + + +
    + + + + + + +
    +

    Benchmarking

    +
    +
    +

    DayTrader provides two servlets to create a workload for benchmarking: TradeApp servlet and TradeScenario servlet. +In either case, the load generation tool used to drive the Trade workload must provide cookie support to handle +HTTP sessions.

    +

    TradeApp servlet provides the standard web interface and +can be accessed with the Go Trade! link. Driving benchmark load using this +interface requires a sophisticated web load +generator that is capable of filling HTML +forms and posting dynamic data.

    +

    TradeScenario servlet emulates a population of web users by generating +a specific Trade operation for a randomly +chosen user on each access to the URL. Test +this servlet by clicking Trade Scenario and hit "Reload" on your browser to step through a Trade Scenario. +To benchmark using this URL aim your favorite web load generator at the +Trade Scenario URL and fire away.

    +

    There is a drawback to using the Trade Scenario +servlet to drive the workload versus using a series of more complicated +load scripts. As previously mentioned, the scenario +servlet is responsible for managing clients and emulating user +operations by dispatching simple client requests to complex Trade +actions. This causes the application server to spend a large percentage +of time performing work that would typically be handled by a client or +a more complex load driver. Consequently, performance numbers are +artificially deflated when using Trade Scenario servlet as compared to +driving the workload directly.

    + + +

    Web Primitive Benchmarking

    +

    A set of automated Web Primitives is also provided. The web primitives leverage the DayTrader infrastructure to test specific features of the web application development environment. This provides basic workloads for servlets, JSPs, EJBs, MDBs and more. The Web Primitives are installed automatically with the daytrader configuration archive.
    +

    +
    + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/docs/documentation.html b/src/test/resources/test-applications/daytrader8/src/main/webapp/docs/documentation.html new file mode 100644 index 00000000..be31be9f --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/docs/documentation.html @@ -0,0 +1,67 @@ + + + + + + + +Technical Documentation + + + +
    + + + + + + + +
    +

    Technical Documentation

    +
    +
    +
    +

    Documents below provide documentation on Trade application design, runtime +characteristics and FAQs.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Trade Technical OverviewProvides an overview of the Trade application design, configuration, and usage
    Trade UML DiagramsUML diagrams showing application architecture
    FAQFrequently Asked Questions
    Runtime and Database
    + Usage Characteristics
    Details runtime characteristics and database operations
    +
    +
    + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/docs/glossary.html b/src/test/resources/test-applications/daytrader8/src/main/webapp/docs/glossary.html new file mode 100644 index 00000000..1c9c5e1d --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/docs/glossary.html @@ -0,0 +1,98 @@ + + + + + + + +Technical Documentation + + + +
    + + + + + + + +
    +

    Trade Glossary and Terms

    +
    +
    +
    +
      +
    • account ID - A unique Integer based key. Each user is assigned an account ID at account creation time.
    • +
    • account Created - The time and date the users account was first created.
    • +
    • cash balance - The current cash balance in the users account. This does not include current stock holdings.
    • +
    • company - The full company name for an individual stock.
      +
    • +
    • current gain/loss - The total gain or loss of this account, computed by substracting the current sum of cash/holdings minus the opening account balance.
    • +
    • current price - The current trading price for a given stock symbol.
      +
    • + +
    • gain/loss - The current gain or loss of an individual stock holding, computed as (current market value - holding basis).
      +
    • +
    • last login - The date and time this user last logged in to Trade.
    • +
    • market value - The current total value of a stock holding, computed as (quantity * current price).
      +
    • + + +
    • number of holdings - The total number of stocks currently owned by this account.
    • +
    • open price - The price of a given stock at the open of the trading session.
      +
    • +
    • opening balance - The initial cash balance in this account when it was opened.
    • +
    • order id - A unique Integer based key. Each order is assigned an order ID at order creation time.
    • +
    • order status - orders are opened, processed, closed and completed. Order status shows the current stat for this order.
    • +
    • price range - The low and high prices for this stock during the current trading session
      +
    • +
    • purchase date - The date and time the a stock was purchased.
    • +
    • purchase price - The price used when purchasing the stock.
    • +
    • purchase basis - The total cost to purchase this holding. This is computed as (quantity * purchase price).
      +
    • + +
    • quantity - The number of stock shares in the order or user holding.
      +
    • + +
    • session created - An HTTP session is created for each user at during login. Session created shows the time and day when the session was created.
    • +
    • sum of cash/holdings - The total current value of this account. This is the sum of the cash balance along with the value of current stock holdings.
    • +
    • symbol - The symbol for a Trade stock.
      +
    • +
    • total logins - The total number of logins performed by this user since the last Trade Reset.
    • +
    • total logouts - The total number of logouts performed by this user since the last Trade Reset.
      +
    • + +
    • total of holdings - The current total value of all stock holdings in this account given the current valuation of each stock held.
    • +
    • Top gainers - The list of stock gaining the most in price during the current trading session.
    • +
    • Top losers - The list of stock falling the most in price during the current trading session.
      +
    • +
    • Trade Stock Index (TSIA) - A computed index of the top 20 stocks in Trade.
    • +
    • Trading Volume - The total number of shares traded for all stocks during this trading session.
      +
    • +
    • txn fee - The fee charged by the brokerage to process this order.
    • +
    • type - The order type (buy or sell).
      +
    • + +
    • user ID - The unique user ID for the account chosen by the user at account registration.
    • +
    • volume - The total number of shares traded for this stock.
    • + +
    + +
    + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/docs/rtCharacterisitics.html b/src/test/resources/test-applications/daytrader8/src/main/webapp/docs/rtCharacterisitics.html new file mode 100644 index 00000000..66132b6e --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/docs/rtCharacterisitics.html @@ -0,0 +1,158 @@ + + + + + + + +Trade Runtime and Database Usage Characteristics + + + +
    + + + + + + + +
    Trade Runtime and Database Usage Characteristics
    +

    The table below details each of the high level user operations in the Trade +application.
    +

    +
      +
    • Description - a short description of the user operation +
    • Complexity - the J2EE components invoked to complete the operation +
    • HTTP Session - operations on HTTP Session objects +
    • DB Activity - Create, Read, RC Read Collection, Update, and Delete operations on database tables +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Trade ActionDescriptionComplexityHTTP SessionDB Activity
    + (C, R, U, D)
    LoginUser sign in, session creation, market summaryServlet, JSP,
    + Session EJB
    + CMP Beans Read, Update, Collections
    Create, UpdateAccount: R, U
    + AccountProfile: R
    +
    Quote: RC *3
    LogoutUse sign-off, session destroyServlet, JSP,
    + Session EJB
    + CMP Bean Read, Update
    Read, DestroyAccount: R, U
    + AccountProfile: R
    BuyQuote followed buy a security purchaseServlet, JSP,
    + Session EJB
    + Message Driven Beans (Queue and Pub/Sub)
    + Multi CMP Read/Update
    ReadQuote: R
    + Account: R, U
    + Holding: C, R, U
    Orders: C, R, U +
    SellPortfolio followed by the sell of a holdingServlet, JSP,
    + Session EJB
    + Message Driven Beans (Queue and Pub/Sub)
    Multi CMP Read/Update
    ReadQuote: R
    + Account: R, U
    + Holding: D, R
    Orders: R, U
    RegisterCreate a new user profile and accountServlet, JSP,
    + Session EJB
    + CMP Bean Creates
    Create, UpdateAccount: C, R
    + AccountProfile: C
    HomePersonalized home page including current market conditions in a detailed market summaryServlet, JSP,
    + Session EJB
    + CMP Bean Read, Collections
    ReadAccount: R
    AccountProfile: R
    Quote: RC *3
    AccountReview current user account and profile information along with recent ordersServlet, JSP,
    + Session EJB
    + CMP Bean Read, Collections
    ReadAccount: R
    AccountProfile: R
    Orders: RC
    Account UpdateAccount followed by user profile update Servlet, JSP,
    + Session EJB
    + CMP Bean Read/Update, Collections
    ReadAccount: R
    AccountProfile: R, U
    Orders: RCQuote: RC
    PortfolioView users current security holdingsServlet, JSP,
    + Session EJB
    + CMP Bean Read, Collections
    ReadHolding: RC
    + Quote: RC
    QuotesView an arbirtray list of current security quotesServlet, JSP
    + Cached CMP Bean Read, Collections
    ReadQuote: RC
    +
    + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/docs/tradeFAQ.html b/src/test/resources/test-applications/daytrader8/src/main/webapp/docs/tradeFAQ.html new file mode 100644 index 00000000..f10e895c --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/docs/tradeFAQ.html @@ -0,0 +1,190 @@ + + + + + + +Frequently Asked Questions + + + +
    + + + + + + + +
    +

    Frequently Asked Questions

    +
    + +

    The Apache Software Foundation® DayTrader Performance Benchmark Sample +provides a suite of workloads for characterizing performance of J2EE 1.4 Application +Servers. The workloads consist of an end-to-end Web application and a full set of Web +primitives. The applications are a collection of JavaTM classes, Java servlets, +Java ServerPagesTM (JSPTM) files and Enterprise JavaBeansTM (EJBTM) built to open Java 2 Platform, Enterprise Edition (J2EETM) APIs. Together, the Trade application and Web primitives provide versatile and portable test cases that are designed to measure aspects +of scalability and performance.


    + +

    Application Design

    + +

    What is DayTrader?

    +

    DayTrader is an end-to-end Web application that is modeled after an on-line stock brokerage. +DayTrader leverages J2EE components such as servlets, JSP files, enterprise beans, +message-driven beans (MDBs) and Java database connectivity (JDBCTM) to +provide a set of user services such as login/logout, stock quotes, buy, +sell, account details, and so on through standards-based HTTP and Web services protocols.

    + +

    What are Web Primitives?

    +

    The Web primitives leverage the DayTrader infrastructure to test specific features +of the Application Servers implementing the J2EE 1.4 programming model. A description of each of the Web +primitives is provided on the main web primitive +page.

    + + +

    What software is required to run DayTrader?

    +
      +
    • Any J2EE 1.4 Compliant Application Server
    • +
    • A database that has a suitable JDBC driver for both XA and non-XA connectivity.
    • +
    + +

    What are the most common configuration scenarios?

      +
    • Single server with a remote database - The DayTrader application runs on a stand alone WebSphere Application Server instance. The required database software and the associated Trade database are located on a different system from the Application Server. The Application Server system must have the necessary database client software to connect to the remote database.
    • +
    • Single server with a local database - Same as the previous scenario; however, the required database software and the + associated DayTrader database are located on the same system as the Application Server.
    • +
    + + +
    +

    Run-time Configuration

    + +

    What does the ResetDayTrader link do?

    +

    The ResetDayTrader link on the configuration page must be clicked between DayTrader runs. +This link sets the database to a consistent size by removing all the newly registered users created during +a DayTrader run. The reset also sets all outstanding orders to a consistent state. Resetting the database +to a consistent size ensures repeatable throughput on subsequent DayTrader runs.

    + +

    How are the DayTrader configuration parameters modified?

    +

    The Trade configuration page provides a dynamic mechanism to set +the run-time configuration for a DayTrader run. These settings control the application +run-time characteristics such as the run-time mode, the order processing mode, and other run-time +variations supported in DayTrader. All settings are reset to defaults when the DayTrader application +server is restarted.

    + +

    Can you make configuration changes permanent?

    +

    Yes. Normally, Trade configuration parameters return to defaults whenever the Trade application +server is restarted. Settings can be made permanent by setting the configuration values in the +servlet init parameters of the TradeApp servlet and the TradeScenario servlet. Modify the +servlet init parameters in the web.xml file of the Trade Web application to change these parameters.

    + +

    What are the run-time modes?

    +

    DayTrader provides two server implementations of the emulated DayTrader brokerage services.

    +
      +
    • EJB - Database access uses EJB 2.1 technology to drive transactional trading operations.
    • +
    • Direct - This mode uses database and messaging access through direct JDBC and JMS code.
    • +
    + +

    What are the order processing modes?

    +

    DayTrader provides an asynchronous order processing mode through messaging with MDBs. The order +processing mode determines the mode for completing stock purchase and sell operations. Synchronous +mode completes the order immediately. Asynchronous mode uses MDB and JMS to queue the order to a +TradeBroker agent to complete the order. Asychronous_2-Phase performs a two-phase commit over the EJB +database and messaging transactions.

    +
      +
    • Synchronous - Orders are completed immediately by the DayTrader session enterprise bean and entity enterprise beans.
    • +
    • Asynchronous 2-phase - Orders are queued to the TradeBrokerMDB for asynchronous processing.
    • +
    + +

    What are the access modes?

    +

    DayTrader provides multiple access modes to the server-side brokerage services.

    +
      + +
    • Standard - Servlets access the Trade enterprise beans through the standard RMI protocol
    • +
    • WebServices - Servlets access DayTrader services through the Web services implementation in + the System Under Test (SUT). Each trading service is available as a standard Web service through the SOAP + Remote Procedure Call (RPC) protocol. Because DayTrader is wrapped to provide SOAP services, each DayTrader + operation (login, quote, buy, and son on) is available as a SOAP service.
    • + +
    + +

    What is the Primitive Iteration setting?

    +

    By default, the DayTrader primitives run one operation per Web request. Setting this value alters +the number of operations performed per client request. This is useful for reducing the amount of work +that is performed by the Web Container and for stressing other components within the application server. + +

    +
    +

    Benchmarking

    + +

    What is the TradeScenario servlet?

    +

    The TradeScenario servlet provides a simple mechanism to drive the DayTrader application. +The Trade database is initially populated with a set of fictitious users with names ranging +from uid:0 to uid:49 and a set of stocks ranging from s:0 to s:99. +The TradeScenario servlet emulates a population of Web users by generating a specific DayTrader operation for +a randomly chosen user on each access to the URL. To run the TradeScenario servlet use the single +TradeScenario URL (http://hostname/daytrader/scenario) with a load generation tool.

    + +

    Although TradeScenario servlet provides a simple mechanism for driving the DayTrader application, +there is a drawback to using this method versus using a series of load generation scripts +that drive the operations directly. This servlet consumes processing resources on the server +to manage incoming clients and dispatch these simple client requests to complex Trade actions. This +action artificially decreases server throughput because the server is emulating tasks that are normally + performed by a standard client or a more complex load generation tool.

    + +

    What is the typical procedure for collecting performance measurements with DayTrader? +

    When DayTrader is successfully installed on the application server and the supporting +database is populated, you can us the DayTrader application to collect performance measurements. +The following list provides the typical process for gathering performance measurements with DayTrader.

    +
      +
    1. Select the DayTrader run-time configuration parameters from the configuration + page (EJB, synchronous, and so on).
    2. +
    3. Reset the DayTrader run-time using the Reset DayTrader link.
    4. +
    5. Warm-up the application server JVMTM by applying load for a short period of time. The load generation tool + may access the TradeScenario servlet, + web primitives, or use custom scripts to drive the various operations of TradeApp servlet. To warm-up the + JVM, each code path within DayTrader must be processed enough times to esnure that the JIT compiler + has compiled and optimzed the application and server paths; generally, about 3000 iterations should do the trick. + Remember that the same code path is not necessarily run on each request unless primitives are being + run. Therefore, perform an adequate number of requests to stabilize the performance results.
    6. +
    7. Stop the load generation tool.
    8. +
    9. Reset the Trade run-time again
    10. +
    11. Restart the load generation tool and record measurements after the driver completes the requests.
    12. +
    13. Repeat steps 5 and 6 to obtain additional measurements.
    14. +
    + +

    Where did DayTrader come from? +

    DayTrader was originally an application designed by IBM to test their commercial Application Server. +The application was designed around common development patterns as well as to use the majority of the +J2EE programming model. The original author was Stan Cox where he developed Trade (the original name) +for J2EE 1.3. Since then Stan has evolved Trade and several other individuals have contributed to the project. +Christopher Blythe has been instrumental in stabilizing the long running capability of the benchmark and Andrew +Spyker introduced the Application Clients. The Application Clients (Streamer and WSAppClient) provide remote +capability to validate remote J2EE functionality and database consistency as well as provide a remote +WebServices client. Matt Hogstrom has used Trade extensively for performance analysis and brought Trade +to the Apache Software Foundation Geronimo Project. He has removed (hopefully) all WebSphere specific items +in the application and introduced additional functionality for gathering server compliance information +and low-level diagnostic information.

    +

    Where is DayTrader now? +

    David Hare developed DayTrader 3.0 internally at IBM. Daytrader 3.0 updated the Daytrader benchmark to +Java EE6 and added some jsf and jax-rs functionality. The Application Clients were removed. Daytrader 3.0 +was made public on IBMs WebSphere Performance page. Joe McClure is now adding functionality and improvements +for Java EE7.

    +
    + + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/docs/tradeFAQ.xhtml b/src/test/resources/test-applications/daytrader8/src/main/webapp/docs/tradeFAQ.xhtml new file mode 100644 index 00000000..0698074e --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/docs/tradeFAQ.xhtml @@ -0,0 +1,209 @@ + + + + + DayTrader + + + + +
    + + +
    +
    + + + + + + + + +
    +

    Frequently Asked Questions

    +
    + +

    The Apache Software Foundation® DayTrader Performance Benchmark Sample +provides a suite of workloads for characterizing performance of J2EE 1.4 Application +Servers. The workloads consist of an end-to-end Web application and a full set of Web +primitives. The applications are a collection of JavaTM classes, Java servlets, +Java ServerPagesTM (JSPTM) files and Enterprise JavaBeansTM (EJBTM) built to open Java 2 Platform, Enterprise Edition (J2EETM) APIs. Together, the Trade application and Web primitives provide versatile and portable test cases that are designed to measure aspects +of scalability and performance.



    + +

    Application Design

    +
    +What is DayTrader?
    +DayTrader is an end-to-end Web application that is modeled after an on-line stock brokerage. +DayTrader leverages J2EE components such as servlets, JSP files, enterprise beans, +message-driven beans (MDBs) and Java database connectivity (JDBCTM) to +provide a set of user services such as login/logout, stock quotes, buy, +sell, account details, and so on through standards-based HTTP and Web services protocols. +

    +What are Web Primitives?
    +The Web primitives leverage the DayTrader infrastructure to test specific features +of the Application Servers implementing the J2EE 1.4 programming model. A description of each of the Web +primitives is provided on the main web primitive +page.

    + + +What software is required to run DayTrader?
    +
      +
    • Any J2EE 1.4 Compliant Application Server
    • +
    • A database that has a suitable JDBC driver for both XA and non-XA connectivity.
    • +
    +

    +What are the most common configuration scenarios?
    +
      +
    • Single server with a remote database - The DayTrader application runs on a stand alone WebSphere Application Server instance. The required database software and the associated Trade database are located on a different system from the Application Server. The Application Server system must have the necessary database client software to connect to the remote database.
    • +
    • Single server with a local database - Same as the previous scenario; however, the required database software and the + associated DayTrader database are located on the same system as the Application Server.
    • +


    + +

    Run-time Configuration

    + +What does the ResetDayTrader link do?
    +The ResetDayTrader link on the configuration page must be clicked between DayTrader runs. +This link sets the database to a consistent size by removing all the newly registered users created during +a DayTrader run. The reset also sets all outstanding orders to a consistent state. Resetting the database +to a consistent size ensures repeatable throughput on subsequent DayTrader runs.

    + +How are the DayTrader configuration parameters modified?
    +The Trade configuration page provides a dynamic mechanism to set +the run-time configuration for a DayTrader run. These settings control the application +run-time characteristics such as the run-time mode, the order processing mode, and other run-time +variations supported in DayTrader. All settings are reset to defaults when the DayTrader application +server is restarted.

    + +Can you make configuration changes permanent?
    +Yes. Normally, Trade configuration parameters return to defaults whenever the Trade application +server is restarted. Settings can be made permanent by setting the configuration values in the +servlet init parameters of the TradeApp servlet and the TradeScenario servlet. Modify the +servlet init parameters in the web.xml file of the Trade Web application to change these parameters.

    + +What are the run-time modes?
    +DayTrader provides two server implementations of the emulated DayTrader brokerage services.
    +
      +
    • EJB - Database access uses EJB 2.1 technology to drive transactional trading operations.
    • +
    • Direct - This mode uses database and messaging access through direct JDBC and JMS code.
    • +


    + +What are the order processing modes?
    +DayTrader provides an asynchronous order processing mode through messaging with MDBs. The order +processing mode determines the mode for completing stock purchase and sell operations. Synchronous +mode completes the order immediately. Asynchronous mode uses MDB and JMS to queue the order to a +TradeBroker agent to complete the order. Asychronous_2-Phase performs a two-phase commit over the EJB +database and messaging transactions.
    +
      +
    • Synchronous - Orders are completed immediately by the DayTrader session enterprise bean and entity enterprise beans.
    • +
    • Asynchronous 2-phase - Orders are queued to the TradeBrokerMDB for asynchronous processing.
    • +


    + +What are the access modes?
    +DayTrader provides multiple access modes to the server-side brokerage services.
    +
      + +
    • Standard - Servlets access the Trade enterprise beans through the standard RMI protocol
    • +
    • WebServices - Servlets access DayTrader services through the Web services implementation in + the System Under Test (SUT). Each trading service is available as a standard Web service through the SOAP + Remote Procedure Call (RPC) protocol. Because DayTrader is wrapped to provide SOAP services, each DayTrader + operation (login, quote, buy, and son on) is available as a SOAP service.
    • + +


    + +What is the Primitive Iteration setting?
    +By default, the DayTrader primitives run one operation per Web request. Setting this value alters +the number of operations performed per client request. This is useful for reducing the amount of work +that is performed by the Web Container and for stressing other components within the application server.

    + +

    Benchmarking


    + +What is the TradeScenario servlet?
    +The TradeScenario servlet provides a simple mechanism to drive the DayTrader application. +The Trade database is initially populated with a set of fictitious users with names ranging +from uid:0 to uid:49 and a set of stocks ranging from s:0 to s:99. +The TradeScenario servlet emulates a population of Web users by generating a specific DayTrader operation for +a randomly chosen user on each access to the URL. To run the TradeScenario servlet use the single +TradeScenario URL (http://hostname/daytrader/scenario) with a load generation tool.
    + +Although TradeScenario servlet provides a simple mechanism for driving the DayTrader application, +there is a drawback to using this method versus using a series of load generation scripts +that drive the operations directly. This servlet consumes processing resources on the server +to manage incoming clients and dispatch these simple client requests to complex Trade actions. This +action artificially decreases server throughput because the server is emulating tasks that are normally + performed by a standard client or a more complex load generation tool.

    + +What is the typical procedure for collecting performance measurements with DayTrader?
    +When DayTrader is successfully installed on the application server and the supporting +database is populated, you can us the DayTrader application to collect performance measurements. +The following list provides the typical process for gathering performance measurements with DayTrader.
    +
      +
    1. Select the DayTrader run-time configuration parameters from the configuration + page (EJB, synchronous, and so on).
    2. +
    3. Reset the DayTrader run-time using the Reset DayTrader link.
    4. +
    5. Warm-up the application server JVMTM by applying load for a short period of time. The load generation tool + may access the TradeScenario servlet, + web primitives, or use custom scripts to drive the various operations of TradeApp servlet. To warm-up the + JVM, each code path within DayTrader must be processed enough times to esnure that the JIT compiler + has compiled and optimzed the application and server paths; generally, about 3000 iterations should do the trick. + Remember that the same code path is not necessarily run on each request unless primitives are being + run. Therefore, perform an adequate number of requests to stabilize the performance results.
    6. +
    7. Stop the load generation tool.
    8. +
    9. Reset the Trade run-time again
    10. +
    11. Restart the load generation tool and record measurements after the driver completes the requests.
    12. +
    13. Repeat steps 5 and 6 to obtain additional measurements.
    14. +

    + +Where did DayTrader come from?
    +

    DayTrader was originally an application designed by IBM to test their commercial Application Server. +The application was designed around common development patterns as well as to use the majority of the +J2EE programming model. The original author was Stan Cox where he developed Trade (the original name) +for J2EE 1.3. Since then Stan has evolved Trade and several other individuals have contributed to the project. +Christopher Blythe has been instrumental in stabilizing the long running capability of the benchmark and Andrew +Spyker introduced the Application Clients. The Application Clients (Streamer and WSAppClient) provide remote +capability to validate remote J2EE functionality and database consistency as well as provide a remote +WebServices client. Matt Hogstrom has used Trade extensively for performance analysis and brought Trade +to the Apache Software Foundation Geronimo Project. He has removed (hopefully) all WebSphere specific items +in the application and introduced additional functionality for gathering server compliance information +and low-level diagnostic information.



    +Where is DayTrader now?
    +David Hare developed DayTrader 3.0 internally at IBM. Daytrader 3.0 updated the Daytrader benchmark to +Java EE6 and added some jsf and jax-rs functionality. The Application Clients were removed. Daytrader 3.0 +was made public on IBMs WebSphere Performance page. Joe McClure is now adding functionality and improvements +for Java EE7.

    +
    +
    + +
    + \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/docs/tradeversion.html b/src/test/resources/test-applications/daytrader8/src/main/webapp/docs/tradeversion.html new file mode 100644 index 00000000..38be2eee --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/docs/tradeversion.html @@ -0,0 +1,24 @@ + + +DayTrader Version + +IBM WebSphere Application Server Samples - DayTrader 8 (Version 8.0.0) +
    Full EE 8 Spec Compliant +
    Date: 20180417 +
    Contact: jdmcclur@us.ibm.com + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/error.jsp b/src/test/resources/test-applications/daytrader8/src/main/webapp/error.jsp new file mode 100644 index 00000000..988ad2d9 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/error.jsp @@ -0,0 +1,122 @@ + + +<%@ page + import="java.io.StringWriter, + java.io.PrintWriter"%> + + + + + + + +
    DayTrader + ErrorDayTrader
    +
    + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    An Error has + occurred during DayTrader processing.
    The + stack trace detailing the error follows. +

    + Please consult the application server error + logs for further details. +

    <% + String message = null; + int status_code = -1; + String exception_info = null; + String url = null; + + try { + Exception theException = null; + Integer status = null; + + //these attribute names are specified by Servlet 2.2 + message = (String) request.getAttribute("javax.servlet.error.message"); + status = ((Integer) request.getAttribute("javax.servlet.error.status_code")); + theException = (Exception) request.getAttribute("javax.servlet.error.exception"); + url = (String) request.getAttribute("javax.servlet.error.request_uri"); + + // convert the stack trace to a string + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + theException.printStackTrace(pw); + pw.flush(); + pw.close(); + + if (message == null) { + message = "not available"; + } + + if (status == null) { + status_code = -1; + } else { + status_code = status.intValue(); + } + + exception_info = theException.toString(); + exception_info = exception_info + "
    " + sw.toString(); + sw.close(); + + } catch (Exception e) { + e.printStackTrace(); + } + + out.println("

    Processing request:" + url); + out.println("
    StatusCode: " + status_code); + out.println("
    Message:" + message); + out.println("
    Exception:" + exception_info); + %> +
    +
    +
    + + + + + + + +
    DayTrader + ErrorDayTrader
    diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/favicon.ico b/src/test/resources/test-applications/daytrader8/src/main/webapp/favicon.ico new file mode 100644 index 00000000..beacc182 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/src/main/webapp/favicon.ico differ diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/footer.html b/src/test/resources/test-applications/daytrader8/src/main/webapp/footer.html new file mode 100644 index 00000000..683d80bf --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/footer.html @@ -0,0 +1,38 @@ + + + +daytrader2_matts_mods + + + + + + + + +
    + + + + +
    +
    + + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/header.html b/src/test/resources/test-applications/daytrader8/src/main/webapp/header.html new file mode 100644 index 00000000..c70149df --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/header.html @@ -0,0 +1,96 @@ + + + +DayTrader Header + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/images/DayTraderHead_blue.gif b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/DayTraderHead_blue.gif new file mode 100644 index 00000000..49745642 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/DayTraderHead_blue.gif differ diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/images/DayTraderHead_red.gif b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/DayTraderHead_red.gif new file mode 100644 index 00000000..5f05eec8 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/DayTraderHead_red.gif differ diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/images/Thumbs.db b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/Thumbs.db new file mode 100644 index 00000000..3b66be0e Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/Thumbs.db differ diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/images/about.gif b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/about.gif new file mode 100644 index 00000000..855c676a Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/about.gif differ diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/images/account.gif b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/account.gif new file mode 100644 index 00000000..a98761b1 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/account.gif differ diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/images/arrowdown.gif b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/arrowdown.gif new file mode 100644 index 00000000..11012117 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/arrowdown.gif differ diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/images/arrowup.gif b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/arrowup.gif new file mode 100644 index 00000000..24b6c53f Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/arrowup.gif differ diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/images/bottomRedBar.gif b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/bottomRedBar.gif new file mode 100644 index 00000000..c814872d Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/bottomRedBar.gif differ diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/images/configuration.gif b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/configuration.gif new file mode 100644 index 00000000..16798fb6 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/configuration.gif differ diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/images/dayTraderLogo.gif b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/dayTraderLogo.gif new file mode 100644 index 00000000..c569db51 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/dayTraderLogo.gif differ diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/images/daytrader_simple_arch.gif b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/daytrader_simple_arch.gif new file mode 100644 index 00000000..5d9bf60e Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/daytrader_simple_arch.gif differ diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/images/faq.gif b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/faq.gif new file mode 100644 index 00000000..37a644c0 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/faq.gif differ diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/images/favicon.ico b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/favicon.ico new file mode 100644 index 00000000..beacc182 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/favicon.ico differ diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/images/graph.gif b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/graph.gif new file mode 100644 index 00000000..7d91ee96 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/graph.gif differ diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/images/home.gif b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/home.gif new file mode 100644 index 00000000..a74e60de Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/home.gif differ diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/images/homeBanner.gif b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/homeBanner.gif new file mode 100644 index 00000000..775318ab Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/homeBanner.gif differ diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/images/line.gif b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/line.gif new file mode 100644 index 00000000..0cf9e512 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/line.gif differ diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/images/logout.gif b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/logout.gif new file mode 100644 index 00000000..e31a6a11 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/logout.gif differ diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/images/lower_banner.gif b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/lower_banner.gif new file mode 100644 index 00000000..9c7c294d Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/lower_banner.gif differ diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/images/menuHome.gif b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/menuHome.gif new file mode 100644 index 00000000..2fa03dd0 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/menuHome.gif differ diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/images/nav_bg.png b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/nav_bg.png new file mode 100644 index 00000000..7157603c Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/nav_bg.png differ diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/images/portfolio.gif b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/portfolio.gif new file mode 100644 index 00000000..637f9ab9 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/portfolio.gif differ diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/images/primitives.gif b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/primitives.gif new file mode 100644 index 00000000..a031415e Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/primitives.gif differ diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/images/quotes.gif b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/quotes.gif new file mode 100644 index 00000000..74499d7f Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/quotes.gif differ diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/images/reports.gif b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/reports.gif new file mode 100644 index 00000000..15c987a9 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/reports.gif differ diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/images/spacer.gif b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/spacer.gif new file mode 100644 index 00000000..5bfd67a2 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/spacer.gif differ diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/images/ticker-anim.gif b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/ticker-anim.gif new file mode 100644 index 00000000..04c4c88b Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/ticker-anim.gif differ diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/images/topRedBar.gif b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/topRedBar.gif new file mode 100644 index 00000000..2198e7d6 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/topRedBar.gif differ diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/images/topline.jpg b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/topline.jpg new file mode 100644 index 00000000..d51fee32 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/topline.jpg differ diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/images/tradeOverview.png b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/tradeOverview.png new file mode 100644 index 00000000..f4215940 Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/tradeOverview.png differ diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/images/tradingAndPortfolios.gif b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/tradingAndPortfolios.gif new file mode 100644 index 00000000..85827ccc Binary files /dev/null and b/src/test/resources/test-applications/daytrader8/src/main/webapp/images/tradingAndPortfolios.gif differ diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/index.html b/src/test/resources/test-applications/daytrader8/src/main/webapp/index.html new file mode 100644 index 00000000..1b09bf01 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/index.html @@ -0,0 +1,37 @@ + + + + + + +DayTrader + + + + + + + <BODY> + <P>Need browser which supports frames to see this page</P> + </BODY> + + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/index.xhtml b/src/test/resources/test-applications/daytrader8/src/main/webapp/index.xhtml new file mode 100644 index 00000000..e6cac242 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/index.xhtml @@ -0,0 +1,93 @@ + + + + + DayTrader + + + + +
    + + +
    +
    +

    Overview

    +
    +
    The Daytrader performance benchmark sample provides a suite of workloads for characterizing performance of Java EE + Application Servers. The workloads consist of an end to end web application and a full set of primitives. The applications are a collection of + Java classes, Java Servlets, JavaServer Pages, and Enterprise Java Beans built to open Java EE APIs. Together these provide versatile and + portable test cases designed to measure aspects of scalability and performance.
    +
    +

    + +
    + Daytrader J2EE Components +
    + Model-View-Controller architecture +

    +
    +
    +

    Daytrader

    + DayTrader is an end-to-end benchmark and performance sample application. It provides a real world Java EE workload. +
    +
    + DayTrader's new design spans Java EE 7, including the new WebSockets specification. Other Java EE features include JSPs, Servlets, EJBs, JPA, + JDBC, JSF, JMS, MDBs, and transactions (synchronous and asynchronous/2-phase commit). +
    +
    + +

    Primitives

    + The + primitives + provide a set of workloads to individually test various components of a Java EE application Server. The primitives leverage the Daytrader + application infrastructure to test specific Java EE components such as the servlet engine, JSP support, EJB Entitiy, Session and Message Driven + beans, HTTp Session support and more. +
    +
    +
    +
    + +
    + \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/leftMenu.html b/src/test/resources/test-applications/daytrader8/src/main/webapp/leftMenu.html new file mode 100644 index 00000000..1b930bc3 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/leftMenu.html @@ -0,0 +1,56 @@ + + + + + +Leftmenu + + + + +
    +

    +
    +
    Overview
    +

    + +

    + Benchmarking +

    +

    + Configuration +

    +

    + Go Trade! +

    +

    + Web Primitives +

    +
    + + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/marketSummary.html b/src/test/resources/test-applications/daytrader8/src/main/webapp/marketSummary.html new file mode 100644 index 00000000..34cdd340 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/marketSummary.html @@ -0,0 +1,283 @@ + + + + +Market Summary Web Socket + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Market Summary
    + DayTrader Stock Index(TSIA)
    Trading Volume
    Top Gainers + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    SymbolPriceChange
    +
    Top Losers + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    SymbolPriceChange
    +
    Recent Price Changes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    SymbolPriceChange
    +
    + + \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/marketSummary.jsp b/src/test/resources/test-applications/daytrader8/src/main/webapp/marketSummary.jsp new file mode 100644 index 00000000..976164a2 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/marketSummary.jsp @@ -0,0 +1,156 @@ + + + + + +DayTrader Market Summary + + + + + <%@ page + import="java.util.Collection, + java.util.Iterator, + java.math.BigDecimal,com.ibm.websphere.samples.daytrader.entities.OrderDataBean,com.ibm.websphere.samples.daytrader.util.FinancialUtils" + session="true" isThreadSafe="true" isErrorPage="false"%> + + + + + + + + + + + + + + + + + + + + + + <% + Collection closedOrders = (Collection) request.getAttribute("closedOrders"); + if ((closedOrders != null) && (closedOrders.size() > 0)) { + %> + + + + + + + <% + } + %> + +
    DayTrader Market SummaryDayTrader
    HomeAccountMarket SummaryPortfolioQuotes/TradeLogoff
    +
    <%=new java.util.Date()%> +
    + Alert: The + following Order(s) have completed. +
    + + + <% + Iterator it = closedOrders.iterator(); + while (it.hasNext()) { + OrderDataBean closedOrderData = (OrderDataBean) it.next(); + %> + + + + + + + + + + + + + + + + + + + + + <% + } + %> + + +
    order + IDorder + statuscreation + datecompletion + datetxn + feetypesymbolquantity
    <%=closedOrderData.getOrderID()%><%=closedOrderData.getOrderStatus()%><%=closedOrderData.getOpenDate()%><%=closedOrderData.getCompletionDate()%><%=closedOrderData.getOrderFee()%><%=closedOrderData.getOrderType()%><%=FinancialUtils.printQuoteLink(closedOrderData.getSymbol())%><%=closedOrderData.getQuantity()%>
    +
    + + +
    + + + + + + + + + + + + + +
    +
    +
    + + + + + + + +
    Note: Click any symbol + for a quote or to trade. + +
    + + +
    +
    +
    DayTrader + Market SummaryDayTrader
    + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/marketSummary.xhtml b/src/test/resources/test-applications/daytrader8/src/main/webapp/marketSummary.xhtml new file mode 100644 index 00000000..aebae230 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/marketSummary.xhtml @@ -0,0 +1,605 @@ + + + + + DayTrader Market + + + + + + + + +
    + + + +
    + +
    + + + + + + + + + + +
    + + Alert: The following Order(s) have completed. + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + + + + + + + +
    +

    Market Summary

    +
    +
    +
    + + + + + + +
    + + + + + + + + + + + +
    + DayTrader Stock Index(TSIA) + +
    +
    + Trading Volume + +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + Recent Changes +
    + Symbol + + Price + + Change +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + Top Gainers +
    + Symbol + + Price + + Change +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + Top Losers +
    + Symbol + + Price + + Change +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    + + + + + + + + + + +
    +
    +
    + + + + + + + +
    + + + + +
    +
    +
    +
    +
    +
    + + +
    + \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/order.jsp b/src/test/resources/test-applications/daytrader8/src/main/webapp/order.jsp new file mode 100644 index 00000000..fdb7fc99 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/order.jsp @@ -0,0 +1,233 @@ + + + + + +DayTrader Order information + + + + <%@ page + import="java.util.Collection, + java.util.Iterator,com.ibm.websphere.samples.daytrader.entities.OrderDataBean,com.ibm.websphere.samples.daytrader.util.FinancialUtils" + session="true" isThreadSafe="true" isErrorPage="false"%> + + + + + + + + + + + + + + + + + + + + + <% + Collection closedOrders = (Collection) request.getAttribute("closedOrders"); + if ((closedOrders != null) && (closedOrders.size() > 0)) { + %> + + + + + + + <% + } + %> + +
    DayTrader New OrdersDayTrader
    HomeAccountMarket SummaryPortfolioQuotes/TradeLogoff
    +
    <%=new java.util.Date()%> +
    + Alert: The + following Order(s) have completed. +
    + + + <% + Iterator it = closedOrders.iterator(); + while (it.hasNext()) { + OrderDataBean closedOrderData = (OrderDataBean) it.next(); + %> + + + + + + + + + + + + + + + + + + + + + <% + } + %> + + +
    order + IDorder + statuscreation + datecompletion + datetxn + feetypesymbolquantity
    <%=closedOrderData.getOrderID()%><%=closedOrderData.getOrderStatus()%><%=closedOrderData.getOpenDate()%><%=closedOrderData.getCompletionDate()%><%=closedOrderData.getOrderFee()%><%=closedOrderData.getOrderType()%><%=FinancialUtils.printQuoteLink(closedOrderData.getSymbol())%><%=closedOrderData.getQuantity()%>
    +
    + + + + + + +
    + + + + + + <% + OrderDataBean orderData = (OrderDataBean) request.getAttribute("orderData"); + if (orderData != null) { + %> + + + + + + + + + + <% + } + %> + +
    New + Order

    + Order <%=orderData.getOrderID()%>
    + to <%=orderData.getOrderType()%> + <%=orderData.getQuantity()%> + shares of <%=orderData.getSymbol()%> + has been submitted for + processing.


    + Order <%=orderData.getOrderID()%> + details: +
    + + + + + + + + + + + + + + + + + + + + + + + +
    order + IDorder + statuscreation + datecompletion + datetxn + feetypesymbolquantity
    <%= orderData.getOrderID()%><%= orderData.getOrderStatus()%><%= orderData.getOpenDate()%><%= orderData.getCompletionDate()%><%= orderData.getOrderFee()%><%= orderData.getOrderType()%><%= FinancialUtils.printQuoteLink(orderData.getSymbol()) %><%= orderData.getQuantity()%>
    +
    +
    + + + + + + + + + + + + + +
    +
    +
    + + + + + + + +
    Note: Click any symbol + for a quote or to trade. +
    + + +
    +
    DayTrader New OrdersDayTrader
    + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/order.xhtml b/src/test/resources/test-applications/daytrader8/src/main/webapp/order.xhtml new file mode 100644 index 00000000..6d90cb98 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/order.xhtml @@ -0,0 +1,308 @@ + + + + + DayTrader Order + + + + + +
    + + + +
    + +
    + + + + + + + + + + +
    + + Alert: The following Order(s) have completed. + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + + + + + + +
    + + + + + + + + + + + + + + + + +
    + New Order +
    + + +
    + Order  + +
    +  to  + + +   + + +  shares of  + + symbol: + + +  has been submitted for processing. +
    +
    +
    + + Order  + + + + + + details: + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + order ID + + order status + + creation date + + completion date + + txn fee + + type + + symbol + + quantity +
    + + + + + + + + + + + + + + + +
    +
    +
    + + + + + + + + + +
    +
    +
    + + + + + + + +
    + + + + +
    +
    +
    +
    +
    +
    + + +
    + \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/orderImg.jsp b/src/test/resources/test-applications/daytrader8/src/main/webapp/orderImg.jsp new file mode 100644 index 00000000..3d105a49 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/orderImg.jsp @@ -0,0 +1,248 @@ + + + + + +DayTrader Order information + + + + + <%@ page + import="java.util.Collection, java.util.Iterator,com.ibm.websphere.samples.daytrader.entities.OrderDataBean,com.ibm.websphere.samples.daytrader.util.FinancialUtils" + session="true" isThreadSafe="true" isErrorPage="false"%> + + + + + + + + + + + + + + + + + + + + <% + Collection closedOrders = (Collection) request.getAttribute("closedOrders"); + if ((closedOrders != null) && (closedOrders.size() > 0)) { + %> + + + + + + + <% + } + %> + +
    DayTrader New Orders
    +

    <%=new java.util.Date()%>
    + Alert: The + following Order(s) have completed. +
    + + + <% + Iterator it = closedOrders.iterator(); + while (it.hasNext()) { + OrderDataBean closedOrderData = (OrderDataBean) it.next(); + %> + + + + + + + + + + + + + + + + + + + + + <% + } + %> + + +
    order + IDorder + statuscreation + datecompletion + datetxn + feetypesymbolquantity
    <%=closedOrderData.getOrderID()%><%=closedOrderData.getOrderStatus()%><%=closedOrderData.getOpenDate()%><%=closedOrderData.getCompletionDate()%><%=closedOrderData.getOrderFee()%><%=closedOrderData.getOrderType()%><%=FinancialUtils.printQuoteLink(closedOrderData.getSymbol())%><%=closedOrderData.getQuantity()%>
    +
    + + + + + + +
    + + + + + + <% + OrderDataBean orderData = (OrderDataBean) request.getAttribute("orderData"); + if (orderData != null) { + %> + + + + + + + + + + <% + } + %> + +
    New + Order

    + Order <%=orderData.getOrderID()%>
    + to <%=orderData.getOrderType()%> + <%=orderData.getQuantity()%> + shares of <%=orderData.getSymbol()%> + has been submitted for + processing.


    + Order <%=orderData.getOrderID()%> + details: +
    + + + + + + + + + + + + + + + + + + + + + + + +
    order + IDorder + statuscreation + datecompletion + datetxn + feetypesymbolquantity
    <%= orderData.getOrderID()%><%= orderData.getOrderStatus()%><%= orderData.getOpenDate()%><%= orderData.getCompletionDate()%><%= orderData.getOrderFee()%><%= orderData.getOrderType()%><%= FinancialUtils.printQuoteLink(orderData.getSymbol()) %><%= orderData.getQuantity()%>
    +
    +
    + + + + + + + + + + + + + +
    +
    +
    + + + + + + + +
    Note: Click any symbol + for a quote or to trade. +
    + + +
    +
    DayTrader New Orders
    + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/portfolio.jsp b/src/test/resources/test-applications/daytrader8/src/main/webapp/portfolio.jsp new file mode 100644 index 00000000..c1fb732a --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/portfolio.jsp @@ -0,0 +1,284 @@ + + + + + +DayTrader Portfolio + + + + + <%@ page + import="java.util.Collection, + java.util.Iterator, + java.util.HashMap, + java.math.BigDecimal,com.ibm.websphere.samples.daytrader.entities.HoldingDataBean,com.ibm.websphere.samples.daytrader.entities.OrderDataBean,com.ibm.websphere.samples.daytrader.entities.QuoteDataBean,com.ibm.websphere.samples.daytrader.util.Log,com.ibm.websphere.samples.daytrader.util.FinancialUtils" + session="true" isThreadSafe="true" isErrorPage="false"%> + + + + + + + + + + + + + + + + + + + + + + <% + Collection closedOrders = (Collection) request.getAttribute("closedOrders"); + if ((closedOrders != null) && (closedOrders.size() > 0)) { + %> + + + + + + + <% + } + %> + +
    DayTrader PortfolioDayTrader
    HomeAccountMarket SummaryPortfolioQuotes/TradeLogoff
    +
    <%=new java.util.Date()%> +
    + Alert: The + following Order(s) have completed. +
    + + + <% + Iterator it = closedOrders.iterator(); + while (it.hasNext()) { + OrderDataBean closedOrderData = (OrderDataBean) it.next(); + %> + + + + + + + + + + + + + + + + + + + + + <% + } + %> + + +
    order + IDorder + statuscreation + datecompletion + datetxn + feetypesymbolquantity
    <%=closedOrderData.getOrderID()%><%=closedOrderData.getOrderStatus()%><%=closedOrderData.getOpenDate()%><%=closedOrderData.getCompletionDate()%><%=closedOrderData.getOrderFee()%><%=closedOrderData.getOrderType()%><%=FinancialUtils.printQuoteLink(closedOrderData.getSymbol())%><%=closedOrderData.getQuantity()%>
    +
    + + + + + + +
    + + + + + + + + + + + + + + +
    Portfolio + Number + of Holdings: <%=holdingDataBeans.size()%>
    +
    + + + + + + + + + + + + + + + + <% + // Create Hashmap for quick lookup of quote values + Iterator it = quoteDataBeans.iterator(); + HashMap quoteMap = new HashMap(); + while (it.hasNext()) { + QuoteDataBean quoteData = (QuoteDataBean) it.next(); + quoteMap.put(quoteData.getSymbol(), quoteData); + } + //Step through and printout Holdings + + it = holdingDataBeans.iterator(); + BigDecimal totalGain = new BigDecimal(0.0); + BigDecimal totalBasis = new BigDecimal(0.0); + BigDecimal totalValue = new BigDecimal(0.0); + try { + while (it.hasNext()) { + HoldingDataBean holdingData = (HoldingDataBean) it.next(); + QuoteDataBean quoteData = (QuoteDataBean) quoteMap.get(holdingData.getQuoteID()); + BigDecimal basis = holdingData.getPurchasePrice().multiply(new BigDecimal(holdingData.getQuantity())); + BigDecimal marketValue = quoteData.getPrice().multiply(new BigDecimal(holdingData.getQuantity())); + totalBasis = totalBasis.add(basis); + totalValue = totalValue.add(marketValue); + BigDecimal gain = marketValue.subtract(basis); + totalGain = totalGain.add(gain); + BigDecimal gainPercent = null; + if (basis.doubleValue() == 0.0) { + gainPercent = new BigDecimal(0.0); + Log.error("portfolio.jsp: Holding with zero basis. holdingID=" + holdingData.getHoldingID() + " symbol=" + holdingData.getQuoteID() + + " purchasePrice=" + holdingData.getPurchasePrice()); + } else + gainPercent = marketValue.divide(basis, BigDecimal.ROUND_HALF_UP).subtract(new BigDecimal(1.0)).multiply(new BigDecimal(100.0)); + %> + + + + + + + + + + + + + <% + } + } catch (Exception e) { + Log.error("portfolio.jsp: error displaying user holdings", e); + } + %> + + + + + + + + + + + + +
    + Portfolio +
    holding + IDpurchase + datesymbolquantitypurchase + pricecurrent + pricepurchase + basismarket + valuegain/(loss)trade
    <%=holdingData.getHoldingID()%><%=holdingData.getPurchaseDate()%><%=FinancialUtils.printQuoteLink(holdingData.getQuoteID())%><%=holdingData.getQuantity()%><%=holdingData.getPurchasePrice()%><%=quoteData.getPrice()%><%=basis%><%=marketValue%><%=FinancialUtils.printGainHTML(gain)%><%="sell"%>
    Total$ + <%=totalBasis%>$ + <%=totalValue%>$ <%=FinancialUtils.printGainHTML(totalGain)%> + <%=FinancialUtils.printGainPercentHTML(FinancialUtils.computeGainPercent(totalValue, totalBasis))%>
    +
    +
    +
    + + + + + + + + + + + + + +
    +
    +
    + + + + + + + +
    Note: Click any symbol + for a quote or to trade. +
    + + +
    +
    DayTrader + PortfolioDayTrader
    + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/portfolio.xhtml b/src/test/resources/test-applications/daytrader8/src/main/webapp/portfolio.xhtml new file mode 100644 index 00000000..8af86c77 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/portfolio.xhtml @@ -0,0 +1,340 @@ + + + + + DayTrader Portfolio + + + + + +
    + + + +
    + +
    + + + + + + + + + + +
    + + Alert: The following Order(s) have completed. + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + + + + + + + + + + + + + + + +
    + Portfolio + Number of Holdings:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + +
    + + + + + + + + + + + +
    Total purchase basisTotal market valueTotal gain/loss
    + $ + + + $ + + + $ + + +
    +
    +
    + + + + + + + + + + +
    +
    +
    + + + + + + + +
    + + + + +
    +
    +
    +
    +
    +
    + + +
    + \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/portfolioImg.jsp b/src/test/resources/test-applications/daytrader8/src/main/webapp/portfolioImg.jsp new file mode 100644 index 00000000..062418bf --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/portfolioImg.jsp @@ -0,0 +1,296 @@ + + + + + +DayTrader Portfolio + + + + + <%@ page + import="java.util.Collection, + java.util.Iterator, + java.util.HashMap, + java.math.BigDecimal,com.ibm.websphere.samples.daytrader.entities.HoldingDataBean,com.ibm.websphere.samples.daytrader.entities.OrderDataBean,com.ibm.websphere.samples.daytrader.entities.QuoteDataBean,com.ibm.websphere.samples.daytrader.util.Log,com.ibm.websphere.samples.daytrader.util.FinancialUtils" + session="true" isThreadSafe="true" isErrorPage="false"%> + + + + + + + + + + + + + + + + + + + + + <% + Collection closedOrders = (Collection) request.getAttribute("closedOrders"); + if ((closedOrders != null) && (closedOrders.size() > 0)) { + %> + + + + + + + <% + } + %> + +
    DayTrader PortfolioDayTrader

    <%=new java.util.Date()%>
    + Alert: The + following Order(s) have completed. +
    + + + <% + Iterator it = closedOrders.iterator(); + while (it.hasNext()) { + OrderDataBean closedOrderData = (OrderDataBean) it.next(); + %> + + + + + + + + + + + + + + + + + + + + + <% + } + %> + + +
    order + IDorder + statuscreation + datecompletion + datetxn + feetypesymbolquantity
    <%=closedOrderData.getOrderID()%><%=closedOrderData.getOrderStatus()%><%=closedOrderData.getOpenDate()%><%=closedOrderData.getCompletionDate()%><%=closedOrderData.getOrderFee()%><%=closedOrderData.getOrderType()%><%=FinancialUtils.printQuoteLink(closedOrderData.getSymbol())%><%=closedOrderData.getQuantity()%>
    +
    + + + + + + +
    + + + + + + + + + + + + + + +
    Portfolio + Number + of Holdings: <%=holdingDataBeans.size()%>
    +
    + + + + + + + + + + + + + + + + <% + // Create Hashmap for quick lookup of quote values + Iterator it = quoteDataBeans.iterator(); + HashMap quoteMap = new HashMap(); + while (it.hasNext()) { + QuoteDataBean quoteData = (QuoteDataBean) it.next(); + quoteMap.put(quoteData.getSymbol(), quoteData); + } + //Step through and printout Holdings + + it = holdingDataBeans.iterator(); + BigDecimal totalGain = new BigDecimal(0.0); + BigDecimal totalBasis = new BigDecimal(0.0); + BigDecimal totalValue = new BigDecimal(0.0); + try { + while (it.hasNext()) { + HoldingDataBean holdingData = (HoldingDataBean) it.next(); + QuoteDataBean quoteData = (QuoteDataBean) quoteMap.get(holdingData.getQuoteID()); + BigDecimal basis = holdingData.getPurchasePrice().multiply(new BigDecimal(holdingData.getQuantity())); + BigDecimal marketValue = quoteData.getPrice().multiply(new BigDecimal(holdingData.getQuantity())); + totalBasis = totalBasis.add(basis); + totalValue = totalValue.add(marketValue); + BigDecimal gain = marketValue.subtract(basis); + totalGain = totalGain.add(gain); + BigDecimal gainPercent = null; + if (basis.doubleValue() == 0.0) { + gainPercent = new BigDecimal(0.0); + Log.error("portfolio.jsp: Holding with zero basis. holdingID=" + holdingData.getHoldingID() + " symbol=" + holdingData.getQuoteID() + + " purchasePrice=" + holdingData.getPurchasePrice()); + } else + gainPercent = marketValue.divide(basis, BigDecimal.ROUND_HALF_UP).subtract(new BigDecimal(1.0)).multiply(new BigDecimal(100.0)); + %> + + + + + + + + + + + + + <% + } + } catch (Exception e) { + Log.error("portfolio.jsp: error displaying user holdings", e); + } + %> + + + + + + + + + + + + +
    + Portfolio +
    holding + IDpurchase + datesymbolquantitypurchase + pricecurrent + pricepurchase + basismarket + valuegain/(loss)trade
    <%=holdingData.getHoldingID()%><%=holdingData.getPurchaseDate()%><%=FinancialUtils.printQuoteLink(holdingData.getQuoteID())%><%=holdingData.getQuantity()%><%=holdingData.getPurchasePrice()%><%=quoteData.getPrice()%><%=basis%><%=marketValue%><%=FinancialUtils.printGainHTML(gain)%><%="sell"%>
    Total$<%=totalBasis%>$<%=totalValue%>$<%=FinancialUtils.printGainHTML(totalGain)%> + <%=FinancialUtils.printGainPercentHTML(FinancialUtils.computeGainPercent(totalValue, totalBasis))%>
    +
    +
    +
    + + + + + + + + + + + + + +
    +
    +
    + + + + + + + +
    Note: Click any symbol + for a quote or to trade. + +
    + + +
    +
    +
    DayTrader PortfolioDayTrader
    + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/properties/daytrader.properties b/src/test/resources/test-applications/daytrader8/src/main/webapp/properties/daytrader.properties new file mode 100644 index 00000000..1f2ebeb2 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/properties/daytrader.properties @@ -0,0 +1,24 @@ + # (C) Copyright IBM Corporation 2015. + # + # 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 + # + # http://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. +runtimeMode=0 +orderProcessingMode=0 +maxUsers=15000 +maxQuotes=10000 +publishQuotePriceChange=true +listQuotePriceChangeFrequency=100 +displayOrderAlerts=true +webInterface=0 +marketSummaryInterval=20 +primIterations=1 +longRun=true diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/quote.jsp b/src/test/resources/test-applications/daytrader8/src/main/webapp/quote.jsp new file mode 100644 index 00000000..e4972624 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/quote.jsp @@ -0,0 +1,234 @@ + + + + + +DayTrader: Quotes and Trading + + + + + + <%@ page + import="java.util.Collection,java.math.BigDecimal,com.ibm.websphere.samples.daytrader.entities.QuoteDataBean,com.ibm.websphere.samples.daytrader.util.Log, + java.util.Iterator,com.ibm.websphere.samples.daytrader.entities.OrderDataBean,com.ibm.websphere.samples.daytrader.util.FinancialUtils" + session="true" isThreadSafe="true" isErrorPage="false"%> + + + + + + + + + + + + + + + + + + + + + <% + Collection closedOrders = (Collection) request.getAttribute("closedOrders"); + if ((closedOrders != null) && (closedOrders.size() > 0)) { + %> + + + + + + + <% + } + %> + +
    DayTrader QuotesDayTrader
    HomeAccountMarket SummaryPortfolioQuotes/TradeLogoff
    +
    <%=new java.util.Date()%> +
    + Alert: The + following Order(s) have completed. +
    + + + <% + Iterator it = closedOrders.iterator(); + while (it.hasNext()) { + OrderDataBean closedOrderData = (OrderDataBean) it.next(); + %> + + + + + + + + + + + + + + + + + + + + + <% + } + %> + + +
    order + IDorder + statuscreation + datecompletion + datetxn + feetypesymbolquantity
    <%=closedOrderData.getOrderID()%><%=closedOrderData.getOrderStatus()%><%=closedOrderData.getOpenDate()%><%=closedOrderData.getCompletionDate()%><%=closedOrderData.getOrderFee()%><%=closedOrderData.getOrderType()%><%=FinancialUtils.printQuoteLink(closedOrderData.getSymbol())%><%=closedOrderData.getQuantity()%>
    +
    + + + + + + +
    + + + + + + + + + + + + +
    Quotes
    + + + + + + + + + + + + + <% + // Create Hashmap for quick lookup of quote values + Iterator it = quoteDataBeans.iterator(); + while (it.hasNext()) { + try { + QuoteDataBean quoteData = (QuoteDataBean) it.next(); + %> + + + + + + + + + + + +<% + } catch (Exception e) { + Log.error("displayQuote.jsp exception. Check that symbol: exists in the database.", e); + } +%> + + + <% + } + %> + +
    symbolcompanyvolumeprice + rangeopen + pricecurrent + pricegain/(loss)trade
    <%=FinancialUtils.printQuoteLink(quoteData.getSymbol())%><%=quoteData.getCompanyName()%><%=quoteData.getVolume()%><%=quoteData.getLow() + " - " + quoteData.getHigh()%><%=quoteData.getOpen()%>$ <%=quoteData.getPrice()%><%=FinancialUtils.printGainHTML(new BigDecimal(quoteData.getChange()))%> + <%=FinancialUtils.printGainPercentHTML(FinancialUtils.computeGainPercent(quoteData.getPrice(), quoteData.getOpen()))%> +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + +
    +
    +
    + + + + + + + +
    Note: Click any symbol + for a quote or to trade. +
    + + +
    +
    DayTrader + QuotesDayTrader
    + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/quote.xhtml b/src/test/resources/test-applications/daytrader8/src/main/webapp/quote.xhtml new file mode 100644 index 00000000..b4822706 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/quote.xhtml @@ -0,0 +1,291 @@ + + + + + DayTrader Quotes + + + + + +
    + + + +
    + +
    + + + + + + + + + + +
    + + Alert: The following Order(s) have completed. + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + + + + + + +
    + + + + + + + + + +
    + Quotes +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + + + + + + + +
    +
    +
    + + + + + + + + + +
    +
    +
    + + + + + + + +
    + + + + +
    +
    +
    +
    +
    +
    + + +
    + \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/quoteDataPrimitive.jsp b/src/test/resources/test-applications/daytrader8/src/main/webapp/quoteDataPrimitive.jsp new file mode 100644 index 00000000..4b6a8f8f --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/quoteDataPrimitive.jsp @@ -0,0 +1,50 @@ + + + + + + + +Quote Data Primitive (PingServet2Session2Entity2JSP) + + + <%@ page + import="com.ibm.websphere.samples.daytrader.entities.QuoteDataBean,com.ibm.websphere.samples.daytrader.util.FinancialUtils" + session="false" isThreadSafe="true" isErrorPage="false"%> + <%!int hitCount = 0; + String initTime = new java.util.Date().toString();%> + <% + QuoteDataBean quoteData = (QuoteDataBean) request.getAttribute("quoteData"); + %> +
    +
    + Quote Data Primitive + (PingServlet2Session2EntityJSP):
    +
    + Init time: <%=initTime%> + <% + hitCount++; + %> +

    + Hit Count: <%=hitCount%> +

    +
    + Quote Information +
    +
    <%=quoteData.toHTML()%> + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/quoteImg.jsp b/src/test/resources/test-applications/daytrader8/src/main/webapp/quoteImg.jsp new file mode 100644 index 00000000..9ae34c54 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/quoteImg.jsp @@ -0,0 +1,255 @@ + + + + + +DayTrader: Quotes and Trading + + + + + + <%@ page + import="java.util.Collection,java.math.BigDecimal,com.ibm.websphere.samples.daytrader.util.Log, + java.util.Iterator,com.ibm.websphere.samples.daytrader.entities.OrderDataBean,com.ibm.websphere.samples.daytrader.entities.QuoteDataBean,com.ibm.websphere.samples.daytrader.util.FinancialUtils" + session="true" isThreadSafe="true" isErrorPage="false"%> + + + + + + + + + + + + + + + + + + + + <% + Collection closedOrders = (Collection) request.getAttribute("closedOrders"); + if ((closedOrders != null) && (closedOrders.size() > 0)) { + %> + + + + + + + <% + } + %> + +
    DayTrader QuotesDayTrader

    <%=new java.util.Date()%>
    + Alert: The + following Order(s) have completed. +
    + + + <% + Iterator it = closedOrders.iterator(); + while (it.hasNext()) { + OrderDataBean closedOrderData = (OrderDataBean) it.next(); + %> + + + + + + + + + + + + + + + + + + + + + <% + } + %> + + +
    order + IDorder + statuscreation + datecompletion + datetxn + feetypesymbolquantity
    <%=closedOrderData.getOrderID()%><%=closedOrderData.getOrderStatus()%><%=closedOrderData.getOpenDate()%><%=closedOrderData.getCompletionDate()%><%=closedOrderData.getOrderFee()%><%=closedOrderData.getOrderType()%><%=FinancialUtils.printQuoteLink(closedOrderData.getSymbol())%><%=closedOrderData.getQuantity()%>
    +
    + + + + + + +
    + + + + + + + + + + + + +
    Quotes
    + + + + + + + + + + + + + + <% + // Create Hashmap for quick lookup of quote values + Iterator it = quoteDataBeans.iterator(); + while (it.hasNext()) { + try { + QuoteDataBean quoteData = (QuoteDataBean) it.next(); + %> + + + + + + + + + + + +<% + } catch (Exception e) { + Log.error("displayQuote.jsp exception. Check that symbol: exists in the database.", e); + } +%> + + + <% + } + %> + +
    symbolcompanyvolumeprice + rangeopen + pricecurrent + pricegain/(loss)trade
    <%=FinancialUtils.printQuoteLink(quoteData.getSymbol())%><%=quoteData.getCompanyName()%><%=quoteData.getVolume()%><%=quoteData.getLow() + " - " + quoteData.getHigh()%><%=quoteData.getOpen()%>$ <%=quoteData.getPrice()%><%=FinancialUtils.printGainHTML(new BigDecimal(quoteData.getChange()))%> + <%=FinancialUtils.printGainPercentHTML(FinancialUtils.computeGainPercent(quoteData.getPrice(), quoteData.getOpen()))%> +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + +
    +
    +
    + + + + + + + +
    Note: Click any symbol + for a quote or to trade. + +
    + + +
    +
    +
    DayTrader QuotesDayTrader
    +
    + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/quotes.html b/src/test/resources/test-applications/daytrader8/src/main/webapp/quotes.html new file mode 100644 index 00000000..a69d6f6c --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/quotes.html @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    + +
    + + + +
    + + + + + + + + + + + + + +

    Get Quotes

    symbol(s):
    +
    +
    +
    + + + + + + + + + + +
    Recent Price Changes
    Recent Price Changes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    SymbolPriceChange
    +
    +
    + +
    +
    + +

     

    diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/register.jsp b/src/test/resources/test-applications/daytrader8/src/main/webapp/register.jsp new file mode 100644 index 00000000..d97eae03 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/register.jsp @@ -0,0 +1,169 @@ + + + + +DayTrader Registration + + + + <%@ page session="false"%> + <% + String blank = ""; + String fakeCC = "123-fake-ccnum-456"; + String fullname = request.getParameter("Full Name"); + String snailmail = request.getParameter("snail mail"); + String email = request.getParameter("email"); + String userID = request.getParameter("user id"); + String money = request.getParameter("money"); + String creditcard = request.getParameter("Credit Card Number"); + String results = (String) request.getAttribute("results"); + %> + + + + + + + +
    DayTrader + RegisterDayTrader
    + + + + + + + + +
    <%=results == null ? blank : results%>
    + + + + + + + +
    Register +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    *Full name:
    *Address:
    *E-Mail address:
      
    *User ID:
    *Password:
    *Confirm password:
      
    *Opening account + balance:$
    *Credit card number:  
    + +
    + + + + + + + + + + + + + +
    +
    +
    DayTrader + RegisterDayTrader
    + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/register.xhtml b/src/test/resources/test-applications/daytrader8/src/main/webapp/register.xhtml new file mode 100644 index 00000000..868b249c --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/register.xhtml @@ -0,0 +1,205 @@ + + + + + DayTrader Register + + + + +
    + + +
    + +
    + + + + + + + + + +
    + + + +
    + + + + + + +
    +

    Register

    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + * + Full name: + + + + +
    + * + Address: + + + + +
    + * + E-Mail address: + + + + +
      
    + * + User ID: + + + + +
    + + * + Password: + + + + + +
    + + * + Confirm password: + + + + + +
      
    + * + Opening account balance: + + + + +
    + + * + Credit card number: + + + + + +
    + +
    +
    +
    +
    +
    + +
    + \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/registerImg.jsp b/src/test/resources/test-applications/daytrader8/src/main/webapp/registerImg.jsp new file mode 100644 index 00000000..6b41d064 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/registerImg.jsp @@ -0,0 +1,172 @@ + + + + +DayTrader Registration + + + + <%@ page session="false"%> + <% + String blank = ""; + String fakeCC = "123-fake-ccnum-456"; + String fullname = request.getParameter("Full Name"); + String snailmail = request.getParameter("snail mail"); + String email = request.getParameter("email"); + String userID = request.getParameter("user id"); + String money = request.getParameter("money"); + String creditcard = request.getParameter("Credit Card Number"); + String results = (String) request.getAttribute("results"); + %> + + + + + + + +
    DayTrader + Register
    + + + + + + + + +
    <%=results == null ? blank : results%>
    + + + + + + + +
    Register +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    *Full name:
    *Address:
    *E-Mail address:
      
    *User ID:
    *Password:
    *Confirm password:
      
    *Opening account + balance:$
    *Credit card number:  
    + +
    + + + + + + + + + + + + + +
    +
    +
    DayTrader + HomeDayTrader
    + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/runStats.jsp b/src/test/resources/test-applications/daytrader8/src/main/webapp/runStats.jsp new file mode 100644 index 00000000..f196a6db --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/runStats.jsp @@ -0,0 +1,445 @@ + + + + + +Welcome to Trade + + + <%@ page + import="com.ibm.websphere.samples.daytrader.util.TradeConfig" + session="false" isThreadSafe="true" isErrorPage="false"%> + + + <% + double loginPercentage = (double) ((TradeConfig.getScenarioMixes())[0][TradeConfig.LOGOUT_OP]) / 100.0; + double logoutPercentage = (double) ((TradeConfig.getScenarioMixes())[0][TradeConfig.LOGOUT_OP]) / 100.0; + double buyOrderPercentage = (double) ((TradeConfig.getScenarioMixes())[0][TradeConfig.BUY_OP]) / 100.0; + double sellOrderPercentage = (double) ((TradeConfig.getScenarioMixes())[0][TradeConfig.SELL_OP]) / 100.0; + double orderPercentage = buyOrderPercentage + sellOrderPercentage; + double registerPercentage = (double) ((TradeConfig.getScenarioMixes())[0][TradeConfig.REGISTER_OP]) / 100.0; + + int logins = runStatsData.getSumLoginCount() - runStatsData.getTradeUserCount(); //account for each user being logged in up front + if (logins < 0) + logins = 0; //no requests before reset + //double expectedRequests = ((double) logins) / loginPercentage; + double expectedRequests = (double) TradeConfig.getScenarioCount(); + TradeConfig.setScenarioCount(0); + + int verifyPercent = TradeConfig.verifyPercent; + %> + <%!// verifies 2 values are w/in tradeConfig.verifyPercent percent + String verify(double expected, double actual, int verifyPercent) { + String retVal = ""; + if ((expected == 0.0) || (actual == 0.0)) + return "N/A"; + double check = (actual / expected) * 100 - 100; + //PASS + retVal += check + "% "; + if ((check >= (-1.0 * verifyPercent)) && (check <= verifyPercent)) + retVal += " Pass"; + else + retVal += " Fail4"; + if (check > 0.0) + retVal = "+" + retVal; + //System.out.println("verify --- expected="+expected+" actual="+actual+ " check="+check); + return retVal; + } + + String verify(int expected, int actual, int verifyPercent) { + return verify((double) expected, (double) actual, verifyPercent); + }%> +
    + + + + + + + + +
    DayTrader Scenario + Runtime StatisticsDayTrader
    + + + + + + + + +
    <% + String status; + status = (String) request.getAttribute("status"); + if (status != null) + out.print(status); + %> + Modify + runtime configuration
    +
    + + + + + + +
    + + + + + + + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + Benchmark + scenario statistics +
    Benchmark + runtime + configuration + summaryValue +
    Run-Time + Mode<%=(TradeConfig.getRunTimeModeNames())[TradeConfig.getRunTimeMode()]%>
    Order-Processing + Mode<%=(TradeConfig.getOrderProcessingModeNames())[TradeConfig.getOrderProcessingMode()]%>
    Web + Interface<%=(TradeConfig.getWebInterfaceNames())[TradeConfig.getWebInterface()]%>
    Active + Traders / Trade + User population<%=runStatsData.getTradeUserCount()%> + / <%=TradeConfig.getMAX_USERS()%> +
    Active + Stocks / Trade + Stock population<%=TradeConfig.getMAX_QUOTES()%> + / <%=runStatsData.getTradeStockCount()%>
    Benchmark + scenario + verification
    Run + StatisticScenario + verification + testExpected + ValueActual + ValuePass/Fail
    Active StocksActive stocks + should generally + equal the db + population of stocks<%=runStatsData.getTradeStockCount()%><%=TradeConfig.getMAX_QUOTES()%><%=(runStatsData.getTradeStockCount() == TradeConfig.getMAX_QUOTES()) ? "Pass" : "Warn"%>
    Active + TradersActive traders + should generally + equal the db + population of + traders<%=runStatsData.getTradeUserCount()%><%=TradeConfig.getMAX_USERS()%><%=(runStatsData.getTradeUserCount() == TradeConfig.getMAX_USERS()) ? "Pass" : "Warn"%>
    Estimated + total requestsActual + benchmark scenario + requests should be + within +/- 2% of the + estimated number of + requests in the last + benchmark run to + pass.<%=expectedRequests%>see2see2
    New + Users Registered + <%=registerPercentage * 100%>% + of expected requests + (<%=registerPercentage%> + * <%=expectedRequests%> + )<%=registerPercentage * expectedRequests%><%=runStatsData.getNewUserCount()%><%=verify(registerPercentage * expectedRequests, (double) runStatsData.getNewUserCount(), verifyPercent)%>
    Logins + <%=loginPercentage * 100%>% + of expected requests + (<%=loginPercentage%> + * <%=expectedRequests%> + ) + initial login<%=loginPercentage * expectedRequests + runStatsData.getTradeUserCount()%><%=runStatsData.getSumLoginCount() + runStatsData.getTradeUserCount()%><%=verify((double) loginPercentage * expectedRequests, (double) runStatsData.getSumLoginCount(), verifyPercent)%>
    Logouts + #logouts must + be >= + #logins-active + traders ( <%=runStatsData.getSumLoginCount()%> + - <%=TradeConfig.getMAX_USERS()%> + ) + <%=runStatsData.getSumLoginCount() - TradeConfig.getMAX_USERS()%><%=runStatsData.getSumLogoutCount()%><%=(runStatsData.getSumLogoutCount() >= (runStatsData.getSumLoginCount() - TradeConfig.getMAX_USERS())) ? "Pass" : "Fail4"%> +
    User + Holdings Trade users own + an average of 5 + holdings, 5* total + Users = ( 5 * <%=runStatsData.getTradeUserCount()%>) + <%=5 * runStatsData.getTradeUserCount()%><%=runStatsData.getHoldingCount()%><%=verify(5 * runStatsData.getTradeUserCount(), runStatsData.getHoldingCount(), verifyPercent)%>
    Buy + Order Count <%=buyOrderPercentage * 100%>% + of expected requests + (<%=buyOrderPercentage%> + * <%=expectedRequests%> + ) + current holdings + count<%=buyOrderPercentage * expectedRequests + runStatsData.getHoldingCount()%><%=runStatsData.getBuyOrderCount()%><%=verify(buyOrderPercentage * expectedRequests + runStatsData.getHoldingCount(), (double) runStatsData.getBuyOrderCount(), verifyPercent)%>
    Sell + Order Count <%=sellOrderPercentage * 100%>% + of expected requests + (<%=sellOrderPercentage%> + * <%=expectedRequests%> + )<%=sellOrderPercentage * expectedRequests%><%=runStatsData.getSellOrderCount()%><%=verify(sellOrderPercentage * expectedRequests, (double) runStatsData.getSellOrderCount(), verifyPercent)%>
    Total + Order Count <%=orderPercentage * 100%>% + of expected requests + (<%=orderPercentage%> + * <%=expectedRequests%> + ) + current holdings + count<%=orderPercentage * expectedRequests + runStatsData.getHoldingCount()%><%=runStatsData.getOrderCount()%><%=verify(orderPercentage * expectedRequests + runStatsData.getHoldingCount(), (double) runStatsData.getOrderCount(), verifyPercent)%>
    Open + Orders All orders + should be completed + before reset3 + 0<%=runStatsData.getOpenOrderCount()%><%=(runStatsData.getOpenOrderCount() > 0) ? "Fail4" : "Pass"%>
    Cancelled + Orders Orders are + cancelled if an + error is encountered + during order + processing.0<%=runStatsData.getCancelledOrderCount()%><%=(runStatsData.getCancelledOrderCount() > 0) ? "Fail4" : "Pass"%>
    Orders + remaining after + reset After Trade + reset, each user + should carry an + average of 5 orders + in the database. 5* + total Users = (5 * <%=runStatsData.getTradeUserCount()%>) + <%=5 * runStatsData.getTradeUserCount()%><%=runStatsData.getOrderCount() - runStatsData.getDeletedOrderCount()%><%=verify(5 * runStatsData.getTradeUserCount(), runStatsData.getOrderCount() - runStatsData.getDeletedOrderCount(), verifyPercent)%>
    +
    +
    +
    +
    +
      +
    1. + Benchmark verification + tests require a Trade + Reset between each + benchmark run.
    2. +
    3. The + expected value of + benchmark requests is + computed based on the + the count from the Web + application since the + last Trade reset.The + actual value of + benchmark request + requires user + verification and may be + incorrect for a cluster.
    4. +
    5. Orders + are processed + asynchronously in Trade. + Therefore, processing + may continue beyond the + end of a benchmark run. + Trade Reset should not + be invoked until + processing is completed.
    6. +
    7. Actual + values must be within + <%=TradeConfig.verifyPercent%>% + of + corresponding estimated + values to pass + verification.
    8. +
    +
    +
    +
    + + + + + + + + + + + + + + + + + +
    +
    +
    DayTrader Scenario + Runtime StatisticsDayTrader
    +
    + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/sample.jsp b/src/test/resources/test-applications/daytrader8/src/main/webapp/sample.jsp new file mode 100644 index 00000000..487f6fa7 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/sample.jsp @@ -0,0 +1,26 @@ + +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> +<%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml"%> +<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql"%> + + + + Hello world JSP on + + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/style-jsf.css b/src/test/resources/test-applications/daytrader8/src/main/webapp/style-jsf.css new file mode 100644 index 00000000..6381df0c --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/style-jsf.css @@ -0,0 +1,253 @@ +/* + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. + */ + + +* { + margin: 0; +} + +html { + height: 100%; +} + +#page-wrap { + min-height: 100%; + /* equal to footer height */ + margin-bottom: -31px; +} + +#page-wrap:after { + content: ""; + display: block; + height: 31px; +} + +body { + height: 100%; + margin: 0; + background-color: #ccc +} + +#content { + width: 700px; + margin: 0 auto; + padding-top: 95px; + padding-bottom: 31px; + font-size: 13px; +} + +#header { + width: 100%; + background-color: #FFFFFF; + position: fixed; +} + +#nav { + width: 100%; + float: left; + margin: 0; + padding: 0 0; + background: url(images/nav_bg.png) repeat-x; +} + +#nav ul { + list-style: none; + width: 450px; + margin: 0 auto; + padding: 0; + height: 31px; + line-height: 31px; +} + +#nav li { + float: left; +} + +#nav li a { + display: block; + width: 90px; + text-align: center; + vertical-align: middle; + font-size: 13px; + padding: 0 0; + text-decoration: none; + font-weight: bold; + color: white; +} + +#nav li a:hover { + text-decoration: underline; +} + +#nav2 { + width: 100%; + float: left; + margin: 0; + padding: 0 0; + background: url(images/nav_bg.png) repeat-x; +} + +#nav2 ul { + list-style: none; + width: 540px; + margin: 0 auto; + padding: 0; + height: 31px; + line-height: 31px; +} + +#nav2 li { + float: left; +} + +#nav2 li a { + display: block; + width: 90px; + text-align: center; + vertical-align: middle; + font-size: 13px; + padding: 0 0; + text-decoration: none; + font-weight: bold; + color: white; +} + +#nav2 li a:hover { + text-decoration: underline; +} + +#footer { + position: absolute; + height: 31px; + line-height: 31px; + vertical-align: middle; + width: 100%; + background: url(images/nav_bg.png) repeat-x; + margin: 0; + color: white; + text-align: center; + font-size: 13px; +} + +#contentContainer { + margin-top: 10px; + border: 1px solid #000; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; + width: 700px; + margin-left: auto; + margin-right: auto; + padding: 10px; + background-color: #eee; + font-size: 14px; + text-decoration: none; +} + +#contentContainer a { + text-decoration: none; + color: #333333; +} + +#loginContainer { + margin-top: 10px; + border: 1px solid #000; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; + width: 400px; + margin-left: auto; + margin-right: auto; + padding: 10px; + background-color: #eee; + font-size: 14px; + text-decoration: none; +} + +#loginContainer a { + text-decoration: none; + color: #333333; +} + +input.rounded { + border: 1px solid #ccc; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; + font-size: 13px; + padding: 4px 4px; + outline: 0; + -webkit-appearance: none; # + margin-bottom: 20px; +} + +input.submit { + border: 1px solid #ccc; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; + font-size: 13px; + padding: 4px 4px; + outline: 1; + -webkit-appearance: none; # + margin-bottom: 20px; + background-color: #0066CC; + color: white; +} + +.table { + border-collapse: collapse; + border: 1px solid #000000; +} + +.tableHeader { + text-align: center; + background: none repeat scroll 0 0 #B5B5B5; + border: 1px solid #000000; + padding: 2px; + font-size: 12px; +} + +.tableHeaderMarket { + text-align: center; + background: none repeat scroll 0 0 #000000; + border: 1px solid #000000; + padding: 10px; + font-size: 14px; +} + +.tableOddRow { + text-align: center; + font-size: 12px; + font-weight: none; + border: 1px solid #000000; + background: none repeat scroll 0 0 #FFFFFF; + padding: 2px; +} + +.tableEvenRow { + text-align: center; + font-size: 12px; + font-weight: none; + border: 1px solid #000000; + background: none repeat scroll 0 0 #fafcb6; + padding: 2px; +} + +.tableColumn { + border: 1px solid #000000; + padding: 2px; +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/style.css b/src/test/resources/test-applications/daytrader8/src/main/webapp/style.css new file mode 100644 index 00000000..3d92fcde --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/style.css @@ -0,0 +1,82 @@ +/*====================================================================== + * (C) Copyright IBM Corporation 2015. + * + * 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 + * + * http://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. +======================================================================*/ +tr th td body { + font-size:12pt; +} + +A:HOVER { + text-decoration: underline; color: red; +} + +A:ACTIVE { + color: red; + font-weight: bold +} + +.table{ + border-collapse:collapse; + border:1px solid #000000; +} + +.tableHeader{ + text-align:center; + background:none repeat scroll 0 0 #B5B5B5; + border:1px solid #000000; + padding:10px; + font-size:12px; +} + +.tableHeaderMarket{ + text-align:center; + background:none repeat scroll 0 0 #000000; + border:1px solid #000000; + padding:10px; + font-size:14px; +} + +.tableOddRow{ + text-align:center; + font-size:12px; + font-weight: none; + border:1px solid #000000; + background:none repeat scroll 0 0 #FFFFFF; +} + +.tableEvenRow{ + text-align:center; + font-size:12px; + font-weight: none; + border:1px solid #000000; + background:none repeat scroll 0 0 #D3D3D3; +} +.tableColumn{ + border:1px solid #000000; +} + +.tableHeader +{ + background:none repeat scroll 0 0 #FFFFFF; + border-collapse: collapse; + border-spacing: 0px; +} +.tableHeader td +{ + padding: 0px 0px; +} +.tableHeader tr +{ + padding: 0px 0px; +} \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/tradehome.jsp b/src/test/resources/test-applications/daytrader8/src/main/webapp/tradehome.jsp new file mode 100644 index 00000000..aead7aae --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/tradehome.jsp @@ -0,0 +1,251 @@ + + + + + +Welcome to DayTrader + + + + + <%@ page + import="java.util.Collection, + java.util.Iterator, + java.math.BigDecimal,com.ibm.websphere.samples.daytrader.entities.OrderDataBean,com.ibm.websphere.samples.daytrader.util.FinancialUtils" + session="true" isThreadSafe="true" isErrorPage="false"%> + + + + + + + + + + + + + + + + + + + + + + + <% + Collection closedOrders = (Collection) request.getAttribute("closedOrders"); + if ((closedOrders != null) && (closedOrders.size() > 0)) { + %> + + + + + + + <% + } + %> + +
    DayTrader HomeDayTrader
    HomeAccountMarket SummaryPortfolioQuotes/TradeLogoff
    +
    <%=new java.util.Date()%> +
    + Alert: The + following Order(s) have completed. +
    + + + <% + Iterator it = closedOrders.iterator(); + while (it.hasNext()) { + OrderDataBean closedOrderData = (OrderDataBean) it.next(); + %> + + + + + + + + + + + + + + + + + + + + + <% + } + %> + + +
    order + IDorder + statuscreation + datecompletion + datetxn + feetypesymbolquantity
    <%=closedOrderData.getOrderID()%><%=closedOrderData.getOrderStatus()%><%=closedOrderData.getOpenDate()%><%=closedOrderData.getCompletionDate()%><%=closedOrderData.getOrderFee()%><%=closedOrderData.getOrderType()%><%=FinancialUtils.printQuoteLink(closedOrderData.getSymbol())%><%=closedOrderData.getQuantity()%>
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Welcome +  <%=accountData.getProfileID()%>, +
    User + Statistics
    account + ID:
    +
    account + created:
    total + logins:
    session + created:
    <%=accountData.getAccountID()%>
    + <%=accountData.getCreationDate()%>
    + <%=accountData.getLoginCount()%>
    + <%=(java.util.Date) session.getAttribute("sessionCreationDate")%>
    Account + Summary
    cash + balance:
    number + of holdings:
    total + of holdings:
    sum of + cash/holdings
    opening + balance:
    +
    +
    + <% + BigDecimal openBalance = accountData.getOpenBalance(); + BigDecimal balance = accountData.getBalance(); + BigDecimal holdingsTotal = FinancialUtils.computeHoldingsTotal(holdingDataBeans); + BigDecimal sumOfCashHoldings = balance.add(holdingsTotal); + BigDecimal gain = FinancialUtils.computeGain(sumOfCashHoldings, openBalance); + BigDecimal gainPercent = FinancialUtils.computeGainPercent(sumOfCashHoldings, openBalance); + %>$ <%=balance%>
    <%=holdingDataBeans.size()%>
    + $ <%=holdingsTotal%>
    $ <%=sumOfCashHoldings%>
    + $ <%=openBalance%>
    + +
    +
    current + gain/(loss):$ <%=FinancialUtils.printGainHTML(gain)%> + <%=FinancialUtils.printGainPercentHTML(gainPercent)%>
    +

    +
    + + + + + + + + + + + + + +
    +
    +
    + + + + + + + +
    Note: Click any symbol + for a quote or to trade. + +
    + + +
    +
    +
    DayTrader + HomeDayTrader
    + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/tradehome.xhtml b/src/test/resources/test-applications/daytrader8/src/main/webapp/tradehome.xhtml new file mode 100644 index 00000000..23ed8ed2 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/tradehome.xhtml @@ -0,0 +1,283 @@ + + + + + DayTrader Home + + + + + +
    + + + +
    + +
    + + +

    + Welcome  + +

    + + + + + + + + + +
    + + Alert: The following Order(s) have completed. + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    User Statistics

    +
    + account ID: +
    + account created: +
    + total logins: +
    + session created: +
    +
    + +
    + +
    + +
    + +
    +
    +

    Account Summary

    +
    + cash balance: +
    + number of holdings: +
    + total of holdings: +
    + sum of cash/holdings +
    + opening balance: +
    +
    +
    + $  + +
    + +
    + $  + +
    + $  + +
    + $  + +
    +
    +
    + current gain/(loss): + + $ + + +   + + +
    + + + + + + + + + + +
    +
    +
    + + + + + + + +
    + + + + +
    +
    +
    +
    +
    +
    + + +
    + \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/tradehomeImg.jsp b/src/test/resources/test-applications/daytrader8/src/main/webapp/tradehomeImg.jsp new file mode 100644 index 00000000..3d7a2990 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/tradehomeImg.jsp @@ -0,0 +1,267 @@ + + + + + +Welcome to DayTrader + + + + + <%@ page + import="java.util.Collection, + java.util.Iterator, + java.math.BigDecimal,com.ibm.websphere.samples.daytrader.entities.AccountDataBean,com.ibm.websphere.samples.daytrader.entities.OrderDataBean,com.ibm.websphere.samples.daytrader.util.FinancialUtils" + session="true" isThreadSafe="true" isErrorPage="false"%> + + + + + + + + + + + + + + + + + + + + + + <% + Collection closedOrders = (Collection) request.getAttribute("closedOrders"); + if ((closedOrders != null) && (closedOrders.size() > 0)) { + %> + + + + + + + <% + } + %> + +
    DayTrader HomeDayTrader

    <%=new java.util.Date()%>
    + Alert: The + following Order(s) have completed. +
    + + + <% + Iterator it = closedOrders.iterator(); + while (it.hasNext()) { + OrderDataBean closedOrderData = (OrderDataBean) it.next(); + %> + + + + + + + + + + + + + + + + + + + + + <% + } + %> + + +
    order + IDorder + statuscreation + datecompletion + datetxn + feetypesymbolquantity
    <%=closedOrderData.getOrderID()%><%=closedOrderData.getOrderStatus()%><%=closedOrderData.getOpenDate()%><%=closedOrderData.getCompletionDate()%><%=closedOrderData.getOrderFee()%><%=closedOrderData.getOrderType()%><%=FinancialUtils.printQuoteLink(closedOrderData.getSymbol())%><%=closedOrderData.getQuantity()%>
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Welcome +  <%=accountData.getProfileID()%>, +
    User + Statistics
    account + ID:
    +
    account + created:
    total + logins:
    session + created:
    <%=accountData.getAccountID()%>
    + <%=accountData.getCreationDate()%>
    + <%=accountData.getLoginCount()%>
    + <%=(java.util.Date) session.getAttribute("sessionCreationDate")%>
    Account + Summary
    cash + balance:
    number + of holdings:
    total + of holdings:
    sum of + cash/holdings
    opening + balance:
    +
    +
    + <% + BigDecimal openBalance = accountData.getOpenBalance(); + BigDecimal balance = accountData.getBalance(); + BigDecimal holdingsTotal = FinancialUtils.computeHoldingsTotal(holdingDataBeans); + BigDecimal sumOfCashHoldings = balance.add(holdingsTotal); + BigDecimal gain = FinancialUtils.computeGain(sumOfCashHoldings, openBalance); + BigDecimal gainPercent = FinancialUtils.computeGainPercent(sumOfCashHoldings, openBalance); + %>$<%=balance%>
    <%=holdingDataBeans.size()%>
    + $<%=holdingsTotal%>
    $<%=sumOfCashHoldings%>
    + $<%=openBalance%>
    + +
    +
    current + gain/(loss):$ <%=FinancialUtils.printGainHTML(gain)%> + <%=FinancialUtils.printGainPercentHTML(gainPercent)%>
    +

    + + + + + + + + + + + + + + + + +
    + + + + + + + +
    Note: Click any symbol + for a quote or to trade. + +
    + + +
    +
    +
    DayTrader HomeDayTrader
    + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/web_prmtv.html b/src/test/resources/test-applications/daytrader8/src/main/webapp/web_prmtv.html new file mode 100644 index 00000000..fa2b5837 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/web_prmtv.html @@ -0,0 +1,449 @@ + + + + + + +Web Primitives + + + + +
    + + + + + + + +
    +

    Web and EJB Primitive Tests

    +
    +
    + + + + + + + + + + + +
    Primitive Test Suite
    +

    The DayTrader performance benchmark sample + provides a suite of web primitives. These + primitives singularly test key operations in the + enterprise Java programming model. Links to each + of the web primitive tests are provided below + along with a description of each operation.

    +

    + Note that some primitives below can have their + main operations repeated. These operations are + marked with a red *. + In order to adjust the repetition, change the + primitive iteration value in the Trade + configuration page. +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Web Container ping suite
    PingHtmlPingHtml is the most + basic operation providing access to a simple + "Hello World" page of static HTML.
    Explicit GCInvoke Garbage + Collection on AppServer. Reports heap statistics + after the GC has completed.
    PingServletPingServlet tests + fundamental dynamic HTML creation through server + side servlet processing.
    PingServletCDIPingServletCDI tests various simple CDI invocations.
    PingServletCDIBeanManagerViaJNDIPingServletCDIBeanManagerViaJNDI tests getting the BeanManager with JNDI.
    PingServletCDIBeanManagerViaCDICurrentPingServletCDIBeanManagerViaCDICurrent tests getting the BeanManager with the CDI spi.
    PingServletWriter + PingServletWriter + extends PingServlet by using a PrintWriter for + formatted output vs. the output stream used by + PingServlet.
    PingServlet2Include*PingServlet2Include + tests response inclusion. Servlet 1 includes the + response of Servlet 2.
    PingServlet2ServletPingServlet2Servlet + tests request dispatching. Servlet 1, the + controller, creates a new JavaBean object + forwards the request with the JavaBean added to + Servlet 2. Servlet 2 obtains access to the + JavaBean through the Servlet request object and + provides dynamic HTML output based on the + JavaBean data.
    PingJSPPingJSP tests a direct + call to JavaServer Page providing server-side + dynamic HTML through JSP scripting.
    PingJSPELPingJSPEL tests a direct + call to JavaServer Page providing server-side + dynamic HTML through JSP scripting and the usage + of the new JSP 2.0 Expression Language.
    PingServlet2JSPPingServlet2JSP tests a + commonly used design pattern, where a request is + issued to servlet providing server side control + processing. The servlet creates a JavaBean + object with dynamically set attributes and + forwards the bean to the JSP through a + RequestDispatcher The JSP obtains access to the + JavaBean and provides formatted display with + dynamic HTML output based on the JavaBean data.
    PingServlet2PDFPingServlet2PDF tests a + call to a servlet which displays the contents of + a PDF Document (~1 MB in file size).
    PingServlet2DBPingServlet2DB tests a + call to a servlet which makes a JDBC connection + to the database.
    PingJSFPingJSF tests a + call to a JSF Facelet which performs a lookup + of quotes.
    PingCDIJSFPingCDIJSF tests a MangedBean called from a jsf page.
    PingHTTPSession1 + PingHTTPSession1 - SessionID + tests fundamental HTTP session function by + creating a unique session ID for each individual + user. The ID is stored in the users session and + is accessed and displayed on each user request. +
    PingHTTPSession2PingHTTPSession2 session + create/destroy further extends the previous + test by invalidating the HTTP Session on every + 5th user access. This results in testing + HTTPSession create and destroy +
    PingHTTPSession3PingHTTPSession3 large + session object tests the servers ability to + manage and persist large HTTPSession data + objects. The servlet creates a large custom java + object. The class contains multiple data fields + and results in 2048 bytes of data. This large + session object is retrieved and stored to the + session on each user request. +
    PingJDBCRead*PingJDBCRead tests + fundamental servlet to JDBC access to a database + performing a single-row read using a prepared + SQL statment.
    PingJDBCRead2JSP*PingJDBCRead2JSP tests + fundamental servlet to JDBC access to a database + performing a single-row read using a prepared + SQL statment, then displays the output in a JSP.
    PingJDBCWrite*PingJDBCRead tests + fundamental servlet to JDBC access to a database + performing a single-row write using a prepared + SQL statment.
    PingServlet2JNDI*PingServlet2JNDI tests + the fundamental J2EE operation of a servlet + allocating a JNDI context and performing a JNDI + lookup of a JDBC DataSource.
    PingUpgradeServletPingUpgradeServlet tests a simple UpgradeHandler request. JMeter is needed for testing.
    PingWebSocketTextSyncPingWebSocketTextSync tests a simple synchronous WebSocket with text.
    PingWebSocketTextAsyncPingWebSocketTextAsync tests a simple asynchronous WebSocket with text.
    PingWebSocketBinaryPingWebSocketBinary tests a simple WebSocket with binary data.
    PingWebSocketJsonPingWebSocketJson tests a WebSocket with a JSON Decoder and Encoder.
    PingManagedThreadPingManagedThread tests a ManagedThreadFactory inside an asynchronous servlet.
    PingManagedExecutorPingManagedExecutor tests the ManagedExecutorService inside an asynchronous servlet.
    + + PingJSONP + + + PingJSONP tests generating and parsing JSON. +
    EJB 3 Container ping + suite
    PingServlet2Session*PingServlet2Session + tests key function of a servlet call to a remote + stateless Session EJB. The Session EJB performs + a simple calculation and returns the result
    PingServlet2Entity*
    PingServlet2Entity tests key function of a + servlet call to an EJB 3.0 Container Managed Entity. In this test the + EJB entity represents a single row in the database table.
    PingServlet2Session2Entity*This tests the full + servlet to Session EJB to Entity EJB path to + retrieve a single row from the database.
    PingServlet2Session2Entity2JSP*This tests the full + servlet to Session EJB to Entity EJB path to + retrieve a single row from the database and + displays the output in a JSP.
    PingServlet2Session2
    + EntityCollection +
    *
    This test extends the + previous EJB Entity test by calling a Session + EJB which uses a finder method on the Entity + that returns a collection of Entity objects. + Each object is displayed by the servlet.
    PingServlet2Session2CMROne2One*This test drives an + Entity EJB to get another Entity EJB's data + through an EJB 3.0 CMR One to One relationship.
    PingServlet2Session2CMROne2Many*This test drives an + Entity EJB to get another Entity EJB's data + through an EJB 3.0 CMR One to Many relationship.
    PingServlet2MDBQueue*PingServlet2MDBQueue + drives messages to a Queue based Message Driven + EJB (MDB). Each request to the servlet posts a + message to the Queue. The MDB receives the + message asynchronously and prints message + delivery statistics on each 100th message. Note: Not intended + for performance testing. + +
    PingServlet2MDBTopic*PingServlet2MDBTopic + drives messages to a Topic based + Publish/Subscribe Message Driven EJB (MDB). Each + request to the servlet posts a message to the + Topic. The TradeStreamMDB receives the message + asynchronously and prints message delivery + statistics on each 100th message. Other + subscribers to the Topic will also receive the + messages. Note: + Not intended for performance testing. +
    PingServlet2TwoPhase*PingServlet2TwoPhase + drives a Session EJB which invokes an Entity EJB + with findByPrimaryKey (DB Access) followed by + posting a message to an MDB through a JMS Queue + (Message access). These operations are wrapped + in a global 2-phase transaction and commit.
    + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/web_prmtv.xhtml b/src/test/resources/test-applications/daytrader8/src/main/webapp/web_prmtv.xhtml new file mode 100644 index 00000000..3cfda53c --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/web_prmtv.xhtml @@ -0,0 +1,584 @@ + + + + + DayTrader Primitives + + + + +
    + + +
    + +
    + + + + + + + +
    +

    Web Primitive Tests

    +
    + + + + + + + + + + +
    + + Primitive Test Suite + +
    +

    The DayTrader performance benchmark sample provides a suite of web primitives. These primitives singularly test key operations in the + enterprise Java programming model. Links to each of the web primitive tests are provided below along with a description of each operation.

    +

    + Note that some primitives below can have their main operations repeated. These operations are marked with a red + * + . In order to adjust the repetition, change the primitive iteration value in the Trade configuration page. + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + Web Container ping suite + +
    + + + PingHtml + + + + PingHtml is the most basic operation providing access to a simple "Hello World" page of static HTML. +
    + + + Explicit GC + + + + Invoke Garbage Collection on AppServer. Reports heap statistics after the GC has completed. +
    + + + PingServlet + + + + PingServlet tests fundamental dynamic HTML creation through server side servlet processing. +
    PingServletCDIPingServletCDI tests + various simple CDI invocations.
    PingServletCDIBeanManagerViaJNDIPingServletCDIBeanManagerViaJNDI tests getting the BeanManager with JNDI.
    PingServletCDIBeanManagerViaCDICurrentIPingServletCDIBeanManagerViaCDICurrent tests getting the BeanManager with SPI.
    + + + PingServletWriter + + + + PingServletWriter extends PingServlet by using a PrintWriter for formatted output vs. the output stream used by + PingServlet. +
    + + + PingServlet2Include + + + * + + PingServlet2Include tests response inclusion. Servlet 1 includes the response of Servlet 2. +
    + + + PingServlet2Servlet + + + + PingServlet2Servlet tests request dispatching. Servlet 1, the controller, creates a new JavaBean object forwards the + request with the JavaBean added to Servlet 2. Servlet 2 obtains access to the JavaBean through the Servlet request object and provides + dynamic HTML output based on the JavaBean data. +
    + + PingJSP + + + PingJSP tests a direct call to JavaServer Page providing server-side dynamic HTML through JSP scripting. +
    + + PingJSPEL + + + PingJSPEL tests a direct call to JavaServer Page providing server-side dynamic HTML through JSP scripting and the usage + of the new JSP 2.0 Expression Language. +
    + + PingServlet2JSP + + + PingServlet2JSP tests a commonly used design pattern, where a request is issued to servlet providing server side + control processing. The servlet creates a JavaBean object with dynamically set attributes and forwards the bean to the JSP through a + RequestDispatcher The JSP obtains access to the JavaBean and provides formatted display with dynamic HTML output based on the JavaBean data. +
    + + PingServlet2PDF + + + PingServlet2PDF tests a call to a servlet which displays the contents of a PDF Document (~1 MB in file size). +
    + + PingServlet2DB + + + PingServlet2DB tests a call to a servlet which makes a JDBC connection to the database. +
    + + PingJSF + + + PingJSF tests a call to a JSF Facelet which performs a lookup of quotes. +
    PingCDIJSFPingCDIJSF tests a MangedBean called from a jsf page.
    + + PingHTTPSession1 + + + + PingHTTPSession1 - + SessionID + tests fundamental HTTP session function by creating a unique session ID for each individual user. The ID is stored in the users session and + is accessed and displayed on each user request. + +
    + + PingHTTPSession2 + + + + PingHTTPSession2 + session create/destroy + further extends the previous test by invalidating the HTTP Session on every 5th user access. This results in testing HTTPSession create and + destroy + +
    + + PingHTTPSession3 + + + + PingHTTPSession3 + large session object + tests the servers ability to manage and persist large HTTPSession data objects. The servlet creates a large custom java object. The class + contains multiple data fields and results in 2048 bytes of data. This large session object is retrieved and stored to the session on each + user request. + +
    + + PingJDBCRead + + * + + PingJDBCRead tests fundamental servlet to JDBC access to a database performing a single-row read using a prepared SQL + statment. +
    + + PingJDBCWrite + + * + + PingJDBCRead tests fundamental servlet to JDBC access to a database performing a single-row write using a prepared SQL + statment. +
    + + PingServlet2JNDI + + * + + PingServlet2JNDI tests the fundamental J2EE operation of a servlet allocating a JNDI context and performing a JNDI + lookup of a JDBC DataSource. +
    PingUpgradeServletPingUpgradeServlet tests a simple UpgradeHandler request. JMeter is needed for testing.
    PingWebSocketTextSyncPingWebSocketTextSync tests a simple synchronous WebSocket with text.
    PingWebSocketTextAsyncPingWebSocketTextAsync tests a simple asynchronous WebSocket with text.
    PingWebSocketBinaryPingWebSocketBinary tests a simple WebSocket with binary data.
    PingWebSocketJsonPingWebSocketJson tests a WebSocket with a JSON Decoder and Encoder.
    + + PingManagedThread + + + + PingManagedThread tests a ManagedThreadFactory inside an asynchronous servlet. +
    + + PingManagedExecutor + + + + PingManagedExecutor tests the ManagedExecutorService inside an asynchronous servlet. +
    + + PingJSONP + + + + PingJSONP tests generating and parsing JSON. +
    + + EJB 3 Container ping suite + +
    + + PingServlet2Session + + * + + PingServlet2Session tests key function of a servlet call to a remote stateless Session EJB. The Session EJB performs a + simple calculation and returns the result +
    + + PingServlet2SessionLocal + + * + + PingServlet2SessionLocal tests key function of a servlet call to a local stateless Session EJB. The Session EJB + performs a simple calculation and returns the result +
    + + PingServlet2Session2Entity + + * + + This tests the full servlet to Session EJB to Entity EJB path to retrieve a single row from the database. +
    + + PingServlet2Session2Entity2JSP + + * + + This tests the full servlet to Session EJB to Entity EJB path to retrieve a single row from the database and displays + the output in a JSP. +
    + + + PingServlet2Session2 +
    + EntityCollection +
    +
    + * +
    + This test extends the previous EJB Entity test by calling a Session EJB which uses a finder method on the Entity that + returns a collection of Entity objects. Each object is displayed by the servlet. +
    + + PingServlet2Session2CMROne2One + + * + + This test drives an Entity EJB to get another Entity EJB's data through an EJB 3.0 CMR One to One relationship. +
    + + PingServlet2Session2CMROne2Many + + * + + This test drives an Entity EJB to get another Entity EJB's data through an EJB 3.0 CMR One to Many relationship. +
    + + PingServlet2Session2JDBC + + * + + This tests the full servlet to Session EJB to JDBC path to retrieve a single row from the database. +
    + + + PingServlet2Session2 +
    + JDBCCollection +
    +
    + * +
    + This test extends the previous JDBC test by calling a Session EJB to JDBC path which returns multiple rows from the + database. +
    + + PingServlet2MDBQueue + + * + + + PingServlet2MDBQueue drives messages to a Queue based Message Driven EJB (MDB). Each request to the servlet posts a message to the Queue. The + MDB receives the message asynchronously and prints message delivery statistics on each 100th message. + + Note: + Not intended for performance testing. + + +
    + + PingServlet2MDBTopic + + * + + + PingServlet2MDBTopic drives messages to a Topic based Publish/Subscribe Message Driven EJB (MDB). Each request to the servlet posts a message + to the Topic. The TradeStreamMDB receives the message asynchronously and prints message delivery statistics on each 100th message. Other + subscribers to the Topic will also receive the messages. + + Note: + Not intended for performance testing. + + +
    + + PingServlet2TwoPhase + + * + + PingServlet2TwoPhase drives a Session EJB which invokes an Entity EJB with findByPrimaryKey (DB Access) followed by + posting a message to an MDB through a JMS Queue (Message access). These operations are wrapped in a global 2-phase transaction and commit. +
    +
    +
    +
    + +
    + \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/welcome.jsp b/src/test/resources/test-applications/daytrader8/src/main/webapp/welcome.jsp new file mode 100644 index 00000000..f2fc601c --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/welcome.jsp @@ -0,0 +1,133 @@ + + + + +DayTrader Login + + + + + <%@ page session="false"%> + + + + + + + +
    DayTrader + LoginDayTrader
    + + + + + + + + +
    + <% + String results; + results = (String) request.getAttribute("results"); + if (results != null) + out.print(results); + %> +
    +
    + + + + + + + + + + + + + +
    Log in +
    Username +              +     Password       +               +               +    
    +
    +       +     +
    +
    + + + + + + + + + + + + + + + + + + + + +
    +
    +
    First + time user?  Please Register
    +
    + Register With DayTrader +
    +
    +
    +
    + + + + + + + + + + + + + +
    +
    +
    DayTrader + LoginDayTrader
    + + diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/welcome.xhtml b/src/test/resources/test-applications/daytrader8/src/main/webapp/welcome.xhtml new file mode 100644 index 00000000..e0577f55 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/welcome.xhtml @@ -0,0 +1,93 @@ + + + + + DayTrader Login + + + + +
    + +
    + +
    + + + + + + + +
    + +
    +

    Log in to DayTrader

    +
    Username +
    + + + + +
    +
    Password +
    + + + +
    +
    + + +
    +
    Don't have an account?
    + Register With DayTrader +
    +
    +
    +
    + +
    + \ No newline at end of file diff --git a/src/test/resources/test-applications/daytrader8/src/main/webapp/welcomeImg.jsp b/src/test/resources/test-applications/daytrader8/src/main/webapp/welcomeImg.jsp new file mode 100644 index 00000000..252a22e6 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/src/main/webapp/welcomeImg.jsp @@ -0,0 +1,132 @@ + + + + +DayTrader Login + + + + + <%@ page session="false"%> + + + + + + + +
    DayTrader LoginDayTrader
    + + + + + + + + + +
    + <% + String results; + results = (String) request.getAttribute("results"); + if (results != null) + out.print(results); + %> +
    +
    + + + + + + + + + + + + + +
    Log in +
    Username +              +     Password       +               +               +    
    +
    +       +     +
    +
    + + + + + + + + + + + + + + + + + + + + +
    +
    +
    First + time user?  Please Register
    +
    + Register With DayTrader +
    +
    +
    +
    + + + + + + + + + + +

    DayTrader + LoginDayTrader
    + + diff --git a/src/test/resources/test-applications/daytrader8/zos_db2_files/RUNSTAT.JCL b/src/test/resources/test-applications/daytrader8/zos_db2_files/RUNSTAT.JCL new file mode 100644 index 00000000..07579d73 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/zos_db2_files/RUNSTAT.JCL @@ -0,0 +1,23 @@ +//TDRUNSTA JOB MSGCLASS=H,MSGLEVEL=(1,1),REGION=0M,NOTIFY=&SYSUID. +//* ----------------------- // +//* DB2V11.JUN2915.SDSNEXIT +//* RUNSTATS +//* +//STEP1 EXEC PGM=DSNUTILB,PARM='DB94,STAA1',DYNAMNBR=25 +//STEPLIB DD DISP=SHR,DSN=DB2V11.JUN2915.SDSNEXIT +//SYSUT1 DD UNIT=SYSDA,SPACE=(CYL,(600,50)) +//SORTWK01 DD UNIT=SYSDA,SPACE=(CYL,(600,50)) +//SORTWK02 DD UNIT=SYSDA,SPACE=(CYL,(600,50)) +//SORTWK03 DD UNIT=SYSDA,SPACE=(CYL,(600,50)) +//SORTWK04 DD UNIT=SYSDA,SPACE=(CYL,(600,50)) +//SYSREC DD UNIT=SYSDA,SPACE=(CYL,(599,49)) +//SYSPRINT DD SYSOUT=* +//UTPRINT DD SYSOUT=* +//SYSUDUMP DD SYSOUT=* +//SYSIN DD * + RUNSTATS TABLESPACE TRADE.TRADETS1 INDEX ALL TABLE ALL REPORT YES + RUNSTATS TABLESPACE TRADE.TRADETS2 INDEX ALL TABLE ALL REPORT YES + RUNSTATS TABLESPACE TRADE.TRADETS3 INDEX ALL TABLE ALL REPORT YES + RUNSTATS TABLESPACE TRADE.TRADETS4 INDEX ALL TABLE ALL REPORT YES + RUNSTATS TABLESPACE TRADE.TRADETS5 INDEX ALL TABLE ALL REPORT YES + RUNSTATS TABLESPACE TRADE.TRADETS6 INDEX ALL TABLE ALL REPORT YES diff --git a/src/test/resources/test-applications/daytrader8/zos_db2_files/dbbind.jcl b/src/test/resources/test-applications/daytrader8/zos_db2_files/dbbind.jcl new file mode 100644 index 00000000..261cabed --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/zos_db2_files/dbbind.jcl @@ -0,0 +1,42 @@ +//DBINDS20 JOB MSGCLASS=H,NOTIFY=&SYSUID.,REGION=0M +//*********************************************************************/00010000 +//* JOB NAME = DSNTIJSG */00020000 +//* */00030000 +//* DESCRIPTIVE NAME = INSTALLATION JOB STREAM */00040000 +//* */00050000 +//*********************************************************************/00290000 +//JOBLIB DD DISP=SHR, 00300000 +// DSN=DB211.D121916.SDSNLOAD 00310000 +//* 00430000 +//DSNTIRU EXEC PGM=IKJEFT01,DYNAMNBR=20 00440000 +//SYSTSPRT DD SYSOUT=* 00450000 +//SYSPRINT DD SYSOUT=* 00460000 +//SYSUDUMP DD SYSOUT=* 00470000 +//SYSTSIN DD * 00480000 + DSN SYSTEM(DB90) 00490000 + REBIND PACKAGE(NULLID.SYSLH100) ISOLATION(CS) CURRENTDATA (NO) 00728260 + REBIND PACKAGE(NULLID.SYSLH200) CURRENTDATA(NO) ISOLATION(CS) 00728260 + REBIND PACKAGE(NULLID.SYSLH300) CURRENTDATA(NO) ISOLATION(CS) 00728260 + REBIND PACKAGE(NULLID.SYSLH400) CURRENTDATA(NO) ISOLATION(CS) 00728260 + REBIND PACKAGE(NULLID.SYSLN100) CURRENTDATA(NO) ISOLATION(CS) 00728260 + REBIND PACKAGE(NULLID.SYSLN200) CURRENTDATA(NO) ISOLATION(CS) 00728260 + REBIND PACKAGE(NULLID.SYSLN300) CURRENTDATA(NO) ISOLATION(CS) 00728260 + REBIND PACKAGE(NULLID.SYSLN400) CURRENTDATA(NO) ISOLATION(CS) 00728260 + REBIND PACKAGE(NULLID.SYSLH101) CURRENTDATA(NO) ISOLATION(CS) 00728260 + REBIND PACKAGE(NULLID.SYSLH201) CURRENTDATA(NO) ISOLATION(CS) 00728260 + REBIND PACKAGE(NULLID.SYSLH301) CURRENTDATA(NO) ISOLATION(CS) 00728260 + REBIND PACKAGE(NULLID.SYSLH401) CURRENTDATA(NO) ISOLATION(CS) 00728260 + REBIND PACKAGE(NULLID.SYSLN101) CURRENTDATA(NO) ISOLATION(CS) 00728260 + REBIND PACKAGE(NULLID.SYSLN201) CURRENTDATA(NO) ISOLATION(CS) 00728260 + REBIND PACKAGE(NULLID.SYSLN301) CURRENTDATA(NO) ISOLATION(CS) 00728260 + REBIND PACKAGE(NULLID.SYSLN401) CURRENTDATA(NO) ISOLATION(CS) 00728260 + REBIND PACKAGE(NULLID.SYSLH102) CURRENTDATA(NO) ISOLATION(CS) 00728260 + REBIND PACKAGE(NULLID.SYSLH202) CURRENTDATA(NO) ISOLATION(CS) 00728260 + REBIND PACKAGE(NULLID.SYSLH302) CURRENTDATA(NO) ISOLATION(CS) 00728260 + REBIND PACKAGE(NULLID.SYSLH402) CURRENTDATA(NO) ISOLATION(CS) 00728260 + REBIND PACKAGE(NULLID.SYSLN102) CURRENTDATA(NO) ISOLATION(CS) 00728260 + REBIND PACKAGE(NULLID.SYSLN202) CURRENTDATA(NO) ISOLATION(CS) 00728260 + REBIND PACKAGE(NULLID.SYSLN302) CURRENTDATA(NO) ISOLATION(CS) 00728260 + REBIND PACKAGE(NULLID.SYSLN402) CURRENTDATA(NO) ISOLATION(CS) 00728260 + REBIND PACKAGE(NULLID.SYSSTAT) CURRENTDATA(NO) ISOLATION(CS) 00728260 + END 00728840 diff --git a/src/test/resources/test-applications/daytrader8/zos_db2_files/dbtable.jcl b/src/test/resources/test-applications/daytrader8/zos_db2_files/dbtable.jcl new file mode 100644 index 00000000..5398fa74 --- /dev/null +++ b/src/test/resources/test-applications/daytrader8/zos_db2_files/dbtable.jcl @@ -0,0 +1,255 @@ +//TDBIGS10 JOB MSGCLASS=H,MSGLEVEL=(1,1),NOTIFY=&SYSUID +//STEP01 EXEC PGM=IKJEFT01,DYNAMNBR=20 +//STEPLIB DD DSN=DB2V11.JUN2915.SDSNLOAD,DISP=SHR +//SYSTSPRT DD SYSOUT=* +//SYSUDUMP DD SYSOUT=* +//SYSPRINT DD SYSOUT=* +//SYSTSIN DD * + DSN SYSTEM(DB90) + RUN PROGRAM(DSNTIAD) PLAN(DSNTIA11) - + LIB('DB90.RUNLIB.LOAD') + END +//SYSIN DD * + + SET CURRENT SQLID='WSADMIN'; + DROP TABLESPACE TRADEDB.TRADETS1; + DROP TABLESPACE TRADEDB.TRADETS2; + DROP TABLESPACE TRADEDB.TRADETS3; + DROP TABLESPACE TRADEDB.TRADETS4; + DROP TABLESPACE TRADEDB.TRADETS5; + DROP TABLESPACE TRADEDB.TRADETS6; + DROP DATABASE TRADEDB; + DROP STOGROUP TRADESG; + COMMIT; +//* LIB('DB2V11.JUN2915.RUNLIB.LOAD') +//STEP02 EXEC PGM=IKJEFT01,DYNAMNBR=20 +//STEPLIB DD DSN=DB2V11.JUN2915.SDSNLOAD,DISP=SHR +//SYSTSPRT DD SYSOUT=* +//SYSUDUMP DD SYSOUT=* +//SYSPRINT DD SYSOUT=* +//SYSTSIN DD * + DSN SYSTEM(DB90) + RUN PROGRAM(DSNTIAD) PLAN(DSNTIA11) - + LIB('DB90.RUNLIB.LOAD') + END +//SYSIN DD * + + SET CURRENT SQLID='WSADMIN'; + + CREATE STOGROUP TRADESG VOLUMES(WSPRF4) VCAT TRADESP6; + COMMIT; + + CREATE DATABASE TRADEDB + STOGROUP TRADESG + BUFFERPOOL BP2; + + COMMIT WORK; + + CREATE TABLESPACE TRADETS1 IN TRADEDB + USING STOGROUP TRADESG + PRIQTY 15000 + SECQTY 5000 + ERASE NO + CLOSE NO + LOCKSIZE ROW + BUFFERPOOL BP4; + + CREATE TABLESPACE TRADETS2 IN TRADEDB + USING STOGROUP TRADESG + PRIQTY 15000 + SECQTY 5000 + ERASE NO + CLOSE NO + LOCKSIZE ROW + BUFFERPOOL BP5; + + CREATE TABLESPACE TRADETS3 IN TRADEDB + USING STOGROUP TRADESG + PRIQTY 15000 + SECQTY 5000 + ERASE NO + CLOSE NO + LOCKSIZE ROW + BUFFERPOOL BP6; + + CREATE TABLESPACE TRADETS4 IN TRADEDB + USING STOGROUP TRADESG + PRIQTY 15000 + SECQTY 5000 + ERASE NO + CLOSE NO + LOCKSIZE ROW + BUFFERPOOL BP7; + + CREATE TABLESPACE TRADETS5 IN TRADEDB + USING STOGROUP TRADESG + PRIQTY 128 + SECQTY 128 + ERASE NO + CLOSE NO + LOCKSIZE ROW + BUFFERPOOL BP3; + + CREATE TABLESPACE TRADETS6 IN TRADEDB + USING STOGROUP TRADESG + PRIQTY 5000 + SECQTY 1000 + ERASE NO + CLOSE NO + LOCKSIZE ROW + BUFFERPOOL BP4; + + CREATE TABLE HOLDINGEJB + (PURCHASEPRICE DECIMAL(14, 2), + HOLDINGID INTEGER NOT NULL, + QUANTITY DOUBLE NOT NULL, + PURCHASEDATE TIMESTAMP, + ACCOUNT_ACCOUNTID INTEGER, + QUOTE_SYMBOL VARCHAR(250), + CONSTRAINT PK_HOLDINGEJB PRIMARY KEY(HOLDINGID)) + IN TRADEDB.TRADETS1; + + CREATE UNIQUE INDEX HOLDINGEJBIDX + ON HOLDINGEJB(HOLDINGID) + USING STOGROUP TRADESG + PRIQTY 5000 + SECQTY 1000 + CLOSE NO + BUFFERPOOL BP8; + + CREATE INDEX HOLDINGACTIDX + ON HOLDINGEJB(ACCOUNT_ACCOUNTID) + USING STOGROUP TRADESG + PRIQTY 5000 + SECQTY 1000 + CLOSE NO + BUFFERPOOL BP9; + + CREATE TABLE ACCOUNTPROFILEEJB + (ADDRESS VARCHAR(250), + PASSWD VARCHAR(250), + USERID VARCHAR(250) NOT NULL, + EMAIL VARCHAR(250), + CREDITCARD VARCHAR(250), + FULLNAME VARCHAR(250), + CONSTRAINT PK_ACCOUNTPROFILE1 PRIMARY KEY(USERID)) + IN TRADEDB.TRADETS2; + + CREATE UNIQUE INDEX ACCTPROFILEEJBIDX + ON ACCOUNTPROFILEEJB(USERID) + USING STOGROUP TRADESG + PRIQTY 5000 + SECQTY 1000 + CLOSE NO + BUFFERPOOL BP10; + + CREATE TABLE QUOTEEJB + (LOW DECIMAL(14, 2), + OPEN1 DECIMAL(14, 2), + VOLUME DOUBLE NOT NULL, + PRICE DECIMAL(14, 2), + HIGH DECIMAL(14, 2), + COMPANYNAME VARCHAR(255), + SYMBOL VARCHAR(250) NOT NULL, + CHANGE1 DOUBLE NOT NULL, + CONSTRAINT PK_QUOTEEJB PRIMARY KEY(SYMBOL)) + IN TRADE.TRADETS6; + + CREATE UNIQUE INDEX QUOTEEJBIDX + ON QUOTEEJB(SYMBOL) + USING STOGROUP TRADESG + PRIQTY 2500 + SECQTY 1000 + CLOSE NO + BUFFERPOOL BP11; + + CREATE TABLE KEYGENEJB + (KEYVAL INTEGER NOT NULL, + KEYNAME VARCHAR(250) NOT NULL, + CONSTRAINT PK_KEYGENEJB PRIMARY KEY(KEYNAME)) + IN TRADEDB.TRADETS5; + + CREATE UNIQUE INDEX KEYGENEJBIDX + ON KEYGENEJB(KEYNAME) + USING STOGROUP TRADESG + PRIQTY 128 + SECQTY 64 + CLOSE NO + BUFFERPOOL BP12; + + CREATE TABLE ACCOUNTEJB + (CREATIONDATE TIMESTAMP, + OPENBALANCE DECIMAL(14, 2), + LOGOUTCOUNT INTEGER NOT NULL, + BALANCE DECIMAL(14, 2), + ACCOUNTID INTEGER NOT NULL, + LASTLOGIN TIMESTAMP, + LOGINCOUNT INTEGER NOT NULL, + PROFILE_USERID VARCHAR(250), + CONSTRAINT PK_ACCOUNTEJB PRIMARY KEY(ACCOUNTID)) + IN TRADEDB.TRADETS4; + + + CREATE UNIQUE INDEX ACCOUNTEJBIDX + ON ACCOUNTEJB(ACCOUNTID) + USING STOGROUP TRADESG + PRIQTY 5000 + SECQTY 1000 + CLOSE NO + BUFFERPOOL BP8; + + CREATE UNIQUE INDEX ACCOUNTPUSRIDX + ON ACCOUNTEJB(PROFILE_USERID) + USING STOGROUP TRADESG + PRIQTY 5000 + SECQTY 1000 + CLOSE NO + BUFFERPOOL BP9; + + CREATE TABLE ORDEREJB + (ORDERFEE DECIMAL(14, 2), + COMPLETIONDATE TIMESTAMP, + ORDERTYPE VARCHAR(250), + ORDERSTATUS VARCHAR(250), + PRICE DECIMAL(14, 2), + QUANTITY DOUBLE NOT NULL, + OPENDATE TIMESTAMP, + ORDERID INTEGER NOT NULL, + ACCOUNT_ACCOUNTID INTEGER, + QUOTE_SYMBOL VARCHAR(250), + HOLDING_HOLDINGID INTEGER, + CONSTRAINT PK_ORDEREJB PRIMARY KEY(ORDERID)) + IN TRADEDB.TRADETS3; + + CREATE UNIQUE INDEX ORDEREJBIDX + ON ORDEREJB(ORDERID) + USING STOGROUP TRADESG + PRIQTY 5000 + SECQTY 1000 + CLOSE NO + BUFFERPOOL BP10; + + CREATE INDEX ORDEREACTIDX + ON ORDEREJB(ACCOUNT_ACCOUNTID) + USING STOGROUP TRADESG + PRIQTY 5000 + SECQTY 1000 + CLOSE NO + BUFFERPOOL BP11; + + CREATE INDEX ORDEREHLDIDX + ON ORDEREJB(HOLDING_HOLDINGID) + USING STOGROUP TRADESG + PRIQTY 5000 + SECQTY 1000 + CLOSE NO + BUFFERPOOL BP12; + + CREATE INDEX CLOSED_ORDERS + ON ORDEREJB(ORDERSTATUS,ACCOUNT_ACCOUNTID) + USING STOGROUP TRADESG + PRIQTY 5000 + SECQTY 1000 + CLOSE NO + BUFFERPOOL BP8; + COMMIT;