Skip to content

feat:[NEXT-287] Direct aws, azure & gcp to the asset state service#2346

Open
kevin-paladin wants to merge 2 commits into
masterfrom
NEXT-287-route-to-asset-state-service
Open

feat:[NEXT-287] Direct aws, azure & gcp to the asset state service#2346
kevin-paladin wants to merge 2 commits into
masterfrom
NEXT-287-route-to-asset-state-service

Conversation

@kevin-paladin
Copy link
Copy Markdown
Collaborator

@kevin-paladin kevin-paladin commented Nov 26, 2024

Description

Send the asset state service start event when finished processing assets. Currently, these are aws, azure & gcp.

NOTE: The asset state service in the ce-extensions repository must be deployed and validated prior to deploying this change.

Type of change

  • New feature (non-breaking change which adds functionality)

How Has This Been Tested?

Manually validated sending event.

Checklist:

  • My code follows the style guidelines of this project
  • My commit message/PR follows the contribution guidelines of this project
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas

Summary by CodeRabbit

  • New Features

    • Enhanced data shipping functionality to handle specific asset types (Azure, AWS, GCP) with updated messaging processes.
    • Introduced new fields in job completion messages to include tenant information and asset types.
  • Bug Fixes

    • Improved logging for message IDs based on event types.
  • Documentation

    • Updated documentation to reflect changes in the JobDoneMessage structure and usage.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Nov 26, 2024

Walkthrough

The changes in this pull request primarily focus on modifying the shipData method in the Main class to enhance its handling of asset-related data. A new conditional pathway has been introduced for specific data sources, allowing for the retrieval and processing of asset types. Additionally, the JobDoneMessage class has been updated to include new fields and constructors, improving its capability to convey job completion details, particularly for asset-related tasks.

Changes

File Change Summary
jobs/pacman-data-shipper/src/main/java/com/tmobile/cso/pacman/datashipper/Main.java - Modified shipData method logic to include a new conditional block for asset types ("azure", "aws", "gcp").
- Added imports for ConfigManager and AssetStateStartEvent.
- Updated logging statements for message IDs.
commons/pac-batch-commons/src/main/java/com/tmobile/pacman/commons/dto/JobDoneMessage.java - Added fields: tenantId, tenantName, and assetTypes.
- Modified constructors to accommodate new fields.
- Added getter methods for new fields.

Possibly related PRs

Suggested reviewers

  • plyubich
  • rnithinpaladin

🐇 In the code, I hop and play,
New pathways bloom, bright as day.
With asset types, we now can see,
A message sent, as swift as can be!
Changes made, with care and cheer,
Let’s celebrate, the code is clear! 🥕


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown
Contributor

@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: 6

🧹 Outside diff range and nitpick comments (5)
commons/pac-batch-commons/src/main/java/com/tmobile/pacman/commons/dto/AssetStateStartEvent.java (1)

1-20: Consider implementing builder pattern

Given the number of parameters and validation requirements, consider implementing the builder pattern for better object construction and validation.

Would you like me to provide an example implementation of the builder pattern for this class?

commons/pac-batch-commons/src/main/java/com/tmobile/pacman/commons/aws/sqs/SQSManager.java (2)

45-47: Consider architectural improvements for message handling.

The class exhibits several architectural concerns:

  1. Inconsistent serialization strategies between JobDoneMessage (JSON) and AssetStateStartEvent (command line)
  2. Multiple responsibilities in message handling
  3. Hardcoded environmental variable names

Consider these improvements:

  1. Create a common message interface with a consistent serialization strategy
  2. Extract message-specific logic into separate handler classes
  3. Move environment variable names to a configuration class

Example interface:

public interface QueueMessage {
    String serialize();
}

Example configuration:

public final class SQSConfig {
    public static final String BASE_ACCOUNT_ENV = "BASE_AWS_ACCOUNT";
    public static final String ROLE_NAME_ENV = "PALADINCLOUD_RO";
    public static final String REGION_ENV = "REGION";
}

Also applies to: 51-57


45-47: Enhance error handling and logging.

The error handling and logging strategy could be improved:

  1. Add correlation IDs for request tracing
  2. Use structured logging for better observability
  3. Consider throwing custom exceptions instead of returning null

