Skip to content

RESTWS-702 : Add support for unvoiding/unretiring resources#373

Merged
dkayiwa merged 1 commit intoopenmrs:masterfrom
Ruhanga:RESTWS-702
Mar 21, 2019
Merged

RESTWS-702 : Add support for unvoiding/unretiring resources#373
dkayiwa merged 1 commit intoopenmrs:masterfrom
Ruhanga:RESTWS-702

Conversation

@Ruhanga
Copy link
Member

@Ruhanga Ruhanga commented Jan 4, 2019

RESTWS-702 Add support for unvoiding/unretiring resources

Description of what I changed

Updated "Deletable" interface to also support: undelete(String uuid, RequestContext context) throws ResponseException;

Made DelegatingCrudeResource class to implement this method (undelete(String uuid, RequestContext context) throws ResponseException;)

Updated BaseDelegatingResource class to have a protected unDelete(Object, RequestContext) which temporarily/by-default provides for an alternative message for the classes that have not yet overridden this method. This pattern follows the design used by delete(Object, String, RequestContext) throws ResponseException; method in the same class.

Overrode the unDelete(Object, RequestContext) for the following Resources:

-> PatientResource1_8
-> PersonResource1_8
-> ObsResource1_8
-> OrderResource1_8
-> EncounterResource1_8

I am welcoming comments and enhancements on resources connected to Voidable Openmrs Objects to include.

Issue I worked on

see https://issues.openmrs.org/browse/RESTWS-702

Checklist: I completed these to help reviewers :)

  • My pull request only contains ONE single commit

  • My IDE is configured to follow the code style of this project.

  • I have added tests to cover my changes.

  • I ran mvn clean package right before creating this pull request and
    added all formatting changes to my commit.

  • All new and existing tests passed.

  • My pull request is based on the latest changes of the master branch.

@mhawila
Copy link
Contributor

mhawila commented Jan 4, 2019

Hi @Ruhanga I was skimming really quick through your code and I see you have named your method unDelete. I think undelete is simply one word hence the method names do not need to be camelized they way you did. My two cents ( or just one 😄 )

Copy link
Member

@djazayeri djazayeri left a comment

Choose a reason for hiding this comment

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

Made some comments.

* @return unvoided/unretired object
* @since 2.2.0
*/
Object unDelete(String uuid, RequestContext context) throws ResponseException;
Copy link
Member

Choose a reason for hiding this comment

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

should be capitalized like undelete (no capital D). E.g. for consistency with unvoid, unretire, etc.

Copy link
Member Author

Choose a reason for hiding this comment

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

I made changes accordingly

* @return Object
*/

// TODO make this method an abstruct method when all subclasses have overriden it
Copy link
Member

Choose a reason for hiding this comment

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

Can't merge code that has a TODO in it. Remove this comment (and the blank lines).

If there is no base implementation of this the method should be abstract, just like delete. Are there many other resources that would need this fixed?

Copy link
Member Author

Choose a reason for hiding this comment

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

I deleted the TODO and empty line but left the default implementation in place because I think this will help the end user trouble shoot problems that may come with existing resources that may not be part of the rest.webservices module and don't have their own implementation for this already.

return RestUtil.updated(response, updated);

