Add validation checks to Product Model

Description

Products (GlobalProduct and TradeItem) still could use validations and consistently formatted errors. In addition associated ProgramProducts and ProductCategories could also have basic validations.

Pull in and clean up v2 code so the service returns a validation error with translation properly in place. We want to share this as a finished working example of i18n for validation error messages in v3. This touches ProductCategoryController.java, ErrorResponse.java, etc in v3. There are some utility classes in v2 that handle message keys, reading from a messages.properties file, applying a Locale and doing variable substitution.

Acceptance Criteria

Attachments

2

QAlity Plus - Test Management

Checklists

Activity

Josh Zamor 
January 17, 2017 at 10:46 PM

Looks good to me, moving to done. Thanks.

Brandon Bowersox-Johnson 
January 17, 2017 at 12:55 AM

Everything we hoped for in this ticket has been achieved. I would like you to double-check before marking it Done.

A quick summary:

  • The simple case was done in December; I had addressed all the feedback in the Fisheye review on this ticket.

  • I also extracted the inner class Message.LocalMessage into its own class. That code (commit 3692869) was not reviewed but it's really simple.

  • The advanced case was recently done by Pawel Nawrocki in ticket OLMIS-1398. He did it basically the way you and I had discussed. There is currently an open review if you are interested. I am leaving him some feedback on that review based on the advice you had given to me. That work is happening in that ticket, so I don't think we need to wait on that Fisheye review to close this ticket here.

  • Finally, the validations for Products (GlobalProduct and TradeItem) having matching dispensing units is where this whole ticket got started. That code does have a properly formatted error now. It uses the message key "referenceData.error.product.dispensingUnits.wrong".

In short, I suggest marking this ticket Done. But if you see more to do, I hope we can wrap it up by Wednesday.

Brandon Bowersox-Johnson 
December 13, 2016 at 3:37 AM
(edited)

I've finished a draft for the simple case and created a review to get your input.

Here is what remains:

  • code the advanced case (above)

  • respond to any review feedback

  • consider pulling out the inner class Message.LocalMessage

  • decide whether to address any of the ProductCategory errors or unit test coverage as part of this ticket (or also whether to file any follow-up tickets such as for converting other ErrorResponse usage to ValidationMessageException usage)

Brandon Bowersox-Johnson 
December 5, 2016 at 8:53 PM
(edited)

To reproduce the old and new before of the simple case describe above...

Steps to reproduce before the change:

  1. Spin up blue with demo data (or use test.openlmis.org)

  2. GET list of trade items for http://HOSTNAME/referencedata/api/globalProducts/bfde33c3-83f1-4feb-a27c-842852f66b71/tradeItems?access_token=YOURTOKEN should return empty array originally "[]"

  3. PUT two trade item IDs, where the second one has a mismatched dispensing unit http://HOSTNAME/referencedata/api/globalProducts/bfde33c3-83f1-4feb-a27c-842852f66b71/tradeItems?access_token=YOURTOKEN
    ```["103396e1-f5e4-4754-bb7b-1c799097dfea", "bac90734-6e58-426e-849b-331286ec77d2"]```

  4. Result: 500 Server Error java.lang.IllegalArgumentException Global product cannot be assigned because dispensing units are different

Steps to reproduce after the change:

  1. Spin up blue with demo data (or use test.openlmis.org)

  2. GET list of trade items for http://HOSTNAME/referencedata/api/globalProducts/bfde33c3-83f1-4feb-a27c-842852f66b71/tradeItems?access_token=YOURTOKEN should return empty array originally "[]" (if it is not empty, clear your demo data or PUT an empty array to reset it)

  3. PUT two trade item IDs, where the second one has a mismatched dispensing unit http://HOSTNAME/referencedata/api/globalProducts/bfde33c3-83f1-4feb-a27c-842852f66b71/tradeItems?access_token=YOURTOKEN

  4. Result: 400 Bad Request with a translatable message string in the JSON body

Brandon Bowersox-Johnson 
December 2, 2016 at 11:05 PM

Per Josh and Brandon discussion, we have decided on a simple case and an advanced case:

Simple Case

  • simple means we respond with a basic translatable message—no DTO, no Validator involved

  • scenario: GlobalProductController: when assigning trade items, it takes UUIDs and responds with a simple validation error if there is a dispensing unit mismatch

  • tooling: Message.java, RefDataErrorHandling to give the right response (a proper HTTP Status Code and a body with the translated message)

Advanced Case

  • advanced means there is a DTO and Validator, JSR-303 style

  • scenario: RequisitionGroupValidator: it has quite a few validations where it currently returns English hard-coded error messages, and we want to change this validator to using Message.java

  • tooling: Message.java, ______ (is it in the Controller or in RefDataErrorHandling)

Done
Pinned fields
Click on the next to a field label to start pinning.

Details

Assignee

Reporter

Story Points

Components

Sprint

Fix versions

Priority

Time Assistant

Created September 15, 2016 at 11:08 PM
Updated January 17, 2017 at 10:47 PM
Resolved January 17, 2017 at 10:46 PM