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

Remove use of Properties for URL query parsing, fixes #6403 #6407

Merged

Conversation

EliasStihl
Copy link
Contributor

Fixes #6403

Changes proposed in this pull request:

  • Deprecate all methods in ParsingUtilities that return java.util.Properties.
  • Introduce a new method, static public Map<String, String> parseParameters(HttpServletRequest request), as a replacement for parseUrlParameters. This new method utilizes the request.getParameterMap() functionality for its implementation.
  • Modify all uses of parseUrlParameters to use the new method.
  • Adjust all necessary code to accommodate the new return type (Map<String, String>).
  • Deprecate all public methods ImportingUtilities that use java.util.Properties and make new versions of them using Map<String, String> instead.

@github-actions github-actions bot added Type: Feature Request Identifies requests for new features or enhancements. These involve proposing new improvements. refactoring labels Mar 1, 2024
@wetneb wetneb requested a review from tfmorris March 1, 2024 17:16
@EliasStihl
Copy link
Contributor Author

When I run the tests locally with ./refine test, all tests pass, any idea why the tests fail on the CI server @tfmorris ?

@tfmorris
Copy link
Member

tfmorris commented Mar 1, 2024 via email

@tfmorris
Copy link
Member

tfmorris commented Mar 1, 2024 via email

@tfmorris
Copy link
Member

tfmorris commented Mar 1, 2024

OK, I'm not sure why the test isn't failing locally (perhaps some difference in the test runner environment?), but the failure is real. I think what's needed is to update the mocks to implement HttpServletRequest.getParameterMap() rather than just HttpServletRequest.getParameter() as they do now

when(request.getParameter("databaseType")).thenReturn(testDbConfig.getDatabaseType());
when(request.getParameter("databaseServer")).thenReturn(testDbConfig.getDatabaseHost());
when(request.getParameter("databasePort")).thenReturn("" + testDbConfig.getDatabasePort());
when(request.getParameter("databaseUser")).thenReturn(testDbConfig.getDatabaseUser());
when(request.getParameter("databasePassword")).thenReturn(testDbConfig.getDatabasePassword());
when(request.getParameter("initialDatabase")).thenReturn(testDbConfig.getDatabaseName());
when(request.getParameter("query")).thenReturn(query);
when(request.getParameter("options")).thenReturn(JSON_OPTION);

@wetneb
Copy link
Sponsor Member

wetneb commented Mar 2, 2024

The local test suite does not have all tests of the database extension enabled, because those require having a running SQL server (of different flavors).
You can see in the CI configuration how they are enabled:

- name: Configure connections to databases
id: configure_db_connections
run: cat extensions/database/tests/conf/github_actions_tests.xml | sed -e "s/MYSQL_PORT/${{ job.services.mysql.ports[3306] }}/g" | sed -e "s/POSTGRES_PORT/${{ job.services.postgres.ports[5432] }}/g" > extensions/database/tests/conf/tests.xml
- name: Populate databases with test data
id: populate_databases_with_test_data
run: |
mysql -u root -h 127.0.0.1 -P ${{ job.services.mysql.ports[3306] }} -proot -e 'CREATE DATABASE test_db;'
mysql -u root -h 127.0.0.1 -P ${{ job.services.mysql.ports[3306] }} -proot < extensions/database/tests/conf/test-mysql.sql
psql -U postgres test_db -h 127.0.0.1 -p ${{ job.services.postgres.ports[5432] }} < extensions/database/tests/conf/test-pgsql.sql
env:
PGPASSWORD: postgres

@EliasStihl
Copy link
Contributor Author

Thank you for your responses, but unfortunately, I am not sure how I should move forward with this? I have tried, but I don't know how I should replicate the failures locally so it becomes very hard for me to test.

One small difference between the old URL parser and the new parser is that the old parser took the last value if the key was provided multiple times. However, @tfmorris explained in the issue that parameters could not be repeated. Therefore it shouldn't be a problem to return the first value like this return request.getParameterMap().entrySet().stream() .collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue()[0])); ?

@tfmorris
Copy link
Member

tfmorris commented Mar 2, 2024

@EliasStihl My apologies. The situation is definitely sub-optimal. The method I used to recreate the failure was to directly run the tests in DatabaseImportControllerTest using my IDE's test runner. I was using IntelliJ, but Eclipse should work as well. Without MySQL installed they won't all succeed, but they should give you enough insight to see what needs to be fixed.

The problem is not with your code, but with the test itself. It mocks getParameter(), but does not mock getParameterMap() which is what the new query parameter parser needs. Because there is other code which still depends on getParameter() they actually both need to be mocked and return the same data, so I'd suggest one or more helper methods be added to the test code.

We apparently don't have the database test environment setup documented for developers, which I will work on now, but you should be able to get away with just MySQL. Basically, you want to:

  1. Install MySQL, then run the two commands that @wetneb mentioned above:
  2. mysql -u root -h 127.0.0.1 -P <port, if non default> -proot -e 'CREATE DATABASE test_db;'
  3. `mysql -u root -h 127.0.0.1 -P -proot < extensions/database/tests/conf/test-mysql.sql
  4. Finally, remove this line from the test configuration file
    <exclude name="requiresMySQL"/>

If you get stuck, or this is too much hassle, let me know and I can fix up the PR so that we can get it merged.

@tfmorris
Copy link
Member

tfmorris commented Mar 2, 2024

Actually, I've got an easier solution. We'll just switch that test to use SQLite instead of MySQL. It doesn't look like I can push to your branch, so I've put the fix up in a branch on my repo. If you git cherry-pick this commit unto your branch, you should get test failures locally. tfmorris@89ee605

@EliasStihl EliasStihl force-pushed the issue-6403-parseUrl-properties branch from d45d5ab to 49f6ea6 Compare March 3, 2024 08:42
@EliasStihl
Copy link
Contributor Author

Once again, thank you for the incredible support! I think all tests pass now, but please let me know if there is anything you want me to change.

Copy link
Member

@tfmorris tfmorris left a comment

Choose a reason for hiding this comment

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

Looks great! Thank you for sticking with it! I'll merge it after #6412 gets merged so I can rebase it on top. I also have a couple of test helper methods for DatabaseImportControllerTest which will remove some of the duplication.

For future reference, it makes it easier for us to review if you push incremental fixes in separate commits rather than force pushing a completely new commit. That way we can easily separate stuff that's been reviewed already from the new stuff. All the commits will get squashed when we merge the PR, so there's no need to worry about the extra commits.

@tfmorris tfmorris self-assigned this Mar 4, 2024
@EliasStihl
Copy link
Contributor Author

Okay, sorry about that, but thanks for telling me so I know how to do it properly in the future!

@tfmorris tfmorris merged commit f487880 into OpenRefine:master Mar 4, 2024
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
refactoring Type: Feature Request Identifies requests for new features or enhancements. These involve proposing new improvements.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Remove use of java.util.Properties for URL query parsing utility
3 participants