diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index d655ae9..f9b1cd5 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -161,3 +161,145 @@ Tests are organized in `src/test/java/com/senzing/sdk/core/auto/`: - `checkstyle`: Enables checkstyle validation with suppressions - `spotbugs`: Enables static analysis including FindSecBugs - `java-17` / `java-18+`: Handle Javadoc tag compatibility across Java versions + +## Java Coding Standards + +**IMPORTANT — apply when generating or modifying Java code:** All Java code +(new and existing) in this repository must conform to the formatting rules in +`.java-coding-standards/docs/java-coding-standards.md`. Apply these rules +**from the start** — do not write code first and reformat afterward. When in +doubt about a specific case (parameter alignment, method continuation, +ternary tier, javadoc reflow), read the full standards document or search +the FAQ: +`mcp__sz-sdk-java-auto-faq__search_faqs(query="java formatting")`. + +### Quick reference + +- **80-character line limit** (enforced by checkstyle via `-Pcheckstyle`). + Lines beyond 80 chars must be wrapped. +- **Allman braces** for class/interface/enum/method/constructor definitions + (opening `{` on its own line, left-aligned with the declaration). +- **Same-line braces** for control flow: `if`/`else`/`for`/`while`/`do`/ + `try`/`catch`/`finally`/`switch`/`synchronized`, lambdas, array + initializers, static init blocks. +- **Multi-line conditions**: when an `if`/`catch`/etc. condition wraps to + multiple lines, the opening brace goes on its own line (Allman) to + visually separate condition from body. +- **Method parameters** (priority order): single line if it fits; otherwise + paren-aligned with types/names aligned in columns; otherwise next-line + double-indented. +- **`throws` clauses** go on their own line, single-indented. +- **Continuation indentation**: +4 per wrap level (cumulating to + 8 spaces of displacement for the typical double-wrap; see the + full standards doc for the per-level rule). +- **Operators on continuation lines**: break **before** `+`, `&&`, `||`, `?`, + `:`, `.` (the operator starts the continuation line). +- **Short-circuit `if`**: `if (cond) statement;` on one line is preferred + (Tier 1) when it fits; otherwise add braces. +- **Javadoc**: reflow prose and `@param`/`@return`/`@throws` to fill lines + near 80 chars; do not leave 1-3 orphan words on a line. +- **CSOFF/CSON**: only for deliberately aligned multi-line output + (column-formatted diagnostics, ASCII art, SQL DDL with aligned clauses) + — never a general escape hatch. + +### Verification + +Run checkstyle: `mvn -Pcheckstyle validate` (must report `BUILD SUCCESS` +before opening a PR). + +### Bulk formatting + +`.java-coding-standards/tooling/scripts/format_file.py` is the +single end-user entry point — a thin wrapper that invokes the +tree-sitter-based AST formatter at `format_java.py` in-process. +Accepts one or more file or directory targets (directories are +recursively scanned for `.java` files): + +```bash +# Format a single file in place. +python3 .java-coding-standards/tooling/scripts/format_file.py path/to/File.java + +# Format every .java file under src/main/java/ in place. +python3 .java-coding-standards/tooling/scripts/format_file.py src/main/java +``` + +The same script is wired to the VSCode `Format Java file to +Senzing standards` task, the `emeraldwalk.runonsave` extension +(format-on-save), and the Claude Code `PostToolUse` hook — so +every save runs the canonical formatter. Same input → same +output, regardless of caller. The `building/java-formatting- +standards` FAQ summarizes day-to-day usage. + +## FAQ MCP Server + +This project ships a local FAQ MCP server registered in `.mcp.json` under +the name `sz-sdk-java-auto-faq`. It serves both: + +- **Shared FAQs** from the standards-repo submodule + (`.java-coding-standards/docs/faqs/`) — coding standards, javadoc reflow + rules, system-stubs/ResourceLock test pattern, FAQ-authoring conventions. +- **Project-local FAQs** from `.claude/faqs//.md` — + project-specific architecture, conventions, build/release notes, + troubleshooting. + +The server merges both into one BM25-ranked search index. Tool surface: + +- `mcp__sz-sdk-java-auto-faq__get_faq_categories` +- `mcp__sz-sdk-java-auto-faq__search_faqs(query=...)` +- `mcp__sz-sdk-java-auto-faq__get_faq(title=...)` + +**Use it BEFORE making design assumptions or troubleshooting.** Specifically: + +- Before changing build, test, or release configuration (`pom.xml`, + surefire, checkstyle, jacoco, spotbugs, release process), call + `search_faqs` for relevant topics. +- Before modifying public APIs, search for any documented invariants or + rationale. +- When a build, test, or dependency issue surfaces, search the + `troubleshooting` category first. +- When unsure what is documented, call `get_faq_categories` to enumerate + what's available. + +**After resolving a non-obvious issue**, ask the user whether to capture +the solution as a new FAQ. Project-specific lessons go in +`.claude/faqs//.md`. Lessons about the standards +themselves go via PR to the standards repo. Restart the session so the +server re-indexes. + +FAQs are pulled on demand, so detail is cheap there. Keep CLAUDE.md lean +and push operational/troubleshooting depth into FAQ files. + +## Testing Configuration + +Tests use JUnit Jupiter with parallel execution enabled (configured in +`pom.xml` surefire plugin): + +- Classes run concurrently. +- Methods within a class run in same thread (default). +- Dynamic parallelism factor. + +### System Stubs, ExecutionMode, and ResourceLock + +Tests that **stub environment variables** or **capture stdout / stderr** +must follow the project's `system-stubs` + `@Execution(SAME_THREAD)` + +`@ResourceLock` pattern to avoid build-log noise and inter-class capture +races. Before writing such a test, search the FAQ: +`mcp__sz-sdk-java-auto-faq__search_faqs(query="system stubs")`. + +Headline rules: + +- Use `system-stubs-jupiter` **programmatically at the method level** + (`new EnvironmentVariables(...).execute(...)`, `new SystemOut().execute(...)`, + `new SystemErr().execute(...)`) — never the `@ExtendWith` annotation form. +- Tag the test (or the class) with `@Execution(ExecutionMode.SAME_THREAD)` + — `System.setOut` / `setErr` are JVM-wide, so concurrent redirects race. +- Add `@ResourceLock(Resources.SYSTEM_OUT)` and/or + `@ResourceLock(Resources.SYSTEM_ERR)` for cross-class mutual exclusion. + When both are present, **always declare `SYSTEM_OUT` first, `SYSTEM_ERR` + second** to avoid deadlock. +- If the production code starts a background thread in its constructor, + place the `new ...()` call **inside** the `stub.execute(...)` lambda so + the redirect is active before the thread starts. + +Full pattern, examples, and the JVM-warning suppression details are in the +shared `testing/system-stubs-and-output-capture` FAQ. diff --git a/.claude/commands/init-java.md b/.claude/commands/init-java.md new file mode 100644 index 0000000..0ecc6c8 --- /dev/null +++ b/.claude/commands/init-java.md @@ -0,0 +1,16 @@ +--- +description: Adopt or refresh the Senzing Java coding standards in this project. +--- + +Run the adoption playbook from the standards-repo submodule: + +@.java-coding-standards/adoption/adopt-standards-prompt.md + +This wires up checkstyle, the FAQ MCP server, the formatter, the bulk-format +scripts, the VSCode integration, the Claude Code hooks, and the CLAUDE.md +sections — all sourced from the submodule pin. Re-run any time to refresh +after a submodule bump or to onboard a fresh Java project. + +The command is deliberately distinct from Claude Code's built-in `/init`, +which continues to work unchanged for projects that just need a CLAUDE.md +without the standards machinery. diff --git a/.claude/faqs/architecture/sz-sdk-java-auto-overview.md b/.claude/faqs/architecture/sz-sdk-java-auto-overview.md new file mode 100644 index 0000000..10d4d2a --- /dev/null +++ b/.claude/faqs/architecture/sz-sdk-java-auto-overview.md @@ -0,0 +1,56 @@ +# sz-sdk-java-auto architecture overview + +`sz-sdk-java-auto` (Maven artifact `com.senzing:sz-sdk-auto`) extends the +Senzing Core SDK for Java (`com.senzing:sz-sdk`) with automatic handling +features for long-running, multi-threaded, server-side applications. +`SzAutoCoreEnvironment` is a drop-in replacement for `SzCoreEnvironment`. + +## The four enhancements + +1. **Automatic basic retry** — any Senzing Core SDK method that fails with an + `SzRetryableException` is retried up to a configurable maximum + (`maxBasicRetries`, default `DEFAULT_MAX_BASIC_RETRIES = 2`) with an + increasing delay between attempts. +2. **Automatic configuration refresh** — keeps the active configuration ID in + sync with the current default configuration ID. See the + `conventions/configuration-refresh-modes` FAQ for the DISABLED / REACTIVE / + PROACTIVE modes. +3. **Isolated thread pool** — confines all SDK operations to a fixed worker + pool so Senzing's thread-local native resources are reused across + operations, while preventing the excessive memory growth that comes from + running Senzing work on too many threads. Controlled by `concurrency` + (`null` = disabled / run on calling thread, `0` = + `Runtime.availableProcessors()`, `N` = fixed count). +4. **`ExecutorService`-like interface** — `submitTask(Callable)` / + `submitTask(Runnable)` run user code on the same pool as SDK operations to + avoid unnecessary context switching when several SDK calls happen in one + task. + +## Key classes + +- **`SzAutoCoreEnvironment`** (`src/main/java/com/senzing/sdk/core/auto/`) + — the main class; extends `SzCoreEnvironment`. Built via the fluent nested + `Builder` / `AbstractBuilder` (generic for extensibility). Only **one + active** environment may exist per JVM — call `destroy()` before creating + another. +- **`Reinitializer`** — background thread used only in PROACTIVE mode; + periodically reinitializes when `activeConfigId != defaultConfigId` and shuts + down gracefully on `destroy()`. +- **`RetryHandler`** (inner class) — a dynamic-proxy `InvocationHandler` that + wraps returned SDK interfaces, detects methods annotated with + `@SzConfigRetryable`, sets the thread-local `CONFIG_RETRY_FLAG`, and + recursively proxies SDK-interface return values. +- **`SzAutoEnvironment`** — interface so `SzAutoCoreEnvironment` functionality + can itself be proxied. + +## Design patterns + +- **Proxy pattern** for intercepting SDK method calls. +- **Thread-local flags** (`CONFIG_RETRY_FLAG`, `RETRIED_FLAG`, + `ENSURING_CONFIG`) to track retry/refresh state across the call stack and + prevent re-entrant recursion during config refresh. +- **`ReentrantReadWriteLock`** to coordinate normal operations against + refresh/destroy. +- **Builder pattern** with type-safe generics for extensibility. + +> Garage project: experimental, not production-supported. diff --git a/.claude/faqs/building/sz-sdk-java-auto-build-commands.md b/.claude/faqs/building/sz-sdk-java-auto-build-commands.md new file mode 100644 index 0000000..205cc8b --- /dev/null +++ b/.claude/faqs/building/sz-sdk-java-auto-build-commands.md @@ -0,0 +1,50 @@ +# sz-sdk-java-auto build & test commands + +Maven project (Java 17). Tests require a working Senzing installation with +native libraries. + +## Common commands + +```bash +mvn clean install # full clean build +mvn test # run all tests (needs native libs) +mvn test -Dtest=ClassName # single test class +mvn test -Dtest=ClassName#method # single test method +mvn -Pcheckstyle validate # checkstyle (must pass before a PR) +``` + +## Required environment for tests + +Tests load the Senzing native libraries through a generated wrapper script +(`target/java-wrapper/bin/java-wrapper.bat`, produced by +`GenerateTestJVMScript` during the `process-test-classes` phase and used as the +surefire JVM). Two environment variables must be set: + +- `SENZING_PATH` — path to the Senzing installation. +- `SENZING_DEV_LIBRARY_PATH` — path to the development libraries. + +The `sz-sdk-java` git submodule must be initialized +(`git submodule update --init --recursive`) — tests reuse test utilities from +it, and they are added as test sources via `build-helper-maven-plugin`. + +## Profiles + +- `jacoco` — coverage report (`mvn -Pjacoco test`, output in + `target/site/jacoco/`). +- `checkstyle` — checkstyle against the shared + `.java-coding-standards/checkstyle/senzing-checkstyle.xml`. +- `spotbugs` — SpotBugs + FindSecBugs static analysis + (`mvn -Pspotbugs validate`). +- `release` — enables GPG signing for Maven Central deployment + (`mvn clean install -Prelease`). + +## Coding standards + +Java formatting is governed by the `.java-coding-standards` submodule. Reformat +with: + +```bash +python3 .java-coding-standards/tooling/scripts/format_file.py src/main/java src/test/java +``` + +See the `building/java-formatting-standards` shared FAQ for day-to-day usage. diff --git a/.claude/faqs/conventions/configuration-refresh-modes.md b/.claude/faqs/conventions/configuration-refresh-modes.md new file mode 100644 index 0000000..f0b2b90 --- /dev/null +++ b/.claude/faqs/conventions/configuration-refresh-modes.md @@ -0,0 +1,38 @@ +# Configuration refresh modes (DISABLED / REACTIVE / PROACTIVE) + +Automatic configuration refresh keeps the +{@code activeConfigId} in sync with the current {@code defaultConfigId}. The +mode is selected by the `configRefreshPeriod` (`Duration`) passed to the +builder: + +| Mode | `configRefreshPeriod` | Behavior | +|------|-----------------------|----------| +| **DISABLED** | `null` (`DISABLED_CONFIG_REFRESH`) | No automatic refresh; `@SzConfigRetryable` methods are not retried after config changes. | +| **REACTIVE** | `Duration.ZERO` (`REACTIVE_CONFIG_REFRESH`) | On-demand: when a method annotated `@SzConfigRetryable` fails, the config is refreshed; if it actually changed, the method is retried automatically. | +| **PROACTIVE** | `Duration.ofSeconds(N)` where `N > 0` | A background `Reinitializer` thread refreshes every `N` seconds **and** still performs the reactive refresh on failures. | + +## How it works + +- REACTIVE/PROACTIVE compare the active vs. default configuration IDs and + reinitialize when they differ. +- Reinitialization is bounded by `MAX_REINITIALIZE_COUNT` (5) to avoid an + infinite loop under racing config changes; on exhaustion a `*** WARNING` + is printed and the caller is allowed to retry anyway. +- The thread-local `ENSURING_CONFIG` flag prevents infinite recursion when + the SDK calls made *during* a refresh (e.g. `getActiveConfigId()`, + `getDefaultConfigId()`, `reinitialize()`) route back through + `execute(...)`. + +## Important constraint + +You **cannot** specify both an explicit `configId` *and* enable configuration +refresh — the builder throws `IllegalStateException`. A fixed `configId` pins +the environment to one configuration, which is fundamentally incompatible with +keeping it in sync with the default. + +## Convenience constants + +- `DISABLED_CONFIG_REFRESH` = `null` `Duration` +- `REACTIVE_CONFIG_REFRESH` = `Duration.ofSeconds(0)` +- `DISABLED_CONCURRENCY` = `null` `Integer` +- `RECOMMENDED_CONCURRENCY` = `0` (use `Runtime.availableProcessors()`) diff --git a/.claude/faqs/testing/native-library-and-environment-setup.md b/.claude/faqs/testing/native-library-and-environment-setup.md new file mode 100644 index 0000000..b648676 --- /dev/null +++ b/.claude/faqs/testing/native-library-and-environment-setup.md @@ -0,0 +1,38 @@ +# Native-library test setup & single-active-environment constraint + +Tests in this project exercise the real Senzing Core SDK, which is backed by +native libraries loaded via JNI. There are two things to know before writing or +running tests. + +## 1. Native-library JVM wrapper + +The build does not run tests on a plain `java` — it generates a wrapper script +that sets up the native library paths first: + +- `GenerateTestJVMScript` (from the `sz-sdk-java` submodule, main scope as of + `sz-sdk` 4.3.0) runs in the `process-test-classes` phase and writes + `target/java-wrapper/bin/java-wrapper.bat`. +- `maven-surefire-plugin` is configured to use that wrapper as its ``. +- Generation reads `SENZING_PATH` and `SENZING_DEV_LIBRARY_PATH` (see the + `building/sz-sdk-java-auto-build-commands` FAQ). Without them, tests cannot + locate the native libraries. + +`AbstractAutoCoreTest` (extends `AbstractCoreTest` from the submodule) is the +base class for the project's tests. + +## 2. One active environment per JVM + +Only **one active** `SzCoreEnvironment` (including `SzAutoCoreEnvironment`) may +exist per JVM process. Constructing a second while one is active throws +`IllegalStateException`; you must `destroy()` the first one first. Tests must +tear down their environment (and let the background `Reinitializer` shut down) +before the next environment is created. + +Surefire runs **classes** concurrently (methods same-thread, dynamic factor) — +so cross-class isolation matters. Tests that stub environment variables or +capture `System.out` / `System.err` must follow the `system-stubs` + +`@Execution(SAME_THREAD)` + `@ResourceLock` pattern; see the shared +`testing/system-stubs-and-output-capture` FAQ. When a production object starts +a background thread in its constructor (e.g. PROACTIVE mode's `Reinitializer`), +construct it **inside** the `stub.execute(...)` lambda so the stream redirect is +active before the thread starts. diff --git a/.claude/settings.json b/.claude/settings.json index bcf43f6..6369b06 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -1,3 +1,36 @@ { - "includeCoAuthoredBy": false + "includeCoAuthoredBy": false, + "hooks": { + "PostToolUse": [ + { + "matcher": "Edit|Write|MultiEdit", + "hooks": [ + { + "type": "command", + "command": "bash -c 'jq -r \".tool_input.file_path\" | { read p; [[ \"$p\" == *.java ]] && python3 \"${CLAUDE_PROJECT_DIR}/.java-coding-standards/tooling/scripts/format_file.py\" \"$p\"; }'" + } + ] + } + ], + "Stop": [ + { + "hooks": [ + { + "type": "command", + "command": "cd \"${CLAUDE_PROJECT_DIR}\" && mvn -Pcheckstyle validate -q 2>&1 | grep -E '(ERROR|WARN)' || true" + } + ] + } + ], + "SessionStart": [ + { + "hooks": [ + { + "type": "command", + "command": "bash -c 'cd \"${CLAUDE_PROJECT_DIR}/.java-coding-standards\" 2>/dev/null || exit 0; head_sha=$(git rev-parse HEAD 2>/dev/null) || exit 0; tags_raw=$(git -c http.lowSpeedLimit=1000 -c http.lowSpeedTime=3 ls-remote --tags origin 2>/dev/null); [ -n \"$tags_raw\" ] || exit 0; latest=$(echo \"$tags_raw\" | awk -F/ \"{print \\$NF}\" | grep -v \"\\^{}$\" | sort -V | tail -1); [ -n \"$latest\" ] || exit 0; case \"$latest\" in *[!A-Za-z0-9._-]*) exit 0 ;; esac; latest_sha=$(echo \"$tags_raw\" | awk \"\\$2==\\\"refs/tags/${latest}^{}\\\" || \\$2==\\\"refs/tags/${latest}\\\" {print \\$1}\" | tail -1); [ \"$head_sha\" = \"$latest_sha\" ] && exit 0; current=$(echo \"$tags_raw\" | awk -v h=\"$head_sha\" \"\\$1==h {n=\\$2; sub(\\\"\\\\\\\\^{}\\\",\\\"\\\",n); sub(\\\"refs/tags/\\\",\\\"\\\",n); print n}\" | sort -V | tail -1); case \"$current\" in *[!A-Za-z0-9._-]*) exit 0 ;; esac; printf \"INSTRUCTION FOR ASSISTANT (from SessionStart hook): At the start of your first response, tell the user verbatim: \\\"Heads up: .java-coding-standards has a newer release available (%s); current pin is %s. Run /init-java to refresh.\\\"\\n\" \"$latest\" \"${current:-untagged}\"'" + } + ] + } + ] + } } diff --git a/.gitignore b/.gitignore index c775265..7d9ce69 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,9 @@ target/** # Visual Studio code .vscode/* !.vscode/cspell.json +!.vscode/settings.json +!.vscode/extensions.json +!.vscode/tasks.json *.code-workspace .history diff --git a/.gitmodules b/.gitmodules index a27b24f..9a265ff 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "sz-sdk-java"] path = sz-sdk-java url = https://github.com/senzing-garage/sz-sdk-java.git +[submodule ".java-coding-standards"] + path = .java-coding-standards + url = https://github.com/senzing-garage/java-coding-standards.git diff --git a/.java-coding-standards b/.java-coding-standards new file mode 160000 index 0000000..6cf4831 --- /dev/null +++ b/.java-coding-standards @@ -0,0 +1 @@ +Subproject commit 6cf4831333af7dd9415e24f7337cd75ba14e1db4 diff --git a/.mcp.json b/.mcp.json new file mode 100644 index 0000000..b8381ce --- /dev/null +++ b/.mcp.json @@ -0,0 +1,15 @@ +{ + "mcpServers": { + "sz-sdk-java-auto-faq": { + "command": "uv", + "args": [ + "run", + "--script", + ".java-coding-standards/mcp/faq_server.py", + "--server-name=sz-sdk-java-auto-faq", + "--faqs-dir=.claude/faqs", + "--shared-faqs-dir=.java-coding-standards/docs/faqs" + ] + } + } +} diff --git a/.vscode/cspell.json b/.vscode/cspell.json index 663f7d4..8885ce3 100644 --- a/.vscode/cspell.json +++ b/.vscode/cspell.json @@ -2,6 +2,7 @@ "version": "0.2", "language": "en", "words": [ + "Allman", "apidocs", "aquasecurity", "barrycaceres", @@ -10,6 +11,8 @@ "CODEOWNER", "CONFIGMGR", "cooldown", + "CSOFF", + "ctxt", "Djacoco", "Dorg", "Dsenzing", @@ -18,6 +21,8 @@ "Dtest", "DYLD", "elete", + "emeraldwalk", + "esac", "ftype", "hange", "ICLA", @@ -36,6 +41,7 @@ "reinit", "Reinitializer", "Retryable", + "runonsave", "Senzing", "senzingsdk", "spotbugs", diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..721f2ac --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,6 @@ +{ + "recommendations": [ + "redhat.java", + "emeraldwalk.runonsave" + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..71050a8 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,14 @@ +{ + "java.configuration.updateBuildConfiguration": "automatic", + "[java]": { + "editor.formatOnSave": false + }, + "emeraldwalk.runonsave": { + "commands": [ + { + "match": "\\.java$", + "cmd": "python3 \"${workspaceFolder}/.java-coding-standards/tooling/scripts/format_file.py\" \"${file}\"" + } + ] + } +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..60aa653 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,29 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Format Java file to Senzing standards", + "type": "shell", + "command": "python3", + "args": [ + "${workspaceFolder}/.java-coding-standards/tooling/scripts/format_file.py", + "${file}" + ], + "presentation": { + "reveal": "silent", + "panel": "shared", + "showReuseMessage": false + }, + "problemMatcher": [] + }, + { + "label": "Format and reload Java file (Senzing standards)", + "dependsOrder": "sequence", + "dependsOn": [ + "Format Java file to Senzing standards" + ], + "command": "${command:workbench.action.files.revert}", + "problemMatcher": [] + } + ] +} diff --git a/checkstyle-suppressions.xml b/checkstyle-suppressions.xml deleted file mode 100644 index 0fe50a2..0000000 --- a/checkstyle-suppressions.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/pom.xml b/pom.xml index e86eea3..3777895 100644 --- a/pom.xml +++ b/pom.xml @@ -48,6 +48,11 @@ 17 UTF-8 UTF-8 + + @@ -236,6 +241,7 @@ 3.5.5 ${project.build.directory}/java-wrapper/bin/java-wrapper.bat + @{argLine} -XX:+EnableDynamicAgentLoading -Xshare:off **/*Test.java **/*Tests.java @@ -366,11 +372,11 @@ maven-checkstyle-plugin 3.6.0 + ${project.basedir}/.java-coding-standards/checkstyle/senzing-checkstyle.xml UTF-8 true true false - checkstyle-suppressions.xml diff --git a/src/main/java/com/senzing/sdk/core/auto/Reinitializer.java b/src/main/java/com/senzing/sdk/core/auto/Reinitializer.java index 6536e7c..0832029 100644 --- a/src/main/java/com/senzing/sdk/core/auto/Reinitializer.java +++ b/src/main/java/com/senzing/sdk/core/auto/Reinitializer.java @@ -3,14 +3,14 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.time.Duration; - import com.senzing.sdk.SzException; /** - * Background thread to refresh the configuration on the + * Background thread to refresh the configuration on the * {@link SzAutoCoreEnvironment}. */ -class Reinitializer extends Thread { +class Reinitializer extends Thread +{ /** * Constant for converting between nanoseconds and milliseconds. */ @@ -31,7 +31,7 @@ class Reinitializer extends Thread { * The {@link SzAutoCoreEnvironment} to monitor and reinitialize. */ private SzAutoCoreEnvironment env; - + /** * Flag indicating if the thread should complete or continue monitoring. */ @@ -42,18 +42,18 @@ class Reinitializer extends Thread { * * @param env The {@link SzAutoCoreEnvironment} to use. */ - Reinitializer(SzAutoCoreEnvironment env) { - this.env = env; - this.complete = false; + Reinitializer(SzAutoCoreEnvironment env) + { + this.env = env; + this.complete = false; } /** * Signals that this thread should complete execution. */ - synchronized void complete() { - if (this.complete) { - return; - } + synchronized void complete() + { + if (this.complete) return; this.complete = true; this.notifyAll(); } @@ -61,19 +61,21 @@ synchronized void complete() { /** * Checks if this thread has received the completion signal. * - * @return true if the completion signal has been received, + * @return true if the completion signal has been received, * otherwise false. */ - synchronized boolean isComplete() { + synchronized boolean isComplete() + { return this.complete; } /** * The run method implemented to periodically check if the active - * configuration ID differs from the default configuration ID - * and if so, reinitializes. + * configuration ID differs from the default configuration ID and if so, + * reinitializes. */ - public void run() { + public void run() + { try { int errorCount = 0; // loop until completed @@ -89,23 +91,24 @@ public void run() { // get the refresh period Duration duration = this.env.getConfigRefreshPeriod(); - // check if zero or null (we should not really get here since + // check if zero or null (we should not really get here since // this thread should not be started if the delay is zero) - if (duration == null || duration.isZero() || this.env.isDestroyed()) { + if (duration + == null || duration.isZero() || this.env.isDestroyed()) { this.complete(); continue; } // convert to milliseconds - long delay = duration.getSeconds() * ONE_THOUSAND - + (duration.getNano() / ONE_MILLION); + long delay = duration.getSeconds() + * ONE_THOUSAND + (duration.getNano() / ONE_MILLION); try { synchronized (this) { // sleep for the delay period this.wait(delay); } - + // check if destroyed if (this.env.isDestroyed()) { this.complete(); @@ -114,7 +117,6 @@ public void run() { // ensure the config is current this.env.ensureConfigCurrent(); - } catch (InterruptedException | SzException e) { errorCount++; continue; @@ -123,13 +125,12 @@ public void run() { // reset the error count if we successfully reach this point errorCount = 0; } - } catch (Exception e) { System.err.println( - "Giving up on monitoring active configuration due to exception:"); + "Giving up on monitoring active configuration due to " + + "exception:"); System.err.println(e.getMessage()); System.err.println(formatStackTrace(e.getStackTrace())); - } finally { this.complete(); } @@ -138,17 +139,17 @@ public void run() { /** * Formats an array of {@link StackTraceElement} instances using {@link * #formatStackTrace(StackTraceElement)} with a single element per line. - * - * @param stackTrace The array of {@link StackTraceElement} instances to format. - * - * @return The formatted {@link String} describing the array of {@link - * StackTraceElement} instances or null if the specified - * array is null. + * + * @param stackTrace The array of {@link StackTraceElement} instances to + * format. + * + * @return The formatted {@link String} describing the array of {@link + * StackTraceElement} instances or null if the + * specified array is null. */ - static String formatStackTrace(StackTraceElement[] stackTrace) { - if (stackTrace == null) { - return null; - } + static String formatStackTrace(StackTraceElement[] stackTrace) + { + if (stackTrace == null) return null; StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); for (StackTraceElement elem : stackTrace) { @@ -158,21 +159,23 @@ static String formatStackTrace(StackTraceElement[] stackTrace) { } /** - * Formats a single {@link StackTraceElement} in the same format as they would appear - * in an exception stack trace. - * + * Formats a single {@link StackTraceElement} in the same format as they + * would appear in an exception stack trace. + * * @param elem The {@link StackTraceElement} to format. - * - * @return The formatted {@link String} describing the {@link StackTraceElement}. + * + * @return The formatted {@link String} describing the {@link + * StackTraceElement}. */ - static String formatStackTrace(StackTraceElement elem) { + static String formatStackTrace(StackTraceElement elem) + { StringBuilder sb = new StringBuilder(); sb.append(" at "); - + // handle a null element if (elem == null) { - sb.append("[unknown: null]"); - return sb.toString(); + sb.append("[unknown: null]"); + return sb.toString(); } String moduleName = elem.getModuleName(); @@ -196,5 +199,4 @@ static String formatStackTrace(StackTraceElement elem) { return sb.toString(); } - } diff --git a/src/main/java/com/senzing/sdk/core/auto/SzAutoCoreEnvironment.java b/src/main/java/com/senzing/sdk/core/auto/SzAutoCoreEnvironment.java index 42ec108..eb6b0f3 100644 --- a/src/main/java/com/senzing/sdk/core/auto/SzAutoCoreEnvironment.java +++ b/src/main/java/com/senzing/sdk/core/auto/SzAutoCoreEnvironment.java @@ -12,7 +12,6 @@ import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; - import com.senzing.sdk.SzConfig; import com.senzing.sdk.SzConfigManager; import com.senzing.sdk.SzConfigRetryable; @@ -23,38 +22,35 @@ import com.senzing.sdk.SzRetryableException; import com.senzing.sdk.SzEnvironmentDestroyedException; import com.senzing.sdk.core.SzCoreEnvironment; - import static java.util.concurrent.CompletableFuture.completedFuture; import static java.util.concurrent.CompletableFuture.failedFuture; - import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** - * Extends {@link SzCoreEnvironment} to provide a more robust - * implementation for instances used in long-running processes - * typically in server-side applications. The features added - * by this implementation are: + * Extends {@link SzCoreEnvironment} to provide a more robust implementation for + * instances used in long-running processes typically in server-side + * applications. The features added by this implementation are: *
    *
  • * Optional basic retry logic to retry any Senzing - * Core SDK method that fails with an {@link + * Core SDK method that fails with an {@link * SzRetryableException}. The method may be retried one * or more times with an increasing delay between retry * attempts. *
  • *
  • * Optional automatic configuration refresh so that the - * active configuration ID remains in sync with the + * active configuration ID remains in sync with the * current default configuration ID. *
  • *
  • * When automatic configuration refresh is enabled, this * implementation automatically refreshes the configuration * when a Senzing Core SDK method annotated as - * {@link SzConfigRetryable} fails with an {@link + * {@link SzConfigRetryable} fails with an {@link * SzException}, subsequently retrying that method if in * fact the the active configuration was changed. *
  • @@ -66,21 +62,22 @@ * Senzing operations in too many threads. * *
  • - * A limited {@link ExecutorService}-like interface to + * A limited {@link ExecutorService}-like interface to * enable executing multiple Senzing Core SDK operations * within the execution thread pool while preventing * excessive context switching. *
  • *
*/ -public class SzAutoCoreEnvironment extends SzCoreEnvironment - implements SzAutoEnvironment +public class SzAutoCoreEnvironment + extends SzCoreEnvironment implements SzAutoEnvironment { /** * The thread-local retry flag. */ static final ThreadLocal CONFIG_RETRY_FLAG = new ThreadLocal<>() { - protected Boolean initialValue() { + protected Boolean initialValue() + { return Boolean.FALSE; } }; @@ -88,36 +85,40 @@ protected Boolean initialValue() { /** * The thread-local flag indicating if a method was retried. */ - private static final ThreadLocal RETRIED_FLAG = new ThreadLocal<>() { - protected Boolean initialValue() { - return Boolean.FALSE; - } - }; + private static final ThreadLocal RETRIED_FLAG + = new ThreadLocal<>() { + protected Boolean initialValue() + { + return Boolean.FALSE; + } + }; /** - * Thread-local flag to indicate that the current thread is already - * inside {@link #ensureConfigCurrent()}. This prevents infinite - * recursion when SDK methods called during config refresh (e.g. + * Thread-local flag to indicate that the current thread is already inside + * {@link #ensureConfigCurrent()}. This prevents infinite recursion when SDK + * methods called during config refresh (e.g. * {@code getActiveConfigId()}, {@code getDefaultConfigId()}, * {@code reinitialize()}) route back through {@link #execute(Callable)} * and would otherwise re-enter config-retry logic. */ - private static final ThreadLocal ENSURING_CONFIG = new ThreadLocal<>() { - protected Boolean initialValue() { - return Boolean.FALSE; - } - }; + private static final ThreadLocal ENSURING_CONFIG + = new ThreadLocal<>() { + protected Boolean initialValue() + { + return Boolean.FALSE; + } + }; /** - * The number of milliseconds to delay (if not notified) until checking - * if we are destroyed. + * The number of milliseconds to delay (if not notified) until checking if + * we are destroyed. */ private static final long DESTROY_DELAY = 5000L; /** - * The default number of times this class will perform a basic - * retry when an {@link SzRetryableException} occurs. The value - * of this constant is {@value}. + * The default number of times this class will perform a basic retry when an + * {@link SzRetryableException} occurs. The value of this constant is + * {@value}. */ public static final int DEFAULT_MAX_BASIC_RETRIES = 2; @@ -125,15 +126,15 @@ protected Boolean initialValue() { * The classes to be proxied using the {@link RetryHandler}. */ private static final Set> PROXY_CLASSES = Set.of(SzEngine.class, - SzProduct.class, - SzConfigManager.class, - SzDiagnostic.class, - SzConfig.class); + SzProduct.class, + SzConfigManager.class, + SzDiagnostic.class, + SzConfig.class); /** - * The maximum number of time to try to reinitialize with the - * latest default configuration ID before giving up. This ensures - * we never get an infinite loop in the case of race conditions. + * The maximum number of time to try to reinitialize with the latest default + * configuration ID before giving up. This ensures we never get an infinite + * loop in the case of race conditions. */ static final int MAX_REINITIALIZE_COUNT = 5; @@ -150,75 +151,73 @@ protected Boolean initialValue() { private static final int SHUTDOWN_WAIT_COUNT = 3; /** - * A null {@link Duration} reference that can be - * used with {@link Builder#configRefreshPeriod(Duration)} to - * disable configuration refresh and automatic retry of failed - * methods that are annotated with {@link SzConfigRetryable}. + * A null {@link Duration} reference that can be used with + * {@link Builder#configRefreshPeriod(Duration)} to disable configuration + * refresh and automatic retry of failed methods that are annotated with + * {@link SzConfigRetryable}. */ public static final Duration DISABLED_CONFIG_REFRESH = null; /** - * A zero (0) {@link Duration} instance that can be used - * with {@link Builder#configRefreshPeriod(Duration)} to - * enable Reactive configuration refresh so that - * configuration refresh and automatic retry are performed - * on demand when a method annotated with {@link + * A zero (0) {@link Duration} instance that can be used with {@link + * Builder#configRefreshPeriod(Duration)} to enable Reactive + * configuration refresh so that configuration refresh and automatic retry + * are performed on demand when a method annotated with {@link * SzConfigRetryable} fails with an {@link SzException}. */ public static final Duration REACTIVE_CONFIG_REFRESH = Duration.ofSeconds(0); - + /** - * A null {@link Integer} reference that can be - * used with {@link Builder#concurrency(Integer)} to disable - * the isolated concurrency thread pool and enable execution - * in the calling thread. + * A null {@link Integer} reference that can be used with + * {@link Builder#concurrency(Integer)} to disable the isolated concurrency + * thread pool and enable execution in the calling thread. */ public static final Integer DISABLED_CONCURRENCY = null; /** * A zero (0) {@link Integer} instance that can be used with * {@link Builder#concurrency(Integer)} to indicate that the - * concurrency should be set to {@link - * Runtime#availableProcessors()}. + * concurrency should be set to {@link Runtime#availableProcessors()}. */ public static final Integer RECOMMENDED_CONCURRENCY = 0; /** * Enumerates the various modes for configuration refresh. - * + * *

- * Configuration refresh is the process by which the + * Configuration refresh is the process by which the * {@linkplain com.senzing.sdk.SzEnvironment#getActiveConfigId() - * active configuration ID} is compared to the current + * active configuration ID} is compared to the current * {@linkplain com.senzing.sdk.SzConfigManager#getDefaultConfigId() - * default configuration ID} and if they are out of sync, the - * {@link SzAutoCoreEnvironment} is {@linkplain - * com.senzing.sdk.SzEnvironment#reinitialize(long) reinitialized} - * with the current default configuration ID. + * default configuration ID} and if they are out of sync, the + * {@link SzAutoCoreEnvironment} is {@linkplain + * com.senzing.sdk.SzEnvironment#reinitialize(long) reinitialized} with the + * current default configuration ID. *

*/ - public enum RefreshMode { + public enum RefreshMode + { /** - * The configuration will never be automatically refreshed. - * Methods annotated with {@link SzConfigRetryable} will + * The configuration will never be automatically refreshed. Methods + * annotated with {@link SzConfigRetryable} will * not be retried upon an exception. */ DISABLED, /** - * The configuration will be refreshed on-demand in response - * to an exception being thrown by a method annotated with + * The configuration will be refreshed on-demand in response to an + * exception being thrown by a method annotated with * {@link SzConfigRetryable}. When this occurs, the method will * be retried to see if it still fails after refresh. */ REACTIVE, /** - * The configuration will be refreshed in the background - * periodically using a specified {@link Duration} as the - * refresh period. This mode ALSO performs the - * on-demand refresh as with Reactive mode. + * The configuration will be refreshed in the background periodically + * using a specified {@link Duration} as the refresh period. This mode + * ALSO performs the on-demand refresh as with Reactive + * mode. */ PROACTIVE; } @@ -226,59 +225,59 @@ public enum RefreshMode { /** * Provides an interface for initializing an instance of * {@link SzAutoCoreEnvironment}. - * + * *

- * This interface is not needed to use {@link SzAutoCoreEnvironment}. - * It is only needed if you are extending {@link SzAutoCoreEnvironment}. + * This interface is not needed to use {@link SzAutoCoreEnvironment}. It is + * only needed if you are extending {@link SzAutoCoreEnvironment}. *

- * + * *

- * This is provided for derived classes of {@link SzAutoCoreEnvironment} - * to initialize their super class and is typically implemented by - * extending {@link AbstractBuilder} in creating a derived - * builder implementation. + * This is provided for derived classes of {@link SzAutoCoreEnvironment} to + * initialize their super class and is typically implemented by extending + * {@link AbstractBuilder} in creating a derived builder implementation. *

*/ - public interface Initializer extends SzCoreEnvironment.Initializer { + public interface Initializer extends SzCoreEnvironment.Initializer + { /** * Gets the configuration refresh period for this instance. - * + * *

- * Configuration refresh is the process by which the + * Configuration refresh is the process by which the * {@linkplain com.senzing.sdk.SzEnvironment#getActiveConfigId() - * active configuration ID} is compared to the current + * active configuration ID} is compared to the current * {@linkplain com.senzing.sdk.SzConfigManager#getDefaultConfigId() - * default configuration ID} and if they are out of sync, the - * {@link SzAutoCoreEnvironment} is {@linkplain - * com.senzing.sdk.SzEnvironment#reinitialize(long) reinitialized} - * with the current default configuration ID. + * default configuration ID} and if they are out of sync, the + * {@link SzAutoCoreEnvironment} is {@linkplain + * com.senzing.sdk.SzEnvironment#reinitialize(long) reinitialized} with + * the current default configuration ID. *

- * + * *

* Configuration refresh can be configured in one of three modes * enumerated by {@link RefreshMode}. *

- * + * *

* NOTE: Configuration refresh cannot be in any mode - * other than {@link RefreshMode#DISABLED} if the {@linkplain - * #getConfigId() configuration ID} is a non-null value. An - * exception will be thrown if attempting to construct an {@link - * SzAutoCoreEnvironment} with an explicit configuration ID - * with configuration refresh enabled. + * other than {@link RefreshMode#DISABLED} if the {@linkplain + * #getConfigId() configuration ID} is a non-null value. An exception + * will be thrown if attempting to construct an {@link + * SzAutoCoreEnvironment} with an explicit configuration ID with + * configuration refresh enabled. *

- * + * *

- * The possible values for this setting with their associated - * mode are as follows: + * The possible values for this setting with their associated mode are + * as follows: *

    *
  • - * A null value implies that configuration + * A null value implies that configuration * refresh is {@linkplain RefreshMode#DISABLED disabled} * (see {@link #DISABLED_CONFIG_REFRESH}). *
  • *
  • - * A zero (0) {@link Duration} implies that configuration + * A zero (0) {@link Duration} implies that configuration * refresh will be {@linkplain RefreshMode#REACTIVE reactive} * (see {@link #REACTIVE_CONFIG_REFRESH}). *
  • @@ -288,23 +287,23 @@ public interface Initializer extends SzCoreEnvironment.Initializer { * with the {@link Duration} value used as the refresh period. * *
- * + * * @return A positive {@link Duration} to enable {@linkplain - * RefreshMode#PROACTIVE proactive} configuration refresh, - * a zero (0) {@link Duration} to enable {@linkplain - * RefreshMode#REACTIVE reactive} configuration refresh or + * RefreshMode#PROACTIVE proactive} configuration refresh, a + * zero (0) {@link Duration} to enable {@linkplain + * RefreshMode#REACTIVE reactive} configuration refresh or * null to {@linkplain RefreshMode#DISABLED * disable} configuration refresh. - * + * * @see #DISABLED_CONFIG_REFRESH * @see #REACTIVE_CONFIG_REFRESH */ Duration getConfigRefreshPeriod(); /** - * Gets the concurrency for the thread pool used to execute the - * Senzing Core SDK operations. - * + * Gets the concurrency for the thread pool used to execute the Senzing + * Core SDK operations. + * *

* The Senzing Core SDK allocates resources that are local to each * thread. These resources are allocated when first needed and then @@ -313,23 +312,23 @@ public interface Initializer extends SzCoreEnvironment.Initializer { * the same threads each time for the Core SDK operations both * for performance reasons and to prevent excessive memory allocation. *

- * + * *

- * Server applications that leverage the Senzing Core SDK may have - * a large number of threads for servicing requests, but should limit - * the concurrency for the Senzing Core SDK to at most the number of + * Server applications that leverage the Senzing Core SDK may have a + * large number of threads for servicing requests, but should limit the + * concurrency for the Senzing Core SDK to at most the number of * processing cores on the machine (or less if memory is limited). *

- * + * * The provided value determines the behavior: *
    *
  • * If null (see {@link #DISABLED_CONCURRENCY}) * then the thread pool is disabled and all operations are * performed in the calling thread. This may be desirable - * if you have an {@link ExecutorService} that you are - * already using to perform one more Senzing Core SDK - * operations in conjunction and you want to avoid + * if you have an {@link ExecutorService} that you are + * already using to perform one more Senzing Core SDK + * operations in conjunction and you want to avoid * unnecessary context switching. *
  • *
  • @@ -343,17 +342,17 @@ public interface Initializer extends SzCoreEnvironment.Initializer { * using that number of threads. *
  • *
- * + * *

* Any created thread pool will be disposed upon calling {@link * #destroy()}. *

- * - * @return A positive integer indicating the size of the thread pool, + * + * @return A positive integer indicating the size of the thread pool, * zero (0) to use the number of threads equal to {@link * Runtime#availableProcessors()}, or null to * disable the thread pool. - * + * * @see #DISABLED_CONCURRENCY * @see #RECOMMENDED_CONCURRENCY * @see #submitTask(Callable) @@ -363,112 +362,110 @@ public interface Initializer extends SzCoreEnvironment.Initializer { Integer getConcurrency(); /** - * Returns the maximum number of times a method invocation should be - * retried either due to an {@link SzRetryableException} being + * Returns the maximum number of times a method invocation should be + * retried either due to an {@link SzRetryableException} being * encountered. - * + * *

* There are several things to note: *

*
    - *
  1. This setting has no effect on the retrying of + *
  2. This setting has no effect on the retrying of * Senzing Core SDK methods annotated with {@link * SzConfigRetryable} methods as that is simply governed by * the active configuration requiring a refresh. *
  3. - *
  4. Each subsequent retry for will occur after increasingly + *
  5. Each subsequent retry for will occur after increasingly * long delay to allow the condition causing the failure to * be resolved. *
  6. - *
  7. Since the basic retries are nested with the configuration + *
  8. Since the basic retries are nested with the configuration * refresh retries, it is possible, though unlikely, for the * total number of retries to exceed the maximum. For example, - * a method may fail due to a missing data source in the active + * a method may fail due to a missing data source in the active * configuration, triggering a retry after the configuration * refresh, and the retried attempt may then fail due to a - * persistent deadlock condition causing multiple {@link + * persistent deadlock condition causing multiple {@link * SzRetryableException}'s being thrown. *
  9. *
- * - * @return The maximum number of times to retry a method invocation - * due to an {@link SzRetryableException}. + * + * @return The maximum number of times to retry a method invocation due + * to an {@link SzRetryableException}. */ int getMaxBasicRetries(); } /** - * Extends {@link SzCoreEnvironment.AbstractBuilder} to provide - * additional initialization properties for {@link - * SzAutoCoreEnvironment}. - * - * @param The {@link SzAutoCoreEnvironment}-derived class - * built by instances of this class. + * Extends {@link SzCoreEnvironment.AbstractBuilder} to provide additional + * initialization properties for {@link SzAutoCoreEnvironment}. + * + * @param The {@link SzAutoCoreEnvironment}-derived class built by + * instances of this class. * @param The {@link AbstractBuilder}-derived class of the * implementation. */ - public abstract static - class AbstractBuilder> - extends SzCoreEnvironment.AbstractBuilder - implements Initializer + // CSOFF + public abstract static class AbstractBuilder> + extends SzCoreEnvironment.AbstractBuilder implements Initializer { + // CSON /** - * The number of threads for executing, or + * The number of threads for executing, or * null if the thread pool is disabled. */ private Integer concurrency = null; /** - * The period with which to background-refresh the - * active configuration, or null if - * configuration refresh is disabled. + * The period with which to background-refresh the active configuration, + * or null if configuration refresh is disabled. */ private Duration configRefreshPeriod = null; /** - * The maximum number of times to perform a retry of a - * method due to an {@link SzRetryableException}. + * The maximum number of times to perform a retry of a method due to an + * {@link SzRetryableException}. */ private int maxBasicRetries = DEFAULT_MAX_BASIC_RETRIES; /** * Default constructor. */ - protected AbstractBuilder() { + protected AbstractBuilder() + { super(); - this.concurrency = DISABLED_CONCURRENCY; - this.configRefreshPeriod = DISABLED_CONFIG_REFRESH; - this.maxBasicRetries = DEFAULT_MAX_BASIC_RETRIES; + this.concurrency = DISABLED_CONCURRENCY; + this.configRefreshPeriod = DISABLED_CONFIG_REFRESH; + this.maxBasicRetries = DEFAULT_MAX_BASIC_RETRIES; } /** - * Sets the configuration refresh period for this instance. - * If not explicitly called, the default value will be + * Sets the configuration refresh period for this instance. If not + * explicitly called, the default value will be * {@link #DISABLED_CONFIG_REFRESH}. - * + * *

- * See {@link #getConfigRefreshPeriod()} for a description - * of how the specified duration relates to the configuration - * refresh modes. + * See {@link #getConfigRefreshPeriod()} for a description of how the + * specified duration relates to the configuration refresh modes. *

- * - * @param duration A positive {@link Duration} to enable Proactive - * configuration refresh, a zero (0) {@link Duration} to - * enable Reactive configuration refresh or - * null to Disable configuration - * refresh. - * + * + * @param duration A positive {@link Duration} to enable + * Proactive configuration refresh, a zero (0) + * {@link Duration} to enable Reactive + * configuration refresh or null to + * Disable configuration refresh. + * * @return A reference to this instance. - * - * @throws IllegalArgumentException If a negative {@link Duration} is + * + * @throws IllegalArgumentException If a negative {@link Duration} is * specified. - * + * * @see #DISABLED_CONFIG_REFRESH * @see #REACTIVE_CONFIG_REFRESH */ @SuppressWarnings("unchecked") - public B configRefreshPeriod(Duration duration) + public B configRefreshPeriod(Duration duration) { if (duration != null && duration.isNegative()) { throw new IllegalArgumentException( @@ -480,36 +477,37 @@ public B configRefreshPeriod(Duration duration) } /** - * Implemented to return the configuration refresh period, - * or null if none has been configured. - * + * Implemented to return the configuration refresh period, or + * null if none has been configured. + * * {@inheritDoc} */ @Override - public Duration getConfigRefreshPeriod() { + public Duration getConfigRefreshPeriod() + { return this.configRefreshPeriod; } /** - * Sets the concurrency for the thread pool used to execute the - * Senzing Core SDK operations. If not explicitly called, the - * default value will be {@link #DISABLED_CONCURRENCY}. - * + * Sets the concurrency for the thread pool used to execute the Senzing + * Core SDK operations. If not explicitly called, the default value will + * be {@link #DISABLED_CONCURRENCY}. + * *

- * See {@link #getConcurrency()} for a description of how the - * specified concurrency affects the thread pool and how it is used. + * See {@link #getConcurrency()} for a description of how the specified + * concurrency affects the thread pool and how it is used. *

- * - * @param concurrency A positive integer indicating the size of - * the thread pool, zero (0) to use the a number - * of threads equal to {@link + * + * @param concurrency A positive integer indicating the size of the + * thread pool, zero (0) to use the a number of + * threads equal to {@link * Runtime#availableProcessors()}, or * null to disable the thread pool. - * + * * @return A reference to this instance. - * + * * @throws IllegalArgumentException If a negative value is specified. - * + * * @see #DISABLED_CONCURRENCY * @see #RECOMMENDED_CONCURRENCY * @see #submitTask(Callable) @@ -530,35 +528,36 @@ public B concurrency(Integer concurrency) } /** - * Implemented to return the concurrency or null - * if none has been configured. - * + * Implemented to return the concurrency or null if none + * has been configured. + * * {@inheritDoc} */ @Override - public Integer getConcurrency() { + public Integer getConcurrency() + { return this.concurrency; } /** - * Sets the maximum number of basic retries to perform when an + * Sets the maximum number of basic retries to perform when an * {@link SzRetryableException} is encountered when invoking an * Senzing Core SDK operation. - * + * *

* See {@link #getMaxBasicRetries()} for a description of how the * maximum is applied. *

- * + * * @param maxRetries A non-negative integer indicating the maximum - * number of times to retry a Senzing Core SDK - * operation that fails with an - * {@link SzRetryableException}. - * + * number of times to retry a Senzing Core SDK + * operation that fails with an {@link + * SzRetryableException}. + * * @return A reference to this instance. - * + * * @throws IllegalArgumentException If a negative value is specified. - * + * * @see #DEFAULT_MAX_BASIC_RETRIES */ @SuppressWarnings("unchecked") @@ -567,63 +566,64 @@ public B maxBasicRetries(int maxRetries) { if (maxRetries < 0) { throw new IllegalArgumentException( - "The specified maximum number of retries cannot be negative: " - + maxRetries); + "The specified maximum number of retries cannot be " + + "negative: " + maxRetries); } this.maxBasicRetries = maxRetries; return ((B) this); } /** - * Implemented to return the configuration refresh period, - * or null if none has been configured. - * + * Implemented to return the configuration refresh period, or + * null if none has been configured. + * * {@inheritDoc} */ @Override - public int getMaxBasicRetries() { + public int getMaxBasicRetries() + { return this.maxBasicRetries; } } /** - * The builder class for creating an instance of + * The builder class for creating an instance of * {@link SzAutoCoreEnvironment}. */ - public static class Builder - extends AbstractBuilder + public static class Builder + extends AbstractBuilder { /** * Default constructor. */ - public Builder() { + public Builder() + { super(); } /** - * Creates a new {@link SzAutoCoreEnvironment} instance based on - * this {@link Builder} instance. This method will throw an {@link + * Creates a new {@link SzAutoCoreEnvironment} instance based on this + * {@link Builder} instance. This method will throw an {@link * IllegalStateException} if another active {@link SzCoreEnvironment} * instance exists since only one active instance can exist within a - * process at any given time. An active instance is one that has - * been constructed, but has not yet been destroyed. - * + * process at any given time. An active instance is one that has been + * constructed, but has not yet been destroyed. + * * @return The newly created {@link SzAutoCoreEnvironment} instance. - * - * @throws IllegalStateException If another active {@link SzCoreEnvironment} - * instance exists when this method is - * invoked OR if there is an explicit - * configuration ID and the configuration - * refresh period is not - * null. + * + * @throws IllegalStateException If another active {@link + * SzCoreEnvironment} instance exists when + * this method is invoked OR if + * there is an explicit configuration ID + * and the configuration refresh period is + * not null. */ @Override - public SzAutoCoreEnvironment build() + public SzAutoCoreEnvironment build() throws IllegalStateException { - if (this.getConfigId() != null - && this.getConfigRefreshPeriod() != null) - { + if (this.getConfigId() != null && this.getConfigRefreshPeriod() + != null) { throw new IllegalStateException( "Cannot provide an explicit configuration ID (" + this.getConfigId() + ") and enable configuration " @@ -639,22 +639,25 @@ public SzAutoCoreEnvironment build() /** * Extends {@link Thread} to allow for identifying of core threads. */ - static class CoreThread extends Thread { + static class CoreThread extends Thread + { /** * Constructs with the specified {@link Runnable}. - * + * * @param runnable The {@link Runnable} with which to construct with. */ - CoreThread(Runnable runnable) { + CoreThread(Runnable runnable) + { super(runnable); } } /** - * The {@link InvocationHandler} implementation that sets the - * thread-local {@link #CONFIG_RETRY_FLAG} if a method is retryable. + * The {@link InvocationHandler} implementation that sets the thread-local + * {@link #CONFIG_RETRY_FLAG} if a method is retryable. */ - private static class RetryHandler implements InvocationHandler { + private static class RetryHandler implements InvocationHandler + { /** * The target object for which to handle methods. */ @@ -662,17 +665,19 @@ private static class RetryHandler implements InvocationHandler { /** * Constructs with the target object. - * + * * @param target The target object for which to handle methods. */ - RetryHandler(Object target) { + RetryHandler(Object target) + { this.target = target; } @Override - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable + public Object invoke(Object proxy, Method method, Object[] args) + throws Throwable { - SzConfigRetryable retryable + SzConfigRetryable retryable = method.getAnnotation(SzConfigRetryable.class); Object result = null; @@ -680,21 +685,17 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl if (retryable == null) { try { result = method.invoke(target, args); - } catch (InvocationTargetException e) { // get the cause of the exception throw e.getCause(); } - } else { Boolean initial = CONFIG_RETRY_FLAG.get(); CONFIG_RETRY_FLAG.set(Boolean.TRUE); try { result = method.invoke(target, args); - } catch (InvocationTargetException e) { throw e.getCause(); - } finally { // set the flag back to what our caller set CONFIG_RETRY_FLAG.set(initial); @@ -703,14 +704,13 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl // check the result to see if we need to proxy it final Object r = result; - if (r != null - && (PROXY_CLASSES.contains(method.getReturnType()) - || PROXY_CLASSES.stream().anyMatch((c) -> c.isInstance(r)))) - { + if (r != null && (PROXY_CLASSES.contains(method.getReturnType()) + || PROXY_CLASSES.stream().anyMatch((c) -> c.isInstance(r)))) { Class[] interfaces = result.getClass().getInterfaces(); ClassLoader classLoader = this.getClass().getClassLoader(); RetryHandler handler = new RetryHandler(result); - result = Proxy.newProxyInstance(classLoader, interfaces, handler); + result = Proxy.newProxyInstance(classLoader, interfaces, + handler); } // return the result (possibly proxied) @@ -721,36 +721,38 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl /** * The {@link ThreadFactory} to be used by instances of this class. */ - private static final ThreadFactory THREAD_FACTORY = (r) -> new CoreThread(r); + private static final ThreadFactory THREAD_FACTORY + = (r) -> new CoreThread(r); /** - * Creates a new instance of {@link Builder} for setting up an instance - * of {@link SzAutoCoreEnvironment}. Keep in mind that while multiple - * {@link Builder} instances can exists, only one active instance of - * {@link SzCoreEnvironment} (including any of its derived classes) can exist - * at time. An active instance is one that has not yet been destroyed. - * + * Creates a new instance of {@link Builder} for setting up an instance of + * {@link SzAutoCoreEnvironment}. Keep in mind that while multiple {@link + * Builder} instances can exists, only one active instance of {@link + * SzCoreEnvironment} (including any of its derived classes) can exist at + * time. An active instance is one that has not yet been destroyed. + * *

* NOTE: The static method {@link #newBuilder()} will produce an * instance of {@link SzCoreEnvironment.Builder} which will only create - * instances of {@link SzCoreEnvironment} rather than {@link + * instances of {@link SzCoreEnvironment} rather than {@link * SzAutoCoreEnvironment}. *

- * + * *

* Alternatively, you can directly call the {@link Builder#Builder()} * constructor. *

- * - * @return The {@link Builder} for configuring and initializing the - * {@link SzAutoCoreEnvironment}. + * + * @return The {@link Builder} for configuring and initializing the {@link + * SzAutoCoreEnvironment}. */ - public static Builder newAutoBuilder() { + public static Builder newAutoBuilder() + { return new Builder(); } /** - * The {@link ExecutorService} to be used by this instance, or + * The {@link ExecutorService} to be used by this instance, or * null if the thread pool is disabled. */ private ExecutorService coreExecutor = null; @@ -771,20 +773,19 @@ public static Builder newAutoBuilder() { private RefreshMode refreshMode = null; /** - * The maximum number of times each method invocation should - * be retried when an {@link SzRetryableException} is encountered. + * The maximum number of times each method invocation should be retried when + * an {@link SzRetryableException} is encountered. */ private int maxBasicRetries = DEFAULT_MAX_BASIC_RETRIES; /** - * Flag indicating if this instance has had its + * Flag indicating if this instance has had its * {@link #destroy()} method called. */ private boolean destroying = false; /** - * The {@link Reinitializer} thread to background refresh - * the configuration. + * The {@link Reinitializer} thread to background refresh the configuration. */ private Reinitializer reinitializer = null; @@ -836,16 +837,16 @@ public static Builder newAutoBuilder() { /** * Protected constructor used by the {@link Builder} to construct the * instance. - * + * * @param initializer The {@link Initializer} with which to construct * (typically an instance of {@link AbstractBuilder}). */ - protected SzAutoCoreEnvironment(Initializer initializer) + protected SzAutoCoreEnvironment(Initializer initializer) { super(initializer); try { - this.readWriteLock = new ReentrantReadWriteLock(true); + this.readWriteLock = new ReentrantReadWriteLock(true); // determine the number of threads we need in the thread pool Integer threadCount = initializer.getConcurrency(); @@ -853,7 +854,6 @@ protected SzAutoCoreEnvironment(Initializer initializer) threadCount = 0; } else if (threadCount == 0) { threadCount = Runtime.getRuntime().availableProcessors(); - } else if (threadCount < 0) { throw new IllegalArgumentException( "The concurrency cannot be negative: " + threadCount); @@ -871,7 +871,7 @@ protected SzAutoCoreEnvironment(Initializer initializer) // determine the configuration refresh period and mode this.configRefreshPeriod = initializer.getConfigRefreshPeriod(); - + if (this.configRefreshPeriod == null) { this.refreshMode = RefreshMode.DISABLED; } else if (this.configRefreshPeriod.isZero()) { @@ -885,15 +885,15 @@ protected SzAutoCoreEnvironment(Initializer initializer) } // setup the executor service - this.coreExecutor = (threadCount == 0) ? null - : Executors.newFixedThreadPool(threadCount, THREAD_FACTORY); + this.coreExecutor = (threadCount == 0) + ? null : Executors.newFixedThreadPool(threadCount, + THREAD_FACTORY); // setup the background configuration refresh if needed if (this.refreshMode == RefreshMode.PROACTIVE) { this.reinitializer = new Reinitializer(this); this.reinitializer.start(); } - } catch (RuntimeException e) { // cleanup anything we might have initialized if (this.coreExecutor != null) { @@ -914,7 +914,8 @@ protected SzAutoCoreEnvironment(Initializer initializer) * {@inheritDoc} */ @Override - public int getConcurrency() { + public int getConcurrency() + { Lock lock = null; try { lock = this.acquireReadLock(); @@ -929,7 +930,8 @@ public int getConcurrency() { * {@inheritDoc} */ @Override - public int getMaxBasicRetries() { + public int getMaxBasicRetries() + { Lock lock = null; try { lock = this.acquireReadLock(); @@ -944,7 +946,8 @@ public int getMaxBasicRetries() { * {@inheritDoc} */ @Override - public int getConfigRefreshCount() { + public int getConfigRefreshCount() + { Lock lock = null; try { lock = this.acquireReadLock(); @@ -961,7 +964,8 @@ public int getConfigRefreshCount() { * {@inheritDoc} */ @Override - public int getRetriedCount() { + public int getRetriedCount() + { Lock lock = null; try { lock = this.acquireReadLock(); @@ -978,7 +982,8 @@ public int getRetriedCount() { * {@inheritDoc} */ @Override - public int getRetriedFailureCount() { + public int getRetriedFailureCount() + { Lock lock = null; try { lock = this.acquireReadLock(); @@ -992,27 +997,30 @@ public int getRetriedFailureCount() { } /** - * Ensures this instance is still active and if not will throw - * an {@link SzEnvironmentDestroyedException}. + * Ensures this instance is still active and if not will throw an {@link + * SzEnvironmentDestroyedException}. * * @throws SzEnvironmentDestroyedException If this instance is not active. */ - void ensureNotDestroyed() throws SzEnvironmentDestroyedException { + void ensureNotDestroyed() + throws SzEnvironmentDestroyedException + { synchronized (this.monitor) { if (this.destroying) { throw new SzEnvironmentDestroyedException( "This instance has already been destroyed."); - } + } } } /** - * Helper to trap destroyed states without throwing an exception. - * Usually the destroyed state is trapped later. - * + * Helper to trap destroyed states without throwing an exception. Usually + * the destroyed state is trapped later. + * * @param The type returned by the callable. */ - class TrapDestroyed { + class TrapDestroyed + { /** * The result to return if destroyed. */ @@ -1026,45 +1034,47 @@ class TrapDestroyed { /** * Constructs with the {@link Callable} and uses * null as the result if destroyed. - * + * * @param callable The {@link Callable} to execute. */ - TrapDestroyed(Callable callable) { + TrapDestroyed(Callable callable) + { this(callable, null); } /** - * Constructs with the {@link Callable} and the - * specified value to return if destroyed. - * + * Constructs with the {@link Callable} and the specified value to + * return if destroyed. + * * @param callable The {@link Callable} to execute. * @param destroyedResult The value to return if destroyed. */ - TrapDestroyed(Callable callable, T destroyedResult) { + TrapDestroyed(Callable callable, T destroyedResult) + { this.callable = callable; this.destroyedResult = destroyedResult; } /** - * Calls the function and traps any {@link SzEnvironmentDestroyedException} - * and returns the destroyed result if encountered. - * - * @return The result from the {@link Callable} or the destroyed - * result if destroyed. - * + * Calls the function and traps any {@link + * SzEnvironmentDestroyedException} and returns the destroyed result if + * encountered. + * + * @return The result from the {@link Callable} or the destroyed result + * if destroyed. + * * @throws SzException If the specified {@link Callable} throws an * {@link SzException}. */ - public T call() throws SzException { + public T call() + throws SzException + { try { return this.callable.call(); - } catch (SzEnvironmentDestroyedException e) { return this.destroyedResult; - } catch (SzException | RuntimeException e) { throw e; - } catch (Exception e) { throw new RuntimeException(e); } @@ -1072,20 +1082,21 @@ public T call() throws SzException { } /** - * Protected method to ensure the active configuration ID is the same - * as the default configuration ID. This will check if they are out - * of sync and, if so, reinitialize with the default configuration ID. - * This will attempt to handle the unlikely (though possible) race - * conditions by rechecking several times that they are in sync after - * reinitializing. - * - * @return true if the active configuration ID was updated - * to the default configuration ID, otherwise false - * if no update was necessary. - * + * Protected method to ensure the active configuration ID is the same as the + * default configuration ID. This will check if they are out of sync and, if + * so, reinitialize with the default configuration ID. This will attempt to + * handle the unlikely (though possible) race conditions by rechecking + * several times that they are in sync after reinitializing. + * + * @return true if the active configuration ID was updated to + * the default configuration ID, otherwise false if no + * update was necessary. + * * @throws SzException If a failure occurs. */ - protected boolean ensureConfigCurrent() throws SzException { + protected boolean ensureConfigCurrent() + throws SzException + { Boolean prevEnsuring = ENSURING_CONFIG.get(); ENSURING_CONFIG.set(Boolean.TRUE); try { @@ -1121,19 +1132,20 @@ protected boolean ensureConfigCurrent() throws SzException { // check if we have exceeded our number of retries if (tryCount >= MAX_REINITIALIZE_COUNT) { System.err.println( - "*** WARNING: Default configuration is constantly changing. Could not reinitialize " - + "to the latest default configuration ID after " + tryCount + " attempts. " - + "activeConfigId=[ " + activeConfigId + " ], defaultConfigId=[ " - + defaultConfigId + " ]"); - - // allow the caller to retry anyway since we did update the config + "*** WARNING: Default configuration is constantly " + + "changing. Could not reinitialize to the latest " + + "default configuration ID after " + tryCount + + " attempts. activeConfigId=[ " + activeConfigId + + " ], defaultConfigId=[ " + defaultConfigId + " ]"); + + // allow the caller to retry anyway since we did update the + // config return true; } // attempt to reinitialize (we may be destroyed at this point) try { this.reinitialize(defaultConfigId); - } catch (SzEnvironmentDestroyedException e) { break; } @@ -1152,13 +1164,14 @@ protected boolean ensureConfigCurrent() throws SzException { } finally { ENSURING_CONFIG.set(prevEnsuring); } - } + } /** * {@inheritDoc} */ @Override - public RefreshMode getConfigRefreshMode() { + public RefreshMode getConfigRefreshMode() + { Lock lock = null; try { lock = this.acquireReadLock(); @@ -1173,7 +1186,8 @@ public RefreshMode getConfigRefreshMode() { * {@inheritDoc} */ @Override - public Duration getConfigRefreshPeriod() { + public Duration getConfigRefreshPeriod() + { Lock lock = null; try { lock = this.acquireReadLock(); @@ -1185,125 +1199,132 @@ public Duration getConfigRefreshPeriod() { } /** - * Overridden to proxy the result to implement the retry-on-refresh - * logic for methods annotated with {@link SzConfigRetryable} that - * fail with an {@link SzException}. - * + * Overridden to proxy the result to implement the retry-on-refresh logic + * for methods annotated with {@link SzConfigRetryable} that fail with an + * {@link SzException}. + * * {@inheritDoc} */ @Override - public SzEngine getEngine() throws SzException { + public SzEngine getEngine() + throws SzException + { synchronized (this.monitor) { this.ensureNotDestroyed(); - if (this.engine != null) { - return this.engine; - } + if (this.engine != null) return this.engine; SzEngine engine = super.getEngine(); Class[] interfaces = engine.getClass().getInterfaces(); ClassLoader classLoader = this.getClass().getClassLoader(); RetryHandler handler = new RetryHandler(engine); - this.engine = (SzEngine) Proxy.newProxyInstance(classLoader, interfaces, handler); + this.engine = (SzEngine) Proxy.newProxyInstance(classLoader, + interfaces, + handler); return this.engine; } } /** - * Overridden to proxy the result to implement the retry-on-refresh - * logic for methods annotated with {@link SzConfigRetryable} that - * fail with an {@link SzException}. - * + * Overridden to proxy the result to implement the retry-on-refresh logic + * for methods annotated with {@link SzConfigRetryable} that fail with an + * {@link SzException}. + * * {@inheritDoc} */ @Override - public SzProduct getProduct() throws SzException { + public SzProduct getProduct() + throws SzException + { synchronized (this.monitor) { this.ensureNotDestroyed(); - if (this.product != null) { - return this.product; - } + if (this.product != null) return this.product; SzProduct product = super.getProduct(); Class[] interfaces = product.getClass().getInterfaces(); ClassLoader classLoader = this.getClass().getClassLoader(); RetryHandler handler = new RetryHandler(product); - this.product = (SzProduct) Proxy.newProxyInstance(classLoader, interfaces, handler); + this.product = (SzProduct) Proxy.newProxyInstance(classLoader, + interfaces, + handler); return this.product; } } /** - * Overridden to proxy the result to implement the retry-on-refresh - * logic for methods annotated with {@link SzConfigRetryable} that - * fail with an {@link SzException}. - * + * Overridden to proxy the result to implement the retry-on-refresh logic + * for methods annotated with {@link SzConfigRetryable} that fail with an + * {@link SzException}. + * * {@inheritDoc} */ @Override - public SzConfigManager getConfigManager() throws SzException { + public SzConfigManager getConfigManager() + throws SzException + { synchronized (this.monitor) { this.ensureNotDestroyed(); - if (this.configManager != null) { - return this.configManager; - } + if (this.configManager != null) return this.configManager; SzConfigManager configManager = super.getConfigManager(); Class[] interfaces = configManager.getClass().getInterfaces(); ClassLoader classLoader = this.getClass().getClassLoader(); RetryHandler handler = new RetryHandler(configManager); - this.configManager = (SzConfigManager) - Proxy.newProxyInstance(classLoader, interfaces, handler); + this.configManager = (SzConfigManager) Proxy.newProxyInstance( + classLoader, + interfaces, + handler); return this.configManager; } } /** - * Overridden to proxy the result to implement the retry-on-refresh - * logic for methods annotated with {@link SzConfigRetryable} that - * fail with an {@link SzException}. - * + * Overridden to proxy the result to implement the retry-on-refresh logic + * for methods annotated with {@link SzConfigRetryable} that fail with an + * {@link SzException}. + * * {@inheritDoc} */ @Override - public SzDiagnostic getDiagnostic() throws SzException { + public SzDiagnostic getDiagnostic() + throws SzException + { synchronized (this.monitor) { this.ensureNotDestroyed(); - if (this.diagnostic != null) { - return this.diagnostic; - } + if (this.diagnostic != null) return this.diagnostic; SzDiagnostic diagnostic = super.getDiagnostic(); Class[] interfaces = diagnostic.getClass().getInterfaces(); ClassLoader classLoader = this.getClass().getClassLoader(); RetryHandler handler = new RetryHandler(diagnostic); - this.diagnostic = (SzDiagnostic) - Proxy.newProxyInstance(classLoader, interfaces, handler); + this.diagnostic = (SzDiagnostic) Proxy.newProxyInstance( + classLoader, + interfaces, + handler); return this.diagnostic; } } /** - * Overridden to ensure that if the configuration refresh is + * Overridden to ensure that if the configuration refresh is * {@linkplain RefreshMode#PROACTIVE proactive} that the background - * thread that handles periodic refresh is shutdown before destroying - * the environment. - * + * thread that handles periodic refresh is shutdown before destroying the + * environment. + * *

* Further, this override will ensure that all threads in the execution * thread pool (if any) are destroyed after the environment is destroyed. *

- * + * * {@inheritDoc} */ @Override - public void destroy() { + public void destroy() + { Lock lock = null; try { synchronized (this.monitor) { // check if already destroyed - if (this.destroying) { - return; - } + if (this.destroying) return; // flag as destroying this.destroying = true; @@ -1315,7 +1336,8 @@ public void destroy() { this.reinitializer.complete(); for (int tryCount = 0; - (tryCount < SHUTDOWN_WAIT_COUNT && this.reinitializer.isAlive()); + (tryCount < SHUTDOWN_WAIT_COUNT + && this.reinitializer.isAlive()); tryCount++) { try { @@ -1325,8 +1347,9 @@ public void destroy() { } } if (this.reinitializer.isAlive()) { - System.err.println("Failed to shutdown reinitializer thread: " - + this.reinitializer.getName()); + System.err.println( + "Failed to shutdown reinitializer thread: " + + this.reinitializer.getName()); } } this.reinitializer = null; @@ -1334,7 +1357,7 @@ public void destroy() { // acquire the write lock to wait for in-flight operations // to complete (including compound retry operations) lock = this.acquireWriteLock(); - + // destroy the environment super.destroy(); @@ -1343,65 +1366,66 @@ public void destroy() { this.configManager = null; this.product = null; this.diagnostic = null; - + // cleanup after the executor if (this.coreExecutor != null) { this.coreExecutor.shutdown(); for (int retryCount = 0; - (retryCount < SHUTDOWN_WAIT_COUNT && !this.coreExecutor.isTerminated()); + (retryCount < SHUTDOWN_WAIT_COUNT + && !this.coreExecutor.isTerminated()); retryCount++) { try { - this.coreExecutor.awaitTermination(SHUTDOWN_WAIT_SECONDS, TimeUnit.SECONDS); + this.coreExecutor.awaitTermination( + SHUTDOWN_WAIT_SECONDS, + TimeUnit.SECONDS); } catch (InterruptedException ignore) { // ignore } } if (!this.coreExecutor.isTerminated()) { - System.err.println("Failed to shutdown executor service: concurrency=[ " - + this.concurrency + " ]"); + System.err.println( + "Failed to shutdown executor service: concurrency=[ " + + this.concurrency + " ]"); } } - } finally { lock = releaseLock(lock); } } - /** - * Calls the super class {@link #execute(Callable)} implementation - * at least once and then repeatedly if necessary until either the - * call succeeds, fails with an exception other than {@link - * SzRetryableException} or the {@linkplain #getMaxBasicRetries() - * configured maximum} number of retry attempts has been reached. - * + * Calls the super class {@link #execute(Callable)} implementation at least + * once and then repeatedly if necessary until either the call succeeds, + * fails with an exception other than {@link SzRetryableException} or the + * {@linkplain #getMaxBasicRetries() configured maximum} number of retry + * attempts has been reached. + * *

- * There will be no delay in making the first retry attempt. - * Subsequent retry attempts will be attempted after an increasing - * delay with each attempt. + * There will be no delay in making the first retry attempt. Subsequent + * retry attempts will be attempted after an increasing delay with each + * attempt. *

- * + * *

* If still failing with {@link SzRetryableException} after the * {@linkplain #getMaxBasicRetries() maximum number retries} has - * been reached, then the {@link SzRetryableException} is simply - * re-thrown. + * been reached, then the {@link SzRetryableException} is simply re-thrown. *

- * + * * @param The return type of the specified {@link Callable}. - * + * * @param task The task to execute. - * + * * @return The return value from the specified {@link Callable} - * - * @throws SzRetryableException If the specified task failed with - * this exception and we have retried - * the maximum number of times. - * + * + * @throws SzRetryableException If the specified task failed with this + * exception and we have retried the maximum + * number of times. + * * @throws SzException If a failure occurs. */ - protected T executeWithBasicRetry(Callable task) + protected T executeWithBasicRetry(Callable task) throws SzException { int maxAttempts = this.maxBasicRetries + 1; @@ -1426,9 +1450,8 @@ protected T executeWithBasicRetry(Callable task) } return super.execute(task); - } catch (SzRetryableException e) { - lastException = e; + lastException = e; } } @@ -1437,20 +1460,21 @@ protected T executeWithBasicRetry(Callable task) } /** - * Overridden to implement retry logic if {@link #getConfigRefreshMode()} - * is not {@link RefreshMode#DISABLED} and an {@link SzException} - * is encountered on a Senzing Core SDK method that is annotated with + * Overridden to implement retry logic if {@link #getConfigRefreshMode()} is + * not {@link RefreshMode#DISABLED} and an {@link SzException} is + * encountered on a Senzing Core SDK method that is annotated with * {@link SzConfigRetryable}. - * + * * {@inheritDoc} */ @Override - protected T execute(Callable task) + protected T execute(Callable task) throws SzException, SzEnvironmentDestroyedException { Lock lock = null; Boolean initialFlag = RETRIED_FLAG.get(); - RETRIED_FLAG.set(Boolean.FALSE); // clear the flag + RETRIED_FLAG.set(Boolean.FALSE); + // clear the flag try { lock = this.acquireReadLock(); this.ensureNotDestroyed(); @@ -1462,25 +1486,23 @@ protected T execute(Callable task) // if we are not refreshing the configuration, we are // already ensuring the config is current, or the // retry flag is not set then just execute the task - if (this.refreshMode == RefreshMode.DISABLED - || Boolean.TRUE.equals(ENSURING_CONFIG.get()) - || (!Boolean.TRUE.equals(CONFIG_RETRY_FLAG.get()))) - { + if (this.refreshMode + == RefreshMode.DISABLED || Boolean.TRUE.equals( + ENSURING_CONFIG.get()) || (!Boolean.TRUE.equals( + CONFIG_RETRY_FLAG.get()))) { return this.executeWithBasicRetry(task); } // otherwise execute and trap any SzException try { return this.executeWithBasicRetry(task); - } catch (SzException e) { - // we need to check the active config and + // we need to check the active config and // update the config if necessary boolean configUpdated = false; try { // refresh the configuration configUpdated = this.ensureConfigCurrent(); - } catch (SzException e2) { e2.printStackTrace(); // if we fail to refresh the config then @@ -1490,9 +1512,7 @@ protected T execute(Callable task) // if the configuration was not updated // then rethrow the original exception - if (!configUpdated) { - throw e; - } + if (!configUpdated) throw e; // flag that we are retrying RETRIED_FLAG.set(Boolean.TRUE); @@ -1500,11 +1520,9 @@ protected T execute(Callable task) // if we get here then try again return this.executeWithBasicRetry(task); } - } catch (SzException | RuntimeException e) { retryFailure = true; throw e; - } finally { // check the retried flag if (Boolean.TRUE.equals(RETRIED_FLAG.get())) { @@ -1518,7 +1536,6 @@ protected T execute(Callable task) // clear the retried flag RETRIED_FLAG.set(initialFlag); } - } finally { // release the lock lock = releaseLock(lock); @@ -1526,19 +1543,18 @@ protected T execute(Callable task) } /** - * Overridden to implement the use of an internal {@link ExecutorService} - * if this instance has been configured with a positive concurrency that + * Overridden to implement the use of an internal {@link ExecutorService} if + * this instance has been configured with a positive concurrency that * provides for an execution thread pool. - * + * * {@inheritDoc} */ @Override - protected T doExecute(Callable task) throws Exception + protected T doExecute(Callable task) + throws Exception { // check if we have a thread pool - if (this.coreExecutor == null) { - return super.doExecute(task); - } + if (this.coreExecutor == null) return super.doExecute(task); // otherwise, use the executor Future future = this.coreExecutor.submit(task); @@ -1546,7 +1562,6 @@ protected T doExecute(Callable task) throws Exception try { // resolve the future return future.get(); - } catch (ExecutionException e) { // get the cause for the exception Throwable cause = e.getCause(); @@ -1555,11 +1570,9 @@ protected T doExecute(Callable task) throws Exception if (cause instanceof Error) { // if an error, rethrow as an error throw ((Error) cause); - } else if (cause instanceof Exception) { // if an exception, rethrow as an exception throw ((Exception) cause); - } else { // for any other throwable, throw the ExecutionException throw e; @@ -1571,7 +1584,8 @@ protected T doExecute(Callable task) throws Exception * {@inheritDoc} */ @Override - public Future submitTask(Callable task) { + public Future submitTask(Callable task) + { Lock lock = null; try { lock = this.acquireReadLock(); @@ -1586,7 +1600,6 @@ public Future submitTask(Callable task) { } else { return this.coreExecutor.submit(task); } - } finally { lock = releaseLock(lock); } @@ -1596,7 +1609,8 @@ public Future submitTask(Callable task) { * {@inheritDoc} */ @Override - public Future submitTask(Runnable task) { + public Future submitTask(Runnable task) + { return this.submitTask(task, null); } @@ -1604,7 +1618,8 @@ public Future submitTask(Runnable task) { * {@inheritDoc} */ @Override - public Future submitTask(Runnable task, T result) { + public Future submitTask(Runnable task, T result) + { Lock lock = null; try { lock = this.acquireReadLock(); @@ -1620,7 +1635,6 @@ public Future submitTask(Runnable task, T result) { } else { return this.coreExecutor.submit(task, result); } - } finally { lock = releaseLock(lock); } @@ -1629,22 +1643,24 @@ public Future submitTask(Runnable task, T result) { /** * Acquires an exclusive write lock from this instance's * {@link ReentrantReadWriteLock}. - * + * * @return The {@link Lock} that was acquired. */ - private Lock acquireWriteLock() { + private Lock acquireWriteLock() + { Lock lock = this.readWriteLock.writeLock(); lock.lock(); return lock; } /** - * Acquires a shared read lock from this instance's + * Acquires a shared read lock from this instance's * {@link ReentrantReadWriteLock}. - * + * * @return The {@link Lock} that was acquired. */ - private Lock acquireReadLock() { + private Lock acquireReadLock() + { Lock lock = this.readWriteLock.readLock(); lock.lock(); return lock; @@ -1652,12 +1668,13 @@ private Lock acquireReadLock() { /** * Releases the specified {@link Lock} if not null. - * + * * @param lock The {@link Lock} to be released. - * + * * @return Always returns null. */ - private Lock releaseLock(Lock lock) { + private Lock releaseLock(Lock lock) + { if (lock != null) { lock.unlock(); } @@ -1666,15 +1683,16 @@ private Lock releaseLock(Lock lock) { /** * {@inheritDoc} - * + * *

- * Overridden to return true once the {@link #destroy()} - * method has been called even before the destruction of this instance - * has completed. + * Overridden to return true once the {@link #destroy()} method + * has been called even before the destruction of this instance has + * completed. *

*/ @Override - public boolean isDestroyed() { + public boolean isDestroyed() + { synchronized (this.monitor) { return this.destroying; } @@ -1682,29 +1700,28 @@ public boolean isDestroyed() { /** * {@inheritDoc} - * + * *

* Overridden to handle timing the blocking of a destroying instance * properly. *

*/ @Override - protected boolean validateActiveInstance() { + protected boolean validateActiveInstance() + { synchronized (this.monitor) { - if (!this.destroying) { - return true; - } + if (!this.destroying) return true; this.waitUntilDestroyed(); return false; } } /** - * Waits until this instance has been destroyed. This is an internal - * method used when this instance is being destroyed and we want to - * wait until it is fully destroyed. + * Waits until this instance has been destroyed. This is an internal method + * used when this instance is being destroyed and we want to wait until it + * is fully destroyed. */ - private void waitUntilDestroyed() + private void waitUntilDestroyed() { synchronized (this.monitor) { while (!super.isDestroyed()) { @@ -1716,5 +1733,4 @@ private void waitUntilDestroyed() } } } - } diff --git a/src/main/java/com/senzing/sdk/core/auto/SzAutoEnvironment.java b/src/main/java/com/senzing/sdk/core/auto/SzAutoEnvironment.java index 89791a7..3815b77 100644 --- a/src/main/java/com/senzing/sdk/core/auto/SzAutoEnvironment.java +++ b/src/main/java/com/senzing/sdk/core/auto/SzAutoEnvironment.java @@ -3,7 +3,6 @@ import java.time.Duration; import java.util.concurrent.Callable; import java.util.concurrent.Future; - import com.senzing.sdk.SzEnvironment; import com.senzing.sdk.core.auto.SzAutoCoreEnvironment.RefreshMode; @@ -12,35 +11,35 @@ * {@link SzAutoCoreEnvironment} so that the functionality may be * proxied or otherwise implemented. */ -public interface SzAutoEnvironment extends SzEnvironment { +public interface SzAutoEnvironment extends SzEnvironment +{ /** * Gets the concurrency with which this instance was initialized. - * + * *

- * The value returned will be zero (0) if the thread pool has been - * disabled, otherwise it will be the number of threads in the - * pool. + * The value returned will be zero (0) if the thread pool has been disabled, + * otherwise it will be the number of threads in the pool. *

- * - * @return The number of threads in the thread pool for the internal - * {@link java.util.concurrent.ExecutorService}, or zero (0) - * if threading is disabled. + * + * @return The number of threads in the thread pool for the internal {@link + * java.util.concurrent.ExecutorService}, or zero (0) if threading + * is disabled. */ int getConcurrency(); /** - * Gets the maximum number of basic retries that will be - * attempted when a Senzing Core SDK operation fails with an + * Gets the maximum number of basic retries that will be attempted when a + * Senzing Core SDK operation fails with an * {@link com.senzing.sdk.SzRetryableException}. - * + * *

* See {@link SzAutoCoreEnvironment.Initializer#getMaxBasicRetries()} for a * description of how the maximum is applied. *

- * - * @return The maximum number of basic retries that will be - * attempted when a Senzing Core SDK operation fails - * with an {@link com.senzing.sdk.SzRetryableException}. + * + * @return The maximum number of basic retries that will be attempted when a + * Senzing Core SDK operation fails with an {@link + * com.senzing.sdk.SzRetryableException}. */ int getMaxBasicRetries(); @@ -48,48 +47,46 @@ public interface SzAutoEnvironment extends SzEnvironment { * Gets the total number of times the configuration was automatically * refreshed either periodically or due to an exception on a method * annotated with {@link com.senzing.sdk.SzConfigRetryable}. - * + * *

- * NOTE: This does NOT include explicit calls to + * NOTE: This does NOT include explicit calls to * {@link #reinitialize(long)}. *

- * + * * @return The total number of times the configuration was automatically * refreshed */ int getConfigRefreshCount(); /** - * Gets the total number Senzing Core SDK method invocations - * that initially failed and were retried whether or not they - * ultimately succeeded. - * - * @return The total number Senzing Core SDK method invocations - * that initially failed and were retried. + * Gets the total number Senzing Core SDK method invocations that initially + * failed and were retried whether or not they ultimately succeeded. + * + * @return The total number Senzing Core SDK method invocations that + * initially failed and were retried. */ int getRetriedCount(); /** - * Gets the total number Senzing Core SDK method invocations - * that initially failed, were retried at least once and - * ultimately failed. - * - * @return The total number Senzing Core SDK method invocations - * that initially failed, were retried and ultimately failed. + * Gets the total number Senzing Core SDK method invocations that initially + * failed, were retried at least once and ultimately failed. + * + * @return The total number Senzing Core SDK method invocations that + * initially failed, were retried and ultimately failed. */ int getRetriedFailureCount(); /** - * Gets the {@link RefreshMode} describing how this instance will - * handle refreshing the configuration (or not refreshing it). The - * mode is set based on the value for the {@linkplain + * Gets the {@link RefreshMode} describing how this instance will handle + * refreshing the configuration (or not refreshing it). The mode is set + * based on the value for the {@linkplain * SzAutoCoreEnvironment.Builder#getConfigRefreshPeriod() configuration - * refresh period} provided to the {@link SzAutoCoreEnvironment.Builder} - * via {@link SzAutoCoreEnvironment.Builder#configRefreshPeriod(Duration)}. - * - * @return The {@link RefreshMode} describing how this instance will - * handle refreshing the configuration (or not). - * + * refresh period} provided to the {@link SzAutoCoreEnvironment.Builder} via + * {@link SzAutoCoreEnvironment.Builder#configRefreshPeriod(Duration)}. + * + * @return The {@link RefreshMode} describing how this instance will handle + * refreshing the configuration (or not). + * * @see #getConfigRefreshPeriod() * @see SzAutoCoreEnvironment.Builder#configRefreshPeriod(Duration) * @see SzAutoCoreEnvironment.Builder#getConfigRefreshPeriod() @@ -98,16 +95,15 @@ public interface SzAutoEnvironment extends SzEnvironment { RefreshMode getConfigRefreshMode(); /** - * Gets the {@link Duration} for the {@linkplain - * SzAutoCoreEnvironment.Builder#getConfigRefreshPeriod() - * configuration refresh period}. - * - * @return The {@link Duration} for the {@linkplain - * SzAutoCoreEnvironment.Builder#getConfigRefreshPeriod() - * configuration refresh period}, or null - * if configuration refresh {@linkplain RefreshMode#DISABLED - * disabled}. - * + * Gets the {@link Duration} for the {@linkplain + * SzAutoCoreEnvironment.Builder#getConfigRefreshPeriod() configuration + * refresh period}. + * + * @return The {@link Duration} for the {@linkplain + * SzAutoCoreEnvironment.Builder#getConfigRefreshPeriod() + * configuration refresh period}, or null if + * configuration refresh {@linkplain RefreshMode#DISABLED disabled}. + * * @see #getConfigRefreshMode() * @see SzAutoCoreEnvironment.Builder#configRefreshPeriod(Duration) * @see SzAutoCoreEnvironment.Builder#getConfigRefreshPeriod() @@ -116,79 +112,78 @@ public interface SzAutoEnvironment extends SzEnvironment { Duration getConfigRefreshPeriod(); /** - * Performs the specified task using this instance's configured - * thread pool and internal {@link java.util.concurrent.ExecutorService} - * via {@link java.util.concurrent.ExecutorService#submit(Callable)} or - * directly executes the task in the calling thread if the thread pool - * has been disabled. - * + * Performs the specified task using this instance's configured thread pool + * and internal {@link java.util.concurrent.ExecutorService} via {@link + * java.util.concurrent.ExecutorService#submit(Callable)} or directly + * executes the task in the calling thread if the thread pool has been + * disabled. + * *

- * This returned {@link Future} will provide the result of the - * task via {@link Future#get()} upon successful completion. + * This returned {@link Future} will provide the result of the task via + * {@link Future#get()} upon successful completion. *

- * + * *

- * NOTE: Any Senzing Core SDK calls made using this + * NOTE: Any Senzing Core SDK calls made using this * {@link SzAutoEnvironment} instance will also be run in * the same thread with no additional context switching. *

- * + * * @param The return type of the task. * @param task The {@link Callable} task to perform. - * @return A {@link Future} representing the result of the - * result of the task. + * @return A {@link Future} representing the result of the result of the + * task. */ Future submitTask(Callable task); - + /** - * Performs the specified task using this instance's configured - * thread pool and internal {@link java.util.concurrent.ExecutorService} - * via {@link java.util.concurrent.ExecutorService#submit(Runnable)} or - * directly executes the task in the calling thread if the thread pool - * has been disabled. - * + * Performs the specified task using this instance's configured thread pool + * and internal {@link java.util.concurrent.ExecutorService} via {@link + * java.util.concurrent.ExecutorService#submit(Runnable)} or directly + * executes the task in the calling thread if the thread pool has been + * disabled. + * *

- * This returned {@link Future} will provide a null - * value via {@link Future#get()} upon successful completion. + * This returned {@link Future} will provide a null value via + * {@link Future#get()} upon successful completion. *

- * + * *

- * NOTE: Any Senzing Core SDK calls made using this - * {@link SzAutoEnvironment} instance will also be run in + * NOTE: Any Senzing Core SDK calls made using this + * {@link SzAutoEnvironment} instance will also be run in * the same thread with no additional context switching. *

- * + * * @param task The {@link Runnable} task to perform. - * @return A {@link Future} representing the result of the - * result of the task that will provide the value - * null upon successful completion. + * @return A {@link Future} representing the result of the result of the + * task that will provide the value null upon + * successful completion. */ Future submitTask(Runnable task); /** - * Performs the specified task using this instance's configured - * thread pool and internal {@link java.util.concurrent.ExecutorService} - * via {@link java.util.concurrent.ExecutorService#submit(Runnable, Object)} - * or directly executes the task in the calling thread if the thread pool - * has been disabled. - * + * Performs the specified task using this instance's configured thread pool + * and internal {@link java.util.concurrent.ExecutorService} via {@link + * java.util.concurrent.ExecutorService#submit(Runnable, Object)} or + * directly executes the task in the calling thread if the thread pool has + * been disabled. + * *

- * This returned {@link Future} will provide the specified result - * value via {@link Future#get()} upon successful completion. + * This returned {@link Future} will provide the specified result value via + * {@link Future#get()} upon successful completion. *

- * + * *

- * NOTE: Any Senzing Core SDK calls made using this + * NOTE: Any Senzing Core SDK calls made using this * {@link SzAutoEnvironment} instance will also be run in the * same thread with no additional context switching. *

- * + * * @param The return type of the task. * @param task The {@link Callable} task to perform. - * @param result The result to return from the returned - * {@link Future}. - * @return A {@link Future} representing the result of the - * result of the task. + * @param result The result to return from the returned {@link Future}. + * @return A {@link Future} representing the result of the result of the + * task. */ - Future submitTask(Runnable task, T result); + Future submitTask(Runnable task, T result); } diff --git a/src/main/java/com/senzing/sdk/core/auto/package-info.java b/src/main/java/com/senzing/sdk/core/auto/package-info.java index 69688f2..80882b4 100644 --- a/src/main/java/com/senzing/sdk/core/auto/package-info.java +++ b/src/main/java/com/senzing/sdk/core/auto/package-info.java @@ -1,31 +1,30 @@ /** - * This package provides the "automatic core" implementation of the - * Senzing Java SDK by extending the Senzing Core SDK implementation - * found in the {@link com.senzing.sdk.core} package. - * + * This package provides the "automatic core" implementation of the Senzing Java + * SDK by extending the Senzing Core SDK implementation found in the {@link + * com.senzing.sdk.core} package. + * *

- * The automatic core implementation adds enhancements that are - * useful when leveraging the Senzing Core SDK in a long-running - * multi-threaded sever-side process. It provides automatic - * handling of the following: + * The automatic core implementation adds enhancements that are useful when + * leveraging the Senzing Core SDK in a long-running multi-threaded sever-side + * process. It provides automatic handling of the following: *

*
    *
  • * Optional basic retry logic to retry any Senzing - * Core SDK method that fails with an {@link + * Core SDK method that fails with an {@link * com.senzing.sdk.SzRetryableException}. The method may be retried one * or more times with an increasing delay between retry * attempts. *
  • *
  • * Optional automatic configuration refresh so that the - * active configuration ID remains in sync with the + * active configuration ID remains in sync with the * current default configuration ID. *
  • *
  • * When automatic configuration refresh is enabled, this * implementation automatically refreshes the configuration - * when a Senzing Core SDK method annotated as {@link + * when a Senzing Core SDK method annotated as {@link * com.senzing.sdk.SzConfigRetryable} fails with an {@link * com.senzing.sdk.SzException}, subsequently retrying that * method if in fact the the active configuration was changed. @@ -44,12 +43,12 @@ * excessive context switching. *
  • *
- * + * *

- * Because this extends the Senzing Core SDK, it still leverages - * the underlying native libraries provided with the Senzing - * product and requires the native library path settings to be - * configured in the same way as the Senzing Core SDK. + * Because this extends the Senzing Core SDK, it still leverages the underlying + * native libraries provided with the Senzing product and requires the native + * library path settings to be configured in the same way as the Senzing Core + * SDK. *

*/ package com.senzing.sdk.core.auto; diff --git a/src/test/java/com/senzing/sdk/core/auto/AbstractAutoCoreTest.java b/src/test/java/com/senzing/sdk/core/auto/AbstractAutoCoreTest.java index 4361baf..0dc93ed 100644 --- a/src/test/java/com/senzing/sdk/core/auto/AbstractAutoCoreTest.java +++ b/src/test/java/com/senzing/sdk/core/auto/AbstractAutoCoreTest.java @@ -2,7 +2,6 @@ import java.io.File; import java.time.Duration; - import com.senzing.sdk.SzConfig; import com.senzing.sdk.SzEnvironment; import com.senzing.sdk.SzException; @@ -11,58 +10,61 @@ /** * Provides a base class for the Auto Core tests. */ -public abstract class AbstractAutoCoreTest extends AbstractCoreTest +public abstract class AbstractAutoCoreTest extends AbstractCoreTest { /** * Protected default constructor. */ - protected AbstractAutoCoreTest() { + protected AbstractAutoCoreTest() + { this(null); } - /** - * Protected constructor allowing the derived class to specify the - * location for the entity respository. + /** + * Protected constructor allowing the derived class to specify the location + * for the entity respository. * * @param repoDirectory The directory in which to include the entity * repository. */ - protected AbstractAutoCoreTest(File repoDirectory) { + protected AbstractAutoCoreTest(File repoDirectory) + { super(repoDirectory); } /** - * Gets the concurrency to use for this test suite. - * This returns null by default. - * + * Gets the concurrency to use for this test suite. This returns + * null by default. + * * @return The concurrency for this test suite. */ - protected Integer getConcurrency() { + protected Integer getConcurrency() + { return null; } /** - * Gets the configuration refresh period to use for this test suite. - * This returns null by default. - * + * Gets the configuration refresh period to use for this test suite. This + * returns null by default. + * * @return The {@link Duration} for the configuration refresh period. */ - protected Duration getConfigRefreshPeriod() { + protected Duration getConfigRefreshPeriod() + { return null; } /** - * Creates a new default config and adds the specified zero or more - * data sources to it and then returns the JSON {@link String} for that - * config. - * + * Creates a new default config and adds the specified zero or more data + * sources to it and then returns the JSON {@link String} for that config. + * * @param env The {@link SzEnvironment} to use. - * + * * @param dataSources The zero or more data sources to add to the config. - * + * * @return The JSON {@link String} that for the created config. */ - protected String createConfig(SzEnvironment env, String... dataSources) + protected String createConfig(SzEnvironment env, String... dataSources) throws SzException { SzConfig config = env.getConfigManager().createConfig(); @@ -71,5 +73,4 @@ protected String createConfig(SzEnvironment env, String... dataSources) } return config.export(); } - } diff --git a/src/test/java/com/senzing/sdk/core/auto/BasicRetryTest.java b/src/test/java/com/senzing/sdk/core/auto/BasicRetryTest.java index 17ba61e..43c865d 100644 --- a/src/test/java/com/senzing/sdk/core/auto/BasicRetryTest.java +++ b/src/test/java/com/senzing/sdk/core/auto/BasicRetryTest.java @@ -11,7 +11,6 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; - import com.senzing.sdk.SzConfig; import com.senzing.sdk.SzConfigManager; import com.senzing.sdk.SzDiagnostic; @@ -30,9 +29,7 @@ import com.senzing.sdk.test.SzRecord; import com.senzing.sdk.test.SzRecord.SzFullName; import com.senzing.sdk.test.SzRecord.SzSocialSecurity; - import static org.junit.jupiter.api.TestInstance.Lifecycle; - import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; @@ -51,10 +48,8 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.Callable; - import javax.json.JsonArray; import javax.json.JsonObject; - import static com.senzing.sdk.SzFlag.SZ_ADD_RECORD_ALL_FLAGS; import static com.senzing.sdk.SzFlag.SZ_DELETE_RECORD_ALL_FLAGS; import static com.senzing.sdk.SzFlag.SZ_ENTITY_ALL_FLAGS; @@ -85,28 +80,33 @@ @TestInstance(Lifecycle.PER_CLASS) @Execution(ExecutionMode.SAME_THREAD) @TestMethodOrder(OrderAnnotation.class) -public class BasicRetryTest extends AbstractAutoCoreTest +public class BasicRetryTest extends AbstractAutoCoreTest { - private static class MockEnvironment extends SzAutoCoreEnvironment { + private static class MockEnvironment extends SzAutoCoreEnvironment + { private static ThreadLocal> MOCK_FAILURES = new ThreadLocal<>(); - public MockEnvironment(String instanceName, String settings) { + public MockEnvironment(String instanceName, String settings) + { super(SzAutoCoreEnvironment.newAutoBuilder() .settings(settings).instanceName(instanceName) .configRefreshPeriod(REACTIVE_CONFIG_REFRESH) .concurrency(null)); } - public void clearMock() { + public void clearMock() + { MOCK_FAILURES.set(null); } - public Object mock(int retryableCount) { - return this.mock(retryableCount, 0); + public Object mock(int retryableCount) + { + return this.mock(retryableCount, 0); } - - public Object mock(int retryableCount, int otherCount) { + + public Object mock(int retryableCount, int otherCount) + { int count = retryableCount + otherCount; List list = new ArrayList<>(count); for (int index = 0; index < count; index++) { @@ -121,7 +121,8 @@ public Object mock(int retryableCount, int otherCount) { } @Override - protected T doExecute(Callable task) throws Exception + protected T doExecute(Callable task) + throws Exception { List mockFailures = MOCK_FAILURES.get(); if (mockFailures != null && mockFailures.size() > 0) { @@ -132,7 +133,6 @@ protected T doExecute(Callable task) throws Exception return super.doExecute(task); } - } /** * An empty object array. @@ -170,7 +170,7 @@ protected T doExecute(Callable task) throws Exception */ public static final SzRecordKey CUSTOMER_ABC123 = SzRecordKey.of(CUSTOMERS, ABC123); - + /** * The {@link SzRecordKey} for customer DEF456. */ @@ -182,43 +182,43 @@ protected T doExecute(Callable task) throws Exception */ public static final SzRecordKey EMPLOYEE_ABC123 = SzRecordKey.of(EMPLOYEES, ABC123); - + /** * The {@link SzRecordKey} for employee DEF456. */ public static final SzRecordKey EMPLOYEE_DEF456 = SzRecordKey.of(EMPLOYEES, DEF456); - + /** - * The record definition for the {@link #CUSTOMER_ABC123} - * and {@link #EMPLOYEE_ABC123} record keys. + * The record definition for the {@link #CUSTOMER_ABC123} and {@link + * #EMPLOYEE_ABC123} record keys. */ public static final String RECORD_ABC123 = """ - { - "NAME_FULL": "Joe Schmoe", - "HOME_PHONE_NUMBER": "702-555-1212", - "MOBILE_PHONE_NUMBER": "702-555-1313", - "ADDR_FULL": "101 Main Street, Las Vegas, NV 89101" - } - """; - + { + "NAME_FULL": "Joe Schmoe", + "HOME_PHONE_NUMBER": "702-555-1212", + "MOBILE_PHONE_NUMBER": "702-555-1313", + "ADDR_FULL": "101 Main Street, Las Vegas, NV 89101" + } + """; + /** - * The record definition for the {@link #CUSTOMER_DEF456} - * and {@link #EMPLOYEE_DEF456} record keys. + * The record definition for the {@link #CUSTOMER_DEF456} and {@link + * #EMPLOYEE_DEF456} record keys. */ public static final String RECORD_DEF456 = """ - { - "NAME_FULL": "Jane Schmoe", - "HOME_PHONE_NUMBER": "702-555-1212", - "MOBILE_PHONE_NUMBER": "702-555-1414", - "ADDR_FULL": "101 Main Street, Las Vegas, NV 89101", - "SSN_NUMBER": "888-88-8888" - } - """; - + { + "NAME_FULL": "Jane Schmoe", + "HOME_PHONE_NUMBER": "702-555-1212", + "MOBILE_PHONE_NUMBER": "702-555-1414", + "ADDR_FULL": "101 Main Street, Las Vegas, NV 89101", + "SSN_NUMBER": "888-88-8888" + } + """; + /** - * The {@link Set} of {@link SzRecord} instances to trigger - * a redo so {@link SzEngine#processRedoRecord(String)} can be tested. + * The {@link Set} of {@link SzRecord} instances to trigger a redo so {@link + * SzEngine#processRedoRecord(String)} can be tested. */ public static final Set PROCESS_REDO_TRIGGER_RECORDS = Set.of( new SzRecord( @@ -266,8 +266,9 @@ protected T doExecute(Callable task) throws Exception * A fake redo record for attempting redo pre-reinitialize. */ public static final Iterator FAKE_REDO_RECORDS; - - static { + + static + { List list = new LinkedList<>(); for (SzRecord record : PROCESS_REDO_TRIGGER_RECORDS) { SzRecordKey recordKey = record.getRecordKey(); @@ -297,8 +298,8 @@ protected T doExecute(Callable task) throws Exception private Set featureIds = null; /** - * The {@link Map} if {@link SzRecordKey} keys to {@link Long} - * entity ID values. + * The {@link Map} if {@link SzRecordKey} keys to {@link Long} entity ID + * values. */ private Map byRecordKeyLookup = null; @@ -306,38 +307,38 @@ protected T doExecute(Callable task) throws Exception * The {@link ServerSocket} with which to communicate to the sub-process. */ private ServerSocket serverSocket = null; - + /** * The socket for communicating with the sub-process. */ private Socket socket = null; /** - * The {@link ObjectInputStream} for communicating - * with the sub-process. + * The {@link ObjectInputStream} for communicating with the sub-process. */ private ObjectInputStream objInputStream = null; /** - * The {@link ObjectOutputStream} for communicating - * with the sub-process. + * The {@link ObjectOutputStream} for communicating with the sub-process. */ private ObjectOutputStream objOutputStream = null; /** * Gets the entity ID for the specified {@link SzRecordKey}. - * + * * @param key The {@link SzRecordKey} for which to lookup the entity. - * + * * @return The entity ID for the specified {@link SzRecordKey}, or * null if not found. */ - private Long getEntityId(SzRecordKey key) { + private Long getEntityId(SzRecordKey key) + { return this.byRecordKeyLookup.get(key); } @BeforeAll - public void initializeEnvironment() { + public void initializeEnvironment() + { this.beginTests(); this.initializeTestEnvironment(); String settings = this.getRepoSettings(); @@ -352,7 +353,6 @@ public void initializeEnvironment() { for (SzRecord record : PROCESS_REDO_TRIGGER_RECORDS) { engine.addRecord(record.getRecordKey(), record.toString()); } - } catch (SzException e) { fail("Failed to load record", e); } @@ -360,17 +360,16 @@ public void initializeEnvironment() { /** * Overridden to configure ONLY the {@link #EMPLOYEES} data source. - * - * @param excludeConfig + * + * @param excludeConfig */ - protected void prepareRepository() { - String settings = this.getRepoSettings(); + protected void prepareRepository() + { + String settings = this.getRepoSettings(); String instanceName = this.getInstanceName(); - SzEnvironment env = SzCoreEnvironment.newBuilder() - .instanceName(instanceName) - .settings(settings) - .build(); + SzEnvironment env = SzCoreEnvironment.newBuilder().instanceName( + instanceName).settings(settings).build(); try { StandardTestDataLoader loader = new StandardTestDataLoader(env); @@ -387,29 +386,30 @@ protected void prepareRepository() { EnumSet.allOf(SzFlag.class)); this.processNetwork(network); - - } catch (SzException e) { + } catch (SzException e) { fail("Failed to prepare repository", e); - } finally { env.destroy(); } } - private void processNetwork(String network) { + private void processNetwork(String network) + { try { - JsonObject jsonObj = parseJsonObject(network); - JsonArray jsonArr = getJsonArray(jsonObj, "ENTITIES"); + JsonObject jsonObj = parseJsonObject(network); + JsonArray jsonArr = getJsonArray(jsonObj, "ENTITIES"); - Map byRecordKeyMap = new LinkedHashMap<>(); - Set featureIds = new LinkedHashSet<>(); + Map byRecordKeyMap = new LinkedHashMap<>(); + Set featureIds = new LinkedHashSet<>(); for (JsonObject entityObj : jsonArr.getValuesAs(JsonObject.class)) { entityObj = getJsonObject(entityObj, "RESOLVED_ENTITY"); - + // get the feature ID's JsonObject features = getJsonObject(entityObj, "FEATURES"); - features.values().forEach((jsonVal) -> { + features + .values() + .forEach((jsonVal) -> { JsonArray featureArr = (JsonArray) jsonVal; for (JsonObject featureObj : featureArr.getValuesAs(JsonObject.class)) { Long featureId = getLong(featureObj, "LIB_FEAT_ID"); @@ -422,27 +422,30 @@ private void processNetwork(String network) { // get the record keys JsonArray recordArr = getJsonArray(entityObj, "RECORDS"); - for (JsonObject recordObj : recordArr.getValuesAs(JsonObject.class)) { - String dataSource = getString(recordObj, "DATA_SOURCE"); - String recordId = getString(recordObj, "RECORD_ID"); + for (JsonObject recordObj : recordArr.getValuesAs( + JsonObject.class)) { + String dataSource = getString(recordObj, "DATA_SOURCE"); + String recordId = getString(recordObj, "RECORD_ID"); if (CUSTOMERS.equals(dataSource)) { - SzRecordKey recordKey = SzRecordKey.of(dataSource, recordId); + SzRecordKey recordKey + = SzRecordKey.of(dataSource, recordId); byRecordKeyMap.put(recordKey, entityId); } } } - this.featureIds = Collections.unmodifiableSet(featureIds); - this.byRecordKeyLookup = Collections.unmodifiableMap(byRecordKeyMap); - + this.featureIds = Collections.unmodifiableSet(featureIds); + this.byRecordKeyLookup = Collections.unmodifiableMap( + byRecordKeyMap); } catch (Exception e) { fail("Failed to parse entity network: " + network, e); } } @AfterAll - public void teardownEnvironment() { + public void teardownEnvironment() + { try { try { if (this.objOutputStream != null) { @@ -490,21 +493,26 @@ public void teardownEnvironment() { } } - public interface Getter { - T get(BasicRetryTest test, Object pre) throws SzException; + public interface Getter + { + T get(BasicRetryTest test, Object pre) + throws SzException; } - public interface PreProcess { + public interface PreProcess + { Object process(BasicRetryTest test) throws SzException; } - public interface PostProcess { + public interface PostProcess + { void process(BasicRetryTest test, Object pre, Object result) throws SzException; } - private static Object[] arrayOf(Object... elems) { + private static Object[] arrayOf(Object... elems) + { return elems; } @@ -514,7 +522,8 @@ private static void addMethod(Set handledMethods, Method method, Getter paramGetter) { - addMethod(handledMethods, results, getter, method, paramGetter, null, null); + addMethod(handledMethods, results, getter, method, paramGetter, null, + null); } private static void addMethod(Set handledMethods, @@ -524,10 +533,10 @@ private static void addMethod(Set handledMethods, Getter paramGetter, PreProcess preProcess, PostProcess postProcess) - { if (handledMethods.contains(method)) return; - results.add(Arguments.of(getter, method, paramGetter, preProcess, postProcess)); + results.add(Arguments.of(getter, method, paramGetter, preProcess, + postProcess)); handledMethods.add(method); } @@ -555,7 +564,6 @@ private static void addProductMethods(Set handledMethods, method, null); } - } catch (NoSuchMethodException e) { throw new RuntimeException(e); } @@ -601,7 +609,7 @@ private static void addConfigManagerMethods(Set handledMethods, config.registerDataSource(EMPLOYEES); return arrayOf(config.export()); }); - + addMethod(handledMethods, results, (test, pre) -> test.env.getConfigManager(), @@ -613,7 +621,7 @@ private static void addConfigManagerMethods(Set handledMethods, (test, pre) -> test.env.getConfigManager(), SzConfigManager.class.getMethod("getDefaultConfigId"), EMPTY_GETTER); - + addMethod(handledMethods, results, (test, pre) -> test.env.getConfigManager(), @@ -625,7 +633,7 @@ private static void addConfigManagerMethods(Set handledMethods, (test, pre) -> test.env.getConfigManager(), SzConfigManager.class.getMethod("setDefaultConfigId", Long.TYPE), null); - + addMethod(handledMethods, results, (test, pre) -> test.env.getConfigManager(), @@ -646,11 +654,9 @@ private static void addConfigManagerMethods(Set handledMethods, method, null); } - } catch (NoSuchMethodException e) { throw new RuntimeException(e); } - } private static void addConfigMethods(Set handledMethods, @@ -663,13 +669,13 @@ private static void addConfigMethods(Set handledMethods, (test, pre) -> test.env.getConfigManager().createConfig(), SzConfig.class.getMethod("export"), EMPTY_GETTER); - + addMethod(handledMethods, results, (test, pre) -> test.env.getConfigManager().createConfig(), SzConfig.class.getMethod("getDataSourceRegistry"), EMPTY_GETTER); - + addMethod(handledMethods, results, (test, pre) -> test.env.getConfigManager().createConfig(), @@ -691,11 +697,9 @@ private static void addConfigMethods(Set handledMethods, method, null); } - } catch (NoSuchMethodException e) { throw new RuntimeException(e); } - } private static void addDiagnosticMethods(Set handledMethods, @@ -708,13 +712,13 @@ private static void addDiagnosticMethods(Set handledMethods, (test, pre) -> test.env.getDiagnostic(), SzDiagnostic.class.getMethod("getRepositoryInfo"), EMPTY_GETTER); - + addMethod(handledMethods, results, (test, pre) -> test.env.getDiagnostic(), SzDiagnostic.class.getMethod("checkRepositoryPerformance", Integer.TYPE), (test, pre) -> arrayOf(5)); - + addMethod(handledMethods, results, (test, pre) -> test.env.getDiagnostic(), @@ -735,11 +739,9 @@ private static void addDiagnosticMethods(Set handledMethods, method, null); } - } catch (NoSuchMethodException e) { throw new RuntimeException(e); } - } private static void addEngineMethods(Set handledMethods, @@ -752,13 +754,13 @@ private static void addEngineMethods(Set handledMethods, (test, pre) -> test.env.getEngine(), SzEngine.class.getMethod("primeEngine"), EMPTY_GETTER); - + addMethod(handledMethods, results, (test, pre) -> test.env.getEngine(), SzEngine.class.getMethod("getStats"), EMPTY_GETTER); - + addMethod(handledMethods, results, (test, pre) -> test.env.getEngine(), @@ -799,14 +801,14 @@ private static void addEngineMethods(Set handledMethods, results, (test, pre) -> test.env.getEngine(), SzEngine.class.getMethod("whySearch", String.class, Long.TYPE, String.class, Set.class), - (test, pre) -> arrayOf(RECORD_ABC123, test.getEntityId(CUSTOMER_DEF456), null, SZ_WHY_SEARCH_ALL_FLAGS)); + (test, pre) -> arrayOf(RECORD_ABC123, test.getEntityId(CUSTOMER_DEF456), null, SZ_WHY_SEARCH_ALL_FLAGS)); addMethod(handledMethods, results, (test, pre) -> test.env.getEngine(), SzEngine.class.getMethod("whySearch", String.class, Long.TYPE, String.class), (test, pre) -> arrayOf(RECORD_ABC123, test.getEntityId(CUSTOMER_DEF456), null)); - + addMethod(handledMethods, results, (test, pre) -> test.env.getEngine(), @@ -889,7 +891,7 @@ private static void addEngineMethods(Set handledMethods, 3, null, null)); - + addMethod(handledMethods, results, (test, pre) -> test.env.getEngine(), @@ -899,7 +901,7 @@ private static void addEngineMethods(Set handledMethods, test.getEntityId(CUSTOMER_DEF456), 3, SZ_FIND_PATH_ALL_FLAGS)); - + addMethod(handledMethods, results, (test, pre) -> test.env.getEngine(), @@ -931,7 +933,7 @@ private static void addEngineMethods(Set handledMethods, 3, null, null)); - + addMethod(handledMethods, results, (test, pre) -> test.env.getEngine(), @@ -941,7 +943,7 @@ private static void addEngineMethods(Set handledMethods, CUSTOMER_DEF456, 3, SZ_FIND_PATH_ALL_FLAGS)); - + addMethod(handledMethods, results, (test, pre) -> test.env.getEngine(), @@ -1106,13 +1108,15 @@ private static void addEngineMethods(Set handledMethods, results, (test, pre) -> test.env.getEngine(), SzEngine.class.getMethod("closeExportReport", Long.TYPE), - null); // requires a valid export handle which cannot be gotten + null); + // requires a valid export handle which cannot be gotten addMethod(handledMethods, results, (test, pre) -> test.env.getEngine(), SzEngine.class.getMethod("fetchNext", Long.TYPE), - null); // requires a valid export handle which cannot be gotten + null); + // requires a valid export handle which cannot be gotten addMethod(handledMethods, results, @@ -1195,14 +1199,13 @@ private static void addEngineMethods(Set handledMethods, method, null); } - } catch (NoSuchMethodException e) { throw new RuntimeException(e); } - } - public List getTestParameters() { + public List getTestParameters() + { List results = new LinkedList<>(); Set handledMethods = new LinkedHashSet<>(); @@ -1228,7 +1231,7 @@ public void testTooManyRetries(Getter getter, Method method, Getter paramGetter, PreProcess preProcess, - PostProcess postProcess) + PostProcess postProcess) { this.performTest(() -> { try { diff --git a/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryConfigManagerTest.java b/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryConfigManagerTest.java index 85ba6a5..1107d54 100644 --- a/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryConfigManagerTest.java +++ b/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryConfigManagerTest.java @@ -4,10 +4,8 @@ import org.junit.jupiter.api.TestMethodOrder; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; - import static org.junit.jupiter.api.MethodOrderer.OrderAnnotation; import static org.junit.jupiter.api.TestInstance.Lifecycle; - import java.time.Duration; @TestInstance(Lifecycle.PER_CLASS) @@ -17,16 +15,17 @@ public class ConcurrentRetryConfigManagerTest extends ConfigManagerTest { private static final Integer CONCURRENCY = 4; - private static final Duration DURATION = Duration.ofMillis(500); @Override - protected Integer getConcurrency() { + protected Integer getConcurrency() + { return CONCURRENCY; } @Override - protected Duration getConfigRefreshPeriod() { + protected Duration getConfigRefreshPeriod() + { return DURATION; } } diff --git a/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryConfigTest.java b/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryConfigTest.java index f59d1ef..f50d062 100644 --- a/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryConfigTest.java +++ b/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryConfigTest.java @@ -3,27 +3,26 @@ import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; - import static org.junit.jupiter.api.TestInstance.Lifecycle; - import java.time.Duration; @TestInstance(Lifecycle.PER_CLASS) @Execution(ExecutionMode.SAME_THREAD) -public class ConcurrentRetryConfigTest extends ConfigTest +public class ConcurrentRetryConfigTest extends ConfigTest { private static final Integer CONCURRENCY = 4; - private static final Duration DURATION = Duration.ofMillis(500); @Override - protected Integer getConcurrency() { + protected Integer getConcurrency() + { return CONCURRENCY; } @Override - protected Duration getConfigRefreshPeriod() { + protected Duration getConfigRefreshPeriod() + { return DURATION; } } diff --git a/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryDiagnosticTest.java b/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryDiagnosticTest.java index 856df23..d886c9d 100644 --- a/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryDiagnosticTest.java +++ b/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryDiagnosticTest.java @@ -3,27 +3,26 @@ import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; - import static org.junit.jupiter.api.TestInstance.Lifecycle; - import java.time.Duration; @TestInstance(Lifecycle.PER_CLASS) @Execution(ExecutionMode.SAME_THREAD) -public class ConcurrentRetryDiagnosticTest extends DiagnosticTest +public class ConcurrentRetryDiagnosticTest extends DiagnosticTest { private static final Integer CONCURRENCY = 4; - private static final Duration DURATION = Duration.ofMillis(500); @Override - protected Integer getConcurrency() { + protected Integer getConcurrency() + { return CONCURRENCY; } @Override - protected Duration getConfigRefreshPeriod() { + protected Duration getConfigRefreshPeriod() + { return DURATION; } } diff --git a/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryEngineBasicsTest.java b/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryEngineBasicsTest.java index 71c50d8..91403fa 100644 --- a/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryEngineBasicsTest.java +++ b/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryEngineBasicsTest.java @@ -3,9 +3,7 @@ import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; - import static org.junit.jupiter.api.TestInstance.Lifecycle; - import java.time.Duration; @TestInstance(Lifecycle.PER_CLASS) @@ -14,16 +12,17 @@ public class ConcurrentRetryEngineBasicsTest extends EngineBasicsTest { private static final Integer CONCURRENCY = 4; - private static final Duration DURATION = Duration.ofMillis(500); @Override - protected Integer getConcurrency() { + protected Integer getConcurrency() + { return CONCURRENCY; } @Override - protected Duration getConfigRefreshPeriod() { + protected Duration getConfigRefreshPeriod() + { return DURATION; } } diff --git a/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryEngineGraphTest.java b/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryEngineGraphTest.java index bd54766..747b454 100644 --- a/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryEngineGraphTest.java +++ b/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryEngineGraphTest.java @@ -3,9 +3,7 @@ import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; - import static org.junit.jupiter.api.TestInstance.Lifecycle; - import java.time.Duration; @TestInstance(Lifecycle.PER_CLASS) @@ -14,16 +12,17 @@ public class ConcurrentRetryEngineGraphTest extends EngineGraphTest { private static final Integer CONCURRENCY = 4; - private static final Duration DURATION = Duration.ofMillis(500); @Override - protected Integer getConcurrency() { + protected Integer getConcurrency() + { return CONCURRENCY; } @Override - protected Duration getConfigRefreshPeriod() { + protected Duration getConfigRefreshPeriod() + { return DURATION; } } diff --git a/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryEngineHowTest.java b/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryEngineHowTest.java index 241c3d6..18e9cc4 100644 --- a/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryEngineHowTest.java +++ b/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryEngineHowTest.java @@ -3,27 +3,26 @@ import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; - import static org.junit.jupiter.api.TestInstance.Lifecycle; - import java.time.Duration; @TestInstance(Lifecycle.PER_CLASS) @Execution(ExecutionMode.SAME_THREAD) -public class ConcurrentRetryEngineHowTest extends EngineHowTest +public class ConcurrentRetryEngineHowTest extends EngineHowTest { private static final Integer CONCURRENCY = 4; - private static final Duration DURATION = Duration.ofMillis(500); @Override - protected Integer getConcurrency() { + protected Integer getConcurrency() + { return CONCURRENCY; } @Override - protected Duration getConfigRefreshPeriod() { + protected Duration getConfigRefreshPeriod() + { return DURATION; } } diff --git a/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryEngineReadTest.java b/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryEngineReadTest.java index 0185a0f..b29d422 100644 --- a/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryEngineReadTest.java +++ b/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryEngineReadTest.java @@ -3,27 +3,26 @@ import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; - import static org.junit.jupiter.api.TestInstance.Lifecycle; - import java.time.Duration; @TestInstance(Lifecycle.PER_CLASS) @Execution(ExecutionMode.SAME_THREAD) -public class ConcurrentRetryEngineReadTest extends EngineReadTest +public class ConcurrentRetryEngineReadTest extends EngineReadTest { private static final Integer CONCURRENCY = 4; - private static final Duration DURATION = Duration.ofMillis(500); @Override - protected Integer getConcurrency() { + protected Integer getConcurrency() + { return CONCURRENCY; } @Override - protected Duration getConfigRefreshPeriod() { + protected Duration getConfigRefreshPeriod() + { return DURATION; } } diff --git a/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryEngineWhyTest.java b/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryEngineWhyTest.java index c691c1f..bc7801f 100644 --- a/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryEngineWhyTest.java +++ b/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryEngineWhyTest.java @@ -3,27 +3,26 @@ import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; - import static org.junit.jupiter.api.TestInstance.Lifecycle; - import java.time.Duration; @TestInstance(Lifecycle.PER_CLASS) @Execution(ExecutionMode.SAME_THREAD) -public class ConcurrentRetryEngineWhyTest extends EngineWhyTest +public class ConcurrentRetryEngineWhyTest extends EngineWhyTest { private static final Integer CONCURRENCY = 4; - private static final Duration DURATION = Duration.ofMillis(500); @Override - protected Integer getConcurrency() { + protected Integer getConcurrency() + { return CONCURRENCY; } @Override - protected Duration getConfigRefreshPeriod() { + protected Duration getConfigRefreshPeriod() + { return DURATION; } } diff --git a/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryEngineWriteTest.java b/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryEngineWriteTest.java index 51af29a..ae667f5 100644 --- a/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryEngineWriteTest.java +++ b/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryEngineWriteTest.java @@ -3,27 +3,26 @@ import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; - import static org.junit.jupiter.api.TestInstance.Lifecycle; - import java.time.Duration; @TestInstance(Lifecycle.PER_CLASS) @Execution(ExecutionMode.SAME_THREAD) -public class ConcurrentRetryEngineWriteTest extends EngineWriteTest +public class ConcurrentRetryEngineWriteTest extends EngineWriteTest { private static final Integer CONCURRENCY = 4; - private static final Duration DURATION = Duration.ofMillis(500); @Override - protected Integer getConcurrency() { + protected Integer getConcurrency() + { return CONCURRENCY; } @Override - protected Duration getConfigRefreshPeriod() { + protected Duration getConfigRefreshPeriod() + { return DURATION; } } diff --git a/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryProductTest.java b/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryProductTest.java index 5bf6821..a82a378 100644 --- a/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryProductTest.java +++ b/src/test/java/com/senzing/sdk/core/auto/ConcurrentRetryProductTest.java @@ -3,9 +3,7 @@ import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; - import static org.junit.jupiter.api.TestInstance.Lifecycle; - import java.time.Duration; @TestInstance(Lifecycle.PER_CLASS) @@ -14,16 +12,17 @@ public class ConcurrentRetryProductTest extends ProductTest { private static final Integer CONCURRENCY = 4; - private static final Duration DURATION = Duration.ofMillis(500); @Override - protected Integer getConcurrency() { + protected Integer getConcurrency() + { return CONCURRENCY; } @Override - protected Duration getConfigRefreshPeriod() { + protected Duration getConfigRefreshPeriod() + { return DURATION; } } diff --git a/src/test/java/com/senzing/sdk/core/auto/ConfigManagerTest.java b/src/test/java/com/senzing/sdk/core/auto/ConfigManagerTest.java index 9731b96..2517f84 100644 --- a/src/test/java/com/senzing/sdk/core/auto/ConfigManagerTest.java +++ b/src/test/java/com/senzing/sdk/core/auto/ConfigManagerTest.java @@ -6,75 +6,69 @@ import org.junit.jupiter.api.TestMethodOrder; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; - import com.senzing.sdk.SzException; import com.senzing.sdk.SzConfigManager; import com.senzing.sdk.SzEnvironment; import com.senzing.sdk.test.StandardTestConfigurator; import com.senzing.sdk.test.SzConfigManagerTest; import com.senzing.sdk.core.SzCoreEnvironment; - import static org.junit.jupiter.api.MethodOrderer.OrderAnnotation; import static org.junit.jupiter.api.TestInstance.Lifecycle; @TestInstance(Lifecycle.PER_CLASS) @Execution(ExecutionMode.SAME_THREAD) @TestMethodOrder(OrderAnnotation.class) -public class ConfigManagerTest - extends AbstractAutoCoreTest - implements SzConfigManagerTest +public class ConfigManagerTest + extends AbstractAutoCoreTest implements SzConfigManagerTest { private SzAutoCoreEnvironment env = null; private TestData testData = new TestData(); @Override - public SzConfigManager getConfigManager() throws SzException { + public SzConfigManager getConfigManager() + throws SzException + { return this.env.getConfigManager(); } - @Override - public TestData getTestData() { + @Override + public TestData getTestData() + { return this.testData; } @BeforeAll - public void initializeEnvironment() { + public void initializeEnvironment() + { this.beginTests(); this.initializeTestEnvironment(true); String settings = this.getRepoSettings(); - + String instanceName = this.getClass().getSimpleName(); - - SzEnvironment env = SzCoreEnvironment.newBuilder() - .instanceName(instanceName) - .settings(settings) - .verboseLogging(false) - .build(); + SzEnvironment env = SzCoreEnvironment.newBuilder().instanceName( + instanceName).settings(settings).verboseLogging(false).build(); try { StandardTestConfigurator configurator = new StandardTestConfigurator(env); this.testData.setup(configurator); - } finally { env.destroy(); } - this.env = SzAutoCoreEnvironment.newAutoBuilder() - .instanceName(instanceName) - .settings(settings) - .verboseLogging(false) - .concurrency(this.getConcurrency()) - .configRefreshPeriod(this.getConfigRefreshPeriod()) - .build(); + this.env = SzAutoCoreEnvironment.newAutoBuilder().instanceName( + instanceName).settings(settings).verboseLogging(false).concurrency( + this.getConcurrency()).configRefreshPeriod( + this.getConfigRefreshPeriod()).build(); } @AfterAll - public void teardownEnvironment() { + public void teardownEnvironment() + { try { if (this.env != null) { this.env.destroy(); diff --git a/src/test/java/com/senzing/sdk/core/auto/ConfigRetryTest.java b/src/test/java/com/senzing/sdk/core/auto/ConfigRetryTest.java index c4da8b5..4fda15d 100644 --- a/src/test/java/com/senzing/sdk/core/auto/ConfigRetryTest.java +++ b/src/test/java/com/senzing/sdk/core/auto/ConfigRetryTest.java @@ -10,7 +10,6 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; - import com.senzing.io.IOUtilities; import com.senzing.sdk.SzConfig; import com.senzing.sdk.SzConfigManager; @@ -31,9 +30,7 @@ import com.senzing.sdk.test.SzRecord; import com.senzing.sdk.test.SzRecord.SzFullName; import com.senzing.sdk.test.SzRecord.SzSocialSecurity; - import static org.junit.jupiter.api.TestInstance.Lifecycle; - import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -56,10 +53,8 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.Callable; - import javax.json.JsonArray; import javax.json.JsonObject; - import static com.senzing.io.IOUtilities.UTF_8; import static com.senzing.sdk.SzFlag.SZ_ADD_RECORD_ALL_FLAGS; import static com.senzing.sdk.SzFlag.SZ_DELETE_RECORD_ALL_FLAGS; @@ -90,34 +85,36 @@ @TestInstance(Lifecycle.PER_CLASS) @Execution(ExecutionMode.SAME_THREAD) @TestMethodOrder(OrderAnnotation.class) -public class ConfigRetryTest extends AbstractAutoCoreTest +public class ConfigRetryTest extends AbstractAutoCoreTest { - private static class MockEnvironment extends SzAutoCoreEnvironment { - private static ThreadLocal MOCK_FAILURE = new ThreadLocal<>(); + private static class MockEnvironment extends SzAutoCoreEnvironment + { + private static ThreadLocal MOCK_FAILURE + = new ThreadLocal<>(); - public MockEnvironment(String instanceName, String settings) { + public MockEnvironment(String instanceName, String settings) + { super(SzAutoCoreEnvironment.newAutoBuilder() .settings(settings).instanceName(instanceName) .configRefreshPeriod(REACTIVE_CONFIG_REFRESH)); } - public Object mock(SzException e) { + public Object mock(SzException e) + { MOCK_FAILURE.set(e); return null; } @Override - protected T doExecute(Callable task) throws Exception + protected T doExecute(Callable task) + throws Exception { SzException mockFailure = MOCK_FAILURE.get(); MOCK_FAILURE.set(null); - if (mockFailure != null) { - throw mockFailure; - } + if (mockFailure != null) throw mockFailure; return super.doExecute(task); } - } /** * An empty object array. @@ -155,7 +152,7 @@ protected T doExecute(Callable task) throws Exception */ public static final SzRecordKey CUSTOMER_ABC123 = SzRecordKey.of(CUSTOMERS, ABC123); - + /** * The {@link SzRecordKey} for customer DEF456. */ @@ -167,43 +164,43 @@ protected T doExecute(Callable task) throws Exception */ public static final SzRecordKey EMPLOYEE_ABC123 = SzRecordKey.of(EMPLOYEES, ABC123); - + /** * The {@link SzRecordKey} for employee DEF456. */ public static final SzRecordKey EMPLOYEE_DEF456 = SzRecordKey.of(EMPLOYEES, DEF456); - + /** - * The record definition for the {@link #CUSTOMER_ABC123} - * and {@link #EMPLOYEE_ABC123} record keys. + * The record definition for the {@link #CUSTOMER_ABC123} and {@link + * #EMPLOYEE_ABC123} record keys. */ public static final String RECORD_ABC123 = """ - { - "NAME_FULL": "Joe Schmoe", - "HOME_PHONE_NUMBER": "702-555-1212", - "MOBILE_PHONE_NUMBER": "702-555-1313", - "ADDR_FULL": "101 Main Street, Las Vegas, NV 89101" - } - """; - + { + "NAME_FULL": "Joe Schmoe", + "HOME_PHONE_NUMBER": "702-555-1212", + "MOBILE_PHONE_NUMBER": "702-555-1313", + "ADDR_FULL": "101 Main Street, Las Vegas, NV 89101" + } + """; + /** - * The record definition for the {@link #CUSTOMER_DEF456} - * and {@link #EMPLOYEE_DEF456} record keys. + * The record definition for the {@link #CUSTOMER_DEF456} and {@link + * #EMPLOYEE_DEF456} record keys. */ public static final String RECORD_DEF456 = """ - { - "NAME_FULL": "Jane Schmoe", - "HOME_PHONE_NUMBER": "702-555-1212", - "MOBILE_PHONE_NUMBER": "702-555-1414", - "ADDR_FULL": "101 Main Street, Las Vegas, NV 89101", - "SSN_NUMBER": "888-88-8888" - } - """; - + { + "NAME_FULL": "Jane Schmoe", + "HOME_PHONE_NUMBER": "702-555-1212", + "MOBILE_PHONE_NUMBER": "702-555-1414", + "ADDR_FULL": "101 Main Street, Las Vegas, NV 89101", + "SSN_NUMBER": "888-88-8888" + } + """; + /** - * The {@link Set} of {@link SzRecord} instances to trigger - * a redo so {@link SzEngine#processRedoRecord(String)} can be tested. + * The {@link Set} of {@link SzRecord} instances to trigger a redo so {@link + * SzEngine#processRedoRecord(String)} can be tested. */ public static final Set PROCESS_REDO_TRIGGER_RECORDS = Set.of( new SzRecord( @@ -251,8 +248,9 @@ protected T doExecute(Callable task) throws Exception * A fake redo record for attempting redo pre-reinitialize. */ public static final Iterator FAKE_REDO_RECORDS; - - static { + + static + { List list = new LinkedList<>(); for (SzRecord record : PROCESS_REDO_TRIGGER_RECORDS) { SzRecordKey recordKey = record.getRecordKey(); @@ -282,8 +280,8 @@ protected T doExecute(Callable task) throws Exception private Set featureIds = null; /** - * The {@link Map} if {@link SzRecordKey} keys to {@link Long} - * entity ID values. + * The {@link Map} if {@link SzRecordKey} keys to {@link Long} entity ID + * values. */ private Map byRecordKeyLookup = null; @@ -291,21 +289,19 @@ protected T doExecute(Callable task) throws Exception * The {@link ServerSocket} with which to communicate to the sub-process. */ private ServerSocket serverSocket = null; - + /** * The socket for communicating with the sub-process. */ private Socket socket = null; /** - * The {@link ObjectInputStream} for communicating - * with the sub-process. + * The {@link ObjectInputStream} for communicating with the sub-process. */ private ObjectInputStream objInputStream = null; /** - * The {@link ObjectOutputStream} for communicating - * with the sub-process. + * The {@link ObjectOutputStream} for communicating with the sub-process. */ private ObjectOutputStream objOutputStream = null; @@ -316,48 +312,53 @@ protected T doExecute(Callable task) throws Exception /** * Gets the entity ID for the specified {@link SzRecordKey}. - * + * * @param key The {@link SzRecordKey} for which to lookup the entity. - * + * * @return The entity ID for the specified {@link SzRecordKey}, or * null if not found. */ - private Long getEntityId(SzRecordKey key) { + private Long getEntityId(SzRecordKey key) + { return this.byRecordKeyLookup.get(key); } /** * Increments the iteration and returns the incremented value. - * + * * @return The incremented iteration value. */ - private synchronized int incrementIteration() { + private synchronized int incrementIteration() + { return (++this.iteration); } /** * Gets the current iteration. - * + * * @return The current iteration. */ - private synchronized int getIteration() { + private synchronized int getIteration() + { return this.iteration; } /** - * Creates and returns an {@link SzRecordKey} for the specified - * record ID and the current data source iteration. - * - * @return The {@link SzRecordKey} for the specified record ID - * and the current data source iteration. + * Creates and returns an {@link SzRecordKey} for the specified record ID + * and the current data source iteration. + * + * @return The {@link SzRecordKey} for the specified record ID and the + * current data source iteration. */ - private synchronized SzRecordKey getRecordKey(String recordId) { + private synchronized SzRecordKey getRecordKey(String recordId) + { String dataSource = CUSTOMERS + "-" + this.getIteration(); return SzRecordKey.of(dataSource, recordId); } @BeforeAll - public void initializeEnvironment() { + public void initializeEnvironment() + { this.beginTests(); this.initializeTestEnvironment(); String settings = this.getRepoSettings(); @@ -372,28 +373,26 @@ public void initializeEnvironment() { for (SzRecord record : PROCESS_REDO_TRIGGER_RECORDS) { engine.addRecord(record.getRecordKey(), record.toString()); } - } catch (SzException e) { fail("Failed to load record", e); } - + // change config and load data in a sub-process this.executeSubProcess(); } /** * Overridden to configure ONLY the {@link #EMPLOYEES} data source. - * - * @param excludeConfig + * + * @param excludeConfig */ - protected void prepareRepository() { - String settings = this.getRepoSettings(); + protected void prepareRepository() + { + String settings = this.getRepoSettings(); String instanceName = this.getInstanceName(); - SzEnvironment env = SzCoreEnvironment.newBuilder() - .instanceName(instanceName) - .settings(settings) - .build(); + SzEnvironment env = SzCoreEnvironment.newBuilder().instanceName( + instanceName).settings(settings).build(); try { StandardTestDataLoader loader = new StandardTestDataLoader(env); @@ -404,23 +403,27 @@ protected void prepareRepository() { } /** - * Executes a sub-process that will add a data source to the config - * and load two records to that data source and then wait for that - * process to commplete. + * Executes a sub-process that will add a data source to the config and load + * two records to that data source and then wait for that process to + * commplete. */ - private void executeSubProcess() { + private void executeSubProcess() + { try { // setup the server socket - this.serverSocket = new ServerSocket(0, 20, InetAddress.getLoopbackAddress()); + this.serverSocket = new ServerSocket( + 0, + 20, + InetAddress.getLoopbackAddress()); File repoDirectory = this.getRepositoryDirectory(); File initFile = new File(repoDirectory, "sz-init.json"); - + String buildDirProp = System.getProperty("project.build.directory"); - File buildDir = new File(buildDirProp); - File wrapperDir = new File(buildDir, "java-wrapper"); - File binDir = new File(wrapperDir, "bin"); - File wrapper = new File(binDir, "java-wrapper.bat"); + File buildDir = new File(buildDirProp); + File wrapperDir = new File(buildDir, "java-wrapper"); + File binDir = new File(wrapperDir, "bin"); + File wrapper = new File(binDir, "java-wrapper.bat"); String[] cmdArray = new String[] { wrapper.getCanonicalPath(), @@ -441,33 +444,37 @@ private void executeSubProcess() { if (!process.isAlive()) { int exitCode = process.exitValue(); - fail("Failed to launch alternate process to update config: " + exitCode); + fail("Failed to launch alternate process to update config: " + + exitCode); } this.socket = this.serverSocket.accept(); - this.objOutputStream = new ObjectOutputStream(this.socket.getOutputStream()); - this.objInputStream = new ObjectInputStream(this.socket.getInputStream()); - - } catch (InterruptedException|IOException e) { + this.objOutputStream = new ObjectOutputStream( + this.socket.getOutputStream()); + this.objInputStream = new ObjectInputStream( + this.socket.getInputStream()); + } catch (InterruptedException | IOException e) { throw new RuntimeException(e); } - } - private void processNetwork(String network) { + private void processNetwork(String network) + { try { - JsonObject jsonObj = parseJsonObject(network); - JsonArray jsonArr = getJsonArray(jsonObj, "ENTITIES"); + JsonObject jsonObj = parseJsonObject(network); + JsonArray jsonArr = getJsonArray(jsonObj, "ENTITIES"); - Map byRecordKeyMap = new LinkedHashMap<>(); - Set featureIds = new LinkedHashSet<>(); + Map byRecordKeyMap = new LinkedHashMap<>(); + Set featureIds = new LinkedHashSet<>(); for (JsonObject entityObj : jsonArr.getValuesAs(JsonObject.class)) { entityObj = getJsonObject(entityObj, "RESOLVED_ENTITY"); - + // get the feature ID's JsonObject features = getJsonObject(entityObj, "FEATURES"); - features.values().forEach((jsonVal) -> { + features + .values() + .forEach((jsonVal) -> { JsonArray featureArr = (JsonArray) jsonVal; for (JsonObject featureObj : featureArr.getValuesAs(JsonObject.class)) { Long featureId = getLong(featureObj, "LIB_FEAT_ID"); @@ -480,27 +487,30 @@ private void processNetwork(String network) { // get the record keys JsonArray recordArr = getJsonArray(entityObj, "RECORDS"); - for (JsonObject recordObj : recordArr.getValuesAs(JsonObject.class)) { - String dataSource = getString(recordObj, "DATA_SOURCE"); - String recordId = getString(recordObj, "RECORD_ID"); + for (JsonObject recordObj : recordArr.getValuesAs( + JsonObject.class)) { + String dataSource = getString(recordObj, "DATA_SOURCE"); + String recordId = getString(recordObj, "RECORD_ID"); if (CUSTOMERS.equals(dataSource)) { - SzRecordKey recordKey = SzRecordKey.of(dataSource, recordId); + SzRecordKey recordKey + = SzRecordKey.of(dataSource, recordId); byRecordKeyMap.put(recordKey, entityId); } } } - this.featureIds = Collections.unmodifiableSet(featureIds); - this.byRecordKeyLookup = Collections.unmodifiableMap(byRecordKeyMap); - + this.featureIds = Collections.unmodifiableSet(featureIds); + this.byRecordKeyLookup = Collections.unmodifiableMap( + byRecordKeyMap); } catch (Exception e) { fail("Failed to parse entity network: " + network, e); } } @AfterAll - public void teardownEnvironment() { + public void teardownEnvironment() + { try { try { if (this.objOutputStream != null) { @@ -548,21 +558,26 @@ public void teardownEnvironment() { } } - public interface Getter { - T get(ConfigRetryTest test, Object pre) throws SzException; + public interface Getter + { + T get(ConfigRetryTest test, Object pre) + throws SzException; } - public interface PreProcess { + public interface PreProcess + { Object process(ConfigRetryTest test) throws SzException; } - public interface PostProcess { + public interface PostProcess + { void process(ConfigRetryTest test, Object pre, Object result) throws SzException; } - private static Object[] arrayOf(Object... elems) { + private static Object[] arrayOf(Object... elems) + { return elems; } @@ -573,7 +588,8 @@ private static void addMethod(Set handledMethods, Boolean expectRetryable, Getter paramGetter) { - addMethod(handledMethods, results, getter, method, expectRetryable, paramGetter, null, null); + addMethod(handledMethods, results, getter, method, expectRetryable, + paramGetter, null, null); } private static void addMethod(Set handledMethods, @@ -584,10 +600,10 @@ private static void addMethod(Set handledMethods, Getter paramGetter, PreProcess preProcess, PostProcess postProcess) - { if (handledMethods.contains(method)) return; - results.add(Arguments.of(getter, method, expectRetryable, paramGetter, preProcess, postProcess)); + results.add(Arguments.of(getter, method, expectRetryable, paramGetter, + preProcess, postProcess)); handledMethods.add(method); } @@ -618,7 +634,6 @@ private static void addProductMethods(Set handledMethods, null, null); } - } catch (NoSuchMethodException e) { throw new RuntimeException(e); } @@ -669,7 +684,7 @@ private static void addConfigManagerMethods(Set handledMethods, config.registerDataSource(EMPLOYEES); return arrayOf(config.export()); }); - + addMethod(handledMethods, results, (test, pre) -> test.env.getConfigManager(), @@ -683,7 +698,7 @@ private static void addConfigManagerMethods(Set handledMethods, SzConfigManager.class.getMethod("getDefaultConfigId"), Boolean.FALSE, EMPTY_GETTER); - + addMethod(handledMethods, results, (test, pre) -> test.env.getConfigManager(), @@ -697,7 +712,7 @@ private static void addConfigManagerMethods(Set handledMethods, SzConfigManager.class.getMethod("setDefaultConfigId", Long.TYPE), Boolean.FALSE, null); - + addMethod(handledMethods, results, (test, pre) -> test.env.getConfigManager(), @@ -721,11 +736,9 @@ private static void addConfigManagerMethods(Set handledMethods, null, null); } - } catch (NoSuchMethodException e) { throw new RuntimeException(e); } - } private static void addConfigMethods(Set handledMethods, @@ -739,14 +752,14 @@ private static void addConfigMethods(Set handledMethods, SzConfig.class.getMethod("export"), Boolean.FALSE, EMPTY_GETTER); - + addMethod(handledMethods, results, (test, pre) -> test.env.getConfigManager().createConfig(), SzConfig.class.getMethod("getDataSourceRegistry"), Boolean.FALSE, EMPTY_GETTER); - + addMethod(handledMethods, results, (test, pre) -> test.env.getConfigManager().createConfig(), @@ -771,11 +784,9 @@ private static void addConfigMethods(Set handledMethods, null, null); } - } catch (NoSuchMethodException e) { throw new RuntimeException(e); } - } private static void addDiagnosticMethods(Set handledMethods, @@ -789,14 +800,14 @@ private static void addDiagnosticMethods(Set handledMethods, SzDiagnostic.class.getMethod("getRepositoryInfo"), Boolean.FALSE, EMPTY_GETTER); - + addMethod(handledMethods, results, (test, pre) -> test.env.getDiagnostic(), SzDiagnostic.class.getMethod("checkRepositoryPerformance", Integer.TYPE), Boolean.FALSE, (test, pre) -> arrayOf(5)); - + addMethod(handledMethods, results, (test, pre) -> test.env.getDiagnostic(), @@ -822,11 +833,9 @@ private static void addDiagnosticMethods(Set handledMethods, null, null); } - } catch (NoSuchMethodException e) { throw new RuntimeException(e); } - } private static void addEngineMethods(Set handledMethods, @@ -840,14 +849,14 @@ private static void addEngineMethods(Set handledMethods, SzEngine.class.getMethod("primeEngine"), Boolean.FALSE, EMPTY_GETTER); - + addMethod(handledMethods, results, (test, pre) -> test.env.getEngine(), SzEngine.class.getMethod("getStats"), Boolean.FALSE, EMPTY_GETTER); - + addMethod(handledMethods, results, (test, pre) -> test.env.getEngine(), @@ -902,7 +911,6 @@ private static void addEngineMethods(Set handledMethods, (test, pre) -> arrayOf(RECORD_ABC123, test.getEntityId(CUSTOMER_DEF456), null, SZ_WHY_SEARCH_ALL_FLAGS), (test) -> test.env.mock(new SzConfigurationException("mock")), null); - addMethod(handledMethods, results, @@ -912,7 +920,7 @@ private static void addEngineMethods(Set handledMethods, (test, pre) -> arrayOf(RECORD_ABC123, test.getEntityId(CUSTOMER_DEF456), null), (test) -> test.env.mock(new SzConfigurationException("mock")), null); - + addMethod(handledMethods, results, (test, pre) -> test.env.getEngine(), @@ -1015,7 +1023,7 @@ private static void addEngineMethods(Set handledMethods, 3, null, null)); - + addMethod(handledMethods, results, (test, pre) -> test.env.getEngine(), @@ -1026,7 +1034,7 @@ private static void addEngineMethods(Set handledMethods, test.getEntityId(CUSTOMER_DEF456), 3, SZ_FIND_PATH_ALL_FLAGS)); - + addMethod(handledMethods, results, (test, pre) -> test.env.getEngine(), @@ -1061,7 +1069,7 @@ private static void addEngineMethods(Set handledMethods, 3, null, null)); - + addMethod(handledMethods, results, (test, pre) -> test.env.getEngine(), @@ -1072,7 +1080,7 @@ private static void addEngineMethods(Set handledMethods, CUSTOMER_DEF456, 3, SZ_FIND_PATH_ALL_FLAGS)); - + addMethod(handledMethods, results, (test, pre) -> test.env.getEngine(), @@ -1263,14 +1271,16 @@ private static void addEngineMethods(Set handledMethods, (test, pre) -> test.env.getEngine(), SzEngine.class.getMethod("closeExportReport", Long.TYPE), Boolean.FALSE, - null); // requires a valid export handle which cannot be gotten + null); + // requires a valid export handle which cannot be gotten addMethod(handledMethods, results, (test, pre) -> test.env.getEngine(), SzEngine.class.getMethod("fetchNext", Long.TYPE), Boolean.TRUE, - null); // requires a valid export handle which cannot be gotten + null); + // requires a valid export handle which cannot be gotten addMethod(handledMethods, results, @@ -1344,7 +1354,6 @@ private static void addEngineMethods(Set handledMethods, (test) -> test.env.mock(new SzConfigurationException("mock")), null); - addMethod(handledMethods, results, (test, pre) -> test.env.getEngine(), @@ -1354,7 +1363,6 @@ private static void addEngineMethods(Set handledMethods, (test) -> test.env.mock(new SzConfigurationException("mock")), null); - addMethod(handledMethods, results, (test, pre) -> test.env.getEngine(), @@ -1378,14 +1386,13 @@ private static void addEngineMethods(Set handledMethods, null, null); } - } catch (NoSuchMethodException e) { throw new RuntimeException(e); } - } - public List getTestParameters() { + public List getTestParameters() + { List results = new LinkedList<>(); Set handledMethods = new LinkedHashSet<>(); @@ -1411,7 +1418,7 @@ public void testConfigRetryMethod(Getter getter, Boolean expectRetryable, Getter paramGetter, PreProcess preProcess, - PostProcess postProcess) + PostProcess postProcess) { this.performTest(() -> { try { @@ -1490,37 +1497,41 @@ public void testConfigRetryMethod(Getter getter, } /** - * Provides the main for the second process that changes the - * config and loads records. The path to the repository's - * initialization file is the expected command-line argument - * and the path to the output file. - * - * + * Provides the main for the second process that changes the config and + * loads records. The path to the repository's initialization file is the + * expected command-line argument and the path to the output file. + * + * * @param args The command-line arguments. */ - public static void main(String[] args) { + public static void main(String[] args) + { SzEnvironment env = null; try { if (args.length < 2) { - System.err.println("Must specify the following command-line arguments:"); - System.err.println(" 1: Path to setting JSON file for the repository"); + System.err.println( + "Must specify the following command-line arguments:"); + System.err.println( + " 1: Path to setting JSON file for the repository"); System.err.println(" 2: The port to connect to"); System.exit(1); } - String initFilePath = args[0]; - int port = 0; - File initFile = new File(initFilePath); - + String initFilePath = args[0]; + int port = 0; + File initFile = new File(initFilePath); + try { port = Integer.parseInt(args[1]); } catch (Exception e) { - System.err.println("The specifid port number is not an integer: " + args[1]); + System.err.println( + "The specifid port number is not an integer: " + args[1]); System.exit(1); } if (!initFile.exists()) { - System.err.println("Settings file does not exist: " + initFilePath); + System.err.println("Settings file does not exist: " + + initFilePath); System.exit(1); } @@ -1533,27 +1544,35 @@ public static void main(String[] args) { SzConfigManager configMgr = env.getConfigManager(); - try (Socket socket = new Socket(InetAddress.getLoopbackAddress(), port); - ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); - ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream())) + try (Socket socket + = new Socket(InetAddress.getLoopbackAddress(), port); + ObjectInputStream ois + = new ObjectInputStream(socket.getInputStream()); + ObjectOutputStream oos + = new ObjectOutputStream(socket.getOutputStream())) { for (Integer iteration = (Integer) ois.readObject(); iteration != null; - iteration = (Integer) ois.readObject()) + iteration = (Integer) ois.readObject()) { String dataSource = CUSTOMERS; if (iteration > 0) { dataSource = dataSource + "-" + iteration; } - SzConfig config = configMgr.createConfig(configMgr.getDefaultConfigId()); + SzConfig config = configMgr.createConfig( + configMgr.getDefaultConfigId()); config.registerDataSource(dataSource); long configId = configMgr.setDefaultConfig(config.export()); env.reinitialize(configId); SzEngine engine = env.getEngine(); - SzRecordKey recordKey1 = SzRecordKey.of(dataSource, EMPLOYEE_ABC123.recordId()); - SzRecordKey recordKey2 = SzRecordKey.of(dataSource, EMPLOYEE_DEF456.recordId()); + SzRecordKey recordKey1 = SzRecordKey.of( + dataSource, + EMPLOYEE_ABC123.recordId()); + SzRecordKey recordKey2 = SzRecordKey.of( + dataSource, + EMPLOYEE_DEF456.recordId()); engine.addRecord(recordKey1, RECORD_ABC123); engine.addRecord(recordKey2, RECORD_DEF456); @@ -1562,22 +1581,20 @@ public static void main(String[] args) { SzRecordKeys.of(recordKey1, recordKey2), 2, 0, 0, EnumSet.allOf(SzFlag.class)); - - + oos.writeObject(network); oos.flush(); } } - } catch (Exception e) { - String buildDirProp = System.getProperty("project.build.directory"); - File buildDir = new File(buildDirProp); - String className = ConfigRetryTest.class.getSimpleName(); - String outFileName = className + "-errors.txt"; - File outFile = new File(buildDir, outFileName); - try (FileOutputStream fos = new FileOutputStream(outFile); + String buildDirProp = System.getProperty("project.build.directory"); + File buildDir = new File(buildDirProp); + String className = ConfigRetryTest.class.getSimpleName(); + String outFileName = className + "-errors.txt"; + File outFile = new File(buildDir, outFileName); + try (FileOutputStream fos = new FileOutputStream(outFile); OutputStreamWriter osw = new OutputStreamWriter(fos, UTF_8); - PrintWriter pw = new PrintWriter(osw)) + PrintWriter pw = new PrintWriter(osw)) { for (int index = 0; index < args.length; index++) { pw.println("ARG " + index + ": " + args[index]); @@ -1585,14 +1602,12 @@ public static void main(String[] args) { pw.println(); e.printStackTrace(pw); pw.flush(); - } catch (IOException e2) { e2.printStackTrace(); } e.printStackTrace(); System.exit(1); - } finally { if (env != null) { env.destroy(); diff --git a/src/test/java/com/senzing/sdk/core/auto/ConfigTest.java b/src/test/java/com/senzing/sdk/core/auto/ConfigTest.java index 568e2cf..ad67978 100644 --- a/src/test/java/com/senzing/sdk/core/auto/ConfigTest.java +++ b/src/test/java/com/senzing/sdk/core/auto/ConfigTest.java @@ -5,71 +5,65 @@ import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; - import com.senzing.sdk.SzConfigManager; import com.senzing.sdk.SzEnvironment; import com.senzing.sdk.SzException; import com.senzing.sdk.test.StandardTestConfigurator; import com.senzing.sdk.test.SzConfigTest; import com.senzing.sdk.core.SzCoreEnvironment; - import static org.junit.jupiter.api.TestInstance.Lifecycle; @TestInstance(Lifecycle.PER_CLASS) @Execution(ExecutionMode.SAME_THREAD) -public class ConfigTest - extends AbstractAutoCoreTest - implements SzConfigTest +public class ConfigTest extends AbstractAutoCoreTest implements SzConfigTest { private SzAutoCoreEnvironment env = null; private TestData testData = new TestData(); @Override - public SzConfigManager getConfigManager() throws SzException { + public SzConfigManager getConfigManager() + throws SzException + { return this.env.getConfigManager(); } - @Override - public TestData getTestData() { + @Override + public TestData getTestData() + { return this.testData; } @BeforeAll - public void initializeEnvironment() { + public void initializeEnvironment() + { this.beginTests(); this.initializeTestEnvironment(); String settings = this.getRepoSettings(); - + String instanceName = this.getClass().getSimpleName(); - SzEnvironment env = SzCoreEnvironment.newBuilder() - .instanceName(instanceName) - .settings(settings) - .verboseLogging(false) - .build(); + SzEnvironment env = SzCoreEnvironment.newBuilder().instanceName( + instanceName).settings(settings).verboseLogging(false).build(); try { StandardTestConfigurator configurator = new StandardTestConfigurator(env); this.testData.setup(configurator); - } finally { env.destroy(); } - this.env = SzAutoCoreEnvironment.newAutoBuilder() - .instanceName(instanceName) - .settings(settings) - .verboseLogging(false) - .concurrency(this.getConcurrency()) - .configRefreshPeriod(this.getConfigRefreshPeriod()) - .build(); + this.env = SzAutoCoreEnvironment.newAutoBuilder().instanceName( + instanceName).settings(settings).verboseLogging(false).concurrency( + this.getConcurrency()).configRefreshPeriod( + this.getConfigRefreshPeriod()).build(); } @AfterAll - public void teardownEnvironment() { + public void teardownEnvironment() + { try { if (this.env != null) { this.env.destroy(); @@ -78,6 +72,6 @@ public void teardownEnvironment() { this.teardownTestEnvironment(); } finally { this.endTests(); - } + } } } diff --git a/src/test/java/com/senzing/sdk/core/auto/DiagnosticTest.java b/src/test/java/com/senzing/sdk/core/auto/DiagnosticTest.java index 8afef9b..173896a 100644 --- a/src/test/java/com/senzing/sdk/core/auto/DiagnosticTest.java +++ b/src/test/java/com/senzing/sdk/core/auto/DiagnosticTest.java @@ -6,83 +6,79 @@ import org.junit.jupiter.api.TestMethodOrder; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; - import com.senzing.sdk.SzException; import com.senzing.sdk.core.SzCoreEnvironment; import com.senzing.sdk.test.StandardTestDataLoader; import com.senzing.sdk.test.SzDiagnosticTest; import com.senzing.sdk.test.TestDataLoader; import com.senzing.sdk.SzDiagnostic; - import static org.junit.jupiter.api.MethodOrderer.OrderAnnotation; import static org.junit.jupiter.api.TestInstance.Lifecycle; /** * Unit tests for {@link SzCoreDiagnostic}. */ - @TestInstance(Lifecycle.PER_CLASS) - @Execution(ExecutionMode.SAME_THREAD) - @TestMethodOrder(OrderAnnotation.class) - public class DiagnosticTest - extends AbstractAutoCoreTest - implements SzDiagnosticTest +@TestInstance(Lifecycle.PER_CLASS) +@Execution(ExecutionMode.SAME_THREAD) +@TestMethodOrder(OrderAnnotation.class) +public class DiagnosticTest + extends AbstractAutoCoreTest implements SzDiagnosticTest { private SzAutoCoreEnvironment env = null; private TestData testData = new TestData(); @Override - public SzDiagnostic getDiagnostic() throws SzException { + public SzDiagnostic getDiagnostic() + throws SzException + { return this.env.getDiagnostic(); } @Override - public TestData getTestData() { + public TestData getTestData() + { return this.testData; } @BeforeAll - public void initializeEnvironment() { + public void initializeEnvironment() + { this.beginTests(); this.initializeTestEnvironment(); String settings = this.getRepoSettings(); - + String instanceName = this.getClass().getSimpleName(); - this.env = SzAutoCoreEnvironment.newAutoBuilder() - .instanceName(instanceName) - .settings(settings) - .verboseLogging(false) - .concurrency(this.getConcurrency()) - .configRefreshPeriod(this.getConfigRefreshPeriod()) - .build(); + this.env = SzAutoCoreEnvironment.newAutoBuilder().instanceName( + instanceName).settings(settings).verboseLogging(false).concurrency( + this.getConcurrency()).configRefreshPeriod( + this.getConfigRefreshPeriod()).build(); } - + /** * Overridden to load test data and extract features. */ - protected void prepareRepository() { + protected void prepareRepository() + { String instanceName = this.getInstanceName(); - String settings = this.getRepoSettings(); + String settings = this.getRepoSettings(); - SzCoreEnvironment env = SzCoreEnvironment.newBuilder() - .instanceName(instanceName) - .settings(settings) - .verboseLogging(false) - .build(); + SzCoreEnvironment env = SzCoreEnvironment.newBuilder().instanceName( + instanceName).settings(settings).verboseLogging(false).build(); try { TestDataLoader loader = new StandardTestDataLoader(env); - + this.testData.setup(loader); - } finally { env.destroy(); } } @AfterAll - public void teardownEnvironment() { + public void teardownEnvironment() + { try { if (this.env != null) { this.env.destroy(); diff --git a/src/test/java/com/senzing/sdk/core/auto/EngineBasicsTest.java b/src/test/java/com/senzing/sdk/core/auto/EngineBasicsTest.java index 3905236..5b85a9b 100644 --- a/src/test/java/com/senzing/sdk/core/auto/EngineBasicsTest.java +++ b/src/test/java/com/senzing/sdk/core/auto/EngineBasicsTest.java @@ -6,11 +6,9 @@ import org.junit.jupiter.api.TestMethodOrder; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; - import com.senzing.sdk.SzEngine; import com.senzing.sdk.SzException; import com.senzing.sdk.test.SzEngineBasicsTest; - import static org.junit.jupiter.api.MethodOrderer.OrderAnnotation; import static org.junit.jupiter.api.TestInstance.Lifecycle; @@ -20,32 +18,29 @@ @TestInstance(Lifecycle.PER_CLASS) @Execution(ExecutionMode.SAME_THREAD) @TestMethodOrder(OrderAnnotation.class) -public class EngineBasicsTest - extends AbstractAutoCoreTest - implements SzEngineBasicsTest +public class EngineBasicsTest + extends AbstractAutoCoreTest implements SzEngineBasicsTest { - private SzAutoCoreEnvironment env = null; @BeforeAll - public void initializeEnvironment() { + public void initializeEnvironment() + { this.beginTests(); this.initializeTestEnvironment(); String settings = this.getRepoSettings(); - + String instanceName = this.getClass().getSimpleName(); - - this.env = SzAutoCoreEnvironment.newAutoBuilder() - .instanceName(instanceName) - .settings(settings) - .verboseLogging(false) - .concurrency(this.getConcurrency()) - .configRefreshPeriod(this.getConfigRefreshPeriod()) - .build(); + + this.env = SzAutoCoreEnvironment.newAutoBuilder().instanceName( + instanceName).settings(settings).verboseLogging(false).concurrency( + this.getConcurrency()).configRefreshPeriod( + this.getConfigRefreshPeriod()).build(); } - + @AfterAll - public void teardownEnvironment() { + public void teardownEnvironment() + { try { if (this.env != null) { this.env.destroy(); @@ -60,10 +55,12 @@ public void teardownEnvironment() { /** * Gets the {@link SzEngine} from the {@link SzCoreEnvironment}. * {@inheritDoc} - * + * * @return The {@link SzEngine} to use for this test. */ - public SzEngine getEngine() throws SzException { + public SzEngine getEngine() + throws SzException + { return this.env.getEngine(); } } diff --git a/src/test/java/com/senzing/sdk/core/auto/EngineGraphTest.java b/src/test/java/com/senzing/sdk/core/auto/EngineGraphTest.java index 8300879..4414b17 100644 --- a/src/test/java/com/senzing/sdk/core/auto/EngineGraphTest.java +++ b/src/test/java/com/senzing/sdk/core/auto/EngineGraphTest.java @@ -4,7 +4,6 @@ import java.util.Set; import java.util.ArrayList; import java.util.TreeSet; - import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.TestInstance; @@ -14,10 +13,8 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; - import static org.junit.jupiter.api.MethodOrderer.OrderAnnotation; import static org.junit.jupiter.api.TestInstance.Lifecycle; - import com.senzing.sdk.SzEngine; import com.senzing.sdk.SzFlag; import com.senzing.sdk.SzRecordKey; @@ -28,7 +25,6 @@ import com.senzing.sdk.test.StandardTestDataLoader; import com.senzing.sdk.test.SzEngineGraphTest; import com.senzing.sdk.test.TestDataLoader; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; import static com.senzing.sdk.SzFlag.*; @@ -39,65 +35,63 @@ @TestInstance(Lifecycle.PER_CLASS) @Execution(ExecutionMode.SAME_THREAD) @TestMethodOrder(OrderAnnotation.class) -public class EngineGraphTest - extends AbstractAutoCoreTest - implements SzEngineGraphTest +public class EngineGraphTest + extends AbstractAutoCoreTest implements SzEngineGraphTest { private SzAutoCoreEnvironment env = null; private TestData testData = new TestData(); @Override - public SzEngine getEngine() throws SzException { + public SzEngine getEngine() + throws SzException + { return this.env.getEngine(); } @Override - public TestData getTestData() { + public TestData getTestData() + { return this.testData; } @BeforeAll - public void initializeEnvironment() { + public void initializeEnvironment() + { this.beginTests(); this.initializeTestEnvironment(); String settings = this.getRepoSettings(); - + String instanceName = this.getClass().getSimpleName(); - - this.env = SzAutoCoreEnvironment.newAutoBuilder() - .instanceName(instanceName) - .settings(settings) - .verboseLogging(false) - .concurrency(this.getConcurrency()) - .configRefreshPeriod(this.getConfigRefreshPeriod()) - .build(); + + this.env = SzAutoCoreEnvironment.newAutoBuilder().instanceName( + instanceName).settings(settings).verboseLogging(false).concurrency( + this.getConcurrency()).configRefreshPeriod( + this.getConfigRefreshPeriod()).build(); } /** * Overridden to configure some data sources. */ - protected void prepareRepository() { + protected void prepareRepository() + { String instanceName = this.getInstanceName(); - String settings = this.getRepoSettings(); + String settings = this.getRepoSettings(); - SzCoreEnvironment env = SzCoreEnvironment.newBuilder() - .instanceName(instanceName) - .settings(settings) - .verboseLogging(false) - .build(); + SzCoreEnvironment env = SzCoreEnvironment.newBuilder().instanceName( + instanceName).settings(settings).verboseLogging(false).build(); try { TestDataLoader loader = new StandardTestDataLoader(env); - + this.testData.loadData(loader); - } finally { env.destroy(); } } - + @AfterAll - public void teardownEnvironment() { + public void teardownEnvironment() + { try { if (this.env != null) { this.env.destroy(); diff --git a/src/test/java/com/senzing/sdk/core/auto/EngineHowTest.java b/src/test/java/com/senzing/sdk/core/auto/EngineHowTest.java index 1331d03..ac89b4b 100644 --- a/src/test/java/com/senzing/sdk/core/auto/EngineHowTest.java +++ b/src/test/java/com/senzing/sdk/core/auto/EngineHowTest.java @@ -3,7 +3,6 @@ import java.util.List; import java.util.Set; import java.util.ArrayList; - import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.TestInstance; @@ -12,7 +11,6 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; - import com.senzing.sdk.SzEngine; import com.senzing.sdk.SzRecordKey; import com.senzing.sdk.core.SzCoreEnvironment; @@ -22,7 +20,6 @@ import com.senzing.sdk.test.SzEngineHowTest; import com.senzing.sdk.test.SzEntityLookup; import com.senzing.sdk.test.TestDataLoader; - import static org.junit.jupiter.api.TestInstance.Lifecycle; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; @@ -34,66 +31,64 @@ */ @TestInstance(Lifecycle.PER_CLASS) @Execution(ExecutionMode.SAME_THREAD) -public class EngineHowTest - extends AbstractAutoCoreTest - implements SzEngineHowTest +public class EngineHowTest + extends AbstractAutoCoreTest implements SzEngineHowTest { private TestData testData = new TestData(); private SzAutoCoreEnvironment env = null; @Override - public TestData getTestData() { + public TestData getTestData() + { return this.testData; } @Override - public SzEngine getEngine() throws SzException { + public SzEngine getEngine() + throws SzException + { return this.env.getEngine(); } @BeforeAll - public void initializeEnvironment() { + public void initializeEnvironment() + { this.beginTests(); this.initializeTestEnvironment(); String settings = this.getRepoSettings(); - + String instanceName = this.getClass().getSimpleName(); - - this.env = SzAutoCoreEnvironment.newAutoBuilder() - .instanceName(instanceName) - .settings(settings) - .verboseLogging(false) - .concurrency(this.getConcurrency()) - .configRefreshPeriod(this.getConfigRefreshPeriod()) - .build(); + + this.env = SzAutoCoreEnvironment.newAutoBuilder().instanceName( + instanceName).settings(settings).verboseLogging(false).concurrency( + this.getConcurrency()).configRefreshPeriod( + this.getConfigRefreshPeriod()).build(); } /** * Overridden to configure some data sources. */ - protected void prepareRepository() { + protected void prepareRepository() + { String instanceName = this.getInstanceName(); - String settings = this.getRepoSettings(); + String settings = this.getRepoSettings(); - SzCoreEnvironment env = SzCoreEnvironment.newBuilder() - .instanceName(instanceName) - .settings(settings) - .verboseLogging(false) - .build(); + SzCoreEnvironment env = SzCoreEnvironment.newBuilder().instanceName( + instanceName).settings(settings).verboseLogging(false).build(); try { TestDataLoader loader = new StandardTestDataLoader(env); - + this.testData.loadData(loader); - } finally { env.destroy(); } } - + @AfterAll - public void teardownEnvironment() { + public void teardownEnvironment() + { try { if (this.env != null) { this.env.destroy(); @@ -146,7 +141,8 @@ public void testVirtualEntityDefaults(Set recordKeys) }); } - public List getHowEntityDefaultParameters() { + public List getHowEntityDefaultParameters() + { List results = new ArrayList<>(RECORD_KEYS.size()); RECORD_KEYS.forEach(key -> { results.add(Arguments.of(key)); @@ -156,7 +152,8 @@ public List getHowEntityDefaultParameters() { @ParameterizedTest @MethodSource("getHowEntityDefaultParameters") - public void testHowEntityDefaults(SzRecordKey recordKey) { + public void testHowEntityDefaults(SzRecordKey recordKey) + { this.performTest(() -> { try { SzEntityLookup lookup = this.getTestData().getEntityLookup(); diff --git a/src/test/java/com/senzing/sdk/core/auto/EngineReadTest.java b/src/test/java/com/senzing/sdk/core/auto/EngineReadTest.java index 108a78b..6a98cca 100644 --- a/src/test/java/com/senzing/sdk/core/auto/EngineReadTest.java +++ b/src/test/java/com/senzing/sdk/core/auto/EngineReadTest.java @@ -2,7 +2,6 @@ import java.util.List; import java.util.ArrayList; - import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.TestInstance; @@ -11,8 +10,6 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; - - import com.senzing.sdk.SzEngine; import com.senzing.sdk.SzFlag; import com.senzing.sdk.SzRecordKey; @@ -22,8 +19,6 @@ import com.senzing.sdk.test.StandardTestDataLoader; import com.senzing.sdk.test.SzEngineReadTest; import com.senzing.sdk.test.TestDataLoader; - - import static org.junit.jupiter.api.TestInstance.Lifecycle; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; @@ -34,65 +29,63 @@ */ @TestInstance(Lifecycle.PER_CLASS) @Execution(ExecutionMode.SAME_THREAD) -public class EngineReadTest - extends AbstractAutoCoreTest - implements SzEngineReadTest +public class EngineReadTest + extends AbstractAutoCoreTest implements SzEngineReadTest { private SzAutoCoreEnvironment env = null; private TestData testData = new TestData(); @Override - public SzEngine getEngine() throws SzException { + public SzEngine getEngine() + throws SzException + { return this.env.getEngine(); } @Override - public TestData getTestData() { + public TestData getTestData() + { return this.testData; } @BeforeAll - public void initializeEnvironment() { + public void initializeEnvironment() + { this.beginTests(); this.initializeTestEnvironment(); String settings = this.getRepoSettings(); - + String instanceName = this.getClass().getSimpleName(); - - this.env = SzAutoCoreEnvironment.newAutoBuilder() - .instanceName(instanceName) - .settings(settings) - .verboseLogging(false) - .concurrency(this.getConcurrency()) - .configRefreshPeriod(this.getConfigRefreshPeriod()) - .build(); + + this.env = SzAutoCoreEnvironment.newAutoBuilder().instanceName( + instanceName).settings(settings).verboseLogging(false).concurrency( + this.getConcurrency()).configRefreshPeriod( + this.getConfigRefreshPeriod()).build(); } /** * Overridden to configure data sources and load test data. */ - protected void prepareRepository() { + protected void prepareRepository() + { String instanceName = this.getInstanceName(); - String settings = this.getRepoSettings(); + String settings = this.getRepoSettings(); - SzCoreEnvironment env = SzCoreEnvironment.newBuilder() - .instanceName(instanceName) - .settings(settings) - .verboseLogging(false) - .build(); + SzCoreEnvironment env = SzCoreEnvironment.newBuilder().instanceName( + instanceName).settings(settings).verboseLogging(false).build(); try { TestDataLoader loader = new StandardTestDataLoader(env); - + this.testData.loadData(loader); - } finally { env.destroy(); } } - + @AfterAll - public void teardownEnvironment() { + public void teardownEnvironment() + { try { if (this.env != null) { this.env.destroy(); @@ -154,7 +147,8 @@ public void testGetEntityByEntityIdDefaults(SzRecordKey recordKey) @ParameterizedTest @MethodSource("getRecordKeyParameters") - public void testGetRecordDefaults(SzRecordKey recordKey) { + public void testGetRecordDefaults(SzRecordKey recordKey) + { this.performTest(() -> { try { SzEngine engine = (SzEngine) this.env.getEngine(); @@ -226,5 +220,4 @@ public void testSearchByAttributesdDefaults(String attributes, } }); } - } diff --git a/src/test/java/com/senzing/sdk/core/auto/EngineWhyTest.java b/src/test/java/com/senzing/sdk/core/auto/EngineWhyTest.java index 0d26c82..0cd7259 100644 --- a/src/test/java/com/senzing/sdk/core/auto/EngineWhyTest.java +++ b/src/test/java/com/senzing/sdk/core/auto/EngineWhyTest.java @@ -2,7 +2,6 @@ import java.util.List; import java.util.ArrayList; - import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.TestInstance; @@ -12,10 +11,8 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; - import static org.junit.jupiter.api.MethodOrderer.OrderAnnotation; import static org.junit.jupiter.api.TestInstance.Lifecycle; - import com.senzing.sdk.SzEngine; import com.senzing.sdk.SzRecordKey; import com.senzing.sdk.core.SzCoreEnvironment; @@ -25,7 +22,6 @@ import com.senzing.sdk.test.SzEngineWhyTest; import com.senzing.sdk.test.SzEntityLookup; import com.senzing.sdk.test.TestDataLoader; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; import static com.senzing.sdk.SzFlag.*; @@ -37,66 +33,64 @@ @TestInstance(Lifecycle.PER_CLASS) @Execution(ExecutionMode.SAME_THREAD) @TestMethodOrder(OrderAnnotation.class) -public class EngineWhyTest - extends AbstractAutoCoreTest - implements SzEngineWhyTest +public class EngineWhyTest + extends AbstractAutoCoreTest implements SzEngineWhyTest { private TestData testData = new TestData(); private SzAutoCoreEnvironment env = null; @Override - public TestData getTestData() { + public TestData getTestData() + { return this.testData; } @Override - public SzEngine getEngine() throws SzException { + public SzEngine getEngine() + throws SzException + { return this.env.getEngine(); - } + } @BeforeAll - public void initializeEnvironment() { + public void initializeEnvironment() + { this.beginTests(); this.initializeTestEnvironment(); String settings = this.getRepoSettings(); - + String instanceName = this.getClass().getSimpleName(); - - this.env = SzAutoCoreEnvironment.newAutoBuilder() - .instanceName(instanceName) - .settings(settings) - .verboseLogging(false) - .concurrency(this.getConcurrency()) - .configRefreshPeriod(this.getConfigRefreshPeriod()) - .build(); + + this.env = SzAutoCoreEnvironment.newAutoBuilder().instanceName( + instanceName).settings(settings).verboseLogging(false).concurrency( + this.getConcurrency()).configRefreshPeriod( + this.getConfigRefreshPeriod()).build(); } /** * Overridden to configure some data sources. */ - protected void prepareRepository() { + protected void prepareRepository() + { String instanceName = this.getInstanceName(); - String settings = this.getRepoSettings(); + String settings = this.getRepoSettings(); - SzCoreEnvironment env = SzCoreEnvironment.newBuilder() - .instanceName(instanceName) - .settings(settings) - .verboseLogging(false) - .build(); + SzCoreEnvironment env = SzCoreEnvironment.newBuilder().instanceName( + instanceName).settings(settings).verboseLogging(false).build(); try { TestDataLoader loader = new StandardTestDataLoader(env); - + this.testData.loadData(loader); - } finally { env.destroy(); } } @AfterAll - public void teardownEnvironment() { + public void teardownEnvironment() + { try { if (this.env != null) { this.env.destroy(); @@ -108,7 +102,8 @@ public void teardownEnvironment() { } } - public List getWhySearchDefaultParameters() { + public List getWhySearchDefaultParameters() + { List whySearchParams = this.getWhySearchParameters(); List defaultParams = new ArrayList<>(whySearchParams.size()); @@ -159,8 +154,10 @@ public void testWhySearchDefaults(String attributes, }); } - public static List getRecordCombinations() { - List result = new ArrayList<>(RECORD_KEYS.size() * RECORD_KEYS.size()); + public static List getRecordCombinations() + { + List result + = new ArrayList<>(RECORD_KEYS.size() * RECORD_KEYS.size()); RECORD_KEYS.forEach(key1 -> { RECORD_KEYS.forEach(key2 -> { @@ -172,7 +169,8 @@ public static List getRecordCombinations() { return result; } - public static List getRecordKeyParameters() { + public static List getRecordKeyParameters() + { List result = new ArrayList<>(RECORD_KEYS.size()); RECORD_KEYS.forEach(key -> { @@ -182,7 +180,6 @@ public static List getRecordKeyParameters() { return result; } - @ParameterizedTest @MethodSource("getRecordCombinations") public void testWhyEntitiesDefaults(SzRecordKey recordKey1, @@ -214,7 +211,8 @@ public void testWhyEntitiesDefaults(SzRecordKey recordKey1, @ParameterizedTest @MethodSource("getRecordKeyParameters") - public void testWhyRecordInEntityDefaults(SzRecordKey recordKey) { + public void testWhyRecordInEntityDefaults(SzRecordKey recordKey) + { this.performTest(() -> { try { SzEngine engine = (SzEngine) this.env.getEngine(); diff --git a/src/test/java/com/senzing/sdk/core/auto/EngineWriteTest.java b/src/test/java/com/senzing/sdk/core/auto/EngineWriteTest.java index 38f11ae..4920287 100644 --- a/src/test/java/com/senzing/sdk/core/auto/EngineWriteTest.java +++ b/src/test/java/com/senzing/sdk/core/auto/EngineWriteTest.java @@ -2,7 +2,6 @@ import java.util.List; import java.util.ArrayList; - import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.TestInstance; @@ -13,10 +12,8 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; - import static org.junit.jupiter.api.MethodOrderer.OrderAnnotation; import static org.junit.jupiter.api.TestInstance.Lifecycle; - import com.senzing.sdk.SzEngine; import com.senzing.sdk.SzRecordKey; import com.senzing.sdk.core.SzCoreEnvironment; @@ -27,7 +24,6 @@ import com.senzing.sdk.test.SzRecord; import com.senzing.sdk.test.TestDataLoader; import com.senzing.util.SemanticVersion; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; import static com.senzing.sdk.SzFlag.*; @@ -38,9 +34,8 @@ @TestInstance(Lifecycle.PER_CLASS) @Execution(ExecutionMode.SAME_THREAD) @TestMethodOrder(OrderAnnotation.class) -public class EngineWriteTest - extends AbstractAutoCoreTest - implements SzEngineWriteTest +public class EngineWriteTest + extends AbstractAutoCoreTest implements SzEngineWriteTest { private TestData testData = new TestData(); @@ -49,35 +44,37 @@ public class EngineWriteTest private SemanticVersion senzingVersion = null; @Override - public TestData getTestData() { + public TestData getTestData() + { return this.testData; } @Override - public SzEngine getEngine() throws SzException { + public SzEngine getEngine() + throws SzException + { return this.env.getEngine(); } @Override - public SemanticVersion getSenzingVersion() { + public SemanticVersion getSenzingVersion() + { return this.senzingVersion; } @BeforeAll - public void initializeEnvironment() { + public void initializeEnvironment() + { this.beginTests(); this.initializeTestEnvironment(); String settings = this.getRepoSettings(); - + String instanceName = this.getClass().getSimpleName(); - - this.env = SzAutoCoreEnvironment.newAutoBuilder() - .instanceName(instanceName) - .settings(settings) - .verboseLogging(false) - .concurrency(this.getConcurrency()) - .configRefreshPeriod(this.getConfigRefreshPeriod()) - .build(); + + this.env = SzAutoCoreEnvironment.newAutoBuilder().instanceName( + instanceName).settings(settings).verboseLogging(false).concurrency( + this.getConcurrency()).configRefreshPeriod( + this.getConfigRefreshPeriod()).build(); this.senzingVersion = SdkTest.getSenzingVersion(this.env); } @@ -85,27 +82,25 @@ public void initializeEnvironment() { /** * Overridden to configure some data sources. */ - protected void prepareRepository() { + protected void prepareRepository() + { String instanceName = this.getInstanceName(); - String settings = this.getRepoSettings(); + String settings = this.getRepoSettings(); - SzCoreEnvironment env = SzCoreEnvironment.newBuilder() - .instanceName(instanceName) - .settings(settings) - .verboseLogging(false) - .build(); + SzCoreEnvironment env = SzCoreEnvironment.newBuilder().instanceName( + instanceName).settings(settings).verboseLogging(false).build(); try { TestDataLoader loader = new StandardTestDataLoader(env); - + this.testData.loadData(loader); - } finally { env.destroy(); } } - + @AfterAll - public void teardownEnvironment() { + public void teardownEnvironment() + { try { if (this.env != null) { this.env.destroy(); @@ -117,7 +112,8 @@ public void teardownEnvironment() { } } - public List getRecordPreviewDefaultArguments() { + public List getRecordPreviewDefaultArguments() + { List baseArgs = this.getRecordPreviewArguments(); List defaultArgs = new ArrayList<>(baseArgs.size()); @@ -154,9 +150,10 @@ public void testRecordPreviewDefaults(SzRecord record) fail("Unexpectedly failed getting entity by record", e); } }); - } + } - public List getAddRecordDefaultArguments() { + public List getAddRecordDefaultArguments() + { List baseArgs = this.getAddRecordArguments(); List defaultArgs = new ArrayList<>(baseArgs.size()); @@ -193,9 +190,10 @@ public void testAddRecordDefaults(SzRecordKey recordKey, SzRecord record) fail("Unexpectedly failed adding record", e); } }); - } + } - public List getReevaluateRecordDefaultArguments() { + public List getReevaluateRecordDefaultArguments() + { List baseArgs = this.getReevaluateRecordArguments(); List defaultArgs = new ArrayList<>(baseArgs.size()); @@ -232,9 +230,10 @@ public void testReevaluateRecordDefaults(SzRecordKey recordKey) fail("Unexpectedly failed reevaluating record", e); } }); - } + } - public List getReevaluateEntityDefaultArguments() { + public List getReevaluateEntityDefaultArguments() + { List baseArgs = this.getReevaluateEntityArguments(); List defaultArgs = new ArrayList<>(baseArgs.size()); @@ -271,9 +270,10 @@ public void testReevaluateEntityDefaults(long entityId) fail("Unexpectedly failed reevaluating entity", e); } }); - } + } - public List getDeleteRecordDefaultArguments() { + public List getDeleteRecordDefaultArguments() + { List baseArgs = this.getDeleteRecordArguments(); List defaultArgs = new ArrayList<>(baseArgs.size()); diff --git a/src/test/java/com/senzing/sdk/core/auto/EnsureConfigRecursionTest.java b/src/test/java/com/senzing/sdk/core/auto/EnsureConfigRecursionTest.java index a0c4f40..c27695d 100644 --- a/src/test/java/com/senzing/sdk/core/auto/EnsureConfigRecursionTest.java +++ b/src/test/java/com/senzing/sdk/core/auto/EnsureConfigRecursionTest.java @@ -8,18 +8,14 @@ import org.junit.jupiter.api.Order; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; - import com.senzing.sdk.SzEngine; import com.senzing.sdk.SzException; import com.senzing.sdk.SzRecordKey; - import uk.org.webcompere.systemstubs.stream.SystemErr; - import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.MethodOrderer.OrderAnnotation; import static org.junit.jupiter.api.TestInstance.Lifecycle; - import java.util.concurrent.Callable; /** @@ -28,17 +24,17 @@ * {@link SzAutoCoreEnvironment#ensureConfigCurrent()}. * *

- * When config refresh is enabled and {@code CONFIG_RETRY_FLAG} is set (via - * a {@code @SzConfigRetryable} proxy), a persistent failure caused + * When config refresh is enabled and {@code CONFIG_RETRY_FLAG} is set (via a + * {@code @SzConfigRetryable} proxy), a persistent failure caused * {@code execute()} to call {@code ensureConfigCurrent()}, which called * {@code getActiveConfigId()} / {@code getDefaultConfigId()} back through * the overridden {@code execute()}, which called * {@code ensureConfigCurrent()} again, ad infinitum. * *

- * The fix uses the {@code ENSURING_CONFIG} thread-local guard to prevent - * nested {@code execute()} calls from re-entering the config-retry path - * while {@code ensureConfigCurrent()} is already in progress. + * The fix uses the {@code ENSURING_CONFIG} thread-local guard to prevent nested + * {@code execute()} calls from re-entering the config-retry path while {@code + * ensureConfigCurrent()} is already in progress. */ @TestInstance(Lifecycle.PER_CLASS) @Execution(ExecutionMode.SAME_THREAD) @@ -49,26 +45,32 @@ public class EnsureConfigRecursionTest extends AbstractAutoCoreTest * A mock environment that can simulate persistent failures at the * {@link #doExecute(Callable)} level to trigger the recursion scenario. */ - private static class MockEnvironment extends SzAutoCoreEnvironment { - private static final ThreadLocal ALWAYS_FAIL = new ThreadLocal<>() { - protected Boolean initialValue() { - return Boolean.FALSE; - } - }; - - public MockEnvironment(String instanceName, String settings) { + private static class MockEnvironment extends SzAutoCoreEnvironment + { + private static final ThreadLocal ALWAYS_FAIL + = new ThreadLocal<>() { + protected Boolean initialValue() + { + return Boolean.FALSE; + } + }; + + public MockEnvironment(String instanceName, String settings) + { super(SzAutoCoreEnvironment.newAutoBuilder() .settings(settings).instanceName(instanceName) .configRefreshPeriod(REACTIVE_CONFIG_REFRESH) .concurrency(null)); } - public void setAlwaysFail(boolean fail) { + public void setAlwaysFail(boolean fail) + { ALWAYS_FAIL.set(fail); } @Override - protected T doExecute(Callable task) throws Exception + protected T doExecute(Callable task) + throws Exception { if (Boolean.TRUE.equals(ALWAYS_FAIL.get())) { throw new SzException("Simulated persistent failure"); @@ -83,16 +85,18 @@ protected T doExecute(Callable task) throws Exception private MockEnvironment env = null; @BeforeAll - public void initializeEnvironment() { + public void initializeEnvironment() + { this.beginTests(); this.initializeTestEnvironment(); - String settings = this.getRepoSettings(); + String settings = this.getRepoSettings(); String instanceName = this.getClass().getSimpleName(); this.env = new MockEnvironment(instanceName, settings); } @AfterAll - public void teardownEnvironment() { + public void teardownEnvironment() + { try { if (this.env != null) { this.env.destroy(); @@ -112,7 +116,9 @@ public void teardownEnvironment() { */ @Test @Order(10) - public void testNoRecursionOnPersistentFailure() throws Exception { + public void testNoRecursionOnPersistentFailure() + throws Exception + { SzEngine engine = null; try { engine = this.env.getEngine(); diff --git a/src/test/java/com/senzing/sdk/core/auto/ProductTest.java b/src/test/java/com/senzing/sdk/core/auto/ProductTest.java index f3e3dfe..b2f8c2b 100644 --- a/src/test/java/com/senzing/sdk/core/auto/ProductTest.java +++ b/src/test/java/com/senzing/sdk/core/auto/ProductTest.java @@ -6,45 +6,43 @@ import org.junit.jupiter.api.TestInstance.Lifecycle; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; - import com.senzing.sdk.SzProduct; import com.senzing.sdk.SzException; import com.senzing.sdk.test.SzProductTest; @TestInstance(Lifecycle.PER_CLASS) @Execution(ExecutionMode.SAME_THREAD) -public class ProductTest - extends AbstractAutoCoreTest - implements SzProductTest +public class ProductTest extends AbstractAutoCoreTest implements SzProductTest { private SzAutoCoreEnvironment env = null; /** * @inheritDoc */ - public SzProduct getProduct() throws SzException { + public SzProduct getProduct() + throws SzException + { return this.env.getProduct(); } @BeforeAll - public void initializeEnvironment() { + public void initializeEnvironment() + { this.beginTests(); this.initializeTestEnvironment(); String settings = this.getRepoSettings(); - + String instanceName = this.getClass().getSimpleName(); - this.env = SzAutoCoreEnvironment.newAutoBuilder() - .instanceName(instanceName) - .settings(settings) - .verboseLogging(false) - .concurrency(this.getConcurrency()) - .configRefreshPeriod(this.getConfigRefreshPeriod()) - .build(); + this.env = SzAutoCoreEnvironment.newAutoBuilder().instanceName( + instanceName).settings(settings).verboseLogging(false).concurrency( + this.getConcurrency()).configRefreshPeriod( + this.getConfigRefreshPeriod()).build(); } @AfterAll - public void teardownEnvironment() { + public void teardownEnvironment() + { try { if (this.env != null) { this.env.destroy(); diff --git a/src/test/java/com/senzing/sdk/core/auto/SzAutoCoreEnvironmentTest.java b/src/test/java/com/senzing/sdk/core/auto/SzAutoCoreEnvironmentTest.java index 065e948..f56612f 100644 --- a/src/test/java/com/senzing/sdk/core/auto/SzAutoCoreEnvironmentTest.java +++ b/src/test/java/com/senzing/sdk/core/auto/SzAutoCoreEnvironmentTest.java @@ -9,15 +9,12 @@ import java.util.IdentityHashMap; import java.util.Iterator; import java.util.Random; - import java.util.concurrent.ThreadPoolExecutor; - import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadFactory; - import static java.util.concurrent.TimeUnit.SECONDS; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.AfterAll; @@ -29,7 +26,6 @@ import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.ValueSource; import org.junit.jupiter.params.provider.Arguments; - import static org.junit.jupiter.api.TestInstance.Lifecycle; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -39,9 +35,7 @@ import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertSame; - import org.junit.jupiter.api.Test; - import com.senzing.sdk.SzProduct; import com.senzing.sdk.core.SzCoreEnvironment; import com.senzing.sdk.core.auto.Reinitializer; @@ -54,7 +48,6 @@ import com.senzing.sdk.SzEnvironment; import com.senzing.sdk.SzDiagnostic; import com.senzing.sdk.SzException; - import static com.senzing.sdk.core.SzCoreEnvironment.*; import static com.senzing.sdk.core.auto.SzAutoCoreEnvironment.DISABLED_CONCURRENCY; import static com.senzing.sdk.core.auto.SzAutoCoreEnvironment.DISABLED_CONFIG_REFRESH; @@ -65,9 +58,10 @@ @TestInstance(Lifecycle.PER_CLASS) @Execution(ExecutionMode.SAME_THREAD) -public class SzAutoCoreEnvironmentTest extends AbstractAutoCoreTest { +public class SzAutoCoreEnvironmentTest extends AbstractAutoCoreTest +{ private static final String EMPLOYEES_DATA_SOURCE = "EMPLOYEES"; - + private static final String CUSTOMERS_DATA_SOURCE = "CUSTOMERS"; private long configId1 = 0L; @@ -76,18 +70,17 @@ public class SzAutoCoreEnvironmentTest extends AbstractAutoCoreTest { private long configId3 = 0L; - @BeforeAll public void initializeEnvironment() { + @BeforeAll + public void initializeEnvironment() + { this.beginTests(); this.initializeTestEnvironment(); - String settings = this.getRepoSettings(); + String settings = this.getRepoSettings(); String instanceName = this.getInstanceName(); - SzEnvironment env = SzCoreEnvironment.newBuilder() - .instanceName(instanceName) - .settings(settings) - .verboseLogging(false) - .build(); - + SzEnvironment env = SzCoreEnvironment.newBuilder().instanceName( + instanceName).settings(settings).verboseLogging(false).build(); + try { String config1 = this.createConfig(env, CUSTOMERS_DATA_SOURCE); String config2 = this.createConfig(env, EMPLOYEES_DATA_SOURCE); @@ -98,16 +91,16 @@ public class SzAutoCoreEnvironmentTest extends AbstractAutoCoreTest { this.configId1 = configMgr.registerConfig(config1, "Config 1"); this.configId2 = configMgr.registerConfig(config2, "Config 2"); this.configId3 = configMgr.registerConfig(config3, "Config 3"); - } catch (Exception e) { fail(e); - } finally { env.destroy(); - } + } } - @AfterAll public void teardownEnvironment() { + @AfterAll + public void teardownEnvironment() + { try { this.teardownTestEnvironment(); } finally { @@ -116,7 +109,8 @@ public class SzAutoCoreEnvironmentTest extends AbstractAutoCoreTest { } @Test - void testNewDefaultBuilder() { + void testNewDefaultBuilder() + { this.performTest(() -> { SzAutoCoreEnvironment env = null; @@ -136,13 +130,12 @@ void testNewDefaultBuilder() { }); } - @ParameterizedTest - @CsvSource({"true,Custom Instance,0,0", "false,Custom Instance,4,2000", "true, ,0,3000", "false,,6,0"}) + @CsvSource({ "true,Custom Instance,0,0", "false,Custom Instance,4,2000", "true, ,0,3000", "false,,6,0" }) void testNewCustomBuilder(boolean verboseLogging, String instanceName, int concurrency, - long duration) + long duration) { this.performTest(() -> { String settings = this.getRepoSettings(); @@ -192,7 +185,8 @@ void testNewCustomBuilder(boolean verboseLogging, } @Test - void testSingletonViolation() { + void testSingletonViolation() + { this.performTest(() -> { SzAutoCoreEnvironment env1 = null; SzAutoCoreEnvironment env2 = null; @@ -223,7 +217,8 @@ void testSingletonViolation() { } @Test - void testMixedSingletonViolation() { + void testMixedSingletonViolation() + { this.performTest(() -> { SzCoreEnvironment env1 = null; SzAutoCoreEnvironment env2 = null; @@ -254,7 +249,8 @@ void testMixedSingletonViolation() { } @Test - void testSingletonAdherence() { + void testSingletonAdherence() + { this.performTest(() -> { SzAutoCoreEnvironment env1 = null; SzAutoCoreEnvironment env2 = null; @@ -286,7 +282,8 @@ void testSingletonAdherence() { } @Test - void testMixedSingletonAdherence() { + void testMixedSingletonAdherence() + { this.performTest(() -> { SzCoreEnvironment env1 = null; SzAutoCoreEnvironment env2 = null; @@ -318,7 +315,8 @@ void testMixedSingletonAdherence() { } @Test - void testDestroy() { + void testDestroy() + { this.performTest(() -> { SzAutoCoreEnvironment env1 = null; SzAutoCoreEnvironment env2 = null; @@ -371,24 +369,28 @@ void testDestroy() { /** * Extends {@link Thread} to allow for identifying of core threads. */ - static class CallingThread extends Thread { + static class CallingThread extends Thread + { /** * Constructs with the specified {@link Runnable}. - * + * * @param runnable The {@link Runnable} with which to construct with. */ - public CallingThread(Runnable runnable) { + public CallingThread(Runnable runnable) + { super(runnable); } } - private static final ThreadFactory THREAD_FACTORY = (r) -> new CallingThread(r); + private static final ThreadFactory THREAD_FACTORY + = (r) -> new CallingThread(r); @ParameterizedTest @CsvSource({"1, 1, Foo", "1, 0, Foo", "2, 0, Bar", "2, 1, Bar", "2, 2, Bar", "3, 0, Phoo", "3, 1, Phoo", "3, 2, Phoo", "4, 0, Phoox", "4, 1, Phoox", "4, 2, Phoox", "4, 3, Phoox", "4, 4, Phoox"}) - void testExecute(int threadCount, int concurrencyParam, String expected) { + void testExecute(int threadCount, int concurrencyParam, String expected) + { Integer concurrency = (concurrencyParam == 0) ? null : concurrencyParam; this.performTest(() -> { SzAutoCoreEnvironment env = null; @@ -501,7 +503,8 @@ void testExecute(int threadCount, int concurrencyParam, String expected) { }); } - void testSubmitTaskFailingCallable() { + void testSubmitTaskFailingCallable() + { this.performTest(() -> { SzAutoCoreEnvironment env = null; try { @@ -541,8 +544,8 @@ void testSubmitTaskFailingCallable() { }); } - - void testSubmitTaskFailingRunnable() { + void testSubmitTaskFailingRunnable() + { this.performTest(() -> { SzAutoCoreEnvironment env = null; try { @@ -578,8 +581,8 @@ void testSubmitTaskFailingRunnable() { }); } - - void testSubmitTaskFailingRunnableResult() { + void testSubmitTaskFailingRunnableResult() + { this.performTest(() -> { SzAutoCoreEnvironment env = null; try { @@ -620,7 +623,10 @@ void testSubmitTaskFailingRunnableResult() { @CsvSource({"1, 1, Foo", "1, 0, Foo", "2, 0, Bar", "2, 1, Bar", "2, 2, Bar", "3, 0, Phoo", "3, 1, Phoo", "3, 2, Phoo", "4, 0, Phoox", "4, 1, Phoox", "4, 2, Phoox", "4, 3, Phoox", "4, 4, Phoox"}) - void testSubmitTaskCallable(int threadCount, int concurrencyParam, String expected) { + void testSubmitTaskCallable(int threadCount, + int concurrencyParam, + String expected) + { Integer concurrency = (concurrencyParam == 0) ? null : concurrencyParam; this.performTest(() -> { SzAutoCoreEnvironment env = null; @@ -749,7 +755,10 @@ void testSubmitTaskCallable(int threadCount, int concurrencyParam, String expect @CsvSource({"1, 1, Foo", "1, 0, Foo", "2, 0, Bar", "2, 1, Bar", "2, 2, Bar", "3, 0, Phoo", "3, 1, Phoo", "3, 2, Phoo", "4, 0, Phoox", "4, 1, Phoox", "4, 2, Phoox", "4, 3, Phoox", "4, 4, Phoox"}) - void testSubmitTaskRunnableResult(int threadCount, int concurrencyParam, String expected) { + void testSubmitTaskRunnableResult(int threadCount, + int concurrencyParam, + String expected) + { Integer concurrency = (concurrencyParam == 0) ? null : concurrencyParam; this.performTest(() -> { SzAutoCoreEnvironment env = null; @@ -876,7 +885,8 @@ void testSubmitTaskRunnableResult(int threadCount, int concurrencyParam, String @ParameterizedTest @CsvSource({"1, 1", "1, 0", "2, 0", "2, 1", "2, 2", "3, 0", "3, 1", "3, 2", "4, 0", "4, 1", "4, 2", "4, 3", "4, 4"}) - void testSubmitTaskRunnable(int threadCount, int concurrencyParam) { + void testSubmitTaskRunnable(int threadCount, int concurrencyParam) + { Integer concurrency = (concurrencyParam == 0) ? null : concurrencyParam; this.performTest(() -> { SzAutoCoreEnvironment env = null; @@ -987,8 +997,9 @@ void testSubmitTaskRunnable(int threadCount, int concurrencyParam) { } @ParameterizedTest - @ValueSource(strings = {"Foo", "Bar", "Phoo", "Phoox"}) - void testExecuteFail(String expected) { + @ValueSource(strings = { "Foo", "Bar", "Phoo", "Phoox" }) + void testExecuteFail(String expected) + { this.performTest(() -> { SzAutoCoreEnvironment env = null; try { @@ -1017,7 +1028,8 @@ void testExecuteFail(String expected) { } @Test - void testDestroyRaceConditions() { + void testDestroyRaceConditions() + { this.performTest(() -> { SzAutoCoreEnvironment env = SzAutoCoreEnvironment.newAutoBuilder().build(); @@ -1105,7 +1117,8 @@ void testDestroyRaceConditions() { } @Test - void testGetActiveInstance() { + void testGetActiveInstance() + { this.performTest(() -> { SzAutoCoreEnvironment env1 = null; SzAutoCoreEnvironment env2 = null; @@ -1162,7 +1175,8 @@ void testGetActiveInstance() { } @Test - void testGetConfigManager() { + void testGetConfigManager() + { this.performTest(() -> { String settings = this.getRepoSettings(); @@ -1195,7 +1209,8 @@ void testGetConfigManager() { } @Test - void testGetDiagnostic() { + void testGetDiagnostic() + { this.performTest(() -> { String settings = this.getRepoSettings(); @@ -1228,7 +1243,8 @@ void testGetDiagnostic() { } @Test - void testGetEngine() { + void testGetEngine() + { this.performTest(() -> { String settings = this.getRepoSettings(); @@ -1261,7 +1277,8 @@ void testGetEngine() { } @Test - void testGetProduct() { + void testGetProduct() + { this.performTest(() -> { this.performTest(() -> { String settings = this.getRepoSettings(); @@ -1295,7 +1312,8 @@ void testGetProduct() { }); } - private List getActiveConfigIdParams() { + private List getActiveConfigIdParams() + { List result = new LinkedList<>(); long[] configIds = { this.configId1, this.configId2, this.configId3 }; @@ -1310,7 +1328,8 @@ private List getActiveConfigIdParams() { @ParameterizedTest @MethodSource("getActiveConfigIdParams") - public void testGetActiveConfigId(long configId, boolean initEngine) { + public void testGetActiveConfigId(long configId, boolean initEngine) + { this.performTest(() -> { SzAutoCoreEnvironment env = null; @@ -1344,8 +1363,9 @@ public void testGetActiveConfigId(long configId, boolean initEngine) { } @ParameterizedTest - @ValueSource(booleans = { true, false}) - public void testGetActiveConfigIdDefault(boolean initEngine) { + @ValueSource(booleans = { true, false }) + public void testGetActiveConfigIdDefault(boolean initEngine) + { this.performTest(() -> { SzAutoCoreEnvironment env = null; @@ -1384,29 +1404,30 @@ public void testGetActiveConfigIdDefault(boolean initEngine) { }); } - private List getReinitializeParams() { + private List getReinitializeParams() + { List result = new LinkedList<>(); List> booleanCombos = getBooleanVariants(2, false); Random prng = new Random(System.currentTimeMillis()); - - - List configIds = List.of(this.configId1, this.configId2, this.configId3); - List> configIdCombos = generateCombinations(configIds, configIds); + List configIds + = List.of(this.configId1, this.configId2, this.configId3); + List> configIdCombos + = generateCombinations(configIds, configIds); Collections.shuffle(configIdCombos, prng); Collections.shuffle(booleanCombos, prng); Iterator> configIdIter = circularIterator(configIdCombos); - for (List bools : booleanCombos) { boolean initEngine = bools.get(0); boolean initDiagnostic = bools.get(1); for (Long configId : configIds) { - result.add(Arguments.of(null, configId, initEngine, initDiagnostic)); + result.add(Arguments.of(null, configId, initEngine, + initDiagnostic)); } List configs = configIdIter.next(); @@ -1420,7 +1441,8 @@ private List getReinitializeParams() { } @Test - public void testExecuteException() { + public void testExecuteException() + { this.performTest(() -> { SzAutoCoreEnvironment env = SzAutoCoreEnvironment.newAutoBuilder().build(); try { @@ -1443,7 +1465,7 @@ public void testExecuteException() { public void testReinitialize(Long startConfig, Long endConfig, boolean initEngine, - boolean initDiagnostic) + boolean initDiagnostic) { this.performTest(() -> { SzAutoCoreEnvironment env = null; @@ -1495,18 +1517,19 @@ public void testReinitialize(Long startConfig, }); } - private static class MockEnvironment extends SzAutoCoreEnvironment { + private static class MockEnvironment extends SzAutoCoreEnvironment + { private int configIndex = 0; private boolean bumpOnReinitialize = false; - - public MockEnvironment(String instanceName, String settings) + + public MockEnvironment(String instanceName, String settings) throws SzException { super(SzAutoCoreEnvironment.newAutoBuilder() .settings(settings).instanceName(instanceName) .configRefreshPeriod(REACTIVE_CONFIG_REFRESH)); - + // revert the default config SzConfigManager configMgr = this.getConfigManager(); configMgr.setDefaultConfig( @@ -1514,63 +1537,75 @@ public MockEnvironment(String instanceName, String settings) // ensure we initialize this.getEngine(); - } - public void setBumpOnReinitialize(boolean bump) { + public void setBumpOnReinitialize(boolean bump) + { this.bumpOnReinitialize = bump; } - protected boolean ensureConfigCurrent() throws SzException { - this.bumpConfig(); // ensure config is out of sync + protected boolean ensureConfigCurrent() + throws SzException + { + this.bumpConfig(); + // ensure config is out of sync return super.ensureConfigCurrent(); } @Override - public void reinitialize(long configId) throws SzException { + public void reinitialize(long configId) + throws SzException + { super.reinitialize(configId); if (this.bumpOnReinitialize) { - this.bumpConfig(); // keep the config out of sync + this.bumpConfig(); + // keep the config out of sync } } - private void bumpConfig() throws SzException { + private void bumpConfig() + throws SzException + { SzConfigManager configMgr = this.getConfigManager(); - SzConfig config = configMgr.createConfig(configMgr.getDefaultConfigId()); - String dataSource = ("DUMMY_SOURCE_" - + TextUtilities.randomAlphanumericText(5) - + "-" + (++configIndex)).toUpperCase(); + SzConfig config + = configMgr.createConfig(configMgr.getDefaultConfigId()); + String dataSource = ("DUMMY_SOURCE_" + + TextUtilities.randomAlphanumericText(5) + + "-" + + (++configIndex)).toUpperCase(); config.registerDataSource(dataSource); configMgr.setDefaultConfig(config.export(), "Added " + dataSource); } } - public static class MockRetryCallable implements Callable { + public static class MockRetryCallable implements Callable + { private List retryList = null; private String errorMessage = null; - - public MockRetryCallable(boolean succeedOnRetry) + + public MockRetryCallable(boolean succeedOnRetry) { this(succeedOnRetry, TextUtilities.randomAlphanumericText(20)); } - public MockRetryCallable(int failureCount) + public MockRetryCallable(int failureCount) { this(failureCount, TextUtilities.randomAlphanumericText(20)); } public MockRetryCallable(boolean succeedOnRetry, - String errorMessage) + String errorMessage) { this.retryList = new LinkedList<>(); this.retryList.add(Boolean.FALSE); this.retryList.add(succeedOnRetry); - this.errorMessage = errorMessage; + this.errorMessage = errorMessage; } - public MockRetryCallable(int failureCount, String errorMessage) { + public MockRetryCallable(int failureCount, String errorMessage) + { this.retryList = new LinkedList<>(); for (int index = 0; index < failureCount; index++) { this.retryList.add(Boolean.FALSE); @@ -1578,12 +1613,15 @@ public MockRetryCallable(int failureCount, String errorMessage) { this.errorMessage = errorMessage; } - public String getErrorMessage() { + public String getErrorMessage() + { return this.errorMessage; } @Override - public Integer call() throws Exception { + public Integer call() + throws Exception + { Boolean succeed = this.retryList.remove(0); if (!succeed) { // use the list size as mock error code @@ -1594,7 +1632,8 @@ public Integer call() throws Exception { } @Test - public void mockRetryTest() { + public void mockRetryTest() + { this.performTest(() -> { SzAutoCoreEnvironment env = null; @@ -1675,7 +1714,8 @@ public void mockRetryTest() { } @Test - public void constructNegativeConcurrencyTest() { + public void constructNegativeConcurrencyTest() + { this.performTest(() -> { try { new SzAutoCoreEnvironment( @@ -1696,7 +1736,8 @@ public Integer getConcurrency() { } @Test - public void constructNegativeMaxRetriesTest() { + public void constructNegativeMaxRetriesTest() + { this.performTest(() -> { try { new SzAutoCoreEnvironment( @@ -1717,7 +1758,8 @@ public int getMaxBasicRetries() { } @Test - public void constructNegativeConfigRefreshPeriodTest() { + public void constructNegativeConfigRefreshPeriodTest() + { this.performTest(() -> { try { new SzAutoCoreEnvironment( @@ -1738,7 +1780,8 @@ public Duration getConfigRefreshPeriod() { } @Test - public void builderFixedConfigWithRefreshTest() { + public void builderFixedConfigWithRefreshTest() + { this.performTest(() -> { SzEnvironment env = null; try { @@ -1763,7 +1806,8 @@ public void builderFixedConfigWithRefreshTest() { }); } - public List getConcurrencyParameters() { + public List getConcurrencyParameters() + { List result = new ArrayList<>(); result.add(null); result.add(0); @@ -1776,7 +1820,8 @@ public List getConcurrencyParameters() { @ParameterizedTest @MethodSource("getConcurrencyParameters") - public void builderConcurrencyTest(Integer concurrency) { + public void builderConcurrencyTest(Integer concurrency) + { this.performTest(() -> { SzAutoCoreEnvironment env = null; @@ -1819,7 +1864,8 @@ public void builderConcurrencyTest(Integer concurrency) { }); } - public List getConfigRefreshPeriodParameters() { + public List getConfigRefreshPeriodParameters() + { List result = new ArrayList<>(); result.add(null); result.add(Duration.ofSeconds(0)); @@ -1831,7 +1877,8 @@ public List getConfigRefreshPeriodParameters() { @ParameterizedTest @MethodSource("getConfigRefreshPeriodParameters") - public void builderConfigRefreshPeriodTest(Duration duration) { + public void builderConfigRefreshPeriodTest(Duration duration) + { this.performTest(() -> { SzAutoCoreEnvironment env = null; @@ -1877,7 +1924,8 @@ public void builderConfigRefreshPeriodTest(Duration duration) { }); } - public List getMaxBasicRetryParameters() { + public List getMaxBasicRetryParameters() + { List result = new ArrayList<>(); result.add(0); result.add(1); @@ -1889,7 +1937,8 @@ public List getMaxBasicRetryParameters() { @ParameterizedTest @MethodSource("getMaxBasicRetryParameters") - public void builderMaxBasicRetryTest(int maxRetries) { + public void builderMaxBasicRetryTest(int maxRetries) + { this.performTest(() -> { SzAutoCoreEnvironment env = null; @@ -1929,7 +1978,8 @@ public void builderMaxBasicRetryTest(int maxRetries) { } @Test - public void formatStackTraceTest() { + public void formatStackTraceTest() + { this.performTest(() -> { StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); @@ -1938,7 +1988,8 @@ public void formatStackTraceTest() { } @Test - public void maxReinitializeTest() { + public void maxReinitializeTest() + { this.performTest(() -> { String instanceName = this.getInstanceName(); String settings = this.getRepoSettings();