Example improvements:

public class SQSException extends RuntimeException {
    public SQSException(String message, Throwable cause) {
        super(message, cause);
    }
}

private String sendMessage(String messageBody, String url) {
    String correlationId = UUID.randomUUID().toString();
    LOGGER.debug("Sending message to SQS. correlationId={}, queueUrl={}", 
        correlationId, url);
    
    try {
        AmazonSQS sqs = generateSQSClient();
        if (sqs == null) {
            throw new SQSException("Failed to initialize SQS client", null);
        }
        SendMessageResult result = sqs.sendMessage(/* ... */);
        LOGGER.info("Message sent successfully. correlationId={}, messageId={}", 
            correlationId, result.getMessageId());
        return result.getMessageId();
    } catch (Exception e) {
        LOGGER.error("Failed to send message. correlationId={}, error={}", 
            correlationId, e.getMessage(), e);
        throw new SQSException("Failed to send message", e);
    }
}

Also applies to: 67-77

jobs/pacman-data-shipper/src/main/java/com/tmobile/cso/pacman/datashipper/Main.java (2)

115-117: Refactor to use a Set for data source comparison

Using a Set for comparing data sources enhances scalability and readability, especially if more data sources are added in the future.

Consider applying this diff to refactor the comparison:

+ Set<String> assetDataSources = new HashSet<>(Arrays.asList("azure", "aws", "gcp"));
+ boolean isAsset = assetDataSources.contains(ds.toLowerCase());
- boolean isAsset = ds.equalsIgnoreCase("azure")
-     || ds.equalsIgnoreCase("aws")
-     || ds.equalsIgnoreCase("gcp");

125-125: Use appropriate logging levels for message IDs

Currently, LOGGER.debug is used to log the SQS message IDs. Depending on the importance of tracking these IDs in production, consider using LOGGER.info to ensure they appear in standard logs.

Also applies to: 130-130

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 985e7cf and 08f17fc.

📒 Files selected for processing (3)
  • commons/pac-batch-commons/src/main/java/com/tmobile/pacman/commons/aws/sqs/SQSManager.java (2 hunks)
  • commons/pac-batch-commons/src/main/java/com/tmobile/pacman/commons/dto/AssetStateStartEvent.java (1 hunks)
  • jobs/pacman-data-shipper/src/main/java/com/tmobile/cso/pacman/datashipper/Main.java (2 hunks)
🔇 Additional comments (4)
commons/pac-batch-commons/src/main/java/com/tmobile/pacman/commons/dto/AssetStateStartEvent.java (1)

1-20: Verify the command line format compatibility

Ensure that the command line format matches the expected format in the asset state service.

commons/pac-batch-commons/src/main/java/com/tmobile/pacman/commons/aws/sqs/SQSManager.java (1)

26-26: LGTM!

The import statement for AssetStateStartEvent is appropriately placed with other DTO imports.

jobs/pacman-data-shipper/src/main/java/com/tmobile/cso/pacman/datashipper/Main.java (2)

124-124: Verify usage of sendMessage vs. sendSQSMessage in SQSManager

Different methods are used to send messages: sendMessage for assetStateStartEvent and sendSQSMessage for jobDoneMessage. Please verify that both methods exist in SQSManager and are intended for their respective message types to ensure consistency and correctness.

Also applies to: 129-129


127-127: Confirm passing null as the last parameter to JobDoneMessage constructor

Passing null as the last parameter in new JobDoneMessage(ds + "-Shipper-Job", tenantId, ds, null) may not be appropriate if the constructor expects a non-null value. Please verify whether null is acceptable or if a valid value should be provided.

Comment on lines +1 to +8
package com.tmobile.pacman.commons.dto;

public class AssetStateStartEvent {
private final String tenantId;
private final String dataSource;
private final String[] assetTypes;
private final boolean isFromPolicyEngine;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add class-level documentation and strengthen immutability

The class lacks documentation explaining its purpose and usage. Additionally, the assetTypes array field could be modified externally, breaking immutability.

Add documentation and defensive copying:

