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

BAH-273 #27

Open
wants to merge 25 commits into
base: master
Choose a base branch
from
Open

BAH-273 #27

wants to merge 25 commits into from

Conversation

ningosi
Copy link

@ningosi ningosi commented Apr 16, 2018

Intersection of lucene and hibernate search


public class Activator extends BaseModuleActivator {

private Log log = LogFactory.getLog(this.getClass());

@Override
public void started() {
AdministrationService service = Context.getAdministrationService();
Copy link
Member

Choose a reason for hiding this comment

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

Please checkout this file from upstream/master, I suspect it should not have been changed.

Copy link
Author

Choose a reason for hiding this comment

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

Checked upstream and corrected

public class BahmniPatientServiceImplIT extends BaseIntegrationTest {

@Autowired
BahmniPatientService bahmniPatientService;
Copy link
Member

Choose a reason for hiding this comment

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

Make this private (or make all members public).

Copy link
Author

Choose a reason for hiding this comment

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

corrected

BahmniPatientService bahmniPatientService;

@Autowired
LocationService locationService;
Copy link
Member

Choose a reason for hiding this comment

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

Make this private (or make all members public).

Copy link
Author

Choose a reason for hiding this comment

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

corrected

private SessionFactory sessionFactory;

private HttpServletRequest mockedRequest = Mockito.mock(HttpServletRequest.class);
private HttpServletResponse mockedRsponse = Mockito.mock(HttpServletResponse.class);
Copy link
Member

Choose a reason for hiding this comment

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

I would keep those two declared in setUp() since they are used only once.

Copy link
Author

Choose a reason for hiding this comment

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

Thanks. Declared those in the setup()

@Override
public List<PatientResponse> luceneHibernateSearch(PatientSearchParameters searchParameters) {
List<PatientResponse> luceneHibernateResponse = new ArrayList<>();
if(searchParameters.getIdentifier() != null || searchParameters.getName() != null || searchParameters.getCustomAttribute() != null){
Copy link
Member

Choose a reason for hiding this comment

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

You will probably want to use StringUtils.isEmpty() here. Or what's the intended behaviour if all the arguments are empty strings?

Copy link
Author

Choose a reason for hiding this comment

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

Yes you are right. Strings will be always empty if they contain nothing.

Copy link
Author

Choose a reason for hiding this comment

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

If all arguments are empty strings, then we don't search for the patient objects

Copy link
Author

Choose a reason for hiding this comment

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

If none of the first 3 parameters are missing and others like program attributes and address are provided, it will get to hibernate search and if nothing is supplied at all, then no search will be called

@@ -18,4 +18,6 @@
public List<Patient> get(String partialIdentifier, boolean shouldMatchExactPatientId);

public List<RelationshipType> getByAIsToB(String aIsToB);
List<PatientResponse> luceneHibernateSearch(PatientSearchParameters searchParameters);
Copy link
Member

Choose a reason for hiding this comment

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

We need a very detailed Javadoc header for this one given the apparently confusing name.

Copy link
Author

Choose a reason for hiding this comment

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

Provided java doc for the method in the service class

assertEquals(1, patients.size());
PatientResponse patient = patients.get(0);
assertTrue(patient.getIdentifier().contains("200006"));
assertTrue(patient.getExtraIdentifiers().contains("200006"));
}

}
@Test
public void shouldSearchByName() {
Copy link
Member

Choose a reason for hiding this comment

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

Surely there were already tests validating that one could search by name, could you explain here what this is in regards to existing tests?

Copy link
Member

Choose a reason for hiding this comment

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

Or perhaps are you re-writing existing tests, but this time going through the Lucene branch of the code? I guess my remarks hold for the next few test methods as well.

Copy link
Author

Choose a reason for hiding this comment

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

Yes. This is through the lucene branch of the code as it is

Copy link

@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.

I made a bunch of comments. It's possible that some of my complaints are already things we've agreed to live with for now (since I wasn't part of the earlier discussions)

Map<Object, Object> programAttributes = Context.getService(BahmniProgramWorkflowService.class).getPatientProgramAttributeByAttributeName(patientIds, programAttributeFieldName);
Set<Patient> patients = new HashSet<>();

if(identifier != null && !identifier.isEmpty()){

Choose a reason for hiding this comment

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

prefer to use org.apache.commons.lang3.StringUtils.isNotEmpty to combine both these checks.

Map<Object, Object> programAttributes = Context.getService(BahmniProgramWorkflowService.class).getPatientProgramAttributeByAttributeName(patientIds, programAttributeFieldName);
Set<Patient> patients = new HashSet<>();

if(identifier != null && !identifier.isEmpty()){

Choose a reason for hiding this comment

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

this whole block can be refactored so as not to duplicate the code blocks about calling name and customAttribute search.
Also, you're making the same patientService.getPatients(String, boolean, int, int) call all three of identifier, name, and customAttribute searching. Don't we need to somehow distinguish between what field we're searching for?

return patientResponse;
}else
return null;
Map<Object, Object> programAttributes = Context.getService(BahmniProgramWorkflowService.class).getPatientProgramAttributeByAttributeName(patientIds, programAttributeFieldName);

Choose a reason for hiding this comment

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

should autowire this service in the constructor instead of doing Context.getService

import java.util.LinkedHashMap;

@Indexed

Choose a reason for hiding this comment

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

Is this going to do anything here? This is not a hibernate managed class.

* @param searchParameters
* @return List of PatientResponse
*/
List<PatientResponse> luceneHibernateSearch(PatientSearchParameters searchParameters);

Choose a reason for hiding this comment

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

Why does this method name need to say this. It's possible that the under-the-hood implementation does in fact use lucene and then hibernate, but is that actually part of the interface contract? Isn't this just "searchBy" or something like that?

<changeSet id="201802211437" author="ningosi">
<preConditions onFail="MARK_RAN">
<sqlCheck expectedResult="1">
SELECT COUNT(*) FROM global_property where property = 'patientIdentifierSearch.matchMode';

Choose a reason for hiding this comment

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

if we're going to have a precondition here I'd have it also check that property_value != 'ANYWHERE'

SELECT COUNT(*) FROM global_property where property = 'patientIdentifierSearch.matchMode';
</sqlCheck>
</preConditions>
<comment>Specify how patient identifiers are matched while searching for a patient</comment>

Choose a reason for hiding this comment

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

This comment is not helpful since it provides no additional info that can't be inferred from "patientIdentifierSearch.matchMode". Instead say here why we're making the change, e.g. "change from default OpenMRS patient identifier matching behavior to search anywhere"

SELECT COUNT(*) FROM global_property where property = 'patientSearch.matchMode';
</sqlCheck>
</preConditions>
<comment>Specify how patient names are matched while searching for a patient</comment>

Choose a reason for hiding this comment

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

Same as above comment. Say why we're doing this, e.g. changing away from some default? (I thought this was already the default name search in OpenMRS)

SELECT COUNT(*) FROM global_property where property = 'person.attributeSearchMatchMode';
</sqlCheck>
</preConditions>
<comment>Specify how person attributes are matched while searching for a patients</comment>

Choose a reason for hiding this comment

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

same as above comment

pom.xml Outdated
@@ -24,7 +24,7 @@

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<openMRSVersion>2.1.1</openMRSVersion>
<openMRSVersion>2.1.3-SNAPSHOT</openMRSVersion>

Choose a reason for hiding this comment

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

Looks like 2.1.3 was already released, so this shouldn't point to a snapshot: https://github.com/openmrs/openmrs-core/releases/tag/2.1.3

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.

3 participants