Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Add empty policyMap when policies are empty or null to fix NPE #36374

Merged
merged 2 commits into from
Sep 18, 2024

Conversation

abhvsn
Copy link
Contributor

@abhvsn abhvsn commented Sep 17, 2024

Description

We have quite a lot of objects in the DB for which we expect the policies should be present but that's not the case. This is causing issues when we migrated to using policyMap where we didn't create empty map if the policies object is empty expecting all such entries are anyway not accessible to the user.
We can query mongodb to find such entries:

db
	.collectionName
	.find({
		policies: [],
		deletedAt: {$exists: false}
	})

We expect collections like plugins, customJSlibs etc to have empty values for policies and hence policyMap was not migrated for this, but we are seeing the same pattern for other collections as well like newAction, workspace etc. which is why we are seeing NPEs. With this PR we intend to remove this NPE by adding a empty map to policyMap field.

With prod dump this is taking 340sec so we need to plan accordingly.

/test Sanity

🔍 Cypress test results

Tip

🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
Workflow run: https://github.com/appsmithorg/appsmith/actions/runs/10903942123
Commit: c1573a6
Cypress dashboard.
Tags: @tag.Sanity
Spec:


Tue, 17 Sep 2024 13:41:53 UTC

Communication

Should the DevRel and Marketing teams inform users about this change?

  • Yes
  • No

Summary by CodeRabbit

  • New Features

    • Implemented a database migration to ensure all relevant documents have a defined policy map, improving data consistency.
  • Bug Fixes

    • Addressed issues where documents had null or missing policy maps by updating them to an empty policy map.

Copy link
Contributor

coderabbitai bot commented Sep 17, 2024

Walkthrough

The changes introduce a new migration class, Migration062AddEmptyPolicyMapForNullValues, which updates multiple MongoDB collections by adding an empty policy map to documents that have a null or non-existent policy map. The migration is performed reactively, ensuring non-blocking operations. It includes methods for executing the migration and a placeholder for rollback functionality, enhancing data consistency across the targeted collections.

Changes

File Path Change Summary
app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/... Added Migration062AddEmptyPolicyMapForNullValues class, including methods for executing migration and handling null policy maps.

Possibly related PRs

Suggested labels

Bug

Poem

In the realm of code where data flows,
A migration blooms, as the policy grows.
Nulls are banished, maps now defined,
Consistency reigns, in the code aligned.
With a dash of logic, and a sprinkle of care,
Our documents flourish, in the database air! 🌟


Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 74defca and c1573a6.

