partial solution implementation.
This commit is contained in:
parent
1b549d8a25
commit
4840a73cf6
|
@ -12,6 +12,7 @@ import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
|||
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
||||
import ca.uhn.fhir.jpa.api.model.ExpungeOptions;
|
||||
import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
|
||||
import ca.uhn.fhir.jpa.api.svc.IResourceSearchUrlSvc;
|
||||
import ca.uhn.fhir.jpa.binary.interceptor.BinaryStorageInterceptor;
|
||||
import ca.uhn.fhir.jpa.binary.provider.BinaryAccessProvider;
|
||||
import ca.uhn.fhir.jpa.bulk.export.api.IBulkDataExportJobSchedulingHelper;
|
||||
|
@ -124,6 +125,7 @@ import ca.uhn.fhir.jpa.searchparam.nickname.NicknameInterceptor;
|
|||
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamProvider;
|
||||
import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc;
|
||||
import ca.uhn.fhir.jpa.sp.SearchParamPresenceSvcImpl;
|
||||
import ca.uhn.fhir.jpa.search.ResourceSearchUrlSvcImpl;
|
||||
import ca.uhn.fhir.jpa.term.TermCodeSystemStorageSvcImpl;
|
||||
import ca.uhn.fhir.jpa.term.TermConceptMappingSvcImpl;
|
||||
import ca.uhn.fhir.jpa.term.TermReadSvcImpl;
|
||||
|
@ -792,4 +794,9 @@ public class JpaConfig {
|
|||
|
||||
@Bean
|
||||
IMdmLinkImplFactory<MdmLink> mdmLinkImplFactory() {return new JpaMdmLinkImplFactory();}
|
||||
|
||||
@Bean
|
||||
public IResourceSearchUrlSvc resourceSearchUrlSvc(){
|
||||
return new ResourceSearchUrlSvcImpl();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -405,6 +405,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||
|
||||
// Pre-cache the match URL
|
||||
if (theMatchUrl != null) {
|
||||
myMatchResourceUrlService.storeMatchUrlForResource(getResourceName(), theMatchUrl, jpaPid);
|
||||
myMatchResourceUrlService.matchUrlResolved(theTransactionDetails, getResourceName(), theMatchUrl, jpaPid);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package ca.uhn.fhir.jpa.dao.data;
|
||||
|
||||
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceSearchUrlEntity;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface IResourceSearchUrlDao extends JpaRepository<ResourceSearchUrlEntity, Long>, IHapiFhirJpaRepository{
|
||||
}
|
|
@ -88,6 +88,27 @@ public class HapiFhirJpaMigrationTasks extends BaseMigrationTasks<VersionEnum> {
|
|||
init620();
|
||||
init630();
|
||||
init640();
|
||||
init642();
|
||||
}
|
||||
|
||||
|
||||
protected void init642() {
|
||||
Builder version = forVersion(VersionEnum.V6_4_2);
|
||||
|
||||
Builder.BuilderWithTableName resSearchUrlTable = version.onTable("HFJ_RES_SEARCH_URL");
|
||||
|
||||
resSearchUrlTable.addColumn("20230227.1","PID").nonNullable().type(ColumnTypeEnum.LONG);
|
||||
resSearchUrlTable.addColumn("20230227.2", "RES_ID").nonNullable().type(ColumnTypeEnum.LONG);
|
||||
|
||||
resSearchUrlTable.addColumn("20230227.3", "RES_SEARC_URL").nonNullable().type(ColumnTypeEnum.STRING);
|
||||
resSearchUrlTable.addColumn("20230227.4", "RES_HASH").nonNullable().type(ColumnTypeEnum.STRING, 128);
|
||||
resSearchUrlTable.addColumn("20230227.5", "RES_SEARCH_URL").nonNullable().type(ColumnTypeEnum.STRING);
|
||||
resSearchUrlTable.addColumn("20230227.6", "CREATED_TIME").nonNullable().type(ColumnTypeEnum.DATE_TIMESTAMP);
|
||||
|
||||
resSearchUrlTable.addForeignKey("20230227.7", "FK_RESSEARCHURL_RESID").toColumn("RES_ID").references("HFJ_RESOURCE", "RES_ID");
|
||||
resSearchUrlTable.addIndex("20230227.8", "IDX_RES_HASH").unique(true).withColumns("RES_HASH");
|
||||
version.addIdGenerator("20230227.9", "SEQ_RESSEARCHURL_ID");
|
||||
|
||||
}
|
||||
|
||||
protected void init640() {
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
package ca.uhn.fhir.jpa.search;
|
||||
|
||||
import ca.uhn.fhir.jpa.api.svc.IResourceSearchUrlSvc;
|
||||
import ca.uhn.fhir.jpa.dao.data.IResourceSearchUrlDao;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceSearchUrlEntity;
|
||||
import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class ResourceSearchUrlSvcImpl implements IResourceSearchUrlSvc {
|
||||
|
||||
@Autowired
|
||||
private IResourceSearchUrlDao myResourceSearchUrlDao;
|
||||
|
||||
@Override
|
||||
public void saveResourceSearchUrl(String theCanonicalizedUrlForStorage, IResourcePersistentId theResourcePersistentId) {
|
||||
ResourceSearchUrlEntity searchUrlEntity = ResourceSearchUrlEntity.from(theCanonicalizedUrlForStorage, (Long)theResourcePersistentId.getId());
|
||||
myResourceSearchUrlDao.save(searchUrlEntity);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
package ca.uhn.fhir.jpa.model.entity;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.ForeignKey;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.persistence.SequenceGenerator;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
import java.util.Date;
|
||||
|
||||
@Entity
|
||||
@Table(name = "HFJ_RES_SEARCH_URL", uniqueConstraints = {@UniqueConstraint(name = "IDX_RES_HASH", columnNames = "RES_HASH")
|
||||
})
|
||||
public class ResourceSearchUrlEntity {
|
||||
|
||||
@Id
|
||||
@SequenceGenerator(name = "SEQ_RESSEARCHURL_ID", sequenceName = "SEQ_RESSEARCHURL_ID")
|
||||
@GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_RESSEARCHURL_ID")
|
||||
@Column(name = "PID")
|
||||
private Long myId;
|
||||
|
||||
@OneToOne()
|
||||
@JoinColumn(name = "RES_ID", referencedColumnName = "RES_ID", nullable = false, updatable = false, foreignKey = @ForeignKey(name = "FK_RESSEARCHURL_RESID"))
|
||||
private ResourceTable myResource;
|
||||
@Column(name = "RES_ID", insertable = false, updatable = false, nullable = false)
|
||||
private Long myResourcePid;
|
||||
|
||||
@Column(name = "RES_HASH", length = 128, nullable = false)
|
||||
private String myHash;
|
||||
|
||||
@Column(name = "RES_SEARCH_URL", nullable = false)
|
||||
private String mySearchUrl;
|
||||
|
||||
@Column(name = "CREATED_TIME", nullable = false)
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
private Date myCreatedTime;
|
||||
|
||||
public static ResourceSearchUrlEntity from(String theUrl, Long theId) {
|
||||
return new ResourceSearchUrlEntity()
|
||||
.setResourcePid(theId)
|
||||
.setSearchUrl(theUrl)
|
||||
.setCreatedTime(new Date());
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return myId;
|
||||
}
|
||||
|
||||
public ResourceSearchUrlEntity setId(Long theId) {
|
||||
myId = theId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ResourceTable getResource() {
|
||||
return myResource;
|
||||
}
|
||||
|
||||
public ResourceSearchUrlEntity setResource(ResourceTable theResource) {
|
||||
myResource = theResource;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Long getResourcePid() {
|
||||
return myResourcePid;
|
||||
}
|
||||
|
||||
public ResourceSearchUrlEntity setResourcePid(Long theResourcePid) {
|
||||
myResourcePid = theResourcePid;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Date getCreatedTime() {
|
||||
return myCreatedTime;
|
||||
}
|
||||
|
||||
public ResourceSearchUrlEntity setCreatedTime(Date theCreatedTime) {
|
||||
myCreatedTime = theCreatedTime;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getHash() {
|
||||
return myHash;
|
||||
}
|
||||
|
||||
public ResourceSearchUrlEntity setHash(String theHash) {
|
||||
myHash = theHash;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getSearchUrl() {
|
||||
return mySearchUrl;
|
||||
}
|
||||
|
||||
public ResourceSearchUrlEntity setSearchUrl(String theSearchUrl) {
|
||||
mySearchUrl = theSearchUrl;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package ca.uhn.fhir.jpa.api.svc;
|
||||
|
||||
import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
|
||||
|
||||
public interface IResourceSearchUrlSvc {
|
||||
void saveResourceSearchUrl(String theCanonicalizedUrlForStorage, IResourcePersistentId theResourcePersistentId);
|
||||
}
|
|
@ -58,6 +58,7 @@ import java.util.Map;
|
|||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import ca.uhn.fhir.jpa.api.svc.IResourceSearchUrlSvc;
|
||||
|
||||
@Service
|
||||
public class MatchResourceUrlService<T extends IResourcePersistentId> {
|
||||
|
@ -76,6 +77,8 @@ public class MatchResourceUrlService<T extends IResourcePersistentId> {
|
|||
private IInterceptorBroadcaster myInterceptorBroadcaster;
|
||||
@Autowired
|
||||
private MemoryCacheService myMemoryCacheService;
|
||||
@Autowired
|
||||
private IResourceSearchUrlSvc myResourceSearchUrlSvc;
|
||||
|
||||
/**
|
||||
* Note that this will only return a maximum of 2 results!!
|
||||
|
@ -109,8 +112,7 @@ public class MatchResourceUrlService<T extends IResourcePersistentId> {
|
|||
}
|
||||
|
||||
if (retVal == null) {
|
||||
RuntimeResourceDefinition resourceDef = myContext.getResourceDefinition(theResourceType);
|
||||
SearchParameterMap paramMap = myMatchUrlService.translateMatchUrl(matchUrl, resourceDef);
|
||||
SearchParameterMap paramMap = deriveSearchParameterMap(matchUrl, myContext.getResourceType(theResourceType));
|
||||
if (paramMap.isEmpty() && paramMap.getLastUpdated() == null) {
|
||||
throw new InvalidRequestException(Msg.code(518) + "Invalid match URL[" + matchUrl + "] - URL has no search parameters");
|
||||
}
|
||||
|
@ -162,6 +164,11 @@ public class MatchResourceUrlService<T extends IResourcePersistentId> {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
private SearchParameterMap deriveSearchParameterMap(String theMatchUrl, String theResourceType) {
|
||||
RuntimeResourceDefinition resourceDef = myContext.getResourceDefinition(theResourceType);
|
||||
return myMatchUrlService.translateMatchUrl(theMatchUrl, resourceDef);
|
||||
}
|
||||
|
||||
private <R extends IBaseResource> IFhirResourceDao<R> getResourceDao(Class<R> theResourceType) {
|
||||
IFhirResourceDao<R> dao = myDaoRegistry.getResourceDao(theResourceType);
|
||||
if (dao == null) {
|
||||
|
@ -223,4 +230,11 @@ public class MatchResourceUrlService<T extends IResourcePersistentId> {
|
|||
}
|
||||
}
|
||||
|
||||
public void storeMatchUrlForResource(String theResourceName, String theMatchUrl, T theResourcePersistentId) {
|
||||
SearchParameterMap matchUrlSearchParameterMap = deriveSearchParameterMap(theMatchUrl, theResourceName);
|
||||
String canonicalizedMatchUrl = matchUrlSearchParameterMap.toNormalizedQueryString(myContext);
|
||||
|
||||
String canonicalizedUrlForStorage = massageForStorage(theResourceName, canonicalizedMatchUrl);
|
||||
myResourceSearchUrlSvc.saveResourceSearchUrl(canonicalizedUrlForStorage, theResourcePersistentId);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue