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

OZ-545: Refactor code to use camel-openmrs-fhir and rewrite routes with Java DSL #22

Merged
merged 3 commits into from
Jul 16, 2024

Conversation

VaishSiddharth
Copy link
Contributor

@VaishSiddharth VaishSiddharth commented May 8, 2024

  1. Add Odoo client
  2. Wrap Odoo client in a camel component
  3. Add Odoo data model
  4. Write fhir<->odoo mappers
  5. Migrate XML routes to Java DSL
  6. Leverage opemrs-fhir
  7. Add Unit tests

Ticket: https://mekomsolutions.atlassian.net/browse/OZ-545

@VaishSiddharth VaishSiddharth marked this pull request as draft May 10, 2024 13:06
@mks-d mks-d changed the title OZ-545 | Refactor code to use openmrs-fhir OZ-545: Refactor code to use openmrs-fhir May 15, 2024
Copy link
Contributor

@mks-d mks-d left a comment

Choose a reason for hiding this comment

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

That's

OZ-545: Refactor code to use camel-openmrs-fhir

right?

@VaishSiddharth VaishSiddharth changed the title OZ-545: Refactor code to use openmrs-fhir OZ-545: Refactor code to use camel-openmrs-fhir Jun 6, 2024
@VaishSiddharth VaishSiddharth changed the title OZ-545: Refactor code to use camel-openmrs-fhir OZ-545: Refactor code to use camel-openmrs-fhir and rewrite routes with Java DSL Jun 6, 2024
Copy link

@ibacher ibacher left a comment

Choose a reason for hiding this comment

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

Thanks @VaishSiddharth Haven't gone through everything, but some quick, mostly minor comments.

pom.xml Outdated
@@ -44,10 +44,12 @@
<camel.version>4.1.0</camel.version>
<spring-boot.version>3.1.4</spring-boot.version>
<xmlRpcClientVersion>3.1.3</xmlRpcClientVersion>
<fhir-stu4.version>7.0.0</fhir-stu4.version>
Copy link

Choose a reason for hiding this comment

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

FHIR releases post 3 use R<x> format. STU is "Standard for Trial Use"—essentially the specification version of "beta".

Suggested change
<fhir-stu4.version>7.0.0</fhir-stu4.version>
<fhir-r4.version>7.0.0</fhir-r4.version>

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for pointing this out.
Lets fix this in eip-erpnext-openmrs repo as well. https://github.com/ozone-his/eip-erpnext-openmrs/blob/main/pom.xml#L61

cc: @corneliouzbett

}
});
}
};
Copy link

Choose a reason for hiding this comment

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

This seems a convoluted way of writing:

var config = new XmlRpcClientConfigImpl();
config.setEnabledForExtensions(true);
config.setServerUrl(/* ... */);

client = new XmlRpcClient();
client.setConfig(config);

The above is actually fewer lines of code (6 vs 10), easier for other maintainers to read / understand, and skips the creation of two anonymous inner classes.

Comment on lines 64 to 68
try {
init();
} catch (IOException e) {
throw new RuntimeException(e);
}
Copy link

Choose a reason for hiding this comment

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

I'd probably do this in the opposite way, i.e., instead of authenticateIfNecessary() each function should call init() which should:

  1. Initialize the client if it hasn't already been initialized
  2. Authenticate the client if it hasn't already been authenticated

};
}

public void authenticate() throws MalformedURLException {
Copy link

Choose a reason for hiding this comment

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

Why is everything but the MalformedURLException turned into an unchecked exception?

}
}

public Integer create(String model, List<Map<String, Object>> dataParams)
Copy link

Choose a reason for hiding this comment

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

Is there a reason for favoring Integer over int here and boxed types over primitives in general?

Copy link
Contributor Author

@VaishSiddharth VaishSiddharth Jun 11, 2024

Choose a reason for hiding this comment

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

Tried to keep the client consistent with Odoo documentation
Screenshot 2024-06-11 at 12 45 13 PM


