在Spring REST应用程序中实现中介器设计模式?

时间:2019-06-11 12:38:52

标签: java spring spring-boot hl7-fhir mediator

我正在使用FHIR API。我有一个PatientService接口和2个实现类,例如DSTU2PatientService,STU3PatientService。

我们的客户有一个针对人口统计的已实现的FHIR DSTU2 API,而过程位于STU3中。

我的用例是,当患者请求从EHR系统获取健康数据时,如何区分应调用哪个服务(DSTU2 / STU3)。

如何包含中介模式以动态实现调用?我不想使用if条件。

application.properties

fhir.demogrphics=DSTU2
fhir.procedure=STU3

FHIRPatientService.java

public interface FHIRPatientService {

    Object getDemographics(PatientDTO patient);

    Object getProcedures(PatientDTO patient);
}

我已经集成了FHIR DSTU2 API DSTU2PatientService

DSTU2PatientService.java

@Service(value = "dstu2PatientService")
public class DSTU2PatientService implements PatientService {

    private static final Logger LOG = LoggerFactory.getLogger(DSTU2PatientService.class);

    private FhirContext fhirContextDstu2;

    @Autowired
    private FHIRConfig fhirConfig;

    @Autowired
    private BasicAuthInterceptor authInterceptor;

    public DSTU2PatientService(@Qualifier("fhirContextDstu2") FhirContext fhirContextDstu2) {
        this.fhirContextDstu2 = fhirContextDstu2;
    }

    @Override
    public Object getDemographics(PatientDTO patient) {
        Bundle bundle = null;
        try {
            IGenericClient clientDstu2 = fhirContextDstu2.newRestfulGenericClient(fhirConfig.getFhirServerPathDstu2());
            clientDstu2.registerInterceptor(authInterceptor);

            bundle = clientDstu2.search()
                .forResource(Patient.class)
                .where(Patient.GIVEN.matches().value(patient.getGiven()))
                .and(Patient.FAMILY.matches().value(patient.getFamily()))
                .and(Patient.BIRTHDATE.exactly().day(patient.getBirthdate()))
                .and(Patient.ADDRESS.contains().value(patient.getAddress()))
                .and(Patient.GENDER.exactly().codes(patient.getGender()))
                .returnBundle(Bundle.class)
                .execute();
        }catch(Exception e){
            LOG.error("Demographics: {}", e.getMessage());
            bundle = new Bundle();
        }
        return bundle;
    }

    @Override
    public Object getProcedures(PatientDTO patient) {
        Bundle bundle = null;
        try {
            IGenericClient clientDstu2 = fhirContextDstu2.newRestfulGenericClient(fhirConfig.getFhirServerPathDstu2());
            clientDstu2.registerInterceptor(authInterceptor);
            clientDstu2.registerInterceptor(CommonUtil.headersInterceptor(patient.getMychartId()));
            bundle = clientDstu2.search()
                    .forResource(Procedure.class)
                    .where(new ReferenceClientParam("patient").hasId(patient.getSubject()))
                    .and(Procedure.DATE.afterOrEquals().day(patient.getStartDate()))
                    .and(Procedure.DATE.beforeOrEquals().day(patient.getEndDate()))
                    .returnBundle(Bundle.class)
                    .execute();
        }catch(Exception e){
            LOG.error("Procedures: {}", e.getMessage());
            bundle = new Bundle();
        }
        return bundle;
    }
}

我已经集成了FHIR STU3 API STU3PatientService

STU3PatientService.java

@Service(value = "stu3PatientService")
public class STU3PatientService implements PatientService {

    private static final Logger LOG = LoggerFactory.getLogger(STU3PatientService.class);

    private FhirContext fhirContextStu3;

    @Autowired
    private FHIRConfig fhirConfig;

    @Autowired
    private BasicAuthInterceptor authInterceptor;

    public STU3PatientService(@Qualifier("fhirContextStu3") FhirContext fhirContextStu3) {
        this.fhirContextStu3 = fhirContextStu3;
    }

