Skip to content

Conversation

@mherman22
Copy link
Member

@mherman22 mherman22 commented Dec 3, 2024

Description of what I changed

Issue I worked on

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

Checklist: I completed these to help reviewers :)

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

    No? Unsure? -> configure your IDE, format the code and add the changes with git add . && git commit --amend

  • I have added tests to cover my changes. (If you refactored
    existing code that was well tested you do not have to add tests)

    No? -> write tests and add them to this commit git add . && git commit --amend

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

    No? -> execute above command

  • All new and existing tests passed.

    No? -> figure out why and add the fix to your commit. It is your responsibility to make sure your code works.

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

    No? Unsure? -> execute command git pull --rebase upstream master

@dkayiwa
Copy link
Member

dkayiwa commented Dec 3, 2024

It is a recommended practice to include the ticket id in the commit message.

@mherman22 mherman22 force-pushed the RESTWS-963-Impl branch 2 times, most recently from 67dbf47 to a3de500 Compare December 3, 2024 20:00
@mherman22 mherman22 requested a review from dkayiwa December 5, 2024 17:54
@dkayiwa
Copy link
Member

dkayiwa commented Dec 6, 2024

I was not expecting the new approach to change any existing methods. I expected to only inspect the resources to do the needful without touching them in any way.

@mherman22
Copy link
Member Author

I was not expecting the new approach to change any existing methods. I expected to only inspect the resources to do the needful without touching them in any way.

it doesn't change any existing method, to get this working i have to make changes within SwaggerSpecificationCreator.java. Except for the @Deprecated method, i am gonna add that back.

public static boolean getRepresentationDescription = false;