 package com.tmobile.pacman.commons.dto;

+/**
+ * Data Transfer Object representing an asset state start event.
+ * Used to notify the asset state service when asset processing begins
+ * for AWS, Azure, and GCP platforms.
+ */
 public class AssetStateStartEvent {
     private final String tenantId;
     private final String dataSource;
-    private final String[] assetTypes;
+    private final String[] assetTypes; // Consider using List<String> or making defensive copies
     private final boolean isFromPolicyEngine;

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +9 to +14
public AssetStateStartEvent(String tenantId, String dataSource, String[] assetTypes, boolean isFromPolicyEngine) {
this.tenantId = tenantId;
this.dataSource = dataSource;
this.assetTypes = assetTypes;
this.isFromPolicyEngine = isFromPolicyEngine;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add parameter validation and defensive copying

The constructor should validate input parameters and make a defensive copy of the array to prevent external modifications.

Apply this improvement:

     public AssetStateStartEvent(String tenantId, String dataSource, String[] assetTypes, boolean isFromPolicyEngine) {
+        if (tenantId == null || tenantId.trim().isEmpty()) {
+            throw new IllegalArgumentException("tenantId cannot be null or empty");
+        }
+        if (dataSource == null || dataSource.trim().isEmpty()) {
+            throw new IllegalArgumentException("dataSource cannot be null or empty");
+        }
+        if (assetTypes == null || assetTypes.length == 0) {
+            throw new IllegalArgumentException("assetTypes cannot be null or empty");
+        }
         this.tenantId = tenantId;
         this.dataSource = dataSource;
-        this.assetTypes = assetTypes;
+        this.assetTypes = assetTypes.clone(); // Defensive copy
         this.isFromPolicyEngine = isFromPolicyEngine;
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public AssetStateStartEvent(String tenantId, String dataSource, String[] assetTypes, boolean isFromPolicyEngine) {
this.tenantId = tenantId;
this.dataSource = dataSource;
this.assetTypes = assetTypes;
this.isFromPolicyEngine = isFromPolicyEngine;
}
public AssetStateStartEvent(String tenantId, String dataSource, String[] assetTypes, boolean isFromPolicyEngine) {
if (tenantId == null || tenantId.trim().isEmpty()) {
throw new IllegalArgumentException("tenantId cannot be null or empty");
}
if (dataSource == null || dataSource.trim().isEmpty()) {
throw new IllegalArgumentException("dataSource cannot be null or empty");
}
if (assetTypes == null || assetTypes.length == 0) {
throw new IllegalArgumentException("assetTypes cannot be null or empty");
}
this.tenantId = tenantId;
this.dataSource = dataSource;
this.assetTypes = assetTypes.clone(); // Defensive copy
this.isFromPolicyEngine = isFromPolicyEngine;
}

Comment on lines +16 to +19
public String toCommandLine() {
return String.format("--tenant_id=%s --data_source=%s --asset_types=%s --is_from_policy_engine=%s",
tenantId, dataSource, String.join(",", assetTypes), isFromPolicyEngine);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add input escaping and getter methods

  1. The toCommandLine method should escape special characters to prevent command injection.
  2. Consider adding getter methods as this is a DTO.

Add getters and improve command line safety:

+    public String getTenantId() {
+        return tenantId;
+    }
+
+    public String getDataSource() {
+        return dataSource;
+    }
+
+    public String[] getAssetTypes() {
+        return assetTypes.clone(); // Return defensive copy
+    }
+
+    public boolean isFromPolicyEngine() {
+        return isFromPolicyEngine;
+    }
+
     public String toCommandLine() {
+        // Escape special characters in values
+        String escapedTenantId = escapeCommandLineArg(tenantId);
+        String escapedDataSource = escapeCommandLineArg(dataSource);
+        String escapedAssetTypes = escapeCommandLineArg(String.join(",", assetTypes));
         return String.format("--tenant_id=%s --data_source=%s --asset_types=%s --is_from_policy_engine=%s",
-            tenantId, dataSource, String.join(",", assetTypes), isFromPolicyEngine);
+            escapedTenantId, escapedDataSource, escapedAssetTypes, isFromPolicyEngine);
     }
+
+    private String escapeCommandLineArg(String value) {
+        return value.replace("\"", "\\\"").replace("'", "\\'");
+    }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public String toCommandLine() {
return String.format("--tenant_id=%s --data_source=%s --asset_types=%s --is_from_policy_engine=%s",
tenantId, dataSource, String.join(",", assetTypes), isFromPolicyEngine);
}
public String getTenantId() {
return tenantId;
}
public String getDataSource() {
return dataSource;
}
public String[] getAssetTypes() {
return assetTypes.clone(); // Return defensive copy
}
public boolean isFromPolicyEngine() {
return isFromPolicyEngine;
}
public String toCommandLine() {
// Escape special characters in values
String escapedTenantId = escapeCommandLineArg(tenantId);
String escapedDataSource = escapeCommandLineArg(dataSource);
String escapedAssetTypes = escapeCommandLineArg(String.join(",", assetTypes));
return String.format("--tenant_id=%s --data_source=%s --asset_types=%s --is_from_policy_engine=%s",
escapedTenantId, escapedDataSource, escapedAssetTypes, isFromPolicyEngine);
}
private String escapeCommandLineArg(String value) {
return value.replace("\"", "\\\"").replace("'", "\\'");
}

Comment on lines +45 to +47
public String sendMessage(AssetStateStartEvent message, String url) {
return sendMessage(message.toCommandLine(), url);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add input validation, documentation, and improve method naming.

The new method needs several improvements:

  1. Add null parameter validation
  2. Add Javadoc documentation
  3. Consider a more specific method name like sendAssetStateEvent
  4. Consider throwing an exception instead of returning null on failure

Here's the suggested implementation:

+    /**
+     * Sends an asset state start event to the specified SQS queue.
+     *
+     * @param message The asset state event to send. Must not be null.
+     * @param url The SQS queue URL. Must not be null.
+     * @return The message ID if successful, null otherwise.
+     * @throws IllegalArgumentException if message or url is null
+     */
-    public String sendMessage(AssetStateStartEvent message, String url) {
-        return sendMessage(message.toCommandLine(), url);
+    public String sendAssetStateEvent(AssetStateStartEvent message, String url) {
+        if (message == null || url == null) {
+            throw new IllegalArgumentException("Message and URL must not be null");
+        }
+        return sendMessage(message.toCommandLine(), url);
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public String sendMessage(AssetStateStartEvent message, String url) {
return sendMessage(message.toCommandLine(), url);
}
/**
* Sends an asset state start event to the specified SQS queue.
*
* @param message The asset state event to send. Must not be null.
* @param url The SQS queue URL. Must not be null.
* @return The message ID if successful, null otherwise.
* @throws IllegalArgumentException if message or url is null
*/
public String sendAssetStateEvent(AssetStateStartEvent message, String url) {
if (message == null || url == null) {
throw new IllegalArgumentException("Message and URL must not be null");
}
return sendMessage(message.toCommandLine(), url);
}

AssetStateStartEvent assetStateStartEvent =
new AssetStateStartEvent(tenantId, ds, assetTypes.toArray(new String[0]), false);
String sqsMessageID =
sqsManager.sendMessage(assetStateStartEvent, System.getenv("ASSET_STATE_QUEUE_URL"));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Handle missing environment variables to prevent runtime exceptions

System.getenv("ASSET_STATE_QUEUE_URL") and System.getenv("SHIPPER_SQS_QUEUE_URL") may return null if the environment variables are not set. This could lead to a NullPointerException when sending messages. Please ensure that these environment variables are validated before use.

Consider adding null checks and handling missing environment variables:

+ String assetStateQueueUrl = System.getenv("ASSET_STATE_QUEUE_URL");
+ if (assetStateQueueUrl == null) {
+     LOGGER.error("Environment variable ASSET_STATE_QUEUE_URL is not set");
+     // Handle the error, e.g., throw an exception or use a default value
+ }
  String sqsMessageID =
      sqsManager.sendMessage(assetStateStartEvent, assetStateQueueUrl);

...

+ String shipperSqsQueueUrl = System.getenv("SHIPPER_SQS_QUEUE_URL");
+ if (shipperSqsQueueUrl == null) {
+     LOGGER.error("Environment variable SHIPPER_SQS_QUEUE_URL is not set");
+     // Handle the error accordingly
+ }
  String sqsMessageID =
      sqsManager.sendSQSMessage(jobDoneMessage, shipperSqsQueueUrl);

Also applies to: 129-129

Comment on lines +119 to +122
List<String> assetTypes = new ArrayList<>(ConfigManager.getTypesWithDisplayName(ds).keySet());
Collections.sort(assetTypes);
AssetStateStartEvent assetStateStartEvent =
new AssetStateStartEvent(tenantId, ds, assetTypes.toArray(new String[0]), false);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add null check for ConfigManager.getTypesWithDisplayName(ds) to prevent NullPointerException

If ConfigManager.getTypesWithDisplayName(ds) returns null, calling keySet() will result in a NullPointerException. It's important to add a null check to ensure the application handles this scenario gracefully.

Consider applying this diff to add the null check:

+ Map<String, String> typesWithDisplayName = ConfigManager.getTypesWithDisplayName(ds);
+ if (typesWithDisplayName != null) {
    List<String> assetTypes = new ArrayList<>(typesWithDisplayName.keySet());
    Collections.sort(assetTypes);
    AssetStateStartEvent assetStateStartEvent =
      new AssetStateStartEvent(tenantId, ds, assetTypes.toArray(new String[0]), false);
    String sqsMessageID =
      sqsManager.sendMessage(assetStateStartEvent, System.getenv("ASSET_STATE_QUEUE_URL"));
    LOGGER.debug("AssetState Start SQS message ID: {}", sqsMessageID);
+ } else {
+     LOGGER.error("Failed to retrieve asset types; typesWithDisplayName is null");
+     // Handle the error appropriately, e.g., throw an exception or set a default value
+ }

Committable suggestion skipped: line range outside the PR's diff.

plyubich
plyubich previously approved these changes Nov 27, 2024
Copy link
Copy Markdown
Contributor

@plyubich plyubich 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
Copy Markdown
Contributor

@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: 1

🧹 Outside diff range and nitpick comments (4)
commons/pac-batch-commons/src/main/java/com/tmobile/pacman/commons/dto/JobDoneMessage.java (3)

22-27: Consider consolidating tenant ID fields

Having two fields (paladinCloudTenantId and tenantId) for the same value increases maintenance overhead and could lead to confusion. Consider:

  1. Using a single field with a clear name
  2. Adding a deprecated annotation if backward compatibility is needed
  3. Planning for future consolidation
-    // NOTE: 'paladinCloudTenantId' is currently sent by the legacy shipper while 'tenantId' is sent
-    // by the delta engine; it's not clear if different recipients will use what's available so
-    // both are sent here.
-    private String paladinCloudTenantId;
-    @JsonProperty("tenant_id")
-    private String tenantId;
+    @JsonProperty(value = "tenant_id", access = JsonProperty.Access.WRITE_ONLY)
+    private String tenantId;
+    
+    @Deprecated
+    public String getPaladinCloudTenantId() {
+        return tenantId;
+    }

30-32: Maintain consistent JSON property naming convention

For consistency with tenant_name, consider adding @JsonProperty annotation to assetTypes using snake_case.

     @JsonProperty("tenant_name")
     private String tenantName;
-    private String[] assetTypes;
+    @JsonProperty("asset_types")
+    private String[] assetTypes;

67-68: Add JavaDoc for new getter methods

Consider adding JavaDoc comments to maintain consistency with other methods in the class.

+    /**
+     * Gets the tenant name.
+     * @return the tenant name
+     */
     public String getTenantName() { return tenantName; }
+
+    /**
+     * Gets the asset types.
+     * @return array of asset types
+     */
     public String[] getAssetTypes() { return assetTypes; }
jobs/pacman-data-shipper/src/main/java/com/tmobile/cso/pacman/datashipper/Main.java (1)

114-116: Optimize cloud provider checks and use constants

The current implementation uses multiple equalsIgnoreCase calls and magic strings. Consider using a Set for better performance and maintainability.

+    private static final Set<String> ASSET_PROVIDERS = Set.of("azure", "aws", "gcp");
+
-        boolean isAsset = ds.equalsIgnoreCase("azure")
-            || ds.equalsIgnoreCase("aws")
-            || ds.equalsIgnoreCase("gcp");
+        boolean isAsset = ASSET_PROVIDERS.contains(ds.toLowerCase());
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 08f17fc and 14e14b9.

📒 Files selected for processing (2)
  • commons/pac-batch-commons/src/main/java/com/tmobile/pacman/commons/dto/JobDoneMessage.java (2 hunks)
  • jobs/pacman-data-shipper/src/main/java/com/tmobile/cso/pacman/datashipper/Main.java (3 hunks)
🔇 Additional comments (2)
jobs/pacman-data-shipper/src/main/java/com/tmobile/cso/pacman/datashipper/Main.java (2)

118-124: ⚠️ Potential issue

Add null checks for ConfigManager and environment variables

The code needs to handle potential null values from ConfigManager and environment variables.

This is a duplicate of previous review comments. The same concerns about null checks for ConfigManager.getTypesWithDisplayName(ds) and validation of environment variables still apply. Please refer to the previous review comments for the suggested fixes.


111-130: Verify integration with asset state service

The implementation routes AWS, Azure, and GCP assets through the asset state service as intended. Let's verify the integration points.

✅ Verification successful

Integration with asset state service appears correctly implemented

The verification shows:

  • ASSET_STATE_QUEUE_URL is only referenced in the data shipper, maintaining clean separation
  • JobDoneMessage implementation supports both asset and non-asset flows with appropriate constructors
  • Other services (Qualys, Tenable, Aqua) use JobDoneMessage but route to ENRICHER_SQS_QUEUE_URL, showing proper separation of concerns
  • Asset state routing is exclusive to cloud provider assets (AWS, Azure, GCP)
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify asset state service integration points

# Check for asset state service configuration
echo "Checking for asset state service configuration..."
rg -l "ASSET_STATE_QUEUE_URL"

# Check for asset type definitions
echo "Checking asset type definitions for cloud providers..."
ast-grep --pattern 'getTypesWithDisplayName($provider)'

# Check for other potential consumers of JobDoneMessage
echo "Checking for JobDoneMessage consumers..."
rg -A 5 "JobDoneMessage"

Length of output: 11624

Comment on lines +74 to 82
public JobDoneMessage (String jobName, String paladinCloudTenantId, String source, String enricherSource, String tenantName, String[] assetTypes) {
this.jobName = jobName;
this.paladinCloudTenantId = paladinCloudTenantId;
this.tenantId = paladinCloudTenantId;
this.tenantName = tenantName;
this.source = source;
this.enricherSource = enricherSource;
this.assetTypes = assetTypes;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Implement defensive copying for array parameter

The assetTypes array should be defensively copied to prevent external modification of the internal state.

     public JobDoneMessage (String jobName, String paladinCloudTenantId, String source, String enricherSource, String tenantName, String[] assetTypes) {
         this.jobName = jobName;
         this.paladinCloudTenantId = paladinCloudTenantId;
         this.tenantId = paladinCloudTenantId;
         this.tenantName = tenantName;
         this.source = source;
         this.enricherSource = enricherSource;
-        this.assetTypes = assetTypes;
+        this.assetTypes = assetTypes != null ? assetTypes.clone() : null;
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public JobDoneMessage (String jobName, String paladinCloudTenantId, String source, String enricherSource, String tenantName, String[] assetTypes) {
this.jobName = jobName;
this.paladinCloudTenantId = paladinCloudTenantId;
this.tenantId = paladinCloudTenantId;
this.tenantName = tenantName;
this.source = source;
this.enricherSource = enricherSource;
this.assetTypes = assetTypes;
}
public JobDoneMessage (String jobName, String paladinCloudTenantId, String source, String enricherSource, String tenantName, String[] assetTypes) {
this.jobName = jobName;
this.paladinCloudTenantId = paladinCloudTenantId;
this.tenantId = paladinCloudTenantId;
this.tenantName = tenantName;
this.source = source;
this.enricherSource = enricherSource;
this.assetTypes = assetTypes != null ? assetTypes.clone() : null;
}

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Dec 2, 2024

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