    @Override
    public Object getDemographics(PatientDTO patient) {
        Bundle bundle = null;
        try {
            IGenericClient clientStu3 = fhirContextStu3.newRestfulGenericClient(fhirConfig.getFhirServerPathStu3());
            clientStu3.registerInterceptor(authInterceptor);

            bundle = clientStu3.search()
                    .forResource(Patient.class)
                    .where(Patient.GIVEN.matches().value(patient.getGiven()))
                    .and(Patient.FAMILY.matches().value(patient.getFamily()))
                    .and(Patient.BIRTHDATE.exactly().day(patient.getBirthdate()))
                    .and(Patient.ADDRESS.contains().value(patient.getAddress()))
                    .and(Patient.GENDER.exactly().codes(patient.getGender()))
                    .returnBundle(Bundle.class)
                    .execute();
        }catch(Exception e){
            LOG.error("Demographics: {}", e.getMessage());
            bundle = new Bundle();
        }
        return bundle;
    }

    @Override
    public bundle getProcedures(PatientDTO patient) {
        Bundle bundle = null;
        try {
            IGenericClient clientStu3 = fhirContextStu3.newRestfulGenericClient(fhirConfig.getFhirServerPathStu3());
            clientStu3.registerInterceptor(authInterceptor);
            clientStu3.registerInterceptor(CommonUtil.headersInterceptor(patient.getMychartId()));

            bundle = clientStu3.search()
                    .forResource(Procedure.class)
                    .where(new ReferenceClientParam("patient").hasId(patient.getSubject()))
                    .and(Procedure.DATE.afterOrEquals().day(patient.getStartDate()))
                    .and(Procedure.DATE.beforeOrEquals().day(patient.getEndDate()))
                    .returnBundle(Bundle.class)
                    .execute();
        }catch(Exception e){
            LOG.error("Procedures: {}", e.getMessage());
            bundle = new Bundle();
        }
        return bundle;
    }

}

FHIRComponent.java

@Component(value = "fhirService")
public class FHIRComponent {

    private static final Logger LOG = LoggerFactory.getLogger(FHIRComponent.class);

    private FHIRResourceVersionConfig fhirResourceVersionConfig;
    private PatientService dstu2PatientService;
    private PatientService stu3PatientService;

    public FHIRComponent(
            @Qualifier("dstu2PatientService") FHIRPatientService dstu2PatientService,
            @Qualifier("stu3PatientService") FHIRPatientService stu3PatientService,
            FHIRResourceVersionConfig fhirResourceVersionConfig) {
        this.dstu2PatientService = dstu2PatientService;
        this.stu3PatientService = stu3PatientService;
        this.fhirResourceVersionConfig = fhirResourceVersionConfig;
    }

    public Object getDemographics(PatientDTO patient, String resourceType) {
        Object result = null;

        if("DSTU2".equalsIgnoreCase(fhirResourceVersionConfig.findResource(resourceName)))
            result = patientServiceDstu2.getDemographics(patient);
        else
            result = patientServiceStu3.getDemographics(patient);
        return result;
    }

    public Object getConditions(PatientDTO patient) {
        Object result = null;

        if("DSTU2".equalsIgnoreCase(fhirResourceVersionConfig.findResource(resourceName)))
            result = patientServiceDstu2.getConditions(patient);
        else
            result = patientServiceStu3.getConditions(patient);
        return result;
    }
}

1 个答案:

答案 0 :(得分:1)

您需要让FHIRPatientService知道它负责哪个代码:

public interface FHIRPatientService {

   String getCode();

   Object getDemographics(PatientDTO patient);

   Object getProcedures(PatientDTO patient);
}

然后您可以重构组件

@Component(value = "fhirService")
public class FHIRComponent {

    private static final Logger LOG = LoggerFactory.getLogger(FHIRComponent.class);

    private FHIRResourceVersionConfig fhirResourceVersionConfig;
    private List<PatientService> patientServices;//spring will inject all services

    public FHIRComponent(
        List<PatientService> patientServices,
        FHIRResourceVersionConfig fhirResourceVersionConfig) {
        this.patientServices= patientServices;
        this.fhirResourceVersionConfig = fhirResourceVersionConfig;
    }

    private Optional<PatientService> getService(String resourceType){
        return patientServices.stream()
            .filter(service => service.getCode().equalsIgnoreCase(fhirResourceVersionConfig.findResource(resourceName)))
            .findAny() 
    }

    public Object getDemographics(PatientDTO patient, String resourceType) {
        return getService(resourceType)
            .map(service => service.getDemographics(patient))
            .orElse(null);
   }
  ...

我希望我的理解有点清晰...