public class OdooUtils {

private static final Logger log = LoggerFactory.getLogger(OdooUtils.class);
Copy link

Choose a reason for hiding this comment

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

Any reason not to use Lombok's @Slf4j annotation here?

log.debug("OdooUtils: Converted map {} to object {}", data, obj);
return obj;
} catch (Exception e) {
throw new RuntimeException(String.format("Error converting map %s to object: %s", data, e.getMessage()));
Copy link

Choose a reason for hiding this comment

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

Not sure that adding HashMap@1882378729 to this error message is helpful...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will it not print something like

{a=1, b=2, c=3}

}
}

public static Map<String, Object> convertObjectToMap(Object object) throws Exception {
Copy link

Choose a reason for hiding this comment

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

This could be a one-liner:

new ObjectMapper().convertValue(object, new TypeReference<Map<String, Object>>() {});

logger.info("Creating odoo endpoint with uri: {} remaining: {} parameters: {} ", uri, remaining, parameters);
String[] parts = remaining.split("/", 2);
if (parts.length != 2) {
throw new IllegalArgumentException("Invalid URI format. The expected format is 'odoo:method/model'");
Copy link

Choose a reason for hiding this comment

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

Here it would be good to actually return the used URL no?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Till this point we don't have the URL.

We have another debug log inside OdooProducer which should print the actual endpoint

log.debug("OdooProducer: Endpoint {} Model: {}, Method {} ", getEndpoint(), model, method);

Comment on lines 44 to 46
public String getEndpointBaseUri() {
return super.getEndpointBaseUri();
}
Copy link

Choose a reason for hiding this comment

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

Seems like we can forgo this, right?

Copy link
Contributor

@rbuisson rbuisson left a comment

Choose a reason for hiding this comment

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

@VaishSiddharth , you should be better off depending on Ozone directly rather than adding all the Ozone configs directly as test resources.

@VaishSiddharth
Copy link
Contributor Author

As per the discussion yesterday with @rbuisson we have decided to create a new PR #27 which will be used to get all the review comments and commits which address those comments. After the review process is done we will break the PR into two

  1. Camel routes using camel-openmrs-fhir with Java DSL
  2. Integration Tests

I will address the comments on this PR from @ibacher and @rbuisson and merge those commits in the combined PR.
Please avoid adding comments on this PR
cc: @corneliouzbett @mks-d @wluyima

@VaishSiddharth
Copy link
Contributor Author

@VaishSiddharth , you should be better off depending on Ozone directly rather than adding all the Ozone configs directly as test resources.

Fixed with this commit
886a18d

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
Copy link
Contributor

Choose a reason for hiding this comment

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

We don't use wildcard imports as a convention

common_config, "authenticate", asList(getDatabase(), getUsername(), getPassword(), emptyMap()));
} catch (XmlRpcException e) {
log.error("Cannot authenticate to Odoo server error: {}", e.getMessage());
throw new RuntimeException("Cannot authenticate to Odoo server");
Copy link
Contributor

Choose a reason for hiding this comment

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

If you're re-throwing the error, you might as well skip logging a message

/**
* Odoo component to integrate with Odoo XML RPC.
*/
@UriEndpoint(firstVersion = "1.0.0", scheme = "odoo", title = "Odoo", syntax = "odoo:method/model", producerOnly = true)
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not set the method as a header or param? I think having something like odoo:get/re.user is less intuitive.

@VaishSiddharth
Copy link
Contributor Author

@wluyima There is a combined PR which is up-to-date. Please do not review this PR.
#22 (comment)

@Autowired
private OdooClient odooClient;

public Integer getCountryId(String countryName) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't this be getCountryByName?

@corneliouzbett corneliouzbett marked this pull request as ready for review July 16, 2024 08:19
@corneliouzbett corneliouzbett merged commit 9f030ec into main Jul 16, 2024
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
6 participants