Files selected for processing (1)
  • app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration062AddEmptyPolicyMapForNullValues.java (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration062AddEmptyPolicyMapForNullValues.java

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 generate interesting stats about this repository and render them as a table.
    -- @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.

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.

@abhvsn abhvsn self-assigned this Sep 17, 2024
@github-actions github-actions bot added the skip-changelog Adding this label to a PR prevents it from being listed in the changelog label Sep 17, 2024
Copy link
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: 0

Outside diff range and nitpick comments (1)
app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration062AddEmptyPolicyMapForNullValues.java (1)

53-54: Consider adding a comment or removing the rollbackExecution method.

The rollbackExecution method is currently empty, which suggests that rollback is not implemented for this migration.

To improve clarity and maintainability, consider:

  • Adding a comment to explain why the method is empty and whether rollback is supported for this migration.
  • If rollback is not supported, consider removing the method altogether to avoid confusion.
Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 7aae152 and 74defca.

Files selected for processing (1)
  • app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration062AddEmptyPolicyMapForNullValues.java (1 hunks)
Additional comments not posted (3)
app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration062AddEmptyPolicyMapForNullValues.java (3)

1-100: Great job on the migration class structure! 👍

The Migration062AddEmptyPolicyMapForNullValues class follows the standard structure for a database migration script and is properly annotated with @ChangeUnit and @RequiredArgsConstructor. Defining the collection names as a constant set is a good practice for maintainability.

A few suggestions for improvement:

  • Consider adding a brief class-level Javadoc comment to describe the purpose of the migration.
  • Consider adding a comment to explain why the rollbackExecution method is empty, or remove it if rollback is not supported for this migration.

57-76: Excellent work on the execute method! 🌟

The execute method follows a reactive programming model using Mono to handle asynchronous operations efficiently. Using Mono.whenDelayError to run the migration in parallel across all collections is a smart approach. The method also properly handles and logs any errors that occur during the migration.

A couple of suggestions for improvement:

  • Consider extracting the error handling logic into a separate method to improve readability and reusability.
  • Consider adding more detailed logging statements to track the progress of the migration for each collection.

78-99: Fantastic work on the addEmptyPolicyMapForNullEntries method! 🎉

The method uses ReactiveMongoTemplate to perform the database operations, which is a standard approach in Spring Data MongoDB. Constructing the query using Criteria to identify the documents that need to be updated is a clear and concise approach. Using UpdateDefinition to set the policy map to an empty HashMap is a straightforward way to add the missing field.

A few suggestions for improvement:

  • Consider extracting the query construction logic into a separate method to improve readability and reusability.
  • Consider adding a comment to explain the purpose of the notDeletedCriteria and why it's included in the query.
  • Consider adding a log statement to indicate when no documents were modified for a collection.

@abhvsn abhvsn added the ok-to-test Required label for CI label Sep 17, 2024

private final ReactiveMongoTemplate mongoTemplate;

private static final Set<String> CE_COLLECTION_NAMES = Set.of(
Copy link
Member

Choose a reason for hiding this comment

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

Is it possible to use mongoTemplate and run this migration for every collection in the db? This way we can avoid adding a EE migration and also not missing any collection.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was hoping to mimic the policyMap refactor to have complete control over which collections are getting migrated. Should we just add the EE collection names as well in that case?

Copy link
Member

Choose a reason for hiding this comment

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

In that case lets stick to this approach, this will save us time in running this migration on prod. Yes we should add EE collection names and handle collection does not exists kind of errors if required.

Copy link
Contributor Author

@abhvsn abhvsn Sep 17, 2024

Choose a reason for hiding this comment

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

handle collection does not exists kind of errors if required.

This won't be required as no objects will be returned.

@abhvsn
Copy link
Contributor Author

abhvsn commented Sep 17, 2024

/build-deploy-preview skip-tests=true

Copy link

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/10903947230.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 36374.
recreate: .


final Query query = new Query().addCriteria(policyMapNotExists).addCriteria(notDeletedCriteria);
UpdateDefinition update = new Update().set(POLICY_MAP, new HashMap<>());
final Mono<UpdateResult> convertToMap = mongoTemplate.updateMulti(query, update, collectionName);
Copy link
Member

Choose a reason for hiding this comment

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

Can this result in an error state if the collection does not exist?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As mentioned above this is equivalent to db.random_collection.find() which doesn't return any result so should not be an issue for us.

Copy link

Deploy-Preview-URL: https://ce-36374.dp.appsmith.com

Copy link

Failed server tests

  • com.appsmith.server.solutions.DatasourceStructureSolutionTest#verifyUseNewStructureWhenIgnoreCacheSetTrue

@abhvsn abhvsn merged commit 0388f63 into release Sep 18, 2024
46 checks passed
@abhvsn abhvsn deleted the add-empty-policy-map branch September 18, 2024 01:56
Shivam-z pushed a commit to Shivam-z/appsmith that referenced this pull request Sep 26, 2024
…appsmithorg#36374)

## Description
We have quite a lot of objects in the DB for which we expect the
policies should be present but that's not the case. This is causing
issues when we migrated to using `policyMap` where we didn't create
empty map if the policies object is empty expecting all such entries are
anyway not accessible to the user.
We can query mongodb to find such entries:  
```
db
	.collectionName
	.find({
		policies: [],
		deletedAt: {$exists: false}
	})
```
We expect collections like plugins, customJSlibs etc to have empty
values for policies and hence policyMap was not migrated for this, but
we are seeing the same pattern for other collections as well like
newAction, workspace etc. which is why we are seeing NPEs. With this PR
we intend to remove this NPE by adding a empty map to policyMap field.

With prod dump this is taking 340sec so we need to plan accordingly.

/test Sanity

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/10903942123>
> Commit: c1573a6
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=10903942123&attempt=1"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.Sanity`
> Spec:
> <hr>Tue, 17 Sep 2024 13:41:53 UTC
<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [x] No


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Implemented a database migration to ensure all relevant documents have
a defined policy map, improving data consistency.
  
- **Bug Fixes**
- Addressed issues where documents had null or missing policy maps by
updating them to an empty policy map.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ok-to-test Required label for CI skip-changelog Adding this label to a PR prevents it from being listed in the changelog
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants