Skip to content

[RORDEV-1435] Improved patching algorithm#1095

Merged
mgoworko merged 38 commits intosscarduzio:developfrom
mgoworko:feature/rordev-1435-improved-patching-algorithm
May 8, 2025
Merged

[RORDEV-1435] Improved patching algorithm#1095
mgoworko merged 38 commits intosscarduzio:developfrom
mgoworko:feature/rordev-1435-improved-patching-algorithm

Conversation

@mgoworko
Copy link
Collaborator

@mgoworko mgoworko commented Apr 1, 2025

🧐Enhancement (ES) Patcher - more robust Elasticsearch patcher + better logs messages

Summary by CodeRabbit

  • Chores

    • Updated the build pipeline to use Ubuntu 22.04 for improved compatibility and performance.
    • Renamed environment variables related to Elasticsearch patching consent for clearer user understanding.
  • New Features

    • Introduced a unified Elasticsearch patch executor with enhanced patch status reporting and error handling.
    • Added detailed error messages and structured error types to improve user feedback during patching.
    • Improved patching consent flow with explicit handling of no input and silent mode guidance.
  • Bug Fixes

    • Corrected command argument formatting for Elasticsearch patching commands.
  • Refactor

    • Simplified patching logic by renaming methods and using boolean patch status checks.
    • Removed deprecated patch action classes and logging decorators to streamline codebase.
    • Enhanced test coverage for patching, unpatching, and verification commands, including interactive consent scenarios.
    • Updated input reading methods to safely handle absent input by returning optional values.
    • Modified patching methods to return detailed metadata about patched files for better tracking.
    • Added patch metadata management to track file hashes and detect unauthorized modifications.
    • Improved internal patch verification with more specific status cases and error handling.
    • Streamlined Java environment selection and patching options in installation scripts based on version checks.
    • Added file hash calculation and patch metadata encoding/decoding for robust patch state tracking.
    • Refactored patch classes to unify patching operations and metadata reporting.
    • Introduced JAR manifest modification to record patch version and detect patched files.
    • Enhanced plugin directory metadata handling with structured patch information.
    • Updated test utilities and input mocking to support optional input scenarios.

@mgoworko mgoworko force-pushed the feature/rordev-1435-improved-patching-algorithm branch from 52965d0 to 67157a1 Compare April 1, 2025 19:04
@mgoworko mgoworko marked this pull request as ready for review April 2, 2025 17:40
@mgoworko mgoworko requested a review from coutoPL April 2, 2025 17:46
@coderabbitai

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

@mgoworko mgoworko requested a review from coutoPL April 5, 2025 19:37
coderabbitai[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as outdated.

coderabbitai[bot]

This comment was marked as outdated.

@mgoworko mgoworko requested a review from coutoPL April 12, 2025 20:32
coderabbitai[bot]

This comment was marked as outdated.

coderabbitai[bot]

This comment was marked as outdated.

Copy link
Collaborator

@coutoPL coutoPL left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great! It seems all the important things we already have here. Only small minor things left

mgoworko added 2 commits May 7, 2025 00:03
…5-improved-patching-algorithm

# Conflicts:
#	gradle.properties
@mgoworko mgoworko requested a review from coutoPL May 6, 2025 22:06
coderabbitai[bot]

This comment was marked as outdated.


def addPatchedByRorVersionProperty(file: File, rorVersion: String): Unit = {
Using(new JarFile(file.toJava)) { jarFile =>
val tempJarFile = File(s"temp-${UUID.randomUUID()}.jar")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we use this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to revert that change. Using temporary file break the patcher - I did not investigate it, but probably some kind of permissions problem. Temp file is created in /temp directory, but then in this part of code we copy and replace the original jar with this temp file.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, let's leave the comment

@mgoworko mgoworko requested a review from coutoPL May 7, 2025 20:52
coderabbitai[bot]

This comment was marked as resolved.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
ror-tools-core/src/main/scala/tech/beshu/ror/tools/core/patches/internal/filePatchers/JarManifestModifier.scala (1)

33-33: Consider using temporary file utilities

The current implementation creates a temporary file in the working directory rather than using better-files' temporary file utilities that would handle cleanup automatically.

-  val tempJarFile = File(s"temp-${UUID.randomUUID()}.jar")
+  val tempJarFile = File.newTemporaryFile("temp-", ".jar")
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7bc476e and 49dc936.

📒 Files selected for processing (2)
  • ror-tools-core/src/main/scala/tech/beshu/ror/tools/core/patches/base/EsPatchExecutor.scala (1 hunks)
  • ror-tools-core/src/main/scala/tech/beshu/ror/tools/core/patches/internal/filePatchers/JarManifestModifier.scala (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (11)
  • GitHub Check: ror (Run all tests IT_es67x)
  • GitHub Check: ror (Run all tests IT_es70x)
  • GitHub Check: ror (Run all tests IT_es80x)
  • GitHub Check: ror (Run all tests IT_es710x)
  • GitHub Check: ror (Run all tests IT_es810x)
  • GitHub Check: ror (Run all tests IT_es717x)
  • GitHub Check: ror (Run all tests IT_es818x)
  • GitHub Check: ror (Run all tests UNIT)
  • GitHub Check: ror (Run all tests IT_es90x)
  • GitHub Check: ror (Run all tests LICENSE)
  • GitHub Check: ror (CVE check Job)
🔇 Additional comments (9)
ror-tools-core/src/main/scala/tech/beshu/ror/tools/core/patches/internal/filePatchers/JarManifestModifier.scala (3)

31-41: Well-implemented resource management with Using blocks

The code correctly uses Scala's Using construct to ensure proper resource management for both the JarFile and JarOutputStream, preventing resource leaks.


43-51: Clean implementation of findPatchedFiles with proper resource handling

This implementation properly manages resources and handles potential exceptions when scanning JAR files for the ROR version property. The flatMap with Using.toOption.flatten pattern is a clean way to filter out JARs that don't contain the property.


55-64: Efficient and resource-safe JAR content copying

The method correctly handles streaming JAR entries and ensures all resources are properly closed via the inner Using block for the input stream.

ror-tools-core/src/main/scala/tech/beshu/ror/tools/core/patches/base/EsPatchExecutor.scala (6)

36-46: Clear patch logic with proper error handling

The patch method follows a good pattern by checking state first and then performing actions, with clear error handling using Either for domain errors.


73-85: Inconsistent error handling in doPatch

While domain errors are properly returned as Either[RorToolsError, Unit], technical errors from esPatch.performPatching() are thrown as exceptions. This is inconsistent with the functional approach used elsewhere.

Based on past review discussions, this appears to be an intentional design decision to distinguish between expected domain errors and unexpected technical failures.

Confirm that exceptions are meant to be thrown for technical failures only (like file I/O issues), while business logic errors like "already patched" should be returned as Either values.


108-127: Comprehensive patch status detection logic

The method thoroughly checks for various patch states, considering both metadata version compatibility and file integrity. This ensures reliable detection of patched, unpatched, and corrupted states.


129-148: Well-documented corruption detection for legacy patches

The additional checking for corrupted patch states without valid metadata is well-commented and handles an important edge case where JAR files might have been patched but metadata is missing.


154-157: Exhaustive pattern matching in validatePatchedFiles

The pattern matching now properly handles all possible cases, including when both lists are empty (case _ => Right(())). This prevents potential MatchError during runtime.


193-204: Clean pattern for converting domain errors to user-facing errors

The PatchProblemOps implicit class provides a clean way to convert internal patch problems to user-facing error messages, enhancing separation of concerns.

Copy link
Collaborator

@coutoPL coutoPL left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
ror-tools-core/src/main/scala/tech/beshu/ror/tools/core/patches/internal/filePatchers/JarManifestModifier.scala (2)

31-42: Improve temp file creation and cleanup

The temp file creation uses a UUID-based approach that creates the file in the current directory, which may have permission issues in some environments. Consider using java.io.File.createTempFile() instead to create the file in the system's temp directory.

Also, consider adding explicit cleanup for the temp file in case the move operation fails.

-  val tempJarFile = File(s"temp-${UUID.randomUUID()}.jar")
+  val tempFile = java.io.File.createTempFile("ror-jar-modifier-", ".jar")
+  tempFile.deleteOnExit() // Ensure cleanup
+  val tempJarFile = File(tempFile)

44-52: Consider limiting directory traversal depth

The directory.walk() call will recursively scan all subdirectories, which could potentially process a large number of files in a deep directory structure. Consider adding a depth limit or more specific filtering to improve performance.

-  directory.walk().filter(_.name.endsWith(".jar")).toList.flatMap { file =>
+  directory.walk(maxDepth = 2).filter(_.name.endsWith(".jar")).toList.flatMap { file =>
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 49dc936 and 2329ca0.

📒 Files selected for processing (1)
  • ror-tools-core/src/main/scala/tech/beshu/ror/tools/core/patches/internal/filePatchers/JarManifestModifier.scala (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (11)
  • GitHub Check: ror (Run all tests IT_es67x)
  • GitHub Check: ror (Run all tests IT_es70x)
  • GitHub Check: ror (Run all tests IT_es80x)
  • GitHub Check: ror (Run all tests IT_es710x)
  • GitHub Check: ror (Run all tests IT_es810x)
  • GitHub Check: ror (Run all tests IT_es717x)
  • GitHub Check: ror (CVE check Job)
  • GitHub Check: ror (Run all tests IT_es90x)
  • GitHub Check: ror (Run all tests IT_es818x)
  • GitHub Check: ror (Run all tests UNIT)
  • GitHub Check: ror (Run all tests LICENSE)
🔇 Additional comments (2)
ror-tools-core/src/main/scala/tech/beshu/ror/tools/core/patches/internal/filePatchers/JarManifestModifier.scala (2)

56-65: Good implementation of jar content copying

The implementation correctly addresses previous review comments by properly handling resource management and fixing the JAR entry copying issue. Each entry's input stream is now properly obtained and closed.


47-50: Robust error handling for jar file processing

Good use of the Using and Option pattern to safely handle JAR files and gracefully manage potential issues. The flattening of the option ensures that only valid patched JARs are returned.

@mgoworko mgoworko merged commit b9516d4 into sscarduzio:develop May 8, 2025
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants