Skip to content
This repository has been archived by the owner on Nov 17, 2023. It is now read-only.

Download Allow List Process #138

Merged
merged 3 commits into from
Oct 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<artifactId>dsf-bpe-process-update-whitelist</artifactId>
<artifactId>dsf-bpe-process-update-allow-list</artifactId>

<parent>
<groupId>org.highmed.dsf</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.highmed.dsf.bpe.plugin;

import org.camunda.bpm.engine.ProcessEngine;
import org.camunda.bpm.model.bpmn.BpmnModelInstance;

public class UpdateAllowListPlugin extends AbstractProcessEnginePlugin
{
private static final String UPDATE_ALLOW_LIST_FILE = "updateAllowList.bpmn";
private static final String DOWNLOAD_ALLOW_LIST_FILE = "downloadAllowList.bpmn";

@Override
public void postProcessEngineBuild(ProcessEngine processEngine)
{
BpmnModelInstance updateAllowListProcess = readAndValidateModel("/" + UPDATE_ALLOW_LIST_FILE);
deploy(processEngine, UPDATE_ALLOW_LIST_FILE, updateAllowListProcess);

BpmnModelInstance downloadAllowListProcess = readAndValidateModel("/" + DOWNLOAD_ALLOW_LIST_FILE);
deploy(processEngine, DOWNLOAD_ALLOW_LIST_FILE, downloadAllowListProcess);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package org.highmed.dsf.bpe.service;

import java.util.EnumSet;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import javax.ws.rs.WebApplicationException;

import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.highmed.dsf.bpe.ConstantsBase;
import org.highmed.dsf.bpe.delegate.AbstractServiceDelegate;
import org.highmed.dsf.bpe.variables.ConstantsUpdateAllowList;
import org.highmed.dsf.fhir.client.FhirWebserviceClientProvider;
import org.highmed.dsf.fhir.task.TaskHelper;
import org.highmed.fhir.client.FhirWebserviceClient;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Bundle.BundleType;
import org.hl7.fhir.r4.model.IdType;
import org.hl7.fhir.r4.model.Reference;
import org.hl7.fhir.r4.model.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ca.uhn.fhir.context.FhirContext;

public class DownloadAllowList extends AbstractServiceDelegate
{
private static final Logger logger = LoggerFactory.getLogger(DownloadAllowList.class);

private final FhirContext context;

public DownloadAllowList(FhirWebserviceClientProvider clientProvider, TaskHelper taskHelper, FhirContext context)
{
super(clientProvider, taskHelper);
this.context = context;
}

@Override
public void afterPropertiesSet() throws Exception
{
super.afterPropertiesSet();
Objects.requireNonNull(context, "fhirContext");
}

@Override
protected void doExecute(DelegateExecution execution) throws Exception
{
Task task = (Task) execution.getVariable(ConstantsBase.VARIABLE_TASK);
IdType bundleId = getBundleId(task);
FhirWebserviceClient requesterClient = getFhirWebserviceClientProvider()
.getRemoteWebserviceClient(bundleId.getBaseUrl());

Bundle bundle;
try
{
if (bundleId.hasVersionIdPart())
bundle = requesterClient.read(Bundle.class, bundleId.getIdPart(), bundleId.getVersionIdPart());
else
bundle = requesterClient.read(Bundle.class, bundleId.getIdPart());
}
catch (WebApplicationException e)
{
logger.error("Error while reading Bundle with id {} from organization {}: {}", bundleId.getValue(),
task.getRequester().getReference(), e.getMessage());
throw new RuntimeException("Error while reading Bundle with id " + bundleId.getValue()
+ " from organization " + task.getRequester().getReference() + ", " + e.getMessage(), e);
}

if (!EnumSet.of(BundleType.TRANSACTION, BundleType.BATCH).contains(bundle.getType()))
{
logger.error("Bundle type TRANSACTION or BATCH expected, but got {}", bundle.getType());
throw new RuntimeException("Bundle type TRANSACTION or BATCH expected, but got " + bundle.getType());
}

try
{
logger.debug("Posting bundle to local endpoint: {}", context.newXmlParser().encodeResourceToString(bundle));
getFhirWebserviceClientProvider().getLocalWebserviceClient().withMinimalReturn().postBundle(bundle);
}
catch (Exception e)
{
logger.error("Error while executing Bundle with id {} from organization {} locally: {}",
bundleId.getValue(), task.getRequester().getReference(), e.getMessage());
throw new RuntimeException("Error while executing Bundle with id " + bundleId.getValue()
+ " from organization " + task.getRequester().getReference() + " locally, " + e.getMessage(), e);
}
}

private IdType getBundleId(Task task)
{
List<Reference> bundleReferences = getTaskHelper()
.getInputParameterReferenceValues(task, ConstantsUpdateAllowList.CODESYSTEM_HIGHMED_UPDATE_ALLOW_LIST,
ConstantsUpdateAllowList.CODESYSTEM_HIGHMED_UPDATE_ALLOW_LIST_VALUE_ALLOW_LIST)
.collect(Collectors.toList());

if (bundleReferences.size() != 1)
{
logger.error("Task input parameter {} contains unexpected number of Bundle IDs, expected 1, got {}",
ConstantsUpdateAllowList.CODESYSTEM_HIGHMED_UPDATE_ALLOW_LIST_VALUE_ALLOW_LIST,
bundleReferences.size());
throw new RuntimeException("Task input parameter "
+ ConstantsUpdateAllowList.CODESYSTEM_HIGHMED_UPDATE_ALLOW_LIST_VALUE_ALLOW_LIST
+ " contains unexpected number of Bundle IDs, expected 1, got " + bundleReferences.size());
}
else if (!bundleReferences.get(0).hasReference()
|| !bundleReferences.get(0).getReference().contains("/Bundle/"))
{
logger.error("Task input parameter {} has no Bundle reference",
ConstantsUpdateAllowList.CODESYSTEM_HIGHMED_UPDATE_ALLOW_LIST_VALUE_ALLOW_LIST);
throw new RuntimeException("Task input parameter "
+ ConstantsUpdateAllowList.CODESYSTEM_HIGHMED_UPDATE_ALLOW_LIST_VALUE_ALLOW_LIST
+ " has no Bundle reference");
}

return new IdType(bundleReferences.get(0).getReference());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.highmed.dsf.bpe.ConstantsBase;
import org.highmed.dsf.bpe.delegate.AbstractServiceDelegate;
import org.highmed.dsf.bpe.variables.ConstantsUpdateWhitelist;
import org.highmed.dsf.bpe.variables.ConstantsUpdateAllowList;
import org.highmed.dsf.fhir.client.FhirWebserviceClientProvider;
import org.highmed.dsf.fhir.organization.OrganizationProvider;
import org.highmed.dsf.fhir.task.TaskHelper;
Expand All @@ -34,13 +34,13 @@

import ca.uhn.fhir.context.FhirContext;

public class UpdateWhitelist extends AbstractServiceDelegate implements InitializingBean
public class UpdateAllowList extends AbstractServiceDelegate implements InitializingBean
{
private static final Logger logger = LoggerFactory.getLogger(UpdateWhitelist.class);
private static final Logger logger = LoggerFactory.getLogger(UpdateAllowList.class);

private final OrganizationProvider organizationProvider;

public UpdateWhitelist(OrganizationProvider organizationProvider, FhirWebserviceClientProvider clientProvider,
public UpdateAllowList(OrganizationProvider organizationProvider, FhirWebserviceClientProvider clientProvider,
TaskHelper taskHelper)
{
super(clientProvider, taskHelper);
Expand Down Expand Up @@ -69,29 +69,31 @@ public void doExecute(DelegateExecution execution) throws Exception
Bundle transaction = new Bundle().setType(BundleType.TRANSACTION);
transaction.getMeta().addTag().setSystem("http://highmed.org/fhir/CodeSystem/authorization-role")
.setCode("REMOTE");
transaction.getIdentifier().setSystem(ConstantsUpdateWhitelist.CODESYSTEM_HIGHMED_UPDATE_WHITELIST)
.setValue(ConstantsUpdateWhitelist.CODESYSTEM_HIGHMED_UPDATE_WHITELIST_VALUE_WHITE_LIST);
transaction.getIdentifier().setSystem(ConstantsUpdateAllowList.CODESYSTEM_HIGHMED_UPDATE_ALLOW_LIST)
.setValue(ConstantsUpdateAllowList.CODESYSTEM_HIGHMED_UPDATE_ALLOW_LIST_VALUE_ALLOW_LIST);
searchSet.getEntry().stream()
.filter(e -> e.hasSearch() && SearchEntryMode.MATCH.equals(e.getSearch().getMode()) && e.hasResource()
&& e.getResource() instanceof Organization).map(e -> (Organization) e.getResource())
.forEach(addWhiteListEntry(transaction, searchSet));
&& e.getResource() instanceof Organization)
.map(e -> (Organization) e.getResource()).forEach(addAllowListEntry(transaction, searchSet));

logger.debug("Uploading new white-list transaction bundle: {}",
logger.debug("Uploading new allow list transaction bundle: {}",
FhirContext.forR4().newJsonParser().encodeResourceToString(transaction));

IdType result = client.withMinimalReturn().updateConditionaly(transaction, Map.of("identifier", Collections
.singletonList(ConstantsUpdateWhitelist.CODESYSTEM_HIGHMED_UPDATE_WHITELIST + "|"
+ ConstantsUpdateWhitelist.CODESYSTEM_HIGHMED_UPDATE_WHITELIST_VALUE_WHITE_LIST)));
IdType result = client.withMinimalReturn().updateConditionaly(transaction,
Map.of("identifier",
Collections.singletonList(ConstantsUpdateAllowList.CODESYSTEM_HIGHMED_UPDATE_ALLOW_LIST + "|"
+ ConstantsUpdateAllowList.CODESYSTEM_HIGHMED_UPDATE_ALLOW_LIST_VALUE_ALLOW_LIST)));

Task task = (Task) execution.getVariable(ConstantsBase.VARIABLE_LEADING_TASK);
task.addOutput().setValue(new Reference(new IdType("Bundle", result.getIdPart(), result.getVersionIdPart())))
.getType().addCoding().setSystem(ConstantsUpdateWhitelist.CODESYSTEM_HIGHMED_UPDATE_WHITELIST)
.setCode(ConstantsUpdateWhitelist.CODESYSTEM_HIGHMED_UPDATE_WHITELIST_VALUE_WHITE_LIST);
.getType().addCoding().setSystem(ConstantsUpdateAllowList.CODESYSTEM_HIGHMED_UPDATE_ALLOW_LIST)
.setCode(ConstantsUpdateAllowList.CODESYSTEM_HIGHMED_UPDATE_ALLOW_LIST_VALUE_ALLOW_LIST);
}

private Consumer<? super Organization> addWhiteListEntry(Bundle transaction, Bundle searchSet)
private Consumer<? super Organization> addAllowListEntry(Bundle transaction, Bundle searchSet)
{
return organization -> {
return organization ->
{
Identifier identifier = getDefaultIdentifier(organization).get();

BundleEntryComponent organizationEntry = transaction.addEntry();
Expand All @@ -105,15 +107,16 @@ private Consumer<? super Organization> addWhiteListEntry(Bundle transaction, Bun
organizationEntry.setResource(organization);

organization.setEndpoint(organization.getEndpoint().stream()
.map(addWhiteListEntryReturnReference(transaction, organizationId, searchSet))
.map(addAllowListEntryReturnReference(transaction, organizationId, searchSet))
.filter(Optional::isPresent).map(Optional::get).collect(Collectors.toList()));
};
}

private Function<Reference, Optional<Reference>> addWhiteListEntryReturnReference(Bundle transaction,
private Function<Reference, Optional<Reference>> addAllowListEntryReturnReference(Bundle transaction,
String organizationId, Bundle searchSet)
{
return endpointRef -> getEndpoint(endpointRef, searchSet).map(endpoint -> {
return endpointRef -> getEndpoint(endpointRef, searchSet).map(endpoint ->
{
Identifier identifier = getDefaultIdentifier(endpoint).get();

BundleEntryComponent endpointEntry = transaction.addEntry();
Expand Down Expand Up @@ -146,7 +149,8 @@ private Optional<Identifier> getDefaultIdentifier(Endpoint ept)
private Optional<Endpoint> getEndpoint(Reference endpoint, Bundle searchSet)
{
return searchSet.getEntry().stream()
.filter(e -> e.hasResource() && e.getResource() instanceof Endpoint && e.getFullUrl()
.endsWith(endpoint.getReference())).map(e -> (Endpoint) e.getResource()).findFirst();
.filter(e -> e.hasResource() && e.getResource() instanceof Endpoint
&& e.getFullUrl().endsWith(endpoint.getReference()))
.map(e -> (Endpoint) e.getResource()).findFirst();
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
package org.highmed.dsf.bpe.spring.config;

import org.camunda.bpm.engine.impl.cfg.ProcessEnginePlugin;
import org.highmed.dsf.bpe.plugin.UpdateWhitelistPlugin;
import org.highmed.dsf.bpe.service.UpdateWhitelist;
import org.highmed.dsf.bpe.plugin.UpdateAllowListPlugin;
import org.highmed.dsf.bpe.service.DownloadAllowList;
import org.highmed.dsf.bpe.service.UpdateAllowList;
import org.highmed.dsf.fhir.client.FhirWebserviceClientProvider;
import org.highmed.dsf.fhir.organization.OrganizationProvider;
import org.highmed.dsf.fhir.task.TaskHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import ca.uhn.fhir.context.FhirContext;

@Configuration
public class UpdateWhitelistConfig
public class UpdateAllowListConfig
{
@Autowired
private FhirWebserviceClientProvider clientProvider;
Expand All @@ -22,15 +25,24 @@ public class UpdateWhitelistConfig
@Autowired
private TaskHelper taskHelper;

@Autowired
private FhirContext fhirContext;

@Bean
public ProcessEnginePlugin updateAllowListPlugin()
{
return new UpdateAllowListPlugin();
}

@Bean
public ProcessEnginePlugin updateWhiteListPlugin()
public UpdateAllowList updateAllowList()
{
return new UpdateWhitelistPlugin();
return new UpdateAllowList(organizationProvider, clientProvider, taskHelper);
}

@Bean
public UpdateWhitelist updateWhiteList()
public DownloadAllowList downloadAllowList()
{
return new UpdateWhitelist(organizationProvider, clientProvider, taskHelper);
return new DownloadAllowList(clientProvider, taskHelper, fhirContext);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.highmed.dsf.bpe.variables;

public interface ConstantsUpdateAllowList
{
String CODESYSTEM_HIGHMED_UPDATE_ALLOW_LIST = "http://highmed.org/fhir/CodeSystem/update-allow-list";
String CODESYSTEM_HIGHMED_UPDATE_ALLOW_LIST_VALUE_ALLOW_LIST = "highmed_allow_list";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_1yb5vw3" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.2.0">
<bpmn:process id="downloadAllowList" isExecutable="true" camunda:versionTag="0.3.0">
<bpmn:sequenceFlow id="SequenceFlow_0bbhq2r" sourceRef="StartEvent_1" targetRef="downloadAllowListTask" />
<bpmn:endEvent id="EndEvent_0xd0x8k">
<bpmn:incoming>SequenceFlow_0oyvmcd</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="SequenceFlow_0oyvmcd" sourceRef="downloadAllowListTask" targetRef="EndEvent_0xd0x8k" />
<bpmn:serviceTask id="downloadAllowListTask" name="downloadAllowList" camunda:class="org.highmed.dsf.bpe.service.DownloadAllowList">
<bpmn:incoming>SequenceFlow_0bbhq2r</bpmn:incoming>
<bpmn:outgoing>SequenceFlow_0oyvmcd</bpmn:outgoing>
</bpmn:serviceTask>
<bpmn:startEvent id="StartEvent_1">
<bpmn:outgoing>SequenceFlow_0bbhq2r</bpmn:outgoing>
<bpmn:messageEventDefinition messageRef="Message_1nn2wdw" />
</bpmn:startEvent>
</bpmn:process>
<bpmn:message id="Message_1nn2wdw" name="downloadAllowListMessage" />
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="downloadAllowList">
<bpmndi:BPMNEdge id="SequenceFlow_0oyvmcd_di" bpmnElement="SequenceFlow_0oyvmcd">
<di:waypoint x="365" y="121" />
<di:waypoint x="415" y="121" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="SequenceFlow_0bbhq2r_di" bpmnElement="SequenceFlow_0bbhq2r">
<di:waypoint x="215" y="121" />
<di:waypoint x="265" y="121" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="EndEvent_0xd0x8k_di" bpmnElement="EndEvent_0xd0x8k">
<dc:Bounds x="415" y="103" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="ServiceTask_0um3ad2_di" bpmnElement="downloadAllowListTask">
<dc:Bounds x="265" y="81" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="StartEvent_0x5gijn_di" bpmnElement="StartEvent_1">
<dc:Bounds x="179" y="103" width="36" height="36" />
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_1yb5vw3" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.5.0">
<bpmn:process id="updateWhitelist" isExecutable="true" camunda:versionTag="0.2.0">
<bpmn:sequenceFlow id="SequenceFlow_0bbhq2r" sourceRef="StartEvent_1" targetRef="updateWhitelistTask" />
<bpmn:process id="updateAllowList" isExecutable="true" camunda:versionTag="0.3.0">
<bpmn:sequenceFlow id="SequenceFlow_0bbhq2r" sourceRef="StartEvent_1" targetRef="updateAllowListTask" />
<bpmn:endEvent id="EndEvent_0xd0x8k">
<bpmn:incoming>SequenceFlow_0oyvmcd</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="SequenceFlow_0oyvmcd" sourceRef="updateWhitelistTask" targetRef="EndEvent_0xd0x8k" />
<bpmn:serviceTask id="updateWhitelistTask" name="updateWhitelist" camunda:class="org.highmed.dsf.bpe.service.UpdateWhitelist">
<bpmn:sequenceFlow id="SequenceFlow_0oyvmcd" sourceRef="updateAllowListTask" targetRef="EndEvent_0xd0x8k" />
<bpmn:serviceTask id="updateAllowListTask" name="updateAllowList" camunda:class="org.highmed.dsf.bpe.service.UpdateAllowList">
<bpmn:incoming>SequenceFlow_0bbhq2r</bpmn:incoming>
<bpmn:outgoing>SequenceFlow_0oyvmcd</bpmn:outgoing>
</bpmn:serviceTask>
Expand All @@ -15,9 +15,9 @@
<bpmn:messageEventDefinition messageRef="Message_1nn2wdw" />
</bpmn:startEvent>
</bpmn:process>
<bpmn:message id="Message_1nn2wdw" name="updateWhitelistMessage" />
<bpmn:message id="Message_1nn2wdw" name="updateAllowListMessage" />
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="updateWhitelist">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="updateAllowList">
<bpmndi:BPMNEdge id="SequenceFlow_0bbhq2r_di" bpmnElement="SequenceFlow_0bbhq2r">
<di:waypoint x="215" y="121" />
<di:waypoint x="265" y="121" />
Expand All @@ -29,7 +29,7 @@
<di:waypoint x="365" y="121" />
<di:waypoint x="415" y="121" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="ServiceTask_0um3ad2_di" bpmnElement="updateWhitelistTask">
<bpmndi:BPMNShape id="ServiceTask_0um3ad2_di" bpmnElement="updateAllowListTask">
<dc:Bounds x="265" y="81" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="StartEvent_0x5gijn_di" bpmnElement="StartEvent_1">
Expand Down
Loading