Final commit before working on dedicated branches to work on separate issues.

This commit is contained in:
Luke deGruchy 2023-03-02 13:10:09 -05:00
parent ab7e8cc2ee
commit 4b5cc68898
11 changed files with 227 additions and 2 deletions

View File

@ -175,6 +175,7 @@ public class Constants {
public static final String PARAM_FORMAT = "_format";
public static final String PARAM_HAS = "_has";
public static final String PARAM_HISTORY = "_history";
public static final String PARAM_HISTORY_COUNT = "_historyCount";
public static final String PARAM_INCLUDE = "_include";
public static final String PARAM_INCLUDE_QUALIFIER_RECURSE = ":recurse";
public static final String PARAM_INCLUDE_RECURSE = "_include" + PARAM_INCLUDE_QUALIFIER_RECURSE;
@ -312,6 +313,8 @@ public class Constants {
*/
public static final int UUID_LENGTH = 36;
public static final String HIBERNATE_INTEGRATION_ENVERS_ENABLED = "hibernate.integration.envers.enabled";
static {
CHARSET_UTF8 = StandardCharsets.UTF_8;
CHARSET_US_ASCII = StandardCharsets.ISO_8859_1;

View File

@ -33,6 +33,7 @@ import ca.uhn.fhir.mdm.api.MdmQuerySearchParameters;
import ca.uhn.fhir.mdm.api.paging.MdmPageRequest;
import ca.uhn.fhir.mdm.dao.IMdmLinkDao;
import ca.uhn.fhir.mdm.model.MdmPidTuple;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.SortOrderEnum;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import org.apache.commons.collections4.CollectionUtils;
@ -239,8 +240,24 @@ public class MdmLinkDaoJpaImpl implements IMdmLinkDao<JpaPid, MdmLink> {
.setMaxResults(pageRequest.getCount())
.getResultList();
// TODO: remove this
result.forEach(mdmLink -> findHistory(mdmLink.getId()));
// TODO: move this into the history method
// final Object propertyHibernateEnversEnabled = myEntityManager.getProperties().get(Constants.HIBERNATE_INTEGRATION_ENVERS_ENABLED);
//
// if (propertyHibernateEnversEnabled instanceof Boolean) {
// if ((Boolean)propertyHibernateEnversEnabled) {
// ourLog.info("envers property IS a Boolean: value: {}", propertyHibernateEnversEnabled);
// // TODO: add pagination to this
// final Integer historyCount = theParams.getHistoryCount();
// final List<Revisions<Integer, MdmLink>> revisions =
// result.stream()
// .map(mdmLink -> findHistory(mdmLink.getId()))
// .collect(Collectors.toUnmodifiableList());
// } else {
// ourLog.info("envers property is NOT a Boolean: class: {} value: {}", propertyHibernateEnversEnabled.getClass(), propertyHibernateEnversEnabled);
// }
// }
return new PageImpl<>(result,
PageRequest.of(pageRequest.getPage(), pageRequest.getCount()),

View File

@ -32,6 +32,8 @@ import ca.uhn.fhir.mdm.api.IMdmControllerSvc;
import ca.uhn.fhir.mdm.api.IMdmLinkCreateSvc;
import ca.uhn.fhir.mdm.api.IMdmLinkQuerySvc;
import ca.uhn.fhir.mdm.api.IMdmLinkUpdaterSvc;
import ca.uhn.fhir.mdm.api.MdmHistorySearchParameters;
import ca.uhn.fhir.mdm.api.MdmLinkHistoryJson;
import ca.uhn.fhir.mdm.api.MdmLinkJson;
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
import ca.uhn.fhir.mdm.api.MdmQuerySearchParameters;
@ -156,6 +158,11 @@ public class MdmControllerSvcImpl implements IMdmControllerSvc {
return myMdmLinkQuerySvc.queryLinks(theMdmQuerySearchParameters, theMdmTransactionContext);
}
@Override
public Page<MdmLinkHistoryJson> queryLinkHistory(MdmHistorySearchParameters theMdmHistorySearchParameters, MdmTransactionContext theMdmTransactionContext) {
return myMdmLinkQuerySvc.queryLinkHistory(theMdmHistorySearchParameters, theMdmTransactionContext);
}
@Override
public Page<MdmLinkJson> getDuplicateGoldenResources(MdmTransactionContext theMdmTransactionContext, MdmPageRequest thePageRequest) {
return myMdmLinkQuerySvc.getDuplicateGoldenResources(theMdmTransactionContext, thePageRequest, null, null);

View File

@ -23,6 +23,8 @@ package ca.uhn.fhir.jpa.mdm.svc;
import ca.uhn.fhir.jpa.mdm.dao.MdmLinkDaoSvc;
import ca.uhn.fhir.mdm.api.IMdmLink;
import ca.uhn.fhir.mdm.api.IMdmLinkQuerySvc;
import ca.uhn.fhir.mdm.api.MdmHistorySearchParameters;
import ca.uhn.fhir.mdm.api.MdmLinkHistoryJson;
import ca.uhn.fhir.mdm.api.MdmLinkJson;
import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum;
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
@ -103,4 +105,11 @@ public class MdmLinkQuerySvcImplSvc implements IMdmLinkQuerySvc {
Page<? extends IMdmLink> mdmLinkPage = myMdmLinkDaoSvc.executeTypedQuery(mdmQuerySearchParameters);
return mdmLinkPage.map(myMdmModelConverterSvc::toJson);
}
@Override
public Page<MdmLinkHistoryJson> queryLinkHistory(MdmHistorySearchParameters theMdmHistorySearchParameters, MdmTransactionContext theMdmTransactionContext) {
return null;
}
}

View File

@ -47,6 +47,8 @@ public interface IMdmControllerSvc {
Page<MdmLinkJson> queryLinksFromPartitionList(MdmQuerySearchParameters theMdmQuerySearchParameters, MdmTransactionContext theMdmTransactionContext);
Page<MdmLinkHistoryJson> queryLinkHistory(MdmHistorySearchParameters theMdmHistorySearchParameters, MdmTransactionContext theMdmTransactionContext);
Page<MdmLinkJson> getDuplicateGoldenResources(MdmTransactionContext theMdmTransactionContext, MdmPageRequest thePageRequest);
Page<MdmLinkJson> getDuplicateGoldenResources(MdmTransactionContext theMdmTransactionContext, MdmPageRequest thePageRequest, RequestDetails theRequestDetails, String theRequestResourceType);

View File

@ -38,4 +38,6 @@ public interface IMdmLinkQuerySvc {
Page<MdmLinkJson> queryLinks(MdmQuerySearchParameters theMdmQuerySearchParameters, MdmTransactionContext theMdmContext);
Page<MdmLinkJson> getDuplicateGoldenResources(MdmTransactionContext theMdmContext, MdmPageRequest thePageRequest);
Page<MdmLinkJson> getDuplicateGoldenResources(MdmTransactionContext theMdmContext, MdmPageRequest thePageRequest, List<Integer> thePartitionId, String theRequestResourceType);
Page<MdmLinkHistoryJson> queryLinkHistory(MdmHistorySearchParameters theMdmHistorySearchParameters, MdmTransactionContext theMdmTransactionContext);
}

View File

@ -0,0 +1,52 @@
package ca.uhn.fhir.mdm.api;
/*-
* #%L
* HAPI FHIR - Master Data Management
* %%
* Copyright (C) 2014 - 2023 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.hl7.fhir.instance.model.api.IIdType;
public class MdmHistorySearchParameters {
// TODO: mdmLinkId
// TODO: goldenResourceId
public static final String MDM_LINK_ID = "myMdmLinkId";
private IIdType myMdmLinkId;
// TODO: other constructors?
public MdmHistorySearchParameters() {}
public IIdType getMdmLinkId() {
return myMdmLinkId;
}
public MdmHistorySearchParameters setMdmLinkId(IIdType theMdmLinkId) {
myMdmLinkId = theMdmLinkId;
return this;
}
@Override
public String toString() {
return new ToStringBuilder(this)
.append("myMdmLinkId", myMdmLinkId)
.toString();
}
}

View File

@ -0,0 +1,42 @@
package ca.uhn.fhir.mdm.api;
/*-
* #%L
* HAPI FHIR - Master Data Management
* %%
* Copyright (C) 2014 - 2023 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.model.api.IModelJson;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.ArrayList;
import java.util.List;
public class MdmLinkHistoryJson implements IModelJson {
// TODO: wrap this with revision data
@JsonProperty(value = "mdmLinks", required = true)
List<MdmLinkJson> myMdmLinks = new ArrayList<>();
public MdmLinkHistoryJson addMdmLink(MdmLinkJson theMdmLinkJson) {
myMdmLinks.add(theMdmLinkJson);
return this;
}
public MdmLinkJson getMdmLink(int theIndex) {
return myMdmLinks.get(theIndex);
}
}

View File

@ -22,6 +22,7 @@ package ca.uhn.fhir.mdm.provider;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.mdm.api.MdmLinkHistoryJson;
import ca.uhn.fhir.mdm.api.MdmLinkJson;
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
import ca.uhn.fhir.mdm.api.paging.MdmPageLinkBuilder;
@ -115,6 +116,13 @@ public abstract class BaseMdmProvider {
return theString.getValue();
}
protected Integer extractIntegerOrNull(IPrimitiveType<Integer> theInteger) {
if (theInteger == null) {
return null;
}
return theInteger.getValue();
}
protected IBaseParameters parametersFromMdmLinks(Page<MdmLinkJson> theMdmLinkStream, boolean includeResultAndSource,
ServletRequestDetails theServletRequestDetails, MdmPageRequest thePageRequest) {
IBaseParameters retval = ParametersUtil.newInstance(myFhirContext);
@ -137,6 +145,28 @@ public abstract class BaseMdmProvider {
return retval;
}
protected IBaseParameters parametersFromMdmLinkHistory(Page<MdmLinkHistoryJson> theMdmLinkHistoryStream, boolean includeResultAndSource,
ServletRequestDetails theServletRequestDetails, MdmPageRequest thePageRequest) {
IBaseParameters retval = ParametersUtil.newInstance(myFhirContext);
addPagingParametersForHistory(retval, theMdmLinkHistoryStream, theServletRequestDetails, thePageRequest);
theMdmLinkHistoryStream.getContent().forEach(mdmLinkHistory -> {
IBase resultPart = ParametersUtil.addParameterToParameters(myFhirContext, retval, "link");
// ParametersUtil.addPartString(myFhirContext, resultPart, "goldenResourceId", mdmLink.getGoldenResourceId());
// ParametersUtil.addPartString(myFhirContext, resultPart, "sourceResourceId", mdmLink.getSourceId());
//
// if (includeResultAndSource) {
// ParametersUtil.addPartString(myFhirContext, resultPart, "matchResult", mdmLink.getMatchResult().name());
// ParametersUtil.addPartString(myFhirContext, resultPart, "linkSource", mdmLink.getLinkSource().name());
// ParametersUtil.addPartBoolean(myFhirContext, resultPart, "eidMatch", mdmLink.getEidMatch());
// ParametersUtil.addPartBoolean(myFhirContext, resultPart, "hadToCreateNewResource", mdmLink.getLinkCreatedNewResource());
// ParametersUtil.addPartDecimal(myFhirContext, resultPart, "score", mdmLink.getScore());
// ParametersUtil.addPartDecimal(myFhirContext, resultPart, "linkCreated", (double) mdmLink.getCreated().getTime());
// ParametersUtil.addPartDecimal(myFhirContext, resultPart, "linkUpdated", (double) mdmLink.getUpdated().getTime());
// }
});
return retval;
}
protected void addPagingParameters(IBaseParameters theParameters, Page<MdmLinkJson> theCurrentPage, ServletRequestDetails theServletRequestDetails, MdmPageRequest thePageRequest) {
MdmPageLinkTuple mdmPageLinkTuple = MdmPageLinkBuilder.buildMdmPageLinks(theServletRequestDetails, theCurrentPage, thePageRequest);
@ -150,4 +180,18 @@ public abstract class BaseMdmProvider {
ParametersUtil.addParameterToParametersUri(myFhirContext, theParameters, "next", mdmPageLinkTuple.getNextLink().get());
}
}
protected void addPagingParametersForHistory(IBaseParameters theParameters, Page<MdmLinkHistoryJson> theCurrentPage, ServletRequestDetails theServletRequestDetails, MdmPageRequest thePageRequest) {
// MdmPageLinkTuple mdmPageLinkTuple = MdmPageLinkBuilder.buildMdmPageLinks(theServletRequestDetails, theCurrentPage, thePageRequest);
//
// if (mdmPageLinkTuple.getPreviousLink().isPresent()) {
// ParametersUtil.addParameterToParametersUri(myFhirContext, theParameters, "prev", mdmPageLinkTuple.getPreviousLink().get());
// }
//
// ParametersUtil.addParameterToParametersUri(myFhirContext, theParameters, "self", mdmPageLinkTuple.getSelfLink());
//
// if (mdmPageLinkTuple.getNextLink().isPresent()) {
// ParametersUtil.addParameterToParametersUri(myFhirContext, theParameters, "next", mdmPageLinkTuple.getNextLink().get());
// }
}
}

View File

@ -26,7 +26,10 @@ import ca.uhn.fhir.mdm.api.IMdmControllerSvc;
import ca.uhn.fhir.mdm.api.IMdmSettings;
import ca.uhn.fhir.mdm.api.IMdmSubmitSvc;
import ca.uhn.fhir.mdm.api.MdmConstants;
import ca.uhn.fhir.mdm.api.MdmLinkHistoryJson;
import ca.uhn.fhir.mdm.api.MdmLinkJson;
import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum;
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
import ca.uhn.fhir.mdm.api.MdmQuerySearchParameters;
import ca.uhn.fhir.mdm.api.paging.MdmPageRequest;
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
@ -42,6 +45,7 @@ import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import ca.uhn.fhir.util.ParametersUtil;
import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBase;
import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IBaseParameters;
import org.hl7.fhir.instance.model.api.IBaseResource;
@ -49,6 +53,7 @@ import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.slf4j.Logger;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import javax.annotation.Nonnull;
import java.math.BigDecimal;
@ -177,6 +182,7 @@ public class MdmProviderDstu3Plus extends BaseMdmProvider {
// TODO: figure out how to provide a history operation here or if at all
// TODO: we probably need to update documentation depending on how the feature will work
// TODO: how should this behave if they've turned off envers?
@Operation(name = ProviderConstants.MDM_QUERY_LINKS, idempotent = true)
public IBaseParameters queryLinks(@OperationParam(name = ProviderConstants.MDM_QUERY_LINKS_GOLDEN_RESOURCE_ID, min = 0, max = 1, typeName = "string") IPrimitiveType<String> theGoldenResourceId,
@OperationParam(name = ProviderConstants.MDM_QUERY_LINKS_RESOURCE_ID, min = 0, max = 1, typeName = "string") IPrimitiveType<String> theResourceId,
@ -213,6 +219,46 @@ public class MdmProviderDstu3Plus extends BaseMdmProvider {
return parametersFromMdmLinks(mdmLinkJson, true, theRequestDetails, mdmPageRequest);
}
// TODO: what does idempotent mean in this case?
@Operation(name = ProviderConstants.MDM_LINK_HISTORY, idempotent = true)
// public IBaseParameters historyLinks() {
// public List<MdmLinkHistoryJson> historyLinks(@OperationParam(name = ProviderConstants.MDM_QUERY_LINKS_GOLDEN_RESOURCE_ID, min = 0, max = 1, typeName = "string") IPrimitiveType<String> theMdmGoldenResourceId) {
public IBaseParameters historyLinks(@OperationParam(name = ProviderConstants.MDM_QUERY_LINKS_GOLDEN_RESOURCE_ID, min = 0, max = 1, typeName = "string") IPrimitiveType<String> theMdmGoldenResourceId) {
ourLog.info("history: mdmLinkId: {}", theMdmGoldenResourceId);
Page<MdmLinkHistoryJson> mdmLinkJson = myMdmControllerSvc.queryLinkHistory(null, null);
final MdmLinkJson mdmLinkJson1 = buildMdmLinkJson(MdmLinkSourceEnum.MANUAL, MdmMatchResultEnum.MATCH, "goldenResourceId1", "sourceId1");
final MdmLinkJson mdmLinkJson2 = buildMdmLinkJson(MdmLinkSourceEnum.AUTO, MdmMatchResultEnum.NO_MATCH, "goldenResourceId1", "sourceId1");
final MdmLinkJson mdmLinkJson3 = buildMdmLinkJson(MdmLinkSourceEnum.MANUAL, MdmMatchResultEnum.GOLDEN_RECORD, "goldenResourceId1", "sourceId1");
final List<MdmLinkHistoryJson> mdmLinkHistoryJsons = List.of(new MdmLinkHistoryJson().addMdmLink(mdmLinkJson1).addMdmLink(mdmLinkJson2).addMdmLink(mdmLinkJson3));
final PageImpl<MdmLinkHistoryJson> hardCodedMdmLinkHistory = new PageImpl<>(mdmLinkHistoryJsons);
// return mdmLinkHistoryJsons;
// return null;
IBaseParameters retVal = ParametersUtil.newInstance(myFhirContext);
hardCodedMdmLinkHistory.forEach(mdmLinkHistory -> {
IBase resultPart = ParametersUtil.addParameterToParameters(myFhirContext, retVal, "historical link");
ParametersUtil.addPartString(myFhirContext, resultPart, "goldenResourceId", mdmLinkHistory.getMdmLink(0).getGoldenResourceId());
});
return retVal;
}
// TODO: move this to a unit test
private static MdmLinkJson buildMdmLinkJson(MdmLinkSourceEnum theMdmLinkSourceEnum, MdmMatchResultEnum theMdmMatchResultEnum, String theGoldenResourceId, String theSourceId) {
final MdmLinkJson link = new MdmLinkJson();
link.setLinkSource(theMdmLinkSourceEnum);
link.setMatchResult(theMdmMatchResultEnum);
link.setGoldenResourceId(theGoldenResourceId);
link.setSourceId(theSourceId);
return link;
}
@Operation(name = ProviderConstants.MDM_DUPLICATE_GOLDEN_RESOURCES, idempotent = true)
public IBaseParameters getDuplicateGoldenResources(
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")

View File

@ -86,6 +86,7 @@ public class ProviderConstants {
public static final String MDM_CREATE_LINK_MATCH_RESULT = "matchResult";
public static final String MDM_QUERY_LINKS = "$mdm-query-links";
public static final String MDM_LINK_HISTORY = "$mdm-link-history";
public static final String MDM_QUERY_LINKS_GOLDEN_RESOURCE_ID = "goldenResourceId";
public static final String MDM_QUERY_LINKS_RESOURCE_ID = "resourceId";
public static final String MDM_QUERY_PARTITION_IDS = "partitionIds";