if (post.get("deleted") != null && "false".equals(post.get("deleted")) && post.size() == 1) {
//This branching provides for unvoiding or unretiring a resource
Copy link
Member

Choose a reason for hiding this comment

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

This comment is obvious from context, so you don't need to explicitly state this.

Copy link
Member Author

Choose a reason for hiding this comment

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

I deleted the comment

protected Object unDelete(Encounter enc, RequestContext context) {
Encounter unvoidedEnc = null;
if (!enc.isVoided()) {
unvoidedEnc = Context.getEncounterService().getEncounter(enc.getEncounterId());
Copy link
Member

Choose a reason for hiding this comment

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

You already have "Encounter enc" passed into the method. Why do you need to fetch it again? Can't you just do

if (enc.isVoided()) {
    // unvoid it
}
return // convert

Copy link
Member Author

Choose a reason for hiding this comment

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

Thank you for this observation, I have adjusted the code accordingly.

@Ruhanga
Copy link
Member Author

Ruhanga commented Jan 6, 2019

I am going ahead to include the rest of the resources that are Deletable .

@Ruhanga
Copy link
Member Author

Ruhanga commented Jan 10, 2019

What I have done

-Included remaining resources to unvoid/unretire that are unretireable including MetaData related resources
-Added more Unit tests for the changes made for the following resources....

DelegatingCrudeResource s

-EncounterResource1_8
-ObsResource1_8
-OrderResource1-8
-PatientResource1_8
-PersonResource1_8
-ProgramEnrollment1_8
-RelationshipResource1_8
-VisitResource1_8

MetaDataDelegatingCrudResource s

-ConceptClassResource1_8
-ConceptSourceResource1_8
-EncounterType1_8
-FieldTypeResource1_8
-FormResource1_8

@dkayiwa
Copy link
Member

dkayiwa commented Jan 17, 2019

@Ruhanga did you address all the changes requested by @djazayeri ?

@Ruhanga
Copy link
Member Author

Ruhanga commented Jan 18, 2019

@dkayiwa , yes I addressed the requests for changes from @djazayeri .

* org.openmrs.module.webservices.rest.web.RequestContext)
*/
@Override
public Object unDelete(String uuid, RequestContext context) throws ResponseException {
Copy link
Member

Choose a reason for hiding this comment

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

Didn't i see comments about renaming these methods?

Copy link
Member Author

Choose a reason for hiding this comment

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

@dkayiwa , sorry for the late response, yes you did see the comments and I made the changes in this second commit cd12521 after the first commit (054593f). I think I have to squash the commits into one. But just for reference purposes I left this out.

Copy link
Member

Choose a reason for hiding this comment

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

@Ruhanga can you please squash your commits into one?

Copy link
Member Author

Choose a reason for hiding this comment

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

Thank you @samuelmale , commits have been squashed into one.

* @return Object
*/
protected T undelete(T delegate, RequestContext context) throws ResponseException {
//Default implimentation of this method if not overriden by sub-class is to raise an
Copy link
Member

Choose a reason for hiding this comment

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

Can you fix this typo "implimentation"?

Copy link
Member Author

Choose a reason for hiding this comment

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

Thank you @samuelmale , I've got this resolved.

* @param context
* @throws ResponseException
* @return unvoided/unretired object
* @since 2.2.0
Copy link
Member

Choose a reason for hiding this comment

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

2.2.0 is a version of what?

Copy link
Member Author

Choose a reason for hiding this comment

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

Thank you very much for pointing out this @dkayiwa , it was supposed to be 2.25.0 (release version to contain these changes). I have updated the commit to reflect the correction. I initially thought the version to be compared against openmrs-core.

* Undeletes the specified resource, which in the OpenMRS context means either unvoiding or
* unretiring it
*
* @param uuid
Copy link
Member

Choose a reason for hiding this comment

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

Did you just forget to document these params?

Copy link
Member Author

Choose a reason for hiding this comment

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

You mean uuid and context ? If so what in their documentation is missing?

Copy link
Member Author

Choose a reason for hiding this comment

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

That was quick, the description is missing. But This is how the other params I have seen in this module being documented.

Copy link
Member

Choose a reason for hiding this comment

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

Did you do some googling about javadoc?

Copy link
Member Author

Choose a reason for hiding this comment

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

Definitely yes, and in this case I had to remind myself. Good convention is to include the @params's description. Gona do just that. Thank you @dkayiwa .

conceptClass.setDateRetired(new Date());
conceptClass.setRetireReason("random reason");
service.saveConceptClass(conceptClass);
Assert.assertTrue(conceptClass.isRetired());
Copy link
Member

Choose a reason for hiding this comment

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

Will the above assertion fail if line 105 is commented out?

Copy link
Member Author

Choose a reason for hiding this comment

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

Definitely not, what was in my mind though was conceptClass = service.saveConceptClass(conceptClass);. I am refactoring to reflect this.

return RestUtil.updated(response, undeletedRes);
}
else {
Updatable res = (Updatable) restService.getResourceByName(buildResourceName(resource));
Copy link
Member

Choose a reason for hiding this comment

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

What happens if you have the deleted property together with others?

Copy link
Member

Choose a reason for hiding this comment

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

Also what happens when the property deleted has a value of true?

Copy link
Member Author

Choose a reason for hiding this comment

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

An Exception similar to all other invalid properties is thrown, i.e conversion Exception.

Copy link
Member

Choose a reason for hiding this comment

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

Do you have a test to confirm so?

Copy link
Member Author

Choose a reason for hiding this comment

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

This test should be part of work done earlier since this is not the first time this possibility exists.

@dkayiwa
Copy link
Member

dkayiwa commented Mar 5, 2019

Did you confirm that you have added this for all resources and a corresponding test for each?

@Ruhanga
Copy link
Member Author

Ruhanga commented Mar 5, 2019

Yes, apart from Condition and Diagnosis which have a different implementation.

public void shouldUnRetireAnEncounterType() throws Exception {
EncounterType encounterType = service.getEncounterTypeByUuid(getUuid());
encounterType.setRetired(true);
encounterType.setRetiredBy(Context.getAuthenticatedUser());
Copy link
Member

Choose a reason for hiding this comment

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

I guess you do not need to set retiredBy, retireReason, and dateRetired.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, thank you for pointing out this @dkayiwa , these methods are deprecated apart from setRetireReason().

obj.setRetiredBy(Context.getAuthenticatedUser());
obj.setDateRetired(new Date());
obj.setRetireReason("random reason");
service.savePersonAttributeType(obj);
Copy link
Member

Choose a reason for hiding this comment

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

What happens if you comment out the above line?

Copy link
Member Author

Choose a reason for hiding this comment

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

This has been resolve.

relationshipType.setRetiredBy(Context.getAuthenticatedUser());
relationshipType.setDateRetired(new Date());
relationshipType.setRetireReason("random reason");
service.saveRelationshipType(relationshipType);
Copy link
Member

Choose a reason for hiding this comment

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

What happens if you comment out the above line?

Copy link
Member Author

Choose a reason for hiding this comment

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

This has been resolved.

patientIdentifierType.setRetiredBy(Context.getAuthenticatedUser());
patientIdentifierType.setDateRetired(new Date());
patientIdentifierType.setRetireReason("random reason");
service.savePatientIdentifierType(patientIdentifierType);
Copy link
Member

Choose a reason for hiding this comment

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

What happens when the above line is commented out?
Am now asking this same question for the third time. Do you take time to review your changes?

Copy link
Member Author

Choose a reason for hiding this comment

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

Apologies on this @dkayiwa , I think I have been following my not up-to date list of the changes and resources affected as I have made on this pull request. The next commit will consider everything is fine. Thank you very much.

* Undeletes the specified resource, which in the OpenMRS context means either unvoiding or
* unretiring it
*
* @param uuid Uuid to the delegate to unvoid/unretire
Copy link
Member

Choose a reason for hiding this comment

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

What does "delegate" mean?

Copy link
Member Author

Choose a reason for hiding this comment

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

Delegate in my thinking as I have seen it being used with respect to this module, is a domain object.

Copy link
Member

Choose a reason for hiding this comment

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

What has that got to do with the API consumer?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think to make this doc safe, I'l replace "delegate" with "resource" instead.


@Test
public void shouldUnVoidAVisit() throws Exception {
Visit visit = service.getVisitByUuid(RestTestConstants1_9.VISIT_UUID);
Copy link
Member

Choose a reason for hiding this comment

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

Can you try void an existing visit in any of the datasets used for VisitServiceTest in the core platform?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think it's not possible since this setting is in a Web and Module context sensitive environment. Unless I duplicate the datasets into this module.

Copy link
Member

Choose a reason for hiding this comment

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

When documenting, avoid exposing internal implementation details to the client.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thank you @dkayiwa , I've taken note of this.

program.setRetireReason("random reason");
program = service.saveProgram(program);
Assert.assertTrue(program.isRetired());

Copy link
Member

Choose a reason for hiding this comment

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

Can you first make a REST call and confirm that it is indeed retired?

Copy link
Member Author

Choose a reason for hiding this comment

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

I have used Service.get.......ByUuid() which is implicitly called on any GET request for a given resource as suggested somewhere on this PR.

public void shouldUnRetireAPersonAttributeType() throws Exception {

final String nonRetiredAttribute = "a0f5521c-dbbd-4c10-81b2-1b7ab18330df";
PersonAttributeType obj = service.getPersonAttributeTypeByUuid(nonRetiredAttribute);
Copy link
Member

Choose a reason for hiding this comment

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

What does obj mean?

Copy link
Member Author

Choose a reason for hiding this comment

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

Just a variable name. Meaning comes from its type definition → PersonAttributeType .

Copy link
Member

Choose a reason for hiding this comment

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

Can you do some googling about good variable names?

Copy link
Member Author

Choose a reason for hiding this comment

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

Thank you @dkayiwa , this helped as it usually does. I going to rename this for better meaning.

PatientIdentifierType patientIdentifierType = service.getPatientIdentifierTypeByUuid(getUuid());
patientIdentifierType.setRetired(true);
patientIdentifierType.setRetireReason("random reason");
patientIdentifierType = service.savePatientIdentifierType(patientIdentifierType);
Copy link
Member

Choose a reason for hiding this comment

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

Generally, instead of asserting using the returned object, i would prefer fetching it afresh using getPatientIdentifierTypeByUuid and then assert that it is retired

Copy link
Member Author

Choose a reason for hiding this comment

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

I agree @dkayiwa . Let me refactor to reflect these changes.

@dkayiwa
Copy link
Member

dkayiwa commented Mar 19, 2019

@Ruhanga did you try run your changes and test using an interface like this to unretire a concept?

@Ruhanga
Copy link
Member Author

Ruhanga commented Mar 19, 2019

@dkayiwa , this was not implemented for the Concept resource because there is currently no Service layer method to un-retire a Concept.

@dkayiwa
Copy link
Member

dkayiwa commented Mar 19, 2019

Do we have a ticket for it?

@Ruhanga
Copy link
Member Author

Ruhanga commented Mar 19, 2019

@dkayiwa , there's actually never been any ticket for or against this, I guess I have to create or rather seek consent from talk to create a ticket that addresses the Unretiring of a Concept .

@dkayiwa
Copy link
Member

dkayiwa commented Mar 19, 2019

@Ruhanga did you try run your changes and test using an interface like this https://demo.openmrs.org/openmrs/module/webservices/rest/test.htm to unretire a patient?

@Ruhanga
Copy link
Member Author

Ruhanga commented Mar 20, 2019

Okay, I hadn't @dkayiwa . Let me hard test these changes on a running instance. Thank you.

@Ruhanga
Copy link
Member Author

Ruhanga commented Mar 20, 2019

@dkayiwa , for the far I have gone unretiring a resource is possible including the patient one.

@dkayiwa
Copy link
Member

dkayiwa commented Mar 20, 2019

Can you share some screenshots on the JIRA ticket?

@Ruhanga
Copy link
Member Author

Ruhanga commented Mar 20, 2019

Cool @dkayiwa .

@dkayiwa dkayiwa merged commit bff28f9 into openmrs:master Mar 21, 2019
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.

5 participants