@Override
public Model getGETModel(Representation rep) {
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 is mainly to fix the test that depends on this class.

@mherman22 mherman22 force-pushed the RESTWS-963-Impl branch 2 times, most recently from e234eac to 9a6ee8e Compare January 11, 2025 19:25
@mherman22 mherman22 force-pushed the RESTWS-963-Impl branch 2 times, most recently from b00e48b to fb399b3 Compare January 31, 2025 05:45
@chibongho
Copy link
Contributor

@dkayiwa @ibacher Herman and I want to bring attention to this PR. It affects, among other things, the scope of the GSoC Project.

I haven't given this a thorough review, but this approach to stop relying on getGetModel(), getCREATEModel() and getUPDATEModel() makes sense . I don't think this PR introduces any backwards incompatibility. Given how incomplete our current swagger docs are, I think it's fairly low risk to merge this in, and make continual improvements on it.

* @param resourceClass the resource class e.g PatientIdentifier.class
* @return the resource handler for the provided class e.g PatientIdentifierResource1_8
*/
Resource getResourceHandlerForSupportedClass(Class<?> resourceClass);
Copy link
Member

Choose a reason for hiding this comment

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

Where are you using this method?

Copy link
Member Author

Choose a reason for hiding this comment

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

To be removed. Oversight

Copy link
Member Author

Choose a reason for hiding this comment

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

So this method handles cases where the field is a List or Set. It extracts the element type and, if it's an OpenMRS resource, references its Swagger definition. If no resource definition is found, it defaults to a StringProperty. Otherwise, it returns a generic ArrayProperty.

if (Set.class.equals(type) || List.class.equals(type)) {
    Class<?> elementType = getGenericTypeFromField(field);
    if (isOpenMRSResource(elementType)) {
        String resourceName = getSubResourceNameBySupportedClass(elementType);
        if (resourceName == null) {
            return new StringProperty();
        }
        return new ArrayProperty(new RefProperty("#/definitions/" + StringUtils.capitalize(resourceName) + operationType));
    }
    return new ArrayProperty();
}

cc: @dkayiwa

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 point me to where it is currently used?

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

Do we need to put it here if it is only used in a utility class?

Copy link
Member Author

Choose a reason for hiding this comment

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

not necessarily, i can just put it within the SwaggerGenerationUtil.java

Copy link
Member Author

Choose a reason for hiding this comment

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

not necessarily, i can just put it within the SwaggerGenerationUtil.java



@Override
public DelegatingResourceDescription getCreatableProperties() throws ResourceDoesNotSupportOperationException {
Copy link
Member

Choose a reason for hiding this comment

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

Why did we add this 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.

This class has a getCREATEModel method that needs to be removed. I wanted to replace that with getcreatableproperties since the new mechanism depends on that

Copy link
Member

Choose a reason for hiding this comment

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

I do not seem to see where you removed it in this pull request.

Copy link
Member Author

Choose a reason for hiding this comment

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

True dat. Will fix that

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 address the above?

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 tried addressing it in this commit but it fails some tests in swaggerspecificationcreatortest so I decided to put it back in this most recent commit.

Its really because we need that method to add SubDetailsResource to the swagger documentation. When I remove it, the tests fail because that resource is not added

Copy link
Member

@dkayiwa dkayiwa Mar 24, 2025

Choose a reason for hiding this comment

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

I still somehow feel we should not add this new method just for the sake of the swagger docs.

Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't we just replace the test with one adapted to this new model? I.e., if getCREATEModel() is no longer what Swagger is using to create docs, then the test is no longer valid?

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 @ibacher, Are you suggesting i remove even the SubDetailsResource? because that's the only way the existing tests especially this one will pass?.

And to be frank, SubDetailsResource is just a test class that shouldn't appear in our swagger spec but apparently does so i am okay with removing it.

Copy link
Member

Choose a reason for hiding this comment

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

Hmmm... it shouldn't appear in the production spec, but I thought it was there so the tests have something to work with. I don't think we should remove it, but I do think we should re-work the SwaggerSpecificationCreatorTest class so that it tests whatever mechanism we're using to generate the Swagger Specification now.

We don't need existing tests to pass if we're changing the mechanism, but we need an equivalent set of tests to pass. Does that make sense?

Also, when actually generating the spec, we should ensure that none of the test modules are on the classpath.

@mherman22 mherman22 requested a review from dkayiwa March 16, 2025 11:25
@Override
public Model getGETModel(Representation rep) {
public DelegatingResourceDescription getRepresentationDescription(Representation rep) {
getGETCalled = true;
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 intentionally leave in the getGETCalled?

Copy link
Member Author

Choose a reason for hiding this comment

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

@Override
public Model getCREATEModel(Representation rep) {
public DelegatingResourceDescription getCreatableProperties() {
getCREATECalled = true;
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 intentionally leave in the getCREATECalled?

Copy link
Member Author

Choose a reason for hiding this comment

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

@Override
public Model getUPDATEModel(Representation rep) {
public DelegatingResourceDescription getUpdatableProperties() throws ResourceDoesNotSupportOperationException {
getUPDATECalled = true;
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 intentionally leave in the getUPDATECalled?

Copy link
Member Author

Choose a reason for hiding this comment

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

To be fixed in next commit

}
}

private void initializeResources() {
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 mind explaining why you moved this from a private method to the base interface?

Copy link
Member Author

Choose a reason for hiding this comment

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

Oversight. To be fixed in next commit

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

Is there any reason why you did not just use RestService.initialize()?

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed


volatile Map<String, ResourceDefinition> resourceDefinitionsByNames;

volatile Map<Class<?>, Resource> resourcesBySupportedClasses;
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 intentionally change the access modifier?

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Member

@dkayiwa dkayiwa Mar 17, 2025

Choose a reason for hiding this comment

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

It is not a good practice for outsiders to directly access internal implementation details of a class?

Copy link
Member Author

Choose a reason for hiding this comment

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

True dat. Let me get a finer way of doing it

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed!

volatile Map<Class<?>, Resource> resourcesBySupportedClasses;

static volatile Map<Class<?>, Resource> resourcesBySupportedClasses;
Copy link
Member

Choose a reason for hiding this comment

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

Originally, this was not static. Is this just a typo?

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 see the above comment?

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed!


/**
* Retrieves the resource handler for the given supported class.
*
Copy link
Member

Choose a reason for hiding this comment

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

Don't we already have a way of getting this without modifying this interface by adding a new method simply for swagger docs?

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 been trying out this method https://github.com/mherman22/openmrs-module-webservices.rest/blob/08b817fd98e0c15f81f021d4e856b0c2b598c125/omod-common/src/main/java/org/openmrs/module/webservices/rest/web/api/impl/RestServiceImpl.java#L440 but it is not giving me what i want.

i dont want to touch the existing tests in https://github.com/mherman22/openmrs-module-webservices.rest/blob/08b817fd98e0c15f81f021d4e856b0c2b598c125/omod-2.0/src/test/java/org/openmrs/module/webservices/rest/doc/SwaggerSpecificationCreatorTest.java#L65

And yet when i use the above method i get the failure below: https://pastebin.com/WknBFXSD which is that it fails with Caused by: org.openmrs.api.APIException: Unknown resource: class org.openmrs.AllergyReaction. AllergyReaction is a dummy class which was added just for the sake of making SwaggerSpecificationCreatorTest pass.

Copy link
Member

Choose a reason for hiding this comment

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

What parameter did you pass into getResourceBySupportedClass?

Copy link
Member Author

Choose a reason for hiding this comment

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

here is the method. i gave it a Class<?> resourceClass.

    /**
     * <strong>Should</strong> return search resources for given resource class
     * @param resourceClass the resource class e.g. PatientIdentifier
     */
    public static org.openmrs.module.webservices.rest.web.resource.api.Resource getResourceHandlerForSupportedClass(Class<?> resourceClass) {
        if (Context.getService(RestService.class).getResourceBySupportedClass(resourceClass) == null) {
            Context.getService(RestService.class).initialize();
        }
        return Context.getService(RestService.class).getResourceBySupportedClass(resourceClass);
    }

Copy link
Member

Choose a reason for hiding this comment

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

What was the exact value contained in resourceClass?

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 i have added a fix by simply using getResourceHandlers() and then use each of the returned resourcehandlers to get its annotation and ensure that the annotation supportedClass is equal to the class i am providing at public static String getSubResourceNameBySupportedClass(Class<?> supportedClass).

@mherman22 mherman22 requested a review from dkayiwa March 22, 2025 15:28
@mherman22 mherman22 force-pushed the RESTWS-963-Impl branch 3 times, most recently from f222c40 to d60be17 Compare March 26, 2025 15:20
@mherman22 mherman22 force-pushed the RESTWS-963-Impl branch 3 times, most recently from 7f68a6c to fae9fdc Compare May 25, 2025 10:48
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.

4 participants